npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

multer-blob-storage

v1.1.1

Published

ES5/6 & Typescript friendly multer storage engine for Azure's blob storage.

Downloads

193

Readme

Multer Azure Blob Storage

npm version publish

ES6 & Typescript friendly Multer storage engine for Azure's blob storage.

Reason for forking

Forked version multer-azure-blob-storage, was not built correctly. The options part, that was passed to the createWriteStreamToBlockBlob of azure-storage package was omitted during build process and so the files uploaded via multer had wrong content type set, hance why, if you tried to access the file via URL, it was always trying to download the file, because it had Content-Type set to application/octet-stream.

I am also publishing this as new npm package multer-blob-storage, since the last time original package was updated, it was 1 year ago.

Installation

npm i -S multer-blob-storage

or

yarn add multer-blob-storage

Usage

Typescript

Leverages strong typings

import * as multer from 'multer';
import { MulterAzureStorage, MASNameResolver } from 'multer-blob-storage';

const resolveBlobName: MASNameResolver = (req: any, file: Express.Multer.File): Promise<string> => {
    return new Promise<string>((resolve, reject) => {
        const blobName: string = yourCustomLogic(req, file);
        resolve(blobName);
    });
};

export type MetadataObj = { [k: string]: string };
const resolveMetadata: MASObjectResolver = (req: any, file: Express.Multer.File): Promise<MetadataObj> => {
    return new Promise<MetadataObj>((resolve, reject) => {
        const metadata: MetadataObj = yourCustomLogic(req, file);
        resolve(metadata);
    });
};

const resolveContentSettings: MASObjectResolver = (req: any, file: Express.Multer.File): Promise<MetadataObj> => {
    return new Promise<MetadataObj>((resolve, reject) => {
        const contentSettings: MetadataObj = yourCustomLogic(req, file);
        resolve(contentSettings);
    });
};

const azureStorage: MulterAzureStorage = new MulterAzureStorage({
    connectionString: 'DefaultEndpointsProtocol=https;AccountName=mystorageaccountname;AccountKey=wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY;EndpointSuffix=core.windows.net',
    accessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY',
    accountName: 'mystorageaccountname',
    containerName: 'documents',
    blobName: resolveBlobName,
    metadata: resolveMetadata,
    contentSettings: resolveContentSettings,
    containerAccessLevel: 'blob',
    urlExpirationTime: 60
});

const upload: multer.Instance = multer({
    storage: azureStorage
});

app.post('/documents', upload.any(), (req: Request, res: Response, next: NextFunction) => {
  console.log(req.files)
  res.status(200).json(req.files)
});

Javascript ES6

Common.js style imports

const multer = require('multer')
const MulterAzureStorage = require('multer-blob-storage').MulterAzureStorage;

E6 style imports

import * as multer from 'multer';
import { MulterAzureStorage } from 'multer-blob-storage';

Rest of the JS code

const resolveBlobName = (req, file) => {
    return new Promise((resolve, reject) => {
        const blobName = yourCustomLogic(req, file);
        resolve(blobName);
    });
};

const resolveMetadata = (req, file) => {
    return new Promise((resolve, reject) => {
        const metadata = yourCustomLogic(req, file);
        resolve(metadata);
    });
};

const resolveContentSettings = (req, file) => {
    return new Promise((resolve, reject)) => {
        const contentSettings = yourCustomLogic(req, file);
        resolve(contentSettings);
    };
};

const azureStorage = new MulterAzureStorage({
    connectionString: 'DefaultEndpointsProtocol=https;AccountName=mystorageaccountname;AccountKey=wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY;EndpointSuffix=core.windows.net',
    accessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY',
    accountName: 'mystorageaccountname',
    containerName: 'documents',
    blobName: resolveBlobName,
    metadata: resolveMetadata,
    contentSettings: resolveContentSettings,
    containerAccessLevel: 'blob',
    urlExpirationTime: 60
});

const upload = multer({
    storage: azureStorage
});

app.post('/documents', upload.any(), (req, res, next) => {
  console.log(req.files)
  res.status(200).json(req.files)
});

More details on using upload can be found in the Multer documentation

File information

Multer Azure Blob Storage will return the following information in each file uploaded. This can be found in the req.files param:

