@calmlens/sdk 0.12.0 → 0.13.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.
Files changed (35) hide show
  1. package/README.md +14 -1
  2. package/cjs/CalmLensConnection-DzRDCMOP.js +233 -0
  3. package/cjs/CalmLensUtils-vX5H_vMn.js +699 -0
  4. package/cjs/{CalmLensError-CKwMKV0S.js → CalmLensVersion-DjhsJ1gj.js} +48 -0
  5. package/cjs/{CalmLensWebhooks-BTPxKvcD.js → CalmLensWebhooks-hVquX5L1.js} +9 -9
  6. package/cjs/{WebhookPayload-Cgb32aSH.d.ts → WebhookPayload-B7CgSmI5.d.ts} +4996 -3255
  7. package/cjs/app.d.ts +3 -3
  8. package/cjs/app.js +10 -10
  9. package/cjs/{index-BgmWj3KL.d.ts → index-BywTQbRq.d.ts} +3 -1
  10. package/cjs/index.d.ts +3 -3
  11. package/cjs/index.js +4 -5
  12. package/cjs/server.d.ts +12 -4
  13. package/cjs/server.js +31 -18
  14. package/cjs/testing.d.ts +6 -1
  15. package/cjs/testing.js +91 -73
  16. package/esm/CalmLensConnection-D8VsTdsA.js +192 -0
  17. package/esm/{CalmLensUtils-Cx32j2zt.js → CalmLensUtils-B4i3Z2He.js} +316 -2
  18. package/esm/{CalmLensError-CihGG26K.js → CalmLensVersion-DK4BMEST.js} +25 -1
  19. package/esm/{CalmLensWebhooks-DShmAal4.js → CalmLensWebhooks-DyCoEvpf.js} +2 -2
  20. package/esm/{WebhookPayload-Cgb32aSH.d.ts → WebhookPayload-B7CgSmI5.d.ts} +4996 -3255
  21. package/esm/app.d.ts +3 -3
  22. package/esm/app.js +4 -4
  23. package/esm/{index-BgmWj3KL.d.ts → index-BywTQbRq.d.ts} +3 -1
  24. package/esm/index.d.ts +3 -3
  25. package/esm/index.js +1 -3
  26. package/esm/server.d.ts +12 -4
  27. package/esm/server.js +20 -7
  28. package/esm/testing.d.ts +6 -1
  29. package/esm/testing.js +59 -41
  30. package/package.json +1 -1
  31. package/cjs/CalmLensConnection-CYtBP-vu.js +0 -516
  32. package/cjs/CalmLensUtils-Dg3s4loH.js +0 -367
  33. package/cjs/src-Dsc8Pn6v.js +0 -45
  34. package/esm/CalmLensConnection-wLNy0OIP.js +0 -475
  35. package/esm/src-CJhrILvM.js +0 -22
