@ooneex/storage 1.1.4 → 1.1.6

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/index.d.ts CHANGED
@@ -28,10 +28,7 @@ interface IStorage {
28
28
  declare class BunnyStorage implements IStorage {
29
29
  private readonly env;
30
30
  private bucket;
31
- private readonly accessKey;
32
31
  private readonly storageZone;
33
- private readonly region;
34
- private readonly baseUrl;
35
32
  constructor(env: AppEnv);
36
33
  getBucket(): string;
37
34
  setBucket(name: string): this;
@@ -46,7 +43,8 @@ declare class BunnyStorage implements IStorage {
46
43
  getAsJson<T = unknown>(key: string): Promise<T>;
47
44
  getAsArrayBuffer(key: string): Promise<ArrayBuffer>;
48
45
  getAsStream(key: string): ReadableStream;
49
- private buildFileUrl;
46
+ private buildFilePath;
47
+ private toReadableStream;
50
48
  }
51
49
  import { AppEnv as AppEnv2 } from "@ooneex/app-env";
52
50
  import { S3Options as S3Options2 } from "bun";
@@ -110,6 +108,6 @@ declare class FilesystemStorage extends Storage {
110
108
  }
111
109
  import { Exception } from "@ooneex/exception";
112
110
  declare class StorageException extends Exception {
113
- constructor(message: string, data?: Record<string, unknown>);
111
+ constructor(message: string, key: string, data?: Record<string, unknown>);
114
112
  }
115
113
  export { decorator, StorageException, StorageClassType, Storage, PutDirOptionsType, IStorage, GetFileOptionsType, FilesystemStorage, CloudflareStorage, BunnyStorage };
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ var __legacyMetadataTS = (k, v) => {
18
18
  // src/BunnyStorage.ts
19
19
  import { readdir } from "fs/promises";
20
20
  import { basename, join } from "path";
21
+ import * as BunnyStorageSDK from "@bunny.net/storage-sdk";
21
22
  import { AppEnv } from "@ooneex/app-env";
22
23
  import { inject } from "@ooneex/container";
23
24
 
@@ -36,8 +37,9 @@ import { Exception } from "@ooneex/exception";
36
37
  import { HttpStatus } from "@ooneex/http-status";
37
38
 
38
39
  class StorageException extends Exception {
39
- constructor(message, data = {}) {
40
+ constructor(message, key, data = {}) {
40
41
  super(message, {
42
+ key,
41
43
  status: HttpStatus.Code.InternalServerError,
42
44
  data
43
45
  });
@@ -46,40 +48,35 @@ class StorageException extends Exception {
46
48
  }
47
49
 
48
50
  // src/BunnyStorage.ts
49
- var REGION_ENDPOINTS = {
50
- de: "storage.bunnycdn.com",
51
- uk: "uk.storage.bunnycdn.com",
52
- ny: "ny.storage.bunnycdn.com",
53
- la: "la.storage.bunnycdn.com",
54
- sg: "sg.storage.bunnycdn.com",
55
- se: "se.storage.bunnycdn.com",
56
- br: "br.storage.bunnycdn.com",
57
- jh: "jh.storage.bunnycdn.com",
58
- syd: "syd.storage.bunnycdn.com"
51
+ var REGION_MAP = {
52
+ de: BunnyStorageSDK.regions.StorageRegion.Falkenstein,
53
+ uk: BunnyStorageSDK.regions.StorageRegion.London,
54
+ ny: BunnyStorageSDK.regions.StorageRegion.NewYork,
55
+ la: BunnyStorageSDK.regions.StorageRegion.LosAngeles,
56
+ sg: BunnyStorageSDK.regions.StorageRegion.Singapore,
57
+ se: BunnyStorageSDK.regions.StorageRegion.Stockholm,
58
+ br: BunnyStorageSDK.regions.StorageRegion.SaoPaulo,
59
+ jh: BunnyStorageSDK.regions.StorageRegion.Johannesburg,
60
+ syd: BunnyStorageSDK.regions.StorageRegion.Sydney
59
61
  };
60
62
 
61
63
  class BunnyStorage {
62
64
  env;
63
65
  bucket = "";
64
- accessKey;
65
66
  storageZone;
66
- region;
67
- baseUrl;
68
67
  constructor(env) {
69
68
  this.env = env;
70
69
  const accessKey = this.env.STORAGE_BUNNY_ACCESS_KEY;
71
70
  const storageZone = this.env.STORAGE_BUNNY_STORAGE_ZONE;
72
71
  const region = this.env.STORAGE_BUNNY_REGION;
73
72
  if (!accessKey) {
74
- throw new StorageException("Bunny access key is required. Please provide an access key either through the constructor options or set the STORAGE_BUNNY_ACCESS_KEY environment variable.");
73
+ throw new StorageException("Bunny access key is required. Please provide an access key either through the constructor options or set the STORAGE_BUNNY_ACCESS_KEY environment variable.", "API_KEY_REQUIRED");
75
74
  }
76
75
  if (!storageZone) {
77
- throw new StorageException("Bunny storage zone is required. Please provide a storage zone either through the constructor options or set the STORAGE_BUNNY_STORAGE_ZONE environment variable.");
76
+ throw new StorageException("Bunny storage zone is required. Please provide a storage zone either through the constructor options or set the STORAGE_BUNNY_STORAGE_ZONE environment variable.", "STORAGE_ZONE_REQUIRED");
78
77
  }
79
- this.accessKey = accessKey;
80
- this.storageZone = storageZone;
81
- this.region = region ?? "de";
82
- this.baseUrl = `https://${REGION_ENDPOINTS[this.region]}`;
78
+ const sdkRegion = REGION_MAP[region ?? "de"];
79
+ this.storageZone = BunnyStorageSDK.zone.connect_with_accesskey(sdkRegion, storageZone, accessKey);
83
80
  }
84
81
  getBucket() {
85
82
  return this.bucket;
@@ -89,23 +86,15 @@ class BunnyStorage {
89
86
  return this;
90
87
  }
91
88
  async list() {
92
- const path = this.bucket ? `${this.bucket}/` : "";
93
- const url = `${this.baseUrl}/${this.storageZone}/${path}`;
94
- const response = await fetch(url, {
95
- method: "GET",
96
- headers: {
97
- AccessKey: this.accessKey,
98
- accept: "application/json"
99
- }
100
- });
101
- if (!response.ok) {
102
- throw new StorageException(`Failed to list files: ${response.status} ${response.statusText}`, {
103
- status: response.status,
89
+ const path = this.bucket ? `/${this.bucket}/` : "/";
90
+ try {
91
+ const files = await BunnyStorageSDK.file.list(this.storageZone, path);
92
+ return files.filter((file2) => !file2.isDirectory).map((file2) => file2.objectName);
93
+ } catch (error) {
94
+ throw new StorageException(`Failed to list files: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_LIST_FAILED", {
104
95
  path
105
96
  });
106
97
  }
107
- const files = await response.json();
108
- return files.filter((file) => !file.IsDirectory).map((file) => file.ObjectName);
109
98
  }
110
99
  async clearBucket() {
111
100
  const keys = await this.list();
@@ -113,33 +102,21 @@ class BunnyStorage {
113
102
  return this;
114
103
  }
115
104
  async exists(key) {
116
- const url = this.buildFileUrl(key);
117
- const response = await fetch(url, {
118
- method: "HEAD",
119
- headers: {
120
- AccessKey: this.accessKey
121
- }
122
- });
123
- return response.ok;
105
+ try {
106
+ await BunnyStorageSDK.file.get(this.storageZone, this.buildFilePath(key));
107
+ return true;
108
+ } catch {
109
+ return false;
110
+ }
124
111
  }
125
112
  async delete(key) {
126
- const url = this.buildFileUrl(key);
127
- const response = await fetch(url, {
128
- method: "DELETE",
129
- headers: {
130
- AccessKey: this.accessKey
131
- }
132
- });
133
- if (!response.ok && response.status !== 404) {
134
- throw new StorageException(`Failed to delete file: ${response.status} ${response.statusText}`, {
135
- status: response.status,
136
- key
137
- });
138
- }
113
+ try {
114
+ await BunnyStorageSDK.file.remove(this.storageZone, this.buildFilePath(key));
115
+ } catch {}
139
116
  }
140
117
  async putFile(key, localPath) {
141
- const file = Bun.file(localPath);
142
- return await this.put(key, file);
118
+ const file2 = Bun.file(localPath);
119
+ return await this.put(key, file2);
143
120
  }
144
121
  async putDir(bucket, options) {
145
122
  const { path, filter } = options;
@@ -165,54 +142,16 @@ class BunnyStorage {
165
142
  return results.reduce((sum, bytes) => sum + bytes, 0);
166
143
  }
167
144
  async put(key, content) {
168
- const url = this.buildFileUrl(key);
169
- let body;
170
- let contentLength;
171
- if (typeof content === "string") {
172
- body = content;
173
- contentLength = new TextEncoder().encode(content).length;
174
- } else if (content instanceof ArrayBuffer) {
175
- body = new Blob([content]);
176
- contentLength = content.byteLength;
177
- } else if (content instanceof SharedArrayBuffer) {
178
- const uint8Array = new Uint8Array(content);
179
- const copiedArray = new Uint8Array(uint8Array.length);
180
- copiedArray.set(uint8Array);
181
- body = new Blob([copiedArray]);
182
- contentLength = content.byteLength;
183
- } else if (ArrayBuffer.isView(content)) {
184
- body = new Blob([new Uint8Array(content.buffer, content.byteOffset, content.byteLength)]);
185
- contentLength = content.byteLength;
186
- } else if (content instanceof Blob) {
187
- body = content;
188
- contentLength = content.size;
189
- } else if (content instanceof Request || content instanceof Response) {
190
- const arrayBuffer = await content.arrayBuffer();
191
- body = new Blob([arrayBuffer]);
192
- contentLength = arrayBuffer.byteLength;
193
- } else if (typeof content === "object" && content !== null && "arrayBuffer" in content) {
194
- const fileContent = content;
195
- const arrayBuffer = await fileContent.arrayBuffer();
196
- body = new Blob([arrayBuffer]);
197
- contentLength = arrayBuffer.byteLength;
198
- } else {
199
- throw new StorageException("Unsupported content type for upload", { key });
200
- }
201
- const response = await fetch(url, {
202
- method: "PUT",
203
- headers: {
204
- AccessKey: this.accessKey,
205
- "Content-Type": "application/octet-stream"
206
- },
207
- body
208
- });
209
- if (!response.ok) {
210
- throw new StorageException(`Failed to upload file: ${response.status} ${response.statusText}`, {
211
- status: response.status,
145
+ const { stream, length } = await this.toReadableStream(content);
146
+ const filePath = this.buildFilePath(key);
147
+ try {
148
+ await BunnyStorageSDK.file.upload(this.storageZone, filePath, stream);
149
+ } catch (error) {
150
+ throw new StorageException(`Failed to upload file: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_UPLOAD_FAILED", {
212
151
  key
213
152
  });
214
153
  }
215
- return contentLength;
154
+ return length;
216
155
  }
217
156
  async getFile(key, options) {
218
157
  const arrayBuffer = await this.getAsArrayBuffer(key);
@@ -221,63 +160,65 @@ class BunnyStorage {
221
160
  return await Bun.write(localPath, arrayBuffer);
222
161
  }
223
162
  async getAsJson(key) {
224
- const url = this.buildFileUrl(key);
225
- const response = await fetch(url, {
226
- method: "GET",
227
- headers: {
228
- AccessKey: this.accessKey
229
- }
230
- });
231
- if (!response.ok) {
232
- throw new StorageException(`Failed to get file as JSON: ${response.status} ${response.statusText}`, {
233
- status: response.status,
234
- key
235
- });
163
+ try {
164
+ const { stream } = await BunnyStorageSDK.file.download(this.storageZone, this.buildFilePath(key));
165
+ return await new Response(stream).json();
166
+ } catch (error) {
167
+ throw new StorageException(`Failed to get file as JSON: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_DOWNLOAD_FAILED", { key });
236
168
  }
237
- return await response.json();
238
169
  }
239
170
  async getAsArrayBuffer(key) {
240
- const url = this.buildFileUrl(key);
241
- const response = await fetch(url, {
242
- method: "GET",
243
- headers: {
244
- AccessKey: this.accessKey
245
- }
246
- });
247
- if (!response.ok) {
248
- throw new StorageException(`Failed to get file as ArrayBuffer: ${response.status} ${response.statusText}`, {
249
- status: response.status,
250
- key
251
- });
171
+ try {
172
+ const { stream } = await BunnyStorageSDK.file.download(this.storageZone, this.buildFilePath(key));
173
+ return await new Response(stream).arrayBuffer();
174
+ } catch (error) {
175
+ throw new StorageException(`Failed to get file as ArrayBuffer: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_DOWNLOAD_FAILED", { key });
252
176
  }
253
- return await response.arrayBuffer();
254
177
  }
255
178
  getAsStream(key) {
256
- const url = this.buildFileUrl(key);
257
- const accessKey = this.accessKey;
179
+ const filePath = this.buildFilePath(key);
258
180
  const { readable, writable } = new TransformStream;
259
- fetch(url, {
260
- method: "GET",
261
- headers: { AccessKey: accessKey }
262
- }).then((response) => {
263
- if (!response.ok) {
264
- writable.abort(new StorageException(`Failed to get file as stream: ${response.status} ${response.statusText}`, {
265
- status: response.status,
266
- key
267
- }));
268
- return;
269
- }
270
- if (!response.body) {
271
- writable.abort(new StorageException("Response body is null", { key }));
272
- return;
273
- }
274
- response.body.pipeTo(writable);
181
+ BunnyStorageSDK.file.download(this.storageZone, filePath).then(({ stream }) => {
182
+ stream.pipeTo(writable);
183
+ }).catch((error) => {
184
+ writable.abort(new StorageException(`Failed to get file as stream: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_DOWNLOAD_FAILED", { key }));
275
185
  });
276
186
  return readable;
277
187
  }
278
- buildFileUrl(key) {
279
- const path = this.bucket ? `${this.bucket}/${key}` : key;
280
- return `${this.baseUrl}/${this.storageZone}/${path}`;
188
+ buildFilePath(key) {
189
+ return this.bucket ? `/${this.bucket}/${key}` : `/${key}`;
190
+ }
191
+ async toReadableStream(content) {
192
+ if (typeof content === "string") {
193
+ const encoded = new TextEncoder().encode(content);
194
+ return { stream: new Blob([encoded]).stream(), length: encoded.length };
195
+ }
196
+ if (content instanceof ArrayBuffer) {
197
+ return { stream: new Blob([content]).stream(), length: content.byteLength };
198
+ }
199
+ if (content instanceof SharedArrayBuffer) {
200
+ const uint8Array = new Uint8Array(content);
201
+ const copied = new Uint8Array(uint8Array.length);
202
+ copied.set(uint8Array);
203
+ return { stream: new Blob([copied]).stream(), length: content.byteLength };
204
+ }
205
+ if (ArrayBuffer.isView(content)) {
206
+ const view = new Uint8Array(content.buffer, content.byteOffset, content.byteLength);
207
+ return { stream: new Blob([view]).stream(), length: content.byteLength };
208
+ }
209
+ if (content instanceof Blob) {
210
+ return { stream: content.stream(), length: content.size };
211
+ }
212
+ if (content instanceof Request || content instanceof Response) {
213
+ const arrayBuffer = await content.arrayBuffer();
214
+ return { stream: new Blob([arrayBuffer]).stream(), length: arrayBuffer.byteLength };
215
+ }
216
+ if (typeof content === "object" && content !== null && "arrayBuffer" in content) {
217
+ const fileContent = content;
218
+ const arrayBuffer = await fileContent.arrayBuffer();
219
+ return { stream: new Blob([arrayBuffer]).stream(), length: arrayBuffer.byteLength };
220
+ }
221
+ throw new StorageException("Unsupported content type for upload", "UNSUPPORTED_CONTENT_TYPE");
281
222
  }
282
223
  }
283
224
  BunnyStorage = __legacyDecorateClassTS([
@@ -324,8 +265,8 @@ class Storage {
324
265
  await client.delete(key);
325
266
  }
326
267
  async putFile(key, localPath) {
327
- const file = Bun.file(localPath);
328
- return await this.put(key, file);
268
+ const file2 = Bun.file(localPath);
269
+ return await this.put(key, file2);
329
270
  }
330
271
  async putDir(bucket, options) {
331
272
  const { path, filter } = options;
@@ -399,13 +340,13 @@ class CloudflareStorage extends Storage {
399
340
  const secretKey = this.env.STORAGE_CLOUDFLARE_SECRET_KEY;
400
341
  const endpoint = this.env.STORAGE_CLOUDFLARE_ENDPOINT;
401
342
  if (!accessKey) {
402
- throw new StorageException("Cloudflare access key is required. Please provide an access key either through the constructor options or set the STORAGE_CLOUDFLARE_ACCESS_KEY environment variable.");
343
+ throw new StorageException("Cloudflare access key is required. Please provide an access key either through the constructor options or set the STORAGE_CLOUDFLARE_ACCESS_KEY environment variable.", "CONFIG_REQUIRED");
403
344
  }
404
345
  if (!secretKey) {
405
- throw new StorageException("Cloudflare secret key is required. Please provide a secret key either through the constructor options or set the STORAGE_CLOUDFLARE_SECRET_KEY environment variable.");
346
+ throw new StorageException("Cloudflare secret key is required. Please provide a secret key either through the constructor options or set the STORAGE_CLOUDFLARE_SECRET_KEY environment variable.", "CONFIG_REQUIRED");
406
347
  }
407
348
  if (!endpoint) {
408
- throw new StorageException("Cloudflare endpoint is required. Please provide an endpoint either through the constructor options or set the STORAGE_CLOUDFLARE_ENDPOINT environment variable.");
349
+ throw new StorageException("Cloudflare endpoint is required. Please provide an endpoint either through the constructor options or set the STORAGE_CLOUDFLARE_ENDPOINT environment variable.", "CONFIG_REQUIRED");
409
350
  }
410
351
  this.accessKey = accessKey;
411
352
  this.secretKey = secretKey;
@@ -444,7 +385,7 @@ class FilesystemStorage extends Storage {
444
385
  this.env = env;
445
386
  const basePath = this.env.FILESYSTEM_STORAGE_PATH;
446
387
  if (!basePath) {
447
- throw new StorageException("Base path is required. Please provide a base path either through the constructor options or set the FILESYSTEM_STORAGE_PATH environment variable.");
388
+ throw new StorageException("Base path is required. Please provide a base path either through the constructor options or set the FILESYSTEM_STORAGE_PATH environment variable.", "STORAGE_ROOT_DIR_REQUIRED");
448
389
  }
449
390
  this.storagePath = basePath;
450
391
  try {
@@ -452,7 +393,7 @@ class FilesystemStorage extends Storage {
452
393
  mkdirSync(basePath, { recursive: true });
453
394
  }
454
395
  } catch (error) {
455
- throw new StorageException(`Failed to create base storage directory at ${basePath}: ${error instanceof Error ? error.message : String(error)}`);
396
+ throw new StorageException(`Failed to create base storage directory at ${basePath}: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_CONFIG_REQUIRED");
456
397
  }
457
398
  }
458
399
  getOptions() {
@@ -466,7 +407,7 @@ class FilesystemStorage extends Storage {
466
407
  }
467
408
  getBucketPath() {
468
409
  if (!this.bucket) {
469
- throw new StorageException("Bucket name is required. Please call setBucket() first.");
410
+ throw new StorageException("Bucket name is required. Please call setBucket() first.", "STORAGE_BUCKET_REQUIRED");
470
411
  }
471
412
  return join3(this.storagePath, this.bucket);
472
413
  }
@@ -481,7 +422,7 @@ class FilesystemStorage extends Storage {
481
422
  mkdirSync(bucketPath, { recursive: true });
482
423
  }
483
424
  } catch (error) {
484
- throw new StorageException(`Failed to create bucket directory at ${bucketPath}: ${error instanceof Error ? error.message : String(error)}`);
425
+ throw new StorageException(`Failed to create bucket directory at ${bucketPath}: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_UPLOAD_FAILED");
485
426
  }
486
427
  return this;
487
428
  }
@@ -494,7 +435,7 @@ class FilesystemStorage extends Storage {
494
435
  const files = await this.listFilesRecursive(bucketPath, bucketPath);
495
436
  return files;
496
437
  } catch (error) {
497
- throw new StorageException(`Failed to list files in bucket: ${error instanceof Error ? error.message : String(error)}`);
438
+ throw new StorageException(`Failed to list files in bucket: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_LIST_FAILED");
498
439
  }
499
440
  }
500
441
  async listFilesRecursive(dir, baseDir) {
@@ -517,23 +458,23 @@ class FilesystemStorage extends Storage {
517
458
  await rm(bucketPath, { recursive: true });
518
459
  await mkdir(bucketPath, { recursive: true });
519
460
  } catch (error) {
520
- throw new StorageException(`Failed to clear bucket: ${error instanceof Error ? error.message : String(error)}`);
461
+ throw new StorageException(`Failed to clear bucket: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_CLEAR_FAILED");
521
462
  }
522
463
  return this;
523
464
  }
524
465
  async exists(key) {
525
466
  const filePath = this.getFilePath(key);
526
- const file = Bun.file(filePath);
527
- return await file.exists();
467
+ const file2 = Bun.file(filePath);
468
+ return await file2.exists();
528
469
  }
529
470
  async delete(key) {
530
471
  const filePath = this.getFilePath(key);
531
- const file = Bun.file(filePath);
532
- if (!await file.exists()) {
472
+ const file2 = Bun.file(filePath);
473
+ if (!await file2.exists()) {
533
474
  return;
534
475
  }
535
476
  try {
536
- await file.delete();
477
+ await file2.delete();
537
478
  let parentDir = dirname(filePath);
538
479
  const bucketPath = this.getBucketPath();
539
480
  while (parentDir !== bucketPath && parentDir !== this.storagePath) {
@@ -550,12 +491,12 @@ class FilesystemStorage extends Storage {
550
491
  }
551
492
  }
552
493
  } catch (error) {
553
- throw new StorageException(`Failed to delete file ${key}: ${error instanceof Error ? error.message : String(error)}`);
494
+ throw new StorageException(`Failed to delete file ${key}: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_DELETE_FAILED");
554
495
  }
555
496
  }
556
497
  async putFile(key, localPath) {
557
- const file = Bun.file(localPath);
558
- return await this.put(key, file);
498
+ const file2 = Bun.file(localPath);
499
+ return await this.put(key, file2);
559
500
  }
560
501
  async put(key, content) {
561
502
  const filePath = this.getFilePath(key);
@@ -565,7 +506,7 @@ class FilesystemStorage extends Storage {
565
506
  await mkdir(dir, { recursive: true });
566
507
  }
567
508
  } catch (error) {
568
- throw new StorageException(`Failed to create directory ${dir}: ${error instanceof Error ? error.message : String(error)}`);
509
+ throw new StorageException(`Failed to create directory ${dir}: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_UPLOAD_FAILED");
569
510
  }
570
511
  try {
571
512
  let bytesWritten;
@@ -591,14 +532,14 @@ class FilesystemStorage extends Storage {
591
532
  }
592
533
  return bytesWritten;
593
534
  } catch (error) {
594
- throw new StorageException(`Failed to write file ${key}: ${error instanceof Error ? error.message : String(error)}`);
535
+ throw new StorageException(`Failed to write file ${key}: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_UPLOAD_FAILED");
595
536
  }
596
537
  }
597
538
  async getFile(key, options) {
598
539
  const filePath = this.getFilePath(key);
599
- const file = Bun.file(filePath);
600
- if (!await file.exists()) {
601
- throw new StorageException(`File ${key} does not exist`);
540
+ const file2 = Bun.file(filePath);
541
+ if (!await file2.exists()) {
542
+ throw new StorageException(`File ${key} does not exist`, "FILE_NOT_FOUND");
602
543
  }
603
544
  const filename = options.filename ?? basename3(key);
604
545
  const localPath = join3(options.outputDir, filename);
@@ -608,48 +549,48 @@ class FilesystemStorage extends Storage {
608
549
  await mkdir(dir, { recursive: true });
609
550
  }
610
551
  } catch (error) {
611
- throw new StorageException(`Failed to create directory ${dir}: ${error instanceof Error ? error.message : String(error)}`);
552
+ throw new StorageException(`Failed to create directory ${dir}: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_DOWNLOAD_FAILED");
612
553
  }
613
554
  try {
614
- return await Bun.write(localPath, file);
555
+ return await Bun.write(localPath, file2);
615
556
  } catch (error) {
616
- throw new StorageException(`Failed to save file ${key} to ${localPath}: ${error instanceof Error ? error.message : String(error)}`);
557
+ throw new StorageException(`Failed to save file ${key} to ${localPath}: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_DOWNLOAD_FAILED");
617
558
  }
618
559
  }
619
560
  async getAsJson(key) {
620
561
  const filePath = this.getFilePath(key);
621
- const file = Bun.file(filePath);
622
- if (!await file.exists()) {
623
- throw new StorageException(`File ${key} does not exist`);
562
+ const file2 = Bun.file(filePath);
563
+ if (!await file2.exists()) {
564
+ throw new StorageException(`File ${key} does not exist`, "FILE_NOT_FOUND");
624
565
  }
625
566
  try {
626
- return await file.json();
567
+ return await file2.json();
627
568
  } catch (error) {
628
- throw new StorageException(`Failed to read file ${key} as JSON: ${error instanceof Error ? error.message : String(error)}`);
569
+ throw new StorageException(`Failed to read file ${key} as JSON: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_DOWNLOAD_FAILED");
629
570
  }
630
571
  }
631
572
  async getAsArrayBuffer(key) {
632
573
  const filePath = this.getFilePath(key);
633
- const file = Bun.file(filePath);
634
- if (!await file.exists()) {
635
- throw new StorageException(`File ${key} does not exist`);
574
+ const file2 = Bun.file(filePath);
575
+ if (!await file2.exists()) {
576
+ throw new StorageException(`File ${key} does not exist`, "FILE_NOT_FOUND");
636
577
  }
637
578
  try {
638
- return await file.arrayBuffer();
579
+ return await file2.arrayBuffer();
639
580
  } catch (error) {
640
- throw new StorageException(`Failed to read file ${key} as ArrayBuffer: ${error instanceof Error ? error.message : String(error)}`);
581
+ throw new StorageException(`Failed to read file ${key} as ArrayBuffer: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_DOWNLOAD_FAILED");
641
582
  }
642
583
  }
643
584
  getAsStream(key) {
644
585
  const filePath = this.getFilePath(key);
645
586
  if (!existsSync(filePath)) {
646
- throw new StorageException(`File ${key} does not exist`);
587
+ throw new StorageException(`File ${key} does not exist`, "FILE_NOT_FOUND");
647
588
  }
648
- const file = Bun.file(filePath);
589
+ const file2 = Bun.file(filePath);
649
590
  try {
650
- return file.stream();
591
+ return file2.stream();
651
592
  } catch (error) {
652
- throw new StorageException(`Failed to read file ${key} as stream: ${error instanceof Error ? error.message : String(error)}`);
593
+ throw new StorageException(`Failed to read file ${key} as stream: ${error instanceof Error ? error.message : String(error)}`, "STORAGE_DOWNLOAD_FAILED");
653
594
  }
654
595
  }
655
596
  }
@@ -669,4 +610,4 @@ export {
669
610
  BunnyStorage
670
611
  };
671
612
 
672
- //# debugId=9C8802670024636664756E2164756E21
613
+ //# debugId=B7060C45594F90B964756E2164756E21
package/dist/index.js.map CHANGED
@@ -2,14 +2,14 @@
2
2
  "version": 3,
3
3
  "sources": ["src/BunnyStorage.ts", "src/decorators.ts", "src/StorageException.ts", "src/CloudflareStorage.ts", "src/Storage.ts", "src/FilesystemStorage.ts"],
4
4
  "sourcesContent": [
5
- "import { readdir } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\nimport { AppEnv } from \"@ooneex/app-env\";\nimport { inject } from \"@ooneex/container\";\nimport type { BunFile, S3File } from \"bun\";\nimport { decorator } from \"./decorators\";\nimport { StorageException } from \"./StorageException\";\nimport type { GetFileOptionsType, IStorage, PutDirOptionsType } from \"./types\";\n\ntype BunnyRegionType = \"de\" | \"uk\" | \"ny\" | \"la\" | \"sg\" | \"se\" | \"br\" | \"jh\" | \"syd\";\n\ntype BunnyFileInfoType = {\n Guid: string;\n StorageZoneName: string;\n Path: string;\n ObjectName: string;\n Length: number;\n LastChanged: string;\n ServerId: number;\n ArrayNumber: number;\n IsDirectory: boolean;\n UserId: string;\n ContentType: string;\n DateCreated: string;\n StorageZoneId: number;\n Checksum: string | null;\n ReplicatedZones: string | null;\n};\n\nconst REGION_ENDPOINTS: Record<BunnyRegionType, string> = {\n de: \"storage.bunnycdn.com\",\n uk: \"uk.storage.bunnycdn.com\",\n ny: \"ny.storage.bunnycdn.com\",\n la: \"la.storage.bunnycdn.com\",\n sg: \"sg.storage.bunnycdn.com\",\n se: \"se.storage.bunnycdn.com\",\n br: \"br.storage.bunnycdn.com\",\n jh: \"jh.storage.bunnycdn.com\",\n syd: \"syd.storage.bunnycdn.com\",\n};\n\n@decorator.storage()\nexport class BunnyStorage implements IStorage {\n private bucket = \"\";\n private readonly accessKey: string;\n private readonly storageZone: string;\n private readonly region: BunnyRegionType;\n private readonly baseUrl: string;\n\n constructor(@inject(AppEnv) private readonly env: AppEnv) {\n const accessKey = this.env.STORAGE_BUNNY_ACCESS_KEY;\n const storageZone = this.env.STORAGE_BUNNY_STORAGE_ZONE;\n const region = this.env.STORAGE_BUNNY_REGION as BunnyRegionType | undefined;\n\n if (!accessKey) {\n throw new StorageException(\n \"Bunny access key is required. Please provide an access key either through the constructor options or set the STORAGE_BUNNY_ACCESS_KEY environment variable.\",\n );\n }\n if (!storageZone) {\n throw new StorageException(\n \"Bunny storage zone is required. Please provide a storage zone either through the constructor options or set the STORAGE_BUNNY_STORAGE_ZONE environment variable.\",\n );\n }\n\n this.accessKey = accessKey;\n this.storageZone = storageZone;\n this.region = region ?? \"de\";\n this.baseUrl = `https://${REGION_ENDPOINTS[this.region]}`;\n }\n\n public getBucket(): string {\n return this.bucket;\n }\n\n public setBucket(name: string): this {\n this.bucket = name;\n\n return this;\n }\n\n public async list(): Promise<string[]> {\n const path = this.bucket ? `${this.bucket}/` : \"\";\n const url = `${this.baseUrl}/${this.storageZone}/${path}`;\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n AccessKey: this.accessKey,\n accept: \"application/json\",\n },\n });\n\n if (!response.ok) {\n throw new StorageException(`Failed to list files: ${response.status} ${response.statusText}`, {\n status: response.status,\n path,\n });\n }\n\n const files: BunnyFileInfoType[] = await response.json();\n\n return files.filter((file) => !file.IsDirectory).map((file) => file.ObjectName);\n }\n\n public async clearBucket(): Promise<this> {\n const keys = await this.list();\n\n await Promise.all(keys.map((key) => this.delete(key)));\n\n return this;\n }\n\n public async exists(key: string): Promise<boolean> {\n const url = this.buildFileUrl(key);\n\n const response = await fetch(url, {\n method: \"HEAD\",\n headers: {\n AccessKey: this.accessKey,\n },\n });\n\n return response.ok;\n }\n\n public async delete(key: string): Promise<void> {\n const url = this.buildFileUrl(key);\n\n const response = await fetch(url, {\n method: \"DELETE\",\n headers: {\n AccessKey: this.accessKey,\n },\n });\n\n if (!response.ok && response.status !== 404) {\n throw new StorageException(`Failed to delete file: ${response.status} ${response.statusText}`, {\n status: response.status,\n key,\n });\n }\n }\n\n public async putFile(key: string, localPath: string): Promise<number> {\n const file = Bun.file(localPath);\n\n return await this.put(key, file);\n }\n\n public async putDir(bucket: string, options: PutDirOptionsType): Promise<number> {\n const { path, filter } = options;\n const entries = await readdir(path, { withFileTypes: true });\n\n const tasks: Promise<number>[] = [];\n\n for (const entry of entries) {\n const entryLocalPath = join(path, entry.name);\n const entryKey = bucket ? `${bucket}/${entry.name}` : entry.name;\n\n if (filter && !filter.test(entryLocalPath)) {\n continue;\n }\n\n if (entry.isDirectory()) {\n const subOptions: PutDirOptionsType = { path: entryLocalPath };\n if (filter) {\n subOptions.filter = filter;\n }\n tasks.push(this.putDir(entryKey, subOptions));\n } else {\n tasks.push(this.putFile(entryKey, entryLocalPath));\n }\n }\n\n const results = await Promise.all(tasks);\n\n return results.reduce((sum, bytes) => sum + bytes, 0);\n }\n\n public async put(\n key: string,\n content: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer | Request | Response | BunFile | S3File | Blob,\n ): Promise<number> {\n const url = this.buildFileUrl(key);\n\n let body: BodyInit;\n let contentLength: number;\n\n if (typeof content === \"string\") {\n body = content;\n contentLength = new TextEncoder().encode(content).length;\n } else if (content instanceof ArrayBuffer) {\n body = new Blob([content]);\n contentLength = content.byteLength;\n } else if (content instanceof SharedArrayBuffer) {\n const uint8Array = new Uint8Array(content);\n const copiedArray = new Uint8Array(uint8Array.length);\n copiedArray.set(uint8Array);\n body = new Blob([copiedArray]);\n contentLength = content.byteLength;\n } else if (ArrayBuffer.isView(content)) {\n body = new Blob([new Uint8Array(content.buffer as ArrayBuffer, content.byteOffset, content.byteLength)]);\n contentLength = content.byteLength;\n } else if (content instanceof Blob) {\n body = content;\n contentLength = content.size;\n } else if (content instanceof Request || content instanceof Response) {\n const arrayBuffer = await content.arrayBuffer();\n body = new Blob([arrayBuffer]);\n contentLength = arrayBuffer.byteLength;\n } else if (typeof content === \"object\" && content !== null && \"arrayBuffer\" in content) {\n const fileContent = content as BunFile | S3File;\n const arrayBuffer = await fileContent.arrayBuffer();\n body = new Blob([arrayBuffer]);\n contentLength = arrayBuffer.byteLength;\n } else {\n throw new StorageException(\"Unsupported content type for upload\", { key });\n }\n\n const response = await fetch(url, {\n method: \"PUT\",\n headers: {\n AccessKey: this.accessKey,\n \"Content-Type\": \"application/octet-stream\",\n },\n body,\n });\n\n if (!response.ok) {\n throw new StorageException(`Failed to upload file: ${response.status} ${response.statusText}`, {\n status: response.status,\n key,\n });\n }\n\n return contentLength;\n }\n\n public async getFile(key: string, options: GetFileOptionsType): Promise<number> {\n const arrayBuffer = await this.getAsArrayBuffer(key);\n const filename = options.filename ?? basename(key);\n const localPath = join(options.outputDir, filename);\n\n return await Bun.write(localPath, arrayBuffer);\n }\n\n public async getAsJson<T = unknown>(key: string): Promise<T> {\n const url = this.buildFileUrl(key);\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n AccessKey: this.accessKey,\n },\n });\n\n if (!response.ok) {\n throw new StorageException(`Failed to get file as JSON: ${response.status} ${response.statusText}`, {\n status: response.status,\n key,\n });\n }\n\n return await response.json();\n }\n\n public async getAsArrayBuffer(key: string): Promise<ArrayBuffer> {\n const url = this.buildFileUrl(key);\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n AccessKey: this.accessKey,\n },\n });\n\n if (!response.ok) {\n throw new StorageException(`Failed to get file as ArrayBuffer: ${response.status} ${response.statusText}`, {\n status: response.status,\n key,\n });\n }\n\n return await response.arrayBuffer();\n }\n\n public getAsStream(key: string): ReadableStream {\n const url = this.buildFileUrl(key);\n const accessKey = this.accessKey;\n\n const { readable, writable } = new TransformStream();\n\n fetch(url, {\n method: \"GET\",\n headers: { AccessKey: accessKey },\n }).then((response) => {\n if (!response.ok) {\n writable.abort(\n new StorageException(`Failed to get file as stream: ${response.status} ${response.statusText}`, {\n status: response.status,\n key,\n }),\n );\n return;\n }\n\n if (!response.body) {\n writable.abort(new StorageException(\"Response body is null\", { key }));\n return;\n }\n\n response.body.pipeTo(writable);\n });\n\n return readable;\n }\n\n private buildFileUrl(key: string): string {\n const path = this.bucket ? `${this.bucket}/${key}` : key;\n\n return `${this.baseUrl}/${this.storageZone}/${path}`;\n }\n}\n",
5
+ "import { readdir } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\nimport type { ReadableStream as NodeReadableStream } from \"node:stream/web\";\nimport * as BunnyStorageSDK from \"@bunny.net/storage-sdk\";\nimport { AppEnv } from \"@ooneex/app-env\";\nimport { inject } from \"@ooneex/container\";\nimport type { BunFile, S3File } from \"bun\";\nimport { decorator } from \"./decorators\";\nimport { StorageException } from \"./StorageException\";\nimport type { GetFileOptionsType, IStorage, PutDirOptionsType } from \"./types\";\n\ntype BunnyRegionType = \"de\" | \"uk\" | \"ny\" | \"la\" | \"sg\" | \"se\" | \"br\" | \"jh\" | \"syd\";\n\nconst REGION_MAP: Record<BunnyRegionType, BunnyStorageSDK.regions.StorageRegion> = {\n de: BunnyStorageSDK.regions.StorageRegion.Falkenstein,\n uk: BunnyStorageSDK.regions.StorageRegion.London,\n ny: BunnyStorageSDK.regions.StorageRegion.NewYork,\n la: BunnyStorageSDK.regions.StorageRegion.LosAngeles,\n sg: BunnyStorageSDK.regions.StorageRegion.Singapore,\n se: BunnyStorageSDK.regions.StorageRegion.Stockholm,\n br: BunnyStorageSDK.regions.StorageRegion.SaoPaulo,\n jh: BunnyStorageSDK.regions.StorageRegion.Johannesburg,\n syd: BunnyStorageSDK.regions.StorageRegion.Sydney,\n};\n\n@decorator.storage()\nexport class BunnyStorage implements IStorage {\n private bucket = \"\";\n private readonly storageZone: BunnyStorageSDK.zone.StorageZone;\n\n constructor(@inject(AppEnv) private readonly env: AppEnv) {\n const accessKey = this.env.STORAGE_BUNNY_ACCESS_KEY;\n const storageZone = this.env.STORAGE_BUNNY_STORAGE_ZONE;\n const region = this.env.STORAGE_BUNNY_REGION as BunnyRegionType | undefined;\n\n if (!accessKey) {\n throw new StorageException(\n \"Bunny access key is required. Please provide an access key either through the constructor options or set the STORAGE_BUNNY_ACCESS_KEY environment variable.\",\n \"API_KEY_REQUIRED\",\n );\n }\n if (!storageZone) {\n throw new StorageException(\n \"Bunny storage zone is required. Please provide a storage zone either through the constructor options or set the STORAGE_BUNNY_STORAGE_ZONE environment variable.\",\n \"STORAGE_ZONE_REQUIRED\",\n );\n }\n\n const sdkRegion = REGION_MAP[region ?? \"de\"];\n this.storageZone = BunnyStorageSDK.zone.connect_with_accesskey(sdkRegion, storageZone, accessKey);\n }\n\n public getBucket(): string {\n return this.bucket;\n }\n\n public setBucket(name: string): this {\n this.bucket = name;\n\n return this;\n }\n\n public async list(): Promise<string[]> {\n const path = this.bucket ? `/${this.bucket}/` : \"/\";\n\n try {\n const files = await BunnyStorageSDK.file.list(this.storageZone, path);\n\n return files.filter((file) => !file.isDirectory).map((file) => file.objectName);\n } catch (error) {\n throw new StorageException(\n `Failed to list files: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_LIST_FAILED\",\n {\n path,\n },\n );\n }\n }\n\n public async clearBucket(): Promise<this> {\n const keys = await this.list();\n\n await Promise.all(keys.map((key) => this.delete(key)));\n\n return this;\n }\n\n public async exists(key: string): Promise<boolean> {\n try {\n await BunnyStorageSDK.file.get(this.storageZone, this.buildFilePath(key));\n\n return true;\n } catch {\n return false;\n }\n }\n\n public async delete(key: string): Promise<void> {\n try {\n await BunnyStorageSDK.file.remove(this.storageZone, this.buildFilePath(key));\n } catch {\n // Ignore errors (file may not exist)\n }\n }\n\n public async putFile(key: string, localPath: string): Promise<number> {\n const file = Bun.file(localPath);\n\n return await this.put(key, file);\n }\n\n public async putDir(bucket: string, options: PutDirOptionsType): Promise<number> {\n const { path, filter } = options;\n const entries = await readdir(path, { withFileTypes: true });\n\n const tasks: Promise<number>[] = [];\n\n for (const entry of entries) {\n const entryLocalPath = join(path, entry.name);\n const entryKey = bucket ? `${bucket}/${entry.name}` : entry.name;\n\n if (filter && !filter.test(entryLocalPath)) {\n continue;\n }\n\n if (entry.isDirectory()) {\n const subOptions: PutDirOptionsType = { path: entryLocalPath };\n if (filter) {\n subOptions.filter = filter;\n }\n tasks.push(this.putDir(entryKey, subOptions));\n } else {\n tasks.push(this.putFile(entryKey, entryLocalPath));\n }\n }\n\n const results = await Promise.all(tasks);\n\n return results.reduce((sum, bytes) => sum + bytes, 0);\n }\n\n public async put(\n key: string,\n content: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer | Request | Response | BunFile | S3File | Blob,\n ): Promise<number> {\n const { stream, length } = await this.toReadableStream(content);\n const filePath = this.buildFilePath(key);\n\n try {\n await BunnyStorageSDK.file.upload(\n this.storageZone,\n filePath,\n stream as unknown as NodeReadableStream<Uint8Array>,\n );\n } catch (error) {\n throw new StorageException(\n `Failed to upload file: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_UPLOAD_FAILED\",\n {\n key,\n },\n );\n }\n\n return length;\n }\n\n public async getFile(key: string, options: GetFileOptionsType): Promise<number> {\n const arrayBuffer = await this.getAsArrayBuffer(key);\n const filename = options.filename ?? basename(key);\n const localPath = join(options.outputDir, filename);\n\n return await Bun.write(localPath, arrayBuffer);\n }\n\n public async getAsJson<T = unknown>(key: string): Promise<T> {\n try {\n const { stream } = await BunnyStorageSDK.file.download(this.storageZone, this.buildFilePath(key));\n\n return await new Response(stream as unknown as BodyInit).json();\n } catch (error) {\n throw new StorageException(\n `Failed to get file as JSON: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_DOWNLOAD_FAILED\",\n { key },\n );\n }\n }\n\n public async getAsArrayBuffer(key: string): Promise<ArrayBuffer> {\n try {\n const { stream } = await BunnyStorageSDK.file.download(this.storageZone, this.buildFilePath(key));\n\n return await new Response(stream as unknown as BodyInit).arrayBuffer();\n } catch (error) {\n throw new StorageException(\n `Failed to get file as ArrayBuffer: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_DOWNLOAD_FAILED\",\n { key },\n );\n }\n }\n\n public getAsStream(key: string): ReadableStream {\n const filePath = this.buildFilePath(key);\n\n const { readable, writable } = new TransformStream();\n\n BunnyStorageSDK.file\n .download(this.storageZone, filePath)\n .then(({ stream }) => {\n (stream as unknown as ReadableStream).pipeTo(writable);\n })\n .catch((error) => {\n writable.abort(\n new StorageException(\n `Failed to get file as stream: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_DOWNLOAD_FAILED\",\n { key },\n ),\n );\n });\n\n return readable;\n }\n\n private buildFilePath(key: string): string {\n return this.bucket ? `/${this.bucket}/${key}` : `/${key}`;\n }\n\n private async toReadableStream(\n content: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer | Request | Response | BunFile | S3File | Blob,\n ): Promise<{ stream: ReadableStream<Uint8Array>; length: number }> {\n if (typeof content === \"string\") {\n const encoded = new TextEncoder().encode(content);\n return { stream: new Blob([encoded]).stream(), length: encoded.length };\n }\n\n if (content instanceof ArrayBuffer) {\n return { stream: new Blob([content]).stream(), length: content.byteLength };\n }\n\n if (content instanceof SharedArrayBuffer) {\n const uint8Array = new Uint8Array(content);\n const copied = new Uint8Array(uint8Array.length);\n copied.set(uint8Array);\n return { stream: new Blob([copied]).stream(), length: content.byteLength };\n }\n\n if (ArrayBuffer.isView(content)) {\n const view = new Uint8Array(content.buffer as ArrayBuffer, content.byteOffset, content.byteLength);\n return { stream: new Blob([view]).stream(), length: content.byteLength };\n }\n\n if (content instanceof Blob) {\n return { stream: content.stream(), length: content.size };\n }\n\n if (content instanceof Request || content instanceof Response) {\n const arrayBuffer = await content.arrayBuffer();\n return { stream: new Blob([arrayBuffer]).stream(), length: arrayBuffer.byteLength };\n }\n\n if (typeof content === \"object\" && content !== null && \"arrayBuffer\" in content) {\n const fileContent = content as BunFile | S3File;\n const arrayBuffer = await fileContent.arrayBuffer();\n return { stream: new Blob([arrayBuffer]).stream(), length: arrayBuffer.byteLength };\n }\n\n throw new StorageException(\"Unsupported content type for upload\", \"UNSUPPORTED_CONTENT_TYPE\");\n }\n}\n",
6
6
  "import { container, EContainerScope } from \"@ooneex/container\";\nimport type { StorageClassType } from \"./types\";\n\nexport const decorator = {\n storage: (scope: EContainerScope = EContainerScope.Singleton) => {\n return (target: StorageClassType): void => {\n container.add(target, scope);\n };\n },\n};\n",
7
- "import { Exception } from \"@ooneex/exception\";\nimport { HttpStatus } from \"@ooneex/http-status\";\n\nexport class StorageException extends Exception {\n constructor(message: string, data: Record<string, unknown> = {}) {\n super(message, {\n status: HttpStatus.Code.InternalServerError,\n data,\n });\n this.name = \"StorageException\";\n }\n}\n",
8
- "import { AppEnv } from \"@ooneex/app-env\";\nimport { inject } from \"@ooneex/container\";\nimport type { S3Options } from \"bun\";\nimport { decorator } from \"./decorators\";\nimport { Storage } from \"./Storage\";\nimport { StorageException } from \"./StorageException\";\n\n@decorator.storage()\nexport class CloudflareStorage extends Storage {\n protected bucket: string;\n private readonly accessKey: string;\n private readonly secretKey: string;\n private readonly endpoint: string;\n private readonly region: string;\n\n constructor(@inject(AppEnv) private readonly env: AppEnv) {\n super();\n\n const accessKey = this.env.STORAGE_CLOUDFLARE_ACCESS_KEY;\n const secretKey = this.env.STORAGE_CLOUDFLARE_SECRET_KEY;\n const endpoint = this.env.STORAGE_CLOUDFLARE_ENDPOINT;\n\n if (!accessKey) {\n throw new StorageException(\n \"Cloudflare access key is required. Please provide an access key either through the constructor options or set the STORAGE_CLOUDFLARE_ACCESS_KEY environment variable.\",\n );\n }\n if (!secretKey) {\n throw new StorageException(\n \"Cloudflare secret key is required. Please provide a secret key either through the constructor options or set the STORAGE_CLOUDFLARE_SECRET_KEY environment variable.\",\n );\n }\n if (!endpoint) {\n throw new StorageException(\n \"Cloudflare endpoint is required. Please provide an endpoint either through the constructor options or set the STORAGE_CLOUDFLARE_ENDPOINT environment variable.\",\n );\n }\n\n this.accessKey = accessKey;\n this.secretKey = secretKey;\n this.endpoint = endpoint;\n this.region = this.env.STORAGE_CLOUDFLARE_REGION || \"EEUR\";\n }\n\n public getOptions(): S3Options {\n return {\n accessKeyId: this.accessKey,\n secretAccessKey: this.secretKey,\n endpoint: this.endpoint,\n bucket: this.bucket,\n region: this.region,\n };\n }\n}\n",
7
+ "import { Exception } from \"@ooneex/exception\";\nimport { HttpStatus } from \"@ooneex/http-status\";\n\nexport class StorageException extends Exception {\n constructor(message: string, key: string, data: Record<string, unknown> = {}) {\n super(message, {\n key,\n status: HttpStatus.Code.InternalServerError,\n data,\n });\n this.name = \"StorageException\";\n }\n}\n",
8
+ "import { AppEnv } from \"@ooneex/app-env\";\nimport { inject } from \"@ooneex/container\";\nimport type { S3Options } from \"bun\";\nimport { decorator } from \"./decorators\";\nimport { Storage } from \"./Storage\";\nimport { StorageException } from \"./StorageException\";\n\n@decorator.storage()\nexport class CloudflareStorage extends Storage {\n protected bucket: string;\n private readonly accessKey: string;\n private readonly secretKey: string;\n private readonly endpoint: string;\n private readonly region: string;\n\n constructor(@inject(AppEnv) private readonly env: AppEnv) {\n super();\n\n const accessKey = this.env.STORAGE_CLOUDFLARE_ACCESS_KEY;\n const secretKey = this.env.STORAGE_CLOUDFLARE_SECRET_KEY;\n const endpoint = this.env.STORAGE_CLOUDFLARE_ENDPOINT;\n\n if (!accessKey) {\n throw new StorageException(\n \"Cloudflare access key is required. Please provide an access key either through the constructor options or set the STORAGE_CLOUDFLARE_ACCESS_KEY environment variable.\",\n \"CONFIG_REQUIRED\",\n );\n }\n if (!secretKey) {\n throw new StorageException(\n \"Cloudflare secret key is required. Please provide a secret key either through the constructor options or set the STORAGE_CLOUDFLARE_SECRET_KEY environment variable.\",\n \"CONFIG_REQUIRED\",\n );\n }\n if (!endpoint) {\n throw new StorageException(\n \"Cloudflare endpoint is required. Please provide an endpoint either through the constructor options or set the STORAGE_CLOUDFLARE_ENDPOINT environment variable.\",\n \"CONFIG_REQUIRED\",\n );\n }\n\n this.accessKey = accessKey;\n this.secretKey = secretKey;\n this.endpoint = endpoint;\n this.region = this.env.STORAGE_CLOUDFLARE_REGION || \"EEUR\";\n }\n\n public getOptions(): S3Options {\n return {\n accessKeyId: this.accessKey,\n secretAccessKey: this.secretKey,\n endpoint: this.endpoint,\n bucket: this.bucket,\n region: this.region,\n };\n }\n}\n",
9
9
  "import { readdir } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\nimport type { BunFile, S3File, S3Options } from \"bun\";\nimport type { GetFileOptionsType, IStorage, PutDirOptionsType } from \"./types\";\n\nexport abstract class Storage implements IStorage {\n protected client: Bun.S3Client | null = null;\n public abstract getOptions(): S3Options;\n protected abstract bucket: string;\n\n public getBucket(): string {\n return this.bucket;\n }\n\n public setBucket(name: string): this {\n this.bucket = name;\n this.client = new Bun.S3Client(this.getOptions());\n\n return this;\n }\n\n public async list(): Promise<string[]> {\n const client = this.getClient();\n\n return (await client.list()).contents?.map((content) => content.key) || [];\n }\n\n public async clearBucket(): Promise<this> {\n const client = this.getClient();\n const keys = await this.list();\n\n await Promise.all(keys.map((key) => client.delete(key)));\n\n return this;\n }\n\n public async exists(key: string): Promise<boolean> {\n const client = this.getClient();\n\n return await client.exists(key);\n }\n\n public async delete(key: string): Promise<void> {\n const client = this.getClient();\n\n await client.delete(key);\n }\n\n public async putFile(key: string, localPath: string): Promise<number> {\n const file = Bun.file(localPath);\n\n return await this.put(key, file);\n }\n\n public async putDir(bucket: string, options: PutDirOptionsType): Promise<number> {\n const { path, filter } = options;\n const entries = await readdir(path, { withFileTypes: true });\n\n const tasks: Promise<number>[] = [];\n\n for (const entry of entries) {\n const entryLocalPath = join(path, entry.name);\n const entryKey = bucket ? `${bucket}/${entry.name}` : entry.name;\n\n if (filter && !filter.test(entryLocalPath)) {\n continue;\n }\n\n if (entry.isDirectory()) {\n const subOptions: PutDirOptionsType = { path: entryLocalPath };\n if (filter) {\n subOptions.filter = filter;\n }\n tasks.push(this.putDir(entryKey, subOptions));\n } else {\n tasks.push(this.putFile(entryKey, entryLocalPath));\n }\n }\n\n const results = await Promise.all(tasks);\n\n return results.reduce((sum, bytes) => sum + bytes, 0);\n }\n\n public async put(\n key: string,\n content: string | ArrayBuffer | SharedArrayBuffer | Request | Response | BunFile | S3File | Blob,\n ): Promise<number> {\n const s3file: S3File = this.getS3File(key);\n\n return await s3file.write(content);\n }\n\n public async getFile(key: string, options: GetFileOptionsType): Promise<number> {\n const arrayBuffer = await this.getAsArrayBuffer(key);\n const filename = options.filename ?? basename(key);\n const localPath = join(options.outputDir, filename);\n\n return await Bun.write(localPath, arrayBuffer);\n }\n\n public async getAsJson<T>(key: string): Promise<T> {\n const s3file: S3File = this.getS3File(key);\n\n return await s3file.json();\n }\n\n public async getAsArrayBuffer(key: string): Promise<ArrayBuffer> {\n const s3file: S3File = this.getS3File(key);\n\n return await s3file.arrayBuffer();\n }\n\n public getAsStream(key: string): ReadableStream {\n const s3file: S3File = this.getS3File(key);\n\n return s3file.stream();\n }\n\n protected getClient(): Bun.S3Client {\n if (!this.client) {\n this.client = new Bun.S3Client(this.getOptions());\n }\n\n return this.client;\n }\n\n protected getS3File(path: string): S3File {\n const client = this.getClient();\n\n return client.file(path);\n }\n}\n",
10
- "import { existsSync, mkdirSync } from \"node:fs\";\nimport { mkdir, readdir, rm, rmdir } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\nimport { AppEnv } from \"@ooneex/app-env\";\nimport { inject } from \"@ooneex/container\";\nimport type { BunFile, S3File, S3Options } from \"bun\";\nimport { decorator } from \"./decorators\";\nimport { Storage } from \"./Storage\";\nimport { StorageException } from \"./StorageException\";\nimport type { GetFileOptionsType } from \"./types\";\n\n@decorator.storage()\nexport class FilesystemStorage extends Storage {\n protected bucket: string;\n private readonly storagePath: string;\n\n constructor(@inject(AppEnv) private readonly env: AppEnv) {\n super();\n\n const basePath = this.env.FILESYSTEM_STORAGE_PATH;\n\n if (!basePath) {\n throw new StorageException(\n \"Base path is required. Please provide a base path either through the constructor options or set the FILESYSTEM_STORAGE_PATH environment variable.\",\n );\n }\n\n this.storagePath = basePath;\n\n try {\n if (!existsSync(basePath)) {\n mkdirSync(basePath, { recursive: true });\n }\n } catch (error) {\n throw new StorageException(\n `Failed to create base storage directory at ${basePath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n public getOptions(): S3Options {\n return {\n accessKeyId: \"filesystem\",\n secretAccessKey: \"filesystem\",\n endpoint: this.storagePath,\n bucket: this.bucket,\n region: \"local\",\n };\n }\n\n private getBucketPath(): string {\n if (!this.bucket) {\n throw new StorageException(\"Bucket name is required. Please call setBucket() first.\");\n }\n return join(this.storagePath, this.bucket);\n }\n\n private getFilePath(key: string): string {\n return join(this.getBucketPath(), key);\n }\n\n public override setBucket(name: string): this {\n this.bucket = name;\n\n const bucketPath = this.getBucketPath();\n try {\n if (!existsSync(bucketPath)) {\n mkdirSync(bucketPath, { recursive: true });\n }\n } catch (error) {\n throw new StorageException(\n `Failed to create bucket directory at ${bucketPath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n return this;\n }\n\n public override async list(): Promise<string[]> {\n const bucketPath = this.getBucketPath();\n\n if (!existsSync(bucketPath)) {\n return [];\n }\n\n try {\n const files = await this.listFilesRecursive(bucketPath, bucketPath);\n return files;\n } catch (error) {\n throw new StorageException(\n `Failed to list files in bucket: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n private async listFilesRecursive(dir: string, baseDir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n\n const results = await Promise.all(\n entries.map(async (entry) => {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n return this.listFilesRecursive(fullPath, baseDir);\n }\n\n return [fullPath.substring(baseDir.length + 1)];\n }),\n );\n\n return results.flat();\n }\n\n public override async clearBucket(): Promise<this> {\n const bucketPath = this.getBucketPath();\n\n if (!existsSync(bucketPath)) {\n return this;\n }\n\n try {\n await rm(bucketPath, { recursive: true });\n await mkdir(bucketPath, { recursive: true });\n } catch (error) {\n throw new StorageException(`Failed to clear bucket: ${error instanceof Error ? error.message : String(error)}`);\n }\n\n return this;\n }\n\n public override async exists(key: string): Promise<boolean> {\n const filePath = this.getFilePath(key);\n const file = Bun.file(filePath);\n return await file.exists();\n }\n\n public override async delete(key: string): Promise<void> {\n const filePath = this.getFilePath(key);\n const file = Bun.file(filePath);\n\n if (!(await file.exists())) {\n return;\n }\n\n try {\n await file.delete();\n\n let parentDir = dirname(filePath);\n const bucketPath = this.getBucketPath();\n\n while (parentDir !== bucketPath && parentDir !== this.storagePath) {\n try {\n const entries = await readdir(parentDir);\n if (entries.length === 0) {\n await rmdir(parentDir);\n parentDir = dirname(parentDir);\n } else {\n break;\n }\n } catch {\n break;\n }\n }\n } catch (error) {\n throw new StorageException(\n `Failed to delete file ${key}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n public override async putFile(key: string, localPath: string): Promise<number> {\n const file = Bun.file(localPath);\n return await this.put(key, file);\n }\n\n public override async put(\n key: string,\n content: string | ArrayBuffer | SharedArrayBuffer | Request | Response | BunFile | S3File | Blob,\n ): Promise<number> {\n const filePath = this.getFilePath(key);\n const dir = dirname(filePath);\n\n try {\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n }\n } catch (error) {\n throw new StorageException(\n `Failed to create directory ${dir}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n try {\n let bytesWritten: number;\n\n if (typeof content === \"string\") {\n bytesWritten = await Bun.write(filePath, content);\n } else if (content instanceof ArrayBuffer) {\n bytesWritten = await Bun.write(filePath, content);\n } else if (content instanceof SharedArrayBuffer) {\n const arrayBuffer = new ArrayBuffer(content.byteLength);\n new Uint8Array(arrayBuffer).set(new Uint8Array(content));\n bytesWritten = await Bun.write(filePath, arrayBuffer);\n } else if (content instanceof Request) {\n const arrayBuffer = await content.arrayBuffer();\n bytesWritten = await Bun.write(filePath, arrayBuffer);\n } else if (content instanceof Response) {\n const arrayBuffer = await content.arrayBuffer();\n bytesWritten = await Bun.write(filePath, arrayBuffer);\n } else if (content instanceof Blob) {\n bytesWritten = await Bun.write(filePath, content);\n } else {\n const arrayBuffer = await (content as BunFile | S3File).arrayBuffer();\n bytesWritten = await Bun.write(filePath, arrayBuffer);\n }\n\n return bytesWritten;\n } catch (error) {\n throw new StorageException(\n `Failed to write file ${key}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n public override async getFile(key: string, options: GetFileOptionsType): Promise<number> {\n const filePath = this.getFilePath(key);\n const file = Bun.file(filePath);\n\n if (!(await file.exists())) {\n throw new StorageException(`File ${key} does not exist`);\n }\n\n const filename = options.filename ?? basename(key);\n const localPath = join(options.outputDir, filename);\n const dir = dirname(localPath);\n\n try {\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n }\n } catch (error) {\n throw new StorageException(\n `Failed to create directory ${dir}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n try {\n return await Bun.write(localPath, file);\n } catch (error) {\n throw new StorageException(\n `Failed to save file ${key} to ${localPath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n public override async getAsJson<T>(key: string): Promise<T> {\n const filePath = this.getFilePath(key);\n const file = Bun.file(filePath);\n\n if (!(await file.exists())) {\n throw new StorageException(`File ${key} does not exist`);\n }\n\n try {\n return await file.json();\n } catch (error) {\n throw new StorageException(\n `Failed to read file ${key} as JSON: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n public override async getAsArrayBuffer(key: string): Promise<ArrayBuffer> {\n const filePath = this.getFilePath(key);\n const file = Bun.file(filePath);\n\n if (!(await file.exists())) {\n throw new StorageException(`File ${key} does not exist`);\n }\n\n try {\n return await file.arrayBuffer();\n } catch (error) {\n throw new StorageException(\n `Failed to read file ${key} as ArrayBuffer: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n public override getAsStream(key: string): ReadableStream {\n const filePath = this.getFilePath(key);\n\n if (!existsSync(filePath)) {\n throw new StorageException(`File ${key} does not exist`);\n }\n\n const file = Bun.file(filePath);\n\n try {\n return file.stream();\n } catch (error) {\n throw new StorageException(\n `Failed to read file ${key} as stream: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n}\n"
10
+ "import { existsSync, mkdirSync } from \"node:fs\";\nimport { mkdir, readdir, rm, rmdir } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\nimport { AppEnv } from \"@ooneex/app-env\";\nimport { inject } from \"@ooneex/container\";\nimport type { BunFile, S3File, S3Options } from \"bun\";\nimport { decorator } from \"./decorators\";\nimport { Storage } from \"./Storage\";\nimport { StorageException } from \"./StorageException\";\nimport type { GetFileOptionsType } from \"./types\";\n\n@decorator.storage()\nexport class FilesystemStorage extends Storage {\n protected bucket: string;\n private readonly storagePath: string;\n\n constructor(@inject(AppEnv) private readonly env: AppEnv) {\n super();\n\n const basePath = this.env.FILESYSTEM_STORAGE_PATH;\n\n if (!basePath) {\n throw new StorageException(\n \"Base path is required. Please provide a base path either through the constructor options or set the FILESYSTEM_STORAGE_PATH environment variable.\",\n \"STORAGE_ROOT_DIR_REQUIRED\",\n );\n }\n\n this.storagePath = basePath;\n\n try {\n if (!existsSync(basePath)) {\n mkdirSync(basePath, { recursive: true });\n }\n } catch (error) {\n throw new StorageException(\n `Failed to create base storage directory at ${basePath}: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_CONFIG_REQUIRED\",\n );\n }\n }\n\n public getOptions(): S3Options {\n return {\n accessKeyId: \"filesystem\",\n secretAccessKey: \"filesystem\",\n endpoint: this.storagePath,\n bucket: this.bucket,\n region: \"local\",\n };\n }\n\n private getBucketPath(): string {\n if (!this.bucket) {\n throw new StorageException(\"Bucket name is required. Please call setBucket() first.\", \"STORAGE_BUCKET_REQUIRED\");\n }\n return join(this.storagePath, this.bucket);\n }\n\n private getFilePath(key: string): string {\n return join(this.getBucketPath(), key);\n }\n\n public override setBucket(name: string): this {\n this.bucket = name;\n\n const bucketPath = this.getBucketPath();\n try {\n if (!existsSync(bucketPath)) {\n mkdirSync(bucketPath, { recursive: true });\n }\n } catch (error) {\n throw new StorageException(\n `Failed to create bucket directory at ${bucketPath}: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_UPLOAD_FAILED\",\n );\n }\n\n return this;\n }\n\n public override async list(): Promise<string[]> {\n const bucketPath = this.getBucketPath();\n\n if (!existsSync(bucketPath)) {\n return [];\n }\n\n try {\n const files = await this.listFilesRecursive(bucketPath, bucketPath);\n return files;\n } catch (error) {\n throw new StorageException(\n `Failed to list files in bucket: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_LIST_FAILED\",\n );\n }\n }\n\n private async listFilesRecursive(dir: string, baseDir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n\n const results = await Promise.all(\n entries.map(async (entry) => {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n return this.listFilesRecursive(fullPath, baseDir);\n }\n\n return [fullPath.substring(baseDir.length + 1)];\n }),\n );\n\n return results.flat();\n }\n\n public override async clearBucket(): Promise<this> {\n const bucketPath = this.getBucketPath();\n\n if (!existsSync(bucketPath)) {\n return this;\n }\n\n try {\n await rm(bucketPath, { recursive: true });\n await mkdir(bucketPath, { recursive: true });\n } catch (error) {\n throw new StorageException(\n `Failed to clear bucket: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_CLEAR_FAILED\",\n );\n }\n\n return this;\n }\n\n public override async exists(key: string): Promise<boolean> {\n const filePath = this.getFilePath(key);\n const file = Bun.file(filePath);\n return await file.exists();\n }\n\n public override async delete(key: string): Promise<void> {\n const filePath = this.getFilePath(key);\n const file = Bun.file(filePath);\n\n if (!(await file.exists())) {\n return;\n }\n\n try {\n await file.delete();\n\n let parentDir = dirname(filePath);\n const bucketPath = this.getBucketPath();\n\n while (parentDir !== bucketPath && parentDir !== this.storagePath) {\n try {\n const entries = await readdir(parentDir);\n if (entries.length === 0) {\n await rmdir(parentDir);\n parentDir = dirname(parentDir);\n } else {\n break;\n }\n } catch {\n break;\n }\n }\n } catch (error) {\n throw new StorageException(\n `Failed to delete file ${key}: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_DELETE_FAILED\",\n );\n }\n }\n\n public override async putFile(key: string, localPath: string): Promise<number> {\n const file = Bun.file(localPath);\n return await this.put(key, file);\n }\n\n public override async put(\n key: string,\n content: string | ArrayBuffer | SharedArrayBuffer | Request | Response | BunFile | S3File | Blob,\n ): Promise<number> {\n const filePath = this.getFilePath(key);\n const dir = dirname(filePath);\n\n try {\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n }\n } catch (error) {\n throw new StorageException(\n `Failed to create directory ${dir}: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_UPLOAD_FAILED\",\n );\n }\n\n try {\n let bytesWritten: number;\n\n if (typeof content === \"string\") {\n bytesWritten = await Bun.write(filePath, content);\n } else if (content instanceof ArrayBuffer) {\n bytesWritten = await Bun.write(filePath, content);\n } else if (content instanceof SharedArrayBuffer) {\n const arrayBuffer = new ArrayBuffer(content.byteLength);\n new Uint8Array(arrayBuffer).set(new Uint8Array(content));\n bytesWritten = await Bun.write(filePath, arrayBuffer);\n } else if (content instanceof Request) {\n const arrayBuffer = await content.arrayBuffer();\n bytesWritten = await Bun.write(filePath, arrayBuffer);\n } else if (content instanceof Response) {\n const arrayBuffer = await content.arrayBuffer();\n bytesWritten = await Bun.write(filePath, arrayBuffer);\n } else if (content instanceof Blob) {\n bytesWritten = await Bun.write(filePath, content);\n } else {\n const arrayBuffer = await (content as BunFile | S3File).arrayBuffer();\n bytesWritten = await Bun.write(filePath, arrayBuffer);\n }\n\n return bytesWritten;\n } catch (error) {\n throw new StorageException(\n `Failed to write file ${key}: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_UPLOAD_FAILED\",\n );\n }\n }\n\n public override async getFile(key: string, options: GetFileOptionsType): Promise<number> {\n const filePath = this.getFilePath(key);\n const file = Bun.file(filePath);\n\n if (!(await file.exists())) {\n throw new StorageException(`File ${key} does not exist`, \"FILE_NOT_FOUND\");\n }\n\n const filename = options.filename ?? basename(key);\n const localPath = join(options.outputDir, filename);\n const dir = dirname(localPath);\n\n try {\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n }\n } catch (error) {\n throw new StorageException(\n `Failed to create directory ${dir}: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_DOWNLOAD_FAILED\",\n );\n }\n\n try {\n return await Bun.write(localPath, file);\n } catch (error) {\n throw new StorageException(\n `Failed to save file ${key} to ${localPath}: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_DOWNLOAD_FAILED\",\n );\n }\n }\n\n public override async getAsJson<T>(key: string): Promise<T> {\n const filePath = this.getFilePath(key);\n const file = Bun.file(filePath);\n\n if (!(await file.exists())) {\n throw new StorageException(`File ${key} does not exist`, \"FILE_NOT_FOUND\");\n }\n\n try {\n return await file.json();\n } catch (error) {\n throw new StorageException(\n `Failed to read file ${key} as JSON: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_DOWNLOAD_FAILED\",\n );\n }\n }\n\n public override async getAsArrayBuffer(key: string): Promise<ArrayBuffer> {\n const filePath = this.getFilePath(key);\n const file = Bun.file(filePath);\n\n if (!(await file.exists())) {\n throw new StorageException(`File ${key} does not exist`, \"FILE_NOT_FOUND\");\n }\n\n try {\n return await file.arrayBuffer();\n } catch (error) {\n throw new StorageException(\n `Failed to read file ${key} as ArrayBuffer: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_DOWNLOAD_FAILED\",\n );\n }\n }\n\n public override getAsStream(key: string): ReadableStream {\n const filePath = this.getFilePath(key);\n\n if (!existsSync(filePath)) {\n throw new StorageException(`File ${key} does not exist`, \"FILE_NOT_FOUND\");\n }\n\n const file = Bun.file(filePath);\n\n try {\n return file.stream();\n } catch (error) {\n throw new StorageException(\n `Failed to read file ${key} as stream: ${error instanceof Error ? error.message : String(error)}`,\n \"STORAGE_DOWNLOAD_FAILED\",\n );\n }\n }\n}\n"
11
11
  ],
12
- "mappings": "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",
13
- "debugId": "9C8802670024636664756E2164756E21",
12
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AACA;AAEA;AACA;AACA;;;ACLA;AAGO,IAAM,YAAY;AAAA,EACvB,SAAS,CAAC,QAAyB,gBAAgB,cAAc;AAAA,IAC/D,OAAO,CAAC,WAAmC;AAAA,MACzC,UAAU,IAAI,QAAQ,KAAK;AAAA;AAAA;AAGjC;;;ACTA;AACA;AAAA;AAEO,MAAM,yBAAyB,UAAU;AAAA,EAC9C,WAAW,CAAC,SAAiB,KAAa,OAAgC,CAAC,GAAG;AAAA,IAC5E,MAAM,SAAS;AAAA,MACb;AAAA,MACA,QAAQ,WAAW,KAAK;AAAA,MACxB;AAAA,IACF,CAAC;AAAA,IACD,KAAK,OAAO;AAAA;AAEhB;;;AFCA,IAAM,aAA6E;AAAA,EACjF,IAAoB,wBAAQ,cAAc;AAAA,EAC1C,IAAoB,wBAAQ,cAAc;AAAA,EAC1C,IAAoB,wBAAQ,cAAc;AAAA,EAC1C,IAAoB,wBAAQ,cAAc;AAAA,EAC1C,IAAoB,wBAAQ,cAAc;AAAA,EAC1C,IAAoB,wBAAQ,cAAc;AAAA,EAC1C,IAAoB,wBAAQ,cAAc;AAAA,EAC1C,IAAoB,wBAAQ,cAAc;AAAA,EAC1C,KAAqB,wBAAQ,cAAc;AAC7C;AAAA;AAGO,MAAM,aAAiC;AAAA,EAIC;AAAA,EAHrC,SAAS;AAAA,EACA;AAAA,EAEjB,WAAW,CAAkC,KAAa;AAAA,IAAb;AAAA,IAC3C,MAAM,YAAY,KAAK,IAAI;AAAA,IAC3B,MAAM,cAAc,KAAK,IAAI;AAAA,IAC7B,MAAM,SAAS,KAAK,IAAI;AAAA,IAExB,IAAI,CAAC,WAAW;AAAA,MACd,MAAM,IAAI,iBACR,+JACA,kBACF;AAAA,IACF;AAAA,IACA,IAAI,CAAC,aAAa;AAAA,MAChB,MAAM,IAAI,iBACR,oKACA,uBACF;AAAA,IACF;AAAA,IAEA,MAAM,YAAY,WAAW,UAAU;AAAA,IACvC,KAAK,cAA8B,qBAAK,uBAAuB,WAAW,aAAa,SAAS;AAAA;AAAA,EAG3F,SAAS,GAAW;AAAA,IACzB,OAAO,KAAK;AAAA;AAAA,EAGP,SAAS,CAAC,MAAoB;AAAA,IACnC,KAAK,SAAS;AAAA,IAEd,OAAO;AAAA;AAAA,OAGI,KAAI,GAAsB;AAAA,IACrC,MAAM,OAAO,KAAK,SAAS,IAAI,KAAK,YAAY;AAAA,IAEhD,IAAI;AAAA,MACF,MAAM,QAAQ,MAAsB,qBAAK,KAAK,KAAK,aAAa,IAAI;AAAA,MAEpE,OAAO,MAAM,OAAO,CAAC,UAAS,CAAC,MAAK,WAAW,EAAE,IAAI,CAAC,UAAS,MAAK,UAAU;AAAA,MAC9E,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,yBAAyB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAC9E,uBACA;AAAA,QACE;AAAA,MACF,CACF;AAAA;AAAA;AAAA,OAIS,YAAW,GAAkB;AAAA,IACxC,MAAM,OAAO,MAAM,KAAK,KAAK;AAAA,IAE7B,MAAM,QAAQ,IAAI,KAAK,IAAI,CAAC,QAAQ,KAAK,OAAO,GAAG,CAAC,CAAC;AAAA,IAErD,OAAO;AAAA;AAAA,OAGI,OAAM,CAAC,KAA+B;AAAA,IACjD,IAAI;AAAA,MACF,MAAsB,qBAAK,IAAI,KAAK,aAAa,KAAK,cAAc,GAAG,CAAC;AAAA,MAExE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO;AAAA;AAAA;AAAA,OAIE,OAAM,CAAC,KAA4B;AAAA,IAC9C,IAAI;AAAA,MACF,MAAsB,qBAAK,OAAO,KAAK,aAAa,KAAK,cAAc,GAAG,CAAC;AAAA,MAC3E,MAAM;AAAA;AAAA,OAKG,QAAO,CAAC,KAAa,WAAoC;AAAA,IACpE,MAAM,QAAO,IAAI,KAAK,SAAS;AAAA,IAE/B,OAAO,MAAM,KAAK,IAAI,KAAK,KAAI;AAAA;AAAA,OAGpB,OAAM,CAAC,QAAgB,SAA6C;AAAA,IAC/E,QAAQ,MAAM,WAAW;AAAA,IACzB,MAAM,UAAU,MAAM,QAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;AAAA,IAE3D,MAAM,QAA2B,CAAC;AAAA,IAElC,WAAW,SAAS,SAAS;AAAA,MAC3B,MAAM,iBAAiB,KAAK,MAAM,MAAM,IAAI;AAAA,MAC5C,MAAM,WAAW,SAAS,GAAG,UAAU,MAAM,SAAS,MAAM;AAAA,MAE5D,IAAI,UAAU,CAAC,OAAO,KAAK,cAAc,GAAG;AAAA,QAC1C;AAAA,MACF;AAAA,MAEA,IAAI,MAAM,YAAY,GAAG;AAAA,QACvB,MAAM,aAAgC,EAAE,MAAM,eAAe;AAAA,QAC7D,IAAI,QAAQ;AAAA,UACV,WAAW,SAAS;AAAA,QACtB;AAAA,QACA,MAAM,KAAK,KAAK,OAAO,UAAU,UAAU,CAAC;AAAA,MAC9C,EAAO;AAAA,QACL,MAAM,KAAK,KAAK,QAAQ,UAAU,cAAc,CAAC;AAAA;AAAA,IAErD;AAAA,IAEA,MAAM,UAAU,MAAM,QAAQ,IAAI,KAAK;AAAA,IAEvC,OAAO,QAAQ,OAAO,CAAC,KAAK,UAAU,MAAM,OAAO,CAAC;AAAA;AAAA,OAGzC,IAAG,CACd,KACA,SACiB;AAAA,IACjB,QAAQ,QAAQ,WAAW,MAAM,KAAK,iBAAiB,OAAO;AAAA,IAC9D,MAAM,WAAW,KAAK,cAAc,GAAG;AAAA,IAEvC,IAAI;AAAA,MACF,MAAsB,qBAAK,OACzB,KAAK,aACL,UACA,MACF;AAAA,MACA,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,0BAA0B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAC/E,yBACA;AAAA,QACE;AAAA,MACF,CACF;AAAA;AAAA,IAGF,OAAO;AAAA;AAAA,OAGI,QAAO,CAAC,KAAa,SAA8C;AAAA,IAC9E,MAAM,cAAc,MAAM,KAAK,iBAAiB,GAAG;AAAA,IACnD,MAAM,WAAW,QAAQ,YAAY,SAAS,GAAG;AAAA,IACjD,MAAM,YAAY,KAAK,QAAQ,WAAW,QAAQ;AAAA,IAElD,OAAO,MAAM,IAAI,MAAM,WAAW,WAAW;AAAA;AAAA,OAGlC,UAAsB,CAAC,KAAyB;AAAA,IAC3D,IAAI;AAAA,MACF,QAAQ,WAAW,MAAsB,qBAAK,SAAS,KAAK,aAAa,KAAK,cAAc,GAAG,CAAC;AAAA,MAEhG,OAAO,MAAM,IAAI,SAAS,MAA6B,EAAE,KAAK;AAAA,MAC9D,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,+BAA+B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KACpF,2BACA,EAAE,IAAI,CACR;AAAA;AAAA;AAAA,OAIS,iBAAgB,CAAC,KAAmC;AAAA,IAC/D,IAAI;AAAA,MACF,QAAQ,WAAW,MAAsB,qBAAK,SAAS,KAAK,aAAa,KAAK,cAAc,GAAG,CAAC;AAAA,MAEhG,OAAO,MAAM,IAAI,SAAS,MAA6B,EAAE,YAAY;AAAA,MACrE,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,sCAAsC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAC3F,2BACA,EAAE,IAAI,CACR;AAAA;AAAA;AAAA,EAIG,WAAW,CAAC,KAA6B;AAAA,IAC9C,MAAM,WAAW,KAAK,cAAc,GAAG;AAAA,IAEvC,QAAQ,UAAU,aAAa,IAAI;AAAA,IAEnB,qBACb,SAAS,KAAK,aAAa,QAAQ,EACnC,KAAK,GAAG,aAAa;AAAA,MACnB,OAAqC,OAAO,QAAQ;AAAA,KACtD,EACA,MAAM,CAAC,UAAU;AAAA,MAChB,SAAS,MACP,IAAI,iBACF,iCAAiC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KACtF,2BACA,EAAE,IAAI,CACR,CACF;AAAA,KACD;AAAA,IAEH,OAAO;AAAA;AAAA,EAGD,aAAa,CAAC,KAAqB;AAAA,IACzC,OAAO,KAAK,SAAS,IAAI,KAAK,UAAU,QAAQ,IAAI;AAAA;AAAA,OAGxC,iBAAgB,CAC5B,SACiE;AAAA,IACjE,IAAI,OAAO,YAAY,UAAU;AAAA,MAC/B,MAAM,UAAU,IAAI,YAAY,EAAE,OAAO,OAAO;AAAA,MAChD,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,QAAQ,OAAO;AAAA,IACxE;AAAA,IAEA,IAAI,mBAAmB,aAAa;AAAA,MAClC,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,QAAQ,WAAW;AAAA,IAC5E;AAAA,IAEA,IAAI,mBAAmB,mBAAmB;AAAA,MACxC,MAAM,aAAa,IAAI,WAAW,OAAO;AAAA,MACzC,MAAM,SAAS,IAAI,WAAW,WAAW,MAAM;AAAA,MAC/C,OAAO,IAAI,UAAU;AAAA,MACrB,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,QAAQ,WAAW;AAAA,IAC3E;AAAA,IAEA,IAAI,YAAY,OAAO,OAAO,GAAG;AAAA,MAC/B,MAAM,OAAO,IAAI,WAAW,QAAQ,QAAuB,QAAQ,YAAY,QAAQ,UAAU;AAAA,MACjG,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,QAAQ,WAAW;AAAA,IACzE;AAAA,IAEA,IAAI,mBAAmB,MAAM;AAAA,MAC3B,OAAO,EAAE,QAAQ,QAAQ,OAAO,GAAG,QAAQ,QAAQ,KAAK;AAAA,IAC1D;AAAA,IAEA,IAAI,mBAAmB,WAAW,mBAAmB,UAAU;AAAA,MAC7D,MAAM,cAAc,MAAM,QAAQ,YAAY;AAAA,MAC9C,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,YAAY,WAAW;AAAA,IACpF;AAAA,IAEA,IAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,iBAAiB,SAAS;AAAA,MAC/E,MAAM,cAAc;AAAA,MACpB,MAAM,cAAc,MAAM,YAAY,YAAY;AAAA,MAClD,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,YAAY,WAAW;AAAA,IACpF;AAAA,IAEA,MAAM,IAAI,iBAAiB,uCAAuC,0BAA0B;AAAA;AAEhG;AAtPa,eAAN;AAAA,EADN,UAAU,QAAQ;AAAA,EAKJ,kCAAO,MAAM;AAAA,EAJrB;AAAA;AAAA;AAAA,GAAM;;AG1Bb,mBAAS;AACT,mBAAS;;;ACDT,oBAAS;AACT,qBAAS,mBAAU;AAAA;AAIZ,MAAe,QAA4B;AAAA,EACtC,SAA8B;AAAA,EAIjC,SAAS,GAAW;AAAA,IACzB,OAAO,KAAK;AAAA;AAAA,EAGP,SAAS,CAAC,MAAoB;AAAA,IACnC,KAAK,SAAS;AAAA,IACd,KAAK,SAAS,IAAI,IAAI,SAAS,KAAK,WAAW,CAAC;AAAA,IAEhD,OAAO;AAAA;AAAA,OAGI,KAAI,GAAsB;AAAA,IACrC,MAAM,SAAS,KAAK,UAAU;AAAA,IAE9B,QAAQ,MAAM,OAAO,KAAK,GAAG,UAAU,IAAI,CAAC,YAAY,QAAQ,GAAG,KAAK,CAAC;AAAA;AAAA,OAG9D,YAAW,GAAkB;AAAA,IACxC,MAAM,SAAS,KAAK,UAAU;AAAA,IAC9B,MAAM,OAAO,MAAM,KAAK,KAAK;AAAA,IAE7B,MAAM,QAAQ,IAAI,KAAK,IAAI,CAAC,QAAQ,OAAO,OAAO,GAAG,CAAC,CAAC;AAAA,IAEvD,OAAO;AAAA;AAAA,OAGI,OAAM,CAAC,KAA+B;AAAA,IACjD,MAAM,SAAS,KAAK,UAAU;AAAA,IAE9B,OAAO,MAAM,OAAO,OAAO,GAAG;AAAA;AAAA,OAGnB,OAAM,CAAC,KAA4B;AAAA,IAC9C,MAAM,SAAS,KAAK,UAAU;AAAA,IAE9B,MAAM,OAAO,OAAO,GAAG;AAAA;AAAA,OAGZ,QAAO,CAAC,KAAa,WAAoC;AAAA,IACpE,MAAM,QAAO,IAAI,KAAK,SAAS;AAAA,IAE/B,OAAO,MAAM,KAAK,IAAI,KAAK,KAAI;AAAA;AAAA,OAGpB,OAAM,CAAC,QAAgB,SAA6C;AAAA,IAC/E,QAAQ,MAAM,WAAW;AAAA,IACzB,MAAM,UAAU,MAAM,SAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;AAAA,IAE3D,MAAM,QAA2B,CAAC;AAAA,IAElC,WAAW,SAAS,SAAS;AAAA,MAC3B,MAAM,iBAAiB,MAAK,MAAM,MAAM,IAAI;AAAA,MAC5C,MAAM,WAAW,SAAS,GAAG,UAAU,MAAM,SAAS,MAAM;AAAA,MAE5D,IAAI,UAAU,CAAC,OAAO,KAAK,cAAc,GAAG;AAAA,QAC1C;AAAA,MACF;AAAA,MAEA,IAAI,MAAM,YAAY,GAAG;AAAA,QACvB,MAAM,aAAgC,EAAE,MAAM,eAAe;AAAA,QAC7D,IAAI,QAAQ;AAAA,UACV,WAAW,SAAS;AAAA,QACtB;AAAA,QACA,MAAM,KAAK,KAAK,OAAO,UAAU,UAAU,CAAC;AAAA,MAC9C,EAAO;AAAA,QACL,MAAM,KAAK,KAAK,QAAQ,UAAU,cAAc,CAAC;AAAA;AAAA,IAErD;AAAA,IAEA,MAAM,UAAU,MAAM,QAAQ,IAAI,KAAK;AAAA,IAEvC,OAAO,QAAQ,OAAO,CAAC,KAAK,UAAU,MAAM,OAAO,CAAC;AAAA;AAAA,OAGzC,IAAG,CACd,KACA,SACiB;AAAA,IACjB,MAAM,SAAiB,KAAK,UAAU,GAAG;AAAA,IAEzC,OAAO,MAAM,OAAO,MAAM,OAAO;AAAA;AAAA,OAGtB,QAAO,CAAC,KAAa,SAA8C;AAAA,IAC9E,MAAM,cAAc,MAAM,KAAK,iBAAiB,GAAG;AAAA,IACnD,MAAM,WAAW,QAAQ,YAAY,UAAS,GAAG;AAAA,IACjD,MAAM,YAAY,MAAK,QAAQ,WAAW,QAAQ;AAAA,IAElD,OAAO,MAAM,IAAI,MAAM,WAAW,WAAW;AAAA;AAAA,OAGlC,UAAY,CAAC,KAAyB;AAAA,IACjD,MAAM,SAAiB,KAAK,UAAU,GAAG;AAAA,IAEzC,OAAO,MAAM,OAAO,KAAK;AAAA;AAAA,OAGd,iBAAgB,CAAC,KAAmC;AAAA,IAC/D,MAAM,SAAiB,KAAK,UAAU,GAAG;AAAA,IAEzC,OAAO,MAAM,OAAO,YAAY;AAAA;AAAA,EAG3B,WAAW,CAAC,KAA6B;AAAA,IAC9C,MAAM,SAAiB,KAAK,UAAU,GAAG;AAAA,IAEzC,OAAO,OAAO,OAAO;AAAA;AAAA,EAGb,SAAS,GAAiB;AAAA,IAClC,IAAI,CAAC,KAAK,QAAQ;AAAA,MAChB,KAAK,SAAS,IAAI,IAAI,SAAS,KAAK,WAAW,CAAC;AAAA,IAClD;AAAA,IAEA,OAAO,KAAK;AAAA;AAAA,EAGJ,SAAS,CAAC,MAAsB;AAAA,IACxC,MAAM,SAAS,KAAK,UAAU;AAAA,IAE9B,OAAO,OAAO,KAAK,IAAI;AAAA;AAE3B;;;AD5HO,MAAM,0BAA0B,QAAQ;AAAA,EAOA;AAAA,EANnC;AAAA,EACO;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,WAAW,CAAkC,KAAa;AAAA,IACxD,MAAM;AAAA,IADqC;AAAA,IAG3C,MAAM,YAAY,KAAK,IAAI;AAAA,IAC3B,MAAM,YAAY,KAAK,IAAI;AAAA,IAC3B,MAAM,WAAW,KAAK,IAAI;AAAA,IAE1B,IAAI,CAAC,WAAW;AAAA,MACd,MAAM,IAAI,iBACR,yKACA,iBACF;AAAA,IACF;AAAA,IACA,IAAI,CAAC,WAAW;AAAA,MACd,MAAM,IAAI,iBACR,wKACA,iBACF;AAAA,IACF;AAAA,IACA,IAAI,CAAC,UAAU;AAAA,MACb,MAAM,IAAI,iBACR,mKACA,iBACF;AAAA,IACF;AAAA,IAEA,KAAK,YAAY;AAAA,IACjB,KAAK,YAAY;AAAA,IACjB,KAAK,WAAW;AAAA,IAChB,KAAK,SAAS,KAAK,IAAI,6BAA6B;AAAA;AAAA,EAG/C,UAAU,GAAc;AAAA,IAC7B,OAAO;AAAA,MACL,aAAa,KAAK;AAAA,MAClB,iBAAiB,KAAK;AAAA,MACtB,UAAU,KAAK;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,IACf;AAAA;AAEJ;AAhDa,oBAAN;AAAA,EADN,UAAU,QAAQ;AAAA,EAQJ,mCAAO,OAAM;AAAA,EAPrB;AAAA;AAAA;AAAA,GAAM;;AERb;AACA,2BAAgB;AAChB,qBAAS,4BAAmB;AAC5B,mBAAS;AACT,mBAAS;AAQF,MAAM,0BAA0B,QAAQ;AAAA,EAIA;AAAA,EAHnC;AAAA,EACO;AAAA,EAEjB,WAAW,CAAkC,KAAa;AAAA,IACxD,MAAM;AAAA,IADqC;AAAA,IAG3C,MAAM,WAAW,KAAK,IAAI;AAAA,IAE1B,IAAI,CAAC,UAAU;AAAA,MACb,MAAM,IAAI,iBACR,qJACA,2BACF;AAAA,IACF;AAAA,IAEA,KAAK,cAAc;AAAA,IAEnB,IAAI;AAAA,MACF,IAAI,CAAC,WAAW,QAAQ,GAAG;AAAA,QACzB,UAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,MACzC;AAAA,MACA,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,8CAA8C,aAAa,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAChH,yBACF;AAAA;AAAA;AAAA,EAIG,UAAU,GAAc;AAAA,IAC7B,OAAO;AAAA,MACL,aAAa;AAAA,MACb,iBAAiB;AAAA,MACjB,UAAU,KAAK;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,QAAQ;AAAA,IACV;AAAA;AAAA,EAGM,aAAa,GAAW;AAAA,IAC9B,IAAI,CAAC,KAAK,QAAQ;AAAA,MAChB,MAAM,IAAI,iBAAiB,2DAA2D,yBAAyB;AAAA,IACjH;AAAA,IACA,OAAO,MAAK,KAAK,aAAa,KAAK,MAAM;AAAA;AAAA,EAGnC,WAAW,CAAC,KAAqB;AAAA,IACvC,OAAO,MAAK,KAAK,cAAc,GAAG,GAAG;AAAA;AAAA,EAGvB,SAAS,CAAC,MAAoB;AAAA,IAC5C,KAAK,SAAS;AAAA,IAEd,MAAM,aAAa,KAAK,cAAc;AAAA,IACtC,IAAI;AAAA,MACF,IAAI,CAAC,WAAW,UAAU,GAAG;AAAA,QAC3B,UAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,MAC3C;AAAA,MACA,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,wCAAwC,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAC5G,uBACF;AAAA;AAAA,IAGF,OAAO;AAAA;AAAA,OAGa,KAAI,GAAsB;AAAA,IAC9C,MAAM,aAAa,KAAK,cAAc;AAAA,IAEtC,IAAI,CAAC,WAAW,UAAU,GAAG;AAAA,MAC3B,OAAO,CAAC;AAAA,IACV;AAAA,IAEA,IAAI;AAAA,MACF,MAAM,QAAQ,MAAM,KAAK,mBAAmB,YAAY,UAAU;AAAA,MAClE,OAAO;AAAA,MACP,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,mCAAmC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KACxF,qBACF;AAAA;AAAA;AAAA,OAIU,mBAAkB,CAAC,KAAa,SAAoC;AAAA,IAChF,MAAM,UAAU,MAAM,SAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAAA,IAE1D,MAAM,UAAU,MAAM,QAAQ,IAC5B,QAAQ,IAAI,OAAO,UAAU;AAAA,MAC3B,MAAM,WAAW,MAAK,KAAK,MAAM,IAAI;AAAA,MAErC,IAAI,MAAM,YAAY,GAAG;AAAA,QACvB,OAAO,KAAK,mBAAmB,UAAU,OAAO;AAAA,MAClD;AAAA,MAEA,OAAO,CAAC,SAAS,UAAU,QAAQ,SAAS,CAAC,CAAC;AAAA,KAC/C,CACH;AAAA,IAEA,OAAO,QAAQ,KAAK;AAAA;AAAA,OAGA,YAAW,GAAkB;AAAA,IACjD,MAAM,aAAa,KAAK,cAAc;AAAA,IAEtC,IAAI,CAAC,WAAW,UAAU,GAAG;AAAA,MAC3B,OAAO;AAAA,IACT;AAAA,IAEA,IAAI;AAAA,MACF,MAAM,GAAG,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,MACxC,MAAM,MAAM,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,MAC3C,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAChF,sBACF;AAAA;AAAA,IAGF,OAAO;AAAA;AAAA,OAGa,OAAM,CAAC,KAA+B;AAAA,IAC1D,MAAM,WAAW,KAAK,YAAY,GAAG;AAAA,IACrC,MAAM,QAAO,IAAI,KAAK,QAAQ;AAAA,IAC9B,OAAO,MAAM,MAAK,OAAO;AAAA;AAAA,OAGL,OAAM,CAAC,KAA4B;AAAA,IACvD,MAAM,WAAW,KAAK,YAAY,GAAG;AAAA,IACrC,MAAM,QAAO,IAAI,KAAK,QAAQ;AAAA,IAE9B,IAAI,CAAE,MAAM,MAAK,OAAO,GAAI;AAAA,MAC1B;AAAA,IACF;AAAA,IAEA,IAAI;AAAA,MACF,MAAM,MAAK,OAAO;AAAA,MAElB,IAAI,YAAY,QAAQ,QAAQ;AAAA,MAChC,MAAM,aAAa,KAAK,cAAc;AAAA,MAEtC,OAAO,cAAc,cAAc,cAAc,KAAK,aAAa;AAAA,QACjE,IAAI;AAAA,UACF,MAAM,UAAU,MAAM,SAAQ,SAAS;AAAA,UACvC,IAAI,QAAQ,WAAW,GAAG;AAAA,YACxB,MAAM,MAAM,SAAS;AAAA,YACrB,YAAY,QAAQ,SAAS;AAAA,UAC/B,EAAO;AAAA,YACL;AAAA;AAAA,UAEF,MAAM;AAAA,UACN;AAAA;AAAA,MAEJ;AAAA,MACA,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,yBAAyB,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KACtF,uBACF;AAAA;AAAA;AAAA,OAIkB,QAAO,CAAC,KAAa,WAAoC;AAAA,IAC7E,MAAM,QAAO,IAAI,KAAK,SAAS;AAAA,IAC/B,OAAO,MAAM,KAAK,IAAI,KAAK,KAAI;AAAA;AAAA,OAGX,IAAG,CACvB,KACA,SACiB;AAAA,IACjB,MAAM,WAAW,KAAK,YAAY,GAAG;AAAA,IACrC,MAAM,MAAM,QAAQ,QAAQ;AAAA,IAE5B,IAAI;AAAA,MACF,IAAI,CAAC,WAAW,GAAG,GAAG;AAAA,QACpB,MAAM,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,MACtC;AAAA,MACA,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,8BAA8B,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAC3F,uBACF;AAAA;AAAA,IAGF,IAAI;AAAA,MACF,IAAI;AAAA,MAEJ,IAAI,OAAO,YAAY,UAAU;AAAA,QAC/B,eAAe,MAAM,IAAI,MAAM,UAAU,OAAO;AAAA,MAClD,EAAO,SAAI,mBAAmB,aAAa;AAAA,QACzC,eAAe,MAAM,IAAI,MAAM,UAAU,OAAO;AAAA,MAClD,EAAO,SAAI,mBAAmB,mBAAmB;AAAA,QAC/C,MAAM,cAAc,IAAI,YAAY,QAAQ,UAAU;AAAA,QACtD,IAAI,WAAW,WAAW,EAAE,IAAI,IAAI,WAAW,OAAO,CAAC;AAAA,QACvD,eAAe,MAAM,IAAI,MAAM,UAAU,WAAW;AAAA,MACtD,EAAO,SAAI,mBAAmB,SAAS;AAAA,QACrC,MAAM,cAAc,MAAM,QAAQ,YAAY;AAAA,QAC9C,eAAe,MAAM,IAAI,MAAM,UAAU,WAAW;AAAA,MACtD,EAAO,SAAI,mBAAmB,UAAU;AAAA,QACtC,MAAM,cAAc,MAAM,QAAQ,YAAY;AAAA,QAC9C,eAAe,MAAM,IAAI,MAAM,UAAU,WAAW;AAAA,MACtD,EAAO,SAAI,mBAAmB,MAAM;AAAA,QAClC,eAAe,MAAM,IAAI,MAAM,UAAU,OAAO;AAAA,MAClD,EAAO;AAAA,QACL,MAAM,cAAc,MAAO,QAA6B,YAAY;AAAA,QACpE,eAAe,MAAM,IAAI,MAAM,UAAU,WAAW;AAAA;AAAA,MAGtD,OAAO;AAAA,MACP,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,wBAAwB,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KACrF,uBACF;AAAA;AAAA;AAAA,OAIkB,QAAO,CAAC,KAAa,SAA8C;AAAA,IACvF,MAAM,WAAW,KAAK,YAAY,GAAG;AAAA,IACrC,MAAM,QAAO,IAAI,KAAK,QAAQ;AAAA,IAE9B,IAAI,CAAE,MAAM,MAAK,OAAO,GAAI;AAAA,MAC1B,MAAM,IAAI,iBAAiB,QAAQ,sBAAsB,gBAAgB;AAAA,IAC3E;AAAA,IAEA,MAAM,WAAW,QAAQ,YAAY,UAAS,GAAG;AAAA,IACjD,MAAM,YAAY,MAAK,QAAQ,WAAW,QAAQ;AAAA,IAClD,MAAM,MAAM,QAAQ,SAAS;AAAA,IAE7B,IAAI;AAAA,MACF,IAAI,CAAC,WAAW,GAAG,GAAG;AAAA,QACpB,MAAM,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,MACtC;AAAA,MACA,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,8BAA8B,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAC3F,yBACF;AAAA;AAAA,IAGF,IAAI;AAAA,MACF,OAAO,MAAM,IAAI,MAAM,WAAW,KAAI;AAAA,MACtC,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,uBAAuB,UAAU,cAAc,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KACpG,yBACF;AAAA;AAAA;AAAA,OAIkB,UAAY,CAAC,KAAyB;AAAA,IAC1D,MAAM,WAAW,KAAK,YAAY,GAAG;AAAA,IACrC,MAAM,QAAO,IAAI,KAAK,QAAQ;AAAA,IAE9B,IAAI,CAAE,MAAM,MAAK,OAAO,GAAI;AAAA,MAC1B,MAAM,IAAI,iBAAiB,QAAQ,sBAAsB,gBAAgB;AAAA,IAC3E;AAAA,IAEA,IAAI;AAAA,MACF,OAAO,MAAM,MAAK,KAAK;AAAA,MACvB,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,uBAAuB,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAC5F,yBACF;AAAA;AAAA;AAAA,OAIkB,iBAAgB,CAAC,KAAmC;AAAA,IACxE,MAAM,WAAW,KAAK,YAAY,GAAG;AAAA,IACrC,MAAM,QAAO,IAAI,KAAK,QAAQ;AAAA,IAE9B,IAAI,CAAE,MAAM,MAAK,OAAO,GAAI;AAAA,MAC1B,MAAM,IAAI,iBAAiB,QAAQ,sBAAsB,gBAAgB;AAAA,IAC3E;AAAA,IAEA,IAAI;AAAA,MACF,OAAO,MAAM,MAAK,YAAY;AAAA,MAC9B,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,uBAAuB,uBAAuB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KACnG,yBACF;AAAA;AAAA;AAAA,EAIY,WAAW,CAAC,KAA6B;AAAA,IACvD,MAAM,WAAW,KAAK,YAAY,GAAG;AAAA,IAErC,IAAI,CAAC,WAAW,QAAQ,GAAG;AAAA,MACzB,MAAM,IAAI,iBAAiB,QAAQ,sBAAsB,gBAAgB;AAAA,IAC3E;AAAA,IAEA,MAAM,QAAO,IAAI,KAAK,QAAQ;AAAA,IAE9B,IAAI;AAAA,MACF,OAAO,MAAK,OAAO;AAAA,MACnB,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,iBACR,uBAAuB,kBAAkB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAC9F,yBACF;AAAA;AAAA;AAGN;AArTa,oBAAN;AAAA,EADN,UAAU,QAAQ;AAAA,EAKJ,mCAAO,OAAM;AAAA,EAJrB;AAAA;AAAA;AAAA,GAAM;",
13
+ "debugId": "B7060C45594F90B964756E2164756E21",
14
14
  "names": []
15
15
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ooneex/storage",
3
3
  "description": "File storage abstraction supporting local filesystem and cloud providers — upload, download, list, and manage files with a unified bucket-based API",
4
- "version": "1.1.4",
4
+ "version": "1.1.6",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",
@@ -28,10 +28,11 @@
28
28
  "npm:publish": "bun publish --tolerate-republish --force --production --access public"
29
29
  },
30
30
  "dependencies": {
31
- "@ooneex/app-env": "1.2.0",
32
- "@ooneex/container": "1.1.2",
33
- "@ooneex/exception": "1.1.2",
34
- "@ooneex/http-status": "1.1.2"
31
+ "@bunny.net/storage-sdk": "^0.3.1",
32
+ "@ooneex/app-env": "1.3.0",
33
+ "@ooneex/container": "1.2.2",
34
+ "@ooneex/exception": "1.2.0",
35
+ "@ooneex/http-status": "1.1.3"
35
36
  },
36
37
  "keywords": [
37
38
  "blob",