Skip to content

πŸ’ͺ Extended MulterModule for NestJS with flexible S3 upload and helpful features

License

Notifications You must be signed in to change notification settings

volbrene/nestjs-multer-extended

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Features

  • Single file upload to an Amazon S3 bucket
  • Support for dynamic paths, upload files wherever you want!
  • Generate thumbnail image along with the original
  • Resize single image or even make it into different sizes
  • Load AWS S3 configuration at runtime

Installation

NPM

$ npm i -s nestjs-multer-extended

Yarn

$ yarn add nestjs-multer-extended

Getting started

Once the installation process is complete, we can import the module either synchronously or asynchronosly into the root AppModule.

Β 

Synchronous configuration

import { Module } from '@nestjs/common';
import { MulterExtendedModule } from 'nestjs-multer-extended';

@Module({
  imports: [
    MulterExtendedModule.register({
      accessKeyId: 'YOUR_AWS_ACCESS_KEY_ID',
      secretAccessKey: 'YOUR_AWS_SECRET_ACCESS_KEY',
      region: 'AWS_REGION_NEAR_TO_YOU',
      bucket: 'YOUR_S3_BUCKET_NAME',
      basePath: 'ROOT_DIR_OF_ASSETS',
      fileSize: 1 * 1024 * 1024,
    }),
  ],
})
export class AppModule {}

Asynchronous configuration

In this example, the module integrates with the awesome nestjs-config package.

useFactory should return an object with MulterExtendedS3Options interface or undefined.

import { Module } from '@nestjs/common';
import { MulterExtendedModule } from 'nestjs-multer-extended';
import { ConfigService } from 'nestjs-config';

@Module({
  imports: [
    MulterExtendedModule.registerAsync({
      useFactory: (config: ConfigService) => config.get('s3'),
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}

Note: You can import this module from not only the root module of your app but also from other feature modules where you want to use it.

Β 

To upload a single file, simply tie the AmazonS3FileInterceptor() interceptor to the route handler and extract file from the request using the @UploadedFile() decorator.

import { Controller, Post, UseInterceptors, UploadedFile } from '@nestjs/common';
import { AmazonS3FileInterceptor } from 'nestjs-multer-extended';

@Controller()
export class AppController {

  @Post('upload')
  @UseInterceptors(AmazonS3FileInterceptor('file'))
  uploadFile(@UploadedFile() file) {
    console.log(file);
  }
}

In this example, uploadFile() method will upload a file under the base path you have configured earlrier.

The AmazonS3FileInterceptor() decorator takes two arguments:

  • fieldName: string that supplies the name of the field from the HTML form that holds a file.
  • options: optional object of type MulterExtendedOptions. (mode details here)

What if you wanted to upload a file in a different location under the base path? Thankfully, AmazonS3FileInterceptor() decorator accepts dynamicPath property as a second argument option. Pass the string path as shown below:

@Post('upload')
@UseInterceptors(
  AmazonS3FileInterceptor('file', {
    dynamicPath: 'aec16138-a75a-4961-b8c1-8e803b6bf2cf'
  }),
)
uploadFile(@UploadedFile() file) {
  console.log(file);
}

In this example, uploadFile() method will upload a file in ${basePath}/aec16138-a75a-4961-b8c1-8e803b6bf2cf/${originalname}.

If you want to resize the file before the upload, you can pass on the resize property as follows:

@Post('upload')
@UseInterceptors(
  AmazonS3FileInterceptor('file', {
    resize: { width: 500, height: 400 },
  }),
)
uploadFile(@UploadedFile() file) {
  console.log(file);
}

You can pass an array of size options to resize a single image into different sizes as follows:

@Post('upload')
@UseInterceptors(
  AmazonS3FileInterceptor('file', {
    resizeMultiple: [
      { suffix: 'sm', width: 200, height: 200 },
      { suffix: 'md', width: 300, height: 300 },
      { suffix: 'lg', width: 400, height: 400 },
    ],
  }
)
uploadFile(@UploadedFile() file) {
  console.log(file);
}

Not only creating a thumbnail image but also willing to change the file size limit, you can pass the properties as follows:

@Post('upload')
@UseInterceptors(
    AmazonS3FileInterceptor('file', {
      thumbnail: { suffix: 'thumb', width: 200, height: 200 },
      limits: { fileSize: 7 * 1024 * 1024 },
    }),
  )
uploadFile(@UploadedFile() file) {
  console.log(file);
}

In this example, uploadFile() method will upload both thumbnail and original images.

Β 

MulterExtendedS3Options

MulterExtendedModule requires an object with the following interface:

interface MulterExtendedS3Options {
  /**
   * AWS Access Key ID
   */
  readonly accessKeyId: string;
  /**
   * AWS Secret Access Key
   */
  readonly secretAccessKey: string;
  /**
   * Default region name
   * default: us-west-2
   */
  readonly region: string;
  /**
   * The name of Amazon S3 bucket
   */
  readonly bucket: string;
  /**
   * The base path where you want to store files in
   */
  readonly basePath: string;
  /**
   * Optional parameter for Access control level for the file
   * default: public-read
   * @see https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl
   */
  readonly acl?: string;
  /**
   * Optional parameter for the file size
   * default: 3MB
   */
  readonly fileSize?: number | string;
  /**
   * Optional parameter for a custom logger
   * default: NestJS built-in text-based logger
   * @see https://docs.nestjs.com/techniques/logger
   */
  readonly logger?: LoggerService;
}

MulterExtendedOptions

Key Default Description Example
dynamicPath undefined The name that you assign to an S3 object "aec16138-a75a-4961-b8c1-8e803b6bf2cf/random/dir"
fileFilter Accepts JPEG, PNG types only Function to control which files are accepted
limits 3MB Limits of the uploaded data 5242880 (in bytes)
resize undefined Resize a single file { width: 300, height: 350 }
resizeMultiple undefined Resize a single file into different sizes (Array<object>) [{ suffix: 'md', width: 300, height: 350 }, { suffix: 'sm', width: 200, height: 200 }]
thumbnail undefined Create a thumbnail image (object) { suffix: 'thumbnail', width: 200, height: 200 }

Support

Buymeacoffee

You could help me out for some coffees πŸ₯€ or give us a star ⭐️

Maintainers

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Minsung Kim

πŸ’» 🚧 πŸ“– πŸš‡ πŸ€” ⚠️

Jay McDoniel

πŸ€” πŸ”§ πŸ‘€ πŸ’»

Semin Lee

🎨

This project follows the all-contributors specification. Contributions of any kind welcome!

About

πŸ’ͺ Extended MulterModule for NestJS with flexible S3 upload and helpful features

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 99.3%
  • JavaScript 0.7%