express-storage 1.0.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 (48) hide show
  1. package/README.md +519 -348
  2. package/dist/drivers/azure.driver.d.ts +88 -0
  3. package/dist/drivers/azure.driver.d.ts.map +1 -0
  4. package/dist/drivers/azure.driver.js +367 -0
  5. package/dist/drivers/azure.driver.js.map +1 -0
  6. package/dist/drivers/base.driver.d.ts +125 -24
  7. package/dist/drivers/base.driver.d.ts.map +1 -1
  8. package/dist/drivers/base.driver.js +248 -62
  9. package/dist/drivers/base.driver.js.map +1 -1
  10. package/dist/drivers/gcs.driver.d.ts +60 -13
  11. package/dist/drivers/gcs.driver.d.ts.map +1 -1
  12. package/dist/drivers/gcs.driver.js +242 -41
  13. package/dist/drivers/gcs.driver.js.map +1 -1
  14. package/dist/drivers/local.driver.d.ts +89 -12
  15. package/dist/drivers/local.driver.d.ts.map +1 -1
  16. package/dist/drivers/local.driver.js +533 -45
  17. package/dist/drivers/local.driver.js.map +1 -1
  18. package/dist/drivers/s3.driver.d.ts +64 -13
  19. package/dist/drivers/s3.driver.d.ts.map +1 -1
  20. package/dist/drivers/s3.driver.js +269 -41
  21. package/dist/drivers/s3.driver.js.map +1 -1
  22. package/dist/factory/driver.factory.d.ts +35 -29
  23. package/dist/factory/driver.factory.d.ts.map +1 -1
  24. package/dist/factory/driver.factory.js +119 -59
  25. package/dist/factory/driver.factory.js.map +1 -1
  26. package/dist/index.d.ts +23 -22
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +26 -46
  29. package/dist/index.js.map +1 -1
  30. package/dist/storage-manager.d.ts +205 -52
  31. package/dist/storage-manager.d.ts.map +1 -1
  32. package/dist/storage-manager.js +644 -73
  33. package/dist/storage-manager.js.map +1 -1
  34. package/dist/types/storage.types.d.ts +243 -18
  35. package/dist/types/storage.types.d.ts.map +1 -1
  36. package/dist/utils/config.utils.d.ts +28 -4
  37. package/dist/utils/config.utils.d.ts.map +1 -1
  38. package/dist/utils/config.utils.js +121 -47
  39. package/dist/utils/config.utils.js.map +1 -1
  40. package/dist/utils/file.utils.d.ts +111 -14
  41. package/dist/utils/file.utils.d.ts.map +1 -1
  42. package/dist/utils/file.utils.js +215 -32
  43. package/dist/utils/file.utils.js.map +1 -1
  44. package/package.json +51 -27
  45. package/dist/drivers/oci.driver.d.ts +0 -37
  46. package/dist/drivers/oci.driver.d.ts.map +0 -1
  47. package/dist/drivers/oci.driver.js +0 -84
  48. package/dist/drivers/oci.driver.js.map +0 -1
