@data-loom/storage-js 0.4.4-alpha.11 → 0.4.4-alpha.12

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/README.md CHANGED
@@ -7,7 +7,7 @@ Dataloom 存储服务 JavaScript SDK,基于 Supabase Storage 修改而来,
7
7
  - 📁 **文件上传和下载** - 支持多种文件格式的上传和下载
8
8
  - 🔗 **签名URL** - 创建具有时效性的安全文件访问链接
9
9
  - 🗑️ **文件管理** - 删除、列表等文件操作
10
- - 🌐 **URL上传** - 从公共URL下载文件并上传到存储桶
10
+ - 🖼️ **图片转换** - 支持图片尺寸调整、质量优化等转换功能
11
11
  - 📊 **批量操作** - 支持批量创建签名URL等批量操作
12
12
  - 🔍 **文件搜索** - 支持文件搜索和分页
13
13
  - 🛡️ **错误处理** - 完善的错误处理机制
@@ -77,179 +77,69 @@ constructor(
77
77
  )
78
78
  ```
79
79
 
80
- ---
81
-
82
80
  ### 文件上传
83
81
 
84
- #### `upload(path, fileBody, fileOptions?)` - 重载1
85
-
86
- 上传文件到指定的存储桶路径。
87
-
88
- **入参:**
89
- ```typescript
90
- function upload(
91
- path: string, // 文件路径,格式为 `folder/subfolder/filename.png`
92
- fileBody: FileBody, // 文件内容
93
- fileOptions?: FileOptions // 上传选项
94
- ): Promise<UploadResult>
95
- ```
96
-
97
- **出参:**
98
- ```typescript
99
- type UploadResult =
100
- | { data: UploadFileData; error: null }
101
- | { data: null; error: StorageError }
102
- ```
103
-
104
- **示例:**
105
- ```javascript
106
- const { data, error } = await storage.upload('avatars/user-123.jpg', file, {
107
- cacheControl: 3600,
108
- contentType: 'image/jpeg',
109
- upsert: false
110
- });
111
- ```
112
-
113
- ---
82
+ #### `uploadFile(fileBody, fileOptions?)` **(推荐)**
114
83
 
115
- #### `upload(fileBody, fileOptions?)` - 重载2
84
+ 使用文件选项上传文件(推荐, 无需关注filePath)。
116
85
 
117
- 使用 FileOptionsV2 上传文件,路径通过 options.filePath 指定。
86
+ **参数:**
87
+ - `fileBody` (FileBody): 文件内容
88
+ - `fileOptions` (FileOptionsV2, 可选): 文件选项,可指定 filePath 等
118
89
 
119
- **入参:**
120
- ```typescript
121
- function upload(
122
- fileBody: FileBody, // 文件内容
123
- fileOptions?: FileOptionsV2 // 上传选项(包含 filePath)
124
- ): Promise<UploadResult>
125
- ```
126
-
127
- **出参:**
128
- ```typescript
129
- type UploadResult =
130
- | { data: UploadFileData; error: null }
131
- | { data: null; error: StorageError }
132
- ```
90
+ **返回:** 同 `upload` 方法
133
91
 
134
92
  **示例:**
135
93
  ```javascript
