@ackplus/nest-file-storage 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/package.json +2 -2
  2. package/src/{index.ts → index.d.ts} +1 -0
  3. package/src/index.d.ts.map +1 -0
  4. package/src/lib/constants.d.ts +2 -0
  5. package/src/lib/constants.d.ts.map +1 -0
  6. package/src/lib/file-storage.service.d.ts +8 -0
  7. package/src/lib/file-storage.service.d.ts.map +1 -0
  8. package/src/lib/{index.ts → index.d.ts} +1 -0
  9. package/src/lib/index.d.ts.map +1 -0
  10. package/src/lib/interceptor/file-storage.interceptor.d.ts +25 -0
  11. package/src/lib/interceptor/file-storage.interceptor.d.ts.map +1 -0
  12. package/src/lib/nest-file-storage.module.d.ts +9 -0
  13. package/src/lib/nest-file-storage.module.d.ts.map +1 -0
  14. package/src/lib/storage/azure.storage.d.ts +19 -0
  15. package/src/lib/storage/azure.storage.d.ts.map +1 -0
  16. package/src/lib/storage/local.storage.d.ts +35 -0
  17. package/src/lib/storage/local.storage.d.ts.map +1 -0
  18. package/src/lib/storage/s3.storage.d.ts +20 -0
  19. package/src/lib/storage/s3.storage.d.ts.map +1 -0
  20. package/src/lib/storage.factory.d.ts +9 -0
  21. package/src/lib/storage.factory.d.ts.map +1 -0
  22. package/src/lib/{types.ts → types.d.ts} +23 -35
  23. package/src/lib/types.d.ts.map +1 -0
  24. package/eslint.config.mjs +0 -22
  25. package/jest.config.ts +0 -10
  26. package/project.json +0 -38
  27. package/src/lib/constants.ts +0 -1
  28. package/src/lib/file-storage.service.ts +0 -36
  29. package/src/lib/interceptor/file-storage.interceptor.ts +0 -174
  30. package/src/lib/nest-file-storage.module.ts +0 -78
  31. package/src/lib/storage/azure.storage.ts +0 -214
  32. package/src/lib/storage/local.storage.ts +0 -233
  33. package/src/lib/storage/s3.storage.ts +0 -242
  34. package/src/lib/storage.factory.ts +0 -58
  35. package/tsconfig.json +0 -17
  36. package/tsconfig.lib.json +0 -14
  37. package/tsconfig.spec.json +0 -15
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@ackplus/nest-file-storage",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "type": "commonjs",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
7
7
  "dependencies": {
8
8
  "tslib": "^2.3.0"
9
9
  }
10
- }
10
+ }
@@ -2,3 +2,4 @@ export * from './lib/nest-file-storage.module';
2
2
  export * from './lib/file-storage.service';
3
3
  export * from './lib/interceptor/file-storage.interceptor';
4
4
  export * from './lib/types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../packages/nest-file-storage/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4CAA4C,CAAC;AAC3D,cAAc,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const FILE_STORAGE_OPTIONS = "FileStorageOptions";
2
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../packages/nest-file-storage/src/lib/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,uBAAuB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { FileStorageEnum, FileStorageModuleOptions } from './types';
2
+ export declare class FileStorageService {
3
+ private static options;
4
+ static setOptions(options: FileStorageModuleOptions): void;
5
+ static getOptions(): FileStorageModuleOptions;
6
+ static getStorage(storageType?: FileStorageEnum): Promise<import("./types").Storage>;
7
+ }
8
+ //# sourceMappingURL=file-storage.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-storage.service.d.ts","sourceRoot":"","sources":["../../../../../packages/nest-file-storage/src/lib/file-storage.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAqD,MAAM,SAAS,CAAC;AAGvH,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,MAAM,CAAC,OAAO,CAA2B;IAEjD,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,wBAAwB;IAInD,MAAM,CAAC,UAAU,IAAI,wBAAwB;WAIhC,UAAU,CAAC,WAAW,CAAC,EAAE,eAAe;CAmBxD"}
@@ -3,3 +3,4 @@ export * from './types';
3
3
  export * from './storage.factory';