@@ -1,75 +1,228 @@
1
- import { FileUploadResult, PresignedUrlResult, FileInput, StorageConfig } from './types/storage.types.js';
2
- /**
3
- * Main storage manager class
4
- */
1
+ import { FileUploadResult, DeleteResult, PresignedUrlResult, FileInput, StorageConfig, StorageOptions, FileValidationOptions, StorageDriver, BlobValidationOptions, BlobValidationResult, ListFilesResult, UploadOptions, FileMetadata } from './types/storage.types.js';
5
2
  export declare class StorageManager {
6
3
  private driver;
7
4
  private config;
8
- private isInitialized;
9
- constructor();
10
- /**
11
- * Initialize storage manager with custom configuration
12
- */
13
- static initialize(config?: Partial<StorageConfig>): StorageManager;
14
- /**
15
- * Upload a single file
16
- */
17
- uploadFile(file: Express.Multer.File): Promise<FileUploadResult>;
18
- /**
19
- * Upload multiple files
20
- */
21
- uploadFiles(files: Express.Multer.File[]): Promise<FileUploadResult[]>;
22
- /**
23
- * Upload files with input type detection
24
- */
25
- upload(input: FileInput): Promise<FileUploadResult | FileUploadResult[]>;
26
- /**
27
- * Generate upload URL for presigned uploads
5
+ private logger;
6
+ private rateLimiter;
7
+ constructor(options?: StorageOptions);
8
+ /**
9
+ * Builds the final configuration by merging environment variables with any
10
+ * options you passed in. Your explicit options always win over env vars.
11
+ */
12
+ private buildConfig;
13
+ /**
14
+ * Uploads a single file to your configured storage.
15
+ *
16
+ * This is the method you'll use most often. It handles everything:
17
+ * validation, unique naming, and the actual upload.
18
+ *
19
+ * @param file - The file from Multer (req.file)
20
+ * @param validation - Optional rules like max size and allowed types
21
+ * @param uploadOptions - Optional metadata, cache headers, etc.
22
+ *
23
+ * @example
24
+ * // Simple upload
25
+ * const result = await storage.uploadFile(req.file);
26
+ *
27
+ * // With validation (reject files over 5MB or wrong type)
28
+ * const result = await storage.uploadFile(req.file, {
29
+ * maxSize: 5 * 1024 * 1024,
30
+ * allowedMimeTypes: ['image/jpeg', 'image/png']
31
+ * });
32
+ *
33
+ * // With custom metadata
34
+ * const result = await storage.uploadFile(req.file, undefined, {
35
+ * metadata: { uploadedBy: 'user123' },
36
+ * cacheControl: 'max-age=31536000'
37
+ * });
38
+ */
39
+ uploadFile(file: Express.Multer.File, validation?: FileValidationOptions, uploadOptions?: UploadOptions): Promise<FileUploadResult>;
40
+ /**
41
+ * Uploads multiple files at once.
42
+ *
43
+ * Files are processed in parallel (up to 10 at a time) for speed,
44
+ * but each file gets its own result — so one failure doesn't stop the others.
45
+ */
46
+ uploadFiles(files: Express.Multer.File[], validation?: FileValidationOptions, uploadOptions?: UploadOptions): Promise<FileUploadResult[]>;
47
+ /**
48
+ * Smart upload that handles both single files and arrays.
49
+ * Pass in what you have and it figures out the rest.
50
+ */
51
+ upload(input: FileInput, validation?: FileValidationOptions, uploadOptions?: UploadOptions): Promise<FileUploadResult | FileUploadResult[]>;
52
+ /**
53
+ * Creates a presigned URL that lets clients upload directly to cloud storage.
54
+ *
55
+ * This is powerful for large files — the upload goes straight to S3/GCS/Azure
56
+ * without passing through your server, saving bandwidth and processing time.
57
+ *
58
+ * The URL is time-limited and (for S3/GCS) locked to specific file constraints.
59
+ *
60
+ * Rate limiting: If you configured `rateLimit` in StorageOptions, this method
61
+ * will reject requests that exceed the limit with an error.
62
+ *
63
+ * @param fileName - What the user wants to call their file
64
+ * @param contentType - The MIME type (e.g., 'image/jpeg')
65
+ * @param fileSize - Exact size in bytes (enforced by S3/GCS, advisory for Azure)
66
+ * @param folder - Where to put the file (overrides your default BUCKET_PATH)
67
+ *
68
+ * @example
69
+ * const result = await storage.generateUploadUrl('photo.jpg', 'image/jpeg', 12345);
70
+ * // Give result.uploadUrl to your frontend
71
+ * // Save result.reference — you'll need it to view or delete the file later
72
+ */
73
+ generateUploadUrl(fileName: string, contentType?: string, fileSize?: number, folder?: string): Promise<PresignedUrlResult>;
74
+ /**
75
+ * Combines folder and filename into a full path.
76
+ * Handles edge cases like leading/trailing slashes.
77
+ */
78
+ private buildFilePath;
79
+ /**
80
+ * Checks folder paths for security issues.
81
+ * Blocks path traversal attempts and other sneaky tricks.
82
+ */
83
+ private validateFolderPath;
84
+ /**
85
+ * Checks if a string looks like a valid MIME type.
86
+ */
87
+ private isValidMimeType;
88
+ /**
89
+ * Converts bytes to a human-readable string like "5.2 MB".
90
+ */
91
+ private formatBytes;
92
+ /**
93
+ * Creates a presigned URL for viewing/downloading an existing file.
94
+ *
95
+ * Rate limiting: If configured, this counts toward the presigned URL rate limit.
96
+ *
97
+ * @param reference - The full path you got from generateUploadUrl
98
+ */
99
+ generateViewUrl(reference: string): Promise<PresignedUrlResult>;
100
+ /**
101
+ * Verifies that a presigned upload actually happened and the file is valid.
102
+ *
103
+ * For Azure, this is essential — Azure doesn't enforce file constraints at
104
+ * the URL level, so we check the actual blob properties here.
105
+ *
106
+ * For S3/GCS, this confirms the file exists and optionally validates it.
107
+ *
108
+ * @param reference - The file path from generateUploadUrl
109
+ * @param options - Expected content type and size to validate against
110
+ *
111
+ * @example
112
+ * // After the client uploads, verify everything looks right
113
+ * const result = await storage.validateAndConfirmUpload(reference, {
114
+ * expectedContentType: 'image/jpeg',
115
+ * expectedFileSize: 12345
116
+ * });
117
+ */
118
+ validateAndConfirmUpload(reference: string, options?: BlobValidationOptions): Promise<BlobValidationResult>;
119
+ /**
120
+ * Returns true if you're using Azure presigned mode.
121
+ *
122
+ * This is your hint that you MUST call validateAndConfirmUpload()
123
+ * after presigned uploads — Azure doesn't enforce constraints otherwise.
124
+ */
125
+ requiresPostUploadValidation(): boolean;
126
+ /**
127
+ * Creates presigned upload URLs for multiple files at once.
128
+ * Great for batch uploads or when letting users select multiple files.
129
+ *
130
+ * @param files - Array of filenames (strings) or file metadata objects
131
+ * @param folder - Optional folder to put all files in
132
+ */
133
+ generateUploadUrls(files: (string | FileMetadata)[], folder?: string): Promise<PresignedUrlResult[]>;
134
+ /**
135
+ * Creates presigned view URLs for multiple files at once.
136
+ * Useful when displaying a gallery or list of downloadable files.
137
+ */
138
+ generateViewUrls(references: string[]): Promise<PresignedUrlResult[]>;
139
+ /**
140
+ * Deletes a single file from storage.
141
+ *
142
+ * @param reference - The full path from uploadFile result or generateUploadUrl
143
+ * @returns true if deleted, false if not found
144
+ */
145
+ deleteFile(reference: string): Promise<boolean>;
146
+ /**
147
+ * Deletes multiple files at once.
148
+ * Returns detailed results so you know exactly what succeeded and what failed.
149
+ */
150
+ deleteFiles(references: string[]): Promise<DeleteResult[]>;
151
+ /**
152
+ * Lists files in your storage with optional filtering and pagination.
153
+ *
154
+ * @param prefix - Only show files starting with this path (e.g., 'uploads/2026/')
155
+ * @param maxResults - How many files to return per page (default: 1000)
156
+ * @param continuationToken - Pass the nextToken from a previous response to get the next page
157
+ *
158
+ * @example
159
+ * // Get all files
160
+ * const result = await storage.listFiles();
161
+ *
162
+ * // Get files in a specific folder
163
+ * const result = await storage.listFiles('users/123/');
164
+ *
165
+ * // Paginate through large results
166
+ * let result = await storage.listFiles(undefined, 100);
167
+ * while (result.nextToken) {
168
+ * result = await storage.listFiles(undefined, 100, result.nextToken);
169
+ * }
28
170
  */
29
- generateUploadUrl(fileName: string): Promise<PresignedUrlResult>;
171
+ listFiles(prefix?: string, maxResults?: number, continuationToken?: string): Promise<ListFilesResult>;
30
172
  /**
31
- * Generate view URL for presigned uploads
173
+ * Returns a copy of the current configuration.
174
+ *
175
+ * WARNING: This includes sensitive credentials like AWS keys, Azure connection strings, etc.
176
+ * Use getSafeConfig() instead if you're logging or exposing this to users.
32
177
  */
33
- generateViewUrl(fileName: string): Promise<PresignedUrlResult>;
34
- /**
35
- * Generate multiple upload URLs
36
- */
37
- generateUploadUrls(fileNames: string[]): Promise<PresignedUrlResult[]>;
38
- /**
39
- * Generate multiple view URLs
40
- */
41
- generateViewUrls(fileNames: string[]): Promise<PresignedUrlResult[]>;
42
- /**
43
- * Delete a single file
44
- */
45
- deleteFile(fileName: string): Promise<boolean>;
178
+ getConfig(): StorageConfig;
46
179
  /**
47
- * Delete multiple files
180
+ * Returns a copy of the configuration with sensitive values masked.
181
+ * Safe for logging, debugging, or displaying to users.
182
+ *
183
+ * Masked fields: awsAccessKey, awsSecretKey, azureConnectionString,
184
+ * azureAccountKey, gcsCredentials
48
185
  */
49
- deleteFiles(fileNames: string[]): Promise<boolean[]>;
186
+ getSafeConfig(): StorageConfig;
50
187
  /**
51
- * Get current configuration
188
+ * Returns which storage driver is currently active.
52
189
  */
53
- getConfig(): StorageConfig;
190
+ getDriverType(): StorageDriver;
54
191
  /**
55
- * Get current driver type
192
+ * Returns true if the driver operates in presigned mode.
193
+ *
194
+ * In presigned mode, upload() returns URLs instead of uploading directly.
195
+ * All cloud drivers can generate presigned URLs via generateUploadUrl()
196
+ * regardless of this setting.
56
197
  */
57
- getDriverType(): string;
198
+ isPresignedUploadMode(): boolean;
58
199
  /**
59
- * Check if presigned URLs are supported
200
+ * Returns rate limit status information.
201
+ * Returns null if rate limiting is not configured.
202
+ *
203
+ * @example
204
+ * const status = storage.getRateLimitStatus();
205
+ * if (status && status.remainingRequests === 0) {
206
+ * console.log(`Rate limited. Resets in ${status.resetTimeMs}ms`);
207
+ * }
60
208
  */
61
- isPresignedSupported(): boolean;
209
+ getRateLimitStatus(): {
210
+ remainingRequests: number;
211
+ resetTimeMs: number;
212
+ } | null;
62
213
  /**
63
- * Get available drivers
214
+ * Returns all available storage drivers.
64
215
  */
65
- static getAvailableDrivers(): string[];
216
+ static getAvailableDrivers(): StorageDriver[];
66
217
  /**
67
- * Clear driver cache
218
+ * Clears the internal driver cache.
219
+ * Useful in tests or when you've changed credentials.
68
220
  */
69
221
  static clearCache(): void;
70
222
  /**
71
- * Ensure storage manager is initialized
223
+ * Validates a file against the provided rules.
224
+ * Returns an error message if validation fails, null if it passes.
72
225
  */
73
- private ensureInitialized;
226
+ private validateFile;
74
227
  }
75
228
  //# sourceMappingURL=storage-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage-manager.d.ts","sourceRoot":"","sources":["../src/storage-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,gBAAgB,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAI1H;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,aAAa,CAAkB;;IAevC;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,cAAc;IAsBlE;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAKtE;;OAEG;IACG,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAK5E;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,gBAAgB,GAAG,gBAAgB,EAAE,CAAC;IAU9E;;OAEG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAKtE;;OAEG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAKpE;;OAEG;IACG,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAK5E;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAK1E;;OAEG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpD;;OAEG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAK1D;;OAEG;IACH,SAAS,IAAI,aAAa;IAI1B;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,oBAAoB,IAAI,OAAO;IAI/B;;OAEG;IACH,MAAM,CAAC,mBAAmB,IAAI,MAAM,EAAE;IAItC;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,IAAI;IAIzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAK1B"}
1
+ {"version":3,"file":"storage-manager.d.ts","sourceRoot":"","sources":["../src/storage-manager.ts"],"names":[],"mappings":"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"}