@@ -1,516 +0,0 @@
1
- const require_CalmLensError = require("./CalmLensError-CKwMKV0S.js");
2
- const require_src = require("./src-Dsc8Pn6v.js");
3
- const require_CalmLensUtils = require("./CalmLensUtils-Dg3s4loH.js");
4
- //#region src/client/CalmLensTransport.ts
5
- /** Retry delays grow from this base, doubling per attempt, with jitter. */
6
- const RETRY_BASE_DELAY_MS = 500;
7
- const RETRY_MAX_DELAY_MS = 8e3;
8
- /** A `Retry-After` longer than this is returned to the caller instead of waited out. */
9
- const RETRY_AFTER_MAX_MS = 6e4;
10
- const RETRYABLE_STATUSES = /* @__PURE__ */ new Set([
11
- 429,
12
- 502,
13
- 503,
14
- 504
15
- ]);
16
- const timeoutReason = () => {
17
- const reason = /* @__PURE__ */ new Error("The operation timed out.");
18
- reason.name = "TimeoutError";
19
- return reason;
20
- };
21
- /**
22
- * Links the callers' signals and a per-attempt deadline. `AbortSignal.any` holds its sources
23
- * weakly, so a long-lived caller signal doesn't collect a listener per streamed response;
24
- * runtimes without it get explicit listeners that `release` removes.
25
- */
26
- const createAttemptSignal = (signals, timeoutMs) => {
27
- const callers = signals.filter((signal) => signal !== void 0);
28
- const deadline = new AbortController();
29
- let timedOut = false;
30
- let signal;
31
- let onAbort;
32
- if (typeof AbortSignal.any === "function") signal = AbortSignal.any([...callers, deadline.signal]);
33
- else {
34
- const controller = new AbortController();
35
- signal = controller.signal;
36
- onAbort = (event) => controller.abort(event.target.reason);
37
- for (const source of [...callers, deadline.signal]) if (source.aborted) controller.abort(source.reason);
38
- else source.addEventListener("abort", onAbort, { once: true });
39
- }
40
- let timer = timeoutMs === void 0 ? void 0 : setTimeout(() => {
41
- timedOut = true;
42
- deadline.abort(timeoutReason());
43
- }, timeoutMs);
44
- return {
45
- signal,
46
- isTimedOut: () => timedOut,
47
- isCancelled: () => callers.some((caller) => caller.aborted),
48
- clearDeadline: () => {
49
- if (timer !== void 0) clearTimeout(timer);
50
- timer = void 0;
51
- },
52
- release: () => {
53
- if (timer !== void 0) clearTimeout(timer);
54
- timer = void 0;
55
- if (onAbort) for (const caller of callers) caller.removeEventListener("abort", onAbort);
56
- }
57
- };
58
- };
59
- /**
60
- * A redirect the SDK must not follow: it would send the API key to another origin. Browsers report
61
- * a manual redirect as an opaque response; other runtimes return the 3xx with its Location.
62
- */
63
- const isRedirect = (response) => response.type === "opaqueredirect" || response.status >= 300 && response.status < 400 && response.headers.has("location");
64
- /** Turns anything thrown while sending or reading a request into a `CalmLensError`. */
65
- const toFailure = (cause, attempt) => {
66
- if (require_CalmLensError.CalmLensError.isCalmLensError(cause)) return cause;
67
- if (attempt.isCancelled()) return new require_CalmLensError.CalmLensError(require_CalmLensError.SDK_ERROR_CODES.CANCELLED, {
68
- message: "Request cancelled",
69
- cause
70
- });
71
- if (attempt.isTimedOut()) return new require_CalmLensError.CalmLensError(require_CalmLensError.SDK_ERROR_CODES.TIMEOUT, {
72
- message: "Request timed out",
73
- cause
74
- });
75
- return new require_CalmLensError.CalmLensError(require_CalmLensError.SDK_ERROR_CODES.TRANSPORT_ERROR, {
76
- message: "Request failed",
77
- cause
78
- });
79
- };
80
- const sleep = (ms, signal) => new Promise((resolve, reject) => {
81
- if (signal?.aborted) {
82
- reject(new require_CalmLensError.CalmLensError(require_CalmLensError.SDK_ERROR_CODES.CANCELLED, { message: "Request cancelled" }));
83
- return;
84
- }
85
- const onAbort = () => {
86
- clearTimeout(timer);
87
- reject(new require_CalmLensError.CalmLensError(require_CalmLensError.SDK_ERROR_CODES.CANCELLED, { message: "Request cancelled" }));
88
- };
89
- const timer = setTimeout(() => {
90
- signal?.removeEventListener("abort", onAbort);
91
- resolve();
92
- }, ms);
93
- signal?.addEventListener("abort", onAbort, { once: true });
94
- });
95
- /** Exponential backoff with jitter: half the delay is fixed, the other half random. */
96
- const getRetryDelayMs = (attempt, random = Math.random) => {
97
- const delay = Math.min(RETRY_MAX_DELAY_MS, RETRY_BASE_DELAY_MS * 2 ** attempt);
98
- return Math.round(delay / 2 + random() * (delay / 2));
99
- };
100
- /** Parses `Retry-After` as seconds or an HTTP date, in seconds from `now`. */
101
- const parseRetryAfter = (value, now = Date.now()) => {
102
- if (!value) return void 0;
103
- const trimmed = value.trim();
104
- if (/^\d+$/.test(trimmed)) return Number(trimmed);
105
- const date = Date.parse(trimmed);
106
- if (Number.isNaN(date)) return void 0;
107
- return Math.max(0, Math.ceil((date - now) / 1e3));
108
- };
109
- /** Bodies that can be sent again unchanged. Streams are consumed by the first attempt. */
110
- const isReplayableBody = (body) => body === void 0 || body === null || typeof body === "string" || body instanceof Blob || body instanceof ArrayBuffer || ArrayBuffer.isView(body) || body instanceof URLSearchParams;
111
- const isApiErrorPayload = (value) => !!value && typeof value === "object" && typeof value.code === "string";
112
- /** Reads at most `limit` bytes of a body, failing with `sdk/response-too-large` beyond that. */
113
- const readBody = async (response, limit) => {
114
- const declared = Number(response.headers.get("content-length"));
115
- const tooLarge = () => new require_CalmLensError.CalmLensError(require_CalmLensError.SDK_ERROR_CODES.RESPONSE_TOO_LARGE, {
116
- message: `Response body exceeds ${limit} bytes`,
117
- status: response.status,
118
- requestId: response.headers.get("x-request-id") ?? void 0,
119
- headers: response.headers
120
- });
121
- if (Number.isFinite(declared) && declared > limit) {
122
- await response.body?.cancel().catch(() => {});
123
- throw tooLarge();
124
- }
125
- if (!response.body) return /* @__PURE__ */ new Uint8Array(0);
126
- const reader = response.body.getReader();
127
- const chunks = [];
128
- let total = 0;
129
- for (;;) {
130
- const { done, value } = await reader.read();
131
- if (done) break;
132
- total += value.byteLength;
133
- if (total > limit) {
134
- await reader.cancel().catch(() => {});
135
- throw tooLarge();
136
- }
137
- chunks.push(value);
138
- }
139
- const bytes = new Uint8Array(total);
140
- let offset = 0;
141
- for (const chunk of chunks) {
142
- bytes.set(chunk, offset);
143
- offset += chunk.byteLength;
144
- }
145
- return bytes;
146
- };
147
- const responseInfo = (response) => ({
148
- status: response.status,
149
- requestId: response.headers.get("x-request-id") ?? void 0,
150
- headers: response.headers,
151
- retryAfter: parseRetryAfter(response.headers.get("retry-after"))
152
- });
153
- /** The `CalmLensError` for a non-2xx response whose body has been read. */
154
- const toHttpError = (response, bytes) => {
155
- let data;
156
- try {
157
- data = JSON.parse(new TextDecoder().decode(bytes));
158
- } catch {}
159
- if (isApiErrorPayload(data)) {
160
- const { code, message, details, traceId } = data;
161
- return new require_CalmLensError.CalmLensError(code, {
162
- message: message ?? code,
163
- ...responseInfo(response),
164
- details: details || traceId ? {
165
- ...details,
166
- ...traceId ? { traceId } : {}
167
- } : void 0
168
- });
169
- }
170
- return new require_CalmLensError.CalmLensError(require_CalmLensError.SDK_ERROR_CODES.HTTP_ERROR, {
171
- message: `HTTP ${response.status}`,
172
- ...responseInfo(response)
173
- });
174
- };
175
- /** Sends requests with the client's credentials, deadlines, retries and response limits. */
176
- var CalmLensTransport = class {
177
- constructor(settings) {
178
- this.settings = settings;
179
- }
180
- headersFor(request) {
181
- const headers = new Headers(request.init?.headers);
182
- for (const [name, value] of Object.entries(request.headers ?? {})) headers.set(name, value);
183
- if (!headers.has("accept") && request.deadline === "body") headers.set("accept", "application/json");
184
- if (this.settings.apiKey) headers.set("x-api-key", this.settings.apiKey);
185
- if (!require_src.isBrowserRuntime()) headers.set("user-agent", require_src.getUserAgent());
186
- if (request.idempotencyKey) headers.set("idempotency-key", request.idempotencyKey);
187
- return Object.fromEntries(headers.entries());
188
- }
189
- canRetry(request) {
190
- return this.settings.maxRetries > 0 && (request.method === "GET" || request.method === "HEAD" || !!request.idempotencyKey) && isReplayableBody(request.body);
191
- }
192
- /**
193
- * Sends a request and returns the response, retrying transport failures, 429, 502–504 and
194
- * `idempotency/request-in-progress` when the request is safe to repeat. Non-2xx responses
195
- * throw unless `allowHttpErrors` is set. Call `release` once the body has been read.
196
- */
197
- async send(request, { allowHttpErrors = false } = {}) {
198
- const fetchImpl = request.fetch ?? this.settings.fetch;
199
- const retryable = this.canRetry(request);
200
- const headers = this.headersFor(request);
201
- for (let attemptNumber = 0;; attemptNumber++) {
202
- const canRetryAgain = retryable && attemptNumber < this.settings.maxRetries;
203
- const attempt = createAttemptSignal([this.settings.signal, request.init?.signal ?? void 0], request.timeoutMs);
204
- let response;
205
- try {
206
- if (attempt.signal.aborted) throw attempt.signal.reason;
207
- response = await fetchImpl(request.url, {
208
- ...request.init,
209
- method: request.method,
210
- headers,
211
- body: request.body,
212
- redirect: "manual",
213
- signal: attempt.signal,
214
- duplex: "half"
215
- });
216
- if (isRedirect(response)) {
217
- await response.body?.cancel().catch(() => {});
218
- throw new require_CalmLensError.CalmLensError(require_CalmLensError.SDK_ERROR_CODES.TRANSPORT_ERROR, { message: `Unexpected redirect (HTTP ${response.status})` });
219
- }
220
- } catch (cause) {
221
- attempt.release();
222
- const failure = toFailure(cause, attempt);
223
- if (canRetryAgain && failure.code === require_CalmLensError.SDK_ERROR_CODES.TRANSPORT_ERROR) {
224
- await sleep(getRetryDelayMs(attemptNumber), this.settings.signal);
225
- continue;
226
- }
227
- throw failure;
228
- }
229
- if (request.deadline === "headers") attempt.clearDeadline();
230
- if (response.ok) return {
231
- response,
232
- attempt
233
- };
234
- if (allowHttpErrors) {
235
- const retryAfter = parseRetryAfter(response.headers.get("retry-after"));
236
- const delayMs = retryAfter !== void 0 ? retryAfter * 1e3 : getRetryDelayMs(attemptNumber);
237
- if (!canRetryAgain || !RETRYABLE_STATUSES.has(response.status) || delayMs > RETRY_AFTER_MAX_MS) return {
238
- response,
239
- attempt
240
- };
241
- attempt.release();
242
- await response.body?.cancel().catch(() => {});
243
- await sleep(delayMs, this.settings.signal);
244
- continue;
245
- }
246
- let error;
247
- try {
248
- error = toHttpError(response, await readBody(response, this.settings.maxResponseBytes));
249
- } catch (cause) {
250
- error = toFailure(cause, attempt);
251
- } finally {
252
- attempt.release();
253
- }
254
- const retryDelayMs = error.retryAfter !== void 0 ? error.retryAfter * 1e3 : getRetryDelayMs(attemptNumber);
255
- if (canRetryAgain && retryDelayMs <= RETRY_AFTER_MAX_MS && (error.status !== void 0 && RETRYABLE_STATUSES.has(error.status) || error.code === require_CalmLensError.API_ERROR_CODES.IDEMPOTENT_REQUEST_IN_PROGRESS)) {
256
- await sleep(retryDelayMs, this.settings.signal);
257
- continue;
258
- }
259
- throw error;
260
- }
261
- }
262
- /** Sends a request and parses its JSON response body. */
263
- async json(request) {
264
- const { response, attempt } = await this.send(request);
265
- try {
266
- const bytes = await readBody(response, this.settings.maxResponseBytes);
267
- if (bytes.byteLength === 0 && (response.status === 204 || request.method === "DELETE")) return;
268
- try {
269
- return JSON.parse(new TextDecoder().decode(bytes));
270
- } catch (cause) {
271
- throw new require_CalmLensError.CalmLensError(require_CalmLensError.SDK_ERROR_CODES.INVALID_RESPONSE, {
272
- message: `Invalid JSON response (HTTP ${response.status})`,
273
- ...responseInfo(response),
274
- cause
275
- });
276
- }
277
- } catch (cause) {
278
- throw toFailure(cause, attempt);
279
- } finally {
280
- attempt.release();
281
- }
282
- }
283
- };
284
- //#endregion
285
- //#region src/client/CalmLensConnection.ts
286
- const DEFAULT_TIMEOUT_MS = 12e4;
287
- const DEFAULT_MAX_RETRIES = 2;
288
- const DEFAULT_MAX_RESPONSE_BYTES = 33554432;
289
- /**
290
- * Bytes as a fetch body. They're sent as they are rather than in a Blob: React Native can't
291
- * build a Blob from bytes, and every fetch accepts a Uint8Array.
292
- */
293
- const toBodyBytes = (value) => value.buffer instanceof ArrayBuffer ? value : Uint8Array.from(value);
294
- const toRawUploadBody = (payload) => {
295
- const data = require_CalmLensUtils.assetToData(payload);
296
- if (data instanceof Response) {
297
- if (!data.body) throw new require_CalmLensError.CalmLensError(require_CalmLensError.API_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Response upload data must have a body" });
298
- return data.body;
299
- }
300
- if (data instanceof ArrayBuffer || data instanceof Blob) return data;
301
- if ("getReader" in data) return data;
302
- return toBodyBytes(data);
303
- };
304
- const setOptionalQueryValue = (params, key, value) => {
305
- if (value !== void 0 && value !== null) params.set(key, typeof value === "string" ? value : JSON.stringify(value));
306
- };
307
- const assertValidUploadMimeType = (mimeType) => {
308
- if (require_CalmLensUtils.isRejectedUploadMimeType(mimeType)) throw new require_CalmLensError.CalmLensError(require_CalmLensError.API_ERROR_CODES.INVALID_UPLOAD_MIME_TYPE, {
309
- message: require_CalmLensUtils.getRejectedUploadMimeTypeError(mimeType),
310
- details: { mimeType }
311
- });
312
- };
313
- const isImageMimeType = (mimeType) => mimeType.toLowerCase().startsWith("image/");
314
- const invalidPayload = (message) => new require_CalmLensError.CalmLensError(require_CalmLensError.API_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message });
315
- /** Checks upload options before anything is sent. */
316
- const prepareSubmitAssetOptions = (options) => {
317
- if (!options || typeof options !== "object") throw require_CalmLensError.invalidArgument("Asset options are required");
318
- if (!("content" in options) && !("url" in options) && !("part" in options)) throw invalidPayload("Either file content, URL, or multipart part is required");
319
- if (!options.name) throw invalidPayload("Asset name is required");
320
- if (!("part" in options) && "isFinal" in options) throw invalidPayload("isFinal is only valid for multipart uploads");
321
- if ("part" in options && options.part.partNumber && options.part.partNumber > 1) throw new require_CalmLensError.CalmLensError(require_CalmLensError.API_ERROR_CODES.USE_UPLOAD_PART, { message: "Use uploadPart for multipart upload parts after the first part" });
322
- if ("content" in options) {
323
- assertValidUploadMimeType(options.content.type);
324
- if (!("plainText" in options.content)) {
325
- const validation = require_CalmLensUtils.validateAssetPayload(options.content);
326
- if (!validation.ok) throw invalidPayload(validation.error);
327
- }
328
- }
329
- if ("part" in options) {
330
- assertValidUploadMimeType(options.part.type);
331
- const partSizeInBytes = options.part.sizeInBytes ?? require_CalmLensUtils.getAssetPayloadByteLength(options.part);
332
- if (isImageMimeType(options.part.type) && partSizeInBytes !== void 0) {
333
- if (partSizeInBytes > require_CalmLensUtils.MAX_IMAGE_UPLOAD_BYTES) throw new require_CalmLensError.CalmLensError(require_CalmLensError.API_ERROR_CODES.MULTIPART_IMAGE_TOO_LARGE, { message: "Multipart image uploads cannot exceed 20MB." });
334
- if (options.part.isFinal && partSizeInBytes < require_CalmLensUtils.MIN_MULTIPART_IMAGE_UPLOAD_BYTES) throw new require_CalmLensError.CalmLensError(require_CalmLensError.API_ERROR_CODES.MULTIPART_IMAGE_TOO_SMALL, { message: "Multipart image uploads must total at least 10MB." });
335
- }
336
- const validation = require_CalmLensUtils.validateAssetPayload(options.part, {
337
- multipart: true,
338
- isFinal: options.part.isFinal
339
- });
340
- if (!validation.ok) throw invalidPayload(validation.error);
341
- }
342
- return options;
343
- };
344
- const newIdempotencyKey = () => require_CalmLensUtils.randomUuid();
345
- /** Text content is small, so it keeps the API deadline; binary files may be arbitrarily large. */
346
- const isTextPayload = (payload) => "plainText" in payload;
347
- const isAsset = (data) => !!data && typeof data === "object" && typeof data.id === "string" && !!data.id && typeof data.status === "string";
348
- const isUploadedAsset = (data) => !!data && typeof data === "object" && typeof data.id === "string" && !!data.id;
349
- const expectUploadedAsset = (data) => {
350
- if (!isUploadedAsset(data)) throw new require_CalmLensError.CalmLensError(require_CalmLensError.SDK_ERROR_CODES.INVALID_RESPONSE, {
351
- message: "Expected an uploaded asset response",
352
- status: 200
353
- });
354
- return data;
355
- };
356
- const expectAsset = (data) => {
357
- if (!isAsset(data)) throw new require_CalmLensError.CalmLensError(require_CalmLensError.SDK_ERROR_CODES.INVALID_RESPONSE, {
358
- message: "Expected an asset response",
359
- status: 200
360
- });
361
- return data;
362
- };
363
- /** Fills in the default API base URL and drops trailing slashes. */
364
- const resolveConnectionOptions = (options) => ({
365
- ...options,
366
- baseUrl: (options.baseUrl ?? `https://api.calmlens.com/v1`).replace(/\/+$/, "")
367
- });
368
- /** One client's transport, base URL and deadlines, and the requests both clients make. */
369
- var CalmLensConnection = class {
370
- constructor(options, apiKey) {
371
- this.options = options;
372
- const resolveFetch = () => {
373
- const fetchImpl = this.options.fetch ?? globalThis.fetch;
374
- if (typeof fetchImpl !== "function") throw new require_CalmLensError.CalmLensError(require_CalmLensError.SDK_ERROR_CODES.NO_FETCH, { message: "No fetch implementation is available; pass one as the fetch option" });
375
- return fetchImpl;
376
- };
377
- this.transport = new CalmLensTransport({
378
- apiKey,
379
- fetch: ((input, init) => resolveFetch()(input, init)),
380
- signal: options.signal,
381
- maxRetries: options.maxRetries ?? DEFAULT_MAX_RETRIES,
382
- maxResponseBytes: options.maxResponseBytes ?? DEFAULT_MAX_RESPONSE_BYTES
383
- });
384
- }
385
- get timeoutMs() {
386
- return this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
387
- }
388
- url(path, query) {
389
- const search = query ? require_CalmLensUtils.stringifyQuery(query) : "";
390
- return `${this.options.baseUrl}${path}${search ? `?${search}` : ""}`;
391
- }
392
- /** A JSON request whose deadline covers reading the response. */
393
- json(method, path, { query, body, headers, idempotencyKey } = {}) {
394
- return this.transport.json({
395
- method,
396
- url: this.url(path, query),
397
- headers: body === void 0 ? headers : {
398
- ...headers,
399
- "Content-Type": "application/json"
400
- },
401
- body: body === void 0 ? void 0 : JSON.stringify(body),
402
- idempotencyKey,
403
- timeoutMs: this.timeoutMs,
404
- deadline: "body"
405
- });
406
- }
407
- upload(url, payload, headers, idempotencyKey) {
408
- return this.transport.json({
409
- method: "POST",
410
- url,
411
- headers,
412
- body: toRawUploadBody(payload),
413
- idempotencyKey,
414
- timeoutMs: isTextPayload(payload) ? this.timeoutMs : this.options.uploadTimeoutMs,
415
- deadline: "body",
416
- fetch: this.options.uploadFetch
417
- });
418
- }
419
- /**
420
- * Uploads file content or a first multipart part to `uploadsPath` (`.../assets`), as raw
421
- * bytes with the options in the query.
422
- */
423
- submitRawUpload(uploadsPath, options, queue, authHeaders = {}) {
424
- const query = new URLSearchParams();
425
- query.set("name", options.name);
426
- query.set("queue", String(queue));
427
- setOptionalQueryValue(query, "description", options.description);
428
- setOptionalQueryValue(query, "processingOptions", options.processingOptions);
429
- setOptionalQueryValue(query, "visibility", options.visibility);
430
- setOptionalQueryValue(query, "metadata", options.metadata);
431
- setOptionalQueryValue(query, "externalId", options.externalId);
432
- setOptionalQueryValue(query, "externalUrl", options.externalUrl);
433
- setOptionalQueryValue(query, "folderId", options.folderId);
434
- setOptionalQueryValue(query, "uploadPresetId", options.uploadPresetId);
435
- const isMultipart = "part" in options;
436
- const payload = isMultipart ? options.part : options.content;
437
- query.set("contentType", payload.type);
438
- setOptionalQueryValue(query, "sizeInBytes", payload.sizeInBytes ?? require_CalmLensUtils.getAssetPayloadByteLength(payload));
439
- if (isMultipart) {
440
- const part = payload;
441
- const multipartOptions = options;
442
- query.set("partNumber", String(part.partNumber ?? 1));
443
- query.set("isFinal", String(part.isFinal ?? false));
444
- setOptionalQueryValue(query, "sizeInBytes", part.sizeInBytes ?? multipartOptions.sizeInBytes);
445
- setOptionalQueryValue(query, "totalSizeInBytes", multipartOptions.totalSizeInBytes);
446
- }
447
- const path = isMultipart ? "multipart-upload" : "upload";
448
- return this.upload(this.url(`${uploadsPath}/${path}?${query}`), payload, {
449
- ...authHeaders,
450
- "Content-Type": payload.type,
451
- "X-CalmLens-Upload": isMultipart ? "part" : "content"
452
- }, options.idempotencyKey ?? newIdempotencyKey());
453
- }
454
- /** Uploads the next part of a multipart upload to `partPath` (`.../assets/{id}/part`). */
455
- uploadPart(partPath, { part, queue, idempotencyKey }, authHeaders = {}) {
456
- if (!part) throw require_CalmLensError.invalidArgument("Part options are required");
457
- const validation = require_CalmLensUtils.validateAssetPayload(part, {
458
- multipart: true,
459
- isFinal: part.isFinal
460
- });
461
- if (!validation.ok) throw invalidPayload(validation.error);
462
- const query = new URLSearchParams({
463
- partNumber: String(part.partNumber),
464
- isFinal: String(part.isFinal ?? false)
465
- });
466
- if (queue !== void 0) query.set("queue", String(queue));
467
- setOptionalQueryValue(query, "sizeInBytes", part.sizeInBytes ?? require_CalmLensUtils.getAssetPayloadByteLength(part));
468
- return this.upload(this.url(`${partPath}?${query}`), part, {
469
- ...authHeaders,
470
- "X-CalmLens-Upload": "part"
471
- }, idempotencyKey ?? newIdempotencyKey());
472
- }
473
- };
474
- //#endregion
475
- Object.defineProperty(exports, "CalmLensConnection", {
476
- enumerable: true,
477
- get: function() {
478
- return CalmLensConnection;
479
- }
480
- });
481
- Object.defineProperty(exports, "expectAsset", {
482
- enumerable: true,
483
- get: function() {
484
- return expectAsset;
485
- }
486
- });
487
- Object.defineProperty(exports, "expectUploadedAsset", {
488
- enumerable: true,
489
- get: function() {
490
- return expectUploadedAsset;
491
- }
492
- });
493
- Object.defineProperty(exports, "invalidPayload", {
494
- enumerable: true,
495
- get: function() {
496
- return invalidPayload;
497
- }
498
- });
499
- Object.defineProperty(exports, "newIdempotencyKey", {
500
- enumerable: true,
501
- get: function() {
502
- return newIdempotencyKey;
503
- }
504
- });
505
- Object.defineProperty(exports, "prepareSubmitAssetOptions", {
506
- enumerable: true,
507
- get: function() {
508
- return prepareSubmitAssetOptions;
509
- }
510
- });
511
- Object.defineProperty(exports, "resolveConnectionOptions", {
512
- enumerable: true,
513
- get: function() {
514
- return resolveConnectionOptions;
515
- }
516
- });