S3に画像などをアップロードするにはmulter-s3を使っているのですが、「サムネイルも欲しい、そしてcontent-typeも設定して欲しい」というリクエストに対応した話です。
他のモジュールも試してみたのですが、content-typeの指定をできるものが見当たらず「みなさん、S3に画像アップロードするときはapplication/octet-streamでやるのが標準なのだろうか?」と思っていたところ、veritas-s3-transformを見つけました。
TypeScriptで書かれているということで、型定義ファイルもあると期待したのですが、index.d.ts
は
export {};
というスッキリした世界だったので、自力で型定義ファイルを雑に用意しています(@types/multer-s3をベースtransformやshouldTransformを追加すれば大丈夫でした)。
変換ルールの記述
基本的にはmulter-s3と同じ感じで使えますが、shouldTransform
とtransforms
という、アップロード時の変換定義が入ります。
shouldTransform: function (req: Express.Request, file: Express.Multer.File, cb: (error: null, key: boolean) => void) {
cb(null, file.fieldname == 'image2')
},
transforms: [
{
id: 'original',
key: function (req: Express.Request, file: Express.Multer.File, cb: (error: null, key?: string) => void) {
cb(null, Date.now().toString() + file.originalname)
},
transform: function (req: Express.Request, file: Express.Multer.File, cb: (error: null, key?: sharp.Sharp) => void) {
cb(null, sharp())
}
},
{
id: 'thumbnail',
key: function (req: Express.Request, file: Express.Multer.File, cb: (error: null, key?: string) => void) {
cb(null, Date.now().toString() + 'thumb' + file.originalname)
},
transform: function (req: Express.Request, file: Express.Multer.File, cb: (error: null, key?: sharp.Sharp) => void) {
cb(null, sharp().resize(100, 100))
}
}
]
上記の場合は、fieldnameがimage2
の場合のみ変換を行う。オリジナルとサムネイルをアップロードするが、オリジナルは変換なしで、サムネイルはリサイズしてアップロード、という意味になります。
content-typeの指定
multer-s3と同じです
contentType: function (req: Express.Request, file: Express.Multer.File, cb: (error: null, mime?: string, stream?: NodeJS.ReadableStream) => void) {
cb(null, file.mimetype)
},