Key | Description | Note ---|---|--- fieldname | The field name/key sent in the form's post request. | Added by Multer originalname | Full original name of the file on the user's computer. | Added by Multer encoding | File encoding type. | Added by Multer mimetype | MIME type of the file. | Added by Multer blobName | Blob/file name of created blob in Azure storage. | container | Name of azure storage container where the blob/file was uploaded to. | blobType | Type of blob. | From the result of call to azure's getBlobProperties() of blobService size | Size of the blob. | From the result of call to azure's getBlobProperties() of blobService etag | Etag. | From the result of call to azure's getBlobProperties() of blobService metadata | Blob's metadata. | From the result of call to azure's getBlobProperties() of blobService url | The full url to access the uploaded blob/file. |

Configuration object

Details of the configuration object that needs to be passed into the constructor of the MulterAzureStorage class.

| Parameter Name | Type | Sample Value | |---|---|---| | connectionString | string | 'DefaultEndpointsProtocol=https;AccountName=mystorageaccountname;AccountKey=wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY;EndpointSuffix=core.windows.net' | | accessKey | string | 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY' | | accountName | string | 'mystorageaccountname' | | containerName | string or function: MASNameResolver | 'documents' or (req: any, file: Express.Multer.File) => Promise<string> | | metadata | { [k: string]: string } or function: MASObjectResolver | '{author: John Doe; album: ASOT}' or (req: any, file: Express.Multer.File) => Promise<{[k: string]: string}> | | blobName | function: MASNameResolver (optional) | (req: any, file: Express.Multer.File) => Promise<string> | | containerAccessLevel | string (optional) | 'blob' or 'container' or 'private' | | urlExpirationTime | number (optional) | 60 |

For more information about the meaning of individual parameters please check Azure documentation on node.js integration.

Defaults

For the optional parameters in the configuration object for the MulterAzureStorage class, here are the default fallbacks:

  • containerAccessLevel: blob
  • urlExpirationTime: 60 minutes. NOTE: To unset this property and not revert to the default, pass in -1
  • blobName: Date.now() + '-' + uuid.v4() + path.extname(file.originalname). This results in a url safe filename that looks like '1511161727560-d83d24c8-d213-444c-ba72-316c7a858805.png'

File naming

The containerName can be anything you choose, as long as it's unique to the storage account and as long as it fits Azure's naming restrictions. If the container does not exist the storage engine will create it.

The blobName in an Azure container also needs to have a unique name.

multer-blob-storage allows you to customize the containerName and blobName per request before uploading the file. This can be done by proving a MASNameResolver function in the configuation object for the desired parameter.

const resolveName: MASNameResolver = (req: any, file: Express.Multer.File): Promise<string> => {
    return new Promise<string>((resolve, reject) => {
        // Compute containerName or blobName with your custom logic.
        const computedName: string = yourCustomLogic(req, file);
        resolve(computedName);
    });
};

multer-blob-storage also allows you to add/customize metadata and contentSettings per request before uploading the file. This can be done by proving a MASObjectResolver function in the configuation object for the desired parameter.

export type MetadataObj = { [k: string]: string };
const resolveMetadata: MASObjectResolver = (req: any, file: Express.Multer.File): Promise<MetadataObj> => {
    return new Promise<MetadataObj>((resolve, reject) => {
        const metadata: MetadataObj = yourCustomLogic(req, file);
        resolve(metadata);
    });
};

Azure

Creating a storage account

For instructions on how to create a storage account, see the following Azure documentation.

Credentials (Quick tips)

Your credentials can all be obtained under the Access keys section in the storage account pane in Azure.

The connectionString is prefered. If its not provides, please provide accessKey and accountName.

You only need to provide one of the two access keys in the accessKey field.

The accountName is just the name of your storage account that you've created in Azure.

If using the MulterAzureStorage class without passing in any configuration options then the following environment variables will need to be set:

  1. AZURE_STORAGE_CONNECTION_STRING, for the connectionString.
  2. AZURE_STORAGE_ACCESS_KEY, for the accessKey.
  3. AZURE_STORAGE_ACCOUNT, for the accountName.

Tests

Not implemented yet

Thanks

All great things are built on the shoulder of giants. I want to thank my giants for lending their shoulders:

License

MIT