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