veritas-s3-transformを使ってみた


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と同じ感じで使えますが、shouldTransformtransformsという、アップロード時の変換定義が入ります。

    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)
    },