@h-ai/storage 0.1.0-alpha8 → 1.0.0-beta.1
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.en.md +287 -0
- package/README.ja.md +287 -0
- package/README.md +235 -59
- package/dist/browser.d.ts +490 -102
- package/dist/browser.js +3 -2
- package/dist/chunk-KVFEQHRX.js +360 -0
- package/dist/chunk-KVFEQHRX.js.map +1 -0
- package/dist/{chunk-KHZOR6CR.js → chunk-P4NA6BCH.js} +37 -12
- package/dist/chunk-P4NA6BCH.js.map +1 -0
- package/dist/chunk-P65WYXJG.js +33 -0
- package/dist/chunk-P65WYXJG.js.map +1 -0
- package/dist/client/index.d.ts +57 -48
- package/dist/client/index.js +1 -1
- package/dist/node.d.ts +15 -11
- package/dist/node.js +582 -178
- package/dist/node.js.map +1 -1
- package/dist/schemas.d.ts +103 -0
- package/dist/schemas.js +3 -0
- package/dist/schemas.js.map +1 -0
- package/package.json +22 -16
- package/dist/api/index.d.ts +0 -167
- package/dist/api/index.js +0 -105
- package/dist/api/index.js.map +0 -1
- package/dist/chunk-KHZOR6CR.js.map +0 -1
- package/dist/chunk-U427BQIQ.js +0 -266
- package/dist/chunk-U427BQIQ.js.map +0 -1
package/dist/browser.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export { ClientDownloadOptions, ClientUploadOptions, UploadProgress, downloadAndSave, downloadWithPresignedUrl, formatFileSize, getFileExtension, getMimeType, uploadWithPresignedUrl } from './client/index.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
+
export { STORAGE_DELETE_MAX_KEYS, STORAGE_KEY_MAX_BYTES, StorageDeleteKeysSchema, StorageKeyIssue, StorageKeySchema, StoragePrefixSchema, StoragePresignExpiresInSchema, getStorageKeyIssue } from './schemas.js';
|
|
3
4
|
import * as _h_ai_core from '@h-ai/core';
|
|
4
|
-
import { HaiResult } from '@h-ai/core';
|
|
5
|
+
import { HaiResult, HaiError } from '@h-ai/core';
|
|
5
6
|
import { Buffer } from 'node:buffer';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
* @h-ai/storage —
|
|
9
|
+
* @h-ai/storage — 存储配置 Schema
|
|
9
10
|
* @module storage-config
|
|
10
11
|
*/
|
|
11
12
|
|
|
@@ -13,112 +14,230 @@ import { Buffer } from 'node:buffer';
|
|
|
13
14
|
* 存储类型枚举
|
|
14
15
|
*
|
|
15
16
|
* 支持的存储类型:
|
|
16
|
-
* - `s3` - S3 协议对象存储(兼容 AWS S3、MinIO、阿里云 OSS 等)
|
|
17
|
+
* - `s3` - S3 协议对象存储(兼容 AWS S3、MinIO、RustFS、阿里云 OSS 等)
|
|
17
18
|
* - `local` - 本地文件存储(仅后端)
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { StorageTypeSchema } from '@h-ai/storage'
|
|
22
|
+
*
|
|
23
|
+
* const value = StorageTypeSchema.parse('local')
|
|
24
|
+
* void value
|
|
25
|
+
* ```
|
|
18
26
|
*/
|
|
19
27
|
declare const StorageTypeSchema: z.ZodEnum<{
|
|
20
28
|
s3: "s3";
|
|
21
29
|
local: "local";
|
|
22
30
|
}>;
|
|
23
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* 存储类型
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* import type { StorageType } from '@h-ai/storage'
|
|
36
|
+
*
|
|
37
|
+
* const value: StorageType = 's3'
|
|
38
|
+
* void value
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
24
41
|
type StorageType = z.infer<typeof StorageTypeSchema>;
|
|
42
|
+
/**
|
|
43
|
+
* StorageOperationLogConfigSchema 的数据约束与操作契约。
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* import { StorageOperationLogConfigSchema } from '@h-ai/storage'
|
|
47
|
+
*
|
|
48
|
+
* const value = StorageOperationLogConfigSchema.parse({ read: false, write: true, maxLength: 500, level: 'debug' })
|
|
49
|
+
* void value
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
declare const StorageOperationLogConfigSchema: z.ZodObject<{
|
|
53
|
+
read: z.ZodDefault<z.ZodBoolean>;
|
|
54
|
+
write: z.ZodDefault<z.ZodBoolean>;
|
|
55
|
+
maxLength: z.ZodDefault<z.ZodNumber>;
|
|
56
|
+
level: z.ZodDefault<z.ZodEnum<{
|
|
57
|
+
info: "info";
|
|
58
|
+
debug: "debug";
|
|
59
|
+
trace: "trace";
|
|
60
|
+
}>>;
|
|
61
|
+
}, z.core.$strip>;
|
|
62
|
+
/**
|
|
63
|
+
* StorageOperationLogConfig 的数据约束与操作契约。
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* import { StorageOperationLogConfigSchema, type StorageOperationLogConfig } from '@h-ai/storage'
|
|
67
|
+
*
|
|
68
|
+
* const value: StorageOperationLogConfig = StorageOperationLogConfigSchema.parse({ read: false, write: true, maxLength: 500, level: 'debug' })
|
|
69
|
+
* void value
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
type StorageOperationLogConfig = z.infer<typeof StorageOperationLogConfigSchema>;
|
|
25
73
|
/**
|
|
26
74
|
* S3 存储配置 Schema
|
|
27
75
|
*
|
|
28
|
-
* 支持标准 AWS S3 以及兼容 S3 协议的存储服务(MinIO、阿里云 OSS 等)。
|
|
76
|
+
* 支持标准 AWS S3 以及兼容 S3 协议的存储服务(MinIO、RustFS、阿里云 OSS 等)。
|
|
29
77
|
* 必填字段:bucket、region、accessKeyId、secretAccessKey。
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* import { S3ConfigSchema } from '@h-ai/storage'
|
|
81
|
+
*
|
|
82
|
+
* const value = S3ConfigSchema.parse({ type: 's3', bucket: 'uploads', region: 'us-east-1', accessKeyId: process.env.HAI_STORAGE_ACCESS_KEY_ID, secretAccessKey: process.env.HAI_STORAGE_SECRET_ACCESS_KEY })
|
|
83
|
+
* void value
|
|
84
|
+
* ```
|
|
30
85
|
*/
|
|
31
86
|
declare const S3ConfigSchema: z.ZodObject<{
|
|
87
|
+
operationLog: z.ZodOptional<z.ZodObject<{
|
|
88
|
+
read: z.ZodDefault<z.ZodBoolean>;
|
|
89
|
+
write: z.ZodDefault<z.ZodBoolean>;
|
|
90
|
+
maxLength: z.ZodDefault<z.ZodNumber>;
|
|
91
|
+
level: z.ZodDefault<z.ZodEnum<{
|
|
92
|
+
info: "info";
|
|
93
|
+
debug: "debug";
|
|
94
|
+
trace: "trace";
|
|
95
|
+
}>>;
|
|
96
|
+
}, z.core.$strip>>;
|
|
32
97
|
type: z.ZodLiteral<"s3">;
|
|
33
98
|
bucket: z.ZodString;
|
|
99
|
+
createBucket: z.ZodDefault<z.ZodBoolean>;
|
|
34
100
|
region: z.ZodString;
|
|
35
101
|
accessKeyId: z.ZodString;
|
|
36
102
|
secretAccessKey: z.ZodString;
|
|
37
103
|
endpoint: z.ZodOptional<z.ZodString>;
|
|
104
|
+
publicEndpoint: z.ZodOptional<z.ZodString>;
|
|
38
105
|
forcePathStyle: z.ZodDefault<z.ZodBoolean>;
|
|
39
106
|
prefix: z.ZodDefault<z.ZodString>;
|
|
40
107
|
publicUrl: z.ZodOptional<z.ZodString>;
|
|
41
108
|
}, z.core.$strip>;
|
|
42
|
-
/**
|
|
109
|
+
/**
|
|
110
|
+
* S3 配置类型(parse 后,带默认值的字段已填充,optional 字段仍可缺省)
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* import { S3ConfigSchema, type S3Config } from '@h-ai/storage'
|
|
114
|
+
*
|
|
115
|
+
* const value: S3Config = S3ConfigSchema.parse({ type: 's3', bucket: 'uploads', region: 'us-east-1', accessKeyId: process.env.HAI_STORAGE_ACCESS_KEY_ID, secretAccessKey: process.env.HAI_STORAGE_SECRET_ACCESS_KEY })
|
|
116
|
+
* void value
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
43
119
|
type S3Config = z.infer<typeof S3ConfigSchema>;
|
|
44
120
|
/**
|
|
45
121
|
* 本地存储配置 Schema
|
|
46
122
|
*
|
|
47
123
|
* 基于本地文件系统,仅后端可用。必填字段:root。
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* import { LocalConfigSchema } from '@h-ai/storage'
|
|
127
|
+
*
|
|
128
|
+
* const value = LocalConfigSchema.parse({ type: 'local', root: './data/uploads' })
|
|
129
|
+
* void value
|
|
130
|
+
* ```
|
|
48
131
|
*/
|
|
49
132
|
declare const LocalConfigSchema: z.ZodObject<{
|
|
133
|
+
operationLog: z.ZodOptional<z.ZodObject<{
|
|
134
|
+
read: z.ZodDefault<z.ZodBoolean>;
|
|
135
|
+
write: z.ZodDefault<z.ZodBoolean>;
|
|
136
|
+
maxLength: z.ZodDefault<z.ZodNumber>;
|
|
137
|
+
level: z.ZodDefault<z.ZodEnum<{
|
|
138
|
+
info: "info";
|
|
139
|
+
debug: "debug";
|
|
140
|
+
trace: "trace";
|
|
141
|
+
}>>;
|
|
142
|
+
}, z.core.$strip>>;
|
|
50
143
|
type: z.ZodLiteral<"local">;
|
|
51
144
|
root: z.ZodString;
|
|
52
145
|
directoryMode: z.ZodDefault<z.ZodNumber>;
|
|
53
146
|
fileMode: z.ZodDefault<z.ZodNumber>;
|
|
54
147
|
}, z.core.$strip>;
|
|
55
|
-
/**
|
|
148
|
+
/**
|
|
149
|
+
* 本地配置类型(parse 后,带默认值的字段已填充,optional 字段仍可缺省)
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* import { LocalConfigSchema, type LocalConfig } from '@h-ai/storage'
|
|
153
|
+
*
|
|
154
|
+
* const value: LocalConfig = LocalConfigSchema.parse({ type: 'local', root: './data/uploads' })
|
|
155
|
+
* void value
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
56
158
|
type LocalConfig = z.infer<typeof LocalConfigSchema>;
|
|
57
159
|
/**
|
|
58
160
|
* 统一存储配置 Schema
|
|
59
161
|
*
|
|
60
162
|
* 支持 S3 和本地文件两种类型的配置验证。
|
|
61
|
-
*
|
|
62
163
|
* @example
|
|
63
164
|
* ```ts
|
|
64
|
-
*
|
|
65
|
-
* const s3Config = StorageConfigSchema.parse({
|
|
66
|
-
* type: 's3',
|
|
67
|
-
* bucket: 'my-bucket',
|
|
68
|
-
* region: 'us-east-1',
|
|
69
|
-
* accessKeyId: 'AKIAXXXXXXXX',
|
|
70
|
-
* secretAccessKey: 'xxxxx'
|
|
71
|
-
* })
|
|
72
|
-
*
|
|
73
|
-
* // MinIO 配置
|
|
74
|
-
* const minioConfig = StorageConfigSchema.parse({
|
|
75
|
-
* type: 's3',
|
|
76
|
-
* bucket: 'my-bucket',
|
|
77
|
-
* region: 'us-east-1',
|
|
78
|
-
* endpoint: 'http://localhost:9000',
|
|
79
|
-
* accessKeyId: 'minioadmin',
|
|
80
|
-
* secretAccessKey: 'minioadmin',
|
|
81
|
-
* forcePathStyle: true
|
|
82
|
-
* })
|
|
165
|
+
* import { StorageConfigSchema } from '@h-ai/storage'
|
|
83
166
|
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* type: 'local',
|
|
87
|
-
* root: '/data/uploads'
|
|
88
|
-
* })
|
|
167
|
+
* const value = StorageConfigSchema.parse({ type: 'local', root: './data/uploads' })
|
|
168
|
+
* void value
|
|
89
169
|
* ```
|
|
90
170
|
*/
|
|
91
171
|
declare const StorageConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
172
|
+
operationLog: z.ZodOptional<z.ZodObject<{
|
|
173
|
+
read: z.ZodDefault<z.ZodBoolean>;
|
|
174
|
+
write: z.ZodDefault<z.ZodBoolean>;
|
|
175
|
+
maxLength: z.ZodDefault<z.ZodNumber>;
|
|
176
|
+
level: z.ZodDefault<z.ZodEnum<{
|
|
177
|
+
info: "info";
|
|
178
|
+
debug: "debug";
|
|
179
|
+
trace: "trace";
|
|
180
|
+
}>>;
|
|
181
|
+
}, z.core.$strip>>;
|
|
92
182
|
type: z.ZodLiteral<"s3">;
|
|
93
183
|
bucket: z.ZodString;
|
|
184
|
+
createBucket: z.ZodDefault<z.ZodBoolean>;
|
|
94
185
|
region: z.ZodString;
|
|
95
186
|
accessKeyId: z.ZodString;
|
|
96
187
|
secretAccessKey: z.ZodString;
|
|
97
188
|
endpoint: z.ZodOptional<z.ZodString>;
|
|
189
|
+
publicEndpoint: z.ZodOptional<z.ZodString>;
|
|
98
190
|
forcePathStyle: z.ZodDefault<z.ZodBoolean>;
|
|
99
191
|
prefix: z.ZodDefault<z.ZodString>;
|
|
100
192
|
publicUrl: z.ZodOptional<z.ZodString>;
|
|
101
193
|
}, z.core.$strip>, z.ZodObject<{
|
|
194
|
+
operationLog: z.ZodOptional<z.ZodObject<{
|
|
195
|
+
read: z.ZodDefault<z.ZodBoolean>;
|
|
196
|
+
write: z.ZodDefault<z.ZodBoolean>;
|
|
197
|
+
maxLength: z.ZodDefault<z.ZodNumber>;
|
|
198
|
+
level: z.ZodDefault<z.ZodEnum<{
|
|
199
|
+
info: "info";
|
|
200
|
+
debug: "debug";
|
|
201
|
+
trace: "trace";
|
|
202
|
+
}>>;
|
|
203
|
+
}, z.core.$strip>>;
|
|
102
204
|
type: z.ZodLiteral<"local">;
|
|
103
205
|
root: z.ZodString;
|
|
104
206
|
directoryMode: z.ZodDefault<z.ZodNumber>;
|
|
105
207
|
fileMode: z.ZodDefault<z.ZodNumber>;
|
|
106
208
|
}, z.core.$strip>], "type">;
|
|
107
|
-
/**
|
|
209
|
+
/**
|
|
210
|
+
* 存储配置类型(parse 后的完整配置)
|
|
211
|
+
* @example
|
|
212
|
+
* ```ts
|
|
213
|
+
* import { StorageConfigSchema, type StorageConfig } from '@h-ai/storage'
|
|
214
|
+
*
|
|
215
|
+
* const value: StorageConfig = StorageConfigSchema.parse({ type: 'local', root: './data/uploads' })
|
|
216
|
+
* void value
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
108
219
|
type StorageConfig = z.infer<typeof StorageConfigSchema>;
|
|
109
|
-
/**
|
|
220
|
+
/**
|
|
221
|
+
* 存储配置输入类型(parse 前,允许省略带默认值的字段)
|
|
222
|
+
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* import type { StorageConfigInput } from '@h-ai/storage'
|
|
225
|
+
*
|
|
226
|
+
* const value: StorageConfigInput = { type: 'local', root: './data/uploads' }
|
|
227
|
+
* void value
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
110
230
|
type StorageConfigInput = z.input<typeof StorageConfigSchema>;
|
|
111
231
|
/**
|
|
112
232
|
* 签名 URL 配置 Schema
|
|
113
233
|
*
|
|
114
234
|
* 用于控制 `storage.presign.getUrl()` 生成的下载签名 URL 参数。
|
|
115
|
-
*
|
|
116
235
|
* @example
|
|
117
236
|
* ```ts
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
237
|
+
* import { PresignOptionsSchema } from '@h-ai/storage'
|
|
238
|
+
*
|
|
239
|
+
* const value = PresignOptionsSchema.parse({ expiresIn: 60 })
|
|
240
|
+
* void value
|
|
122
241
|
* ```
|
|
123
242
|
*/
|
|
124
243
|
declare const PresignOptionsSchema: z.ZodObject<{
|
|
@@ -126,20 +245,27 @@ declare const PresignOptionsSchema: z.ZodObject<{
|
|
|
126
245
|
responseContentType: z.ZodOptional<z.ZodString>;
|
|
127
246
|
responseContentDisposition: z.ZodOptional<z.ZodString>;
|
|
128
247
|
}, z.core.$strip>;
|
|
129
|
-
/**
|
|
130
|
-
|
|
248
|
+
/**
|
|
249
|
+
* 签名 URL 输入选项,允许省略带默认值的字段。
|
|
250
|
+
* @example
|
|
251
|
+
* ```ts
|
|
252
|
+
* import type { PresignOptions } from '@h-ai/storage'
|
|
253
|
+
*
|
|
254
|
+
* const value: PresignOptions = { expiresIn: 60, responseContentType: 'text/plain' }
|
|
255
|
+
* void value
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
type PresignOptions = z.input<typeof PresignOptionsSchema>;
|
|
131
259
|
/**
|
|
132
260
|
* 上传签名 URL 配置 Schema
|
|
133
261
|
*
|
|
134
262
|
* 继承 PresignOptionsSchema 并扩展上传专属参数,用于 `storage.presign.putUrl()`。
|
|
135
|
-
*
|
|
136
263
|
* @example
|
|
137
264
|
* ```ts
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* })
|
|
265
|
+
* import { PresignUploadOptionsSchema } from '@h-ai/storage'
|
|
266
|
+
*
|
|
267
|
+
* const value = PresignUploadOptionsSchema.parse({ contentType: 'text/plain' })
|
|
268
|
+
* void value
|
|
143
269
|
* ```
|
|
144
270
|
*/
|
|
145
271
|
declare const PresignUploadOptionsSchema: z.ZodObject<{
|
|
@@ -147,11 +273,30 @@ declare const PresignUploadOptionsSchema: z.ZodObject<{
|
|
|
147
273
|
responseContentType: z.ZodOptional<z.ZodString>;
|
|
148
274
|
responseContentDisposition: z.ZodOptional<z.ZodString>;
|
|
149
275
|
contentType: z.ZodDefault<z.ZodString>;
|
|
150
|
-
maxSize: z.ZodOptional<z.ZodNumber>;
|
|
151
276
|
}, z.core.$strip>;
|
|
152
|
-
/**
|
|
153
|
-
|
|
277
|
+
/**
|
|
278
|
+
* 上传签名 URL 输入选项,省略 contentType 时使用 application/octet-stream。
|
|
279
|
+
* @example
|
|
280
|
+
* ```ts
|
|
281
|
+
* import type { PresignUploadOptions } from '@h-ai/storage'
|
|
282
|
+
*
|
|
283
|
+
* const value: PresignUploadOptions = { expiresIn: 60, contentType: 'text/plain' }
|
|
284
|
+
* void value
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
type PresignUploadOptions = z.input<typeof PresignUploadOptionsSchema>;
|
|
154
288
|
|
|
289
|
+
/**
|
|
290
|
+
* HaiStorageError 的数据约束与操作契约。
|
|
291
|
+
* @example
|
|
292
|
+
* ```ts
|
|
293
|
+
* import { HaiStorageError } from '@h-ai/storage'
|
|
294
|
+
* import { err } from '@h-ai/core'
|
|
295
|
+
*
|
|
296
|
+
* const result = err(HaiStorageError.NOT_FOUND, 'File missing')
|
|
297
|
+
* if (!result.success) void result.error.code
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
155
300
|
declare const HaiStorageError: {
|
|
156
301
|
readonly CONNECTION_FAILED: _h_ai_core.HaiErrorDef;
|
|
157
302
|
readonly OPERATION_FAILED: _h_ai_core.HaiErrorDef;
|
|
@@ -168,11 +313,81 @@ declare const HaiStorageError: {
|
|
|
168
313
|
readonly PRESIGN_FAILED: _h_ai_core.HaiErrorDef;
|
|
169
314
|
readonly UPLOAD_FAILED: _h_ai_core.HaiErrorDef;
|
|
170
315
|
readonly DOWNLOAD_FAILED: _h_ai_core.HaiErrorDef;
|
|
316
|
+
readonly CHECKSUM_FAILED: _h_ai_core.HaiErrorDef;
|
|
317
|
+
readonly INVALID_CHECKSUM: _h_ai_core.HaiErrorDef;
|
|
318
|
+
readonly UNSUPPORTED_OPERATION: _h_ai_core.HaiErrorDef;
|
|
319
|
+
readonly INVALID_LIST_OPTIONS: _h_ai_core.HaiErrorDef;
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* 批量删除中未确认完成的一项;key 始终使用调用方视角,不含 Provider prefix。
|
|
323
|
+
* @example
|
|
324
|
+
* ```ts
|
|
325
|
+
* import type { StorageDeleteFailure } from '@h-ai/storage'
|
|
326
|
+
*
|
|
327
|
+
* const value: StorageDeleteFailure = { key: 'private.txt', code: 'AccessDenied', retryable: false, outcome: 'failed' }
|
|
328
|
+
* void value
|
|
329
|
+
* ```
|
|
330
|
+
*/
|
|
331
|
+
interface StorageDeleteFailure {
|
|
332
|
+
/** 调用方提交的文件键。 */
|
|
333
|
+
key: string;
|
|
334
|
+
/** 渠道/框架错误标识,不包含渠道原始 Message。 */
|
|
335
|
+
code: string;
|
|
336
|
+
/** 是否属于可重试的瞬时故障;未知结果重试前仍需考虑并发上传/版本语义。 */
|
|
337
|
+
retryable: boolean;
|
|
338
|
+
/** failed 为已知失败,unknown 为已发送但结果未知,notAttempted 为尚未发送。 */
|
|
339
|
+
outcome: 'failed' | 'unknown' | 'notAttempted';
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* 批量删除进度;任一失败不能宣称全部删除完成。
|
|
343
|
+
* @example
|
|
344
|
+
* ```ts
|
|
345
|
+
* import type { StorageDeleteSummary } from '@h-ai/storage'
|
|
346
|
+
*
|
|
347
|
+
* const value: StorageDeleteSummary = { deletedKeys: ['a.txt'], failures: [] }
|
|
348
|
+
* void value
|
|
349
|
+
* ```
|
|
350
|
+
*/
|
|
351
|
+
interface StorageDeleteSummary {
|
|
352
|
+
/** 已确认删除或本来就不存在的唯一文件键。 */
|
|
353
|
+
deletedKeys: string[];
|
|
354
|
+
/** 失败、未知及尚未尝试的唯一文件键。 */
|
|
355
|
+
failures: StorageDeleteFailure[];
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* 批量删除结果;失败仍遵守 HaiResult,部分进度置于 error.ext.deleteMany。
|
|
359
|
+
* @example
|
|
360
|
+
* ```ts
|
|
361
|
+
* import { storage, type StorageDeleteResult } from '@h-ai/storage'
|
|
362
|
+
*
|
|
363
|
+
* async function remove() {
|
|
364
|
+
* const result: StorageDeleteResult = await storage.file.deleteMany(['a.txt', 'b.txt'])
|
|
365
|
+
* return result.success ? result.data : result.error.ext?.deleteMany
|
|
366
|
+
* }
|
|
367
|
+
* ```
|
|
368
|
+
*/
|
|
369
|
+
type StorageDeleteResult = {
|
|
370
|
+
success: true;
|
|
371
|
+
data: StorageDeleteSummary;
|
|
372
|
+
} | {
|
|
373
|
+
success: false;
|
|
374
|
+
error: HaiError & {
|
|
375
|
+
ext?: Record<string, unknown> & {
|
|
376
|
+
deleteMany?: StorageDeleteSummary;
|
|
377
|
+
};
|
|
378
|
+
};
|
|
171
379
|
};
|
|
172
380
|
/**
|
|
173
381
|
* 文件元数据接口
|
|
174
382
|
*
|
|
175
383
|
* 表示存储中单个文件的元信息,由 put/head/copy/list 等操作返回。
|
|
384
|
+
* @example
|
|
385
|
+
* ```ts
|
|
386
|
+
* import type { FileMetadata } from '@h-ai/storage'
|
|
387
|
+
*
|
|
388
|
+
* const value: FileMetadata = { key: 'a.txt', size: 5, contentType: 'text/plain', lastModified: new Date() }
|
|
389
|
+
* void value
|
|
390
|
+
* ```
|
|
176
391
|
*/
|
|
177
392
|
interface FileMetadata {
|
|
178
393
|
/** 文件键/路径(不含配置 prefix,对用户透明) */
|
|
@@ -183,7 +398,7 @@ interface FileMetadata {
|
|
|
183
398
|
contentType: string;
|
|
184
399
|
/** 最后修改时间 */
|
|
185
400
|
lastModified: Date;
|
|
186
|
-
/** ETag
|
|
401
|
+
/** ETag(缓存验证标记;本地为 size-mtime,S3 由服务端生成,不等同于内容 checksum) */
|
|
187
402
|
etag?: string;
|
|
188
403
|
/** 自定义元数据键值对 */
|
|
189
404
|
metadata?: Record<string, string>;
|
|
@@ -192,6 +407,13 @@ interface FileMetadata {
|
|
|
192
407
|
* 列表选项
|
|
193
408
|
*
|
|
194
409
|
* 用于控制 `storage.dir.list()` 的过滤、分页和目录模拟行为。
|
|
410
|
+
* @example
|
|
411
|
+
* ```ts
|
|
412
|
+
* import type { ListOptions } from '@h-ai/storage'
|
|
413
|
+
*
|
|
414
|
+
* const value: ListOptions = { prefix: 'reports/', delimiter: '/', maxKeys: 100 }
|
|
415
|
+
* void value
|
|
416
|
+
* ```
|
|
195
417
|
*/
|
|
196
418
|
interface ListOptions {
|
|
197
419
|
/** 前缀过滤(只返回以此前缀开头的文件) */
|
|
@@ -199,23 +421,30 @@ interface ListOptions {
|
|
|
199
421
|
/**
|
|
200
422
|
* 分页标记(从上次 ListResult.nextContinuationToken 获取)
|
|
201
423
|
*
|
|
202
|
-
*
|
|
424
|
+
* Local 游标绑定根目录、prefix 和 delimiter,可跨实例使用;不得跨查询或 provider 混用。
|
|
203
425
|
*/
|
|
204
426
|
continuationToken?: string;
|
|
205
|
-
/**
|
|
427
|
+
/** 每页逻辑条目上限(1–1000,默认 1000);files 和 commonPrefixes 合计计数。 */
|
|
206
428
|
maxKeys?: number;
|
|
207
|
-
/**
|
|
429
|
+
/** 分隔符,通常为 '/';从 prefix 之后首次出现的位置折叠 commonPrefixes,空字符串表示不折叠。 */
|
|
208
430
|
delimiter?: string;
|
|
209
431
|
}
|
|
210
432
|
/**
|
|
211
433
|
* 列表结果
|
|
212
434
|
*
|
|
213
435
|
* 包含当前页的文件列表、目录前缀、分页信息。
|
|
436
|
+
* @example
|
|
437
|
+
* ```ts
|
|
438
|
+
* import type { ListResult } from '@h-ai/storage'
|
|
439
|
+
*
|
|
440
|
+
* const value: ListResult = { files: [], commonPrefixes: ['reports/'], isTruncated: false }
|
|
441
|
+
* void value
|
|
442
|
+
* ```
|
|
214
443
|
*/
|
|
215
444
|
interface ListResult {
|
|
216
445
|
/** 当前页文件元数据列表 */
|
|
217
446
|
files: FileMetadata[];
|
|
218
|
-
/**
|
|
447
|
+
/** 公共前缀:由实际匹配文件按 delimiter 折叠,不包含 Local 空物理目录。 */
|
|
219
448
|
commonPrefixes: string[];
|
|
220
449
|
/** 下一页标记;无后续页时为 undefined */
|
|
221
450
|
nextContinuationToken?: string;
|
|
@@ -226,8 +455,19 @@ interface ListResult {
|
|
|
226
455
|
* 上传选项
|
|
227
456
|
*
|
|
228
457
|
* 用于控制 `storage.file.put()` 的元数据与缓存行为。
|
|
458
|
+
* @example
|
|
459
|
+
* ```ts
|
|
460
|
+
* import type { UploadOptions } from '@h-ai/storage'
|
|
461
|
+
*
|
|
462
|
+
* const value: UploadOptions = { ifNoneMatch: '*', contentType: 'text/plain', signal: new AbortController().signal }
|
|
463
|
+
* void value
|
|
464
|
+
* ```
|
|
229
465
|
*/
|
|
230
466
|
interface UploadOptions {
|
|
467
|
+
/** 仅当 key 不存在时原子写入;S3 使用标准 If-None-Match,后端不支持时返回错误。 */
|
|
468
|
+
ifNoneMatch?: '*';
|
|
469
|
+
/** 取消上传;失败或取消时清理未完成的临时文件/分片。 */
|
|
470
|
+
signal?: AbortSignal;
|
|
231
471
|
/** 内容类型(不指定时根据文件扩展名自动推断) */
|
|
232
472
|
contentType?: string;
|
|
233
473
|
/** 自定义元数据键值对(存储后可通过 head 获取) */
|
|
@@ -242,8 +482,17 @@ interface UploadOptions {
|
|
|
242
482
|
*
|
|
243
483
|
* 用于控制 `storage.file.get()` 的范围读取。
|
|
244
484
|
* 两个字段均为字节偏移(含),与 HTTP Range 语义一致。
|
|
485
|
+
* @example
|
|
486
|
+
* ```ts
|
|
487
|
+
* import type { DownloadOptions } from '@h-ai/storage'
|
|
488
|
+
*
|
|
489
|
+
* const value: DownloadOptions = { rangeStart: 0, rangeEnd: 99 }
|
|
490
|
+
* void value
|
|
491
|
+
* ```
|
|
245
492
|
*/
|
|
246
493
|
interface DownloadOptions {
|
|
494
|
+
/** 取消读取。 */
|
|
495
|
+
signal?: AbortSignal;
|
|
247
496
|
/** 范围起始位置(字节,含);不指定时从文件开头读取 */
|
|
248
497
|
rangeStart?: number;
|
|
249
498
|
/** 范围结束位置(字节,含);不指定时读取到文件末尾 */
|
|
@@ -254,6 +503,13 @@ interface DownloadOptions {
|
|
|
254
503
|
*
|
|
255
504
|
* 用于控制 `storage.file.copy()` 的目标文件元数据。
|
|
256
505
|
* 提供任意字段时,S3 Provider 会使用 MetadataDirective='REPLACE' 覆盖源文件元数据。
|
|
506
|
+
* @example
|
|
507
|
+
* ```ts
|
|
508
|
+
* import type { CopyOptions } from '@h-ai/storage'
|
|
509
|
+
*
|
|
510
|
+
* const value: CopyOptions = { contentType: 'text/plain', metadata: { category: 'reports' } }
|
|
511
|
+
* void value
|
|
512
|
+
* ```
|
|
257
513
|
*/
|
|
258
514
|
interface CopyOptions {
|
|
259
515
|
/** 目标文件的内容类型(不指定时继承源文件) */
|
|
@@ -261,17 +517,81 @@ interface CopyOptions {
|
|
|
261
517
|
/** 目标文件的自定义元数据(不指定时继承源文件) */
|
|
262
518
|
metadata?: Record<string, string>;
|
|
263
519
|
}
|
|
520
|
+
/**
|
|
521
|
+
* 文件内容;异步字节流支持 Node Readable 等,不将整个文件载入内存。
|
|
522
|
+
* @example
|
|
523
|
+
* ```ts
|
|
524
|
+
* import type { StorageData } from '@h-ai/storage'
|
|
525
|
+
*
|
|
526
|
+
* const value: StorageData = new TextEncoder().encode('hello')
|
|
527
|
+
* void value
|
|
528
|
+
* ```
|
|
529
|
+
*/
|
|
530
|
+
type StorageData = Buffer | Uint8Array | string | AsyncIterable<Uint8Array>;
|
|
531
|
+
/**
|
|
532
|
+
* 常见 checksum 算法;MD5/SHA-1 仅用于兼容性完整性校验,不用于安全认证。
|
|
533
|
+
* @example
|
|
534
|
+
* ```ts
|
|
535
|
+
* import type { ChecksumAlgorithm } from '@h-ai/storage'
|
|
536
|
+
*
|
|
537
|
+
* const value: ChecksumAlgorithm = 'sha256'
|
|
538
|
+
* void value
|
|
539
|
+
* ```
|
|
540
|
+
*/
|
|
541
|
+
type ChecksumAlgorithm = 'sha256' | 'sha384' | 'sha512' | 'sha1' | 'md5';
|
|
542
|
+
/**
|
|
543
|
+
* checksum 计算选项;默认 SHA-256、小写 hex。
|
|
544
|
+
* @example
|
|
545
|
+
* ```ts
|
|
546
|
+
* import type { ChecksumOptions } from '@h-ai/storage'
|
|
547
|
+
*
|
|
548
|
+
* const value: ChecksumOptions = { algorithm: 'sha256', encoding: 'hex' }
|
|
549
|
+
* void value
|
|
550
|
+
* ```
|
|
551
|
+
*/
|
|
552
|
+
interface ChecksumOptions {
|
|
553
|
+
algorithm?: ChecksumAlgorithm;
|
|
554
|
+
encoding?: 'hex' | 'base64';
|
|
555
|
+
signal?: AbortSignal;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Node 端无状态 checksum 工具,不依赖 storage.init;流输入仅消费一次。
|
|
559
|
+
* @example
|
|
560
|
+
* ```ts
|
|
561
|
+
* import type { ChecksumOperations } from '@h-ai/storage'
|
|
562
|
+
*
|
|
563
|
+
* async function inspect(operations: ChecksumOperations) {
|
|
564
|
+
* const result = await operations.generate('hello')
|
|
565
|
+
* if (!result.success) return result.error.message
|
|
566
|
+
* return result.data
|
|
567
|
+
* }
|
|
568
|
+
* ```
|
|
569
|
+
*/
|
|
570
|
+
interface ChecksumOperations {
|
|
571
|
+
generate: (data: StorageData, options?: ChecksumOptions) => Promise<HaiResult<string>>;
|
|
572
|
+
verify: (data: StorageData, expected: string, options?: ChecksumOptions) => Promise<HaiResult<boolean>>;
|
|
573
|
+
}
|
|
264
574
|
/**
|
|
265
575
|
* 文件操作接口
|
|
266
576
|
*
|
|
267
577
|
* 提供文件的读写操作。
|
|
578
|
+
* @example
|
|
579
|
+
* ```ts
|
|
580
|
+
* import type { FileOperations } from '@h-ai/storage'
|
|
581
|
+
*
|
|
582
|
+
* async function inspect(operations: FileOperations) {
|
|
583
|
+
* const result = await operations.getStream('reports/a.txt')
|
|
584
|
+
* if (!result.success) return result.error.message
|
|
585
|
+
* for await (const chunk of result.data) void chunk.byteLength
|
|
586
|
+
* }
|
|
587
|
+
* ```
|
|
268
588
|
*/
|
|
269
589
|
interface FileOperations {
|
|
270
590
|
/**
|
|
271
591
|
* 上传文件
|
|
272
592
|
*
|
|
273
593
|
* @param key - 文件键/路径
|
|
274
|
-
* @param data - 文件内容(Buffer、Uint8Array
|
|
594
|
+
* @param data - 文件内容(Buffer、Uint8Array、字符串或异步字节流)
|
|
275
595
|
* @param options - 上传选项
|
|
276
596
|
* @returns 上传结果包含文件元数据
|
|
277
597
|
* @example
|
|
@@ -282,7 +602,7 @@ interface FileOperations {
|
|
|
282
602
|
* }
|
|
283
603
|
* ```
|
|
284
604
|
*/
|
|
285
|
-
put: (key: string, data:
|
|
605
|
+
put: (key: string, data: StorageData, options?: UploadOptions) => Promise<HaiResult<FileMetadata>>;
|
|
286
606
|
/**
|
|
287
607
|
* 下载文件
|
|
288
608
|
*
|
|
@@ -294,10 +614,29 @@ interface FileOperations {
|
|
|
294
614
|
* const result = await storage.file.get('uploads/a.txt')
|
|
295
615
|
* if (result.success) {
|
|
296
616
|
* const buffer = result.data
|
|
617
|
+
* void buffer
|
|
297
618
|
* }
|
|
298
619
|
* ```
|
|
299
620
|
*/
|
|
300
621
|
get: (key: string, options?: DownloadOptions) => Promise<HaiResult<Buffer>>;
|
|
622
|
+
/**
|
|
623
|
+
* 读取字节流,支持 Range 与取消;消费方负责及时迭代或关闭流。
|
|
624
|
+
* @throws 迭代期间的 I/O/取消错误;初始请求失败通过 HaiResult 返回。
|
|
625
|
+
* @example
|
|
626
|
+
* ```ts
|
|
627
|
+
* import { storage } from '@h-ai/storage'
|
|
628
|
+
*
|
|
629
|
+
* const result = await storage.file.getStream('reports/a.txt')
|
|
630
|
+
* if (!result.success) throw new Error(result.error.message)
|
|
631
|
+
* try {
|
|
632
|
+
* for await (const chunk of result.data) void chunk.byteLength
|
|
633
|
+
* } catch (error) {
|
|
634
|
+
* // 初始请求成功后,迭代仍可能因 I/O/取消失败。
|
|
635
|
+
* throw error
|
|
636
|
+
* }
|
|
637
|
+
* ```
|
|
638
|
+
*/
|
|
639
|
+
getStream: (key: string, options?: DownloadOptions) => Promise<HaiResult<AsyncIterable<Uint8Array>>>;
|
|
301
640
|
/**
|
|
302
641
|
* 获取文件元数据
|
|
303
642
|
*
|
|
@@ -333,7 +672,10 @@ interface FileOperations {
|
|
|
333
672
|
* @returns 删除结果
|
|
334
673
|
* @example
|
|
335
674
|
* ```ts
|
|
336
|
-
*
|
|
675
|
+
* import { storage } from '@h-ai/storage'
|
|
676
|
+
*
|
|
677
|
+
* const result = await storage.file.delete('uploads/a.txt')
|
|
678
|
+
* if (!result.success) throw new Error(result.error.message)
|
|
337
679
|
* ```
|
|
338
680
|
*/
|
|
339
681
|
delete: (key: string) => Promise<HaiResult<void>>;
|
|
@@ -341,13 +683,15 @@ interface FileOperations {
|
|
|
341
683
|
* 批量删除文件
|
|
342
684
|
*
|
|
343
685
|
* @param keys - 文件键/路径列表
|
|
344
|
-
* @returns
|
|
686
|
+
* @returns 全部成功时返回进度;任一失败时 success=false,进度在 error.ext.deleteMany
|
|
345
687
|
* @example
|
|
346
688
|
* ```ts
|
|
347
|
-
* await storage.file.deleteMany(['a.txt', 'b.txt'])
|
|
689
|
+
* const result = await storage.file.deleteMany(['a.txt', 'b.txt'])
|
|
690
|
+
* const progress = result.success ? result.data : result.error.ext?.deleteMany
|
|
691
|
+
* void progress
|
|
348
692
|
* ```
|
|
349
693
|
*/
|
|
350
|
-
deleteMany: (keys: string[]) => Promise<
|
|
694
|
+
deleteMany: (keys: string[]) => Promise<StorageDeleteResult>;
|
|
351
695
|
/**
|
|
352
696
|
* 复制文件
|
|
353
697
|
*
|
|
@@ -357,7 +701,11 @@ interface FileOperations {
|
|
|
357
701
|
* @returns 目标文件元数据
|
|
358
702
|
* @example
|
|
359
703
|
* ```ts
|
|
360
|
-
*
|
|
704
|
+
* import { storage } from '@h-ai/storage'
|
|
705
|
+
*
|
|
706
|
+
* const result = await storage.file.copy('a.txt', 'b.txt')
|
|
707
|
+
* if (!result.success) throw new Error(result.error.message)
|
|
708
|
+
* void result.data.key
|
|
361
709
|
* ```
|
|
362
710
|
*/
|
|
363
711
|
copy: (sourceKey: string, destKey: string, options?: CopyOptions) => Promise<HaiResult<FileMetadata>>;
|
|
@@ -366,6 +714,16 @@ interface FileOperations {
|
|
|
366
714
|
* 目录操作接口
|
|
367
715
|
*
|
|
368
716
|
* 提供目录(前缀)的列表操作。
|
|
717
|
+
* @example
|
|
718
|
+
* ```ts
|
|
719
|
+
* import type { DirOperations } from '@h-ai/storage'
|
|
720
|
+
*
|
|
721
|
+
* async function inspect(operations: DirOperations) {
|
|
722
|
+
* const page = await operations.list({ prefix: 'reports/', maxKeys: 100 })
|
|
723
|
+
* if (!page.success) return page.error.message
|
|
724
|
+
* return page.data.files
|
|
725
|
+
* }
|
|
726
|
+
* ```
|
|
369
727
|
*/
|
|
370
728
|
interface DirOperations {
|
|
371
729
|
/**
|
|
@@ -389,7 +747,10 @@ interface DirOperations {
|
|
|
389
747
|
* @returns 删除结果
|
|
390
748
|
* @example
|
|
391
749
|
* ```ts
|
|
392
|
-
*
|
|
750
|
+
* import { storage } from '@h-ai/storage'
|
|
751
|
+
*
|
|
752
|
+
* const result = await storage.dir.delete('uploads/tmp/')
|
|
753
|
+
* if (!result.success) throw new Error(result.error.message)
|
|
393
754
|
* ```
|
|
394
755
|
*/
|
|
395
756
|
delete: (prefix: string) => Promise<HaiResult<void>>;
|
|
@@ -397,30 +758,47 @@ interface DirOperations {
|
|
|
397
758
|
/**
|
|
398
759
|
* 签名 URL 操作接口
|
|
399
760
|
*
|
|
400
|
-
*
|
|
761
|
+
* S3 provider 提供临时授权 URL,支持前端直接上传下载。
|
|
762
|
+
* local 的 getUrl/putUrl 返回 UNSUPPORTED_OPERATION,publicUrl 返回 null。
|
|
763
|
+
* @example
|
|
764
|
+
* ```ts
|
|
765
|
+
* import type { PresignOperations } from '@h-ai/storage'
|
|
766
|
+
*
|
|
767
|
+
* async function inspect(operations: PresignOperations) {
|
|
768
|
+
* const signed = await operations.putUrl('reports/a.txt', { contentType: 'text/plain', expiresIn: 300 })
|
|
769
|
+
* if (!signed.success) return signed.error.message
|
|
770
|
+
* return signed.data
|
|
771
|
+
* }
|
|
772
|
+
* ```
|
|
401
773
|
*/
|
|
402
774
|
interface PresignOperations {
|
|
403
775
|
/**
|
|
404
|
-
*
|
|
776
|
+
* 生成 GET 下载签名 URL;使用 publicEndpoint,缺省回退 endpoint/AWS 端点,签名后不能改写地址。
|
|
405
777
|
*
|
|
406
778
|
* @param key - 文件键/路径
|
|
407
779
|
* @param options - 签名选项
|
|
408
|
-
* @returns 签名 URL
|
|
780
|
+
* @returns 成功时为可访问的 S3 签名 URL;local 返回 UNSUPPORTED_OPERATION。
|
|
409
781
|
* @example
|
|
410
782
|
* ```ts
|
|
411
783
|
* const result = await storage.presign.getUrl('a.txt', { expiresIn: 60 })
|
|
784
|
+
* if (!result.success) throw new Error(result.error.message)
|
|
785
|
+
* const downloadUrl = result.data
|
|
786
|
+
* void downloadUrl
|
|
412
787
|
* ```
|
|
413
788
|
*/
|
|
414
789
|
getUrl: (key: string, options?: PresignOptions) => Promise<HaiResult<string>>;
|
|
415
790
|
/**
|
|
416
|
-
*
|
|
791
|
+
* 生成 PUT 上传签名 URL;使用 publicEndpoint,服务端 CRUD 仍使用内部 endpoint。
|
|
417
792
|
*
|
|
418
793
|
* @param key - 文件键/路径
|
|
419
794
|
* @param options - 上传签名选项
|
|
420
|
-
* @returns 签名 URL
|
|
795
|
+
* @returns 成功时为可访问的 S3 签名 URL;local 返回 UNSUPPORTED_OPERATION。
|
|
421
796
|
* @example
|
|
422
797
|
* ```ts
|
|
423
798
|
* const result = await storage.presign.putUrl('a.txt', { contentType: 'text/plain' })
|
|
799
|
+
* if (!result.success) throw new Error(result.error.message)
|
|
800
|
+
* const uploadUrl = result.data
|
|
801
|
+
* void uploadUrl
|
|
424
802
|
* ```
|
|
425
803
|
*/
|
|
426
804
|
putUrl: (key: string, options?: PresignUploadOptions) => Promise<HaiResult<string>>;
|
|
@@ -428,10 +806,11 @@ interface PresignOperations {
|
|
|
428
806
|
* 获取公开访问 URL(如果配置了 publicUrl)
|
|
429
807
|
*
|
|
430
808
|
* @param key - 文件键/路径
|
|
431
|
-
* @returns 公开 URL
|
|
809
|
+
* @returns 公开 URL;S3 未配置 publicUrl 或 local provider 均返回 null。
|
|
432
810
|
* @example
|
|
433
811
|
* ```ts
|
|
434
812
|
* const url = storage.presign.publicUrl('a.txt')
|
|
813
|
+
* void url
|
|
435
814
|
* ```
|
|
436
815
|
*/
|
|
437
816
|
publicUrl: (key: string) => string | null;
|
|
@@ -445,26 +824,62 @@ interface PresignOperations {
|
|
|
445
824
|
* - `storage.file` — 文件操作(上传/下载/删除/复制等)
|
|
446
825
|
* - `storage.dir` — 目录操作(列表/删除)
|
|
447
826
|
* - `storage.presign` — 签名 URL 操作
|
|
448
|
-
* - `storage.config` —
|
|
827
|
+
* - `storage.config` — 当前脱敏配置快照(未初始化时为 null)
|
|
449
828
|
* - `storage.isInitialized` — 初始化状态
|
|
829
|
+
* @example
|
|
830
|
+
* ```ts
|
|
831
|
+
* import { storage } from '@h-ai/storage'
|
|
832
|
+
*
|
|
833
|
+
* const initialized = await storage.init({ type: 'local', root: './data/uploads' })
|
|
834
|
+
* if (!initialized.success) throw new Error(initialized.error.message)
|
|
835
|
+
* try {
|
|
836
|
+
* const uploaded = await storage.file.put('reports/a.txt', 'hello', { ifNoneMatch: '*' })
|
|
837
|
+
* if (!uploaded.success) throw new Error(uploaded.error.message)
|
|
838
|
+
* const downloaded = await storage.file.get('reports/a.txt')
|
|
839
|
+
* if (!downloaded.success) throw new Error(downloaded.error.message)
|
|
840
|
+
* void downloaded.data
|
|
841
|
+
* } finally {
|
|
842
|
+
* const closed = await storage.close()
|
|
843
|
+
* if (!closed.success) throw new Error(closed.error.message)
|
|
844
|
+
* }
|
|
845
|
+
* ```
|
|
450
846
|
*/
|
|
451
847
|
interface StorageFunctions {
|
|
848
|
+
/** 无状态 checksum 生成与校验,Node 专用,无需初始化。 */
|
|
849
|
+
readonly checksum: ChecksumOperations;
|
|
452
850
|
/**
|
|
453
851
|
* 初始化存储连接
|
|
454
852
|
*
|
|
455
853
|
* 已有连接时会先 close 再重新初始化。
|
|
456
854
|
*
|
|
457
855
|
* @param config - 存储配置(支持省略带默认值的字段)
|
|
458
|
-
* @returns 成功 ok(undefined);失败返回 err(含
|
|
856
|
+
* @returns 成功 ok(undefined);失败返回 err(含 HaiStorageError 定义的错误信息)
|
|
857
|
+
* @example
|
|
858
|
+
* ```ts
|
|
859
|
+
* import { storage } from '@h-ai/storage'
|
|
860
|
+
*
|
|
861
|
+
* const initialized = await storage.init({ type: 'local', root: './data/uploads' })
|
|
862
|
+
* if (!initialized.success) throw new Error(initialized.error.message)
|
|
863
|
+
* const closed = await storage.close()
|
|
864
|
+
* if (!closed.success) throw new Error(closed.error.message)
|
|
865
|
+
* ```
|
|
459
866
|
*/
|
|
460
867
|
init: (config: StorageConfigInput) => Promise<HaiResult<void>>;
|
|
461
868
|
/**
|
|
462
869
|
* 关闭存储连接并释放资源
|
|
463
870
|
*
|
|
464
|
-
*
|
|
871
|
+
* 等待初始化并合并并发关闭;失败时操作不可用,资源保留供 close/init 重试。
|
|
872
|
+
* @returns 所有资源释放成功才返回成功;未初始化时同样成功。
|
|
873
|
+
* @example
|
|
874
|
+
* ```ts
|
|
875
|
+
* import { storage } from '@h-ai/storage'
|
|
876
|
+
*
|
|
877
|
+
* const closed = await storage.close()
|
|
878
|
+
* if (!closed.success) throw new Error(closed.error.message)
|
|
879
|
+
* ```
|
|
465
880
|
*/
|
|
466
|
-
close: () => Promise<void
|
|
467
|
-
/**
|
|
881
|
+
close: () => Promise<HaiResult<void>>;
|
|
882
|
+
/** 当前脱敏后的存储配置快照;未初始化或已关闭时为 null */
|
|
468
883
|
readonly config: StorageConfig | null;
|
|
469
884
|
/** 是否已完成初始化 */
|
|
470
885
|
readonly isInitialized: boolean;
|
|
@@ -475,32 +890,5 @@ interface StorageFunctions {
|
|
|
475
890
|
/** 签名 URL 操作接口(getUrl / putUrl / publicUrl) */
|
|
476
891
|
readonly presign: PresignOperations;
|
|
477
892
|
}
|
|
478
|
-
/**
|
|
479
|
-
* 存储 Provider 接口
|
|
480
|
-
*
|
|
481
|
-
* 由各具体存储实现(S3、Local)实现此接口。
|
|
482
|
-
* Provider 仅在 storage-main 内部使用,不直接对外暴露实例。
|
|
483
|
-
*/
|
|
484
|
-
interface StorageProvider {
|
|
485
|
-
/** Provider 名称标识(如 's3'、'local') */
|
|
486
|
-
readonly name: string;
|
|
487
|
-
/**
|
|
488
|
-
* 建立与存储服务的连接
|
|
489
|
-
*
|
|
490
|
-
* @param config - 经 Schema 校验后的完整配置
|
|
491
|
-
* @returns 连接结果
|
|
492
|
-
*/
|
|
493
|
-
connect: (config: StorageConfig) => Promise<HaiResult<void>>;
|
|
494
|
-
/** 关闭连接并释放资源 */
|
|
495
|
-
close: () => Promise<void>;
|
|
496
|
-
/** 检查是否已连接 */
|
|
497
|
-
isConnected: () => boolean;
|
|
498
|
-
/** 文件操作接口 */
|
|
499
|
-
readonly file: FileOperations;
|
|
500
|
-
/** 目录操作接口 */
|
|
501
|
-
readonly dir: DirOperations;
|
|
502
|
-
/** 签名 URL 操作接口 */
|
|
503
|
-
readonly presign: PresignOperations;
|
|
504
|
-
}
|
|
505
893
|
|
|
506
|
-
export { type CopyOptions, type DirOperations, type DownloadOptions, type FileMetadata, type FileOperations, HaiStorageError, type ListOptions, type ListResult, type LocalConfig, LocalConfigSchema, type PresignOperations, type PresignOptions, PresignOptionsSchema, type PresignUploadOptions, PresignUploadOptionsSchema, type S3Config, S3ConfigSchema, type StorageConfig, type StorageConfigInput, StorageConfigSchema, type StorageFunctions, type
|
|
894
|
+
export { type ChecksumAlgorithm, type ChecksumOperations, type ChecksumOptions, type CopyOptions, type DirOperations, type DownloadOptions, type FileMetadata, type FileOperations, HaiStorageError, type ListOptions, type ListResult, type LocalConfig, LocalConfigSchema, type PresignOperations, type PresignOptions, PresignOptionsSchema, type PresignUploadOptions, PresignUploadOptionsSchema, type S3Config, S3ConfigSchema, type StorageConfig, type StorageConfigInput, StorageConfigSchema, type StorageData, type StorageDeleteFailure, type StorageDeleteResult, type StorageDeleteSummary, type StorageFunctions, type StorageOperationLogConfig, StorageOperationLogConfigSchema, type StorageType, StorageTypeSchema, type UploadOptions };
|