4
4
  export * from './interceptor/file-storage.interceptor';
5
5
  export * from './file-storage.service';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/nest-file-storage/src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,SAAS,CAAC;AACxB,cAAc,mBAAmB,CAAC;AAClC,cAAc,wCAAwC,CAAC;AACvD,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { NestInterceptor } from '@nestjs/common';
2
+ import { Request } from 'express';
3
+ import { FileStorageEnum, StorageOptions } from '../types';
4
+ export type FileUploadConfig = {
5
+ type: 'single' | 'array' | 'fields';
6
+ fieldName?: string;
7
+ maxCount?: number;
8
+ fields?: {
9
+ name: string;
10
+ maxCount?: number;
11
+ }[];
12
+ };
13
+ export type FileStorageInterceptorOptions = {
14
+ fileName?: (file: any, req?: Request) => string;
15
+ fileDist?: (file: any, req?: Request) => string;
16
+ prefix?: string;
17
+ storageType?: FileStorageEnum;
18
+ storageOptions?: StorageOptions;
19
+ mapToRequestBody?: (file: any, fieldName: string, req?: Request) => any;
20
+ };
21
+ /**
22
+ * Function-based interceptor that accepts storage options dynamically.
23
+ */
24
+ export declare function FileStorageInterceptor(fileConfig: FileUploadConfig | string, interceptorOptions?: FileStorageInterceptorOptions): NestInterceptor;
25
+ //# sourceMappingURL=file-storage.interceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-storage.interceptor.d.ts","sourceRoot":"","sources":["../../../../../../packages/nest-file-storage/src/lib/interceptor/file-storage.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAiC,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAMlC,OAAO,EAAE,eAAe,EAAE,cAAc,EAA0C,MAAM,UAAU,CAAC;AAGnG,MAAM,MAAM,gBAAgB,GAAG;IAC3B,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IACxC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;IAChD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,cAAc,CAAC,EAAE,cAAc,CAAC;IAGhC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,KAAK,GAAG,CAAC;CAC3E,CAAC;AA2DF;;GAEG;AACH,wBAAgB,sBAAsB,CAClC,UAAU,EAAE,gBAAgB,GAAG,MAAM,EACrC,kBAAkB,CAAC,EAAE,6BAA6B,GACnD,eAAe,CAkFjB"}
@@ -0,0 +1,9 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { FileStorageAsyncOptions, FileStorageModuleOptions } from './types';
3
+ export declare class NestFileStorageModule {
4
+ static forRoot(options: FileStorageModuleOptions): DynamicModule;
5
+ static forRootAsync(options: FileStorageAsyncOptions): DynamicModule;
6
+ private static createAsyncProviders;
7
+ private static createAsyncOptionsProvider;
8
+ }
9
+ //# sourceMappingURL=nest-file-storage.module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nest-file-storage.module.d.ts","sourceRoot":"","sources":["../../../../../packages/nest-file-storage/src/lib/nest-file-storage.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,aAAa,EAAY,MAAM,gBAAgB,CAAC;AAIjE,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAA6B,MAAM,SAAS,CAAC;AAGvG,qBACa,qBAAqB;IAE9B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,wBAAwB,GAAG,aAAa;IAkBhE,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa;IAWpE,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAcnC,OAAO,CAAC,MAAM,CAAC,0BAA0B;CAwB5C"}
@@ -0,0 +1,19 @@
1
+ import { BlobSASSignatureValues } from '@azure/storage-blob';
2
+ import { StorageEngine } from 'multer';
3
+ import { AzureStorageOptions, Storage, UploadedFile } from '../types';
4
+ export declare class AzureStorage implements StorageEngine, Storage {
5
+ private options;
6
+ private blobServiceClient;
7
+ private fileNameFunction;
8
+ private fileDistFunction;
9
+ constructor(options: AzureStorageOptions);
10
+ _handleFile(req: any, file: any, cb: (error?: any, info?: any) => void): Promise<void>;
11
+ _removeFile(_req: any, file: any, cb: (error: Error | null) => void): Promise<void>;
12
+ getUrl(key: string): string;
13
+ getSignedUrl(key: string, signatureValues?: Partial<Omit<BlobSASSignatureValues, 'containerName'>>): string;
14
+ getFile(key: string): Promise<Buffer>;
15
+ putFile(buffer: Buffer, key: string): Promise<UploadedFile>;
16
+ deleteFile(key: string): Promise<void>;
17
+ copyFile(oldKey: string, newKey: string): Promise<UploadedFile>;
18
+ }
19
+ //# sourceMappingURL=azure.storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"azure.storage.d.ts","sourceRoot":"","sources":["../../../../../../packages/nest-file-storage/src/lib/storage/azure.storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,sBAAsB,EAKzB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAIvC,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGtE,qBAAa,YAAa,YAAW,aAAa,EAAE,OAAO;IAQ3C,OAAO,CAAC,OAAO;IAN3B,OAAO,CAAC,iBAAiB,CAAoB;IAE7C,OAAO,CAAC,gBAAgB,CAAqE;IAC7F,OAAO,CAAC,gBAAgB,CAAqE;gBAGzE,OAAO,EAAE,mBAAmB;IAoB1C,WAAW,CACb,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,GAAG,EACT,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC;IA6BV,WAAW,CACb,IAAI,EAAE,GAAG,EACT,IAAI,EAAE,GAAG,EACT,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,GAClC,OAAO,CAAC,IAAI,CAAC;IAahB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAK3B,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,GAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAM,GAAG,MAAM;IAqCzG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAcrC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAwB3D,UAAU,CAAC,GAAG,EAAE,MAAM;IAYtB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CA0BxE"}
@@ -0,0 +1,35 @@
1
+ import { StorageEngine } from 'multer';
2
+ import { LocalStorageOptions, Storage, UploadedFile } from '../types';
3
+ export declare class LocalStorage implements StorageEngine, Storage {
4
+ private options;
5
+ private rootPath;
6
+ private fileNameFunction;
7
+ private fileDistFunction;
8
+ /**
9
+ * Convert OS-specific file path to URL-friendly key
10
+ * This ensures keys are consistent across all platforms
11
+ * Windows: C:\uploads\2024\01\file.jpg -> 2024/01/file.jpg
12
+ * Unix: /uploads/2024/01/file.jpg -> 2024/01/file.jpg
13
+ */
14
+ private pathToUrl;
15
+ /**
16
+ * Convert URL-friendly key to OS-specific file path
17
+ * This converts stored keys back to valid file system paths
18
+ * 2024/01/file.jpg -> Windows: 2024\01\file.jpg, Unix: 2024/01/file.jpg
19
+ */
20
+ private urlToPath;
21
+ /**
22
+ * Get full file system path from URL-friendly key
23
+ */
24
+ private getFullPath;
25
+ constructor(options: LocalStorageOptions);
26
+ _handleFile(req: any, file: Express.Multer.File, cb: (error?: any, info?: any) => void): Promise<void>;
27
+ _removeFile(_req: any, file: any, cb: (error: Error | null) => void): void;
28
+ getUrl(urlKey: string): string;
29
+ getFile(urlKey: string): Promise<Buffer>;
30
+ deleteFile(urlKey: string): Promise<void>;
31
+ putFile(fileContent: Buffer, urlKey: string): Promise<UploadedFile>;
32
+ path(urlKey: string): string;
33
+ copyFile(oldUrlKey: string, newUrlKey: string): Promise<UploadedFile>;
34
+ }
35
+ //# sourceMappingURL=local.storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.storage.d.ts","sourceRoot":"","sources":["../../../../../../packages/nest-file-storage/src/lib/storage/local.storage.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAMvC,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGtE,qBAAa,YAAa,YAAW,aAAa,EAAE,OAAO;IA8C3C,OAAO,CAAC,OAAO;IA5C3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,gBAAgB,CAAqE;IAC7F,OAAO,CAAC,gBAAgB,CAAqE;IAE7F;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IAajB;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAQjB;;OAEG;IACH,OAAO,CAAC,WAAW;gBAKC,OAAO,EAAE,mBAAmB;IAmB1C,WAAW,CACb,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EACzB,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI;IAgCzC,WAAW,CACP,IAAI,EAAE,GAAG,EACT,IAAI,EAAE,GAAG,EACT,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI;IAarC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAgBxB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMxC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzC,OAAO,CACT,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC;IAiCxB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAQtB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAgC9E"}
@@ -0,0 +1,20 @@
1
+ import { GetObjectCommandInput } from '@aws-sdk/client-s3';
2
+ import { StorageEngine } from 'multer';
3
+ import { S3StorageOptions, Storage, UploadedFile } from '../types';
4
+ export declare class S3Storage implements StorageEngine, Storage {
5
+ private options;
6
+ private s3;
7
+ private fileNameFunction;
8
+ private fileDistFunction;
9
+ constructor(options: S3StorageOptions);
10
+ _handleFile(req: any, file: Express.Multer.File, cb: (error?: any, info?: any) => void): Promise<void>;
11
+ _removeFile(_req: any, file: any, cb: (error: Error | null) => void): void;
12
+ getUrl(key: string): string;
13
+ getSignedUrl(key: string, objectConfig?: Partial<GetObjectCommandInput>): Promise<string>;
14
+ getFile(key: string): Promise<Buffer>;
15
+ putFile(fileContent: Buffer, key: string): Promise<any>;
16
+ deleteFile(key: string): Promise<void>;
17
+ private streamToBuffer;
18
+ copyFile(oldKey: string, newKey: string): Promise<UploadedFile>;
19
+ }
20
+ //# sourceMappingURL=s3.storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3.storage.d.ts","sourceRoot":"","sources":["../../../../../../packages/nest-file-storage/src/lib/storage/s3.storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,qBAAqB,EAAM,MAAM,oBAAoB,CAAC;AAIlF,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAMvC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGnE,qBAAa,SAAU,YAAW,aAAa,EAAE,OAAO;IAMxC,OAAO,CAAC,OAAO;IAJ3B,OAAO,CAAC,EAAE,CAAK;IACf,OAAO,CAAC,gBAAgB,CAAqE;IAC7F,OAAO,CAAC,gBAAgB,CAAqE;gBAEzE,OAAO,EAAE,gBAAgB;IAmBvC,WAAW,CACb,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EACzB,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC;IAkChB,WAAW,CACP,IAAI,EAAE,GAAG,EACT,IAAI,EAAE,GAAG,EACT,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,GAClC,IAAI;IAYP,MAAM,CAAC,GAAG,EAAE,MAAM;IAOZ,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAezF,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA8BrC,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IA0CvD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAmB9B,cAAc;IAQtB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CA4BxE"}
@@ -0,0 +1,9 @@
1
+ import { FileStorageEnum, StorageOptions } from './types';
2
+ import { StorageEngine } from 'multer';
3
+ import { Storage } from './types';
4
+ export declare class StorageFactory {
5
+ private static storageInstances;
6
+ static createStorage(storageType: FileStorageEnum, options: StorageOptions): Promise<StorageEngine & Storage>;
7
+ static clearCache(): void;
8
+ }
9
+ //# sourceMappingURL=storage.factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.factory.d.ts","sourceRoot":"","sources":["../../../../../packages/nest-file-storage/src/lib/storage.factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,eAAe,EAAyC,cAAc,EAAE,MAAM,SAAS,CAAC;AACtH,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAA8C;WAEhE,aAAa,CAAC,WAAW,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC;IA+CnH,MAAM,CAAC,UAAU;CAGpB"}
@@ -1,20 +1,16 @@
1
1
  import { ModuleMetadata, Type } from '@nestjs/common';
