@pelatform/storage 1.0.1
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/LICENSE +21 -0
- package/README.md +10 -0
- package/dist/chunk-KJMGBTTL.js +413 -0
- package/dist/chunk-ZTZZCC52.js +169 -0
- package/dist/cloudinary.d.ts +93 -0
- package/dist/cloudinary.js +496 -0
- package/dist/helpers.d.ts +762 -0
- package/dist/helpers.js +68 -0
- package/dist/index.d.ts +281 -0
- package/dist/index.js +24 -0
- package/dist/s3.d.ts +108 -0
- package/dist/s3.js +799 -0
- package/dist/storage-interface-UizTndyU.d.ts +316 -0
- package/package.json +78 -0
|
@@ -0,0 +1,762 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage helper utilities
|
|
3
|
+
* Provides utility functions for file operations, MIME type detection, and path manipulation
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Generate a unique file key with timestamp and random string
|
|
7
|
+
* @param originalName Original file name
|
|
8
|
+
* @param prefix Optional prefix for the key
|
|
9
|
+
* @returns Unique file key
|
|
10
|
+
* @public
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { generateFileKey } from '@pelatform/storage/helpers';
|
|
15
|
+
*
|
|
16
|
+
* const key1 = generateFileKey('document.pdf');
|
|
17
|
+
* // Returns: "document-1703123456789-abc123.pdf"
|
|
18
|
+
*
|
|
19
|
+
* const key2 = generateFileKey('photo.jpg', 'uploads/images');
|
|
20
|
+
* // Returns: "uploads/images/photo-1703123456789-def456.jpg"
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare function generateFileKey(originalName: string, prefix?: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Get MIME type from file name or extension
|
|
26
|
+
* @param fileName File name or path
|
|
27
|
+
* @returns MIME type string
|
|
28
|
+
* @public
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* import { getMimeType } from '@pelatform/storage/helpers';
|
|
33
|
+
*
|
|
34
|
+
* const type1 = getMimeType('document.pdf');
|
|
35
|
+
* // Returns: "application/pdf"
|
|
36
|
+
*
|
|
37
|
+
* const type2 = getMimeType('photo.jpg');
|
|
38
|
+
* // Returns: "image/jpeg"
|
|
39
|
+
*
|
|
40
|
+
* const type3 = getMimeType('unknown.xyz');
|
|
41
|
+
* // Returns: "application/octet-stream"
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
declare function getMimeType(fileName: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Validate file size against maximum allowed size
|
|
47
|
+
* @param fileSize File size in bytes
|
|
48
|
+
* @param maxSize Maximum allowed size in bytes
|
|
49
|
+
* @returns Validation result with error message if invalid
|
|
50
|
+
* @public
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* import { validateFileSize } from '@pelatform/storage/helpers';
|
|
55
|
+
*
|
|
56
|
+
* const result1 = validateFileSize(1024 * 1024, 5 * 1024 * 1024); // 1MB vs 5MB limit
|
|
57
|
+
* // Returns: { valid: true }
|
|
58
|
+
*
|
|
59
|
+
* const result2 = validateFileSize(10 * 1024 * 1024, 5 * 1024 * 1024); // 10MB vs 5MB limit
|
|
60
|
+
* // Returns: { valid: false, error: "File size 10 MB exceeds maximum allowed size 5 MB" }
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
declare function validateFileSize(fileSize: number, maxSize: number): {
|
|
64
|
+
valid: boolean;
|
|
65
|
+
error?: string;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Validate file type against allowed types (MIME types or extensions)
|
|
69
|
+
* @param fileName File name or path
|
|
70
|
+
* @param allowedTypes Array of allowed MIME types or file extensions
|
|
71
|
+
* @returns Validation result with error message if invalid
|
|
72
|
+
* @public
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* import { validateFileType } from '@pelatform/storage/helpers';
|
|
77
|
+
*
|
|
78
|
+
* // Using MIME types
|
|
79
|
+
* const result1 = validateFileType('photo.jpg', ['image/*', 'application/pdf']);
|
|
80
|
+
* // Returns: { valid: true }
|
|
81
|
+
*
|
|
82
|
+
* // Using file extensions
|
|
83
|
+
* const result2 = validateFileType('document.txt', ['.pdf', '.doc', '.docx']);
|
|
84
|
+
* // Returns: { valid: false, error: "File type not allowed. Allowed types: .pdf, .doc, .docx" }
|
|
85
|
+
*
|
|
86
|
+
* // Mixed MIME types and extensions
|
|
87
|
+
* const result3 = validateFileType('video.mp4', ['image/*', '.pdf', 'video/mp4']);
|
|
88
|
+
* // Returns: { valid: true }
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
declare function validateFileType(fileName: string, allowedTypes: string[]): {
|
|
92
|
+
valid: boolean;
|
|
93
|
+
error?: string;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Format file size in human readable format
|
|
97
|
+
* @param bytes File size in bytes
|
|
98
|
+
* @returns Formatted file size string
|
|
99
|
+
* @public
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* import { formatFileSize } from '@pelatform/storage/helpers';
|
|
104
|
+
*
|
|
105
|
+
* const size1 = formatFileSize(1024);
|
|
106
|
+
* // Returns: "1 KB"
|
|
107
|
+
*
|
|
108
|
+
* const size2 = formatFileSize(1048576);
|
|
109
|
+
* // Returns: "1 MB"
|
|
110
|
+
*
|
|
111
|
+
* const size3 = formatFileSize(1073741824);
|
|
112
|
+
* // Returns: "1 GB"
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
declare function formatFileSize(bytes: number): string;
|
|
116
|
+
/**
|
|
117
|
+
* Sanitize file name for S3 key by removing special characters
|
|
118
|
+
* @param fileName Original file name
|
|
119
|
+
* @returns Sanitized file name safe for S3 keys
|
|
120
|
+
* @public
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* import { sanitizeFileName } from '@pelatform/storage/helpers';
|
|
125
|
+
*
|
|
126
|
+
* const safe1 = sanitizeFileName('My Document (2023).pdf');
|
|
127
|
+
* // Returns: "my_document_2023.pdf"
|
|
128
|
+
*
|
|
129
|
+
* const safe2 = sanitizeFileName('file@#$%name.txt');
|
|
130
|
+
* // Returns: "file_name.txt"
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
declare function sanitizeFileName(fileName: string): string;
|
|
134
|
+
/**
|
|
135
|
+
* Extract file extension from file name
|
|
136
|
+
* @param fileName File name or path
|
|
137
|
+
* @returns File extension with dot (e.g., '.pdf')
|
|
138
|
+
* @public
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* import { getFileExtension } from '@pelatform/storage/helpers';
|
|
143
|
+
*
|
|
144
|
+
* const ext1 = getFileExtension('document.pdf');
|
|
145
|
+
* // Returns: ".pdf"
|
|
146
|
+
*
|
|
147
|
+
* const ext2 = getFileExtension('photo.JPEG');
|
|
148
|
+
* // Returns: ".jpeg"
|
|
149
|
+
*
|
|
150
|
+
* const ext3 = getFileExtension('noextension');
|
|
151
|
+
* // Returns: ""
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
declare function getFileExtension(fileName: string): string;
|
|
155
|
+
/**
|
|
156
|
+
* Generate cache control header for HTTP responses
|
|
157
|
+
* @param maxAge Cache max age in seconds (default: 1 year)
|
|
158
|
+
* @param isPublic Whether cache should be public or private
|
|
159
|
+
* @returns Cache control header string
|
|
160
|
+
* @public
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* import { generateCacheControl } from '@pelatform/storage/helpers';
|
|
165
|
+
*
|
|
166
|
+
* const cache1 = generateCacheControl();
|
|
167
|
+
* // Returns: "public, max-age=31536000"
|
|
168
|
+
*
|
|
169
|
+
* const cache2 = generateCacheControl(3600, false);
|
|
170
|
+
* // Returns: "private, max-age=3600"
|
|
171
|
+
*
|
|
172
|
+
* const cache3 = generateCacheControl(86400); // 1 day
|
|
173
|
+
* // Returns: "public, max-age=86400"
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
declare function generateCacheControl(maxAge?: number, // 1 year default
|
|
177
|
+
isPublic?: boolean): string;
|
|
178
|
+
/**
|
|
179
|
+
* Parse S3 URL to extract bucket and key
|
|
180
|
+
* @param url S3 URL to parse
|
|
181
|
+
* @returns Object containing bucket and key
|
|
182
|
+
* @public
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* import { parseS3Url } from '@pelatform/storage/helpers';
|
|
187
|
+
*
|
|
188
|
+
* // Virtual hosted-style URL
|
|
189
|
+
* const result1 = parseS3Url('https://my-bucket.s3.us-east-1.amazonaws.com/folder/file.pdf');
|
|
190
|
+
* // Returns: { bucket: "my-bucket", key: "folder/file.pdf" }
|
|
191
|
+
*
|
|
192
|
+
* // Path-style URL
|
|
193
|
+
* const result2 = parseS3Url('https://s3.us-east-1.amazonaws.com/my-bucket/folder/file.pdf');
|
|
194
|
+
* // Returns: { bucket: "my-bucket", key: "folder/file.pdf" }
|
|
195
|
+
*
|
|
196
|
+
* // Custom endpoint (R2, MinIO)
|
|
197
|
+
* const result3 = parseS3Url('https://my-endpoint.com/my-bucket/folder/file.pdf');
|
|
198
|
+
* // Returns: { bucket: "my-bucket", key: "folder/file.pdf" }
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
declare function parseS3Url(url: string): {
|
|
202
|
+
bucket?: string;
|
|
203
|
+
key?: string;
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* Build public URL for a file
|
|
207
|
+
* @param baseUrl Base URL of the storage service
|
|
208
|
+
* @param bucket Bucket name
|
|
209
|
+
* @param key File key/path
|
|
210
|
+
* @returns Complete public URL
|
|
211
|
+
* @public
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* import { buildPublicUrl } from '@pelatform/storage/helpers';
|
|
216
|
+
*
|
|
217
|
+
* const url1 = buildPublicUrl('https://cdn.example.com', 'my-bucket', 'folder/file.pdf');
|
|
218
|
+
* // Returns: "https://cdn.example.com/my-bucket/folder/file.pdf"
|
|
219
|
+
*
|
|
220
|
+
* const url2 = buildPublicUrl('https://storage.example.com/', 'assets', 'images/logo.png');
|
|
221
|
+
* // Returns: "https://storage.example.com/assets/images/logo.png"
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
declare function buildPublicUrl(baseUrl: string, bucket: string, key: string): string;
|
|
225
|
+
/**
|
|
226
|
+
* Validate S3 key format according to AWS S3 naming rules
|
|
227
|
+
* @param key S3 object key to validate
|
|
228
|
+
* @returns Validation result with error message if invalid
|
|
229
|
+
* @public
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```typescript
|
|
233
|
+
* import { validateS3Key } from '@pelatform/storage/helpers';
|
|
234
|
+
*
|
|
235
|
+
* const result1 = validateS3Key('documents/report.pdf');
|
|
236
|
+
* // Returns: { valid: true }
|
|
237
|
+
*
|
|
238
|
+
* const result2 = validateS3Key('/invalid/key/');
|
|
239
|
+
* // Returns: { valid: false, error: "Key cannot start or end with forward slash" }
|
|
240
|
+
* ```
|
|
241
|
+
*/
|
|
242
|
+
declare function validateS3Key(key: string): {
|
|
243
|
+
valid: boolean;
|
|
244
|
+
error?: string;
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* Convert File object to Buffer for upload
|
|
248
|
+
* @param file File object from browser input
|
|
249
|
+
* @returns Promise that resolves to Buffer
|
|
250
|
+
* @public
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```typescript
|
|
254
|
+
* import { fileToBuffer } from '@pelatform/storage/helpers';
|
|
255
|
+
*
|
|
256
|
+
* // In browser with file input
|
|
257
|
+
* const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
|
|
258
|
+
* const file = fileInput.files?.[0];
|
|
259
|
+
*
|
|
260
|
+
* if (file) {
|
|
261
|
+
* const buffer = await fileToBuffer(file);
|
|
262
|
+
* // Use buffer for upload
|
|
263
|
+
* await storage.uploadFile('uploads/file.pdf', buffer);
|
|
264
|
+
* }
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
declare function fileToBuffer(file: File): Promise<Buffer>;
|
|
268
|
+
/**
|
|
269
|
+
* Get file information from File object
|
|
270
|
+
* @param file File object from browser input
|
|
271
|
+
* @returns Object containing file metadata
|
|
272
|
+
* @public
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```typescript
|
|
276
|
+
* import { getFileInfo } from '@pelatform/storage/helpers';
|
|
277
|
+
*
|
|
278
|
+
* // In browser with file input
|
|
279
|
+
* const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
|
|
280
|
+
* const file = fileInput.files?.[0];
|
|
281
|
+
*
|
|
282
|
+
* if (file) {
|
|
283
|
+
* const info = getFileInfo(file);
|
|
284
|
+
* console.log(info);
|
|
285
|
+
* // Returns: {
|
|
286
|
+
* // name: "document.pdf",
|
|
287
|
+
* // size: 1048576,
|
|
288
|
+
* // type: "application/pdf",
|
|
289
|
+
* // lastModified: Date
|
|
290
|
+
* // }
|
|
291
|
+
* }
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
declare function getFileInfo(file: File): {
|
|
295
|
+
name: string;
|
|
296
|
+
size: number;
|
|
297
|
+
type: string;
|
|
298
|
+
lastModified: Date;
|
|
299
|
+
};
|
|
300
|
+
/**
|
|
301
|
+
* Generate unique key with prefix and timestamp
|
|
302
|
+
* @param fileName Original file name
|
|
303
|
+
* @param prefix Optional prefix for the key
|
|
304
|
+
* @param includeTimestamp Whether to include timestamp for uniqueness
|
|
305
|
+
* @returns Unique file key
|
|
306
|
+
* @public
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* ```typescript
|
|
310
|
+
* import { generateUniqueKey } from '@pelatform/storage/helpers';
|
|
311
|
+
*
|
|
312
|
+
* const key1 = generateUniqueKey('report.pdf', 'documents');
|
|
313
|
+
* // Returns: "documents/report-1703123456789-abc123.pdf"
|
|
314
|
+
*
|
|
315
|
+
* const key2 = generateUniqueKey('photo.jpg', 'images', false);
|
|
316
|
+
* // Returns: "images/photo.jpg"
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
319
|
+
declare function generateUniqueKey(fileName: string, prefix?: string, includeTimestamp?: boolean): string;
|
|
320
|
+
/**
|
|
321
|
+
* Extract bucket, key, and region from S3 URL
|
|
322
|
+
* @param url S3 URL to parse
|
|
323
|
+
* @returns Object containing bucket, key, and region information
|
|
324
|
+
* @public
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* ```typescript
|
|
328
|
+
* import { extractS3Info } from '@pelatform/storage/helpers';
|
|
329
|
+
*
|
|
330
|
+
* // AWS S3 virtual hosted-style
|
|
331
|
+
* const result1 = extractS3Info('https://my-bucket.s3.us-west-2.amazonaws.com/folder/file.pdf');
|
|
332
|
+
* // Returns: { bucket: "my-bucket", key: "folder/file.pdf", region: "us-west-2" }
|
|
333
|
+
*
|
|
334
|
+
* // AWS S3 path-style
|
|
335
|
+
* const result2 = extractS3Info('https://s3.eu-central-1.amazonaws.com/my-bucket/file.pdf');
|
|
336
|
+
* // Returns: { bucket: "my-bucket", key: "file.pdf", region: "eu-central-1" }
|
|
337
|
+
*
|
|
338
|
+
* // Custom endpoint
|
|
339
|
+
* const result3 = extractS3Info('https://minio.example.com/my-bucket/folder/file.pdf');
|
|
340
|
+
* // Returns: { bucket: "my-bucket", key: "folder/file.pdf" }
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
declare function extractS3Info(url: string): {
|
|
344
|
+
bucket?: string;
|
|
345
|
+
key?: string;
|
|
346
|
+
region?: string;
|
|
347
|
+
};
|
|
348
|
+
/**
|
|
349
|
+
* Validate S3 configuration object
|
|
350
|
+
* @param config S3 configuration object to validate
|
|
351
|
+
* @returns Validation result with list of errors
|
|
352
|
+
* @public
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* ```typescript
|
|
356
|
+
* import { validateS3Config } from '@pelatform/storage/helpers';
|
|
357
|
+
*
|
|
358
|
+
* const config = {
|
|
359
|
+
* provider: 'aws',
|
|
360
|
+
* region: 'us-east-1',
|
|
361
|
+
* bucket: 'my-bucket',
|
|
362
|
+
* accessKeyId: 'AKIA...',
|
|
363
|
+
* secretAccessKey: 'secret...'
|
|
364
|
+
* };
|
|
365
|
+
*
|
|
366
|
+
* const result = validateS3Config(config);
|
|
367
|
+
* // Returns: { valid: true, errors: [] }
|
|
368
|
+
*
|
|
369
|
+
* const invalidConfig = { provider: 'aws' }; // Missing required fields
|
|
370
|
+
* const result2 = validateS3Config(invalidConfig);
|
|
371
|
+
* // Returns: { valid: false, errors: ["Region is required", "Bucket is required", ...] }
|
|
372
|
+
* ```
|
|
373
|
+
*/
|
|
374
|
+
declare function validateS3Config(config: Record<string, unknown>): {
|
|
375
|
+
valid: boolean;
|
|
376
|
+
errors: string[];
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* Validate S3 bucket name according to AWS naming rules
|
|
380
|
+
* @param bucketName Bucket name to validate
|
|
381
|
+
* @returns Validation result with error message if invalid
|
|
382
|
+
* @public
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* ```typescript
|
|
386
|
+
* import { validateBucketName } from '@pelatform/storage/helpers';
|
|
387
|
+
*
|
|
388
|
+
* const result1 = validateBucketName('my-valid-bucket');
|
|
389
|
+
* // Returns: { valid: true }
|
|
390
|
+
*
|
|
391
|
+
* const result2 = validateBucketName('My-Invalid-Bucket');
|
|
392
|
+
* // Returns: { valid: false, error: "Bucket name can only contain lowercase letters, numbers, dots, and hyphens" }
|
|
393
|
+
*
|
|
394
|
+
* const result3 = validateBucketName('ab');
|
|
395
|
+
* // Returns: { valid: false, error: "Bucket name must be between 3 and 63 characters" }
|
|
396
|
+
* ```
|
|
397
|
+
*/
|
|
398
|
+
declare function validateBucketName(bucketName: string): {
|
|
399
|
+
valid: boolean;
|
|
400
|
+
error?: string;
|
|
401
|
+
};
|
|
402
|
+
/**
|
|
403
|
+
* Generate content disposition header for file downloads
|
|
404
|
+
* @param fileName File name for the download
|
|
405
|
+
* @param disposition Whether to display inline or as attachment
|
|
406
|
+
* @returns Content disposition header string
|
|
407
|
+
* @public
|
|
408
|
+
*
|
|
409
|
+
* @example
|
|
410
|
+
* ```typescript
|
|
411
|
+
* import { getContentDisposition } from '@pelatform/storage/helpers';
|
|
412
|
+
*
|
|
413
|
+
* const header1 = getContentDisposition('document.pdf');
|
|
414
|
+
* // Returns: 'attachment; filename="document.pdf"'
|
|
415
|
+
*
|
|
416
|
+
* const header2 = getContentDisposition('image.jpg', 'inline');
|
|
417
|
+
* // Returns: 'inline; filename="image.jpg"'
|
|
418
|
+
*
|
|
419
|
+
* const header3 = getContentDisposition('file@#$name.txt');
|
|
420
|
+
* // Returns: 'attachment; filename="filename.txt"'
|
|
421
|
+
* ```
|
|
422
|
+
*/
|
|
423
|
+
declare function getContentDisposition(fileName: string, disposition?: 'inline' | 'attachment'): string;
|
|
424
|
+
/**
|
|
425
|
+
* Check if file is an image based on MIME type
|
|
426
|
+
* @param fileName File name or path
|
|
427
|
+
* @returns True if file is an image
|
|
428
|
+
* @public
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* ```typescript
|
|
432
|
+
* import { isImageFile } from '@pelatform/storage/helpers';
|
|
433
|
+
*
|
|
434
|
+
* const result1 = isImageFile('photo.jpg');
|
|
435
|
+
* // Returns: true
|
|
436
|
+
*
|
|
437
|
+
* const result2 = isImageFile('document.pdf');
|
|
438
|
+
* // Returns: false
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
declare function isImageFile(fileName: string): boolean;
|
|
442
|
+
/**
|
|
443
|
+
* Check if file is a video based on MIME type
|
|
444
|
+
* @param fileName File name or path
|
|
445
|
+
* @returns True if file is a video
|
|
446
|
+
* @public
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* ```typescript
|
|
450
|
+
* import { isVideoFile } from '@pelatform/storage/helpers';
|
|
451
|
+
*
|
|
452
|
+
* const result1 = isVideoFile('movie.mp4');
|
|
453
|
+
* // Returns: true
|
|
454
|
+
*
|
|
455
|
+
* const result2 = isVideoFile('document.pdf');
|
|
456
|
+
* // Returns: false
|
|
457
|
+
* ```
|
|
458
|
+
*/
|
|
459
|
+
declare function isVideoFile(fileName: string): boolean;
|
|
460
|
+
/**
|
|
461
|
+
* Check if file is an audio file based on MIME type
|
|
462
|
+
* @param fileName File name or path
|
|
463
|
+
* @returns True if file is an audio file
|
|
464
|
+
* @public
|
|
465
|
+
*
|
|
466
|
+
* @example
|
|
467
|
+
* ```typescript
|
|
468
|
+
* import { isAudioFile } from '@pelatform/storage/helpers';
|
|
469
|
+
*
|
|
470
|
+
* const result1 = isAudioFile('song.mp3');
|
|
471
|
+
* // Returns: true
|
|
472
|
+
*
|
|
473
|
+
* const result2 = isAudioFile('document.pdf');
|
|
474
|
+
* // Returns: false
|
|
475
|
+
* ```
|
|
476
|
+
*/
|
|
477
|
+
declare function isAudioFile(fileName: string): boolean;
|
|
478
|
+
/**
|
|
479
|
+
* Check if file is a document based on MIME type
|
|
480
|
+
* @param fileName File name or path
|
|
481
|
+
* @returns True if file is a document
|
|
482
|
+
* @public
|
|
483
|
+
*
|
|
484
|
+
* @example
|
|
485
|
+
* ```typescript
|
|
486
|
+
* import { isDocumentFile } from '@pelatform/storage/helpers';
|
|
487
|
+
*
|
|
488
|
+
* const result1 = isDocumentFile('report.pdf');
|
|
489
|
+
* // Returns: true
|
|
490
|
+
*
|
|
491
|
+
* const result2 = isDocumentFile('spreadsheet.xlsx');
|
|
492
|
+
* // Returns: true
|
|
493
|
+
*
|
|
494
|
+
* const result3 = isDocumentFile('photo.jpg');
|
|
495
|
+
* // Returns: false
|
|
496
|
+
* ```
|
|
497
|
+
*/
|
|
498
|
+
declare function isDocumentFile(fileName: string): boolean;
|
|
499
|
+
/**
|
|
500
|
+
* Normalize path separators and remove redundant slashes
|
|
501
|
+
* @param path Path to normalize
|
|
502
|
+
* @returns Normalized path
|
|
503
|
+
* @public
|
|
504
|
+
*
|
|
505
|
+
* @example
|
|
506
|
+
* ```typescript
|
|
507
|
+
* import { normalizePath } from '@pelatform/storage/helpers';
|
|
508
|
+
*
|
|
509
|
+
* const path1 = normalizePath('folder//subfolder///file.txt');
|
|
510
|
+
* // Returns: "folder/subfolder/file.txt"
|
|
511
|
+
*
|
|
512
|
+
* const path2 = normalizePath('\\folder\\file.txt');
|
|
513
|
+
* // Returns: "folder/file.txt"
|
|
514
|
+
*
|
|
515
|
+
* const path3 = normalizePath('/folder/file.txt/');
|
|
516
|
+
* // Returns: "folder/file.txt"
|
|
517
|
+
* ```
|
|
518
|
+
*/
|
|
519
|
+
declare function normalizePath(path: string): string;
|
|
520
|
+
/**
|
|
521
|
+
* Join path segments safely with proper separators
|
|
522
|
+
* @param segments Path segments to join
|
|
523
|
+
* @returns Joined path
|
|
524
|
+
* @public
|
|
525
|
+
*
|
|
526
|
+
* @example
|
|
527
|
+
* ```typescript
|
|
528
|
+
* import { joinPath } from '@pelatform/storage/helpers';
|
|
529
|
+
*
|
|
530
|
+
* const path1 = joinPath('folder', 'subfolder', 'file.txt');
|
|
531
|
+
* // Returns: "folder/subfolder/file.txt"
|
|
532
|
+
*
|
|
533
|
+
* const path2 = joinPath('/folder/', '/subfolder/', '/file.txt/');
|
|
534
|
+
* // Returns: "folder/subfolder/file.txt"
|
|
535
|
+
*
|
|
536
|
+
* const path3 = joinPath('', 'folder', '', 'file.txt');
|
|
537
|
+
* // Returns: "folder/file.txt"
|
|
538
|
+
* ```
|
|
539
|
+
*/
|
|
540
|
+
declare function joinPath(...segments: string[]): string;
|
|
541
|
+
/**
|
|
542
|
+
* Get parent directory path from a file key
|
|
543
|
+
* @param key File key or path
|
|
544
|
+
* @returns Parent directory path
|
|
545
|
+
* @public
|
|
546
|
+
*
|
|
547
|
+
* @example
|
|
548
|
+
* ```typescript
|
|
549
|
+
* import { getParentPath } from '@pelatform/storage/helpers';
|
|
550
|
+
*
|
|
551
|
+
* const parent1 = getParentPath('folder/subfolder/file.txt');
|
|
552
|
+
* // Returns: "folder/subfolder"
|
|
553
|
+
*
|
|
554
|
+
* const parent2 = getParentPath('file.txt');
|
|
555
|
+
* // Returns: ""
|
|
556
|
+
*
|
|
557
|
+
* const parent3 = getParentPath('folder/file.txt');
|
|
558
|
+
* // Returns: "folder"
|
|
559
|
+
* ```
|
|
560
|
+
*/
|
|
561
|
+
declare function getParentPath(key: string): string;
|
|
562
|
+
/**
|
|
563
|
+
* Get filename from a file key or path
|
|
564
|
+
* @param key File key or path
|
|
565
|
+
* @returns Filename without path
|
|
566
|
+
* @public
|
|
567
|
+
*
|
|
568
|
+
* @example
|
|
569
|
+
* ```typescript
|
|
570
|
+
* import { getFileName } from '@pelatform/storage/helpers';
|
|
571
|
+
*
|
|
572
|
+
* const name1 = getFileName('folder/subfolder/document.pdf');
|
|
573
|
+
* // Returns: "document.pdf"
|
|
574
|
+
*
|
|
575
|
+
* const name2 = getFileName('file.txt');
|
|
576
|
+
* // Returns: "file.txt"
|
|
577
|
+
*
|
|
578
|
+
* const name3 = getFileName('folder/subfolder/');
|
|
579
|
+
* // Returns: ""
|
|
580
|
+
* ```
|
|
581
|
+
*/
|
|
582
|
+
declare function getFileName(key: string): string;
|
|
583
|
+
/**
|
|
584
|
+
* Convert base64 string to Buffer
|
|
585
|
+
* @param base64 Base64 encoded string
|
|
586
|
+
* @returns Buffer containing the decoded data
|
|
587
|
+
* @public
|
|
588
|
+
*
|
|
589
|
+
* @example
|
|
590
|
+
* ```typescript
|
|
591
|
+
* import { base64ToBuffer } from '@pelatform/storage/helpers';
|
|
592
|
+
*
|
|
593
|
+
* const base64 = 'SGVsbG8gV29ybGQ='; // "Hello World" in base64
|
|
594
|
+
* const buffer = base64ToBuffer(base64);
|
|
595
|
+
* console.log(buffer.toString()); // "Hello World"
|
|
596
|
+
*
|
|
597
|
+
* // For file uploads from base64 data
|
|
598
|
+
* const imageBase64 = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD...';
|
|
599
|
+
* const cleanBase64 = imageBase64.split(',')[1]; // Remove data URL prefix
|
|
600
|
+
* const imageBuffer = base64ToBuffer(cleanBase64);
|
|
601
|
+
* await storage.uploadFile('images/photo.jpg', imageBuffer);
|
|
602
|
+
* ```
|
|
603
|
+
*/
|
|
604
|
+
declare function base64ToBuffer(base64: string): Buffer;
|
|
605
|
+
/**
|
|
606
|
+
* Convert Buffer to base64 string
|
|
607
|
+
* @param buffer Buffer to encode
|
|
608
|
+
* @param includeDataUrl Whether to include data URL prefix
|
|
609
|
+
* @param mimeType MIME type for data URL (required if includeDataUrl is true)
|
|
610
|
+
* @returns Base64 encoded string
|
|
611
|
+
* @public
|
|
612
|
+
*
|
|
613
|
+
* @example
|
|
614
|
+
* ```typescript
|
|
615
|
+
* import { bufferToBase64 } from '@pelatform/storage/helpers';
|
|
616
|
+
*
|
|
617
|
+
* const buffer = Buffer.from('Hello World');
|
|
618
|
+
* const base64 = bufferToBase64(buffer);
|
|
619
|
+
* // Returns: "SGVsbG8gV29ybGQ="
|
|
620
|
+
*
|
|
621
|
+
* // With data URL for images
|
|
622
|
+
* const imageBuffer = await storage.downloadFile('images/photo.jpg');
|
|
623
|
+
* const dataUrl = bufferToBase64(imageBuffer.content!, true, 'image/jpeg');
|
|
624
|
+
* // Returns: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
|
|
625
|
+
*
|
|
626
|
+
* // Use in HTML img tag
|
|
627
|
+
* document.querySelector('img').src = dataUrl;
|
|
628
|
+
* ```
|
|
629
|
+
*/
|
|
630
|
+
declare function bufferToBase64(buffer: Buffer, includeDataUrl?: boolean, mimeType?: string): string;
|
|
631
|
+
/**
|
|
632
|
+
* Generate file hash/checksum for integrity verification
|
|
633
|
+
* @param content File content as Buffer or string
|
|
634
|
+
* @param algorithm Hash algorithm to use
|
|
635
|
+
* @returns Hash string
|
|
636
|
+
* @public
|
|
637
|
+
*
|
|
638
|
+
* @example
|
|
639
|
+
* ```typescript
|
|
640
|
+
* import { generateFileHash } from '@pelatform/storage/helpers';
|
|
641
|
+
*
|
|
642
|
+
* const content = Buffer.from('Hello World');
|
|
643
|
+
*
|
|
644
|
+
* const md5Hash = generateFileHash(content, 'md5');
|
|
645
|
+
* // Returns: "b10a8db164e0754105b7a99be72e3fe5"
|
|
646
|
+
*
|
|
647
|
+
* const sha256Hash = generateFileHash(content, 'sha256');
|
|
648
|
+
* // Returns: "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"
|
|
649
|
+
*
|
|
650
|
+
* // For file integrity checking
|
|
651
|
+
* const fileBuffer = await storage.downloadFile('document.pdf');
|
|
652
|
+
* const currentHash = generateFileHash(fileBuffer.content!, 'sha256');
|
|
653
|
+
* const expectedHash = 'a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e';
|
|
654
|
+
*
|
|
655
|
+
* if (currentHash === expectedHash) {
|
|
656
|
+
* console.log('File integrity verified');
|
|
657
|
+
* } else {
|
|
658
|
+
* console.log('File may be corrupted');
|
|
659
|
+
* }
|
|
660
|
+
* ```
|
|
661
|
+
*/
|
|
662
|
+
declare function generateFileHash(content: Buffer | string, algorithm?: 'md5' | 'sha1' | 'sha256'): Promise<string>;
|
|
663
|
+
/**
|
|
664
|
+
* Generate multiple unique keys at once for batch operations
|
|
665
|
+
* @param fileNames Array of file names
|
|
666
|
+
* @param prefix Optional prefix for all keys
|
|
667
|
+
* @returns Array of unique keys
|
|
668
|
+
* @public
|
|
669
|
+
*
|
|
670
|
+
* @example
|
|
671
|
+
* ```typescript
|
|
672
|
+
* import { generateBatchKeys } from '@pelatform/storage/helpers';
|
|
673
|
+
*
|
|
674
|
+
* const fileNames = ['document1.pdf', 'document2.pdf', 'image.jpg'];
|
|
675
|
+
* const keys = generateBatchKeys(fileNames, 'uploads');
|
|
676
|
+
* // Returns: [
|
|
677
|
+
* // "uploads/document1-1703123456789-abc123.pdf",
|
|
678
|
+
* // "uploads/document2-1703123456790-def456.pdf",
|
|
679
|
+
* // "uploads/image-1703123456791-ghi789.jpg"
|
|
680
|
+
* // ]
|
|
681
|
+
*
|
|
682
|
+
* // Use for batch uploads
|
|
683
|
+
* const files = [file1, file2, file3];
|
|
684
|
+
* const keys = generateBatchKeys(files.map(f => f.name), 'batch-upload');
|
|
685
|
+
*
|
|
686
|
+
* for (let i = 0; i < files.length; i++) {
|
|
687
|
+
* await storage.uploadFile(keys[i], files[i]);
|
|
688
|
+
* }
|
|
689
|
+
* ```
|
|
690
|
+
*/
|
|
691
|
+
declare function generateBatchKeys(fileNames: string[], prefix?: string): string[];
|
|
692
|
+
/**
|
|
693
|
+
* Validate multiple files at once with consistent options
|
|
694
|
+
* @param files Array of File objects to validate
|
|
695
|
+
* @param options Validation options
|
|
696
|
+
* @returns Array of validation results
|
|
697
|
+
* @public
|
|
698
|
+
*
|
|
699
|
+
* @example
|
|
700
|
+
* ```typescript
|
|
701
|
+
* import { validateBatchFiles } from '@pelatform/storage/helpers';
|
|
702
|
+
*
|
|
703
|
+
* const files = [file1, file2, file3]; // File objects from input
|
|
704
|
+
* const options = {
|
|
705
|
+
* maxSize: 5 * 1024 * 1024, // 5MB
|
|
706
|
+
* allowedTypes: ['image/*', 'application/pdf'],
|
|
707
|
+
* maxFiles: 10
|
|
708
|
+
* };
|
|
709
|
+
*
|
|
710
|
+
* const results = validateBatchFiles(files, options);
|
|
711
|
+
* // Returns: [
|
|
712
|
+
* // { valid: true, fileName: "image.jpg" },
|
|
713
|
+
* // { valid: false, fileName: "large.pdf", errors: ["File size exceeds limit"] },
|
|
714
|
+
* // { valid: true, fileName: "document.pdf" }
|
|
715
|
+
* // ]
|
|
716
|
+
*
|
|
717
|
+
* const validFiles = files.filter((_, index) => results[index].valid);
|
|
718
|
+
* const invalidFiles = files.filter((_, index) => !results[index].valid);
|
|
719
|
+
* ```
|
|
720
|
+
*/
|
|
721
|
+
declare function validateBatchFiles(files: File[], options: {
|
|
722
|
+
maxSize?: number;
|
|
723
|
+
allowedTypes?: string[];
|
|
724
|
+
maxFiles?: number;
|
|
725
|
+
}): Array<{
|
|
726
|
+
valid: boolean;
|
|
727
|
+
fileName: string;
|
|
728
|
+
errors?: string[];
|
|
729
|
+
}>;
|
|
730
|
+
/**
|
|
731
|
+
* Detect file type from content using magic numbers/file signatures
|
|
732
|
+
* @param buffer File content buffer
|
|
733
|
+
* @returns Detected MIME type or 'application/octet-stream' if unknown
|
|
734
|
+
* @public
|
|
735
|
+
*
|
|
736
|
+
* @example
|
|
737
|
+
* ```typescript
|
|
738
|
+
* import { detectFileTypeFromContent } from '@pelatform/storage/helpers';
|
|
739
|
+
*
|
|
740
|
+
* // Read file content
|
|
741
|
+
* const fileBuffer = await storage.downloadFile('unknown-file');
|
|
742
|
+
* const detectedType = detectFileTypeFromContent(fileBuffer.content!);
|
|
743
|
+
*
|
|
744
|
+
* console.log(detectedType);
|
|
745
|
+
* // Returns: "image/jpeg" for JPEG files
|
|
746
|
+
* // Returns: "application/pdf" for PDF files
|
|
747
|
+
* // Returns: "image/png" for PNG files
|
|
748
|
+
* // Returns: "application/octet-stream" for unknown types
|
|
749
|
+
*
|
|
750
|
+
* // Verify file type matches extension
|
|
751
|
+
* const fileName = 'document.pdf';
|
|
752
|
+
* const expectedType = getMimeType(fileName);
|
|
753
|
+
* const actualType = detectFileTypeFromContent(fileBuffer.content!);
|
|
754
|
+
*
|
|
755
|
+
* if (expectedType !== actualType) {
|
|
756
|
+
* console.warn('File extension does not match content type');
|
|
757
|
+
* }
|
|
758
|
+
* ```
|
|
759
|
+
*/
|
|
760
|
+
declare function detectFileTypeFromContent(buffer: Buffer): string;
|
|
761
|
+
|
|
762
|
+
export { base64ToBuffer, bufferToBase64, buildPublicUrl, detectFileTypeFromContent, extractS3Info, fileToBuffer, formatFileSize, generateBatchKeys, generateCacheControl, generateFileHash, generateFileKey, generateUniqueKey, getContentDisposition, getFileExtension, getFileInfo, getFileName, getMimeType, getParentPath, isAudioFile, isDocumentFile, isImageFile, isVideoFile, joinPath, normalizePath, parseS3Url, sanitizeFileName, validateBatchFiles, validateBucketName, validateFileSize, validateFileType, validateS3Config, validateS3Key };
|