All Projects β†’ jeffminsungkim β†’ Nestjs Multer Extended

jeffminsungkim / Nestjs Multer Extended

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

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Nestjs Multer Extended

S3mock
A simple mock implementation of the AWS S3 API startable as Docker image, JUnit 4 rule, or JUnit Jupiter extension
Stars: ✭ 332 (+235.35%)
Mutual labels:  s3, aws-s3
S3fs Fuse
FUSE-based file system backed by Amazon S3
Stars: ✭ 5,733 (+5690.91%)
Mutual labels:  s3, aws-s3
Goofys
a high-performance, POSIX-ish Amazon S3 file system written in Go
Stars: ✭ 3,932 (+3871.72%)
Mutual labels:  s3, aws-s3
s3-mongo-backup
Mongodb backups to S3
Stars: ✭ 18 (-81.82%)
Mutual labels:  aws-s3, s3
S3proxy
Access other storage backends via the S3 API
Stars: ✭ 952 (+861.62%)
Mutual labels:  s3, aws-s3
simply-static-deploy
WordPress plugin to deploy static sites easily to an AWS S3 bucket.
Stars: ✭ 48 (-51.52%)
Mutual labels:  aws-s3, s3
S3 Sync Action
πŸ”„ GitHub Action to sync a directory with a remote S3 bucket 🧺
Stars: ✭ 497 (+402.02%)
Mutual labels:  s3, aws-s3
punic
Punic is a remote cache CLI built for Carthage and Apple .xcframework
Stars: ✭ 25 (-74.75%)
Mutual labels:  aws-s3, s3
Awslib scala
An idiomatic Scala wrapper around the AWS Java SDK
Stars: ✭ 20 (-79.8%)
Mutual labels:  s3, aws-s3
S3 Permission Checker
Check read, write permissions on S3 buckets in your account
Stars: ✭ 18 (-81.82%)
Mutual labels:  s3, aws-s3
fluency
High throughput data ingestion logger to Fluentd, AWS S3 and Treasure Data
Stars: ✭ 135 (+36.36%)
Mutual labels:  aws-s3, s3
Minio Hs
MinIO Client SDK for Haskell
Stars: ✭ 39 (-60.61%)
Mutual labels:  s3, aws-s3
laravel-s3-tools
This Laravel package contains additional functionality not currently in Laravel for interfacing with Amazon's S3 service (including managing versioned objects).
Stars: ✭ 31 (-68.69%)
Mutual labels:  aws-s3, s3
Aws.s3
Amazon Simple Storage Service (S3) API Client
Stars: ✭ 302 (+205.05%)
Mutual labels:  s3, aws-s3
laravel-uppy-s3-multipart-upload
Multipart Uploads using Laravel, AWS S3, and Uppy
Stars: ✭ 30 (-69.7%)
Mutual labels:  aws-s3, s3
Discharge
⚑️ A simple, easy way to deploy static websites to Amazon S3.
Stars: ✭ 483 (+387.88%)
Mutual labels:  s3, aws-s3
Dive-Into-AWS
Links to the Repos and Sections in our Dive into AWS Course.
Stars: ✭ 27 (-72.73%)
Mutual labels:  aws-s3, s3
ionic-image-upload
Ionic Plugin for Uploading Images to Amazon S3
Stars: ✭ 26 (-73.74%)
Mutual labels:  aws-s3, s3
Rome
Carthage cache for S3, Minio, Ceph, Google Storage, Artifactory and many others
Stars: ✭ 724 (+631.31%)
Mutual labels:  s3, aws-s3
Aws S3 Scala
Scala client for Amazon S3
Stars: ✭ 35 (-64.65%)
Mutual labels:  s3, aws-s3

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({
      awsConfig: {
        accessKeyId: 'YOUR_AWS_ACCESS_KEY_ID',
        secretAccessKey: 'YOUR_AWS_ACCESS_KEY_ID',
        region: 'AWS_REGION_NEAR_TO_YOU',
        // ... any options you want to pass to the AWS instance
      },
      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}.

Route parameters can also be used as a key. For example, if you have the route /user/:name, then pass the name into the dynamicPath property as a value.

@Post('user/:name')
@UseInterceptors(
  AmazonS3FileInterceptor('file', {
    dynamicPath: 'name'
  }),
)
uploadFile(@UploadedFile() file) {
  // POST /user/jeffminsungkim
  console.log(file);
  // => YOUR-BASE-PATH/jeffminsungkim/filename.png
}

@Post('user/:name/team/:no')
@UseInterceptors(
  AmazonS3FileInterceptor('file', {
    dynamicPath: 'no'
  }),
)
uploadFile(@UploadedFile() file) {
  // POST /user/jeffminsungkim/team/8987
  console.log(file);
  // => YOUR-BASE-PATH/8987/filename.png
}

@Post('user/:name/team/:no')
@UseInterceptors(
  AmazonS3FileInterceptor('file', {
    dynamicPath: ['name', 'no']
  }),
)
uploadFile(@UploadedFile() file) {
  // POST /user/jeffminsungkim/team/8987
  console.log(file);
  // => YOUR-BASE-PATH/jeffminsungkim/8987/filename.png
}

 

You may want to store the file with an arbitrary name instead of the original file name. You can do this by passing the randomFilename property attribute set to true as follows:

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

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
   * @deprecated v2 use awsConfig instead
   */
  readonly accessKeyId?: string;
  /**
   * AWS Secret Access Key
   * @deprecated v2 use awsConfig instead
   */
  readonly secretAccessKey?: string;
  /**
   * Default region name
   * default: us-west-2
   * @deprecated v2 use awsConfig instead
   */
  readonly region?: string;
  /**
   * AWS Config
   */
  readonly awsConfig?: ConfigurationOptions & ConfigurationServicePlaceholders & APIVersions & {[key: string]: any};
  /**
   * S3 Config
   */
  readonly s3Config?: AWS.S3.Types.ClientConfiguration;
  /**
   * 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;
  /**
   * AWS Endpoint
   * @deprecated v2 use s3Config instead
   */
  readonly endpoint?: 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"
randomFilename undefined If this property sets to true, a random file name will be generated "aec16138-a75a-4961-b8c1-8e803b6bf2cf"
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

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

semin3276

🎨

RenΓ© Volbach

πŸ’» ⚠️

gimyboya

πŸ’»

dineshsalunke

πŸ’» πŸ“–

Michael Wolz

πŸ’» πŸ“–

visurel

πŸ’» πŸ“–

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].