136
- const { data, error } = await storage.upload(file, {
94
+ const { data, error } = await storage.uploadFile(file, {
137
95
  filePath: 'documents/report.pdf',
96
+ cacheControl: 3600,
138
97
  contentType: 'application/pdf',
139
98
  contentDisposition: 'attachment; filename="report.pdf"'
140
99
  });
141
100
  ```
142
101
 
143
- ---
102
+ #### `upload(path, fileBody, fileOptions?)`
144
103
 
145
- #### `uploadFile(fileBody, fileOptions?)`
104
+ 上传文件到指定的存储桶路径。
146
105
 
147
- 使用文件选项上传文件(推荐,与 upload 重载2 功能相同)。
106
+ **参数:**
107
+ - `path` (string): 文件路径,格式为 `folder/subfolder/filename.png`
108
+ - `fileBody` (FileBody): 文件内容,支持多种格式
109
+ - `fileOptions` (FileOptions, 可选): 文件选项
148
110
 
149
- **入参:**
111
+ **返回:**
150
112
  ```typescript
151
- function uploadFile(
152
- fileBody: FileBody, // 文件内容
153
- fileOptions?: FileOptionsV2 // 上传选项
154
- ): Promise<UploadResult>
155
- ```
156
-
157
- **出参:**
158
- ```typescript
159
- type UploadResult =
160
- | { data: UploadFileData; error: null }
161
- | { data: null; error: StorageError }
113
+ {
114
+ data: UploadFileData; // 包含文件ID、路径、存储桶ID和下载URL
115
+ error: null;
116
+ } | {
117
+ data: null;
118
+ error: StorageError;
119
+ }
162
120
  ```
163
121
 
164
122
  **示例:**
165
123
  ```javascript
166
- const { data, error } = await storage.uploadFile(file, {
167
- filePath: 'documents/report.pdf',
168
- cacheControl: 3600,
169
- contentType: 'application/pdf',
170
- contentDisposition: 'attachment; filename="report.pdf"'
124
+ const fileInput = document.getElementById('fileInput');
125
+ const file = fileInput.files[0];
126
+
127
+ const { data, error } = await storage.upload('avatars/user-123.jpg', file, {
128
+ cacheControl: '3600',
129
+ contentType: 'image/jpeg',
130
+ upsert: false
171
131
  });
172
132
  ```
173
133
 
174
- ---
175
-
176
134
  ### 文件更新
177
135
 
178
136
  #### `update(path, fileBody, fileOptions?)`
179
137
 
180
138
  替换指定路径的现有文件。
181
139
 
182
- **入参:**
183
- ```typescript
184
- function update(
185
- path: string, // 文件路径
186
- fileBody: FileBody, // 文件内容
187
- fileOptions?: FileOptions // 上传选项
188
- ): Promise<UploadResult>
189
- ```
190
-
191
- **出参:**
192
- ```typescript
193
- type UploadResult =
194
- | { data: UploadFileData; error: null }
195
- | { data: null; error: StorageError }
196
- ```
197
-
198
- ---
199
-
200
- ### 从URL上传文件
140
+ **参数:** 同 `upload` 方法
201
141
 
202
- #### `uploadFromUrl(url)`
203
-
204
- 从公共URL上传文件到存储桶。自动透传响应头(content-type、content-disposition、cache-control)到上传请求。对于火山引擎北京区域的 TOS URL,会使用服务端复制优化性能。
205
-
206
- **入参:**
207
- ```typescript
208
- function uploadFromUrl(
209
- url: string // 公共文件URL(如 CDN 链接)
210
- ): Promise<UploadFromUrlResult>
211
- ```
212
-
213
- **出参:**
214
- ```typescript
215
- type UploadFromUrlResult =
216
- | { data: UploadFileData; error: null }
217
- | { data: null; error: StorageError }
218
- ```
219
-
220
- **功能特性:**
221
- - ✅ 只允许 `http://` 和 `https://` 协议
222
- - ✅ 自动透传响应头到上传请求(contentType、contentDisposition、cacheControl)
223
- - ✅ 检测并拒绝空文件
224
- - ✅ 火山引擎北京区域 TOS URL 使用服务端复制优化
225
-
226
- **示例:**
227
- ```javascript
228
- // 基本用法
229
- const { data, error } = await storage.uploadFromUrl(
230
- 'https://cdn.example.com/images/photo.jpg'
231
- );
232
-
233
- if (data) {
234
- console.log('文件上传成功:', data.download_url);
235
- }
236
- ```
237
-
238
- **错误处理:**
239
- ```javascript
240
- const { data, error } = await storage.uploadFromUrl('https://example.com/file.pdf');
241
-
242
- if (error) {
243
- // 可能的错误类型:
244
- // - 'Invalid URL provided' - URL格式无效
245
- // - 'Only http and https protocols are supported' - 协议不支持
246
- // - 'Failed to download file from URL: 404 Not Found' - 下载失败
247
- // - 'Downloaded file is empty' - 下载的文件为空
248
- console.error(error.message);
249
- }
250
- ```
251
-
252
- ---
142
+ **返回:** `upload` 方法
253
143
 
254
144
  ### 创建签名URL
255
145
 
@@ -257,23 +147,22 @@ if (error) {
257
147
 
258
148
  创建具有时效性的安全文件访问链接。
259
149
 
260
- **入参:**
261
- ```typescript
262
- function createSignedUrl(
263
- path: string, // 文件路径或 download_url
264
- expiresIn: number, // 过期时间(秒)
265
- options?: {
266
- download?: string | boolean; // 是否触发下载
267
- transform?: TransformOptions; // 图片转换选项
268
- }
269
- ): Promise<SignedUrlResult>
270
- ```
271
-
272
- **出参:**
273
- ```typescript
274
- type SignedUrlResult =
275
- | { data: { signedUrl: string }; error: null }
276
- | { data: null; error: StorageError }
150
+ **参数:**
151
+ - `path` (string): 文件路径或上传接口返回的download_url
152
+ - `expiresIn` (number): 过期时间(秒)
153
+ - `options` (object, 可选): 选项
154
+ - `download` (string | boolean): 是否触发下载,可指定文件名
155
+ - `transform` (TransformOptions): 图片转换选项
156
+
157
+ **返回:**
158
+ ```typescript
159
+ {
160
+ data: { signedUrl: string };
161
+ error: null;
162
+ } | {
163
+ data: null;
164
+ error: StorageError;
165
+ }
277
166
  ```
278
167
 
279
168
  **示例:**
@@ -292,99 +181,80 @@ const { data, error } = await storage.createSignedUrl('images/photo.jpg', 3600,
292
181
  });
293
182
  ```
294
183
 
295
- ---
296
-
297
184
  #### `createSignedUrls(paths, expiresIn, options?)`
298
185
 
299
186
  批量创建签名URL。
300
187
 
301
- **入参:**
302
- ```typescript
303
- function createSignedUrls(
304
- paths: string[], // 文件路径或 download_url 数组
305
- expiresIn: number, // 过期时间(秒)
306
- options?: {
307
- download?: string | boolean;
308
- }
309
- ): Promise<SignedUrlsResult>
310
- ```
311
-
312
- **出参:**
313
- ```typescript
314
- type SignedUrlsResult =
315
- | {
316
- data: Array<{
317
- error: string | null;
318
- path: string | null;
319
- signedUrl: string;
320
- }>;
321
- error: null
322
- }
323
- | { data: null; error: StorageError }
324
- ```
325
-
326
- **示例:**
327
- ```javascript
328
- const { data, error } = await storage.createSignedUrls(
329
- ['file1.pdf', 'file2.pdf', 'file3.pdf'],
330
- 3600
331
- );
188
+ **参数:**
189
+ - `paths` (string[]): 文件路径或上传接口返回的download_url数组
190
+ - `expiresIn` (number): 过期时间(秒)
191
+ - `options` (object, 可选): 选项
192
+
193
+ **返回:**
194
+ ```typescript
195
+ {
196
+ data: Array<{
197
+ error: string | null;
198
+ path: string | null;
199
+ signedUrl: string;
200
+ }>;
201
+ error: null;
202
+ } | {
203
+ data: null;
204
+ error: StorageError;
205
+ }
332
206
  ```
333
207
 
334
- ---
335
-
336
208
  ### 文件下载
337
209
 
338
210
  #### `download(path, options?)`
339
211
 
340
212
  从私有存储桶下载文件。
341
213
 
342
- **入参:**
343
- ```typescript
344
- function download(
345
- path: string, // 文件路径
346
- options?: {
347
- transform?: TransformOptions; // 图片转换选项
348
- }
349
- ): Promise<DownloadResult>
350
- ```
214
+ **参数:**
215
+ - `path` (string): 文件路径
216
+ - `options` (object, 可选): 选项
217
+ - `transform` (TransformOptions): 图片转换选项
351
218
 
352
- **出参:**
219
+ **返回:**
353
220
  ```typescript
354
- type DownloadResult =
355
- | { data: Blob; error: null }
356
- | { data: null; error: StorageError }
221
+ {
222
+ data: Blob;
223
+ error: null;
224
+ } | {
225
+ data: null;
226
+ error: StorageError;
227
+ }
357
228
  ```
358
229
 
359
230
  **示例:**
360
231
  ```javascript
361
232
  const { data, error } = await storage.download('documents/report.pdf');
362
233
  if (data) {
234
+ // 处理下载的文件数据
363
235
  const url = URL.createObjectURL(data);
364
236
  window.open(url);
365
237
  }
366
238
  ```
367
239
 
368
- ---
369
-
370
240
  ### 文件删除
371
241
 
372
242
  #### `remove(paths)`
373
243
 
374
244
  删除指定路径的文件。
375
245
 
376
- **入参:**
377
- ```typescript
378
- function remove(
379
- paths: string[] // 文件路径或 download_url 数组
380
- ): Promise<RemoveResult>
381
- ```
246
+ **参数:**
247
+ - `paths` (string[]): 要删除的文件路径或上传接口返回的download_url数组
382
248
 
383
- **出参:**
249
+ **返回:**
384
250
  ```typescript
385
- type RemoveResult =
386
- | { data: FileObject[]; error: null }
387
- | { data: null; error: StorageError }
251
+ {
252
+ data: FileObject[]; // 被删除的文件信息
253
+ error: null;
254
+ } | {
255
+ data: null;
256
+ error: StorageError;
257
+ }
388
258
  ```
389
259
 
390
260
  **示例:**
@@ -395,28 +265,26 @@ const { data, error } = await storage.remove([
395
265
  ]);
396
266
  ```
397
267
 
398
- ---
399
-
400
268
  ### 文件列表
401
269
 
402
270
  #### `list(path?, options?, parameters?)`
403
271
 
404
272
  列出存储桶中的文件。
405
273
 
406
- **入参:**
407
- ```typescript
408
- function list(
409
- path?: string, // 文件夹路径
410
- options?: SearchOptions, // 搜索选项
411
- parameters?: FetchParameters // 请求参数
412
- ): Promise<ListResult>
413
- ```
274
+ **参数:**
275
+ - `path` (string, 可选): 文件夹路径
276
+ - `options` (SearchOptions, 可选): 搜索选项
277
+ - `parameters` (FetchParameters, 可选): 请求参数
414
278
 
415
- **出参:**
279
+ **返回:**
416
280
  ```typescript
417
- type ListResult =
418
- | { data: FileObject[]; error: null }
419
- | { data: null; error: StorageError }
281
+ {
282
+ data: FileObject[]; // 文件列表
283
+ error: null;
284
+ } | {
285
+ data: null;
286
+ error: StorageError;
287
+ }
420
288
  ```
421
289
 
422
290
  **示例:**
@@ -436,208 +304,99 @@ const { data, error } = await storage.list('documents', {
436
304
  });
437
305
  ```
438
306
 
439
- ---
440
-
441
307
  ## 类型定义
442
308
 
443
309
  ### FileBody
444
-
445
310
  支持以下文件格式:
446
-
447
- ```typescript
448
- type FileBody =
449
- | ArrayBuffer
450
- | ArrayBufferView
451
- | Blob
452
- | Buffer
453
- | File
454
- | FormData
455
- | NodeJS.ReadableStream
456
- | ReadableStream<Uint8Array>
457
- | URLSearchParams
458
- | string;
459
- ```
311
+ - `ArrayBuffer`
312
+ - `ArrayBufferView`
313
+ - `Blob`
314
+ - `Buffer`
315
+ - `File`
316
+ - `FormData`
317
+ - `NodeJS.ReadableStream`
318
+ - `ReadableStream<Uint8Array>`
319
+ - `URLSearchParams`
320
+ - `string`
460
321
 
461
322
  ### FileOptions
462
-
463
323
  ```typescript
464
324
  interface FileOptions {
465
- /** 缓存控制时间(秒),设置 Cache-Control: max-age=<seconds> 头 */
466
- cacheControl?: string | number;
467
- /** Content-Type 头值 */
468
- contentType?: string;
469
- /** 是否覆盖已存在文件,默认 false */
470
- upsert?: boolean;
471
- /** 双工流选项 */
472
- duplex?: string;
473
- /** 文件元数据 */
474
- metadata?: Record<string, any>;
475
- /** 额外请求头 */
476
- headers?: Record<string, string>;
325
+ cacheControl?: string | number; // 缓存控制(秒)
326
+ contentType?: string; // 内容类型
327
+ upsert?: boolean; // 是否覆盖已存在文件
328
+ duplex?: string; // 双工流选项
329
+ metadata?: Record<string, any>; // 元数据
330
+ headers?: Record<string, string>; // 额外请求头
477
331
  }
478
332
  ```
479
333
 
480
334
  ### FileOptionsV2
481
-
482
335
  ```typescript
483
336
  interface FileOptionsV2 {
484
- /** 文件上传路径 */
485
- filePath?: string;
486
- /** 缓存控制时间(秒) */
487
- cacheControl?: string | number;
488
- /** Content-Type 头值 */
489
- contentType?: string;
490
- /** 是否覆盖已存在文件,默认 false */
491
- upsert?: boolean;
492
- /** Content-Disposition 响应头值 */
493
- contentDisposition?: string;
337
+ filePath?: string; // 文件路径(用于 uploadFile)
338
+ cacheControl?: string | number; // 缓存控制(秒)
339
+ contentType?: string; // 内容类型
340
+ upsert?: boolean; // 是否覆盖已存在文件
341
+ contentDisposition?: string; // 内容处置
494
342
  }
495
343
  ```
496
344
 
497
- ### UploadFileData
498
-
345
+ ### TransformOptions
499
346
  ```typescript
500
- interface UploadFileData {
501
- /** 文件ID */
502
- id: string;
503
- /** 文件路径 */
504
- file_path: string;
505
- /** 存储桶ID */
506
- bucket_id: string;
507
- /** 下载URL */
508
- download_url: string;
347
+ interface TransformOptions {
348
+ width?: number; // 宽度(像素)
349
+ height?: number; // 高度(像素)
350
+ resize?: 'cover' | 'contain' | 'fill'; // 调整大小模式
351
+ quality?: number; // 质量(20-100)
352
+ format?: 'origin'; // 格式
509
353
  }
510
354
  ```
511
355
 
512
- ### FileObject
513
-
356
+ ### UploadFileData
514
357
  ```typescript
515
- interface FileObject {
516
- /** 文件名 */
517
- name: string;
518
- /** 存储桶ID */
519
- bucket_id: string;
520
- /** 所有者 */
521
- owner: string;
522
- /** 文件ID */
523
- id: string;
524
- /** 更新时间 */
525
- updated_at: string;
526
- /** 创建时间 */
527
- created_at: string;
528
- /** 创建者 */
529
- created_by: string;
530
- /** 更新者 */
531
- updated_by: string;
532
- /** 最后访问时间 */
533
- last_accessed_at?: string;
534
- /** 元数据 */
535
- metadata: Record<string, any>;
536
- /** 存储桶信息 */
537
- buckets: Bucket;
358
+ interface UploadFileData {
359
+ id: string; // 文件ID
360
+ file_path: string; // 文件路径
361
+ bucket_id: string; // 存储桶ID
362
+ download_url: string; // 下载URL
538
363
  }
539
364
  ```
540
365
 
541
- ### Bucket
542
-
366
+ ### FileObject
543
367
  ```typescript
544
- interface Bucket {
545
- /** 存储桶ID */
546
- id: string;
547
- /** 存储桶类型 */
548
- type?: 'STANDARD' | 'ANALYTICS';
549
- /** 存储桶名称 */
550
- name: string;
551
- /** 所有者 */
552
- owner: string;
553
- /** 文件大小限制 */
554
- file_size_limit?: number;
555
- /** 允许的MIME类型 */
556
- allowed_mime_types?: string[];
557
- /** 创建时间 */
558
- created_at: string;
559
- /** 更新时间 */
560
- updated_at: string;
561
- /** 是否公开 */
562
- public: boolean;
368
+ interface FileObject {
369
+ name: string; // 文件名
370
+ bucket_id: string; // 存储桶ID
371
+ owner: string; // 所有者
372
+ id: string; // 文件ID
373
+ updated_at: string; // 更新时间
374
+ created_at: string; // 创建时间
375
+ created_by: string; // 创建者
376
+ updated_by: string; // 更新者
377
+ last_accessed_at?: string; // 最后访问时间
378
+ metadata: Record<string, any>; // 元数据
379
+ buckets: Bucket; // 存储桶信息
563
380
  }
564
381
  ```
565
382
 
566
383
  ### SearchOptions
567
-
568
384
  ```typescript
569
385
  interface SearchOptions {
570
- /** 返回文件数量,默认 100 */
571
- limit?: number;
572
- /** 起始位置 */
573
- offset?: number;
574
- /** 排序选项 */
575
- sortBy?: SortBy;
576
- /** 搜索字符串 */
577
- search?: string;
578
- }
579
- ```
580
-
581
- ### SortBy
582
-
583
- ```typescript
584
- interface SortBy {
585
- /** 排序列名 */
586
- column?: string;
587
- /** 排序顺序:'asc' | 'desc' */
588
- order?: string;
589
- }
590
- ```
591
-
592
- ### TransformOptions
593
-
594
- ```typescript
595
- interface TransformOptions {
596
- /** 宽度(像素) */
597
- width?: number;
598
- /** 高度(像素) */
599
- height?: number;
600
- /** 调整大小模式 */
601
- resize?: 'cover' | 'contain' | 'fill';
602
- /** 质量(20-100) */
603
- quality?: number;
604
- /** 格式 */
605
- format?: 'origin';
386
+ limit?: number; // 返回文件数量(默认100
387
+ offset?: number; // 起始位置
388
+ sortBy?: SortBy; // 排序选项
389
+ search?: string; // 搜索字符串
606
390
  }
607
391
  ```
608
392
 
609
393
  ### FetchParameters
610
-
611
394
  ```typescript
612
395
  interface FetchParameters {
613
- /** AbortController 信号,用于取消请求 */
614
- signal?: AbortSignal;
615
- }
616
- ```
617
-
618
- ### StorageError
619
-
620
- ```typescript
621
- class StorageError extends Error {
622
- message: string;
396
+ signal?: AbortSignal; // AbortController 信号
623
397
  }
624
398
  ```
625
399
 
626
- ### OnRequestErrorType
627
-
628
- ```typescript
629
- interface OnRequestErrorType {
630
- code: number;
631
- details: string;
632
- hint: string | null;
633
- message: string;
634
- status: number;
635
- statusText: string;
636
- }
637
- ```
638
-
639
- ---
640
-
641
400
  ## 错误处理
642
401
 
643
402
  所有API方法都返回包含 `data` 和 `error` 的对象。当操作成功时,`error` 为 `null`,`data` 包含返回数据;当操作失败时,`data` 为 `null`,`error` 包含错误信息。
@@ -647,13 +406,13 @@ const { data, error } = await storage.upload('test.jpg', file);
647
406
 
648
407
  if (error) {
649
408
  console.error('操作失败:', error.message);
409
+ // 错误处理
650
410
  } else {
651
411
  console.log('操作成功:', data);
412
+ // 处理返回数据
652
413
  }
653
414
  ```
654
415
 
655
- ---
656
-
657
416
  ## 高级用法
658
417
 
659
418
  ### 日志记录
@@ -685,6 +444,7 @@ const storage = new StorageFileApi(
685
444
  false,
686
445
  (error) => {
687
446
  console.error('请求错误:', error);
447
+ // 自定义错误处理
688
448
  }
689
449
  );
690
450
  ```
@@ -708,8 +468,6 @@ const storage = new StorageFileApi(
708
468
  );
709
469
  ```
710
470
 
711
- ---
712
-
713
471
  ## 许可证
714
472
 
715
473
  MIT License