@vertracloud/blob 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +169 -2
- package/dist/index.cjs +1097 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +293 -0
- package/dist/index.d.ts +293 -0
- package/dist/index.js +1063 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -5
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { APIBlobObject, BlobVisibility, BlobContentDisposition, APIBlobUpload, SnowFlake, APIBlobObjectList, APIBlobBatchResult, APIBlobDeleteResult, APIBlobDownload, APIBlobStats, APIBlobUploadToken, APIBlobS3Credentials, APIBlobShare, APIBlobRules, RESTPutAPIBlobRuleBody, APIBlobCustomDomain, RESTPatchAPIBlobDomainBody } from '@vertracloud/api-types/v1';
|
|
2
|
+
export { APIBlobBatchResult, APIBlobCustomDomain, APIBlobDeleteResult, APIBlobDownload, APIBlobLimits, APIBlobObject, APIBlobObjectList, APIBlobRule, APIBlobRules, APIBlobS3Credentials, APIBlobShare, APIBlobSharePublic, APIBlobStats, APIBlobUpload, APIBlobUploadPart, APIBlobUploadToken, APIErrorCode, BlobContentDisposition, BlobCustomDomainStatus, BlobUploadMode, BlobUploadStatus, BlobVisibility, ISODateString, RESTBlobObjectWriteOptions, RESTBlobRuleInput, RESTDeleteAPIBlobObjectsBody, RESTDeleteAPIBlobObjectsResponse, RESTDeleteAPIBlobRuleResponse, RESTGetAPIBlobDomainsResponse, RESTGetAPIBlobObjectDownloadQuery, RESTGetAPIBlobObjectDownloadResponse, RESTGetAPIBlobObjectResponse, RESTGetAPIBlobObjectsQuery, RESTGetAPIBlobObjectsResponse, RESTGetAPIBlobRulesResponse, RESTGetAPIBlobS3CredentialsResponse, RESTGetAPIBlobSharesQuery, RESTGetAPIBlobSharesResponse, RESTGetAPIBlobStatsResponse, RESTGetAPIBlobUploadResponse, RESTGetAPIBlobUploadsResponse, RESTPatchAPIBlobDomainBody, RESTPatchAPIBlobDomainResponse, RESTPatchAPIBlobObjectBody, RESTPatchAPIBlobObjectResponse, RESTPatchAPIBlobObjectsBody, RESTPatchAPIBlobObjectsResponse, RESTPostAPIBlobDomainBody, RESTPostAPIBlobDomainResponse, RESTPostAPIBlobDomainVerifyResponse, RESTPostAPIBlobObjectCopyBody, RESTPostAPIBlobObjectCopyResponse, RESTPostAPIBlobObjectQuery, RESTPostAPIBlobObjectResponse, RESTPostAPIBlobShareBody, RESTPostAPIBlobShareResponse, RESTPostAPIBlobUploadBody, RESTPostAPIBlobUploadCompleteResponse, RESTPostAPIBlobUploadPartsBody, RESTPostAPIBlobUploadPartsResponse, RESTPostAPIBlobUploadResponse, RESTPostAPIBlobUploadTokenBody, RESTPostAPIBlobUploadTokenResponse, RESTPutAPIBlobRuleBody, RESTPutAPIBlobRuleResponse, RESTPutAPIBlobRulesBody, RESTPutAPIBlobRulesResponse, SnowFlake } from '@vertracloud/api-types/v1';
|
|
3
|
+
|
|
4
|
+
/** Alias of `APIBlobObject`, the object returned by `put`, `get`, `list`, … */
|
|
5
|
+
type BlobObject = APIBlobObject;
|
|
6
|
+
|
|
7
|
+
/** Everything `put` and `resume` accept as file content. A `ReadableStream` also needs `size`. */
|
|
8
|
+
type BlobData = Blob | ArrayBuffer | Uint8Array | ReadableStream<Uint8Array> | string;
|
|
9
|
+
|
|
10
|
+
/** Error envelope sent by the API on any non-2xx response: `{ code, message?, details? }`. */
|
|
11
|
+
interface BlobErrorBody {
|
|
12
|
+
code: string;
|
|
13
|
+
message?: string;
|
|
14
|
+
details?: unknown;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Codes the SDK raises itself (they never come from the API): `NETWORK_ERROR`, `TIMEOUT`, `ABORTED`,
|
|
18
|
+
* `INVALID_ARGUMENT`, `UPLOAD_FAILED` (the storage rejected a direct upload) and `INVALID_RESPONSE`.
|
|
19
|
+
* `status` is `0` for the ones that happened before an HTTP response existed.
|
|
20
|
+
*/
|
|
21
|
+
type BlobClientErrorCode = "NETWORK_ERROR" | "TIMEOUT" | "ABORTED" | "INVALID_ARGUMENT" | "UPLOAD_FAILED" | "INVALID_RESPONSE";
|
|
22
|
+
/**
|
|
23
|
+
* Error thrown for every failed call: an API error response (`code` is an `APIErrorCode`, for example
|
|
24
|
+
* `BLOB_OBJECT_NOT_FOUND`) or a client-side failure (see {@link BlobClientErrorCode}).
|
|
25
|
+
*
|
|
26
|
+
* `toString()` and `toJSON()` never include the request that produced the error (URL, headers,
|
|
27
|
+
* credentials, signed upload URLs) — only `status`, `code`, `message`, `details` and `retryAfter`.
|
|
28
|
+
*/
|
|
29
|
+
declare class BlobError extends Error {
|
|
30
|
+
readonly status: number;
|
|
31
|
+
readonly code: string;
|
|
32
|
+
readonly details: unknown;
|
|
33
|
+
/** Seconds to wait before retrying, from the `Retry-After` header (429 responses). */
|
|
34
|
+
readonly retryAfter: number | undefined;
|
|
35
|
+
constructor(status: number, body: BlobErrorBody, retryAfter?: number);
|
|
36
|
+
toJSON(): {
|
|
37
|
+
name: string;
|
|
38
|
+
status: number;
|
|
39
|
+
code: string;
|
|
40
|
+
message: string;
|
|
41
|
+
details: unknown;
|
|
42
|
+
retryAfter: number | undefined;
|
|
43
|
+
};
|
|
44
|
+
toString(): string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
|
|
48
|
+
|
|
49
|
+
interface BlobClientOptions {
|
|
50
|
+
/** API key (`blob:read` / `blob:write`). Sent as `Authorization: Bearer <apiKey>`. */
|
|
51
|
+
apiKey?: string;
|
|
52
|
+
/** Upload token (`vcup_…`) for browsers and other untrusted clients; valid on the upload routes only. */
|
|
53
|
+
uploadToken?: string;
|
|
54
|
+
/**
|
|
55
|
+
* API base URL **including the version prefix**; every route is appended to it (`${baseUrl}/objects`).
|
|
56
|
+
* Default `https://blob.vertracloud.app/v1`.
|
|
57
|
+
*/
|
|
58
|
+
baseUrl?: string;
|
|
59
|
+
/** Custom `fetch` (proxies, tests, instrumentation). When set, upload progress is by completed part instead of by byte. */
|
|
60
|
+
fetch?: FetchLike;
|
|
61
|
+
/** Sent with every API call. Use `"include"` with a cookie session; then no Authorization header is needed. Never sent to signed upload URLs. */
|
|
62
|
+
credentials?: RequestCredentials;
|
|
63
|
+
/** Added as `?workspace_id=` to every API call, to act on the blob of a workspace owner. */
|
|
64
|
+
workspaceId?: string;
|
|
65
|
+
/** Extra headers for every API call. */
|
|
66
|
+
headers?: Record<string, string>;
|
|
67
|
+
/** Parts uploaded at the same time in a multipart upload. Default 4. */
|
|
68
|
+
partConcurrency?: number;
|
|
69
|
+
/** Retries for idempotent calls (GET, and the PUT of a part or single upload) on 5xx and network errors. Default 3. Never applied to 429. */
|
|
70
|
+
maxRetries?: number;
|
|
71
|
+
/** First retry delay in ms; doubles each attempt, with jitter. Default 300. */
|
|
72
|
+
retryDelayMs?: number;
|
|
73
|
+
/** Default timeout in ms for each API call. Default 30000; `0` disables. */
|
|
74
|
+
timeout?: number;
|
|
75
|
+
/** Timeout in ms for each request that sends file bytes (a part, a single PUT, or the simple upload). Default 300000; `0` disables. */
|
|
76
|
+
uploadTimeout?: number;
|
|
77
|
+
}
|
|
78
|
+
interface RequestOptions {
|
|
79
|
+
signal?: AbortSignal;
|
|
80
|
+
/** Timeout in ms for this call, overriding the client default. */
|
|
81
|
+
timeout?: number;
|
|
82
|
+
}
|
|
83
|
+
interface BlobProgress {
|
|
84
|
+
loaded: number;
|
|
85
|
+
total: number;
|
|
86
|
+
}
|
|
87
|
+
interface BlobWriteOptions {
|
|
88
|
+
visibility?: BlobVisibility;
|
|
89
|
+
/** Replace an existing object at the same path. */
|
|
90
|
+
overwrite?: boolean;
|
|
91
|
+
/** Insert `-<10 random characters>` before the extension. */
|
|
92
|
+
randomSuffix?: boolean;
|
|
93
|
+
cacheControl?: string;
|
|
94
|
+
contentDisposition?: BlobContentDisposition;
|
|
95
|
+
/** File name suggested on download. */
|
|
96
|
+
filename?: string;
|
|
97
|
+
expiresAt?: Date | string;
|
|
98
|
+
/** Hex SHA-256 of the file. */
|
|
99
|
+
checksumSha256?: string;
|
|
100
|
+
/** Up to 5 keys, plan-dependent. */
|
|
101
|
+
metadata?: Record<string, string>;
|
|
102
|
+
}
|
|
103
|
+
interface BlobPutOptions extends BlobWriteOptions, RequestOptions {
|
|
104
|
+
/** Total size in bytes. Required for a `ReadableStream`. */
|
|
105
|
+
size?: number;
|
|
106
|
+
/** Called as bytes are sent. By byte in browsers (XMLHttpRequest); by finished part in Node and edge runtimes. */
|
|
107
|
+
onProgress?: (progress: BlobProgress) => void;
|
|
108
|
+
/** Called once a direct upload exists, before any byte is sent. Keep `upload.id` to `resume` after a crash. */
|
|
109
|
+
onUpload?: (upload: APIBlobUpload) => void;
|
|
110
|
+
}
|
|
111
|
+
interface BlobResumeOptions extends RequestOptions {
|
|
112
|
+
size?: number;
|
|
113
|
+
onProgress?: (progress: BlobProgress) => void;
|
|
114
|
+
}
|
|
115
|
+
interface BlobListOptions extends RequestOptions {
|
|
116
|
+
prefix?: string;
|
|
117
|
+
/** Group paths into folders at this character (usually `/`); folders only come back from `listPage`. */
|
|
118
|
+
delimiter?: string;
|
|
119
|
+
visibility?: BlobVisibility;
|
|
120
|
+
/** Page size, 1–1000. Default 100. */
|
|
121
|
+
limit?: number;
|
|
122
|
+
}
|
|
123
|
+
interface BlobListPageOptions extends BlobListOptions {
|
|
124
|
+
cursor?: string;
|
|
125
|
+
}
|
|
126
|
+
interface BlobUpdateChanges {
|
|
127
|
+
visibility?: BlobVisibility;
|
|
128
|
+
/** `null` restores the default. */
|
|
129
|
+
cacheControl?: string | null;
|
|
130
|
+
contentDisposition?: BlobContentDisposition | null;
|
|
131
|
+
filename?: string | null;
|
|
132
|
+
expiresAt?: Date | string | null;
|
|
133
|
+
/** A `null` value removes that key. */
|
|
134
|
+
metadata?: Record<string, string | null>;
|
|
135
|
+
}
|
|
136
|
+
interface BlobCopyOptions extends RequestOptions {
|
|
137
|
+
overwrite?: boolean;
|
|
138
|
+
randomSuffix?: boolean;
|
|
139
|
+
visibility?: BlobVisibility;
|
|
140
|
+
}
|
|
141
|
+
interface BlobDownloadUrlOptions extends RequestOptions {
|
|
142
|
+
/** Seconds, 60–86400. Default 3600. */
|
|
143
|
+
expiresIn?: number;
|
|
144
|
+
disposition?: BlobContentDisposition;
|
|
145
|
+
filename?: string;
|
|
146
|
+
}
|
|
147
|
+
interface BlobUploadTokenOptions extends RequestOptions {
|
|
148
|
+
path?: string;
|
|
149
|
+
prefix?: string;
|
|
150
|
+
visibility?: BlobVisibility;
|
|
151
|
+
/** Let uploads made with the token replace an existing object. Default `false`. */
|
|
152
|
+
overwrite?: boolean;
|
|
153
|
+
maxSize?: number;
|
|
154
|
+
allowedExtensions?: string[];
|
|
155
|
+
cacheControl?: string;
|
|
156
|
+
contentDisposition?: BlobContentDisposition;
|
|
157
|
+
expiresAt?: Date | string;
|
|
158
|
+
metadata?: Record<string, string>;
|
|
159
|
+
/** Seconds the token stays valid, 60–3600. Default 900. */
|
|
160
|
+
expiresIn?: number;
|
|
161
|
+
/** 1–100. Default 1. */
|
|
162
|
+
maxUses?: number;
|
|
163
|
+
}
|
|
164
|
+
interface BlobShareOptions extends RequestOptions {
|
|
165
|
+
/** Seconds, 60 to 30 days. Default 24 hours. */
|
|
166
|
+
expiresIn?: number;
|
|
167
|
+
maxDownloads?: number;
|
|
168
|
+
password?: string;
|
|
169
|
+
}
|
|
170
|
+
/** One folder rule, with camelCase keys (the snake_case wire shape returned by `rules.get()` is accepted too). */
|
|
171
|
+
interface BlobRuleInput {
|
|
172
|
+
visibility?: BlobVisibility;
|
|
173
|
+
expireSeconds?: number;
|
|
174
|
+
maxSize?: number;
|
|
175
|
+
extensions?: string[];
|
|
176
|
+
cacheControl?: string;
|
|
177
|
+
deleteAfterDays?: number;
|
|
178
|
+
}
|
|
179
|
+
type BlobRuleWithPrefix = (BlobRuleInput | RESTPutAPIBlobRuleBody) & {
|
|
180
|
+
prefix: string;
|
|
181
|
+
};
|
|
182
|
+
interface BlobImageOptions {
|
|
183
|
+
width?: number;
|
|
184
|
+
height?: number;
|
|
185
|
+
/** For example `scale-down`, `contain`, `cover`, `crop`, `pad`. */
|
|
186
|
+
fit?: string;
|
|
187
|
+
/** For example `auto`, `webp`, `avif`, `jpeg`, `png`. */
|
|
188
|
+
format?: string;
|
|
189
|
+
/** 1–100. */
|
|
190
|
+
quality?: number;
|
|
191
|
+
}
|
|
192
|
+
type BlobDeleteManyInput = {
|
|
193
|
+
ids: SnowFlake[];
|
|
194
|
+
} | {
|
|
195
|
+
prefix: string;
|
|
196
|
+
};
|
|
197
|
+
declare class BlobClient {
|
|
198
|
+
readonly baseUrl: string;
|
|
199
|
+
private readonly apiKey;
|
|
200
|
+
private readonly fetchImpl;
|
|
201
|
+
private readonly credentials;
|
|
202
|
+
private readonly workspaceId;
|
|
203
|
+
private readonly extraHeaders;
|
|
204
|
+
private readonly partConcurrency;
|
|
205
|
+
private readonly maxRetries;
|
|
206
|
+
private readonly retryDelayMs;
|
|
207
|
+
private readonly timeout;
|
|
208
|
+
private readonly uploadTimeout;
|
|
209
|
+
constructor(options?: BlobClientOptions);
|
|
210
|
+
/**
|
|
211
|
+
* Uploads a file. Up to 5 MB it is one `POST /objects`; above that it starts a direct upload and
|
|
212
|
+
* follows the mode the API picks: one signed PUT, or parts sent in parallel. Returns the object.
|
|
213
|
+
* Aborting `signal` during a direct upload cancels it on the server (best effort).
|
|
214
|
+
*/
|
|
215
|
+
put(path: string, data: BlobData, options?: BlobPutOptions): Promise<APIBlobObject>;
|
|
216
|
+
/** Continues an interrupted direct upload, sending only the parts the server does not have yet. `data` must be the same file. */
|
|
217
|
+
resume(uploadId: SnowFlake, data: BlobData, options?: BlobResumeOptions): Promise<APIBlobObject>;
|
|
218
|
+
/** Direct uploads still in progress. */
|
|
219
|
+
listUploads(options?: RequestOptions): Promise<APIBlobUpload[]>;
|
|
220
|
+
/** Aborts a direct upload and frees its reserved storage. Repeating it is not an error. */
|
|
221
|
+
abortUpload(uploadId: SnowFlake, options?: RequestOptions): Promise<void>;
|
|
222
|
+
private putSimple;
|
|
223
|
+
private transfer;
|
|
224
|
+
private putSingle;
|
|
225
|
+
private putParts;
|
|
226
|
+
/** PUT to a signed URL with exactly the headers the API returned. No credentials are attached. Retried on 5xx and network errors. */
|
|
227
|
+
private putBytes;
|
|
228
|
+
/** One page of objects plus the `folders` found under the prefix, and the `cursor` of the next page (`null` on the last). */
|
|
229
|
+
listPage(options?: BlobListPageOptions): Promise<APIBlobObjectList>;
|
|
230
|
+
/** Iterates every object that matches, fetching pages as needed. */
|
|
231
|
+
list(options?: BlobListOptions): AsyncGenerator<APIBlobObject, void, undefined>;
|
|
232
|
+
get(id: SnowFlake, options?: RequestOptions): Promise<APIBlobObject>;
|
|
233
|
+
update(id: SnowFlake, changes: BlobUpdateChanges, options?: RequestOptions): Promise<APIBlobObject>;
|
|
234
|
+
/** Applies the same changes to any number of objects (sent in batches of 100, the API limit); one result per id, in the order of `ids`. */
|
|
235
|
+
updateMany(ids: SnowFlake[], changes: BlobUpdateChanges, options?: RequestOptions): Promise<APIBlobBatchResult[]>;
|
|
236
|
+
copy(id: SnowFlake, path: string, options?: BlobCopyOptions & {
|
|
237
|
+
move?: boolean;
|
|
238
|
+
}): Promise<APIBlobObject>;
|
|
239
|
+
/** Moves or renames an object; the id stays the same. */
|
|
240
|
+
move(id: SnowFlake, path: string, options?: BlobCopyOptions): Promise<APIBlobObject>;
|
|
241
|
+
delete(id: SnowFlake, options?: RequestOptions): Promise<void>;
|
|
242
|
+
/**
|
|
243
|
+
* Deletes by `ids` or by folder `prefix`, repeating while the API reports `remaining`
|
|
244
|
+
* (it deletes up to 1000 per call). The result merges every round.
|
|
245
|
+
*/
|
|
246
|
+
deleteMany(input: BlobDeleteManyInput, options?: RequestOptions): Promise<APIBlobDeleteResult>;
|
|
247
|
+
/** A temporary download link (`{ url, expires_at }`). It cannot be revoked. */
|
|
248
|
+
downloadUrl(id: SnowFlake, options?: BlobDownloadUrlOptions): Promise<APIBlobDownload>;
|
|
249
|
+
/**
|
|
250
|
+
* Builds an image-transformation URL from a public object (or its public URL). Pure: no request is made.
|
|
251
|
+
* Throws for a private object, which has no public URL.
|
|
252
|
+
*/
|
|
253
|
+
imageUrl(source: Pick<APIBlobObject, "url"> | string, options?: BlobImageOptions): string;
|
|
254
|
+
stats(options?: RequestOptions): Promise<APIBlobStats>;
|
|
255
|
+
/** Creates a token that fixes every constraint you pass; hand it to a browser as `uploadToken`. */
|
|
256
|
+
createUploadToken(options?: BlobUploadTokenOptions): Promise<APIBlobUploadToken>;
|
|
257
|
+
/** S3-compatible credentials derived from the API key, for aws-cli, rclone or boto3. */
|
|
258
|
+
s3Credentials(options?: RequestOptions): Promise<APIBlobS3Credentials>;
|
|
259
|
+
readonly shares: {
|
|
260
|
+
create: (objectId: SnowFlake, options?: BlobShareOptions) => Promise<APIBlobShare>;
|
|
261
|
+
list: (options?: RequestOptions & {
|
|
262
|
+
objectId?: SnowFlake;
|
|
263
|
+
}) => Promise<APIBlobShare[]>;
|
|
264
|
+
revoke: (shareId: SnowFlake, options?: RequestOptions) => Promise<void>;
|
|
265
|
+
};
|
|
266
|
+
readonly rules: {
|
|
267
|
+
get: (options?: RequestOptions) => Promise<APIBlobRules>;
|
|
268
|
+
/** Replaces the whole list. `etag` is the one from the list you read; a stale one fails with `BLOB_RULES_CONFLICT`. */
|
|
269
|
+
set: (rules: BlobRuleWithPrefix[], etag: string, options?: RequestOptions) => Promise<APIBlobRules>;
|
|
270
|
+
/** Creates or changes the rule of one folder; returns the whole list and its new etag. */
|
|
271
|
+
put: (prefix: string, rule: BlobRuleInput | RESTPutAPIBlobRuleBody, options?: RequestOptions) => Promise<APIBlobRules>;
|
|
272
|
+
delete: (prefix: string, options?: RequestOptions) => Promise<APIBlobRules>;
|
|
273
|
+
};
|
|
274
|
+
readonly domains: {
|
|
275
|
+
list: (options?: RequestOptions) => Promise<APIBlobCustomDomain[]>;
|
|
276
|
+
add: (hostname: string, options?: RequestOptions & {
|
|
277
|
+
prefix?: string;
|
|
278
|
+
web_content?: boolean;
|
|
279
|
+
}) => Promise<APIBlobCustomDomain>;
|
|
280
|
+
update: (domainId: SnowFlake, body: RESTPatchAPIBlobDomainBody, options?: RequestOptions) => Promise<APIBlobCustomDomain>;
|
|
281
|
+
verify: (domainId: SnowFlake, options?: RequestOptions) => Promise<APIBlobCustomDomain>;
|
|
282
|
+
remove: (domainId: SnowFlake, options?: RequestOptions) => Promise<void>;
|
|
283
|
+
};
|
|
284
|
+
/** One API call: builds the URL, authenticates, unwraps `{ response }` and turns an error envelope into a `BlobError`. */
|
|
285
|
+
private api;
|
|
286
|
+
/** Sends a request, retrying 5xx and network errors when `req.retry` (never 429). */
|
|
287
|
+
private exec;
|
|
288
|
+
private once;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
declare const VERSION = "0.1.0";
|
|
292
|
+
|
|
293
|
+
export { BlobClient, type BlobClientErrorCode, type BlobClientOptions, type BlobCopyOptions, type BlobData, type BlobDeleteManyInput, type BlobDownloadUrlOptions, BlobError, type BlobErrorBody, type BlobImageOptions, type BlobListOptions, type BlobListPageOptions, type BlobObject, type BlobProgress, type BlobPutOptions, type BlobResumeOptions, type BlobRuleInput, type BlobRuleWithPrefix, type BlobShareOptions, type BlobUpdateChanges, type BlobUploadTokenOptions, type BlobWriteOptions, type FetchLike, type RequestOptions, VERSION };
|