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.
- package/README.md +519 -348
- package/dist/drivers/azure.driver.d.ts +88 -0
- package/dist/drivers/azure.driver.d.ts.map +1 -0
- package/dist/drivers/azure.driver.js +367 -0
- package/dist/drivers/azure.driver.js.map +1 -0
- package/dist/drivers/base.driver.d.ts +125 -24
- package/dist/drivers/base.driver.d.ts.map +1 -1
- package/dist/drivers/base.driver.js +248 -62
- package/dist/drivers/base.driver.js.map +1 -1
- package/dist/drivers/gcs.driver.d.ts +60 -13
- package/dist/drivers/gcs.driver.d.ts.map +1 -1
- package/dist/drivers/gcs.driver.js +242 -41
- package/dist/drivers/gcs.driver.js.map +1 -1
- package/dist/drivers/local.driver.d.ts +89 -12
- package/dist/drivers/local.driver.d.ts.map +1 -1
- package/dist/drivers/local.driver.js +533 -45
- package/dist/drivers/local.driver.js.map +1 -1
- package/dist/drivers/s3.driver.d.ts +64 -13
- package/dist/drivers/s3.driver.d.ts.map +1 -1
- package/dist/drivers/s3.driver.js +269 -41
- package/dist/drivers/s3.driver.js.map +1 -1
- package/dist/factory/driver.factory.d.ts +35 -29
- package/dist/factory/driver.factory.d.ts.map +1 -1
- package/dist/factory/driver.factory.js +119 -59
- package/dist/factory/driver.factory.js.map +1 -1
- package/dist/index.d.ts +23 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -46
- package/dist/index.js.map +1 -1
- package/dist/storage-manager.d.ts +205 -52
- package/dist/storage-manager.d.ts.map +1 -1
- package/dist/storage-manager.js +644 -73
- package/dist/storage-manager.js.map +1 -1
- package/dist/types/storage.types.d.ts +243 -18
- package/dist/types/storage.types.d.ts.map +1 -1
- package/dist/utils/config.utils.d.ts +28 -4
- package/dist/utils/config.utils.d.ts.map +1 -1
- package/dist/utils/config.utils.js +121 -47
- package/dist/utils/config.utils.js.map +1 -1
- package/dist/utils/file.utils.d.ts +111 -14
- package/dist/utils/file.utils.d.ts.map +1 -1
- package/dist/utils/file.utils.js +215 -32
- package/dist/utils/file.utils.js.map +1 -1
- package/package.json +51 -27
- package/dist/drivers/oci.driver.d.ts +0 -37
- package/dist/drivers/oci.driver.d.ts.map +0 -1
- package/dist/drivers/oci.driver.js +0 -84
- 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
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
*
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
*
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
*
|
|
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
|
-
|
|
171
|
+
listFiles(prefix?: string, maxResults?: number, continuationToken?: string): Promise<ListFilesResult>;
|
|
30
172
|
/**
|
|
31
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
186
|
+
getSafeConfig(): StorageConfig;
|
|
50
187
|
/**
|
|
51
|
-
*
|
|
188
|
+
* Returns which storage driver is currently active.
|
|
52
189
|
*/
|
|
53
|
-
|
|
190
|
+
getDriverType(): StorageDriver;
|
|
54
191
|
/**
|
|
55
|
-
*
|
|
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
|
-
|
|
198
|
+
isPresignedUploadMode(): boolean;
|
|
58
199
|
/**
|
|
59
|
-
*
|
|
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
|
-
|
|
209
|
+
getRateLimitStatus(): {
|
|
210
|
+
remainingRequests: number;
|
|
211
|
+
resetTimeMs: number;
|
|
212
|
+
} | null;
|
|
62
213
|
/**
|
|
63
|
-
*
|
|
214
|
+
* Returns all available storage drivers.
|
|
64
215
|
*/
|
|
65
|
-
static getAvailableDrivers():
|
|
216
|
+
static getAvailableDrivers(): StorageDriver[];
|
|
66
217
|
/**
|
|
67
|
-
*
|
|
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
|
-
*
|
|
223
|
+
* Validates a file against the provided rules.
|
|
224
|
+
* Returns an error message if validation fails, null if it passes.
|
|
72
225
|
*/
|
|
73
|
-
private
|
|
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,
|
|
1
|
+
{"version":3,"file":"storage-manager.d.ts","sourceRoot":"","sources":["../src/storage-manager.ts"],"names":[],"mappings":"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"}
|