2
2
  import { Request } from 'express';
3
-
4
-
5
- export enum FileStorageEnum {
6
- LOCAL = 'local',
7
- S3 = 's3',
8
- AZURE = 'azure',
3
+ export declare enum FileStorageEnum {
4
+ LOCAL = "local",
5
+ S3 = "s3",
6
+ AZURE = "azure"
9
7
  }
10
-
11
8
  export interface FileStorageOptions {
12
9
  prefix?: string;
13
- fileName?: (file: any, req: Request) => string; // Custom file key
14
- fileDist?: (file: any, req: Request) => string; // Custom file dist
10
+ fileName?: (file: any, req: Request) => string;
11
+ fileDist?: (file: any, req: Request) => string;
15
12
  transformUploadedFileObject?: (file: any) => any;
16
13
  }
17
-
18
14
  export interface S3StorageOptions extends FileStorageOptions {
19
15
  accessKeyId: string;
20
16
  secretAccessKey: string;
@@ -23,36 +19,31 @@ export interface S3StorageOptions extends FileStorageOptions {
23
19
  endpoint?: string;
24
20
  cloudFrontUrl?: string;
25
21
  }
26
-
27
22
  export interface LocalStorageOptions extends FileStorageOptions {
28
23
  rootPath: string;
29
24
  baseUrl: string;
30
25
  }
31
-
32
26
  export interface AzureStorageOptions extends FileStorageOptions {
33
27
  account: string;
34
28
  accountKey: string;
35
29
  container: string;
36
30
  }
37
-
38
31
  export type StorageOptions = S3StorageOptions | AzureStorageOptions | LocalStorageOptions;
39
-
40
- // Define discriminated union types - Configuration-based approach
41
- export type FileStorageConfigOptions =
42
- | { storage: FileStorageEnum.LOCAL; localConfig: LocalStorageOptions; }
43
- | { storage: FileStorageEnum.S3; s3Config: S3StorageOptions; }
44
- | { storage: FileStorageEnum.AZURE; azureConfig: AzureStorageOptions; };
45
-
46
- // Class factory approach - for direct storage instance usage
32
+ export type FileStorageConfigOptions = {
33
+ storage: FileStorageEnum.LOCAL;
34
+ localConfig: LocalStorageOptions;
35
+ } | {
36
+ storage: FileStorageEnum.S3;
37
+ s3Config: S3StorageOptions;
38
+ } | {
39
+ storage: FileStorageEnum.AZURE;
40
+ azureConfig: AzureStorageOptions;
41
+ };
47
42
  export interface FileStorageClassOptions {
48
43
  storageFactory: () => Promise<new (...args: any[]) => Storage> | (new (...args: any[]) => Storage);
49
44
  options?: any;
50
45
  }
51
-
52
- // Combined module options
53
46
  export type FileStorageModuleOptions = FileStorageConfigOptions | FileStorageClassOptions;
54
-
55
-
56
47
  export interface FileStorageAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
57
48
  /**
58
49
  * The `useExisting` syntax allows you to create aliases for existing providers.
@@ -72,26 +63,22 @@ export interface FileStorageAsyncOptions extends Pick<ModuleMetadata, 'imports'>
72
63
  */
73
64
  inject?: any[];
74
65
  }
75
-
76
66
  export interface FileStorageOptionsFactory {
77
67
  createFileStorageOptions(): Promise<FileStorageModuleOptions> | FileStorageModuleOptions;
78
68
  }
79
-
80
-
81
69
  export interface UploadedFile {
82
70
  fieldName?: string;
83
71
  fieldname?: string;
84
72
  fileName: string;
85
- originalName: string; // original file name
86
- size: number; // files in bytes
73
+ originalName: string;
74
+ size: number;
87
75
  mimetype?: string;
88
76
  buffer?: Buffer;
89
- key: string; // path of the file in storage
90
- url: string; // file public url
91
- fullPath: string; // Full path of the file
77
+ key: string;
78
+ url: string;
79
+ fullPath: string;
92
80
  encoding?: string;
93
81
  }
94
-
95
82
  export interface Storage {
96
83
  getFile(key: string): Promise<Buffer> | Buffer;
97
84
  deleteFile(key: string): Promise<void> | void;
@@ -99,5 +86,6 @@ export interface Storage {
99
86
  path?(filePath: string): Promise<string> | string;
100
87
  getUrl(key: string): Promise<string> | string;
101
88
  getSignedUrl?(key: string, options: any): Promise<string> | string;
102
- copyFile(oldKey: string, newKey: string): Promise<UploadedFile>
89
+ copyFile(oldKey: string, newKey: string): Promise<UploadedFile>;
103
90
  }
91
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../packages/nest-file-storage/src/lib/types.ts"],"names":[],"mappings":"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"}
package/eslint.config.mjs DELETED
@@ -1,22 +0,0 @@
1
- import baseConfig from '../../eslint.base.config';
2
-
3
- export default [
4
- ...baseConfig,
5
- {
6
- files: ['**/*.json'],
7
- rules: {
8
- '@nx/dependency-checks': [
9
- 'error',
10
- {
11
- ignoredFiles: ['{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}'],
12
- },
13
- ],
14
- },
15
- languageOptions: {
16
- parser: await import('jsonc-eslint-parser'),
17
- },
18
- },
19
- {
20
- ignores: ['**/out-tsc'],
21
- },
22
- ];
package/jest.config.ts DELETED
@@ -1,10 +0,0 @@
1
- export default {
2
- displayName: 'nest-file-storage',
3
- preset: '../../jest.preset.js',
4
- testEnvironment: 'node',
5
- transform: {
6
- '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
7
- },
8
- moduleFileExtensions: ['ts', 'js', 'html'],
9
- coverageDirectory: '../../coverage/packages/nest-file-storage',
10
- };
package/project.json DELETED
@@ -1,38 +0,0 @@
1
- {
2
- "name": "nest-file-storage",
3
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
- "sourceRoot": "packages/nest-file-storage/src",
5
- "projectType": "library",
6
- "release": {
7
- "version": {
8
- "manifestRootsToUpdate": [
9
- "dist/{projectRoot}"
10
- ],
11
- "currentVersionResolver": "git-tag",
12
- "fallbackCurrentVersionResolver": "disk"
13
- }
14
- },
15
- "tags": [],
16
- "targets": {
17
- "build": {
18
- "executor": "@nx/js:tsc",
19
- "outputs": [
20
- "{options.outputPath}"
21
- ],
22
- "options": {
23
- "outputPath": "dist/packages/nest-file-storage",
24
- "tsConfig": "packages/nest-file-storage/tsconfig.lib.json",
25
- "packageJson": "packages/nest-file-storage/package.json",
26
- "main": "packages/nest-file-storage/src/index.ts",
27
- "assets": [
28
- "packages/nest-file-storage/*.md"
29
- ]
30
- }
31
- },
32
- "nx-release-publish": {
33
- "options": {
34
- "packageRoot": "dist/{projectRoot}"
35
- }
36
- }
37
- }
38
- }
@@ -1 +0,0 @@
1
- export const FILE_STORAGE_OPTIONS = 'FileStorageOptions';
@@ -1,36 +0,0 @@
1
- import { StorageFactory } from './storage.factory';
2
- import { FileStorageEnum, FileStorageModuleOptions, FileStorageConfigOptions, FileStorageClassOptions } from './types';
3
-
4
-
5
- export class FileStorageService {
6
-
7
- private static options: FileStorageModuleOptions; // ✅ Static global property
8
-
9
- static setOptions(options: FileStorageModuleOptions) {
10
- FileStorageService.options = options;
11
- }
12
-
13
- static getOptions(): FileStorageModuleOptions {
14
- return FileStorageService.options;
15
- }
16
-
17
- static async getStorage(storageType?: FileStorageEnum) {
18
- const options = this.getOptions();
19
-
20
- // Check if it's a class factory approach
21
- if ('storageFactory' in options) {
22
- const classOptions = options as FileStorageClassOptions;
23
- const StorageClass = await classOptions.storageFactory();
24
- return new StorageClass(classOptions.options);
25
- }
26
-
27
- // Configuration-based approach
28
- const configOptions = options as FileStorageConfigOptions;
29
- if (!storageType) {
30
- storageType = configOptions.storage;
31
- }
32
- const config = (configOptions as any)[`Config`];
33
- return await StorageFactory.createStorage(storageType, config);
34
- }
35
-
36
- }
@@ -1,174 +0,0 @@
1
- import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
2
- import { Request } from 'express';
3
- import multer from 'multer';
4
- import { Observable } from 'rxjs';
5
-
6
- import { FileStorageService } from '../file-storage.service';
7
- import { StorageFactory } from '../storage.factory';
8
- import { FileStorageEnum, StorageOptions, FileStorageConfigOptions, UploadedFile } from '../types';
9
-
10
-
11
- export type FileUploadConfig = {
12
- type: 'single' | 'array' | 'fields';
13
- fieldName?: string;
14
- maxCount?: number;
15
- fields?: { name: string; maxCount?: number }[];
16
- };
17
-
18
- export type FileStorageInterceptorOptions = {
19
- fileName?: (file: any, req?: Request) => string;
20
- fileDist?: (file: any, req?: Request) => string;
21
- prefix?: string;
22
- storageType?: FileStorageEnum;
23
- storageOptions?: StorageOptions;
24
-
25
- // File mapping callback - user defines what to return (defaults to file.key)
26
- mapToRequestBody?: (file: any, fieldName: string, req?: Request) => any;
27
- };
28
-
29
- // Helper function to map file object
30
- function mapFileObject(file: any) {
31
- return {
32
- fieldName: file.fieldname,
33
- originalName: file.originalname,
34
- fileName: file.filename,
35
- mimetype: file.mimetype,
36
- size: file.size,
37
- key: (file as any).key,
38
- path: (file as any).path,
39
- url: (file as any).url,
40
- encoding: file.encoding,
41
- fullPath: (file as any).fullPath
42
- } as unknown as UploadedFile;
43
- }
44
-
45
- // Helper function to apply file mapping with callback
46
- function applyFileKeyMapping(
47
- request: Request,
48
- fileConfig: FileUploadConfig,
49
- interceptorOptions?: FileStorageInterceptorOptions
50
- ): void {
51
- // Default callback returns the file key
52
- const mapCallback = interceptorOptions?.mapToRequestBody || ((file: any) => {
53
- // For arrays, return array of keys
54
- if (Array.isArray(file)) {
55
- return file.map(f => f.key);
56
- }
57
- // For single file, return the key
58
- return file.key;
59
- });
60
-
61
- if (fileConfig.type === 'single') {
62
- const file = request.file;
63
- if (file) {
64
- const fieldName = fileConfig.fieldName || 'file';
65
- const mappedFile = mapFileObject(file);
66
- request.body[fieldName] = mapCallback(mappedFile, fieldName, request);
67
- }
68
- } else if (fileConfig.type === 'array') {
69
- const files = request.files as Express.Multer.File[];
70
- if (files && files.length > 0) {
71
- const fieldName = fileConfig.fieldName || 'files';
72
- const mappedFiles = files.map(file => mapFileObject(file));
73
- request.body[fieldName] = mapCallback(mappedFiles, fieldName, request);
74
- }
75
- } else if (fileConfig.type === 'fields') {
76
- const files = request.files as { [fieldname: string]: Express.Multer.File[] };
77
- if (files) {
78
- Object.keys(files).forEach(fieldName => {
79
- const mappedFiles = files[fieldName].map(file => mapFileObject(file));
80
- request.body[fieldName] = mapCallback(mappedFiles, fieldName, request);
81
- });
82
- }
83
- }
84
- }
85
-
86
- /**
87
- * Function-based interceptor that accepts storage options dynamically.
88
- */
89
- export function FileStorageInterceptor(
90
- fileConfig: FileUploadConfig | string,
91
- interceptorOptions?: FileStorageInterceptorOptions,
92
- ): NestInterceptor {
93
- if (typeof fileConfig === 'string') {
94
- fileConfig = {
95
- type: 'single',
96
- fieldName: fileConfig,
97
- };
98
- }
99
-
100
- return {
101
- async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>> {
102
- const options = FileStorageService.getOptions();
103
- const request = context.switchToHttp().getRequest();
104
- const response = context.switchToHttp().getResponse();
105
-
106
- // Determine storage type - handle both config approaches
107
- let storageType: FileStorageEnum;
108
- let storageConfig: any;
109
-
110
- if ('storage' in options) {
111
- // Configuration-based approach
112
- const configOptions = options as FileStorageConfigOptions;
113
- storageType = interceptorOptions?.storageType ?? configOptions.storage;
114
- storageConfig = (configOptions as any)[`Config`];
115
- } else {
116
- // Class factory approach - default to LOCAL
117
- storageType = interceptorOptions?.storageType ?? FileStorageEnum.LOCAL;
118
- storageConfig = {};
119
- }
120
-
121
- const storageOptions = {
122
- ...storageConfig,
123
- ...(interceptorOptions?.storageOptions || {}),
124
- fileName: interceptorOptions?.fileName || storageConfig?.fileName,
125
- fileDist: (file: any, req: any) => {
126
- if (interceptorOptions?.fileDist) {
127
- return interceptorOptions.fileDist(file, req);
128
- }
129
- return storageConfig?.fileDist?.(file, req);
130
- },
131
- prefix: interceptorOptions?.prefix || storageConfig?.prefix,
132
- };
133
-
134
- // Create storage instance dynamically
135
- const storage = await StorageFactory.createStorage(storageType, storageOptions);
136
- const multerInstance = multer({ storage });
137
-
138
- // Multer setup based on fileConfig
139
- let multerMiddleware;
140
- switch (fileConfig.type) {
141
- case 'single':
142
- if (!fileConfig.fieldName) {
143
- throw new Error('fieldName is required for single file upload.');
144
- }
145
- multerMiddleware = multerInstance.single(fileConfig.fieldName);
146
- break;
147
- case 'array':
148
- if (!fileConfig.fieldName) {
149
- throw new Error('fieldName is required for multiple file upload.');
150
- }
151
- multerMiddleware = multerInstance.array(fileConfig.fieldName, fileConfig.maxCount);
152
- break;
153
- case 'fields':
154
- if (!fileConfig.fields || !Array.isArray(fileConfig.fields)) {
155
- throw new Error('fields array is required for multiple fields file upload.');
156
- }
157
- multerMiddleware = multerInstance.fields(fileConfig.fields);
158
- break;
159
- default:
160
- throw new Error('Invalid file upload type. Use "single", "array", or "fields".');
161
- }
162
-
163
- // Execute Multer middleware
164
- await new Promise((resolve, reject) => {
165
- multerMiddleware(request, response, (err) => (err ? reject(err) : resolve(true)));
166
- });
167
-
168
- // Apply file key mapping after multer processing
169
- applyFileKeyMapping(request, fileConfig, interceptorOptions);
170
-
171
- return next.handle();
172
- }
173
- };
174
- }