@bigbucket-ai/sdk 0.0.0-stage → 0.2.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 +227 -2
- package/dist/index.d.mts +353 -0
- package/dist/index.d.ts +353 -0
- package/dist/index.js +556 -0
- package/dist/index.mjs +516 -0
- package/package.json +52 -4
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var BigBucketError = class extends Error {
|
|
3
|
+
statusCode;
|
|
4
|
+
code;
|
|
5
|
+
requestId;
|
|
6
|
+
details;
|
|
7
|
+
isRetryable;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
super(options.message);
|
|
10
|
+
this.name = "BigBucketError";
|
|
11
|
+
this.statusCode = options.statusCode ?? 500;
|
|
12
|
+
this.code = options.code ?? "INTERNAL_SERVER_ERROR";
|
|
13
|
+
this.requestId = options.requestId;
|
|
14
|
+
this.details = options.details;
|
|
15
|
+
this.cause = options.cause;
|
|
16
|
+
this.isRetryable = this.statusCode === 429 || this.statusCode >= 500 && this.statusCode <= 599;
|
|
17
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var AuthenticationError = class extends BigBucketError {
|
|
21
|
+
constructor(options) {
|
|
22
|
+
super({ ...options, statusCode: options.statusCode ?? 401 });
|
|
23
|
+
this.name = "AuthenticationError";
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var NotFoundError = class extends BigBucketError {
|
|
27
|
+
constructor(options) {
|
|
28
|
+
super({ ...options, statusCode: 404 });
|
|
29
|
+
this.name = "NotFoundError";
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var PayloadTooLargeError = class extends BigBucketError {
|
|
33
|
+
constructor(options) {
|
|
34
|
+
super({ ...options, statusCode: 413 });
|
|
35
|
+
this.name = "PayloadTooLargeError";
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var UnsupportedFormatError = class extends BigBucketError {
|
|
39
|
+
constructor(options) {
|
|
40
|
+
super({ ...options, statusCode: 415 });
|
|
41
|
+
this.name = "UnsupportedFormatError";
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var RateLimitError = class extends BigBucketError {
|
|
45
|
+
constructor(options) {
|
|
46
|
+
super({ ...options, statusCode: 429 });
|
|
47
|
+
this.name = "RateLimitError";
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
var StorageUploadError = class extends BigBucketError {
|
|
51
|
+
constructor(message, cause) {
|
|
52
|
+
super({
|
|
53
|
+
message,
|
|
54
|
+
statusCode: 502,
|
|
55
|
+
code: "STORAGE_UPLOAD_FAILED",
|
|
56
|
+
cause
|
|
57
|
+
});
|
|
58
|
+
this.name = "StorageUploadError";
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var TimeoutError = class extends BigBucketError {
|
|
62
|
+
constructor(message = "Request timed out") {
|
|
63
|
+
super({
|
|
64
|
+
message,
|
|
65
|
+
statusCode: 408,
|
|
66
|
+
code: "REQUEST_TIMEOUT"
|
|
67
|
+
});
|
|
68
|
+
this.name = "TimeoutError";
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// src/http/transport.ts
|
|
73
|
+
var HttpTransport = class {
|
|
74
|
+
apiKey;
|
|
75
|
+
baseUrl;
|
|
76
|
+
timeout;
|
|
77
|
+
customFetch;
|
|
78
|
+
constructor(config) {
|
|
79
|
+
if (!config.apiKey || typeof config.apiKey !== "string") {
|
|
80
|
+
throw new Error("A valid BigBucket API key is required (e.g. bb_live_...)");
|
|
81
|
+
}
|
|
82
|
+
this.apiKey = config.apiKey.trim();
|
|
83
|
+
this.baseUrl = (config.baseUrl || "http://localhost:8000/api/v1").replace(/\/+$/, "");
|
|
84
|
+
this.timeout = config.timeout ?? 3e4;
|
|
85
|
+
this.customFetch = config.fetch ?? globalThis.fetch;
|
|
86
|
+
if (!this.customFetch) {
|
|
87
|
+
throw new Error("No native fetch implementation found. Pass a custom fetch in options.");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Execute an authenticated request against the BigBucket API.
|
|
92
|
+
*/
|
|
93
|
+
async request(path, options = {}) {
|
|
94
|
+
const url = `${this.baseUrl}${path.startsWith("/") ? "" : "/"}${path}`;
|
|
95
|
+
const headers = {
|
|
96
|
+
Accept: "application/json",
|
|
97
|
+
"X-API-Key": this.apiKey,
|
|
98
|
+
...options.headers
|
|
99
|
+
};
|
|
100
|
+
if (options.body && typeof options.body === "string" && !headers["Content-Type"]) {
|
|
101
|
+
headers["Content-Type"] = "application/json";
|
|
102
|
+
}
|
|
103
|
+
const controller = new AbortController();
|
|
104
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
105
|
+
let response;
|
|
106
|
+
try {
|
|
107
|
+
response = await this.customFetch(url, {
|
|
108
|
+
...options,
|
|
109
|
+
headers,
|
|
110
|
+
signal: controller.signal
|
|
111
|
+
});
|
|
112
|
+
} catch (err) {
|
|
113
|
+
clearTimeout(timeoutId);
|
|
114
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
115
|
+
throw new TimeoutError(`Request timed out after ${this.timeout}ms`);
|
|
116
|
+
}
|
|
117
|
+
throw new BigBucketError({
|
|
118
|
+
message: `Network request failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
119
|
+
statusCode: 0,
|
|
120
|
+
cause: err
|
|
121
|
+
});
|
|
122
|
+
} finally {
|
|
123
|
+
clearTimeout(timeoutId);
|
|
124
|
+
}
|
|
125
|
+
const requestId = response.headers.get("X-Request-ID") ?? void 0;
|
|
126
|
+
let responseBody = null;
|
|
127
|
+
const contentType = response.headers.get("content-type");
|
|
128
|
+
if (contentType && contentType.includes("application/json")) {
|
|
129
|
+
try {
|
|
130
|
+
responseBody = await response.json();
|
|
131
|
+
} catch {
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (!response.ok) {
|
|
135
|
+
const errPayload = responseBody?.error ?? {};
|
|
136
|
+
const message = errPayload.message || `Request failed with status ${response.status}`;
|
|
137
|
+
const code = errPayload.code || "REQUEST_FAILED";
|
|
138
|
+
const details = errPayload.details;
|
|
139
|
+
const errorOptions = {
|
|
140
|
+
message,
|
|
141
|
+
statusCode: response.status,
|
|
142
|
+
code,
|
|
143
|
+
requestId: errPayload.request_id || requestId,
|
|
144
|
+
details
|
|
145
|
+
};
|
|
146
|
+
if (response.status === 401) throw new AuthenticationError(errorOptions);
|
|
147
|
+
if (response.status === 404) throw new NotFoundError(errorOptions);
|
|
148
|
+
if (response.status === 413) throw new PayloadTooLargeError(errorOptions);
|
|
149
|
+
if (response.status === 415) throw new UnsupportedFormatError(errorOptions);
|
|
150
|
+
if (response.status === 429) throw new RateLimitError(errorOptions);
|
|
151
|
+
throw new BigBucketError(errorOptions);
|
|
152
|
+
}
|
|
153
|
+
return responseBody;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Upload binary data directly to the storage provider (Cloudflare R2 or Local Storage).
|
|
157
|
+
* Note: Permanent BigBucket credentials MUST NOT be forwarded to the storage provider.
|
|
158
|
+
*/
|
|
159
|
+
async uploadToPresignedUrl(uploadUrl, method, signedHeaders, body) {
|
|
160
|
+
const controller = new AbortController();
|
|
161
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout * 2);
|
|
162
|
+
try {
|
|
163
|
+
const response = await this.customFetch(uploadUrl, {
|
|
164
|
+
method: method || "PUT",
|
|
165
|
+
headers: signedHeaders,
|
|
166
|
+
body,
|
|
167
|
+
signal: controller.signal
|
|
168
|
+
});
|
|
169
|
+
if (!response.ok) {
|
|
170
|
+
throw new StorageUploadError(
|
|
171
|
+
`Direct storage upload failed with status ${response.status} ${response.statusText}`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
} catch (err) {
|
|
175
|
+
clearTimeout(timeoutId);
|
|
176
|
+
if (err instanceof BigBucketError) {
|
|
177
|
+
throw err;
|
|
178
|
+
}
|
|
179
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
180
|
+
throw new TimeoutError(`Direct storage upload timed out after ${this.timeout * 2}ms`);
|
|
181
|
+
}
|
|
182
|
+
throw new StorageUploadError(
|
|
183
|
+
`Failed to upload image bytes to storage provider: ${err instanceof Error ? err.message : String(err)}`,
|
|
184
|
+
err
|
|
185
|
+
);
|
|
186
|
+
} finally {
|
|
187
|
+
clearTimeout(timeoutId);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
// src/resources/images.ts
|
|
193
|
+
var ImagesResource = class {
|
|
194
|
+
constructor(transport) {
|
|
195
|
+
this.transport = transport;
|
|
196
|
+
}
|
|
197
|
+
transport;
|
|
198
|
+
mapAsset(d) {
|
|
199
|
+
return {
|
|
200
|
+
id: d.id,
|
|
201
|
+
projectId: d.project_id,
|
|
202
|
+
url: d.url,
|
|
203
|
+
originalFilename: d.original_filename,
|
|
204
|
+
mimeType: d.mime_type,
|
|
205
|
+
fileSize: d.file_size,
|
|
206
|
+
width: d.width,
|
|
207
|
+
height: d.height,
|
|
208
|
+
format: d.format,
|
|
209
|
+
status: d.status,
|
|
210
|
+
createdAt: d.created_at,
|
|
211
|
+
updatedAt: d.updated_at,
|
|
212
|
+
variants: (d.variants || []).map((v) => ({
|
|
213
|
+
variantName: v.variant_name,
|
|
214
|
+
url: v.url,
|
|
215
|
+
mimeType: v.mime_type,
|
|
216
|
+
fileSize: v.file_size,
|
|
217
|
+
width: v.width,
|
|
218
|
+
height: v.height,
|
|
219
|
+
format: v.format
|
|
220
|
+
}))
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Retrieve metadata and stable delivery URL for an image.
|
|
225
|
+
*/
|
|
226
|
+
async get(imageId) {
|
|
227
|
+
const res = await this.transport.request(
|
|
228
|
+
`/images/${encodeURIComponent(imageId)}`,
|
|
229
|
+
{
|
|
230
|
+
method: "GET"
|
|
231
|
+
}
|
|
232
|
+
);
|
|
233
|
+
return this.mapAsset(res.data);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* List and paginate media assets belonging to the authenticated project.
|
|
237
|
+
*/
|
|
238
|
+
async list(options = {}) {
|
|
239
|
+
const params = new URLSearchParams();
|
|
240
|
+
if (options.page !== void 0) params.set("page", String(options.page));
|
|
241
|
+
if (options.pageSize !== void 0) params.set("page_size", String(options.pageSize));
|
|
242
|
+
if (options.status !== void 0) params.set("status", options.status);
|
|
243
|
+
if (options.format !== void 0) params.set("format", options.format);
|
|
244
|
+
const query = params.toString() ? `?${params.toString()}` : "";
|
|
245
|
+
const res = await this.transport.request(
|
|
246
|
+
`/images${query}`,
|
|
247
|
+
{
|
|
248
|
+
method: "GET"
|
|
249
|
+
}
|
|
250
|
+
);
|
|
251
|
+
return {
|
|
252
|
+
data: (res.data || []).map((item) => this.mapAsset(item)),
|
|
253
|
+
pagination: {
|
|
254
|
+
total: res.pagination.total,
|
|
255
|
+
page: res.pagination.page,
|
|
256
|
+
pageSize: res.pagination.page_size,
|
|
257
|
+
hasNext: res.pagination.has_next
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Delete an image from storage and mark it deleted in BigBucket.
|
|
263
|
+
*/
|
|
264
|
+
async delete(imageId) {
|
|
265
|
+
const res = await this.transport.request(
|
|
266
|
+
`/images/${encodeURIComponent(imageId)}`,
|
|
267
|
+
{
|
|
268
|
+
method: "DELETE"
|
|
269
|
+
}
|
|
270
|
+
);
|
|
271
|
+
return {
|
|
272
|
+
success: true,
|
|
273
|
+
id: res.data.id
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
// src/resources/uploads.ts
|
|
279
|
+
var UploadsResource = class {
|
|
280
|
+
constructor(transport) {
|
|
281
|
+
this.transport = transport;
|
|
282
|
+
}
|
|
283
|
+
transport;
|
|
284
|
+
/**
|
|
285
|
+
* Request permission and generate a presigned upload URL.
|
|
286
|
+
*/
|
|
287
|
+
async create(options) {
|
|
288
|
+
const res = await this.transport.request("/uploads", {
|
|
289
|
+
method: "POST",
|
|
290
|
+
body: JSON.stringify({
|
|
291
|
+
filename: options.filename,
|
|
292
|
+
content_type: options.contentType,
|
|
293
|
+
file_size: options.fileSize
|
|
294
|
+
})
|
|
295
|
+
});
|
|
296
|
+
const d = res.data;
|
|
297
|
+
return {
|
|
298
|
+
uploadId: d.upload_id,
|
|
299
|
+
objectKey: d.object_key,
|
|
300
|
+
presigned: {
|
|
301
|
+
url: d.presigned.url,
|
|
302
|
+
method: d.presigned.method,
|
|
303
|
+
headers: d.presigned.headers
|
|
304
|
+
},
|
|
305
|
+
expiresAt: d.expires_at
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Finalize an upload session once the client has uploaded bytes to the presigned URL.
|
|
310
|
+
*/
|
|
311
|
+
async complete(uploadId) {
|
|
312
|
+
const res = await this.transport.request(
|
|
313
|
+
`/uploads/${encodeURIComponent(uploadId)}/complete`,
|
|
314
|
+
{
|
|
315
|
+
method: "POST"
|
|
316
|
+
}
|
|
317
|
+
);
|
|
318
|
+
const d = res.data;
|
|
319
|
+
return {
|
|
320
|
+
id: d.id,
|
|
321
|
+
projectId: d.project_id,
|
|
322
|
+
url: d.url,
|
|
323
|
+
originalFilename: d.original_filename,
|
|
324
|
+
mimeType: d.mime_type,
|
|
325
|
+
fileSize: d.file_size,
|
|
326
|
+
width: d.width,
|
|
327
|
+
height: d.height,
|
|
328
|
+
format: d.format,
|
|
329
|
+
status: d.status,
|
|
330
|
+
createdAt: d.created_at,
|
|
331
|
+
updatedAt: d.updated_at,
|
|
332
|
+
variants: (d.variants || []).map((v) => ({
|
|
333
|
+
variantName: v.variant_name,
|
|
334
|
+
url: v.url,
|
|
335
|
+
mimeType: v.mime_type,
|
|
336
|
+
fileSize: v.file_size,
|
|
337
|
+
width: v.width,
|
|
338
|
+
height: v.height,
|
|
339
|
+
format: v.format
|
|
340
|
+
}))
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Check the status of an ongoing or completed upload session.
|
|
345
|
+
*/
|
|
346
|
+
async get(uploadId) {
|
|
347
|
+
const res = await this.transport.request(
|
|
348
|
+
`/uploads/${encodeURIComponent(uploadId)}`,
|
|
349
|
+
{
|
|
350
|
+
method: "GET"
|
|
351
|
+
}
|
|
352
|
+
);
|
|
353
|
+
const d = res.data;
|
|
354
|
+
return {
|
|
355
|
+
id: d.id,
|
|
356
|
+
projectId: d.project_id,
|
|
357
|
+
objectKey: d.object_key,
|
|
358
|
+
expectedFileSize: d.expected_file_size,
|
|
359
|
+
expectedMimeType: d.expected_mime_type,
|
|
360
|
+
status: d.status,
|
|
361
|
+
expiresAt: d.expires_at,
|
|
362
|
+
createdAt: d.created_at,
|
|
363
|
+
completedAt: d.completed_at ?? null,
|
|
364
|
+
assetId: d.asset_id ?? null
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
// src/resources/usage.ts
|
|
370
|
+
var UsageResource = class {
|
|
371
|
+
constructor(transport) {
|
|
372
|
+
this.transport = transport;
|
|
373
|
+
}
|
|
374
|
+
transport;
|
|
375
|
+
/**
|
|
376
|
+
* Retrieve usage metrics for a project or the account.
|
|
377
|
+
*/
|
|
378
|
+
async get(projectId) {
|
|
379
|
+
const path = projectId ? `/projects/${encodeURIComponent(projectId)}/usage` : "/usage";
|
|
380
|
+
const res = await this.transport.request(path, {
|
|
381
|
+
method: "GET"
|
|
382
|
+
});
|
|
383
|
+
const d = res.data;
|
|
384
|
+
return {
|
|
385
|
+
totalStoredBytes: d.total_stored_bytes,
|
|
386
|
+
totalReadyImages: d.total_ready_images,
|
|
387
|
+
successfulUploads: d.successful_uploads,
|
|
388
|
+
deletedImages: d.deleted_images
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
// src/transform.ts
|
|
394
|
+
function buildTransformUrl(baseUrl, options) {
|
|
395
|
+
if (!baseUrl) return "";
|
|
396
|
+
if (!options || Object.keys(options).length === 0) return baseUrl;
|
|
397
|
+
const url = new URL(baseUrl);
|
|
398
|
+
if (options.tr) {
|
|
399
|
+
url.searchParams.set("tr", options.tr);
|
|
400
|
+
}
|
|
401
|
+
const w = options.width ?? options.w;
|
|
402
|
+
if (w !== void 0) {
|
|
403
|
+
url.searchParams.set("w", String(w));
|
|
404
|
+
}
|
|
405
|
+
const h = options.height ?? options.h;
|
|
406
|
+
if (h !== void 0) {
|
|
407
|
+
url.searchParams.set("h", String(h));
|
|
408
|
+
}
|
|
409
|
+
if (options.fit) {
|
|
410
|
+
url.searchParams.set("fit", options.fit);
|
|
411
|
+
}
|
|
412
|
+
const q = options.quality ?? options.q;
|
|
413
|
+
if (q !== void 0) {
|
|
414
|
+
url.searchParams.set("q", String(q));
|
|
415
|
+
}
|
|
416
|
+
const fmt = options.format ?? options.fmt;
|
|
417
|
+
if (fmt) {
|
|
418
|
+
url.searchParams.set("fmt", fmt);
|
|
419
|
+
}
|
|
420
|
+
return url.toString();
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// src/client.ts
|
|
424
|
+
var BigBucket = class {
|
|
425
|
+
transport;
|
|
426
|
+
images;
|
|
427
|
+
uploads;
|
|
428
|
+
usage;
|
|
429
|
+
constructor(options) {
|
|
430
|
+
this.transport = new HttpTransport({
|
|
431
|
+
apiKey: options.apiKey,
|
|
432
|
+
baseUrl: options.baseUrl,
|
|
433
|
+
timeout: options.timeout,
|
|
434
|
+
fetch: options.fetch
|
|
435
|
+
});
|
|
436
|
+
this.images = new ImagesResource(this.transport);
|
|
437
|
+
this.uploads = new UploadsResource(this.transport);
|
|
438
|
+
this.usage = new UsageResource(this.transport);
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Helper method to normalize arbitrary input types (Buffer, Uint8Array, Blob, etc.)
|
|
442
|
+
* and resolve byte length.
|
|
443
|
+
*/
|
|
444
|
+
resolveFileData(file, explicitSize) {
|
|
445
|
+
if (typeof Blob !== "undefined" && file instanceof Blob) {
|
|
446
|
+
return { body: file, size: explicitSize ?? file.size };
|
|
447
|
+
}
|
|
448
|
+
if (file instanceof ArrayBuffer) {
|
|
449
|
+
return { body: file, size: explicitSize ?? file.byteLength };
|
|
450
|
+
}
|
|
451
|
+
if (file instanceof Uint8Array) {
|
|
452
|
+
return { body: file, size: explicitSize ?? file.byteLength };
|
|
453
|
+
}
|
|
454
|
+
if (typeof file === "object" && file !== null && "buffer" in file && file.buffer instanceof ArrayBuffer) {
|
|
455
|
+
const buffer = file.buffer;
|
|
456
|
+
return { body: buffer, size: explicitSize ?? buffer.byteLength };
|
|
457
|
+
}
|
|
458
|
+
if (typeof file === "string") {
|
|
459
|
+
const encoded = new TextEncoder().encode(file);
|
|
460
|
+
return { body: encoded, size: explicitSize ?? encoded.byteLength };
|
|
461
|
+
}
|
|
462
|
+
if (explicitSize !== void 0) {
|
|
463
|
+
return { body: file, size: explicitSize };
|
|
464
|
+
}
|
|
465
|
+
throw new Error(
|
|
466
|
+
"Unable to determine file size. Please provide 'options.fileSize' explicitly."
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Complete end-to-end image upload workflow:
|
|
471
|
+
* 1. Requests an upload session and receives presigned storage URL.
|
|
472
|
+
* 2. Uploads binary data directly to the storage provider (Cloudflare R2).
|
|
473
|
+
* 3. Finalizes the upload with server verification and content inspection.
|
|
474
|
+
* 4. Returns verified ImageAsset with delivery URL.
|
|
475
|
+
*/
|
|
476
|
+
async upload(file, options) {
|
|
477
|
+
const { body, size } = this.resolveFileData(file, options.fileSize);
|
|
478
|
+
const session = await this.uploads.create({
|
|
479
|
+
filename: options.filename,
|
|
480
|
+
contentType: options.contentType,
|
|
481
|
+
fileSize: size
|
|
482
|
+
});
|
|
483
|
+
await this.transport.uploadToPresignedUrl(
|
|
484
|
+
session.presigned.url,
|
|
485
|
+
session.presigned.method,
|
|
486
|
+
session.presigned.headers,
|
|
487
|
+
body
|
|
488
|
+
);
|
|
489
|
+
return await this.uploads.complete(session.uploadId);
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Helper method to generate an optimized, transformed image delivery URL.
|
|
493
|
+
*
|
|
494
|
+
* @param baseUrl The original delivery URL of the image asset.
|
|
495
|
+
* @param options Dynamic transformation parameters (width, height, quality, format, or Zepto shorthand).
|
|
496
|
+
*/
|
|
497
|
+
transformUrl(baseUrl, options) {
|
|
498
|
+
return buildTransformUrl(baseUrl, options);
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
export {
|
|
502
|
+
AuthenticationError,
|
|
503
|
+
BigBucket,
|
|
504
|
+
BigBucketError,
|
|
505
|
+
HttpTransport,
|
|
506
|
+
ImagesResource,
|
|
507
|
+
NotFoundError,
|
|
508
|
+
PayloadTooLargeError,
|
|
509
|
+
RateLimitError,
|
|
510
|
+
StorageUploadError,
|
|
511
|
+
TimeoutError,
|
|
512
|
+
UnsupportedFormatError,
|
|
513
|
+
UploadsResource,
|
|
514
|
+
UsageResource,
|
|
515
|
+
buildTransformUrl
|
|
516
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,54 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bigbucket-ai/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Official TypeScript/JavaScript SDK for the BigBucket Image Storage and Management Platform",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md",
|
|
23
|
+
"LICENSE"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"type-check": "tsc --noEmit",
|
|
29
|
+
"lint": "eslint src/ --ext .ts"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"bigbucket",
|
|
33
|
+
"image-storage",
|
|
34
|
+
"image-upload",
|
|
35
|
+
"r2",
|
|
36
|
+
"cloudflare-r2",
|
|
37
|
+
"fastapi",
|
|
38
|
+
"sdk"
|
|
39
|
+
],
|
|
40
|
+
"author": "BigBucket Team",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18.0.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^20.14.0",
|
|
50
|
+
"tsup": "^8.1.0",
|
|
51
|
+
"typescript": "^5.4.5",
|
|
52
|
+
"vitest": "^1.6.0"
|
|
53
|
+
}
|
|
54
|
+
}
|