Skip to content

Instantly share code, notes, and snippets.

@teslamint
Last active December 3, 2020 08:48
Show Gist options
  • Save teslamint/5b12e4ad3a2a889671d05713a15deb15 to your computer and use it in GitHub Desktop.
Save teslamint/5b12e4ad3a2a889671d05713a15deb15 to your computer and use it in GitHub Desktop.
AWS S3 Storage Adapter for NestJS with Fastify
import { Req } from "@nestjs/common";
import { FastifyRequest } from "fastify";
import { File, StorageEngine } from "fastify-multer/lib/interfaces";
import * as uuid from 'uuid';
export type Info = Partial<
File & AWS.S3.ManagedUpload.SendData & AWS.S3.Types.PutObjectRequest
>;
export class S3Storage implements StorageEngine {
private readonly s3: AWS.S3;
private readonly bucket: string;
private readonly prefix: string;
private readonly randomFileName: boolean;
private readonly acl: string;
constructor(opts) {
this.s3 = opts.s3;
this.bucket = opts.bucket;
this.prefix = opts.prefix || '';
this.randomFileName = opts.randomFileName || false;
this.acl = opts.acl ?? undefined;
}
_handleFile(@Req() req: FastifyRequest, file: File, cb: (error: Error|null, info?: Info) => void) {
let currentSize = 0;
const extension = file.originalname.split('.').pop().toLowerCase();
const uid = uuid.v4();
const params: AWS.S3.Types.PutObjectRequest = {
Bucket: this.bucket,
Key: `${this.prefix}${file.path ?? !this.randomFileName ? `${uid}/` : ''}${this.randomFileName ? `${uid}.${extension}` : file.originalname}`,
Body: file.stream,
ContentType: file.mimetype,
ACL: this.acl,
};
const upload = this.s3.upload(params);
upload.on('httpUploadProgress', (e) => {
if (e.total) {
currentSize = e.total;
}
});
upload.promise().then((uploadData) => {
cb(null, {
size: currentSize,
...uploadData,
})
}, cb);
}
_removeFile(req: FastifyRequest, file: Info, cb: (error: Error|null) => void) {
this.s3.deleteObject({ Bucket: file.Bucket, Key: file.Key }, cb);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment