express-storage 2.0.2 → 3.0.0

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 (177) hide show
  1. package/README.md +366 -34
  2. package/dist/cjs/config/index.d.ts +10 -0
  3. package/dist/cjs/config/index.d.ts.map +1 -0
  4. package/dist/cjs/config/index.js +19 -0
  5. package/dist/cjs/config/index.js.map +1 -0
  6. package/dist/cjs/drivers/azure.driver.d.ts +73 -0
  7. package/dist/cjs/drivers/azure.driver.d.ts.map +1 -0
  8. package/dist/cjs/drivers/azure.driver.js +390 -0
  9. package/dist/cjs/drivers/azure.driver.js.map +1 -0
  10. package/dist/cjs/drivers/base.driver.d.ts +136 -0
  11. package/dist/cjs/drivers/base.driver.d.ts.map +1 -0
  12. package/dist/cjs/drivers/base.driver.js +357 -0
  13. package/dist/cjs/drivers/base.driver.js.map +1 -0
  14. package/dist/{drivers → cjs/drivers}/gcs.driver.d.ts +20 -38
  15. package/dist/cjs/drivers/gcs.driver.d.ts.map +1 -0
  16. package/dist/cjs/drivers/gcs.driver.js +343 -0
  17. package/dist/cjs/drivers/gcs.driver.js.map +1 -0
  18. package/dist/cjs/drivers/index.d.ts +15 -0
  19. package/dist/cjs/drivers/index.d.ts.map +1 -0
  20. package/dist/cjs/drivers/index.js +26 -0
  21. package/dist/cjs/drivers/index.js.map +1 -0
  22. package/dist/cjs/drivers/local.driver.d.ts +86 -0
  23. package/dist/cjs/drivers/local.driver.d.ts.map +1 -0
  24. package/dist/cjs/drivers/local.driver.js +556 -0
  25. package/dist/cjs/drivers/local.driver.js.map +1 -0
  26. package/dist/{drivers → cjs/drivers}/s3.driver.d.ts +19 -39
  27. package/dist/cjs/drivers/s3.driver.d.ts.map +1 -0
  28. package/dist/cjs/drivers/s3.driver.js +400 -0
  29. package/dist/cjs/drivers/s3.driver.js.map +1 -0
  30. package/dist/cjs/factory/driver.factory.d.ts +43 -0
  31. package/dist/cjs/factory/driver.factory.d.ts.map +1 -0
  32. package/dist/cjs/factory/driver.factory.js +101 -0
  33. package/dist/cjs/factory/driver.factory.js.map +1 -0
  34. package/dist/cjs/index.d.ts +26 -0
  35. package/dist/cjs/index.d.ts.map +1 -0
  36. package/dist/cjs/index.js +31 -0
  37. package/dist/cjs/index.js.map +1 -0
  38. package/dist/cjs/package.json +1 -0
  39. package/dist/cjs/storage-manager.d.ts +210 -0
  40. package/dist/cjs/storage-manager.d.ts.map +1 -0
  41. package/dist/cjs/storage-manager.js +649 -0
  42. package/dist/cjs/storage-manager.js.map +1 -0
  43. package/dist/cjs/types/storage.types.d.ts +438 -0
  44. package/dist/cjs/types/storage.types.d.ts.map +1 -0
  45. package/dist/cjs/types/storage.types.js +3 -0
  46. package/dist/cjs/types/storage.types.js.map +1 -0
  47. package/dist/cjs/utils/config.utils.d.ts.map +1 -0
  48. package/dist/cjs/utils/config.utils.js +213 -0
  49. package/dist/cjs/utils/config.utils.js.map +1 -0
  50. package/dist/{utils → cjs/utils}/file.utils.d.ts +62 -8
  51. package/dist/cjs/utils/file.utils.d.ts.map +1 -0
  52. package/dist/cjs/utils/file.utils.js +464 -0
  53. package/dist/cjs/utils/file.utils.js.map +1 -0
  54. package/dist/cjs/utils/index.d.ts +12 -0
  55. package/dist/cjs/utils/index.d.ts.map +1 -0
  56. package/dist/cjs/utils/index.js +36 -0
  57. package/dist/cjs/utils/index.js.map +1 -0
  58. package/dist/cjs/utils/rate-limiter.d.ts +40 -0
  59. package/dist/cjs/utils/rate-limiter.d.ts.map +1 -0
  60. package/dist/cjs/utils/rate-limiter.js +87 -0
  61. package/dist/cjs/utils/rate-limiter.js.map +1 -0
  62. package/dist/esm/config/index.d.ts +10 -0
  63. package/dist/esm/config/index.d.ts.map +1 -0
  64. package/dist/esm/config/index.js +10 -0
  65. package/dist/esm/config/index.js.map +1 -0
  66. package/dist/esm/drivers/azure.driver.d.ts +73 -0
  67. package/dist/esm/drivers/azure.driver.d.ts.map +1 -0
  68. package/dist/esm/drivers/azure.driver.js +353 -0
  69. package/dist/esm/drivers/azure.driver.js.map +1 -0
  70. package/dist/esm/drivers/base.driver.d.ts +136 -0
  71. package/dist/esm/drivers/base.driver.d.ts.map +1 -0
  72. package/dist/esm/drivers/base.driver.js +350 -0
  73. package/dist/esm/drivers/base.driver.js.map +1 -0
  74. package/dist/esm/drivers/gcs.driver.d.ts +68 -0
  75. package/dist/esm/drivers/gcs.driver.d.ts.map +1 -0
  76. package/dist/esm/drivers/gcs.driver.js +306 -0
  77. package/dist/esm/drivers/gcs.driver.js.map +1 -0
  78. package/dist/esm/drivers/index.d.ts +15 -0
  79. package/dist/esm/drivers/index.d.ts.map +1 -0
  80. package/dist/esm/drivers/index.js +15 -0
  81. package/dist/esm/drivers/index.js.map +1 -0
  82. package/dist/esm/drivers/local.driver.d.ts +86 -0
  83. package/dist/esm/drivers/local.driver.d.ts.map +1 -0
  84. package/dist/esm/drivers/local.driver.js +549 -0
  85. package/dist/esm/drivers/local.driver.js.map +1 -0
  86. package/dist/esm/drivers/s3.driver.d.ts +69 -0
  87. package/dist/esm/drivers/s3.driver.d.ts.map +1 -0
  88. package/dist/esm/drivers/s3.driver.js +363 -0
  89. package/dist/esm/drivers/s3.driver.js.map +1 -0
  90. package/dist/esm/factory/driver.factory.d.ts +43 -0
  91. package/dist/esm/factory/driver.factory.d.ts.map +1 -0
  92. package/dist/esm/factory/driver.factory.js +92 -0
  93. package/dist/esm/factory/driver.factory.js.map +1 -0
  94. package/dist/esm/index.d.ts +26 -0
  95. package/dist/esm/index.d.ts.map +1 -0
  96. package/dist/esm/index.js +26 -0
  97. package/dist/esm/index.js.map +1 -0
  98. package/dist/esm/package.json +1 -0
  99. package/dist/esm/storage-manager.d.ts +210 -0
  100. package/dist/esm/storage-manager.d.ts.map +1 -0
  101. package/dist/esm/storage-manager.js +645 -0
  102. package/dist/esm/storage-manager.js.map +1 -0
  103. package/dist/esm/types/storage.types.d.ts +438 -0
  104. package/dist/esm/types/storage.types.d.ts.map +1 -0
  105. package/dist/esm/types/storage.types.js.map +1 -0
  106. package/dist/esm/utils/config.utils.d.ts +45 -0
  107. package/dist/esm/utils/config.utils.d.ts.map +1 -0
  108. package/dist/esm/utils/config.utils.js.map +1 -0
  109. package/dist/esm/utils/file.utils.d.ts +196 -0
  110. package/dist/esm/utils/file.utils.d.ts.map +1 -0
  111. package/dist/esm/utils/file.utils.js +439 -0
  112. package/dist/esm/utils/file.utils.js.map +1 -0
  113. package/dist/esm/utils/index.d.ts +12 -0
  114. package/dist/esm/utils/index.d.ts.map +1 -0
  115. package/dist/esm/utils/index.js +11 -0
  116. package/dist/esm/utils/index.js.map +1 -0
  117. package/dist/esm/utils/rate-limiter.d.ts +40 -0
  118. package/dist/esm/utils/rate-limiter.d.ts.map +1 -0
  119. package/dist/esm/utils/rate-limiter.js +82 -0
  120. package/dist/esm/utils/rate-limiter.js.map +1 -0
  121. package/package.json +90 -52
  122. package/src/config/index.ts +17 -0
  123. package/src/drivers/azure.driver.ts +434 -0
  124. package/src/drivers/base.driver.ts +436 -0
  125. package/src/drivers/gcs.driver.ts +366 -0
  126. package/src/drivers/index.ts +15 -0
  127. package/src/drivers/local.driver.ts +626 -0
  128. package/src/drivers/s3.driver.ts +459 -0
  129. package/src/factory/driver.factory.ts +101 -0
  130. package/src/index.ts +72 -0
  131. package/src/storage-manager.ts +801 -0
  132. package/src/types/storage.types.ts +561 -0
  133. package/src/utils/config.utils.ts +229 -0
  134. package/src/utils/file.utils.ts +536 -0
  135. package/src/utils/index.ts +35 -0
  136. package/src/utils/rate-limiter.ts +94 -0
  137. package/dist/drivers/azure.driver.d.ts +0 -88
  138. package/dist/drivers/azure.driver.d.ts.map +0 -1
  139. package/dist/drivers/azure.driver.js +0 -391
  140. package/dist/drivers/azure.driver.js.map +0 -1
  141. package/dist/drivers/base.driver.d.ts +0 -170
  142. package/dist/drivers/base.driver.d.ts.map +0 -1
  143. package/dist/drivers/base.driver.js +0 -347
  144. package/dist/drivers/base.driver.js.map +0 -1
  145. package/dist/drivers/gcs.driver.d.ts.map +0 -1
  146. package/dist/drivers/gcs.driver.js +0 -354
  147. package/dist/drivers/gcs.driver.js.map +0 -1
  148. package/dist/drivers/local.driver.d.ts +0 -107
  149. package/dist/drivers/local.driver.d.ts.map +0 -1
  150. package/dist/drivers/local.driver.js +0 -621
  151. package/dist/drivers/local.driver.js.map +0 -1
  152. package/dist/drivers/s3.driver.d.ts.map +0 -1
  153. package/dist/drivers/s3.driver.js +0 -387
  154. package/dist/drivers/s3.driver.js.map +0 -1
  155. package/dist/factory/driver.factory.d.ts +0 -62
  156. package/dist/factory/driver.factory.d.ts.map +0 -1
  157. package/dist/factory/driver.factory.js +0 -177
  158. package/dist/factory/driver.factory.js.map +0 -1
  159. package/dist/index.d.ts +0 -30
  160. package/dist/index.d.ts.map +0 -1
  161. package/dist/index.js +0 -33
  162. package/dist/index.js.map +0 -1
  163. package/dist/storage-manager.d.ts +0 -228
  164. package/dist/storage-manager.d.ts.map +0 -1
  165. package/dist/storage-manager.js +0 -715
  166. package/dist/storage-manager.js.map +0 -1
  167. package/dist/types/storage.types.d.ts +0 -295
  168. package/dist/types/storage.types.d.ts.map +0 -1
  169. package/dist/types/storage.types.js.map +0 -1
  170. package/dist/utils/config.utils.d.ts.map +0 -1
  171. package/dist/utils/config.utils.js.map +0 -1
  172. package/dist/utils/file.utils.d.ts.map +0 -1
  173. package/dist/utils/file.utils.js +0 -278
  174. package/dist/utils/file.utils.js.map +0 -1
  175. /package/dist/{utils → cjs/utils}/config.utils.d.ts +0 -0
  176. /package/dist/{types → esm/types}/storage.types.js +0 -0
  177. /package/dist/{utils → esm/utils}/config.utils.js +0 -0
@@ -1,354 +0,0 @@
1
- import { Storage } from '@google-cloud/storage';
2
- import { BaseStorageDriver } from './base.driver.js';
3
- /**
4
- * GCSStorageDriver - Handles file operations with Google Cloud Storage.
5
- *
6
- * Supports two authentication methods:
7
- * 1. Service account JSON file (GCS_CREDENTIALS path)
8
- * 2. Application Default Credentials (when running on GCP)
9
- *
10
- * If you're running on GCP (Cloud Run, GKE, etc.), you usually don't need
11
- * to provide credentials — the SDK picks them up automatically.
12
- */
13
- export class GCSStorageDriver extends BaseStorageDriver {
14
- constructor(config) {
15
- super(config);
16
- this.bucketName = config.bucketName;
17
- this.projectId = config.gcsProjectId;
18
- const storageOptions = {
19
- projectId: this.projectId,
20
- };
21
- if (config.gcsCredentials) {
22
- storageOptions.keyFilename = config.gcsCredentials;
23
- }
24
- this.storage = new Storage(storageOptions);
25
- this.bucket = this.storage.bucket(this.bucketName);
26
- }
27
- /**
28
- * Uploads a file directly to GCS.
29
- * Handles both memory and disk storage from Multer.
30
- *
31
- * For large files (>100MB), uses streaming upload to reduce
32
- * memory usage and improve reliability.
33
- */
34
- async upload(file, options) {
35
- try {
36
- const validationErrors = this.validateFile(file);
37
- if (validationErrors.length > 0) {
38
- return this.createErrorResult(validationErrors.join(', '));
39
- }
40
- const fileName = this.generateFileName(file.originalname);
41
- const filePath = this.buildFilePath(fileName);
42
- const gcsFile = this.bucket.file(filePath);
43
- const metadata = {
44
- contentType: options?.contentType || file.mimetype,
45
- };
46
- if (options?.cacheControl) {
47
- metadata.cacheControl = options.cacheControl;
48
- }
49
- if (options?.contentDisposition) {
50
- metadata.contentDisposition = options.contentDisposition;
51
- }
52
- if (options?.metadata) {
53
- metadata.metadata = options.metadata;
54
- }
55
- // Use streaming upload for large files to reduce memory usage
56
- if (this.shouldUseStreaming(file)) {
57
- await this.uploadWithStream(gcsFile, file, metadata);
58
- }
59
- else {
60
- const fileContent = this.getFileContent(file);
61
- await gcsFile.save(fileContent, { metadata });
62
- }
63
- // Build the public URL with proper encoding
64
- const encodedPath = filePath.split('/').map(segment => encodeURIComponent(segment)).join('/');
65
- const fileUrl = `https://storage.googleapis.com/${this.bucketName}/${encodedPath}`;
66
- return this.createSuccessResult(filePath, fileUrl);
67
- }
68
- catch (error) {
69
- return this.createErrorResult(error instanceof Error ? error.message : 'Failed to upload file to GCS');
70
- }
71
- }
72
- /**
73
- * Uploads a large file using streaming.
74
- *
75
- * This method pipes the file stream directly to GCS, which is more
76
- * memory-efficient for large files.
77
- */
78
- async uploadWithStream(gcsFile, file, metadata) {
79
- return new Promise((resolve, reject) => {
80
- const fileStream = this.getFileStream(file);
81
- const writeStream = gcsFile.createWriteStream({
82
- metadata,
83
- resumable: true, // Enable resumable uploads for reliability
84
- });
85
- // Handle errors from the source stream (fileStream) explicitly
86
- // to ensure they propagate and don't get silently dropped
87
- fileStream.on('error', reject);
88
- fileStream
89
- .pipe(writeStream)
90
- .on('error', reject)
91
- .on('finish', resolve);
92
- });
93
- }
94
- /**
95
- * Creates a presigned URL for uploading directly to GCS.
96
- *
97
- * The URL enforces:
98
- * - Exact content type
99
- * - Exact file size (via x-goog-content-length-range header)
100
- *
101
- * Clients that try to upload different content will get a 403.
102
- */
103
- async generateUploadUrl(fileName, contentType, fileSize) {
104
- // Security: Defense-in-depth validation (StorageManager also validates)
105
- // Decode URL-encoded characters first to catch encoded traversal attempts like %2e%2e%2f
106
- let decodedFileName;
107
- try {
108
- decodedFileName = decodeURIComponent(fileName);
109
- }
110
- catch {
111
- return this.createPresignedErrorResult('Invalid fileName: malformed URL encoding');
112
- }
113
- if (decodedFileName.includes('..') || decodedFileName.includes('\0')) {
114
- return this.createPresignedErrorResult('Invalid fileName: path traversal sequences are not allowed');
115
- }
116
- try {
117
- const gcsFile = this.bucket.file(decodedFileName);
118
- const resolvedContentType = contentType || 'application/octet-stream';
119
- const expiresOn = new Date(Date.now() + (this.getPresignedUrlExpiry() * 1000));
120
- const options = {
121
- version: 'v4',
122
- action: 'write',
123
- expires: expiresOn,
124
- contentType: resolvedContentType,
125
- };
126
- // GCS enforces exact file size via this header
127
- if (fileSize !== undefined) {
128
- options.extensionHeaders = {
129
- 'x-goog-content-length-range': `${fileSize},${fileSize}`,
130
- };
131
- }
132
- const [uploadUrl] = await gcsFile.getSignedUrl(options);
133
- return this.createPresignedSuccessResult(uploadUrl);
134
- }
135
- catch (error) {
136
- return this.createPresignedErrorResult(error instanceof Error ? error.message : 'Failed to generate upload URL');
137
- }
138
- }
139
- /**
140
- * Creates a presigned URL for downloading/viewing a file.
141
- */
142
- async generateViewUrl(fileName) {
143
- // Security: Defense-in-depth validation
144
- // Decode URL-encoded characters first to catch encoded traversal attempts like %2e%2e%2f
145
- let decodedFileName;
146
- try {
147
- decodedFileName = decodeURIComponent(fileName);
148
- }
149
- catch {
150
- return this.createPresignedErrorResult('Invalid fileName: malformed URL encoding');
151
- }
152
- if (decodedFileName.includes('..') || decodedFileName.includes('\0')) {
153
- return this.createPresignedErrorResult('Invalid fileName: path traversal sequences are not allowed');
154
- }
155
- try {
156
- const gcsFile = this.bucket.file(decodedFileName);
157
- const expiresOn = new Date(Date.now() + (this.getPresignedUrlExpiry() * 1000));
158
- const [viewUrl] = await gcsFile.getSignedUrl({
159
- version: 'v4',
160
- action: 'read',
161
- expires: expiresOn,
162
- });
163
- return this.createPresignedSuccessResult(undefined, viewUrl);
164
- }
165
- catch (error) {
166
- return this.createPresignedErrorResult(error instanceof Error ? error.message : 'Failed to generate view URL');
167
- }
168
- }
169
- /**
170
- * Deletes a file from GCS.
171
- * Returns false if the file doesn't exist, throws on real errors.
172
- */
173
- async delete(fileName) {
174
- // Security: Defense-in-depth validation
175
- // Decode URL-encoded characters first to catch encoded traversal attempts like %2e%2e%2f
176
- let decodedFileName;
177
- try {
178
- decodedFileName = decodeURIComponent(fileName);
179
- }
180
- catch {
181
- return false;
182
- }
183
- if (decodedFileName.includes('..') || decodedFileName.includes('\0')) {
184
- return false;
185
- }
186
- const gcsFile = this.bucket.file(decodedFileName);
187
- const [exists] = await gcsFile.exists();
188
- if (!exists) {
189
- return false;
190
- }
191
- await gcsFile.delete();
192
- return true;
193
- }
194
- /**
195
- * Confirms an upload and optionally validates the file.
196
- *
197
- * For GCS, validation is optional since constraints are enforced at URL level.
198
- * But you can still use this to verify the file matches expectations.
199
- */
200
- async validateAndConfirmUpload(reference, options) {
201
- const deleteOnFailure = options?.deleteOnFailure !== false;
202
- try {
203
- const gcsFile = this.bucket.file(reference);
204
- const [metadata] = await gcsFile.getMetadata();
205
- const actualContentType = metadata.contentType;
206
- let actualFileSize;
207
- if (metadata.size !== undefined) {
208
- const parsed = typeof metadata.size === 'string' ? parseInt(metadata.size, 10) : metadata.size;
209
- actualFileSize = Number.isNaN(parsed) ? undefined : parsed;
210
- }
211
- // Validate content type if expected
212
- if (options?.expectedContentType && actualContentType !== options.expectedContentType) {
213
- if (deleteOnFailure) {
214
- await this.delete(reference);
215
- }
216
- const errorResult = {
217
- success: false,
218
- error: `Content type mismatch: expected '${options.expectedContentType}', got '${actualContentType}'${deleteOnFailure ? ' (file deleted)' : ' (file kept for inspection)'}`,
219
- };
220
- if (actualContentType)
221
- errorResult.actualContentType = actualContentType;
222
- if (actualFileSize !== undefined)
223
- errorResult.actualFileSize = actualFileSize;
224
- return errorResult;
225
- }
226
- // Validate file size if expected
227
- if (options?.expectedFileSize !== undefined && actualFileSize !== options.expectedFileSize) {
228
- if (deleteOnFailure) {
229
- await this.delete(reference);
230
- }
231
- const errorResult = {
232
- success: false,
233
- error: `File size mismatch: expected ${options.expectedFileSize} bytes, got ${actualFileSize} bytes${deleteOnFailure ? ' (file deleted)' : ' (file kept for inspection)'}`,
234
- };
235
- if (actualContentType)
236
- errorResult.actualContentType = actualContentType;
237
- if (actualFileSize !== undefined)
238
- errorResult.actualFileSize = actualFileSize;
239
- return errorResult;
240
- }
241
- const viewResult = await this.generateViewUrl(reference);
242
- const result = {
243
- success: true,
244
- reference,
245
- expiresIn: this.getPresignedUrlExpiry(),
246
- };
247
- if (viewResult.viewUrl) {
248
- result.viewUrl = viewResult.viewUrl;
249
- }
250
- if (actualContentType) {
251
- result.actualContentType = actualContentType;
252
- }
253
- if (actualFileSize !== undefined) {
254
- result.actualFileSize = actualFileSize;
255
- }
256
- return result;
257
- }
258
- catch (error) {
259
- const errorMessage = error instanceof Error ? error.message : 'File not found or access denied';
260
- return {
261
- success: false,
262
- error: errorMessage,
263
- };
264
- }
265
- }
266
- /**
267
- * Lists files in the bucket with optional prefix filtering and pagination.
268
- */
269
- async listFiles(prefix, maxResults = 1000, continuationToken) {
270
- try {
271
- const validatedMaxResults = Math.floor(Math.max(1, Math.min(Number.isNaN(maxResults) ? 1000 : maxResults, 1000)));
272
- const options = {
273
- maxResults: validatedMaxResults,
274
- };
275
- if (prefix)
276
- options.prefix = prefix;
277
- if (continuationToken)
278
- options.pageToken = continuationToken;
279
- const [files, , apiResponse] = await this.bucket.getFiles(options);
280
- const fileList = files.map((file) => {
281
- const fileInfo = { name: file.name };
282
- if (file.metadata.size) {
283
- const parsed = parseInt(String(file.metadata.size), 10);
284
- if (!Number.isNaN(parsed)) {
285
- fileInfo.size = parsed;
286
- }
287
- }
288
- if (file.metadata.contentType) {
289
- fileInfo.contentType = file.metadata.contentType;
290
- }
291
- if (file.metadata.updated) {
292
- fileInfo.lastModified = new Date(file.metadata.updated);
293
- }
294
- return fileInfo;
295
- });
296
- const result = {
297
- success: true,
298
- files: fileList,
299
- };
300
- const responseWithToken = apiResponse;
301
- if (responseWithToken?.nextPageToken) {
302
- result.nextToken = responseWithToken.nextPageToken;
303
- }
304
- return result;
305
- }
306
- catch (error) {
307
- return {
308
- success: false,
309
- error: error instanceof Error ? error.message : 'Failed to list files',
310
- };
311
- }
312
- }
313
- }
314
- /**
315
- * GCSPresignedStorageDriver - GCS driver that returns presigned URLs from upload().
316
- *
317
- * Use this when you want clients to upload directly to GCS without
318
- * the file passing through your server.
319
- */
320
- export class GCSPresignedStorageDriver extends GCSStorageDriver {
321
- constructor(config) {
322
- super(config);
323
- }
324
- /**
325
- * Instead of uploading the file, returns a presigned URL for the client to use.
326
- *
327
- * The returned fileUrl is the presigned upload URL.
328
- * After the client uploads, use validateAndConfirmUpload() to get a view URL.
329
- *
330
- * Note: The `options` parameter (metadata, cacheControl, etc.) is NOT applied
331
- * when using presigned uploads. These options must be set by the client when
332
- * making the actual upload request to GCS, or configured via bucket settings.
333
- * For server-side uploads with full options support, use the regular 'gcs' driver.
334
- */
335
- async upload(file, _options) {
336
- try {
337
- const validationErrors = this.validateFile(file);
338
- if (validationErrors.length > 0) {
339
- return this.createErrorResult(validationErrors.join(', '));
340
- }
341
- const fileName = this.generateFileName(file.originalname);
342
- const filePath = this.buildFilePath(fileName);
343
- const presignedResult = await this.generateUploadUrl(filePath, file.mimetype, file.size);
344
- if (!presignedResult.success) {
345
- return this.createErrorResult(presignedResult.error || 'Failed to generate presigned URL');
346
- }
347
- return this.createSuccessResult(filePath, presignedResult.uploadUrl);
348
- }
349
- catch (error) {
350
- return this.createErrorResult(error instanceof Error ? error.message : 'Failed to generate presigned URL');
351
- }
352
- }
353
- }
354
- //# sourceMappingURL=gcs.driver.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gcs.driver.js","sourceRoot":"","sources":["../../src/drivers/gcs.driver.ts"],"names":[],"mappings":"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"}
@@ -1,107 +0,0 @@
1
- import { BaseStorageDriver } from './base.driver.js';
2
- import { FileUploadResult, PresignedUrlResult, StorageConfig, ListFilesResult, UploadOptions } from '../types/storage.types.js';
3
- /**
4
- * LocalStorageDriver - Saves files to your local filesystem.
5
- *
6
- * Great for development and small-scale applications.
7
- * Files are organized by year/month folders automatically.
8
- *
9
- * **Security features:**
10
- * - Path traversal prevention (blocks ../ and null bytes)
11
- * - Symlinks are NOT followed or deleted (prevents directory escape attacks)
12
- * - Magic byte detection for content-type validation (prevents extension spoofing)
13
- * - Files stay within the configured base directory
14
- *
15
- * **Symlink behavior:** This driver explicitly rejects symlinks for security.
16
- * If a file is a symlink, it will not be read, deleted, or listed. This prevents
17
- * attackers from using symlinks to access files outside the storage directory.
18
- *
19
- * Note: Local storage doesn't support presigned URLs since
20
- * there's no external service to sign requests against.
21
- */
22
- export declare class LocalStorageDriver extends BaseStorageDriver {
23
- private basePath;
24
- constructor(config: StorageConfig);
25
- /**
26
- * Saves a file to the local filesystem.
27
- *
28
- * Files are automatically organized into YYYY/MM folders.
29
- * For example, a file uploaded in January 2026 goes into:
30
- * {basePath}/2026/01/{unique_filename}.jpg
31
- *
32
- * For large files (>100MB), uses streaming to reduce memory usage
33
- * and prevent application crashes.
34
- */
35
- upload(file: Express.Multer.File, _options?: UploadOptions): Promise<FileUploadResult>;
36
- /**
37
- * Uploads a large file using streaming.
38
- *
39
- * This method pipes the file stream directly to disk, which is more
40
- * memory-efficient for large files (>100MB).
41
- */
42
- private uploadWithStream;
43
- /**
44
- * Builds a URL for accessing the file.
45
- *
46
- * If your basePath starts with 'public/', we strip that prefix
47
- * since Express.static('public') serves files from /
48
- *
49
- * Example: public/uploads/2026/01/photo.jpg -> /uploads/2026/01/photo.jpg
50
- */
51
- private generateFileUrl;
52
- /**
53
- * Converts Windows backslashes to forward slashes.
54
- */
55
- private normalizePathSeparators;
56
- /**
57
- * Removes duplicate slashes from URLs.
58
- */
59
- private normalizeUrl;
60
- /**
61
- * Local storage doesn't support presigned upload URLs.
62
- */
63
- generateUploadUrl(_fileName: string, _contentType?: string, _maxSize?: number): Promise<PresignedUrlResult>;
64
- /**
65
- * Local storage doesn't support presigned view URLs.
66
- */
67
- generateViewUrl(_fileName: string): Promise<PresignedUrlResult>;
68
- /**
69
- * Validates a local file exists and matches expected values.
70
- *
71
- * Content type detection uses a two-tier approach:
72
- * 1. Magic byte detection (examines actual file content for security)
73
- * 2. Extension-based fallback (when magic bytes don't match)
74
- *
75
- * This helps detect extension spoofing attacks where a malicious file
76
- * is renamed with an innocent extension (e.g., malware.exe -> photo.jpg).
77
- */
78
- validateAndConfirmUpload(reference: string, options?: import('../types/storage.types.js').BlobValidationOptions): Promise<import('../types/storage.types.js').BlobValidationResult>;
79
- /**
80
- * Deletes a file from local storage.
81
- *
82
- * Security checks:
83
- * - Rejects path traversal attempts (../ sequences)
84
- * - Rejects null bytes in paths
85
- * - Verifies target stays within base directory
86
- * - Won't follow or delete symlinks (security: prevents directory escape attacks)
87
- * - Only deletes regular files (not directories)
88
- *
89
- * @param reference - The file path relative to the storage base directory
90
- * @returns true if file was deleted, false if not found or security check failed
91
- */
92
- delete(reference: string): Promise<boolean>;
93
- /**
94
- * Safely resolves a reference to a file path within our base directory.
95
- * Returns null for any suspicious input.
96
- */
97
- private resolveFilePath;
98
- /**
99
- * Lists files in local storage with optional prefix filtering and pagination.
100
- *
101
- * Uses early termination to avoid loading all files into memory when possible.
102
- * Files are collected in sorted order and iteration stops once we have enough
103
- * results for the requested page.
104
- */
105
- listFiles(prefix?: string, maxResults?: number, continuationToken?: string): Promise<ListFilesResult>;
106
- }
107
- //# sourceMappingURL=local.driver.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"local.driver.d.ts","sourceRoot":"","sources":["../../src/drivers/local.driver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAY,MAAM,2BAA2B,CAAC;AA0I1I;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,kBAAmB,SAAQ,iBAAiB;IACvD,OAAO,CAAC,QAAQ,CAAS;gBAEb,MAAM,EAAE,aAAa;IAKjC;;;;;;;;;OASG;IACG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAwC5F;;;;;OAKG;YACW,gBAAgB;IAmC9B;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAiBvB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAI/B;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;OAEG;IACG,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAMjH;;OAEG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAMrE;;;;;;;;;OASG;IACY,wBAAwB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,2BAA2B,EAAE,qBAAqB,GAClE,OAAO,CAAC,OAAO,2BAA2B,EAAE,oBAAoB,CAAC;IAgFpE;;;;;;;;;;;;OAYG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiDjD;;;OAGG;IACH,OAAO,CAAC,eAAe;IAuCvB;;;;;;OAMG;IACG,SAAS,CACb,MAAM,CAAC,EAAE,MAAM,EACf,UAAU,GAAE,MAAa,EACzB,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,eAAe,CAAC;CA2L5B"}