anacronw / multer-s3

multer storage engine for amazon s3
MIT License
660 stars 190 forks source link

Typescript multer-s3 v3.0.1 - Type 'S3Client' is missing the following properties from type 'S3': abortMultipartUpload, completeMultipartUpload, copyObject, createBucket, and 104 more. #177

Closed lorflea closed 2 years ago

lorflea commented 2 years ago

Following the example, in typescript:

const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: 'some-bucket',
    metadata: function (req, file, cb) {
      cb(null, {fieldName: file.fieldname});
    },
    key: function (req, file, cb) {
      cb(null, Date.now().toString())
    }
  })
})

3rd line gives me the following typescript error: Type 'S3Client' is missing the following properties from type 'S3': abortMultipartUpload, completeMultipartUpload, copyObject, createBucket, and 104 more.

arminhupka commented 2 years ago

I have the same issue

Type 'S3Client' is missing the following properties from type 'S3': abortMultipartUpload, completeMultipartUpload, copyObject, createBucket, and 104 more.
LinusU commented 2 years ago

Duplicate of #173? I think that this is an issue in DefinitelyTyped since this package currently doesn't ship with types...

Lil-Strudel commented 2 years ago

I created a temporary solution to this problem. The correct way to solve this is to update multer-s3 in DefinitelyTyped to match the new v3 changes or maybe even convert the entire project to ts. I don't really have time to do that right now, so for the time being I tweaked the old v2 types in DefinitelyTyped to support the new aws s3Client. Hopefully this helps :)

(I'm not that good with typescript so this might be absolutely horrible for reasons I don't know, but it worked for he hahaha)

types/multer-s3.d.ts

namespace Express {
  namespace MulterS3 {
    interface File extends Multer.File {
      bucket: string;
      key: string;
      acl: string;
      contentType: string;
      contentDisposition: null;
      storageClass: string;
      serverSideEncryption: null;
      metadata: any;
      location: string;
      etag: string;
    }
  }
  interface Request {
    file?: MulterS3.File | undefined;
    files?:
      | {
          [fieldname: string]: MulterS3.File[];
        }
      | MulterS3.File[]
      | undefined;
  }
}

declare module "multer-s3" {
  interface Options {
    s3: import("@aws-sdk/client-s3").S3Client;
    bucket:
      | ((req: Express.Request, file: Express.Multer.File, callback: (error: any, bucket?: string) => void) => void)
      | string;
    key?(req: Express.Request, file: Express.Multer.File, callback: (error: any, key?: string) => void): void;
    acl?:
      | ((req: Express.Request, file: Express.Multer.File, callback: (error: any, acl?: string) => void) => void)
      | string
      | undefined;
    contentType?(
      req: Express.Request,
      file: Express.Multer.File,
      callback: (error: any, mime?: string, stream?: NodeJS.ReadableStream) => void
    ): void;
    contentDisposition?:
      | ((
          req: Express.Request,
          file: Express.Multer.File,
          callback: (error: any, contentDisposition?: string) => void
        ) => void)
      | string
      | undefined;
    metadata?(req: Express.Request, file: Express.Multer.File, callback: (error: any, metadata?: any) => void): void;
    cacheControl?:
      | ((
          req: Express.Request,
          file: Express.Multer.File,
          callback: (error: any, cacheControl?: string) => void
        ) => void)
      | string
      | undefined;
    serverSideEncryption?:
      | ((
          req: Express.Request,
          file: Express.Multer.File,
          callback: (error: any, serverSideEncryption?: string) => void
        ) => void)
      | string
      | undefined;
  }

  interface S3Storage {
    (options?: Options): import("multer").StorageEngine;

    AUTO_CONTENT_TYPE: (
      req: Express.Request,
      file: Express.Multer.File,
      callback: (error: any, mime?: string, stream?: NodeJS.ReadableStream) => void
    ) => void;
    DEFAULT_CONTENT_TYPE: (
      req: Express.Request,
      file: Express.Multer.File,
      callback: (error: any, mime?: string) => void
    ) => void;
  }

  const S3Storage: S3Storage;

  export = S3Storage;
}
arminhupka commented 2 years ago

@Lil-Strudel working like a charm! Thanks!