@nuvix/storage 1.0.0 → 2.0.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/index.d.ts CHANGED
@@ -1,470 +1,14 @@
1
- interface DeviceMetadata {
2
- [key: string]: any;
3
- }
4
- declare abstract class Device {
5
- /**
6
- * Max chunk size while transferring file from one device to another
7
- */
8
- protected transferChunkSize: number;
9
- /**
10
- * Sets the maximum number of keys returned to the response. By default, the action returns up to 1,000 key names.
11
- */
12
- protected static readonly MAX_PAGE_SIZE: number;
13
- /**
14
- * Set Transfer Chunk Size
15
- */
16
- setTransferChunkSize(chunkSize: number): void;
17
- /**
18
- * Get Transfer Chunk Size
19
- */
20
- getTransferChunkSize(): number;
21
- /**
22
- * Get Name.
23
- *
24
- * Get storage device name
25
- */
26
- abstract getName(): string;
27
- /**
28
- * Get Type.
29
- *
30
- * Get storage device type
31
- */
32
- abstract getType(): string;
33
- /**
34
- * Get Description.
35
- *
36
- * Get storage device description and purpose.
37
- */
38
- abstract getDescription(): string;
39
- /**
40
- * Get Root.
41
- *
42
- * Get storage device root path
43
- */
44
- abstract getRoot(): string;
45
- /**
46
- * Get Path.
47
- *
48
- * Each device hold a complex directory structure that is being build in this method.
49
- */
50
- abstract getPath(filename: string, prefix?: string): string;
51
- /**
52
- * Upload.
53
- *
54
- * Upload a file to desired destination in the selected disk
55
- * return number of chunks uploaded or 0 if it fails.
56
- */
57
- abstract upload(source: string, path: string, chunk?: number, chunks?: number, metadata?: DeviceMetadata): Promise<number>;
58
- /**
59
- * Upload Data.
60
- *
61
- * Upload file contents to desired destination in the selected disk.
62
- * return number of chunks uploaded or 0 if it fails.
63
- */
64
- abstract uploadData(data: string | Buffer, path: string, contentType: string, chunk?: number, chunks?: number, metadata?: DeviceMetadata): Promise<number>;
65
- /**
66
- * Abort Chunked Upload
67
- */
68
- abstract abort(path: string, extra?: string): Promise<boolean>;
69
- /**
70
- * Read file by given path.
71
- */
72
- abstract read(path: string, offset?: number, length?: number): Promise<Buffer>;
73
- /**
74
- * Transfer
75
- * Transfer a file from current device to destination device.
76
- */
77
- abstract transfer(path: string, destination: string, device: Device): Promise<boolean>;
78
- /**
79
- * Write file by given path.
80
- */
81
- abstract write(path: string, data: string | Buffer, contentType: string): Promise<boolean>;
82
- /**
83
- * Move file from given source to given path, return true on success and false on failure.
84
- */
85
- move(source: string, target: string): Promise<boolean>;
86
- /**
87
- * Delete file in given path return true on success and false on failure.
88
- */
89
- abstract delete(path: string, recursive?: boolean): Promise<boolean>;
90
- /**
91
- * Delete files in given path, path must be a directory. return true on success and false on failure.
92
- */
93
- abstract deletePath(path: string): Promise<boolean>;
94
- /**
95
- * Check if file exists
96
- */
97
- abstract exists(path: string): Promise<boolean>;
98
- /**
99
- * Returns given file path its size.
100
- */
101
- abstract getFileSize(path: string): Promise<number>;
102
- /**
103
- * Returns given file path its mime type.
104
- */
105
- abstract getFileMimeType(path: string): Promise<string>;
106
- /**
107
- * Returns given file path its MD5 hash value.
108
- */
109
- abstract getFileHash(path: string): Promise<string>;
110
- /**
111
- * Create a directory at the specified path.
112
- *
113
- * Returns true on success or if the directory already exists and false on error
114
- */
115
- abstract createDirectory(path: string): Promise<boolean>;
116
- /**
117
- * Get directory size in bytes.
118
- *
119
- * Return -1 on error
120
- */
121
- abstract getDirectorySize(path: string): Promise<number>;
122
- /**
123
- * Get Partition Free Space.
124
- *
125
- * Returns available space on filesystem or disk partition
126
- */
127
- abstract getPartitionFreeSpace(): Promise<number>;
128
- /**
129
- * Get Partition Total Space.
130
- *
131
- * Returns the total size of a filesystem or disk partition
132
- */
133
- abstract getPartitionTotalSpace(): Promise<number>;
134
- /**
135
- * Get all files and directories inside a directory.
136
- */
137
- abstract getFiles(dir: string, max?: number, continuationToken?: string): Promise<any[]>;
138
- /**
139
- * Get the absolute path by resolving strings like ../, .., //, /\ and so on.
140
- *
141
- * Works like the realpath function but works on files that does not exist
142
- */
143
- getAbsolutePath(path: string): string;
144
- protected getMimeType(filePath: string): Promise<string>;
145
- }
146
-
147
- declare class Storage {
148
- /**
149
- * Supported devices
150
- */
151
- static readonly DEVICE_LOCAL = "local";
152
- static readonly DEVICE_S3 = "s3";
153
- static readonly DEVICE_WASABI = "wasabi";
154
- static readonly DEVICE_MINIO = "minio";
155
- /**
156
- * Devices.
157
- *
158
- * List of all available storage devices
159
- */
160
- private static devices;
161
- /**
162
- * Set Device.
163
- *
164
- * Add device by name
165
- *
166
- * @param name
167
- * @param device
168
- * @throws Error
169
- */
170
- static setDevice(name: string, device: Device): void;
171
- /**
172
- * Get Device.
173
- *
174
- * Get device by name
175
- *
176
- * @param name
177
- * @returns Device
178
- * @throws Error
179
- */
180
- static getDevice(name: string): Device;
181
- /**
182
- * Exists.
183
- *
184
- * Checks if given storage name is registered or not
185
- *
186
- * @param name
187
- * @returns boolean
188
- */
189
- static exists(name: string): boolean;
190
- /**
191
- * Human readable data size format from bytes input.
192
- *
193
- * Based on: https://stackoverflow.com/a/38659168/2299554
194
- *
195
- * @param bytes
196
- * @param decimals
197
- * @param system
198
- * @returns string
199
- */
200
- static human(bytes: number, decimals?: number, system?: "binary" | "metric"): string;
201
- }
202
-
203
- declare abstract class Validator {
204
- static TYPE_STRING: string;
205
- static TYPE_ARRAY: string;
206
- static TYPE_INTEGER: string;
207
- static TYPE_BOOLEAN: string;
208
- abstract isValid(value: any): boolean | Promise<boolean>;
209
- }
210
-
211
- declare class File extends Validator {
212
- getDescription(): string;
213
- /**
214
- * NOT MUCH RIGHT NOW.
215
- *
216
- * TODO think what to do here, currently only used for parameter to be present in SDKs
217
- *
218
- * @param name
219
- * @return boolean
220
- */
221
- isValid(name: any): boolean;
222
- }
223
-
224
- declare class FileExt extends Validator {
225
- static readonly TYPE_JPEG = "jpeg";
226
- static readonly TYPE_JPG = "jpg";
227
- static readonly TYPE_GIF = "gif";
228
- static readonly TYPE_PNG = "png";
229
- static readonly TYPE_GZIP = "gz";
230
- static readonly TYPE_ZIP = "zip";
231
- private allowed;
232
- constructor(allowed: string[]);
233
- getDescription(): string;
234
- isValid(filename: string): boolean;
235
- private getFileExtension;
236
- }
237
-
238
- declare class FileName extends Validator {
239
- /**
240
- * Get Description
241
- */
242
- getDescription(): string;
243
- /**
244
- * The file name can only contain "a-z", "A-Z", "0-9" and "." and not empty.
245
- *
246
- * @param name - The filename to validate
247
- * @returns boolean indicating if the filename is valid
248
- */
249
- isValid(name: any): boolean;
250
- }
251
-
252
- declare class FileSize extends Validator {
253
- private max;
254
- /**
255
- * Max size in bytes
256
- */
257
- constructor(max: number);
258
- /**
259
- * Get Description
260
- */
261
- getDescription(): string;
262
- /**
263
- * Finds whether a file size is smaller than required limit.
264
- */
265
- isValid(fileSize: any): boolean;
266
- }
267
-
268
- declare class FileType extends Validator {
269
- /**
270
- * File Types Constants.
271
- */
272
- static readonly FILE_TYPE_JPEG = "jpeg";
273
- static readonly FILE_TYPE_GIF = "gif";
274
- static readonly FILE_TYPE_PNG = "png";
275
- static readonly FILE_TYPE_GZIP = "gz";
276
- /**
277
- * File Type Binaries.
278
- */
279
- private readonly types;
280
- private readonly allowed;
281
- constructor(allowed: string[]);
282
- /**
283
- * Get Description
284
- */
285
- getDescription(): string;
286
- /**
287
- * Is Valid.
288
- *
289
- * Binary check to finds whether a file is of valid type
290
- */
291
- isValid(path: string): Promise<boolean>;
292
- }
293
-
294
- declare class Upload extends Validator {
295
- /**
296
- * Get Description
297
- */
298
- getDescription(): string;
299
- /**
300
- * Check if a file is a valid upload file
301
- *
302
- * @param path - The file path to validate
303
- * @returns Promise that resolves to true if valid upload file, false otherwise
304
- */
305
- isValid(path: unknown): Promise<boolean>;
306
- }
307
-
308
- declare class Local extends Device {
309
- protected root: string;
310
- protected readonly MAX_PAGE_SIZE = 1000;
311
- constructor(root?: string);
312
- getName(): string;
313
- getType(): string;
314
- getDescription(): string;
315
- getRoot(): string;
316
- getPath(filename: string, prefix?: string): string;
317
- upload(source: string, filePath: string, chunk?: number, chunks?: number, metadata?: Record<string, any>): Promise<number>;
318
- uploadData(data: string | Buffer, filePath: string, contentType: string, chunk?: number, chunks?: number, metadata?: Record<string, any>): Promise<number>;
319
- private joinChunks;
320
- transfer(filePath: string, destination: string, device: Device): Promise<boolean>;
321
- abort(filePath: string, extra?: string): Promise<boolean>;
322
- read(filePath: string, offset?: number, length?: number): Promise<Buffer>;
323
- write(filePath: string, data: string | Buffer, contentType?: string): Promise<boolean>;
324
- move(source: string, target: string): Promise<boolean>;
325
- delete(filePath: string, recursive?: boolean): Promise<boolean>;
326
- deletePath(filePath: string): Promise<boolean>;
327
- exists(filePath: string): Promise<boolean>;
328
- getFileSize(filePath: string): Promise<number>;
329
- getFileMimeType(filePath: string): Promise<string>;
330
- getFileHash(filePath: string): Promise<string>;
331
- createDirectory(dirPath: string): Promise<boolean>;
332
- getDirectorySize(dirPath: string): Promise<number>;
333
- getPartitionFreeSpace(): Promise<number>;
334
- getPartitionTotalSpace(): Promise<number>;
335
- getFiles(dir: string, max?: number, continuationToken?: string): Promise<string[]>;
336
- }
337
-
338
- declare class S3 extends Device {
339
- static readonly METHOD_GET = "GET";
340
- static readonly METHOD_POST = "POST";
341
- static readonly METHOD_PUT = "PUT";
342
- static readonly METHOD_PATCH = "PATCH";
343
- static readonly METHOD_DELETE = "DELETE";
344
- static readonly METHOD_HEAD = "HEAD";
345
- static readonly METHOD_OPTIONS = "OPTIONS";
346
- static readonly METHOD_CONNECT = "CONNECT";
347
- static readonly METHOD_TRACE = "TRACE";
348
- static readonly US_EAST_1 = "us-east-1";
349
- static readonly US_EAST_2 = "us-east-2";
350
- static readonly US_WEST_1 = "us-west-1";
351
- static readonly US_WEST_2 = "us-west-2";
352
- static readonly AF_SOUTH_1 = "af-south-1";
353
- static readonly AP_EAST_1 = "ap-east-1";
354
- static readonly AP_SOUTH_1 = "ap-south-1";
355
- static readonly AP_NORTHEAST_3 = "ap-northeast-3";
356
- static readonly AP_NORTHEAST_2 = "ap-northeast-2";
357
- static readonly AP_NORTHEAST_1 = "ap-northeast-1";
358
- static readonly AP_SOUTHEAST_1 = "ap-southeast-1";
359
- static readonly AP_SOUTHEAST_2 = "ap-southeast-2";
360
- static readonly CA_CENTRAL_1 = "ca-central-1";
361
- static readonly EU_CENTRAL_1 = "eu-central-1";
362
- static readonly EU_WEST_1 = "eu-west-1";
363
- static readonly EU_SOUTH_1 = "eu-south-1";
364
- static readonly EU_WEST_2 = "eu-west-2";
365
- static readonly EU_WEST_3 = "eu-west-3";
366
- static readonly EU_NORTH_1 = "eu-north-1";
367
- static readonly SA_EAST_1 = "eu-north-1";
368
- static readonly CN_NORTH_1 = "cn-north-1";
369
- static readonly CN_NORTH_4 = "cn-north-4";
370
- static readonly CN_NORTHWEST_1 = "cn-northwest-1";
371
- static readonly ME_SOUTH_1 = "me-south-1";
372
- static readonly US_GOV_EAST_1 = "us-gov-east-1";
373
- static readonly US_GOV_WEST_1 = "us-gov-west-1";
374
- static readonly ACL_PRIVATE = "private";
375
- static readonly ACL_PUBLIC_READ = "public-read";
376
- static readonly ACL_PUBLIC_READ_WRITE = "public-read-write";
377
- static readonly ACL_AUTHENTICATED_READ = "authenticated-read";
378
- protected static readonly MAX_PAGE_SIZE = 1000;
379
- protected static retryAttempts: number;
380
- protected static retryDelay: number;
381
- protected accessKey: string;
382
- protected secretKey: string;
383
- protected bucket: string;
384
- protected region: string;
385
- protected acl: string;
386
- protected root: string;
387
- protected headers: Record<string, string>;
388
- protected amzHeaders: Record<string, string>;
389
- constructor(root: string, accessKey: string, secretKey: string, bucket: string, region?: string, acl?: string, endpointUrl?: string);
390
- getName(): string;
391
- getType(): string;
392
- getDescription(): string;
393
- getRoot(): string;
394
- getPath(filename: string, prefix?: string): string;
395
- getPartitionTotalSpace(): Promise<number>;
396
- static setRetryAttempts(attempts: number): void;
397
- static setRetryDelay(delay: number): void;
398
- upload(source: string | Buffer, path: string, chunk?: number, chunks?: number, metadata?: Record<string, any>): Promise<number>;
399
- uploadData(data: Buffer, path: string, contentType: string, chunk?: number, chunks?: number, metadata?: Record<string, any>): Promise<number>;
400
- transfer(path: string, destination: string, device: Device): Promise<boolean>;
401
- protected createMultipartUpload(path: string, contentType: string): Promise<string>;
402
- protected uploadPart(data: Buffer, path: string, contentType: string, chunk: number, uploadId: string): Promise<string>;
403
- protected completeMultipartUpload(path: string, uploadId: string, parts: Record<number, string>): Promise<boolean>;
404
- abort(path: string, extra?: string): Promise<boolean>;
405
- read(path: string, offset?: number, length?: number): Promise<Buffer>;
406
- write(path: string, data: Buffer, contentType?: string): Promise<boolean>;
407
- delete(path: string, recursive?: boolean): Promise<boolean>;
408
- protected listObjects(prefix?: string, maxKeys?: number, continuationToken?: string): Promise<any>;
409
- deletePath(path: string): Promise<boolean>;
410
- exists(path: string): Promise<boolean>;
411
- getFileSize(path: string): Promise<number>;
412
- getFileMimeType(path: string): Promise<string>;
413
- getFileHash(path: string): Promise<string>;
414
- createDirectory(path: string): Promise<boolean>;
415
- getDirectorySize(path: string): Promise<number>;
416
- getPartitionFreeSpace(): Promise<number>;
417
- getFiles(dir: string, max?: number, continuationToken?: string): Promise<any>;
418
- private getInfo;
419
- protected getSignatureV4(method: string, uri: string, parameters?: Record<string, string>): string;
420
- protected call(method: string, uri: string, data?: string | Buffer, parameters?: Record<string, string>, decode?: boolean): Promise<{
421
- body: any;
422
- buffer: ArrayBuffer;
423
- headers: Record<string, string>;
424
- code: number;
425
- }>;
426
- protected md5(data: string | Buffer): Buffer;
427
- protected sha256(data: string | Buffer): string;
428
- protected hmacSha256(data: string | Buffer, key: string | Buffer, encoding?: "hex" | "binary"): string | Buffer;
429
- }
430
-
431
- declare class Wasabi extends S3 {
432
- /**
433
- * Regions constants
434
- */
435
- static readonly US_WEST_1 = "us-west-1";
436
- static readonly AP_NORTHEAST_1 = "ap-northeast-1";
437
- static readonly AP_NORTHEAST_2 = "ap-northeast-2";
438
- static readonly EU_CENTRAL_1 = "eu-central-1";
439
- static readonly EU_CENTRAL_2 = "eu-central-2";
440
- static readonly EU_WEST_1 = "eu-west-1";
441
- static readonly EU_WEST_2 = "eu-west-2";
442
- static readonly US_CENTRAL_1 = "us-central-1";
443
- static readonly US_EAST_1 = "us-east-1";
444
- static readonly US_EAST_2 = "us-east-2";
445
- /**
446
- * Wasabi Constructor
447
- */
448
- constructor(root: string, accessKey: string, secretKey: string, bucket: string, region?: string, acl?: string);
449
- getName(): string;
450
- getDescription(): string;
451
- getType(): string;
452
- }
453
-
454
- declare class MinIO extends S3 {
455
- /**
456
- * MinIO Constructor
457
- */
458
- constructor(root: string, accessKey: string, secretKey: string, bucket: string, endpoint?: string, acl?: string, useSSL?: boolean);
459
- private endpointUrl;
460
- getName(): string;
461
- getDescription(): string;
462
- getType(): string;
463
- /**
464
- * Override the call method to use the custom endpoint
465
- */
466
- protected call(method: string, uri: string, data?: string | Buffer, parameters?: Record<string, string>, decode?: boolean): Promise<any>;
467
- }
468
-
469
- export { Device, File, FileExt, FileName, FileSize, FileType, Local, MinIO, S3, Storage, Upload, Wasabi };
470
- export type { DeviceMetadata };
1
+ export * from "./src/errors.js";
2
+ export * from "./src/device.js";
3
+ export * from "./src/storage.js";
4
+ export * from "./src/validator/file.js";
5
+ export * from "./src/validator/file-ext.js";
6
+ export * from "./src/validator/file-name.js";
7
+ export * from "./src/validator/file-size.js";
8
+ export * from "./src/validator/file-type.js";
9
+ export * from "./src/validator/upload.js";
10
+ export * from "./src/device/local.js";
11
+ export * from "./src/device/s3.js";
12
+ export * from "./src/device/wasabi.js";
13
+ export * from "./src/device/minio.js";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ var D=import.meta.require;class a extends Error{code;path;constructor(t,e,r){super(e);this.name="StorageError",this.code=t,this.path=r}}class y{transferChunkSize=20000000;setTransferChunkSize(t){this.transferChunkSize=t}getTransferChunkSize(){return this.transferChunkSize}async transfer(t,e,r){if(!await this.exists(t))throw new a("FILE_NOT_FOUND",`File not found: ${t}`,t);let i=await this.getFileSize(t),s=await this.getFileMimeType(t);if(i<=this.transferChunkSize)return r.write(e,await this.read(t),s);let n=Math.ceil(i/this.transferChunkSize),o={};for(let c=0;c<n;c++){let p=await this.read(t,c*this.transferChunkSize,this.transferChunkSize);await r.uploadData(p,e,s,c+1,n,o)}return!0}async move(t,e){if(t===e)return!1;if(!await this.exists(t))return!1;if(await this.transfer(t,e,this))return this.delete(t);return!1}presign(t,e){throw new a("UNSUPPORTED_OPERATION",`${this.getName()} does not support presigned URLs`)}getAbsolutePath(t){let r=t.replace(/[/\\]/g,"/").split("/").filter((s)=>s.length>0),i=[];for(let s of r){if(s===".")continue;if(s==="..")i.pop();else i.push(s)}return"/"+i.join("/")}}class d{static DEVICE_LOCAL="local";static DEVICE_S3="s3";static DEVICE_WASABI="wasabi";static DEVICE_MINIO="minio";static devices=new Map;static setDevice(t,e){this.devices.set(t,e)}static getDevice(t){let e=this.devices.get(t);if(!e)throw new a("DEVICE_NOT_FOUND",`The device "${t}" is not listed`,t);return e}static exists(t){return this.devices.has(t)}static removeDevice(t){return this.devices.delete(t)}static listDevices(){return[...this.devices.keys()]}static human(t,e=2,r="metric"){let i=r==="binary"?1024:1000,s={binary:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"],metric:["B","kB","MB","GB","TB","PB","EB","ZB","YB"]},n=Math.floor((t.toString().length-1)/3);return`${(t/Math.pow(i,n)).toFixed(e)}${s[r][n]}`}}class u{static TYPE_STRING="string";static TYPE_ARRAY="array";static TYPE_INTEGER="integer";static TYPE_BOOLEAN="boolean"}class B extends u{getDescription(){return"File is not valid"}isValid(t){return!0}}class k extends u{static TYPE_JPEG="jpeg";static TYPE_JPG="jpg";static TYPE_GIF="gif";static TYPE_PNG="png";static TYPE_GZIP="gz";static TYPE_ZIP="zip";allowed;constructor(t){super();this.allowed=t}getDescription(){return"File extension is not valid"}isValid(t){let e=this.getFileExtension(t).toLowerCase();return this.allowed.includes(e)}getFileExtension(t){let e=t.lastIndexOf(".");return e!==-1?t.substring(e+1):""}}class C extends u{getDescription(){return"Filename is not valid"}isValid(t){if(!t)return!1;if(typeof t!=="string")return!1;if(!/^[a-zA-Z0-9.]+$/.test(t))return!1;return!0}}class U extends u{max;constructor(t){super();this.max=t}getDescription(){return`File size can't be bigger than ${this.max}`}isValid(t){if(typeof t!=="number"||!Number.isInteger(t))return!1;if(t>this.max||t<0)return!1;return!0}}class f extends u{static FILE_TYPE_JPEG="jpeg";static FILE_TYPE_GIF="gif";static FILE_TYPE_PNG="png";static FILE_TYPE_GZIP="gz";types={[f.FILE_TYPE_JPEG]:[255,216,255],[f.FILE_TYPE_GIF]:[71,73,70],[f.FILE_TYPE_PNG]:[137,80,78,71,13,10],[f.FILE_TYPE_GZIP]:[31,139]};allowed;constructor(t){super();for(let e of t)if(!(e in this.types))throw Error("Unknown file mime type");this.allowed=t}getDescription(){return"File mime-type is not allowed "}async isValid(t){try{let e=Math.max(...Object.values(this.types).map((i)=>i.length)),r=await Bun.file(t).slice(0,e).bytes();return this.allowed.some((i)=>{let s=this.types[i];return s!==void 0&&s.every((n,o)=>r[o]===n)})}catch{return!1}}}import{promises as z}from"fs";class M extends u{getDescription(){return"Not a valid upload file"}async isValid(t){if(typeof t!=="string")return!1;try{return(await z.stat(t)).isFile()}catch{return!1}}}import{mkdir as R,readdir as x,rm as E,statfs as F}from"fs/promises";import l from"path";var I=".part.";class V extends y{root;constructor(t=""){super();this.root=t}getName(){return"Local Storage"}getType(){return d.DEVICE_LOCAL}getDescription(){return"Adapter for local storage on the physical or virtual machine, or mounted to it."}getRoot(){return this.root}getPath(t,e){return this.getAbsolutePath(l.join(this.root,t))}async upload(t,e,r=1,i=1,s={}){if(i<=1){await this.createDirectory(l.dirname(e));try{return await this.rename(t,e),1}catch{throw new a("UPLOAD_FAILED",`Can't upload file ${e}`,e)}}let n=m(e);await this.createDirectory(n);let o=T(e,r);try{await this.rename(t,o)}catch{throw new a("UPLOAD_FAILED",`Failed to write chunk ${r}`,e)}let c=(await this.listParts(e)).length;if(c===i)await this.joinChunks(e,i);return c}async uploadData(t,e,r,i=1,s=1,n={}){if(s<=1)return await this.write(e,t)?1:0;let o=m(e);await this.createDirectory(o);try{await Bun.write(T(e,i),t)}catch{throw new a("UPLOAD_FAILED",`Failed to write chunk ${i}`,e)}let c=(await this.listParts(e)).length;if(c===s)await this.joinChunks(e,s);return c}async abort(t,e=""){let r=m(t);if(await Bun.file(t).exists())await Bun.file(t).delete();if(!await w(r))throw new a("FILE_NOT_FOUND",`No staged upload for ${t}`,t);return await E(r,{recursive:!0,force:!0}),!0}async read(t,e=0,r){let i=Bun.file(t);if(!await i.exists())throw new a("FILE_NOT_FOUND",`File not found: ${t}`,t);let s=r===void 0?e>0?i.slice(e):i:i.slice(e,e+r);return Buffer.from(await s.arrayBuffer())}async write(t,e,r=""){try{return await this.createDirectory(l.dirname(t)),await Bun.write(Bun.file(t),e),!0}catch{throw new a("WRITE_FAILED",`Can't write to path ${t}`,t)}}async move(t,e){if(t===e||!await G(t))return!1;try{return await this.createDirectory(l.dirname(e)),await this.rename(t,e),!0}catch{return!1}}async delete(t,e=!1){try{let r=Bun.file(t);if(await r.exists())return await r.delete(),!0;if(e&&await w(t))return await E(t,{recursive:!0}),!0;return!1}catch{return!1}}async deletePath(t){if(!await w(t))return!1;return await E(t,{recursive:!0,force:!0}),!0}async exists(t){return Bun.file(t).exists()}async getFileSize(t){let e=Bun.file(t).size;if(e===-1&&!await Bun.file(t).exists())throw new a("FILE_NOT_FOUND",`File not found: ${t}`,t);return e}async getFileMimeType(t){return A(Bun.file(t).type)}async getFileHash(t){let e=new Bun.CryptoHasher("md5");return e.update(await Bun.file(t).bytes()),e.digest("hex")}async stat(t){let e=Bun.file(t);if(!await e.exists())throw new a("FILE_NOT_FOUND",`File not found: ${t}`,t);return{size:e.size,mimeType:A(e.type)}}async createDirectory(t){try{return await R(t,{recursive:!0,mode:493}),!0}catch{return!1}}async getDirectorySize(t){let e=0,r;try{r=await this.getFiles(t)}catch{return-1}for(let i of r)if(await w(i.key))e+=await this.getDirectorySize(i.key);else e+=Bun.file(i.key).size;return e}async getPartitionFreeSpace(){let t=await F(this.root||".");return t.bavail*t.bsize}async getPartitionTotalSpace(){let t=await F(this.root||".");return t.blocks*t.bsize}async getFiles(t){try{return(await x(t,{withFileTypes:!0})).map((r)=>({key:l.join(t,r.name),size:r.isFile()?Bun.file(l.join(t,r.name)).size:void 0}))}catch{return[]}}async joinChunks(t,e){let i=Bun.file(t).writer();for(let s=1;s<=e;s++){let n=T(t,s);i.write(await Bun.file(n).bytes())}await i.end(),await E(m(t),{recursive:!0,force:!0})}async listParts(t){let e=m(t),r=`${l.parse(t).name}${I}`;try{return(await x(e)).filter((s)=>s.startsWith(r))}catch{return[]}}async rename(t,e){await import("fs").then((r)=>r.promises.rename(t,e))}}function m(t){return l.join(l.dirname(t),`tmp_${l.basename(t)}`)}function T(t,e){return l.join(m(t),`${l.parse(t).name}${I}${e}`)}async function G(t){return Bun.file(t).exists()}async function w(t){try{let{stat:e}=await import("fs/promises");return(await e(t)).isDirectory()}catch{return!1}}function A(t){return t.split(";")[0]?.trim()??""}var{S3Client:W}=globalThis.Bun;var b=".part-",P=(t)=>String(t).padStart(5,"0"),O=(t)=>t.replace(/^"|"$/g,""),v=(t)=>t.split(";")[0]?.trim()??"";class g extends y{static US_EAST_1="us-east-1";static US_EAST_2="us-east-2";static US_WEST_1="us-west-1";static US_WEST_2="us-west-2";static AF_SOUTH_1="af-south-1";static AP_EAST_1="ap-east-1";static AP_SOUTH_1="ap-south-1";static AP_NORTHEAST_1="ap-northeast-1";static AP_NORTHEAST_2="ap-northeast-2";static AP_NORTHEAST_3="ap-northeast-3";static AP_SOUTHEAST_1="ap-southeast-1";static AP_SOUTHEAST_2="ap-southeast-2";static CA_CENTRAL_1="ca-central-1";static EU_CENTRAL_1="eu-central-1";static EU_WEST_1="eu-west-1";static EU_WEST_2="eu-west-2";static EU_WEST_3="eu-west-3";static EU_SOUTH_1="eu-south-1";static EU_NORTH_1="eu-north-1";static SA_EAST_1="sa-east-1";static CN_NORTH_1="cn-north-1";static CN_NORTHWEST_1="cn-northwest-1";static ME_SOUTH_1="me-south-1";static US_GOV_EAST_1="us-gov-east-1";static US_GOV_WEST_1="us-gov-west-1";static ACL_PRIVATE="private";static ACL_PUBLIC_READ="public-read";static ACL_PUBLIC_READ_WRITE="public-read-write";static ACL_AUTHENTICATED_READ="authenticated-read";static MAX_PAGE_SIZE=1000;client;root;writerOptions;constructor(t){super();let{accessKeyId:e,secretAccessKey:r,bucket:i}=t;if(!e||!r||!i)throw new a("INVALID_CONFIG","S3 requires `accessKeyId`, `secretAccessKey` and `bucket`");this.root=t.root??"",this.writerOptions={partSize:t.partSize,queueSize:t.queueSize,retry:t.retry},this.client=new W({accessKeyId:e,secretAccessKey:r,bucket:i,region:t.region,acl:t.acl,endpoint:t.endpoint,sessionToken:t.sessionToken})}getName(){return"S3 Storage"}getType(){return d.DEVICE_S3}getDescription(){return"S3 Bucket Storage drive for AWS or on-premise solutions, powered by Bun's native S3 client"}getRoot(){return this.root}getPath(t,e){return this.root?`${this.root}/${t}`:t}key(t){return this.getPath(t)}async write(t,e,r=""){try{return await this.client.write(this.key(t),e,r?{type:r}:{}),!0}catch(i){throw new a("WRITE_FAILED",`Failed to write ${t}: ${h(i)}`,t)}}async read(t,e=0,r){let i=this.client.file(this.key(t)),s=r===void 0?e>0?i.slice(e):i:i.slice(e,e+r);try{return Buffer.from(await s.bytes())}catch(n){if(N(n))throw new a("FILE_NOT_FOUND",`File not found: ${t}`,t);throw new a("READ_FAILED",`Failed to read ${t}: ${h(n)}`,t)}}async upload(t,e,r=1,i=1,s={}){let n=Bun.file(t);if(!await n.exists())throw new a("FILE_NOT_FOUND",`Source file not found: ${t}`,t);let o=Buffer.from(await n.arrayBuffer()),c=typeof s.contentType==="string"&&s.contentType.length>0?s.contentType:v(n.type)||"application/octet-stream";return this.uploadData(o,e,c,r,i,s)}async uploadData(t,e,r,i=1,s=1,n={}){if(s<=1)return await this.write(e,t,r),1;let o=this.key(e),c=`${o}${b}${P(i)}`;await this.client.write(c,t,{type:r});let p=Number(n.receivedChunks??0)+1;if(n.receivedChunks=p,p<s)return p;try{let _=this.client.file(o,{type:r}).writer({...this.writerOptions});for(let S=1;S<=s;S++)_.write(await this.client.file(`${o}${b}${P(S)}`).bytes());await _.end()}catch(_){throw new a("UPLOAD_FAILED",`Failed to assemble chunks for ${e}: ${h(_)}`,e)}finally{await this.deleteStagedParts(o,s)}return p}async abort(t,e=""){return await this.deleteStagedPartsByPrefix(`${this.key(t)}${b}`),!0}async delete(t,e=!1){try{return await this.client.delete(this.key(t)),!0}catch(r){throw new a("DELETE_FAILED",`Failed to delete ${t}: ${h(r)}`,t)}}async deletePath(t){let e=`${this.key(t)}/`,r;do{let i=await this.client.list({prefix:e,maxKeys:g.MAX_PAGE_SIZE,continuationToken:r}),s=(i.contents??[]).map((n)=>n.key);await Promise.all(s.map((n)=>this.client.delete(n))),r=i.isTruncated?i.nextContinuationToken:void 0}while(r);return!0}async exists(t){return this.client.exists(this.key(t))}async stat(t){try{let e=await this.client.stat(this.key(t));return{size:e.size,mimeType:v(e.type),etag:e.etag?O(e.etag):void 0,lastModified:e.lastModified}}catch(e){if(N(e))throw new a("FILE_NOT_FOUND",`File not found: ${t}`,t);throw e}}async getFileSize(t){return(await this.stat(t)).size}async getFileMimeType(t){return(await this.stat(t)).mimeType}async getFileHash(t){return(await this.stat(t)).etag??""}presign(t,e={}){return this.client.presign(this.key(t),e)}async createDirectory(t){return!0}async getDirectorySize(t){let e=0,r;do{let i=await this.client.list({prefix:`${this.key(t)}/`,maxKeys:g.MAX_PAGE_SIZE,continuationToken:r});for(let s of i.contents??[])e+=s.size??0;r=i.isTruncated?i.nextContinuationToken:void 0}while(r);return e}async getPartitionFreeSpace(){return-1}async getPartitionTotalSpace(){return-1}async getFiles(t,e=g.MAX_PAGE_SIZE,r=""){return((await this.client.list({prefix:t?`${this.key(t)}/`:`${this.root}/`,maxKeys:Math.min(e,g.MAX_PAGE_SIZE),continuationToken:r||void 0})).contents??[]).map((s)=>({key:s.key,size:s.size,lastModified:s.lastModified?new Date(s.lastModified):void 0,etag:s.eTag?O(s.eTag):void 0}))}async deleteStagedParts(t,e){await Promise.all(Array.from({length:e},(r,i)=>this.client.delete(`${t}${b}${P(i+1)}`).catch(()=>{return})))}async deleteStagedPartsByPrefix(t){let e=await this.client.list({prefix:t,maxKeys:g.MAX_PAGE_SIZE});await Promise.all((e.contents??[]).map((r)=>this.client.delete(r.key).catch(()=>{return})))}}function h(t){return t instanceof Error?t.message:String(t)}function N(t){let e=h(t).toLowerCase();return e.includes("404")||e.includes("nosuchkey")}class L extends g{static US_WEST_1="us-west-1";static US_CENTRAL_1="us-central-1";static US_EAST_1="us-east-1";static US_EAST_2="us-east-2";static AP_NORTHEAST_1="ap-northeast-1";static AP_NORTHEAST_2="ap-northeast-2";static EU_CENTRAL_1="eu-central-1";static EU_CENTRAL_2="eu-central-2";static EU_WEST_1="eu-west-1";static EU_WEST_2="eu-west-2";constructor(t){let e=t.region??L.EU_CENTRAL_1;super({...t,region:e,endpoint:`https://s3.${e}.wasabisys.com`})}getName(){return"Wasabi Storage"}getDescription(){return"Wasabi hot cloud storage drive, powered by Bun's native S3 client"}getType(){return d.DEVICE_WASABI}}class Y extends g{constructor(t){let{endpoint:e="localhost:9000",useSSL:r=!1,...i}=t,s=e.replace(/^https?:\/\//,"");super({...i,region:i.region??g.US_EAST_1,endpoint:`${r?"https":"http"}://${s}`})}getName(){return"MinIO Storage"}getDescription(){return"MinIO S3-compatible object storage server, powered by Bun's native S3 client"}getType(){return d.DEVICE_MINIO}}export{y as Device,B as File,k as FileExt,C as FileName,U as FileSize,f as FileType,V as Local,Y as MinIO,g as S3,d as Storage,a as StorageError,M as Upload,L as Wasabi};
@@ -1,20 +1,28 @@
1
- import { Device } from "../device";
1
+ import { Device, DeviceMetadata, FileEntry, FileStat } from "../device.js";
2
+ /**
3
+ * Local filesystem storage device built on Bun's native file APIs
4
+ * (`Bun.file`, `Bun.write`). Directory operations use Bun's built-in
5
+ * Node-compatible `node:fs` module.
6
+ */
2
7
  export declare class Local extends Device {
3
8
  protected root: string;
4
- protected readonly MAX_PAGE_SIZE = 1000;
5
9
  constructor(root?: string);
6
10
  getName(): string;
7
11
  getType(): string;
8
12
  getDescription(): string;
9
13
  getRoot(): string;
10
- getPath(filename: string, prefix?: string): string;
11
- upload(source: string, filePath: string, chunk?: number, chunks?: number, metadata?: Record<string, any>): Promise<number>;
12
- uploadData(data: string | Buffer, filePath: string, contentType: string, chunk?: number, chunks?: number, metadata?: Record<string, any>): Promise<number>;
13
- private joinChunks;
14
- transfer(filePath: string, destination: string, device: Device): Promise<boolean>;
15
- abort(filePath: string, extra?: string): Promise<boolean>;
14
+ getPath(filename: string, _prefix?: string): string;
15
+ upload(source: string, filePath: string, chunk?: number, chunks?: number, _metadata?: DeviceMetadata): Promise<number>;
16
+ uploadData(data: string | Buffer, filePath: string, _contentType: string, chunk?: number, chunks?: number, _metadata?: DeviceMetadata): Promise<number>;
17
+ /**
18
+ * Abort a chunked upload: remove staged parts and any partial target.
19
+ */
20
+ abort(filePath: string, _extra?: string): Promise<boolean>;
16
21
  read(filePath: string, offset?: number, length?: number): Promise<Buffer>;
17
- write(filePath: string, data: string | Buffer, contentType?: string): Promise<boolean>;
22
+ write(filePath: string, data: string | Buffer, _contentType?: string): Promise<boolean>;
23
+ /**
24
+ * Move a file within the local device using an atomic rename.
25
+ */
18
26
  move(source: string, target: string): Promise<boolean>;
19
27
  delete(filePath: string, recursive?: boolean): Promise<boolean>;
20
28
  deletePath(filePath: string): Promise<boolean>;
@@ -22,10 +30,20 @@ export declare class Local extends Device {
22
30
  getFileSize(filePath: string): Promise<number>;
23
31
  getFileMimeType(filePath: string): Promise<string>;
24
32
  getFileHash(filePath: string): Promise<string>;
33
+ stat(filePath: string): Promise<FileStat>;
25
34
  createDirectory(dirPath: string): Promise<boolean>;
26
35
  getDirectorySize(dirPath: string): Promise<number>;
27
36
  getPartitionFreeSpace(): Promise<number>;
28
37
  getPartitionTotalSpace(): Promise<number>;
29
- getFiles(dir: string, max?: number, continuationToken?: string): Promise<string[]>;
38
+ getFiles(dir: string): Promise<FileEntry[]>;
39
+ /**
40
+ * Concatenate staged parts into the final file and clean up.
41
+ */
42
+ private joinChunks;
43
+ /**
44
+ * Count staged part files for a target path.
45
+ */
46
+ private listParts;
47
+ private rename;
30
48
  }
31
49
  //# sourceMappingURL=local.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/device/local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAMnC,qBAAa,KAAM,SAAQ,MAAM;IAC/B,SAAS,CAAC,IAAI,EAAE,MAAM,CAAU;IAChC,SAAS,CAAC,QAAQ,CAAC,aAAa,QAAQ;gBAE5B,IAAI,GAAE,MAAW;IAK7B,OAAO,IAAI,MAAM;IAIjB,OAAO,IAAI,MAAM;IAIjB,cAAc,IAAI,MAAM;IAIxB,OAAO,IAAI,MAAM;IAIjB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IAI5C,MAAM,CACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE,MAAU,EACjB,MAAM,GAAE,MAAU,EAClB,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GACjC,OAAO,CAAC,MAAM,CAAC;IAiDZ,UAAU,CACd,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,MAAU,EACjB,MAAM,GAAE,MAAU,EAClB,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GACjC,OAAO,CAAC,MAAM,CAAC;YAyCJ,UAAU;IA0BlB,QAAQ,CACZ,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC;IAgCb,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAyB7D,IAAI,CACR,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAU,EAClB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC;IAgBZ,KAAK,CACT,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,WAAW,GAAE,MAAW,GACvB,OAAO,CAAC,OAAO,CAAC;IAUb,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IActD,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,GAAE,OAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAoBtE,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA+B9C,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS1C,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK9C,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlD,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK9C,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASlD,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBlD,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAKxC,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;IAKzC,QAAQ,CACZ,GAAG,EAAE,MAAM,EACX,GAAG,GAAE,MAA2B,EAChC,iBAAiB,GAAE,MAAW,GAC7B,OAAO,CAAC,MAAM,EAAE,CAAC;CAQrB"}
1
+ {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/device/local.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAM3E;;;;GAIG;AACH,qBAAa,KAAM,SAAQ,MAAM;IAC/B,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEX,IAAI,SAAK;IAKrB,OAAO,IAAI,MAAM;IAIjB,OAAO,IAAI,MAAM;IAIjB,cAAc,IAAI,MAAM;IAIxB,OAAO,IAAI,MAAM;IAIjB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;IAI7C,MAAM,CACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,KAAK,SAAI,EACT,MAAM,SAAI,EACV,SAAS,GAAE,cAAmB,GAC7B,OAAO,CAAC,MAAM,CAAC;IA8BZ,UAAU,CACd,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,KAAK,SAAI,EACT,MAAM,SAAI,EACV,SAAS,GAAE,cAAmB,GAC7B,OAAO,CAAC,MAAM,CAAC;IAuBlB;;OAEG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IAetD,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAapE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,YAAY,SAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IAUzF;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAatD,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAkB7D,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ9C,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1C,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ9C,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKlD,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAM9C,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAWzC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASlD,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBlD,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAKxC,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;IAKzC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAYjD;;OAEG;YACW,UAAU;IAaxB;;OAEG;YACW,SAAS;YAYT,MAAM;CAGrB"}
@@ -1,16 +1,22 @@
1
- import { S3 } from "./s3";
1
+ import { S3, S3Options } from "./s3.js";
2
+ /**
3
+ * MinIO-specific options.
4
+ */
5
+ export interface MinIOOptions extends Omit<S3Options, "endpoint"> {
6
+ /** MinIO server host, e.g. `localhost:9000`. Protocol prefixes are stripped. */
7
+ endpoint?: string;
8
+ /** Use HTTPS instead of HTTP. Default: false. */
9
+ useSSL?: boolean;
10
+ }
11
+ /**
12
+ * MinIO object storage — an S3-compatible device pointing at a self-hosted
13
+ * MinIO server. Bun's S3Client uses path-style URLs for custom endpoints,
14
+ * which is exactly what MinIO expects.
15
+ */
2
16
  export declare class MinIO extends S3 {
3
- /**
4
- * MinIO Constructor
5
- */
6
- constructor(root: string, accessKey: string, secretKey: string, bucket: string, endpoint?: string, acl?: string, useSSL?: boolean);
7
- private endpointUrl;
17
+ constructor(options: MinIOOptions);
8
18
  getName(): string;
9
19
  getDescription(): string;
10
20
  getType(): string;
11
- /**
12
- * Override the call method to use the custom endpoint
13
- */
14
- protected call(method: string, uri: string, data?: string | Buffer, parameters?: Record<string, string>, decode?: boolean): Promise<any>;
15
21
  }
16
22
  //# sourceMappingURL=minio.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"minio.d.ts","sourceRoot":"","sources":["../../../src/device/minio.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAE1B,qBAAa,KAAM,SAAQ,EAAE;IAC3B;;OAEG;gBAED,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAyB,EACnC,GAAG,GAAE,MAAuB,EAC5B,MAAM,GAAE,OAAe;IAezB,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,IAAI,MAAM;IAIjB,cAAc,IAAI,MAAM;IAIxB,OAAO,IAAI,MAAM;IAIjB;;OAEG;cACa,IAAI,CAClB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,MAAM,GAAG,MAAW,EAC1B,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACvC,MAAM,GAAE,OAAc,GACrB,OAAO,CAAC,GAAG,CAAC;CA6FhB"}
1
+ {"version":3,"file":"minio.d.ts","sourceRoot":"","sources":["../../../src/device/minio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGxC;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/D,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,qBAAa,KAAM,SAAQ,EAAE;gBACf,OAAO,EAAE,YAAY;IAWjC,OAAO,IAAI,MAAM;IAIjB,cAAc,IAAI,MAAM;IAIxB,OAAO,IAAI,MAAM;CAGlB"}