@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.
package/dist/s3.js ADDED
@@ -0,0 +1,779 @@
1
+ import { s as loadS3Config } from "./config-t-NVJICl.js";
2
+ import { buildPublicUrl, getMimeType } from "./helpers.js";
3
+ import { CopyObjectCommand, DeleteObjectCommand, DeleteObjectsCommand, GetObjectCommand, HeadObjectCommand, ListObjectsV2Command, PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
4
+ import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
5
+ //#region src/operations/file-operations.ts
6
+ /**
7
+ * S3 file operations implementation
8
+ * Provides comprehensive file management operations for S3-compatible storage providers
9
+ */
10
+ /**
11
+ * S3 file operations implementation
12
+ * Handles all file-related operations for S3-compatible storage providers
13
+ * @internal
14
+ */
15
+ var FileOperations = class {
16
+ client;
17
+ config;
18
+ constructor(client, config) {
19
+ this.client = client;
20
+ this.config = config;
21
+ }
22
+ async upload(options) {
23
+ try {
24
+ const contentType = options.contentType || getMimeType(options.key);
25
+ const command = new PutObjectCommand({
26
+ Bucket: this.config.bucket,
27
+ Key: options.key,
28
+ Body: options.file,
29
+ ContentType: contentType,
30
+ Metadata: options.metadata,
31
+ CacheControl: options.cacheControl,
32
+ ContentDisposition: options.contentDisposition,
33
+ ACL: options.acl,
34
+ Expires: options.expires
35
+ });
36
+ const result = await this.client.send(command);
37
+ const publicUrl = this.getPublicUrl(options.key);
38
+ return {
39
+ success: true,
40
+ key: options.key,
41
+ url: publicUrl,
42
+ publicUrl,
43
+ etag: result.ETag?.replace(/"/g, ""),
44
+ size: typeof options.file === "string" ? Buffer.byteLength(options.file, "utf8") : options.file.length
45
+ };
46
+ } catch (error) {
47
+ return {
48
+ success: false,
49
+ error: error instanceof Error ? error.message : "Upload failed"
50
+ };
51
+ }
52
+ }
53
+ async download(options) {
54
+ try {
55
+ const command = new GetObjectCommand({
56
+ Bucket: this.config.bucket,
57
+ Key: options.key,
58
+ Range: options.range
59
+ });
60
+ const result = await this.client.send(command);
61
+ if (!result.Body) return {
62
+ success: false,
63
+ error: "No data received"
64
+ };
65
+ const chunks = [];
66
+ const reader = result.Body.transformToWebStream().getReader();
67
+ while (true) {
68
+ const { done, value } = await reader.read();
69
+ if (done) break;
70
+ chunks.push(value);
71
+ }
72
+ const data = Buffer.concat(chunks);
73
+ return {
74
+ success: true,
75
+ content: data,
76
+ data,
77
+ contentType: result.ContentType,
78
+ contentLength: result.ContentLength,
79
+ lastModified: result.LastModified,
80
+ etag: result.ETag?.replace(/"/g, ""),
81
+ metadata: result.Metadata
82
+ };
83
+ } catch (error) {
84
+ return {
85
+ success: false,
86
+ error: error instanceof Error ? error.message : "Download failed"
87
+ };
88
+ }
89
+ }
90
+ async delete(options) {
91
+ try {
92
+ const command = new DeleteObjectCommand({
93
+ Bucket: this.config.bucket,
94
+ Key: options.key
95
+ });
96
+ await this.client.send(command);
97
+ return { success: true };
98
+ } catch (error) {
99
+ return {
100
+ success: false,
101
+ error: error instanceof Error ? error.message : "Delete failed"
102
+ };
103
+ }
104
+ }
105
+ async batchDelete(options) {
106
+ try {
107
+ const command = new DeleteObjectsCommand({
108
+ Bucket: this.config.bucket,
109
+ Delete: {
110
+ Objects: options.keys.map((key) => ({ Key: key })),
111
+ Quiet: false
112
+ }
113
+ });
114
+ const result = await this.client.send(command);
115
+ const deleted = result.Deleted?.map((obj) => obj.Key).filter(Boolean);
116
+ const errors = result.Errors?.map((err) => ({
117
+ key: err.Key || "",
118
+ error: err.Message || "Unknown error"
119
+ })) || [];
120
+ return {
121
+ success: true,
122
+ deleted,
123
+ errors: errors.length > 0 ? errors : void 0
124
+ };
125
+ } catch (error) {
126
+ return {
127
+ success: false,
128
+ errors: options.keys.map((key) => ({
129
+ key,
130
+ error: error instanceof Error ? error.message : "Batch delete failed"
131
+ }))
132
+ };
133
+ }
134
+ }
135
+ async list(options = {}) {
136
+ try {
137
+ const command = new ListObjectsV2Command({
138
+ Bucket: this.config.bucket,
139
+ Prefix: options.prefix,
140
+ Delimiter: options.delimiter,
141
+ MaxKeys: options.maxKeys,
142
+ ContinuationToken: options.continuationToken
143
+ });
144
+ const result = await this.client.send(command);
145
+ return {
146
+ success: true,
147
+ files: result.Contents?.map((obj) => ({
148
+ key: obj.Key,
149
+ size: obj.Size || 0,
150
+ lastModified: obj.LastModified || /* @__PURE__ */ new Date(),
151
+ etag: obj.ETag?.replace(/"/g, "") || "",
152
+ contentType: getMimeType(obj.Key)
153
+ })) || [],
154
+ isTruncated: result.IsTruncated,
155
+ nextContinuationToken: result.NextContinuationToken,
156
+ commonPrefixes: result.CommonPrefixes?.map((cp) => cp.Prefix)
157
+ };
158
+ } catch (error) {
159
+ return {
160
+ success: false,
161
+ error: error instanceof Error ? error.message : "List failed"
162
+ };
163
+ }
164
+ }
165
+ async exists(key) {
166
+ try {
167
+ const command = new HeadObjectCommand({
168
+ Bucket: this.config.bucket,
169
+ Key: key
170
+ });
171
+ const result = await this.client.send(command);
172
+ return {
173
+ exists: true,
174
+ fileInfo: {
175
+ key,
176
+ size: result.ContentLength || 0,
177
+ lastModified: result.LastModified || /* @__PURE__ */ new Date(),
178
+ etag: result.ETag?.replace(/"/g, "") || "",
179
+ contentType: result.ContentType,
180
+ metadata: result.Metadata
181
+ }
182
+ };
183
+ } catch (error) {
184
+ if (error instanceof Error && error.name === "NotFound") return { exists: false };
185
+ return {
186
+ exists: false,
187
+ error: error instanceof Error ? error.message : "Check existence failed"
188
+ };
189
+ }
190
+ }
191
+ async copy(options) {
192
+ try {
193
+ const command = new CopyObjectCommand({
194
+ Bucket: this.config.bucket,
195
+ CopySource: `${this.config.bucket}/${options.sourceKey}`,
196
+ Key: options.destinationKey,
197
+ Metadata: options.metadata,
198
+ MetadataDirective: options.metadataDirective || "COPY"
199
+ });
200
+ return {
201
+ success: true,
202
+ etag: (await this.client.send(command)).CopyObjectResult?.ETag?.replace(/"/g, "")
203
+ };
204
+ } catch (error) {
205
+ return {
206
+ success: false,
207
+ error: error instanceof Error ? error.message : "Copy failed"
208
+ };
209
+ }
210
+ }
211
+ async move(options) {
212
+ try {
213
+ const copyResult = await this.copy({
214
+ sourceKey: options.sourceKey,
215
+ destinationKey: options.destinationKey,
216
+ metadata: options.metadata,
217
+ metadataDirective: options.metadataDirective
218
+ });
219
+ if (!copyResult.success) return {
220
+ success: false,
221
+ error: copyResult.error || "Move failed during copy operation"
222
+ };
223
+ const deleteResult = await this.delete({ key: options.sourceKey });
224
+ if (!deleteResult.success) return {
225
+ success: false,
226
+ error: deleteResult.error || "Move failed during delete operation"
227
+ };
228
+ return {
229
+ success: true,
230
+ etag: copyResult.etag
231
+ };
232
+ } catch (error) {
233
+ return {
234
+ success: false,
235
+ error: error instanceof Error ? error.message : "Move failed"
236
+ };
237
+ }
238
+ }
239
+ async duplicate(options) {
240
+ return this.copy(options);
241
+ }
242
+ async getPresignedUrl(options) {
243
+ try {
244
+ const expiresIn = options.expiresIn || 3600;
245
+ let command;
246
+ if (options.operation === "get") command = new GetObjectCommand({
247
+ Bucket: this.config.bucket,
248
+ Key: options.key
249
+ });
250
+ else command = new PutObjectCommand({
251
+ Bucket: this.config.bucket,
252
+ Key: options.key,
253
+ ContentType: options.contentType
254
+ });
255
+ return {
256
+ success: true,
257
+ url: await getSignedUrl(this.client, command, { expiresIn }),
258
+ expiresAt: new Date(Date.now() + expiresIn * 1e3)
259
+ };
260
+ } catch (error) {
261
+ return {
262
+ success: false,
263
+ error: error instanceof Error ? error.message : "Presigned URL generation failed"
264
+ };
265
+ }
266
+ }
267
+ getPublicUrl(key) {
268
+ const isCloudflare = this.config.provider === "cloudflare-r2";
269
+ const isSupabase = this.config.provider === "supabase";
270
+ if (this.config.publicUrl) return buildPublicUrl(this.config.publicUrl, isCloudflare ? "" : this.config.bucket, key, isSupabase);
271
+ if (this.config.endpoint) return buildPublicUrl(this.config.endpoint, this.config.bucket, key, isSupabase);
272
+ return `https://${this.config.bucket}.s3.${this.config.region}.amazonaws.com/${key}`;
273
+ }
274
+ };
275
+ //#endregion
276
+ //#region src/operations/folder-operations.ts
277
+ /**
278
+ * S3 folder operations implementation
279
+ * Provides comprehensive folder management operations for S3-compatible storage providers
280
+ */
281
+ /**
282
+ * S3 folder operations implementation
283
+ * Handles all folder-related operations for S3-compatible storage providers
284
+ * @internal
285
+ */
286
+ var FolderOperations = class {
287
+ client;
288
+ config;
289
+ constructor(client, config) {
290
+ this.client = client;
291
+ this.config = config;
292
+ }
293
+ async createFolder(options) {
294
+ try {
295
+ const folderPath = options.path.endsWith("/") ? options.path : `${options.path}/`;
296
+ const command = new PutObjectCommand({
297
+ Bucket: this.config.bucket,
298
+ Key: folderPath,
299
+ Body: "",
300
+ ContentType: "application/x-directory"
301
+ });
302
+ await this.client.send(command);
303
+ return {
304
+ success: true,
305
+ path: folderPath
306
+ };
307
+ } catch (error) {
308
+ return {
309
+ success: false,
310
+ error: error instanceof Error ? error.message : "Create folder failed"
311
+ };
312
+ }
313
+ }
314
+ async deleteFolder(options) {
315
+ try {
316
+ const folderPath = options.path.endsWith("/") ? options.path : `${options.path}/`;
317
+ if (options.recursive) {
318
+ const listCommand = new ListObjectsV2Command({
319
+ Bucket: this.config.bucket,
320
+ Prefix: folderPath
321
+ });
322
+ const listResult = await this.client.send(listCommand);
323
+ if (!listResult.Contents || listResult.Contents.length === 0) return {
324
+ success: true,
325
+ deletedFiles: []
326
+ };
327
+ const deleteCommand = new DeleteObjectsCommand({
328
+ Bucket: this.config.bucket,
329
+ Delete: {
330
+ Objects: listResult.Contents.map((obj) => ({ Key: obj.Key })),
331
+ Quiet: false
332
+ }
333
+ });
334
+ return {
335
+ success: true,
336
+ deletedFiles: (await this.client.send(deleteCommand)).Deleted?.map((obj) => obj.Key).filter(Boolean) || []
337
+ };
338
+ } else {
339
+ const deleteCommand = new DeleteObjectsCommand({
340
+ Bucket: this.config.bucket,
341
+ Delete: {
342
+ Objects: [{ Key: folderPath }],
343
+ Quiet: false
344
+ }
345
+ });
346
+ await this.client.send(deleteCommand);
347
+ return {
348
+ success: true,
349
+ deletedFiles: [folderPath]
350
+ };
351
+ }
352
+ } catch (error) {
353
+ return {
354
+ success: false,
355
+ error: error instanceof Error ? error.message : "Delete folder failed"
356
+ };
357
+ }
358
+ }
359
+ async listFolders(options = {}) {
360
+ try {
361
+ const command = new ListObjectsV2Command({
362
+ Bucket: this.config.bucket,
363
+ Prefix: options.prefix,
364
+ Delimiter: options.delimiter || "/",
365
+ MaxKeys: options.maxKeys,
366
+ ContinuationToken: options.continuationToken
367
+ });
368
+ const result = await this.client.send(command);
369
+ return {
370
+ success: true,
371
+ folders: result.CommonPrefixes?.map((cp) => {
372
+ const path = cp.Prefix;
373
+ return {
374
+ name: path.split("/").filter(Boolean).pop() || "",
375
+ path,
376
+ size: 0,
377
+ fileCount: 0,
378
+ lastModified: /* @__PURE__ */ new Date()
379
+ };
380
+ }) || [],
381
+ files: result.Contents?.map((obj) => ({
382
+ key: obj.Key,
383
+ size: obj.Size || 0,
384
+ lastModified: obj.LastModified || /* @__PURE__ */ new Date(),
385
+ etag: obj.ETag?.replace(/"/g, "") || "",
386
+ contentType: getMimeType(obj.Key)
387
+ })) || [],
388
+ isTruncated: result.IsTruncated,
389
+ nextContinuationToken: result.NextContinuationToken
390
+ };
391
+ } catch (error) {
392
+ return {
393
+ success: false,
394
+ error: error instanceof Error ? error.message : "List folders failed"
395
+ };
396
+ }
397
+ }
398
+ async folderExists(path) {
399
+ try {
400
+ const folderPath = path.endsWith("/") ? path : `${path}/`;
401
+ const command = new ListObjectsV2Command({
402
+ Bucket: this.config.bucket,
403
+ Prefix: folderPath,
404
+ MaxKeys: 1
405
+ });
406
+ const result = await this.client.send(command);
407
+ if (result.Contents && result.Contents.length > 0 || result.CommonPrefixes && result.CommonPrefixes.length > 0) return {
408
+ exists: true,
409
+ folderInfo: {
410
+ name: folderPath.split("/").filter(Boolean).pop() || "",
411
+ path: folderPath,
412
+ size: 0,
413
+ fileCount: 0,
414
+ lastModified: /* @__PURE__ */ new Date()
415
+ }
416
+ };
417
+ return { exists: false };
418
+ } catch (error) {
419
+ return {
420
+ exists: false,
421
+ error: error instanceof Error ? error.message : "Check folder existence failed"
422
+ };
423
+ }
424
+ }
425
+ async renameFolder(options) {
426
+ try {
427
+ const oldPath = options.oldPath.endsWith("/") ? options.oldPath : `${options.oldPath}/`;
428
+ const newPath = options.newPath.endsWith("/") ? options.newPath : `${options.newPath}/`;
429
+ const listCommand = new ListObjectsV2Command({
430
+ Bucket: this.config.bucket,
431
+ Prefix: oldPath
432
+ });
433
+ const listResult = await this.client.send(listCommand);
434
+ if (!listResult.Contents || listResult.Contents.length === 0) return {
435
+ success: true,
436
+ movedFiles: []
437
+ };
438
+ const movedFiles = [];
439
+ for (const obj of listResult.Contents) {
440
+ const oldKey = obj.Key;
441
+ const newKey = oldKey.replace(oldPath, newPath);
442
+ const copyCommand = new CopyObjectCommand({
443
+ Bucket: this.config.bucket,
444
+ Key: newKey,
445
+ CopySource: `${this.config.bucket}/${oldKey}`
446
+ });
447
+ await this.client.send(copyCommand);
448
+ movedFiles.push(newKey);
449
+ }
450
+ const deleteCommand = new DeleteObjectsCommand({
451
+ Bucket: this.config.bucket,
452
+ Delete: {
453
+ Objects: listResult.Contents.map((obj) => ({ Key: obj.Key })),
454
+ Quiet: true
455
+ }
456
+ });
457
+ await this.client.send(deleteCommand);
458
+ return {
459
+ success: true,
460
+ movedFiles
461
+ };
462
+ } catch (error) {
463
+ return {
464
+ success: false,
465
+ error: error instanceof Error ? error.message : "Rename folder failed"
466
+ };
467
+ }
468
+ }
469
+ async copyFolder(options) {
470
+ try {
471
+ const sourcePath = options.sourcePath.endsWith("/") ? options.sourcePath : `${options.sourcePath}/`;
472
+ const destPath = options.destinationPath.endsWith("/") ? options.destinationPath : `${options.destinationPath}/`;
473
+ const listCommand = new ListObjectsV2Command({
474
+ Bucket: this.config.bucket,
475
+ Prefix: sourcePath
476
+ });
477
+ const listResult = await this.client.send(listCommand);
478
+ if (!listResult.Contents || listResult.Contents.length === 0) return {
479
+ success: true,
480
+ copiedFiles: []
481
+ };
482
+ const copiedFiles = [];
483
+ for (const obj of listResult.Contents) {
484
+ const sourceKey = obj.Key;
485
+ const destKey = sourceKey.replace(sourcePath, destPath);
486
+ const copyCommand = new CopyObjectCommand({
487
+ Bucket: this.config.bucket,
488
+ Key: destKey,
489
+ CopySource: `${this.config.bucket}/${sourceKey}`
490
+ });
491
+ await this.client.send(copyCommand);
492
+ copiedFiles.push(destKey);
493
+ }
494
+ return {
495
+ success: true,
496
+ copiedFiles
497
+ };
498
+ } catch (error) {
499
+ return {
500
+ success: false,
501
+ error: error instanceof Error ? error.message : "Copy folder failed"
502
+ };
503
+ }
504
+ }
505
+ };
506
+ //#endregion
507
+ //#region src/providers/s3.ts
508
+ /**
509
+ * S3-compatible storage provider implementation
510
+ * Provides cloud storage operations using AWS S3 SDK for S3-compatible services
511
+ */
512
+ /**
513
+ * S3-compatible storage provider
514
+ * Implements StorageInterface for AWS S3 and S3-compatible services
515
+ * @internal
516
+ */
517
+ var S3Provider = class {
518
+ client;
519
+ config;
520
+ fileOps;
521
+ folderOps;
522
+ constructor(config) {
523
+ this.config = config;
524
+ this.client = new S3Client({
525
+ region: config.region,
526
+ credentials: {
527
+ accessKeyId: config.accessKeyId,
528
+ secretAccessKey: config.secretAccessKey
529
+ },
530
+ endpoint: config.endpoint,
531
+ forcePathStyle: config.forcePathStyle || false
532
+ });
533
+ this.fileOps = new FileOperations(this.client, this.config);
534
+ this.folderOps = new FolderOperations(this.client, this.config);
535
+ }
536
+ async upload(options) {
537
+ return this.fileOps.upload(options);
538
+ }
539
+ async download(options) {
540
+ return this.fileOps.download(options);
541
+ }
542
+ async delete(options) {
543
+ return this.fileOps.delete(options);
544
+ }
545
+ async batchDelete(options) {
546
+ return this.fileOps.batchDelete(options);
547
+ }
548
+ async list(options) {
549
+ return this.fileOps.list(options);
550
+ }
551
+ async exists(key) {
552
+ return this.fileOps.exists(key);
553
+ }
554
+ async copy(options) {
555
+ return this.fileOps.copy(options);
556
+ }
557
+ async move(options) {
558
+ return this.fileOps.move(options);
559
+ }
560
+ async duplicate(options) {
561
+ return this.fileOps.duplicate(options);
562
+ }
563
+ async getPresignedUrl(options) {
564
+ return this.fileOps.getPresignedUrl(options);
565
+ }
566
+ getPublicUrl(key) {
567
+ return this.fileOps.getPublicUrl(key);
568
+ }
569
+ async createFolder(options) {
570
+ return this.folderOps.createFolder(options);
571
+ }
572
+ async deleteFolder(options) {
573
+ return this.folderOps.deleteFolder(options);
574
+ }
575
+ async listFolders(options) {
576
+ return this.folderOps.listFolders(options);
577
+ }
578
+ async folderExists(path) {
579
+ return this.folderOps.folderExists(path);
580
+ }
581
+ async renameFolder(options) {
582
+ return this.folderOps.renameFolder(options);
583
+ }
584
+ async copyFolder(options) {
585
+ return this.folderOps.copyFolder(options);
586
+ }
587
+ };
588
+ //#endregion
589
+ //#region src/services/s3.ts
590
+ /**
591
+ * S3 storage service implementation
592
+ * High-level service wrapper for S3-compatible storage operations with convenience methods
593
+ */
594
+ /**
595
+ * S3 storage service
596
+ * High-level service for S3-compatible storage operations with convenience methods
597
+ * @public
598
+ */
599
+ var S3Service = class {
600
+ provider;
601
+ config;
602
+ constructor(config) {
603
+ this.config = config || loadS3Config();
604
+ this.provider = this.createProvider(this.config);
605
+ }
606
+ createProvider(config) {
607
+ switch (config.provider) {
608
+ case "aws":
609
+ case "cloudflare-r2":
610
+ case "minio":
611
+ case "digitalocean":
612
+ case "supabase":
613
+ case "custom": return new S3Provider(config);
614
+ default: throw new Error(`Unsupported S3 provider: ${config.provider}`);
615
+ }
616
+ }
617
+ getConfig() {
618
+ return { ...this.config };
619
+ }
620
+ getBucket() {
621
+ return this.config.bucket;
622
+ }
623
+ getRegion() {
624
+ return this.config.region;
625
+ }
626
+ getProvider() {
627
+ return this.config.provider;
628
+ }
629
+ getPublicUrl(key) {
630
+ return this.provider.getPublicUrl(key);
631
+ }
632
+ async upload(options) {
633
+ return this.provider.upload(options);
634
+ }
635
+ async download(options) {
636
+ return this.provider.download(options);
637
+ }
638
+ async delete(options) {
639
+ return this.provider.delete(options);
640
+ }
641
+ async batchDelete(options) {
642
+ return this.provider.batchDelete(options);
643
+ }
644
+ async list(options) {
645
+ return this.provider.list(options);
646
+ }
647
+ async exists(key) {
648
+ return this.provider.exists(key);
649
+ }
650
+ async copy(options) {
651
+ return this.provider.copy(options);
652
+ }
653
+ async move(options) {
654
+ return this.provider.move(options);
655
+ }
656
+ async duplicate(options) {
657
+ return this.provider.duplicate(options);
658
+ }
659
+ async getPresignedUrl(options) {
660
+ return this.provider.getPresignedUrl(options);
661
+ }
662
+ async createFolder(options) {
663
+ return this.provider.createFolder(options);
664
+ }
665
+ async deleteFolder(options) {
666
+ return this.provider.deleteFolder(options);
667
+ }
668
+ async listFolders(options) {
669
+ return this.provider.listFolders(options);
670
+ }
671
+ async folderExists(path) {
672
+ return this.provider.folderExists(path);
673
+ }
674
+ async renameFolder(options) {
675
+ return this.provider.renameFolder(options);
676
+ }
677
+ async copyFolder(options) {
678
+ return this.provider.copyFolder(options);
679
+ }
680
+ async uploadFile(key, file, options) {
681
+ return this.upload({
682
+ key,
683
+ file,
684
+ ...options
685
+ });
686
+ }
687
+ async downloadFile(key) {
688
+ return this.download({ key });
689
+ }
690
+ async deleteFile(key) {
691
+ return this.delete({ key });
692
+ }
693
+ async deleteFiles(keys) {
694
+ return this.batchDelete({ keys });
695
+ }
696
+ async listFiles(prefix, maxKeys) {
697
+ return this.list({
698
+ prefix,
699
+ maxKeys
700
+ });
701
+ }
702
+ async fileExists(key) {
703
+ return (await this.exists(key)).exists;
704
+ }
705
+ async copyFile(sourceKey, destinationKey, options) {
706
+ return this.copy({
707
+ sourceKey,
708
+ destinationKey,
709
+ ...options
710
+ });
711
+ }
712
+ async moveFile(sourceKey, destinationKey, options) {
713
+ return this.move({
714
+ sourceKey,
715
+ destinationKey,
716
+ ...options
717
+ });
718
+ }
719
+ async duplicateFile(sourceKey, destinationKey, options) {
720
+ return this.duplicate({
721
+ sourceKey,
722
+ destinationKey,
723
+ ...options
724
+ });
725
+ }
726
+ async renameFile(sourceKey, newKey, options) {
727
+ return this.moveFile(sourceKey, newKey, options);
728
+ }
729
+ async getDownloadUrl(key, expiresIn) {
730
+ return this.getPresignedUrl({
731
+ key,
732
+ operation: "get",
733
+ expiresIn
734
+ });
735
+ }
736
+ async getUploadUrl(key, contentType, expiresIn) {
737
+ return this.getPresignedUrl({
738
+ key,
739
+ operation: "put",
740
+ contentType,
741
+ expiresIn
742
+ });
743
+ }
744
+ async createFolderPath(path) {
745
+ return this.createFolder({ path });
746
+ }
747
+ async deleteFolderPath(path, recursive = false) {
748
+ return this.deleteFolder({
749
+ path,
750
+ recursive
751
+ });
752
+ }
753
+ async folderPathExists(path) {
754
+ return (await this.folderExists(path)).exists;
755
+ }
756
+ async renameFolderPath(oldPath, newPath) {
757
+ return this.renameFolder({
758
+ oldPath,
759
+ newPath
760
+ });
761
+ }
762
+ async copyFolderPath(sourcePath, destinationPath, recursive = true) {
763
+ return this.copyFolder({
764
+ sourcePath,
765
+ destinationPath,
766
+ recursive
767
+ });
768
+ }
769
+ };
770
+ //#endregion
771
+ //#region src/s3.ts
772
+ function createS3(config, env) {
773
+ if (config) return new S3Service(config);
774
+ return new S3Service(loadS3Config(env));
775
+ }
776
+ //#endregion
777
+ export { S3Service, createS3 };
778
+
779
+ //# sourceMappingURL=s3.js.map