Skip to content

Instantly share code, notes, and snippets.

@irvanherz
Created October 30, 2022 10:47
Show Gist options
  • Save irvanherz/26d0178af00a199a7dcd78285962402c to your computer and use it in GitHub Desktop.
Save irvanherz/26d0178af00a199a7dcd78285962402c to your computer and use it in GitHub Desktop.
Streaming multer storage engine for Minio
/* global Express */
import { Request } from 'express'
import { Client, ClientOptions, UploadedObjectInfo } from 'minio'
import multer from 'multer'
import path from 'path'
type FilenameCallbackType = (req: Request, file: Express.Multer.File) => string
type HandleFileCallbackInfoType = Partial<Express.Multer.File> & { objectinfo?: UploadedObjectInfo }
type HandleFileCallbackType = (error?: any, info?: HandleFileCallbackInfoType) => void
const defaultFilenameCallback:FilenameCallbackType = (_req, file) => {
const fileExt = path.extname(file.originalname)
return `${Date.now()}${fileExt}`
}
type Options = {
filename?: FilenameCallbackType
bucket: string
clientOptions: ClientOptions
}
class MulterMinioStorage implements multer.StorageEngine {
private filename: FilenameCallbackType
private bucket: string
private minioClient: Client
constructor (opts: Options) {
this.filename = opts.filename || defaultFilenameCallback
this.bucket = opts.bucket
this.minioClient = new Client(opts.clientOptions)
}
_handleFile (
req: Request,
file: Express.Multer.File,
callback: HandleFileCallbackType
) {
const fileName = this.filename(req, file)
const fileReadStream = file.stream
this.minioClient.putObject(this.bucket, fileName, fileReadStream)
.then(value => {
callback(null, {
...file,
filename: fileName,
objectinfo: value
})
})
.catch(err => {
callback(err, {})
})
}
_removeFile = (_req: Request, file: Express.Multer.File, callback: (error: Error | null) => void): void => {
this.minioClient.removeObject(this.bucket, file.filename, () => callback(null))
}
}
export default MulterMinioStorage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment