@makeswift/runtime 0.28.8 → 0.28.9-canary.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.
@@ -27,7 +27,7 @@ class MakeswiftGraphQLApiClient {
27
27
  graphqlClient;
28
28
  constructor({ endpoint }) {
29
29
  this.graphqlClient = new import_client.GraphQLClient(endpoint, {
30
- "makeswift-runtime-version": "0.28.8"
30
+ "makeswift-runtime-version": "0.28.9-canary.0"
31
31
  });
32
32
  }
33
33
  async createTableRecord(tableId, columns) {
@@ -0,0 +1,862 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/api/ky.ts
21
+ var ky_exports = {};
22
+ __export(ky_exports, {
23
+ HTTPError: () => HTTPError,
24
+ default: () => distribution_default,
25
+ isHTTPError: () => isHTTPError
26
+ });
27
+ module.exports = __toCommonJS(ky_exports);
28
+
29
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/HTTPError.js
30
+ var HTTPError = class extends Error {
31
+ response;
32
+ request;
33
+ options;
34
+ constructor(response, request, options) {
35
+ const code = response.status || response.status === 0 ? response.status : "";
36
+ const title = response.statusText ?? "";
37
+ const status = `${code} ${title}`.trim();
38
+ const reason = status ? `status code ${status}` : "an unknown error";
39
+ super(`Request failed with ${reason}: ${request.method} ${request.url}`);
40
+ this.name = "HTTPError";
41
+ this.response = response;
42
+ this.request = request;
43
+ this.options = options;
44
+ }
45
+ };
46
+
47
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/NonError.js
48
+ var NonError = class extends Error {
49
+ name = "NonError";
50
+ value;
51
+ constructor(value) {
52
+ let message = "Non-error value was thrown";
53
+ try {
54
+ if (typeof value === "string") {
55
+ message = value;
56
+ } else if (value && typeof value === "object" && "message" in value && typeof value.message === "string") {
57
+ message = value.message;
58
+ }
59
+ } catch {
60
+ }
61
+ super(message);
62
+ this.value = value;
63
+ }
64
+ };
65
+
66
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/ForceRetryError.js
67
+ var ForceRetryError = class extends Error {
68
+ name = "ForceRetryError";
69
+ customDelay;
70
+ code;
71
+ customRequest;
72
+ constructor(options) {
73
+ const cause = options?.cause ? options.cause instanceof Error ? options.cause : new NonError(options.cause) : void 0;
74
+ super(options?.code ? `Forced retry: ${options.code}` : "Forced retry", cause ? { cause } : void 0);
75
+ this.customDelay = options?.delay;
76
+ this.code = options?.code;
77
+ this.customRequest = options?.request;
78
+ }
79
+ };
80
+
81
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/core/constants.js
82
+ var supportsRequestStreams = (() => {
83
+ let duplexAccessed = false;
84
+ let hasContentType = false;
85
+ const supportsReadableStream = typeof globalThis.ReadableStream === "function";
86
+ const supportsRequest = typeof globalThis.Request === "function";
87
+ if (supportsReadableStream && supportsRequest) {
88
+ try {
89
+ hasContentType = new globalThis.Request("https://empty.invalid", {
90
+ body: new globalThis.ReadableStream(),
91
+ method: "POST",
92
+ // @ts-expect-error - Types are outdated.
93
+ get duplex() {
94
+ duplexAccessed = true;
95
+ return "half";
96
+ }
97
+ }).headers.has("Content-Type");
98
+ } catch (error) {
99
+ if (error instanceof Error && error.message === "unsupported BodyInit type") {
100
+ return false;
101
+ }
102
+ throw error;
103
+ }
104
+ }
105
+ return duplexAccessed && !hasContentType;
106
+ })();
107
+ var supportsAbortController = typeof globalThis.AbortController === "function";
108
+ var supportsAbortSignal = typeof globalThis.AbortSignal === "function" && typeof globalThis.AbortSignal.any === "function";
109
+ var supportsResponseStreams = typeof globalThis.ReadableStream === "function";
110
+ var supportsFormData = typeof globalThis.FormData === "function";
111
+ var requestMethods = ["get", "post", "put", "patch", "head", "delete"];
112
+ var validate = () => void 0;
113
+ validate();
114
+ var responseTypes = {
115
+ json: "application/json",
116
+ text: "text/*",
117
+ formData: "multipart/form-data",
118
+ arrayBuffer: "*/*",
119
+ blob: "*/*",
120
+ // Supported in modern Fetch implementations (for example, browsers and recent Node.js/undici).
121
+ // We still feature-check at runtime before exposing the shortcut.
122
+ bytes: "*/*"
123
+ };
124
+ var maxSafeTimeout = 2147483647;
125
+ var usualFormBoundarySize = new TextEncoder().encode("------WebKitFormBoundaryaxpyiPgbbPti10Rw").length;
126
+ var stop = Symbol("stop");
127
+ var RetryMarker = class {
128
+ options;
129
+ constructor(options) {
130
+ this.options = options;
131
+ }
132
+ };
133
+ var retry = (options) => new RetryMarker(options);
134
+ var kyOptionKeys = {
135
+ json: true,
136
+ parseJson: true,
137
+ stringifyJson: true,
138
+ searchParams: true,
139
+ prefixUrl: true,
140
+ retry: true,
141
+ timeout: true,
142
+ hooks: true,
143
+ throwHttpErrors: true,
144
+ onDownloadProgress: true,
145
+ onUploadProgress: true,
146
+ fetch: true,
147
+ context: true
148
+ };
149
+ var vendorSpecificOptions = {
150
+ next: true
151
+ // Next.js cache revalidation (revalidate, tags)
152
+ };
153
+ var requestOptionsRegistry = {
154
+ method: true,
155
+ headers: true,
156
+ body: true,
157
+ mode: true,
158
+ credentials: true,
159
+ cache: true,
160
+ redirect: true,
161
+ referrer: true,
162
+ referrerPolicy: true,
163
+ integrity: true,
164
+ keepalive: true,
165
+ signal: true,
166
+ window: true,
167
+ duplex: true
168
+ };
169
+
170
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/body.js
171
+ var getBodySize = (body) => {
172
+ if (!body) {
173
+ return 0;
174
+ }
175
+ if (body instanceof FormData) {
176
+ let size = 0;
177
+ for (const [key, value] of body) {
178
+ size += usualFormBoundarySize;
179
+ size += new TextEncoder().encode(`Content-Disposition: form-data; name="${key}"`).length;
180
+ size += typeof value === "string" ? new TextEncoder().encode(value).length : value.size;
181
+ }
182
+ return size;
183
+ }
184
+ if (body instanceof Blob) {
185
+ return body.size;
186
+ }
187
+ if (body instanceof ArrayBuffer) {
188
+ return body.byteLength;
189
+ }
190
+ if (typeof body === "string") {
191
+ return new TextEncoder().encode(body).length;
192
+ }
193
+ if (body instanceof URLSearchParams) {
194
+ return new TextEncoder().encode(body.toString()).length;
195
+ }
196
+ if ("byteLength" in body) {
197
+ return body.byteLength;
198
+ }
199
+ if (typeof body === "object" && body !== null) {
200
+ try {
201
+ const jsonString = JSON.stringify(body);
202
+ return new TextEncoder().encode(jsonString).length;
203
+ } catch {
204
+ return 0;
205
+ }
206
+ }
207
+ return 0;
208
+ };
209
+ var withProgress = (stream, totalBytes, onProgress) => {
210
+ let previousChunk;
211
+ let transferredBytes = 0;
212
+ return stream.pipeThrough(new TransformStream({
213
+ transform(currentChunk, controller) {
214
+ controller.enqueue(currentChunk);
215
+ if (previousChunk) {
216
+ transferredBytes += previousChunk.byteLength;
217
+ let percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes;
218
+ if (percent >= 1) {
219
+ percent = 1 - Number.EPSILON;
220
+ }
221
+ onProgress?.({ percent, totalBytes: Math.max(totalBytes, transferredBytes), transferredBytes }, previousChunk);
222
+ }
223
+ previousChunk = currentChunk;
224
+ },
225
+ flush() {
226
+ if (previousChunk) {
227
+ transferredBytes += previousChunk.byteLength;
228
+ onProgress?.({ percent: 1, totalBytes: Math.max(totalBytes, transferredBytes), transferredBytes }, previousChunk);
229
+ }
230
+ }
231
+ }));
232
+ };
233
+ var streamResponse = (response, onDownloadProgress) => {
234
+ if (!response.body) {
235
+ return response;
236
+ }
237
+ if (response.status === 204) {
238
+ return new Response(null, {
239
+ status: response.status,
240
+ statusText: response.statusText,
241
+ headers: response.headers
242
+ });
243
+ }
244
+ const totalBytes = Math.max(0, Number(response.headers.get("content-length")) || 0);
245
+ return new Response(withProgress(response.body, totalBytes, onDownloadProgress), {
246
+ status: response.status,
247
+ statusText: response.statusText,
248
+ headers: response.headers
249
+ });
250
+ };
251
+ var streamRequest = (request, onUploadProgress, originalBody) => {
252
+ if (!request.body) {
253
+ return request;
254
+ }
255
+ const totalBytes = getBodySize(originalBody ?? request.body);
256
+ return new Request(request, {
257
+ // @ts-expect-error - Types are outdated.
258
+ duplex: "half",
259
+ body: withProgress(request.body, totalBytes, onUploadProgress)
260
+ });
261
+ };
262
+
263
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/is.js
264
+ var isObject = (value) => value !== null && typeof value === "object";
265
+
266
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/merge.js
267
+ var validateAndMerge = (...sources) => {
268
+ for (const source of sources) {
269
+ if ((!isObject(source) || Array.isArray(source)) && source !== void 0) {
270
+ throw new TypeError("The `options` argument must be an object");
271
+ }
272
+ }
273
+ return deepMerge({}, ...sources);
274
+ };
275
+ var mergeHeaders = (source1 = {}, source2 = {}) => {
276
+ const result = new globalThis.Headers(source1);
277
+ const isHeadersInstance = source2 instanceof globalThis.Headers;
278
+ const source = new globalThis.Headers(source2);
279
+ for (const [key, value] of source.entries()) {
280
+ if (isHeadersInstance && value === "undefined" || value === void 0) {
281
+ result.delete(key);
282
+ } else {
283
+ result.set(key, value);
284
+ }
285
+ }
286
+ return result;
287
+ };
288
+ function newHookValue(original, incoming, property) {
289
+ return Object.hasOwn(incoming, property) && incoming[property] === void 0 ? [] : deepMerge(original[property] ?? [], incoming[property] ?? []);
290
+ }
291
+ var mergeHooks = (original = {}, incoming = {}) => ({
292
+ beforeRequest: newHookValue(original, incoming, "beforeRequest"),
293
+ beforeRetry: newHookValue(original, incoming, "beforeRetry"),
294
+ afterResponse: newHookValue(original, incoming, "afterResponse"),
295
+ beforeError: newHookValue(original, incoming, "beforeError")
296
+ });
297
+ var appendSearchParameters = (target, source) => {
298
+ const result = new URLSearchParams();
299
+ for (const input of [target, source]) {
300
+ if (input === void 0) {
301
+ continue;
302
+ }
303
+ if (input instanceof URLSearchParams) {
304
+ for (const [key, value] of input.entries()) {
305
+ result.append(key, value);
306
+ }
307
+ } else if (Array.isArray(input)) {
308
+ for (const pair of input) {
309
+ if (!Array.isArray(pair) || pair.length !== 2) {
310
+ throw new TypeError("Array search parameters must be provided in [[key, value], ...] format");
311
+ }
312
+ result.append(String(pair[0]), String(pair[1]));
313
+ }
314
+ } else if (isObject(input)) {
315
+ for (const [key, value] of Object.entries(input)) {
316
+ if (value !== void 0) {
317
+ result.append(key, String(value));
318
+ }
319
+ }
320
+ } else {
321
+ const parameters = new URLSearchParams(input);
322
+ for (const [key, value] of parameters.entries()) {
323
+ result.append(key, value);
324
+ }
325
+ }
326
+ }
327
+ return result;
328
+ };
329
+ var deepMerge = (...sources) => {
330
+ let returnValue = {};
331
+ let headers = {};
332
+ let hooks = {};
333
+ let searchParameters;
334
+ const signals = [];
335
+ for (const source of sources) {
336
+ if (Array.isArray(source)) {
337
+ if (!Array.isArray(returnValue)) {
338
+ returnValue = [];
339
+ }
340
+ returnValue = [...returnValue, ...source];
341
+ } else if (isObject(source)) {
342
+ for (let [key, value] of Object.entries(source)) {
343
+ if (key === "signal" && value instanceof globalThis.AbortSignal) {
344
+ signals.push(value);
345
+ continue;
346
+ }
347
+ if (key === "context") {
348
+ if (value !== void 0 && value !== null && (!isObject(value) || Array.isArray(value))) {
349
+ throw new TypeError("The `context` option must be an object");
350
+ }
351
+ returnValue = {
352
+ ...returnValue,
353
+ context: value === void 0 || value === null ? {} : { ...returnValue.context, ...value }
354
+ };
355
+ continue;
356
+ }
357
+ if (key === "searchParams") {
358
+ if (value === void 0 || value === null) {
359
+ searchParameters = void 0;
360
+ } else {
361
+ searchParameters = searchParameters === void 0 ? value : appendSearchParameters(searchParameters, value);
362
+ }
363
+ continue;
364
+ }
365
+ if (isObject(value) && key in returnValue) {
366
+ value = deepMerge(returnValue[key], value);
367
+ }
368
+ returnValue = { ...returnValue, [key]: value };
369
+ }
370
+ if (isObject(source.hooks)) {
371
+ hooks = mergeHooks(hooks, source.hooks);
372
+ returnValue.hooks = hooks;
373
+ }
374
+ if (isObject(source.headers)) {
375
+ headers = mergeHeaders(headers, source.headers);
376
+ returnValue.headers = headers;
377
+ }
378
+ }
379
+ }
380
+ if (searchParameters !== void 0) {
381
+ returnValue.searchParams = searchParameters;
382
+ }
383
+ if (signals.length > 0) {
384
+ if (signals.length === 1) {
385
+ returnValue.signal = signals[0];
386
+ } else if (supportsAbortSignal) {
387
+ returnValue.signal = AbortSignal.any(signals);
388
+ } else {
389
+ returnValue.signal = signals.at(-1);
390
+ }
391
+ }
392
+ return returnValue;
393
+ };
394
+
395
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/normalize.js
396
+ var normalizeRequestMethod = (input) => requestMethods.includes(input) ? input.toUpperCase() : input;
397
+ var retryMethods = ["get", "put", "head", "delete", "options", "trace"];
398
+ var retryStatusCodes = [408, 413, 429, 500, 502, 503, 504];
399
+ var retryAfterStatusCodes = [413, 429, 503];
400
+ var defaultRetryOptions = {
401
+ limit: 2,
402
+ methods: retryMethods,
403
+ statusCodes: retryStatusCodes,
404
+ afterStatusCodes: retryAfterStatusCodes,
405
+ maxRetryAfter: Number.POSITIVE_INFINITY,
406
+ backoffLimit: Number.POSITIVE_INFINITY,
407
+ delay: (attemptCount) => 0.3 * 2 ** (attemptCount - 1) * 1e3,
408
+ jitter: void 0,
409
+ retryOnTimeout: false
410
+ };
411
+ var normalizeRetryOptions = (retry2 = {}) => {
412
+ if (typeof retry2 === "number") {
413
+ return {
414
+ ...defaultRetryOptions,
415
+ limit: retry2
416
+ };
417
+ }
418
+ if (retry2.methods && !Array.isArray(retry2.methods)) {
419
+ throw new Error("retry.methods must be an array");
420
+ }
421
+ retry2.methods &&= retry2.methods.map((method) => method.toLowerCase());
422
+ if (retry2.statusCodes && !Array.isArray(retry2.statusCodes)) {
423
+ throw new Error("retry.statusCodes must be an array");
424
+ }
425
+ const normalizedRetry = Object.fromEntries(Object.entries(retry2).filter(([, value]) => value !== void 0));
426
+ return {
427
+ ...defaultRetryOptions,
428
+ ...normalizedRetry
429
+ };
430
+ };
431
+
432
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/TimeoutError.js
433
+ var TimeoutError = class extends Error {
434
+ request;
435
+ constructor(request) {
436
+ super(`Request timed out: ${request.method} ${request.url}`);
437
+ this.name = "TimeoutError";
438
+ this.request = request;
439
+ }
440
+ };
441
+
442
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/timeout.js
443
+ async function timeout(request, init, abortController, options) {
444
+ return new Promise((resolve, reject) => {
445
+ const timeoutId = setTimeout(() => {
446
+ if (abortController) {
447
+ abortController.abort();
448
+ }
449
+ reject(new TimeoutError(request));
450
+ }, options.timeout);
451
+ void options.fetch(request, init).then(resolve).catch(reject).then(() => {
452
+ clearTimeout(timeoutId);
453
+ });
454
+ });
455
+ }
456
+
457
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/delay.js
458
+ async function delay(ms, { signal }) {
459
+ return new Promise((resolve, reject) => {
460
+ if (signal) {
461
+ signal.throwIfAborted();
462
+ signal.addEventListener("abort", abortHandler, { once: true });
463
+ }
464
+ function abortHandler() {
465
+ clearTimeout(timeoutId);
466
+ reject(signal.reason);
467
+ }
468
+ const timeoutId = setTimeout(() => {
469
+ signal?.removeEventListener("abort", abortHandler);
470
+ resolve();
471
+ }, ms);
472
+ });
473
+ }
474
+
475
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/options.js
476
+ var findUnknownOptions = (request, options) => {
477
+ const unknownOptions = {};
478
+ for (const key in options) {
479
+ if (!Object.hasOwn(options, key)) {
480
+ continue;
481
+ }
482
+ if (!(key in requestOptionsRegistry) && !(key in kyOptionKeys) && (!(key in request) || key in vendorSpecificOptions)) {
483
+ unknownOptions[key] = options[key];
484
+ }
485
+ }
486
+ return unknownOptions;
487
+ };
488
+ var hasSearchParameters = (search) => {
489
+ if (search === void 0) {
490
+ return false;
491
+ }
492
+ if (Array.isArray(search)) {
493
+ return search.length > 0;
494
+ }
495
+ if (search instanceof URLSearchParams) {
496
+ return search.size > 0;
497
+ }
498
+ if (typeof search === "object") {
499
+ return Object.keys(search).length > 0;
500
+ }
501
+ if (typeof search === "string") {
502
+ return search.trim().length > 0;
503
+ }
504
+ return Boolean(search);
505
+ };
506
+
507
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/type-guards.js
508
+ function isHTTPError(error) {
509
+ return error instanceof HTTPError || error?.name === HTTPError.name;
510
+ }
511
+ function isTimeoutError(error) {
512
+ return error instanceof TimeoutError || error?.name === TimeoutError.name;
513
+ }
514
+
515
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/core/Ky.js
516
+ var Ky = class _Ky {
517
+ static create(input, options) {
518
+ const ky2 = new _Ky(input, options);
519
+ const function_ = async () => {
520
+ if (typeof ky2.#options.timeout === "number" && ky2.#options.timeout > maxSafeTimeout) {
521
+ throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`);
522
+ }
523
+ await Promise.resolve();
524
+ let response = await ky2.#fetch();
525
+ for (const hook of ky2.#options.hooks.afterResponse) {
526
+ const clonedResponse = ky2.#decorateResponse(response.clone());
527
+ let modifiedResponse;
528
+ try {
529
+ modifiedResponse = await hook(ky2.request, ky2.#getNormalizedOptions(), clonedResponse, { retryCount: ky2.#retryCount });
530
+ } catch (error) {
531
+ ky2.#cancelResponseBody(clonedResponse);
532
+ ky2.#cancelResponseBody(response);
533
+ throw error;
534
+ }
535
+ if (modifiedResponse instanceof RetryMarker) {
536
+ ky2.#cancelResponseBody(clonedResponse);
537
+ ky2.#cancelResponseBody(response);
538
+ throw new ForceRetryError(modifiedResponse.options);
539
+ }
540
+ const nextResponse = modifiedResponse instanceof globalThis.Response ? modifiedResponse : response;
541
+ if (clonedResponse !== nextResponse) {
542
+ ky2.#cancelResponseBody(clonedResponse);
543
+ }
544
+ if (response !== nextResponse) {
545
+ ky2.#cancelResponseBody(response);
546
+ }
547
+ response = nextResponse;
548
+ }
549
+ ky2.#decorateResponse(response);
550
+ if (!response.ok && (typeof ky2.#options.throwHttpErrors === "function" ? ky2.#options.throwHttpErrors(response.status) : ky2.#options.throwHttpErrors)) {
551
+ let error = new HTTPError(response, ky2.request, ky2.#getNormalizedOptions());
552
+ for (const hook of ky2.#options.hooks.beforeError) {
553
+ error = await hook(error, { retryCount: ky2.#retryCount });
554
+ }
555
+ throw error;
556
+ }
557
+ if (ky2.#options.onDownloadProgress) {
558
+ if (typeof ky2.#options.onDownloadProgress !== "function") {
559
+ throw new TypeError("The `onDownloadProgress` option must be a function");
560
+ }
561
+ if (!supportsResponseStreams) {
562
+ throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");
563
+ }
564
+ const progressResponse = response.clone();
565
+ ky2.#cancelResponseBody(response);
566
+ return streamResponse(progressResponse, ky2.#options.onDownloadProgress);
567
+ }
568
+ return response;
569
+ };
570
+ const result = ky2.#retry(function_).finally(() => {
571
+ const originalRequest = ky2.#originalRequest;
572
+ ky2.#cancelBody(originalRequest?.body ?? void 0);
573
+ ky2.#cancelBody(ky2.request.body ?? void 0);
574
+ });
575
+ for (const [type, mimeType] of Object.entries(responseTypes)) {
576
+ if (type === "bytes" && typeof globalThis.Response?.prototype?.bytes !== "function") {
577
+ continue;
578
+ }
579
+ result[type] = async () => {
580
+ ky2.request.headers.set("accept", ky2.request.headers.get("accept") || mimeType);
581
+ const response = await result;
582
+ if (type === "json") {
583
+ if (response.status === 204) {
584
+ return "";
585
+ }
586
+ const text = await response.text();
587
+ if (text === "") {
588
+ return "";
589
+ }
590
+ if (options.parseJson) {
591
+ return options.parseJson(text);
592
+ }
593
+ return JSON.parse(text);
594
+ }
595
+ return response[type]();
596
+ };
597
+ }
598
+ return result;
599
+ }
600
+ // eslint-disable-next-line unicorn/prevent-abbreviations
601
+ static #normalizeSearchParams(searchParams) {
602
+ if (searchParams && typeof searchParams === "object" && !Array.isArray(searchParams) && !(searchParams instanceof URLSearchParams)) {
603
+ return Object.fromEntries(Object.entries(searchParams).filter(([, value]) => value !== void 0));
604
+ }
605
+ return searchParams;
606
+ }
607
+ request;
608
+ #abortController;
609
+ #retryCount = 0;
610
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly -- False positive: #input is reassigned on line 202
611
+ #input;
612
+ #options;
613
+ #originalRequest;
614
+ #userProvidedAbortSignal;
615
+ #cachedNormalizedOptions;
616
+ // eslint-disable-next-line complexity
617
+ constructor(input, options = {}) {
618
+ this.#input = input;
619
+ this.#options = {
620
+ ...options,
621
+ headers: mergeHeaders(this.#input.headers, options.headers),
622
+ hooks: mergeHooks({
623
+ beforeRequest: [],
624
+ beforeRetry: [],
625
+ beforeError: [],
626
+ afterResponse: []
627
+ }, options.hooks),
628
+ method: normalizeRequestMethod(options.method ?? this.#input.method ?? "GET"),
629
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
630
+ prefixUrl: String(options.prefixUrl || ""),
631
+ retry: normalizeRetryOptions(options.retry),
632
+ throwHttpErrors: options.throwHttpErrors ?? true,
633
+ timeout: options.timeout ?? 1e4,
634
+ fetch: options.fetch ?? globalThis.fetch.bind(globalThis),
635
+ context: options.context ?? {}
636
+ };
637
+ if (typeof this.#input !== "string" && !(this.#input instanceof URL || this.#input instanceof globalThis.Request)) {
638
+ throw new TypeError("`input` must be a string, URL, or Request");
639
+ }
640
+ if (this.#options.prefixUrl && typeof this.#input === "string") {
641
+ if (this.#input.startsWith("/")) {
642
+ throw new Error("`input` must not begin with a slash when using `prefixUrl`");
643
+ }
644
+ if (!this.#options.prefixUrl.endsWith("/")) {
645
+ this.#options.prefixUrl += "/";
646
+ }
647
+ this.#input = this.#options.prefixUrl + this.#input;
648
+ }
649
+ if (supportsAbortController && supportsAbortSignal) {
650
+ this.#userProvidedAbortSignal = this.#options.signal ?? this.#input.signal;
651
+ this.#abortController = new globalThis.AbortController();
652
+ this.#options.signal = this.#userProvidedAbortSignal ? AbortSignal.any([this.#userProvidedAbortSignal, this.#abortController.signal]) : this.#abortController.signal;
653
+ }
654
+ if (supportsRequestStreams) {
655
+ this.#options.duplex = "half";
656
+ }
657
+ if (this.#options.json !== void 0) {
658
+ this.#options.body = this.#options.stringifyJson?.(this.#options.json) ?? JSON.stringify(this.#options.json);
659
+ this.#options.headers.set("content-type", this.#options.headers.get("content-type") ?? "application/json");
660
+ }
661
+ const userProvidedContentType = options.headers && new globalThis.Headers(options.headers).has("content-type");
662
+ if (this.#input instanceof globalThis.Request && (supportsFormData && this.#options.body instanceof globalThis.FormData || this.#options.body instanceof URLSearchParams) && !userProvidedContentType) {
663
+ this.#options.headers.delete("content-type");
664
+ }
665
+ this.request = new globalThis.Request(this.#input, this.#options);
666
+ if (hasSearchParameters(this.#options.searchParams)) {
667
+ const textSearchParams = typeof this.#options.searchParams === "string" ? this.#options.searchParams.replace(/^\?/, "") : new URLSearchParams(_Ky.#normalizeSearchParams(this.#options.searchParams)).toString();
668
+ const searchParams = "?" + textSearchParams;
669
+ const url = this.request.url.replace(/(?:\?.*?)?(?=#|$)/, searchParams);
670
+ this.request = new globalThis.Request(url, this.#options);
671
+ }
672
+ if (this.#options.onUploadProgress) {
673
+ if (typeof this.#options.onUploadProgress !== "function") {
674
+ throw new TypeError("The `onUploadProgress` option must be a function");
675
+ }
676
+ if (!supportsRequestStreams) {
677
+ throw new Error("Request streams are not supported in your environment. The `duplex` option for `Request` is not available.");
678
+ }
679
+ this.request = this.#wrapRequestWithUploadProgress(this.request, this.#options.body ?? void 0);
680
+ }
681
+ }
682
+ #calculateDelay() {
683
+ const retryDelay = this.#options.retry.delay(this.#retryCount);
684
+ let jitteredDelay = retryDelay;
685
+ if (this.#options.retry.jitter === true) {
686
+ jitteredDelay = Math.random() * retryDelay;
687
+ } else if (typeof this.#options.retry.jitter === "function") {
688
+ jitteredDelay = this.#options.retry.jitter(retryDelay);
689
+ if (!Number.isFinite(jitteredDelay) || jitteredDelay < 0) {
690
+ jitteredDelay = retryDelay;
691
+ }
692
+ }
693
+ const backoffLimit = this.#options.retry.backoffLimit ?? Number.POSITIVE_INFINITY;
694
+ return Math.min(backoffLimit, jitteredDelay);
695
+ }
696
+ async #calculateRetryDelay(error) {
697
+ this.#retryCount++;
698
+ if (this.#retryCount > this.#options.retry.limit) {
699
+ throw error;
700
+ }
701
+ const errorObject = error instanceof Error ? error : new NonError(error);
702
+ if (errorObject instanceof ForceRetryError) {
703
+ return errorObject.customDelay ?? this.#calculateDelay();
704
+ }
705
+ if (!this.#options.retry.methods.includes(this.request.method.toLowerCase())) {
706
+ throw error;
707
+ }
708
+ if (this.#options.retry.shouldRetry !== void 0) {
709
+ const result = await this.#options.retry.shouldRetry({ error: errorObject, retryCount: this.#retryCount });
710
+ if (result === false) {
711
+ throw error;
712
+ }
713
+ if (result === true) {
714
+ return this.#calculateDelay();
715
+ }
716
+ }
717
+ if (isTimeoutError(error) && !this.#options.retry.retryOnTimeout) {
718
+ throw error;
719
+ }
720
+ if (isHTTPError(error)) {
721
+ if (!this.#options.retry.statusCodes.includes(error.response.status)) {
722
+ throw error;
723
+ }
724
+ const retryAfter = error.response.headers.get("Retry-After") ?? error.response.headers.get("RateLimit-Reset") ?? error.response.headers.get("X-RateLimit-Retry-After") ?? error.response.headers.get("X-RateLimit-Reset") ?? error.response.headers.get("X-Rate-Limit-Reset");
725
+ if (retryAfter && this.#options.retry.afterStatusCodes.includes(error.response.status)) {
726
+ let after = Number(retryAfter) * 1e3;
727
+ if (Number.isNaN(after)) {
728
+ after = Date.parse(retryAfter) - Date.now();
729
+ } else if (after >= Date.parse("2024-01-01")) {
730
+ after -= Date.now();
731
+ }
732
+ const max = this.#options.retry.maxRetryAfter ?? after;
733
+ return after < max ? after : max;
734
+ }
735
+ if (error.response.status === 413) {
736
+ throw error;
737
+ }
738
+ }
739
+ return this.#calculateDelay();
740
+ }
741
+ #decorateResponse(response) {
742
+ if (this.#options.parseJson) {
743
+ response.json = async () => this.#options.parseJson(await response.text());
744
+ }
745
+ return response;
746
+ }
747
+ #cancelBody(body) {
748
+ if (!body) {
749
+ return;
750
+ }
751
+ void body.cancel().catch(() => void 0);
752
+ }
753
+ #cancelResponseBody(response) {
754
+ this.#cancelBody(response.body ?? void 0);
755
+ }
756
+ async #retry(function_) {
757
+ try {
758
+ return await function_();
759
+ } catch (error) {
760
+ const ms = Math.min(await this.#calculateRetryDelay(error), maxSafeTimeout);
761
+ if (this.#retryCount < 1) {
762
+ throw error;
763
+ }
764
+ await delay(ms, this.#userProvidedAbortSignal ? { signal: this.#userProvidedAbortSignal } : {});
765
+ if (error instanceof ForceRetryError && error.customRequest) {
766
+ const managedRequest = this.#options.signal ? new globalThis.Request(error.customRequest, { signal: this.#options.signal }) : new globalThis.Request(error.customRequest);
767
+ this.#assignRequest(managedRequest);
768
+ }
769
+ for (const hook of this.#options.hooks.beforeRetry) {
770
+ const hookResult = await hook({
771
+ request: this.request,
772
+ options: this.#getNormalizedOptions(),
773
+ error,
774
+ retryCount: this.#retryCount
775
+ });
776
+ if (hookResult instanceof globalThis.Request) {
777
+ this.#assignRequest(hookResult);
778
+ break;
779
+ }
780
+ if (hookResult instanceof globalThis.Response) {
781
+ return hookResult;
782
+ }
783
+ if (hookResult === stop) {
784
+ return;
785
+ }
786
+ }
787
+ return this.#retry(function_);
788
+ }
789
+ }
790
+ async #fetch() {
791
+ if (this.#abortController?.signal.aborted) {
792
+ this.#abortController = new globalThis.AbortController();
793
+ this.#options.signal = this.#userProvidedAbortSignal ? AbortSignal.any([this.#userProvidedAbortSignal, this.#abortController.signal]) : this.#abortController.signal;
794
+ this.request = new globalThis.Request(this.request, { signal: this.#options.signal });
795
+ }
796
+ for (const hook of this.#options.hooks.beforeRequest) {
797
+ const result = await hook(this.request, this.#getNormalizedOptions(), { retryCount: this.#retryCount });
798
+ if (result instanceof Response) {
799
+ return result;
800
+ }
801
+ if (result instanceof globalThis.Request) {
802
+ this.#assignRequest(result);
803
+ break;
804
+ }
805
+ }
806
+ const nonRequestOptions = findUnknownOptions(this.request, this.#options);
807
+ this.#originalRequest = this.request;
808
+ this.request = this.#originalRequest.clone();
809
+ if (this.#options.timeout === false) {
810
+ return this.#options.fetch(this.#originalRequest, nonRequestOptions);
811
+ }
812
+ return timeout(this.#originalRequest, nonRequestOptions, this.#abortController, this.#options);
813
+ }
814
+ #getNormalizedOptions() {
815
+ if (!this.#cachedNormalizedOptions) {
816
+ const { hooks, ...normalizedOptions } = this.#options;
817
+ this.#cachedNormalizedOptions = Object.freeze(normalizedOptions);
818
+ }
819
+ return this.#cachedNormalizedOptions;
820
+ }
821
+ #assignRequest(request) {
822
+ this.#cachedNormalizedOptions = void 0;
823
+ this.request = this.#wrapRequestWithUploadProgress(request);
824
+ }
825
+ #wrapRequestWithUploadProgress(request, originalBody) {
826
+ if (!this.#options.onUploadProgress || !request.body) {
827
+ return request;
828
+ }
829
+ return streamRequest(request, this.#options.onUploadProgress, originalBody ?? this.#options.body ?? void 0);
830
+ }
831
+ };
832
+
833
+ // ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/index.js
834
+ var createInstance = (defaults) => {
835
+ const ky2 = (input, options) => Ky.create(input, validateAndMerge(defaults, options));
836
+ for (const method of requestMethods) {
837
+ ky2[method] = (input, options) => Ky.create(input, validateAndMerge(defaults, options, { method }));
838
+ }
839
+ ky2.create = (newDefaults) => createInstance(validateAndMerge(newDefaults));
840
+ ky2.extend = (newDefaults) => {
841
+ if (typeof newDefaults === "function") {
842
+ newDefaults = newDefaults(defaults ?? {});
843
+ }
844
+ return createInstance(validateAndMerge(defaults, newDefaults));
845
+ };
846
+ ky2.stop = stop;
847
+ ky2.retry = retry;
848
+ return ky2;
849
+ };
850
+ var ky = createInstance();
851
+ var distribution_default = ky;
852
+ // Annotate the CommonJS export names for ESM import in node:
853
+ 0 && (module.exports = {
854
+ HTTPError,
855
+ isHTTPError
856
+ });
857
+ /*! Bundled license information:
858
+
859
+ ky/distribution/index.js:
860
+ (*! MIT License © Sindre Sorhus *)
861
+ */
862
+ //# sourceMappingURL=ky.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/api/ky.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/errors/HTTPError.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/errors/NonError.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/errors/ForceRetryError.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/core/constants.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/utils/body.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/utils/is.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/utils/merge.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/utils/normalize.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/errors/TimeoutError.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/utils/timeout.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/utils/delay.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/utils/options.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/utils/type-guards.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/core/Ky.ts","../../../../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/source/index.ts"],"sourcesContent":["// `ky` is an ESM-only package: it has no `require` condition in its exports map\n// and ships no CommonJS build. Because we build with `bundle: false`, importing\n// it directly would leave a bare `require('ky')` in our CommonJS output, which\n// throws `ERR_REQUIRE_ESM` on any host whose loader doesn't implement\n// `require(esm)` — older Node, or a platform that patches `Module._load` (some\n// serverless runtimes do).\n//\n// Routing every `ky` import through this module lets us bundle `ky` into the\n// CommonJS build, so the shipped `dist/cjs` output never requires it. See the\n// `ky` entry in `tsup.config.ts`.\nexport { default, HTTPError, isHTTPError } from 'ky'\nexport type { KyInstance } from 'ky'\n","import type {NormalizedOptions} from '../types/options.js';\nimport type {KyRequest} from '../types/request.js';\nimport type {KyResponse} from '../types/response.js';\n\nexport class HTTPError<T = unknown> extends Error {\n\tpublic response: KyResponse<T>;\n\tpublic request: KyRequest;\n\tpublic options: NormalizedOptions;\n\n\tconstructor(response: Response, request: Request, options: NormalizedOptions) {\n\t\tconst code = (response.status || response.status === 0) ? response.status : '';\n\t\tconst title = response.statusText ?? '';\n\t\tconst status = `${code} ${title}`.trim();\n\t\tconst reason = status ? `status code ${status}` : 'an unknown error';\n\n\t\tsuper(`Request failed with ${reason}: ${request.method} ${request.url}`);\n\n\t\tthis.name = 'HTTPError';\n\t\tthis.response = response;\n\t\tthis.request = request;\n\t\tthis.options = options;\n\t}\n}\n","/**\nWrapper for non-Error values that were thrown.\n\nIn JavaScript, any value can be thrown (not just Error instances). This class wraps such values to ensure consistent error handling.\n*/\nexport class NonError extends Error {\n\toverride name = 'NonError';\n\treadonly value: unknown;\n\n\tconstructor(value: unknown) {\n\t\tlet message = 'Non-error value was thrown';\n\n\t\t// Intentionally minimal as this error is just an edge-case.\n\t\ttry {\n\t\t\tif (typeof value === 'string') {\n\t\t\t\tmessage = value;\n\t\t\t} else if (value && typeof value === 'object' && 'message' in value && typeof value.message === 'string') {\n\t\t\t\tmessage = value.message;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Use default message if accessing properties throws\n\t\t}\n\n\t\tsuper(message);\n\n\t\tthis.value = value;\n\t}\n}\n","import type {ForceRetryOptions} from '../core/constants.js';\nimport {NonError} from './NonError.js';\n\n/**\nInternal error used to signal a forced retry from afterResponse hooks.\nThis is thrown when a user returns ky.retry() from an afterResponse hook.\n*/\nexport class ForceRetryError extends Error {\n\toverride name = 'ForceRetryError' as const;\n\tcustomDelay: number | undefined;\n\tcode: string | undefined;\n\tcustomRequest: Request | undefined;\n\n\tconstructor(options?: ForceRetryOptions) {\n\t\t// Runtime protection: wrap non-Error causes in NonError\n\t\t// TypeScript type is Error for guidance, but JS users can pass anything\n\t\tconst cause = options?.cause\n\t\t\t? (options.cause instanceof Error ? options.cause : new NonError(options.cause))\n\t\t\t: undefined;\n\n\t\tsuper(\n\t\t\toptions?.code ? `Forced retry: ${options.code}` : 'Forced retry',\n\t\t\tcause ? {cause} : undefined,\n\t\t);\n\n\t\tthis.customDelay = options?.delay;\n\t\tthis.code = options?.code;\n\t\tthis.customRequest = options?.request;\n\t}\n}\n","import type {Expect, Equal} from '@type-challenges/utils';\nimport {type KyOptionsRegistry, type RequestHttpMethod} from '../types/options.js';\n\nexport const supportsRequestStreams = (() => {\n\tlet duplexAccessed = false;\n\tlet hasContentType = false;\n\tconst supportsReadableStream = typeof globalThis.ReadableStream === 'function';\n\tconst supportsRequest = typeof globalThis.Request === 'function';\n\n\tif (supportsReadableStream && supportsRequest) {\n\t\ttry {\n\t\t\thasContentType = new globalThis.Request('https://empty.invalid', {\n\t\t\t\tbody: new globalThis.ReadableStream(),\n\t\t\t\tmethod: 'POST',\n\t\t\t\t// @ts-expect-error - Types are outdated.\n\t\t\t\tget duplex() {\n\t\t\t\t\tduplexAccessed = true;\n\t\t\t\t\treturn 'half';\n\t\t\t\t},\n\t\t\t}).headers.has('Content-Type');\n\t\t} catch (error) {\n\t\t\t// QQBrowser on iOS throws \"unsupported BodyInit type\" error (see issue #581)\n\t\t\tif (error instanceof Error && error.message === 'unsupported BodyInit type') {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn duplexAccessed && !hasContentType;\n})();\n\nexport const supportsAbortController = typeof globalThis.AbortController === 'function';\nexport const supportsAbortSignal = typeof globalThis.AbortSignal === 'function' && typeof globalThis.AbortSignal.any === 'function';\nexport const supportsResponseStreams = typeof globalThis.ReadableStream === 'function';\nexport const supportsFormData = typeof globalThis.FormData === 'function';\n\nexport const requestMethods = ['get', 'post', 'put', 'patch', 'head', 'delete'] as const;\n\nconst validate = <T extends Array<true>>() => undefined as unknown as T;\nvalidate<[\n\tExpect<Equal<typeof requestMethods[number], RequestHttpMethod>>,\n]>();\n\nexport const responseTypes = {\n\tjson: 'application/json',\n\ttext: 'text/*',\n\tformData: 'multipart/form-data',\n\tarrayBuffer: '*/*',\n\tblob: '*/*',\n\t// Supported in modern Fetch implementations (for example, browsers and recent Node.js/undici).\n\t// We still feature-check at runtime before exposing the shortcut.\n\tbytes: '*/*',\n} as const;\n\n// The maximum value of a 32bit int (see issue #117)\nexport const maxSafeTimeout = 2_147_483_647;\n\n// Size in bytes of a typical form boundary, used to help estimate upload size\nexport const usualFormBoundarySize = new TextEncoder().encode('------WebKitFormBoundaryaxpyiPgbbPti10Rw').length;\n\nexport const stop = Symbol('stop');\n\n/**\nOptions for forcing a retry via `ky.retry()`.\n*/\nexport type ForceRetryOptions = {\n\t/**\n\tCustom delay in milliseconds before retrying.\n\n\tIf not provided, uses the default retry delay calculation based on `retry.delay` configuration.\n\n\t**Note:** Custom delays bypass jitter and `backoffLimit`. This is intentional, as custom delays often come from server responses (e.g., `Retry-After` headers) and should be respected exactly as specified.\n\t*/\n\tdelay?: number;\n\n\t/**\n\tError code for the retry.\n\n\tThis machine-readable identifier will be included in the error message passed to `beforeRetry` hooks, allowing you to distinguish between different types of forced retries.\n\n\t@example\n\t```\n\treturn ky.retry({code: 'RATE_LIMIT'});\n\t// Resulting error message: 'Forced retry: RATE_LIMIT'\n\t```\n\t*/\n\tcode?: string;\n\n\t/**\n\tOriginal error that caused the retry.\n\n\tThis allows you to preserve the error chain when forcing a retry based on caught exceptions. The error will be set as the `cause` of the `ForceRetryError`, enabling proper error chain traversal.\n\n\t@example\n\t```\n\ttry {\n\t\tconst data = await response.clone().json();\n\t\tvalidateBusinessLogic(data);\n\t} catch (error) {\n\t\treturn ky.retry({\n\t\t\tcode: 'VALIDATION_FAILED',\n\t\t\tcause: error // Preserves original error in chain\n\t\t});\n\t}\n\t```\n\t*/\n\tcause?: Error;\n\n\t/**\n\tCustom request to use for the retry.\n\n\tThis allows you to modify or completely replace the request during a forced retry. The custom request becomes the starting point for the retry - `beforeRetry` hooks can still further modify it if needed.\n\n\t**Note:** The custom request's `signal` will be replaced with Ky's managed signal to handle timeouts and user-provided abort signals correctly. If the original request body has been consumed, you must provide a new body or clone the request before consuming.\n\n\t@example\n\t```\n\t// Fallback to a different endpoint\n\treturn ky.retry({\n\t\trequest: new Request('https://backup-api.com/endpoint', {\n\t\t\tmethod: request.method,\n\t\t\theaders: request.headers,\n\t\t}),\n\t\tcode: 'BACKUP_ENDPOINT'\n\t});\n\n\t// Retry with refreshed authentication token\n\tconst data = await response.clone().json();\n\treturn ky.retry({\n\t\trequest: new Request(request, {\n\t\t\theaders: {\n\t\t\t\t...Object.fromEntries(request.headers),\n\t\t\t\t'Authorization': `Bearer ${data.newToken}`\n\t\t\t}\n\t\t}),\n\t\tcode: 'TOKEN_REFRESHED'\n\t});\n\t```\n\t*/\n\trequest?: Request;\n};\n\n/**\nMarker returned by ky.retry() to signal a forced retry from afterResponse hooks.\n*/\nexport class RetryMarker {\n\tconstructor(public options?: ForceRetryOptions) {}\n}\n\n/**\nForce a retry from an `afterResponse` hook.\n\nThis allows you to retry a request based on the response content, even if the response has a successful status code. The retry will respect the `retry.limit` option and skip the `shouldRetry` check. The forced retry is observable in `beforeRetry` hooks, where the error will be a `ForceRetryError`.\n\n@param options - Optional configuration for the retry.\n\n@example\n```\nimport ky, {isForceRetryError} from 'ky';\n\nconst api = ky.extend({\n\thooks: {\n\t\tafterResponse: [\n\t\t\tasync (request, options, response) => {\n\t\t\t\t// Retry based on response body content\n\t\t\t\tif (response.status === 200) {\n\t\t\t\t\tconst data = await response.clone().json();\n\n\t\t\t\t\t// Simple retry with default delay\n\t\t\t\t\tif (data.error?.code === 'TEMPORARY_ERROR') {\n\t\t\t\t\t\treturn ky.retry();\n\t\t\t\t\t}\n\n\t\t\t\t\t// Retry with custom delay from API response\n\t\t\t\t\tif (data.error?.code === 'RATE_LIMIT') {\n\t\t\t\t\t\treturn ky.retry({\n\t\t\t\t\t\t\tdelay: data.error.retryAfter * 1000,\n\t\t\t\t\t\t\tcode: 'RATE_LIMIT'\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Retry with a modified request (e.g., fallback endpoint)\n\t\t\t\t\tif (data.error?.code === 'FALLBACK_TO_BACKUP') {\n\t\t\t\t\t\treturn ky.retry({\n\t\t\t\t\t\t\trequest: new Request('https://backup-api.com/endpoint', {\n\t\t\t\t\t\t\t\tmethod: request.method,\n\t\t\t\t\t\t\t\theaders: request.headers,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tcode: 'BACKUP_ENDPOINT'\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Retry with refreshed authentication\n\t\t\t\t\tif (data.error?.code === 'TOKEN_REFRESH' && data.newToken) {\n\t\t\t\t\t\treturn ky.retry({\n\t\t\t\t\t\t\trequest: new Request(request, {\n\t\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t\t...Object.fromEntries(request.headers),\n\t\t\t\t\t\t\t\t\t'Authorization': `Bearer ${data.newToken}`\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tcode: 'TOKEN_REFRESHED'\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Retry with cause to preserve error chain\n\t\t\t\t\ttry {\n\t\t\t\t\t\tvalidateResponse(data);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treturn ky.retry({\n\t\t\t\t\t\t\tcode: 'VALIDATION_FAILED',\n\t\t\t\t\t\t\tcause: error\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t],\n\t\tbeforeRetry: [\n\t\t\t({error, retryCount}) => {\n\t\t\t\t// Observable in beforeRetry hooks\n\t\t\t\tif (isForceRetryError(error)) {\n\t\t\t\t\tconsole.log(`Forced retry #${retryCount}: ${error.message}`);\n\t\t\t\t\t// Example output: \"Forced retry #1: Forced retry: RATE_LIMIT\"\n\t\t\t\t}\n\t\t\t}\n\t\t]\n\t}\n});\n\nconst response = await api.get('https://example.com/api');\n```\n*/\nexport const retry = (options?: ForceRetryOptions) => new RetryMarker(options);\n\nexport const kyOptionKeys: KyOptionsRegistry = {\n\tjson: true,\n\tparseJson: true,\n\tstringifyJson: true,\n\tsearchParams: true,\n\tprefixUrl: true,\n\tretry: true,\n\ttimeout: true,\n\thooks: true,\n\tthrowHttpErrors: true,\n\tonDownloadProgress: true,\n\tonUploadProgress: true,\n\tfetch: true,\n\tcontext: true,\n};\n\n// Vendor-specific fetch options that should always be passed to fetch()\n// even if they appear on the Request object due to vendor patching.\n// See: https://github.com/sindresorhus/ky/issues/541\nexport const vendorSpecificOptions = {\n\tnext: true, // Next.js cache revalidation (revalidate, tags)\n} as const;\n\n// Standard RequestInit options that should NOT be passed separately to fetch()\n// because they're already applied to the Request object.\n// Note: `dispatcher` and `priority` are NOT included here - they're fetch-only\n// options that the Request constructor doesn't accept, so they need to be passed\n// separately to fetch().\nexport const requestOptionsRegistry = {\n\tmethod: true,\n\theaders: true,\n\tbody: true,\n\tmode: true,\n\tcredentials: true,\n\tcache: true,\n\tredirect: true,\n\treferrer: true,\n\treferrerPolicy: true,\n\tintegrity: true,\n\tkeepalive: true,\n\tsignal: true,\n\twindow: true,\n\tduplex: true,\n} as const;\n","import type {Options} from '../types/options.js';\nimport {usualFormBoundarySize} from '../core/constants.js';\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const getBodySize = (body?: BodyInit | null): number => {\n\tif (!body) {\n\t\treturn 0;\n\t}\n\n\tif (body instanceof FormData) {\n\t\t// This is an approximation, as FormData size calculation is not straightforward\n\t\tlet size = 0;\n\n\t\tfor (const [key, value] of body) {\n\t\t\tsize += usualFormBoundarySize;\n\t\t\tsize += new TextEncoder().encode(`Content-Disposition: form-data; name=\"${key}\"`).length;\n\t\t\tsize += typeof value === 'string'\n\t\t\t\t? new TextEncoder().encode(value).length\n\t\t\t\t: value.size;\n\t\t}\n\n\t\treturn size;\n\t}\n\n\tif (body instanceof Blob) {\n\t\treturn body.size;\n\t}\n\n\tif (body instanceof ArrayBuffer) {\n\t\treturn body.byteLength;\n\t}\n\n\tif (typeof body === 'string') {\n\t\treturn new TextEncoder().encode(body).length;\n\t}\n\n\tif (body instanceof URLSearchParams) {\n\t\treturn new TextEncoder().encode(body.toString()).length;\n\t}\n\n\tif ('byteLength' in body) {\n\t\treturn (body).byteLength;\n\t}\n\n\tif (typeof body === 'object' && body !== null) {\n\t\ttry {\n\t\t\tconst jsonString = JSON.stringify(body);\n\t\t\treturn new TextEncoder().encode(jsonString).length;\n\t\t} catch {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\treturn 0; // Default case, unable to determine size\n};\n\nconst withProgress = (stream: ReadableStream<Uint8Array>, totalBytes: number, onProgress: Options['onDownloadProgress'] | Options['onUploadProgress']): ReadableStream<Uint8Array> => {\n\tlet previousChunk: Uint8Array | undefined;\n\tlet transferredBytes = 0;\n\n\treturn stream.pipeThrough(new TransformStream<Uint8Array, Uint8Array>({\n\t\ttransform(currentChunk, controller) {\n\t\t\tcontroller.enqueue(currentChunk);\n\n\t\t\tif (previousChunk) {\n\t\t\t\ttransferredBytes += previousChunk.byteLength;\n\n\t\t\t\tlet percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes;\n\t\t\t\t// Avoid reporting 100% progress before the stream is actually finished (in case totalBytes is inaccurate)\n\t\t\t\tif (percent >= 1) {\n\t\t\t\t\t// Epsilon is used here to get as close as possible to 100% without reaching it.\n\t\t\t\t\t// If we were to use 0.99 here, percent could potentially go backwards.\n\t\t\t\t\tpercent = 1 - Number.EPSILON;\n\t\t\t\t}\n\n\t\t\t\tonProgress?.({percent, totalBytes: Math.max(totalBytes, transferredBytes), transferredBytes}, previousChunk);\n\t\t\t}\n\n\t\t\tpreviousChunk = currentChunk;\n\t\t},\n\t\tflush() {\n\t\t\tif (previousChunk) {\n\t\t\t\ttransferredBytes += previousChunk.byteLength;\n\t\t\t\tonProgress?.({percent: 1, totalBytes: Math.max(totalBytes, transferredBytes), transferredBytes}, previousChunk);\n\t\t\t}\n\t\t},\n\t}));\n};\n\nexport const streamResponse = (response: Response, onDownloadProgress: Options['onDownloadProgress']) => {\n\tif (!response.body) {\n\t\treturn response;\n\t}\n\n\tif (response.status === 204) {\n\t\treturn new Response(\n\t\t\tnull,\n\t\t\t{\n\t\t\t\tstatus: response.status,\n\t\t\t\tstatusText: response.statusText,\n\t\t\t\theaders: response.headers,\n\t\t\t},\n\t\t);\n\t}\n\n\tconst totalBytes = Math.max(0, Number(response.headers.get('content-length')) || 0);\n\n\treturn new Response(\n\t\twithProgress(response.body, totalBytes, onDownloadProgress),\n\t\t{\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\theaders: response.headers,\n\t\t},\n\t);\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const streamRequest = (request: Request, onUploadProgress: Options['onUploadProgress'], originalBody?: BodyInit | null) => {\n\tif (!request.body) {\n\t\treturn request;\n\t}\n\n\t// Use original body for size calculation since request.body is already a stream\n\tconst totalBytes = getBodySize(originalBody ?? request.body);\n\n\treturn new Request(request, {\n\t\t// @ts-expect-error - Types are outdated.\n\t\tduplex: 'half',\n\t\tbody: withProgress(request.body, totalBytes, onUploadProgress),\n\t});\n};\n","// eslint-disable-next-line @typescript-eslint/ban-types\nexport const isObject = (value: unknown): value is object => value !== null && typeof value === 'object';\n","import type {KyHeadersInit, Options} from '../types/options.js';\nimport type {Hooks} from '../types/hooks.js';\nimport {supportsAbortSignal} from '../core/constants.js';\nimport {isObject} from './is.js';\n\nexport const validateAndMerge = (...sources: Array<Partial<Options> | undefined>): Partial<Options> => {\n\tfor (const source of sources) {\n\t\tif ((!isObject(source) || Array.isArray(source)) && source !== undefined) {\n\t\t\tthrow new TypeError('The `options` argument must be an object');\n\t\t}\n\t}\n\n\treturn deepMerge({}, ...sources);\n};\n\nexport const mergeHeaders = (source1: KyHeadersInit = {}, source2: KyHeadersInit = {}) => {\n\tconst result = new globalThis.Headers(source1 as RequestInit['headers']);\n\tconst isHeadersInstance = source2 instanceof globalThis.Headers;\n\tconst source = new globalThis.Headers(source2 as RequestInit['headers']);\n\n\tfor (const [key, value] of source.entries()) {\n\t\tif ((isHeadersInstance && value === 'undefined') || value === undefined) {\n\t\t\tresult.delete(key);\n\t\t} else {\n\t\t\tresult.set(key, value);\n\t\t}\n\t}\n\n\treturn result;\n};\n\nfunction newHookValue<K extends keyof Hooks>(original: Hooks, incoming: Hooks, property: K): Required<Hooks>[K] {\n\treturn (Object.hasOwn(incoming, property) && incoming[property] === undefined)\n\t\t? []\n\t\t: deepMerge<Required<Hooks>[K]>(original[property] ?? [], incoming[property] ?? []);\n}\n\nexport const mergeHooks = (original: Hooks = {}, incoming: Hooks = {}): Required<Hooks> => (\n\t{\n\t\tbeforeRequest: newHookValue(original, incoming, 'beforeRequest'),\n\t\tbeforeRetry: newHookValue(original, incoming, 'beforeRetry'),\n\t\tafterResponse: newHookValue(original, incoming, 'afterResponse'),\n\t\tbeforeError: newHookValue(original, incoming, 'beforeError'),\n\t}\n);\n\nconst appendSearchParameters = (target: any, source: any): URLSearchParams => {\n\tconst result = new URLSearchParams();\n\n\tfor (const input of [target, source]) {\n\t\tif (input === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (input instanceof URLSearchParams) {\n\t\t\tfor (const [key, value] of input.entries()) {\n\t\t\t\tresult.append(key, value);\n\t\t\t}\n\t\t} else if (Array.isArray(input)) {\n\t\t\tfor (const pair of input) {\n\t\t\t\tif (!Array.isArray(pair) || pair.length !== 2) {\n\t\t\t\t\tthrow new TypeError('Array search parameters must be provided in [[key, value], ...] format');\n\t\t\t\t}\n\n\t\t\t\tresult.append(String(pair[0]), String(pair[1]));\n\t\t\t}\n\t\t} else if (isObject(input)) {\n\t\t\tfor (const [key, value] of Object.entries(input)) {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tresult.append(key, String(value));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// String\n\t\t\tconst parameters = new URLSearchParams(input);\n\t\t\tfor (const [key, value] of parameters.entries()) {\n\t\t\t\tresult.append(key, value);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n};\n\n// TODO: Make this strongly-typed (no `any`).\nexport const deepMerge = <T>(...sources: Array<Partial<T> | undefined>): T => {\n\tlet returnValue: any = {};\n\tlet headers = {};\n\tlet hooks = {};\n\tlet searchParameters: any;\n\tconst signals: AbortSignal[] = [];\n\n\tfor (const source of sources) {\n\t\tif (Array.isArray(source)) {\n\t\t\tif (!Array.isArray(returnValue)) {\n\t\t\t\treturnValue = [];\n\t\t\t}\n\n\t\t\treturnValue = [...returnValue, ...source];\n\t\t} else if (isObject(source)) {\n\t\t\tfor (let [key, value] of Object.entries(source)) {\n\t\t\t\t// Special handling for AbortSignal instances\n\t\t\t\tif (key === 'signal' && value instanceof globalThis.AbortSignal) {\n\t\t\t\t\tsignals.push(value);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Special handling for context - shallow merge only\n\t\t\t\tif (key === 'context') {\n\t\t\t\t\tif (value !== undefined && value !== null && (!isObject(value) || Array.isArray(value))) {\n\t\t\t\t\t\tthrow new TypeError('The `context` option must be an object');\n\t\t\t\t\t}\n\n\t\t\t\t\t// Shallow merge: always create a new object to prevent mutation bugs\n\t\t\t\t\treturnValue = {\n\t\t\t\t\t\t...returnValue,\n\t\t\t\t\t\tcontext: (value === undefined || value === null)\n\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t: {...returnValue.context, ...value},\n\t\t\t\t\t};\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Special handling for searchParams\n\t\t\t\tif (key === 'searchParams') {\n\t\t\t\t\tif (value === undefined || value === null) {\n\t\t\t\t\t\t// Explicit undefined or null removes searchParams\n\t\t\t\t\t\tsearchParameters = undefined;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// First source: keep as-is to preserve type (string/object/URLSearchParams)\n\t\t\t\t\t\t// Subsequent sources: merge and convert to URLSearchParams\n\t\t\t\t\t\tsearchParameters = searchParameters === undefined ? value : appendSearchParameters(searchParameters, value);\n\t\t\t\t\t}\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (isObject(value) && key in returnValue) {\n\t\t\t\t\tvalue = deepMerge(returnValue[key], value);\n\t\t\t\t}\n\n\t\t\t\treturnValue = {...returnValue, [key]: value};\n\t\t\t}\n\n\t\t\tif (isObject((source as any).hooks)) {\n\t\t\t\thooks = mergeHooks(hooks, (source as any).hooks);\n\t\t\t\treturnValue.hooks = hooks;\n\t\t\t}\n\n\t\t\tif (isObject((source as any).headers)) {\n\t\t\t\theaders = mergeHeaders(headers, (source as any).headers);\n\t\t\t\treturnValue.headers = headers;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (searchParameters !== undefined) {\n\t\treturnValue.searchParams = searchParameters;\n\t}\n\n\tif (signals.length > 0) {\n\t\tif (signals.length === 1) {\n\t\t\treturnValue.signal = signals[0];\n\t\t} else if (supportsAbortSignal) {\n\t\t\treturnValue.signal = AbortSignal.any(signals);\n\t\t} else {\n\t\t\t// When AbortSignal.any is not available, use the last signal\n\t\t\t// This maintains the previous behavior before signal merging was added\n\t\t\t// This can be remove when the `supportsAbortSignal` check is removed.`\n\t\t\treturnValue.signal = signals.at(-1);\n\t\t}\n\t}\n\n\treturn returnValue;\n};\n","import {requestMethods} from '../core/constants.js';\nimport type {RetryOptions} from '../types/retry.js';\nimport type {HttpMethod, RequestHttpMethod} from '../types/options.js';\n\nexport const normalizeRequestMethod = (input: string): string =>\n\trequestMethods.includes(input as RequestHttpMethod) ? input.toUpperCase() : input;\n\nconst retryMethods: HttpMethod[] = ['get', 'put', 'head', 'delete', 'options', 'trace'];\n\nconst retryStatusCodes = [408, 413, 429, 500, 502, 503, 504];\n\nconst retryAfterStatusCodes = [413, 429, 503];\n\ntype InternalRetryOptions = Required<Omit<RetryOptions, 'shouldRetry'>> & Pick<RetryOptions, 'shouldRetry'>;\n\nconst defaultRetryOptions: InternalRetryOptions = {\n\tlimit: 2,\n\tmethods: retryMethods,\n\tstatusCodes: retryStatusCodes,\n\tafterStatusCodes: retryAfterStatusCodes,\n\tmaxRetryAfter: Number.POSITIVE_INFINITY,\n\tbackoffLimit: Number.POSITIVE_INFINITY,\n\tdelay: attemptCount => 0.3 * (2 ** (attemptCount - 1)) * 1000,\n\tjitter: undefined,\n\tretryOnTimeout: false,\n};\n\nexport const normalizeRetryOptions = (retry: number | RetryOptions = {}): InternalRetryOptions => {\n\tif (typeof retry === 'number') {\n\t\treturn {\n\t\t\t...defaultRetryOptions,\n\t\t\tlimit: retry,\n\t\t};\n\t}\n\n\tif (retry.methods && !Array.isArray(retry.methods)) {\n\t\tthrow new Error('retry.methods must be an array');\n\t}\n\n\tretry.methods &&= retry.methods.map(method => method.toLowerCase());\n\n\tif (retry.statusCodes && !Array.isArray(retry.statusCodes)) {\n\t\tthrow new Error('retry.statusCodes must be an array');\n\t}\n\n\tconst normalizedRetry = Object.fromEntries(\n\t\tObject.entries(retry).filter(([, value]) => value !== undefined),\n\t) as RetryOptions;\n\n\treturn {\n\t\t...defaultRetryOptions,\n\t\t...normalizedRetry,\n\t};\n};\n","import type {KyRequest} from '../types/request.js';\n\nexport class TimeoutError extends Error {\n\tpublic request: KyRequest;\n\n\tconstructor(request: Request) {\n\t\tsuper(`Request timed out: ${request.method} ${request.url}`);\n\t\tthis.name = 'TimeoutError';\n\t\tthis.request = request;\n\t}\n}\n","import {TimeoutError} from '../errors/TimeoutError.js';\n\nexport type TimeoutOptions = {\n\ttimeout: number;\n\tfetch: typeof fetch;\n};\n\n// `Promise.race()` workaround (#91)\nexport default async function timeout(\n\trequest: Request,\n\tinit: RequestInit,\n\tabortController: AbortController | undefined,\n\toptions: TimeoutOptions,\n): Promise<Response> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst timeoutId = setTimeout(() => {\n\t\t\tif (abortController) {\n\t\t\t\tabortController.abort();\n\t\t\t}\n\n\t\t\treject(new TimeoutError(request));\n\t\t}, options.timeout);\n\n\t\tvoid options\n\t\t\t.fetch(request, init)\n\t\t\t.then(resolve)\n\t\t\t.catch(reject)\n\t\t\t.then(() => {\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t});\n\t});\n}\n","// https://github.com/sindresorhus/delay/tree/ab98ae8dfcb38e1593286c94d934e70d14a4e111\n\nimport {type InternalOptions} from '../types/options.js';\n\nexport type DelayOptions = {\n\tsignal?: InternalOptions['signal'];\n};\n\nexport default async function delay(\n\tms: number,\n\t{signal}: DelayOptions,\n): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (signal) {\n\t\t\tsignal.throwIfAborted();\n\t\t\tsignal.addEventListener('abort', abortHandler, {once: true});\n\t\t}\n\n\t\tfunction abortHandler() {\n\t\t\tclearTimeout(timeoutId);\n\t\t\treject(signal!.reason as Error);\n\t\t}\n\n\t\tconst timeoutId = setTimeout(() => {\n\t\t\tsignal?.removeEventListener('abort', abortHandler);\n\t\t\tresolve();\n\t\t}, ms);\n\t});\n}\n","import {kyOptionKeys, requestOptionsRegistry, vendorSpecificOptions} from '../core/constants.js';\nimport type {SearchParamsOption} from '../types/options.js';\n\nexport const findUnknownOptions = (\n\trequest: Request,\n\toptions: Record<string, unknown>,\n): Record<string, unknown> => {\n\tconst unknownOptions: Record<string, unknown> = {};\n\n\tfor (const key in options) {\n\t\t// Skip inherited properties\n\t\tif (!Object.hasOwn(options, key)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// An option is passed to fetch() if:\n\t\t// 1. It's not a standard RequestInit option (not in requestOptionsRegistry)\n\t\t// 2. It's not a ky-specific option (not in kyOptionKeys)\n\t\t// 3. Either:\n\t\t// a. It's not on the Request object, OR\n\t\t// b. It's a vendor-specific option that should always be passed (in vendorSpecificOptions)\n\t\tif (!(key in requestOptionsRegistry) && !(key in kyOptionKeys) && (!(key in request) || key in vendorSpecificOptions)) {\n\t\t\tunknownOptions[key] = options[key];\n\t\t}\n\t}\n\n\treturn unknownOptions;\n};\n\nexport const hasSearchParameters = (search: SearchParamsOption): boolean => {\n\tif (search === undefined) {\n\t\treturn false;\n\t}\n\n\t// The `typeof array` still gives \"object\", so we need different checking for array.\n\tif (Array.isArray(search)) {\n\t\treturn search.length > 0;\n\t}\n\n\tif (search instanceof URLSearchParams) {\n\t\treturn search.size > 0;\n\t}\n\n\t// Record\n\tif (typeof search === 'object') {\n\t\treturn Object.keys(search).length > 0;\n\t}\n\n\tif (typeof search === 'string') {\n\t\treturn search.trim().length > 0;\n\t}\n\n\treturn Boolean(search);\n};\n","import {HTTPError} from '../errors/HTTPError.js';\nimport {TimeoutError} from '../errors/TimeoutError.js';\nimport {ForceRetryError} from '../errors/ForceRetryError.js';\n\n/**\nType guard to check if an error is a Ky error.\n\n@param error - The error to check\n@returns `true` if the error is a Ky error, `false` otherwise\n\n@example\n```\nimport ky, {isKyError} from 'ky';\ntry {\n\tconst response = await ky.get('/api/data');\n} catch (error) {\n\tif (isKyError(error)) {\n\t\t// Handle Ky-specific errors\n\t\tconsole.log('Ky error occurred:', error.message);\n\t} else {\n\t\t// Handle other errors\n\t\tconsole.log('Unknown error:', error);\n\t}\n}\n```\n*/\nexport function isKyError(error: unknown): error is HTTPError | TimeoutError | ForceRetryError {\n\treturn isHTTPError(error) || isTimeoutError(error) || isForceRetryError(error);\n}\n\n/**\nType guard to check if an error is an HTTPError.\n\n@param error - The error to check\n@returns `true` if the error is an HTTPError, `false` otherwise\n\n@example\n```\nimport ky, {isHTTPError} from 'ky';\ntry {\n\tconst response = await ky.get('/api/data');\n} catch (error) {\n\tif (isHTTPError(error)) {\n\t\tconsole.log('HTTP error status:', error.response.status);\n\t}\n}\n```\n*/\nexport function isHTTPError<T = unknown>(error: unknown): error is HTTPError<T> {\n\treturn error instanceof HTTPError || ((error as any)?.name === HTTPError.name);\n}\n\n/**\nType guard to check if an error is a TimeoutError.\n\n@param error - The error to check\n@returns `true` if the error is a TimeoutError, `false` otherwise\n\n@example\n```\nimport ky, {isTimeoutError} from 'ky';\ntry {\n\tconst response = await ky.get('/api/data', { timeout: 1000 });\n} catch (error) {\n\tif (isTimeoutError(error)) {\n\t\tconsole.log('Request timed out:', error.request.url);\n\t}\n}\n```\n*/\nexport function isTimeoutError(error: unknown): error is TimeoutError {\n\treturn error instanceof TimeoutError || ((error as any)?.name === TimeoutError.name);\n}\n\n/**\nType guard to check if an error is a ForceRetryError.\n\n@param error - The error to check\n@returns `true` if the error is a ForceRetryError, `false` otherwise\n\n@example\n```\nimport ky, {isForceRetryError} from 'ky';\n\nconst api = ky.extend({\n\thooks: {\n\t\tbeforeRetry: [\n\t\t\t({error, retryCount}) => {\n\t\t\t\tif (isForceRetryError(error)) {\n\t\t\t\t\tconsole.log(`Forced retry #${retryCount}: ${error.code}`);\n\t\t\t\t}\n\t\t\t}\n\t\t]\n\t}\n});\n```\n*/\nexport function isForceRetryError(error: unknown): error is ForceRetryError {\n\treturn error instanceof ForceRetryError || ((error as any)?.name === ForceRetryError.name);\n}\n","import {HTTPError} from '../errors/HTTPError.js';\nimport {NonError} from '../errors/NonError.js';\nimport {ForceRetryError} from '../errors/ForceRetryError.js';\nimport type {\n\tInput,\n\tInternalOptions,\n\tNormalizedOptions,\n\tOptions,\n\tSearchParamsInit,\n\tSearchParamsOption,\n} from '../types/options.js';\nimport {type ResponsePromise} from '../types/ResponsePromise.js';\nimport {streamRequest, streamResponse} from '../utils/body.js';\nimport {mergeHeaders, mergeHooks} from '../utils/merge.js';\nimport {normalizeRequestMethod, normalizeRetryOptions} from '../utils/normalize.js';\nimport timeout, {type TimeoutOptions} from '../utils/timeout.js';\nimport delay from '../utils/delay.js';\nimport {type ObjectEntries} from '../utils/types.js';\nimport {findUnknownOptions, hasSearchParameters} from '../utils/options.js';\nimport {isHTTPError, isTimeoutError} from '../utils/type-guards.js';\nimport {\n\tmaxSafeTimeout,\n\tresponseTypes,\n\tstop,\n\tRetryMarker,\n\tsupportsAbortController,\n\tsupportsAbortSignal,\n\tsupportsFormData,\n\tsupportsResponseStreams,\n\tsupportsRequestStreams,\n} from './constants.js';\n\nexport class Ky {\n\tstatic create(input: Input, options: Options): ResponsePromise {\n\t\tconst ky = new Ky(input, options);\n\n\t\tconst function_ = async (): Promise<Response> => {\n\t\t\tif (typeof ky.#options.timeout === 'number' && ky.#options.timeout > maxSafeTimeout) {\n\t\t\t\tthrow new RangeError(`The \\`timeout\\` option cannot be greater than ${maxSafeTimeout}`);\n\t\t\t}\n\n\t\t\t// Delay the fetch so that body method shortcuts can set the Accept header\n\t\t\tawait Promise.resolve();\n\t\t\t// Before using ky.request, _fetch clones it and saves the clone for future retries to use.\n\t\t\t// If retry is not needed, close the cloned request's ReadableStream for memory safety.\n\t\t\tlet response = await ky.#fetch();\n\n\t\t\tfor (const hook of ky.#options.hooks.afterResponse) {\n\t\t\t\t// Clone the response before passing to hook so we can cancel it if needed\n\t\t\t\tconst clonedResponse = ky.#decorateResponse(response.clone());\n\n\t\t\t\tlet modifiedResponse;\n\t\t\t\ttry {\n\t\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\t\tmodifiedResponse = await hook(\n\t\t\t\t\t\tky.request,\n\t\t\t\t\t\tky.#getNormalizedOptions(),\n\t\t\t\t\t\tclonedResponse,\n\t\t\t\t\t\t{retryCount: ky.#retryCount},\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Cancel both responses to prevent memory leaks when hook throws\n\t\t\t\t\tky.#cancelResponseBody(clonedResponse);\n\t\t\t\t\tky.#cancelResponseBody(response);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\tif (modifiedResponse instanceof RetryMarker) {\n\t\t\t\t\t// Cancel both the cloned response passed to the hook and the current response to prevent resource leaks (especially important in Deno/Bun).\n\t\t\t\t\t// Do not await cancellation since hooks can clone the response, leaving extra tee branches that keep cancel promises pending per the Streams spec.\n\t\t\t\t\tky.#cancelResponseBody(clonedResponse);\n\t\t\t\t\tky.#cancelResponseBody(response);\n\t\t\t\t\tthrow new ForceRetryError(modifiedResponse.options);\n\t\t\t\t}\n\n\t\t\t\t// Determine which response to use going forward\n\t\t\t\tconst nextResponse = modifiedResponse instanceof globalThis.Response ? modifiedResponse : response;\n\n\t\t\t\t// Cancel any response bodies we won't use to prevent memory leaks.\n\t\t\t\t// Uses fire-and-forget since hooks may have cloned the response, creating tee branches that block cancellation.\n\t\t\t\tif (clonedResponse !== nextResponse) {\n\t\t\t\t\tky.#cancelResponseBody(clonedResponse);\n\t\t\t\t}\n\n\t\t\t\tif (response !== nextResponse) {\n\t\t\t\t\tky.#cancelResponseBody(response);\n\t\t\t\t}\n\n\t\t\t\tresponse = nextResponse;\n\t\t\t}\n\n\t\t\tky.#decorateResponse(response);\n\n\t\t\tif (!response.ok && (\n\t\t\t\ttypeof ky.#options.throwHttpErrors === 'function'\n\t\t\t\t\t? ky.#options.throwHttpErrors(response.status)\n\t\t\t\t\t: ky.#options.throwHttpErrors\n\t\t\t)) {\n\t\t\t\tlet error = new HTTPError(response, ky.request, ky.#getNormalizedOptions());\n\n\t\t\t\tfor (const hook of ky.#options.hooks.beforeError) {\n\t\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\t\terror = await hook(error, {retryCount: ky.#retryCount});\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\t// If `onDownloadProgress` is passed, it uses the stream API internally\n\t\t\tif (ky.#options.onDownloadProgress) {\n\t\t\t\tif (typeof ky.#options.onDownloadProgress !== 'function') {\n\t\t\t\t\tthrow new TypeError('The `onDownloadProgress` option must be a function');\n\t\t\t\t}\n\n\t\t\t\tif (!supportsResponseStreams) {\n\t\t\t\t\tthrow new Error('Streams are not supported in your environment. `ReadableStream` is missing.');\n\t\t\t\t}\n\n\t\t\t\tconst progressResponse = response.clone();\n\t\t\t\tky.#cancelResponseBody(response);\n\t\t\t\treturn streamResponse(progressResponse, ky.#options.onDownloadProgress);\n\t\t\t}\n\n\t\t\treturn response;\n\t\t};\n\n\t\t// Always wrap in #retry to catch forced retries from afterResponse hooks\n\t\t// Method retriability is checked in #calculateRetryDelay for non-forced retries\n\t\tconst result = ky.#retry(function_)\n\t\t\t.finally(() => {\n\t\t\t\tconst originalRequest = ky.#originalRequest;\n\n\t\t\t\t// Ignore cancellation errors from already-locked or already-consumed streams.\n\t\t\t\tky.#cancelBody(originalRequest?.body ?? undefined);\n\t\t\t\tky.#cancelBody(ky.request.body ?? undefined);\n\t\t\t}) as ResponsePromise;\n\n\t\tfor (const [type, mimeType] of Object.entries(responseTypes) as ObjectEntries<typeof responseTypes>) {\n\t\t\t// Only expose `.bytes()` when the environment implements it.\n\t\t\tif (\n\t\t\t\ttype === 'bytes'\n\t\t\t\t&& typeof (globalThis.Response?.prototype as unknown as {bytes?: unknown})?.bytes !== 'function'\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tresult[type] = async () => {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n\t\t\t\tky.request.headers.set('accept', ky.request.headers.get('accept') || mimeType);\n\n\t\t\t\tconst response = await result;\n\n\t\t\t\tif (type === 'json') {\n\t\t\t\t\tif (response.status === 204) {\n\t\t\t\t\t\treturn '';\n\t\t\t\t\t}\n\n\t\t\t\t\tconst text = await response.text();\n\t\t\t\t\tif (text === '') {\n\t\t\t\t\t\treturn '';\n\t\t\t\t\t}\n\n\t\t\t\t\tif (options.parseJson) {\n\t\t\t\t\t\treturn options.parseJson(text);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn JSON.parse(text);\n\t\t\t\t}\n\n\t\t\t\treturn response[type]();\n\t\t\t};\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t// eslint-disable-next-line unicorn/prevent-abbreviations\n\tstatic #normalizeSearchParams(searchParams: SearchParamsOption): SearchParamsOption {\n\t\t// Filter out undefined values from plain objects\n\t\tif (searchParams && typeof searchParams === 'object' && !Array.isArray(searchParams) && !(searchParams instanceof URLSearchParams)) {\n\t\t\treturn Object.fromEntries(\n\t\t\t\tObject.entries(searchParams).filter(([, value]) => value !== undefined),\n\t\t\t);\n\t\t}\n\n\t\treturn searchParams;\n\t}\n\n\tpublic request: Request;\n\t#abortController?: AbortController;\n\t#retryCount = 0;\n\t// eslint-disable-next-line @typescript-eslint/prefer-readonly -- False positive: #input is reassigned on line 202\n\t#input: Input;\n\treadonly #options: InternalOptions;\n\t#originalRequest?: Request;\n\treadonly #userProvidedAbortSignal?: AbortSignal;\n\t#cachedNormalizedOptions: NormalizedOptions | undefined;\n\n\t// eslint-disable-next-line complexity\n\tconstructor(input: Input, options: Options = {}) {\n\t\tthis.#input = input;\n\n\t\tthis.#options = {\n\t\t\t...options,\n\t\t\theaders: mergeHeaders((this.#input as Request).headers, options.headers),\n\t\t\thooks: mergeHooks(\n\t\t\t\t{\n\t\t\t\t\tbeforeRequest: [],\n\t\t\t\t\tbeforeRetry: [],\n\t\t\t\t\tbeforeError: [],\n\t\t\t\t\tafterResponse: [],\n\t\t\t\t},\n\t\t\t\toptions.hooks,\n\t\t\t),\n\t\t\tmethod: normalizeRequestMethod(options.method ?? (this.#input as Request).method ?? 'GET'),\n\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n\t\t\tprefixUrl: String(options.prefixUrl || ''),\n\t\t\tretry: normalizeRetryOptions(options.retry),\n\t\t\tthrowHttpErrors: options.throwHttpErrors ?? true,\n\t\t\ttimeout: options.timeout ?? 10_000,\n\t\t\tfetch: options.fetch ?? globalThis.fetch.bind(globalThis),\n\t\t\tcontext: options.context ?? {},\n\t\t};\n\n\t\tif (typeof this.#input !== 'string' && !(this.#input instanceof URL || this.#input instanceof globalThis.Request)) {\n\t\t\tthrow new TypeError('`input` must be a string, URL, or Request');\n\t\t}\n\n\t\tif (this.#options.prefixUrl && typeof this.#input === 'string') {\n\t\t\tif (this.#input.startsWith('/')) {\n\t\t\t\tthrow new Error('`input` must not begin with a slash when using `prefixUrl`');\n\t\t\t}\n\n\t\t\tif (!this.#options.prefixUrl.endsWith('/')) {\n\t\t\t\tthis.#options.prefixUrl += '/';\n\t\t\t}\n\n\t\t\tthis.#input = this.#options.prefixUrl + this.#input;\n\t\t}\n\n\t\tif (supportsAbortController && supportsAbortSignal) {\n\t\t\tthis.#userProvidedAbortSignal = this.#options.signal ?? (this.#input as Request).signal;\n\t\t\tthis.#abortController = new globalThis.AbortController();\n\t\t\tthis.#options.signal = this.#userProvidedAbortSignal ? AbortSignal.any([this.#userProvidedAbortSignal, this.#abortController.signal]) : this.#abortController.signal;\n\t\t}\n\n\t\tif (supportsRequestStreams) {\n\t\t\t// @ts-expect-error - Types are outdated.\n\t\t\tthis.#options.duplex = 'half';\n\t\t}\n\n\t\tif (this.#options.json !== undefined) {\n\t\t\tthis.#options.body = this.#options.stringifyJson?.(this.#options.json) ?? JSON.stringify(this.#options.json);\n\t\t\tthis.#options.headers.set('content-type', this.#options.headers.get('content-type') ?? 'application/json');\n\t\t}\n\n\t\t// To provide correct form boundary, Content-Type header should be deleted when creating Request from another Request with FormData/URLSearchParams body\n\t\t// Only delete if user didn't explicitly provide a custom content-type\n\t\tconst userProvidedContentType = options.headers && new globalThis.Headers(options.headers as HeadersInit).has('content-type');\n\t\tif (\n\t\t\tthis.#input instanceof globalThis.Request\n\t\t\t&& ((supportsFormData && this.#options.body instanceof globalThis.FormData) || this.#options.body instanceof URLSearchParams)\n\t\t\t&& !userProvidedContentType\n\t\t) {\n\t\t\tthis.#options.headers.delete('content-type');\n\t\t}\n\n\t\tthis.request = new globalThis.Request(this.#input, this.#options);\n\n\t\tif (hasSearchParameters(this.#options.searchParams)) {\n\t\t\t// eslint-disable-next-line unicorn/prevent-abbreviations\n\t\t\tconst textSearchParams = typeof this.#options.searchParams === 'string'\n\t\t\t\t? this.#options.searchParams.replace(/^\\?/, '')\n\t\t\t\t: new URLSearchParams(Ky.#normalizeSearchParams(this.#options.searchParams) as unknown as SearchParamsInit).toString();\n\t\t\t// eslint-disable-next-line unicorn/prevent-abbreviations\n\t\t\tconst searchParams = '?' + textSearchParams;\n\t\t\tconst url = this.request.url.replace(/(?:\\?.*?)?(?=#|$)/, searchParams);\n\n\t\t\t// Recreate request with the updated URL. We already have all options in this.#options, including duplex.\n\t\t\tthis.request = new globalThis.Request(url, this.#options as RequestInit);\n\t\t}\n\n\t\t// If `onUploadProgress` is passed, it uses the stream API internally\n\t\tif (this.#options.onUploadProgress) {\n\t\t\tif (typeof this.#options.onUploadProgress !== 'function') {\n\t\t\t\tthrow new TypeError('The `onUploadProgress` option must be a function');\n\t\t\t}\n\n\t\t\tif (!supportsRequestStreams) {\n\t\t\t\tthrow new Error('Request streams are not supported in your environment. The `duplex` option for `Request` is not available.');\n\t\t\t}\n\n\t\t\tthis.request = this.#wrapRequestWithUploadProgress(this.request, this.#options.body ?? undefined);\n\t\t}\n\t}\n\n\t#calculateDelay(): number {\n\t\tconst retryDelay = this.#options.retry.delay(this.#retryCount);\n\n\t\tlet jitteredDelay = retryDelay;\n\t\tif (this.#options.retry.jitter === true) {\n\t\t\tjitteredDelay = Math.random() * retryDelay;\n\t\t} else if (typeof this.#options.retry.jitter === 'function') {\n\t\t\tjitteredDelay = this.#options.retry.jitter(retryDelay);\n\n\t\t\tif (!Number.isFinite(jitteredDelay) || jitteredDelay < 0) {\n\t\t\t\tjitteredDelay = retryDelay;\n\t\t\t}\n\t\t}\n\n\t\t// Handle undefined backoffLimit by treating it as no limit (Infinity)\n\t\tconst backoffLimit = this.#options.retry.backoffLimit ?? Number.POSITIVE_INFINITY;\n\t\treturn Math.min(backoffLimit, jitteredDelay);\n\t}\n\n\tasync #calculateRetryDelay(error: unknown) {\n\t\tthis.#retryCount++;\n\n\t\tif (this.#retryCount > this.#options.retry.limit) {\n\t\t\tthrow error;\n\t\t}\n\n\t\t// Wrap non-Error throws to ensure consistent error handling\n\t\tconst errorObject = error instanceof Error ? error : new NonError(error);\n\n\t\t// Handle forced retry from afterResponse hook - skip method check and shouldRetry\n\t\tif (errorObject instanceof ForceRetryError) {\n\t\t\treturn errorObject.customDelay ?? this.#calculateDelay();\n\t\t}\n\n\t\t// Check if method is retriable for non-forced retries\n\t\tif (!this.#options.retry.methods.includes(this.request.method.toLowerCase())) {\n\t\t\tthrow error;\n\t\t}\n\n\t\t// User-provided shouldRetry function takes precedence over all other checks\n\t\tif (this.#options.retry.shouldRetry !== undefined) {\n\t\t\tconst result = await this.#options.retry.shouldRetry({error: errorObject, retryCount: this.#retryCount});\n\n\t\t\t// Strict boolean checking - only exact true/false are handled specially\n\t\t\tif (result === false) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tif (result === true) {\n\t\t\t\t// Force retry - skip all other validation and return delay\n\t\t\t\treturn this.#calculateDelay();\n\t\t\t}\n\n\t\t\t// If undefined or any other value, fall through to default behavior\n\t\t}\n\n\t\t// Default timeout behavior\n\t\tif (isTimeoutError(error) && !this.#options.retry.retryOnTimeout) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tif (isHTTPError(error)) {\n\t\t\tif (!this.#options.retry.statusCodes.includes(error.response.status)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tconst retryAfter = error.response.headers.get('Retry-After')\n\t\t\t\t?? error.response.headers.get('RateLimit-Reset')\n\t\t\t\t?? error.response.headers.get('X-RateLimit-Retry-After') // Symfony-based services\n\t\t\t\t?? error.response.headers.get('X-RateLimit-Reset') // GitHub\n\t\t\t\t?? error.response.headers.get('X-Rate-Limit-Reset'); // Twitter\n\t\t\tif (retryAfter && this.#options.retry.afterStatusCodes.includes(error.response.status)) {\n\t\t\t\tlet after = Number(retryAfter) * 1000;\n\t\t\t\tif (Number.isNaN(after)) {\n\t\t\t\t\tafter = Date.parse(retryAfter) - Date.now();\n\t\t\t\t} else if (after >= Date.parse('2024-01-01')) {\n\t\t\t\t\t// A large number is treated as a timestamp (fixed threshold protects against clock skew)\n\t\t\t\t\tafter -= Date.now();\n\t\t\t\t}\n\n\t\t\t\tconst max = this.#options.retry.maxRetryAfter ?? after;\n\t\t\t\t// Don't apply jitter when server provides explicit retry timing\n\t\t\t\treturn after < max ? after : max;\n\t\t\t}\n\n\t\t\tif (error.response.status === 413) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn this.#calculateDelay();\n\t}\n\n\t#decorateResponse(response: Response): Response {\n\t\tif (this.#options.parseJson) {\n\t\t\tresponse.json = async () => this.#options.parseJson!(await response.text());\n\t\t}\n\n\t\treturn response;\n\t}\n\n\t#cancelBody(body: ReadableStream | undefined): void {\n\t\tif (!body) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Ignore cancellation failures from already-locked or already-consumed streams.\n\t\tvoid body.cancel().catch(() => undefined);\n\t}\n\n\t#cancelResponseBody(response: Response): void {\n\t\t// Ignore cancellation failures from already-locked or already-consumed streams.\n\t\tthis.#cancelBody(response.body ?? undefined);\n\t}\n\n\tasync #retry<T extends (...arguments_: any) => Promise<any>>(function_: T): Promise<ReturnType<T> | Response | void> {\n\t\ttry {\n\t\t\treturn await function_();\n\t\t} catch (error) {\n\t\t\tconst ms = Math.min(await this.#calculateRetryDelay(error), maxSafeTimeout);\n\t\t\tif (this.#retryCount < 1) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\t// Only use user-provided signal for delay, not our internal abortController\n\t\t\tawait delay(ms, this.#userProvidedAbortSignal ? {signal: this.#userProvidedAbortSignal} : {});\n\n\t\t\t// Apply custom request from forced retry before beforeRetry hooks\n\t\t\t// Ensure the custom request has the correct managed signal for timeouts and user aborts\n\t\t\tif (error instanceof ForceRetryError && error.customRequest) {\n\t\t\t\tconst managedRequest = this.#options.signal\n\t\t\t\t\t? new globalThis.Request(error.customRequest, {signal: this.#options.signal})\n\t\t\t\t\t: new globalThis.Request(error.customRequest);\n\n\t\t\t\tthis.#assignRequest(managedRequest);\n\t\t\t}\n\n\t\t\tfor (const hook of this.#options.hooks.beforeRetry) {\n\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\tconst hookResult = await hook({\n\t\t\t\t\trequest: this.request,\n\t\t\t\t\toptions: this.#getNormalizedOptions(),\n\t\t\t\t\terror: error as Error,\n\t\t\t\t\tretryCount: this.#retryCount,\n\t\t\t\t});\n\n\t\t\t\tif (hookResult instanceof globalThis.Request) {\n\t\t\t\t\tthis.#assignRequest(hookResult);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// If a Response is returned, use it and skip the retry\n\t\t\t\tif (hookResult instanceof globalThis.Response) {\n\t\t\t\t\treturn hookResult;\n\t\t\t\t}\n\n\t\t\t\t// If `stop` is returned from the hook, the retry process is stopped\n\t\t\t\tif (hookResult === stop) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn this.#retry(function_);\n\t\t}\n\t}\n\n\tasync #fetch(): Promise<Response> {\n\t\t// Reset abortController if it was aborted (happens on timeout retry)\n\t\tif (this.#abortController?.signal.aborted) {\n\t\t\tthis.#abortController = new globalThis.AbortController();\n\t\t\tthis.#options.signal = this.#userProvidedAbortSignal ? AbortSignal.any([this.#userProvidedAbortSignal, this.#abortController.signal]) : this.#abortController.signal;\n\t\t\t// Recreate request with new signal\n\t\t\tthis.request = new globalThis.Request(this.request, {signal: this.#options.signal});\n\t\t}\n\n\t\tfor (const hook of this.#options.hooks.beforeRequest) {\n\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\tconst result = await hook(\n\t\t\t\tthis.request,\n\t\t\t\tthis.#getNormalizedOptions(),\n\t\t\t\t{retryCount: this.#retryCount},\n\t\t\t);\n\n\t\t\tif (result instanceof Response) {\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tif (result instanceof globalThis.Request) {\n\t\t\t\tthis.#assignRequest(result);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tconst nonRequestOptions = findUnknownOptions(this.request, this.#options);\n\n\t\t// Cloning is done here to prepare in advance for retries\n\t\tthis.#originalRequest = this.request;\n\t\tthis.request = this.#originalRequest.clone();\n\n\t\tif (this.#options.timeout === false) {\n\t\t\treturn this.#options.fetch(this.#originalRequest, nonRequestOptions);\n\t\t}\n\n\t\treturn timeout(this.#originalRequest, nonRequestOptions, this.#abortController, this.#options as TimeoutOptions);\n\t}\n\n\t#getNormalizedOptions(): NormalizedOptions {\n\t\tif (!this.#cachedNormalizedOptions) {\n\t\t\tconst {hooks, ...normalizedOptions} = this.#options;\n\t\t\tthis.#cachedNormalizedOptions = Object.freeze(normalizedOptions) as NormalizedOptions;\n\t\t}\n\n\t\treturn this.#cachedNormalizedOptions;\n\t}\n\n\t#assignRequest(request: Request): void {\n\t\tthis.#cachedNormalizedOptions = undefined;\n\t\tthis.request = this.#wrapRequestWithUploadProgress(request);\n\t}\n\n\t#wrapRequestWithUploadProgress(request: Request, originalBody?: BodyInit): Request {\n\t\tif (!this.#options.onUploadProgress || !request.body) {\n\t\t\treturn request;\n\t\t}\n\n\t\treturn streamRequest(request, this.#options.onUploadProgress, originalBody ?? this.#options.body ?? undefined);\n\t}\n}\n","/*! MIT License © Sindre Sorhus */\n\nimport {Ky} from './core/Ky.js';\nimport {requestMethods, stop, retry} from './core/constants.js';\nimport type {KyInstance} from './types/ky.js';\nimport type {Input, Options} from './types/options.js';\nimport {validateAndMerge} from './utils/merge.js';\nimport {type Mutable} from './utils/types.js';\n\nconst createInstance = (defaults?: Partial<Options>): KyInstance => {\n\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\tconst ky: Partial<Mutable<KyInstance>> = (input: Input, options?: Options) => Ky.create(input, validateAndMerge(defaults, options));\n\n\tfor (const method of requestMethods) {\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\tky[method] = (input: Input, options?: Options) => Ky.create(input, validateAndMerge(defaults, options, {method}));\n\t}\n\n\tky.create = (newDefaults?: Partial<Options>) => createInstance(validateAndMerge(newDefaults));\n\tky.extend = (newDefaults?: Partial<Options> | ((parentDefaults: Partial<Options>) => Partial<Options>)) => {\n\t\tif (typeof newDefaults === 'function') {\n\t\t\tnewDefaults = newDefaults(defaults ?? {});\n\t\t}\n\n\t\treturn createInstance(validateAndMerge(defaults, newDefaults));\n\t};\n\n\tky.stop = stop;\n\tky.retry = retry;\n\n\treturn ky as KyInstance;\n};\n\nconst ky = createInstance();\n\nexport default ky;\n\nexport type {KyInstance} from './types/ky.js';\n\nexport type {\n\tInput,\n\tOptions,\n\tNormalizedOptions,\n\tRetryOptions,\n\tShouldRetryState,\n\tSearchParamsOption,\n\tProgress,\n} from './types/options.js';\n\nexport type {\n\tHooks,\n\tBeforeRequestHook,\n\tBeforeRequestState,\n\tBeforeRetryHook,\n\tBeforeRetryState,\n\tBeforeErrorHook,\n\tBeforeErrorState,\n\tAfterResponseHook,\n\tAfterResponseState,\n} from './types/hooks.js';\n\nexport type {ResponsePromise} from './types/ResponsePromise.js';\nexport type {KyRequest} from './types/request.js';\nexport type {KyResponse} from './types/response.js';\nexport {HTTPError} from './errors/HTTPError.js';\nexport {TimeoutError} from './errors/TimeoutError.js';\nexport {ForceRetryError} from './errors/ForceRetryError.js';\nexport {\n\tisKyError,\n\tisHTTPError,\n\tisTimeoutError,\n\tisForceRetryError,\n} from './utils/type-guards.js';\n\n// Intentionally not exporting this for now as it's just an implementation detail and we don't want to commit to a certain API yet at least.\n// export {NonError} from './errors/NonError.js';\n"],"mappings":"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","names":["retry","ky","ky"]}
@@ -33,7 +33,7 @@ __export(rest_api_client_exports, {
33
33
  failedResponseBody: () => failedResponseBody
34
34
  });
35
35
  module.exports = __toCommonJS(rest_api_client_exports);
36
- var import_ky = __toESM(require("ky"));
36
+ var import_ky = __toESM(require("./ky"));
37
37
  var Schema = __toESM(require("./schema"));
38
38
  const RetryBackoffConfig = {
39
39
  MaxAttempts: 3,
@@ -172,7 +172,7 @@ class MakeswiftRestAPIClient {
172
172
  const requestHeaders = new Headers({
173
173
  "x-api-key": this.apiKey,
174
174
  "makeswift-site-api-key": this.apiKey,
175
- "makeswift-runtime-version": "0.28.8"
175
+ "makeswift-runtime-version": "0.28.9-canary.0"
176
176
  });
177
177
  if (siteVersion?.token) {
178
178
  requestUrl.searchParams.set("version", siteVersion.version);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/api/rest-api-client.ts"],"sourcesContent":["import ky, { HTTPError, isHTTPError, type KyInstance } from 'ky'\n\nimport {\n type GlobalElement,\n type LocalizedGlobalElement,\n type PagePathnameSlice,\n type Swatch,\n type Typography,\n type HttpFetch,\n} from './types'\n\nimport { type SiteVersion } from './site-version'\nimport * as Schema from './schema'\n\nconst RetryBackoffConfig = {\n MaxAttempts: 3,\n MaxDelayMs: 5_000,\n}\n\nexport class MakeswiftRestAPIClient {\n private _fetch: KyInstance\n\n readonly apiKey: string\n readonly apiOrigin: string\n\n constructor({\n fetch,\n apiKey,\n apiOrigin,\n }: {\n fetch: HttpFetch\n apiKey: string\n apiOrigin: string\n }) {\n this._fetch = ky.create({\n fetch,\n timeout: false,\n retry: {\n statusCodes: [429],\n limit: RetryBackoffConfig.MaxAttempts,\n backoffLimit: RetryBackoffConfig.MaxDelayMs,\n delay: attemptCount => 2 ** (attemptCount - 1) * 1000,\n jitter: true,\n },\n hooks: {\n beforeRetry: [\n async ({ request, error, retryCount }) => {\n console.warn(\n `Request to ${request.url} failed with ${error}. Retrying (${retryCount}/${RetryBackoffConfig.MaxAttempts})`,\n )\n // Drain the response body before retrying so we don't leak unconsumed\n // response bodies (see the comment on `failedResponseBody` below).\n if (isHTTPError(error)) await failedResponseBody(error.response)\n },\n ],\n },\n })\n\n this.apiKey = apiKey\n this.apiOrigin = apiOrigin\n }\n\n async getSwatch(swatchId: string, siteVersion: SiteVersion | null): Promise<Swatch | null> {\n const response = await this.fetch(`v3/swatches/${swatchId}`, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(`Failed to get swatch '${swatchId}'`, response, {\n body: failedBody,\n siteVersion,\n })\n }\n\n const swatch = await response.json()\n\n return swatch\n }\n\n async getTypography(\n typographyId: string,\n siteVersion: SiteVersion | null,\n ): Promise<Typography | null> {\n const response = await this.fetch(`v3/typographies/${typographyId}`, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(`Failed to get typography '${typographyId}'`, response, {\n body: failedBody,\n siteVersion,\n })\n }\n\n const typography = await response.json()\n\n return typography\n }\n\n async getGlobalElement(\n globalElementId: string,\n siteVersion: SiteVersion | null,\n ): Promise<GlobalElement | null> {\n const response = await this.fetch(`v3/global-elements/${globalElementId}`, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(`Failed to get global element '${globalElementId}'`, response, {\n body: failedBody,\n siteVersion,\n })\n }\n\n const globalElement = await response.json()\n\n return globalElement\n }\n\n async getLocalizedGlobalElement(\n globalElementId: string,\n locale: string,\n siteVersion: SiteVersion | null,\n ): Promise<LocalizedGlobalElement | null> {\n const response = await this.fetch(\n `v3/localized-global-elements/${globalElementId}?locale=${locale}`,\n siteVersion,\n )\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(\n `Failed to get localized global element '${globalElementId}'`,\n response,\n { body: failedBody, siteVersion, locale },\n )\n }\n\n const localizedGlobalElement = await response.json()\n\n return localizedGlobalElement\n }\n\n async getPagePathnameSlices(\n pageIds: string[],\n siteVersion: SiteVersion | null,\n { locale }: { locale?: string | null },\n ): Promise<(PagePathnameSlice | null)[]> {\n if (pageIds.length === 0) return []\n\n const url = new URL(`v3/page-pathname-slices/bulk`, this.apiOrigin)\n\n pageIds.forEach(id => url.searchParams.append('ids', id))\n if (locale != null) url.searchParams.set('locale', locale)\n\n const response = await this.fetch(url.pathname + url.search, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return []\n\n throw new RestApiClientError(\n `Failed to get page pathname slice(s) for ${pageIds.join(', ')}`,\n response,\n { body: failedBody, siteVersion, locale },\n )\n }\n\n const json = await response.json()\n\n const pagePathnameSlices = Schema.pagePathnameSlices.parse(json)\n\n // We're mapping the basePageId to be the id, because we're still using the GraphQL\n // fragment as our APIResource. The id on the APIResource needs to match the pageId\n // so that we can find the corresponding page pathname slice when we call getPagePathnameSlice(pageId).\n // TODO: Update this once we move away from the GraphQL fragments.\n return pagePathnameSlices.map(pagePathnameSlice => {\n if (pagePathnameSlice == null) return null\n\n return {\n ...pagePathnameSlice,\n id: pagePathnameSlice.basePageId,\n localizedPathname: pagePathnameSlice.localizedPathname ?? null,\n }\n })\n }\n\n async getPagePathnameSlice(\n pageId: string,\n siteVersion: SiteVersion | null,\n { locale }: { locale?: string | null } = {},\n ): Promise<PagePathnameSlice | null> {\n const pagePathnameSlices = await this.getPagePathnameSlices([pageId], siteVersion, { locale })\n\n return pagePathnameSlices.at(0) ?? null\n }\n\n protected async fetch(\n path: string,\n siteVersion: SiteVersion | null,\n init?: RequestInit,\n ): Promise<Response> {\n const requestUrl = new URL(path, this.apiOrigin)\n\n const requestHeaders = new Headers({\n 'x-api-key': this.apiKey,\n 'makeswift-site-api-key': this.apiKey,\n 'makeswift-runtime-version': PACKAGE_VERSION,\n })\n\n if (siteVersion?.token) {\n requestUrl.searchParams.set('version', siteVersion.version)\n requestHeaders.set('makeswift-preview-token', siteVersion.token)\n }\n\n if (init?.headers) {\n new Headers(init.headers).forEach((value, key) => {\n requestHeaders.set(key, value)\n })\n }\n\n try {\n return await this._fetch(requestUrl.toString(), {\n ...init,\n headers: requestHeaders,\n ...(siteVersion != null ? { cache: 'no-store' } : {}),\n })\n } catch (error) {\n if (error instanceof HTTPError) return error.response\n throw error\n }\n }\n}\n\n// This function attempts to consume the response body of a failed response, and\n// returns either the parsed JSON or raw text. This is useful for logging more\n// detailed error information when an API request fails.\n//\n// Cloudflare Worker Note: The Cloudflare Worker runtime has automatic deadlock\n// prevention (in the form of auto-cancelling responses) that triggers when too\n// many response bodies are unconsumed. This applies for error responses as\n// well. As such, in this client we use this function to consume the response\n// body whenever the request fails, even if we don't end up logging the body\n// itself, to avoid hitting the deadlock prevention.\nexport async function failedResponseBody(response: Response): Promise<unknown> {\n try {\n const text = await response.text()\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n } catch (e) {\n return `Failed to extract response body: ${e}`\n }\n}\n\nfunction responseError(response: Response): string {\n return `${response.status} ${response.statusText}`\n}\n\nexport class RestApiClientError extends Error {\n readonly status: number\n\n constructor(message: string, response: Response, cause: Record<string, unknown>) {\n super(`${message}: ${responseError(response)}`, { cause })\n\n this.name = 'RestApiClientError'\n this.status = response.status\n }\n}\n"],"mappings":"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","names":["ky"]}
1
+ {"version":3,"sources":["../../../src/api/rest-api-client.ts"],"sourcesContent":["import ky, { HTTPError, isHTTPError, type KyInstance } from './ky'\n\nimport {\n type GlobalElement,\n type LocalizedGlobalElement,\n type PagePathnameSlice,\n type Swatch,\n type Typography,\n type HttpFetch,\n} from './types'\n\nimport { type SiteVersion } from './site-version'\nimport * as Schema from './schema'\n\nconst RetryBackoffConfig = {\n MaxAttempts: 3,\n MaxDelayMs: 5_000,\n}\n\nexport class MakeswiftRestAPIClient {\n private _fetch: KyInstance\n\n readonly apiKey: string\n readonly apiOrigin: string\n\n constructor({\n fetch,\n apiKey,\n apiOrigin,\n }: {\n fetch: HttpFetch\n apiKey: string\n apiOrigin: string\n }) {\n this._fetch = ky.create({\n fetch,\n timeout: false,\n retry: {\n statusCodes: [429],\n limit: RetryBackoffConfig.MaxAttempts,\n backoffLimit: RetryBackoffConfig.MaxDelayMs,\n delay: attemptCount => 2 ** (attemptCount - 1) * 1000,\n jitter: true,\n },\n hooks: {\n beforeRetry: [\n async ({ request, error, retryCount }) => {\n console.warn(\n `Request to ${request.url} failed with ${error}. Retrying (${retryCount}/${RetryBackoffConfig.MaxAttempts})`,\n )\n // Drain the response body before retrying so we don't leak unconsumed\n // response bodies (see the comment on `failedResponseBody` below).\n if (isHTTPError(error)) await failedResponseBody(error.response)\n },\n ],\n },\n })\n\n this.apiKey = apiKey\n this.apiOrigin = apiOrigin\n }\n\n async getSwatch(swatchId: string, siteVersion: SiteVersion | null): Promise<Swatch | null> {\n const response = await this.fetch(`v3/swatches/${swatchId}`, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(`Failed to get swatch '${swatchId}'`, response, {\n body: failedBody,\n siteVersion,\n })\n }\n\n const swatch = await response.json()\n\n return swatch\n }\n\n async getTypography(\n typographyId: string,\n siteVersion: SiteVersion | null,\n ): Promise<Typography | null> {\n const response = await this.fetch(`v3/typographies/${typographyId}`, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(`Failed to get typography '${typographyId}'`, response, {\n body: failedBody,\n siteVersion,\n })\n }\n\n const typography = await response.json()\n\n return typography\n }\n\n async getGlobalElement(\n globalElementId: string,\n siteVersion: SiteVersion | null,\n ): Promise<GlobalElement | null> {\n const response = await this.fetch(`v3/global-elements/${globalElementId}`, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(`Failed to get global element '${globalElementId}'`, response, {\n body: failedBody,\n siteVersion,\n })\n }\n\n const globalElement = await response.json()\n\n return globalElement\n }\n\n async getLocalizedGlobalElement(\n globalElementId: string,\n locale: string,\n siteVersion: SiteVersion | null,\n ): Promise<LocalizedGlobalElement | null> {\n const response = await this.fetch(\n `v3/localized-global-elements/${globalElementId}?locale=${locale}`,\n siteVersion,\n )\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(\n `Failed to get localized global element '${globalElementId}'`,\n response,\n { body: failedBody, siteVersion, locale },\n )\n }\n\n const localizedGlobalElement = await response.json()\n\n return localizedGlobalElement\n }\n\n async getPagePathnameSlices(\n pageIds: string[],\n siteVersion: SiteVersion | null,\n { locale }: { locale?: string | null },\n ): Promise<(PagePathnameSlice | null)[]> {\n if (pageIds.length === 0) return []\n\n const url = new URL(`v3/page-pathname-slices/bulk`, this.apiOrigin)\n\n pageIds.forEach(id => url.searchParams.append('ids', id))\n if (locale != null) url.searchParams.set('locale', locale)\n\n const response = await this.fetch(url.pathname + url.search, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return []\n\n throw new RestApiClientError(\n `Failed to get page pathname slice(s) for ${pageIds.join(', ')}`,\n response,\n { body: failedBody, siteVersion, locale },\n )\n }\n\n const json = await response.json()\n\n const pagePathnameSlices = Schema.pagePathnameSlices.parse(json)\n\n // We're mapping the basePageId to be the id, because we're still using the GraphQL\n // fragment as our APIResource. The id on the APIResource needs to match the pageId\n // so that we can find the corresponding page pathname slice when we call getPagePathnameSlice(pageId).\n // TODO: Update this once we move away from the GraphQL fragments.\n return pagePathnameSlices.map(pagePathnameSlice => {\n if (pagePathnameSlice == null) return null\n\n return {\n ...pagePathnameSlice,\n id: pagePathnameSlice.basePageId,\n localizedPathname: pagePathnameSlice.localizedPathname ?? null,\n }\n })\n }\n\n async getPagePathnameSlice(\n pageId: string,\n siteVersion: SiteVersion | null,\n { locale }: { locale?: string | null } = {},\n ): Promise<PagePathnameSlice | null> {\n const pagePathnameSlices = await this.getPagePathnameSlices([pageId], siteVersion, { locale })\n\n return pagePathnameSlices.at(0) ?? null\n }\n\n protected async fetch(\n path: string,\n siteVersion: SiteVersion | null,\n init?: RequestInit,\n ): Promise<Response> {\n const requestUrl = new URL(path, this.apiOrigin)\n\n const requestHeaders = new Headers({\n 'x-api-key': this.apiKey,\n 'makeswift-site-api-key': this.apiKey,\n 'makeswift-runtime-version': PACKAGE_VERSION,\n })\n\n if (siteVersion?.token) {\n requestUrl.searchParams.set('version', siteVersion.version)\n requestHeaders.set('makeswift-preview-token', siteVersion.token)\n }\n\n if (init?.headers) {\n new Headers(init.headers).forEach((value, key) => {\n requestHeaders.set(key, value)\n })\n }\n\n try {\n return await this._fetch(requestUrl.toString(), {\n ...init,\n headers: requestHeaders,\n ...(siteVersion != null ? { cache: 'no-store' } : {}),\n })\n } catch (error) {\n if (error instanceof HTTPError) return error.response\n throw error\n }\n }\n}\n\n// This function attempts to consume the response body of a failed response, and\n// returns either the parsed JSON or raw text. This is useful for logging more\n// detailed error information when an API request fails.\n//\n// Cloudflare Worker Note: The Cloudflare Worker runtime has automatic deadlock\n// prevention (in the form of auto-cancelling responses) that triggers when too\n// many response bodies are unconsumed. This applies for error responses as\n// well. As such, in this client we use this function to consume the response\n// body whenever the request fails, even if we don't end up logging the body\n// itself, to avoid hitting the deadlock prevention.\nexport async function failedResponseBody(response: Response): Promise<unknown> {\n try {\n const text = await response.text()\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n } catch (e) {\n return `Failed to extract response body: ${e}`\n }\n}\n\nfunction responseError(response: Response): string {\n return `${response.status} ${response.statusText}`\n}\n\nexport class RestApiClientError extends Error {\n readonly status: number\n\n constructor(message: string, response: Response, cause: Record<string, unknown>) {\n super(`${message}: ${responseError(response)}`, { cause })\n\n this.name = 'RestApiClientError'\n this.status = response.status\n }\n}\n"],"mappings":"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","names":["ky"]}
@@ -28,7 +28,7 @@ async function manifestHandler(req, { apiKey, manifest }) {
28
28
  return import_request_response.ApiResponse.json({ message: "Unauthorized" }, { status: 401 });
29
29
  }
30
30
  return import_request_response.ApiResponse.json({
31
- version: "0.28.8",
31
+ version: "0.28.9-canary.0",
32
32
  interactionMode: true,
33
33
  clientSideNavigation: false,
34
34
  elementFromPoint: false,
@@ -9,7 +9,7 @@ class MakeswiftGraphQLApiClient {
9
9
  graphqlClient;
10
10
  constructor({ endpoint }) {
11
11
  this.graphqlClient = new GraphQLClient(endpoint, {
12
- "makeswift-runtime-version": "0.28.8"
12
+ "makeswift-runtime-version": "0.28.9-canary.0"
13
13
  });
14
14
  }
15
15
  async createTableRecord(tableId, columns) {
@@ -0,0 +1,7 @@
1
+ import { default as default2, HTTPError, isHTTPError } from "ky";
2
+ export {
3
+ HTTPError,
4
+ default2 as default,
5
+ isHTTPError
6
+ };
7
+ //# sourceMappingURL=ky.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/api/ky.ts"],"sourcesContent":["// `ky` is an ESM-only package: it has no `require` condition in its exports map\n// and ships no CommonJS build. Because we build with `bundle: false`, importing\n// it directly would leave a bare `require('ky')` in our CommonJS output, which\n// throws `ERR_REQUIRE_ESM` on any host whose loader doesn't implement\n// `require(esm)` — older Node, or a platform that patches `Module._load` (some\n// serverless runtimes do).\n//\n// Routing every `ky` import through this module lets us bundle `ky` into the\n// CommonJS build, so the shipped `dist/cjs` output never requires it. See the\n// `ky` entry in `tsup.config.ts`.\nexport { default, HTTPError, isHTTPError } from 'ky'\nexport type { KyInstance } from 'ky'\n"],"mappings":"AAUA,SAAS,WAAAA,UAAS,WAAW,mBAAmB;","names":["default"]}
@@ -1,4 +1,4 @@
1
- import ky, { HTTPError, isHTTPError } from "ky";
1
+ import ky, { HTTPError, isHTTPError } from "./ky";
2
2
  import * as Schema from "./schema";
3
3
  const RetryBackoffConfig = {
4
4
  MaxAttempts: 3,
@@ -137,7 +137,7 @@ class MakeswiftRestAPIClient {
137
137
  const requestHeaders = new Headers({
138
138
  "x-api-key": this.apiKey,
139
139
  "makeswift-site-api-key": this.apiKey,
140
- "makeswift-runtime-version": "0.28.8"
140
+ "makeswift-runtime-version": "0.28.9-canary.0"
141
141
  });
142
142
  if (siteVersion?.token) {
143
143
  requestUrl.searchParams.set("version", siteVersion.version);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/api/rest-api-client.ts"],"sourcesContent":["import ky, { HTTPError, isHTTPError, type KyInstance } from 'ky'\n\nimport {\n type GlobalElement,\n type LocalizedGlobalElement,\n type PagePathnameSlice,\n type Swatch,\n type Typography,\n type HttpFetch,\n} from './types'\n\nimport { type SiteVersion } from './site-version'\nimport * as Schema from './schema'\n\nconst RetryBackoffConfig = {\n MaxAttempts: 3,\n MaxDelayMs: 5_000,\n}\n\nexport class MakeswiftRestAPIClient {\n private _fetch: KyInstance\n\n readonly apiKey: string\n readonly apiOrigin: string\n\n constructor({\n fetch,\n apiKey,\n apiOrigin,\n }: {\n fetch: HttpFetch\n apiKey: string\n apiOrigin: string\n }) {\n this._fetch = ky.create({\n fetch,\n timeout: false,\n retry: {\n statusCodes: [429],\n limit: RetryBackoffConfig.MaxAttempts,\n backoffLimit: RetryBackoffConfig.MaxDelayMs,\n delay: attemptCount => 2 ** (attemptCount - 1) * 1000,\n jitter: true,\n },\n hooks: {\n beforeRetry: [\n async ({ request, error, retryCount }) => {\n console.warn(\n `Request to ${request.url} failed with ${error}. Retrying (${retryCount}/${RetryBackoffConfig.MaxAttempts})`,\n )\n // Drain the response body before retrying so we don't leak unconsumed\n // response bodies (see the comment on `failedResponseBody` below).\n if (isHTTPError(error)) await failedResponseBody(error.response)\n },\n ],\n },\n })\n\n this.apiKey = apiKey\n this.apiOrigin = apiOrigin\n }\n\n async getSwatch(swatchId: string, siteVersion: SiteVersion | null): Promise<Swatch | null> {\n const response = await this.fetch(`v3/swatches/${swatchId}`, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(`Failed to get swatch '${swatchId}'`, response, {\n body: failedBody,\n siteVersion,\n })\n }\n\n const swatch = await response.json()\n\n return swatch\n }\n\n async getTypography(\n typographyId: string,\n siteVersion: SiteVersion | null,\n ): Promise<Typography | null> {\n const response = await this.fetch(`v3/typographies/${typographyId}`, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(`Failed to get typography '${typographyId}'`, response, {\n body: failedBody,\n siteVersion,\n })\n }\n\n const typography = await response.json()\n\n return typography\n }\n\n async getGlobalElement(\n globalElementId: string,\n siteVersion: SiteVersion | null,\n ): Promise<GlobalElement | null> {\n const response = await this.fetch(`v3/global-elements/${globalElementId}`, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(`Failed to get global element '${globalElementId}'`, response, {\n body: failedBody,\n siteVersion,\n })\n }\n\n const globalElement = await response.json()\n\n return globalElement\n }\n\n async getLocalizedGlobalElement(\n globalElementId: string,\n locale: string,\n siteVersion: SiteVersion | null,\n ): Promise<LocalizedGlobalElement | null> {\n const response = await this.fetch(\n `v3/localized-global-elements/${globalElementId}?locale=${locale}`,\n siteVersion,\n )\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(\n `Failed to get localized global element '${globalElementId}'`,\n response,\n { body: failedBody, siteVersion, locale },\n )\n }\n\n const localizedGlobalElement = await response.json()\n\n return localizedGlobalElement\n }\n\n async getPagePathnameSlices(\n pageIds: string[],\n siteVersion: SiteVersion | null,\n { locale }: { locale?: string | null },\n ): Promise<(PagePathnameSlice | null)[]> {\n if (pageIds.length === 0) return []\n\n const url = new URL(`v3/page-pathname-slices/bulk`, this.apiOrigin)\n\n pageIds.forEach(id => url.searchParams.append('ids', id))\n if (locale != null) url.searchParams.set('locale', locale)\n\n const response = await this.fetch(url.pathname + url.search, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return []\n\n throw new RestApiClientError(\n `Failed to get page pathname slice(s) for ${pageIds.join(', ')}`,\n response,\n { body: failedBody, siteVersion, locale },\n )\n }\n\n const json = await response.json()\n\n const pagePathnameSlices = Schema.pagePathnameSlices.parse(json)\n\n // We're mapping the basePageId to be the id, because we're still using the GraphQL\n // fragment as our APIResource. The id on the APIResource needs to match the pageId\n // so that we can find the corresponding page pathname slice when we call getPagePathnameSlice(pageId).\n // TODO: Update this once we move away from the GraphQL fragments.\n return pagePathnameSlices.map(pagePathnameSlice => {\n if (pagePathnameSlice == null) return null\n\n return {\n ...pagePathnameSlice,\n id: pagePathnameSlice.basePageId,\n localizedPathname: pagePathnameSlice.localizedPathname ?? null,\n }\n })\n }\n\n async getPagePathnameSlice(\n pageId: string,\n siteVersion: SiteVersion | null,\n { locale }: { locale?: string | null } = {},\n ): Promise<PagePathnameSlice | null> {\n const pagePathnameSlices = await this.getPagePathnameSlices([pageId], siteVersion, { locale })\n\n return pagePathnameSlices.at(0) ?? null\n }\n\n protected async fetch(\n path: string,\n siteVersion: SiteVersion | null,\n init?: RequestInit,\n ): Promise<Response> {\n const requestUrl = new URL(path, this.apiOrigin)\n\n const requestHeaders = new Headers({\n 'x-api-key': this.apiKey,\n 'makeswift-site-api-key': this.apiKey,\n 'makeswift-runtime-version': PACKAGE_VERSION,\n })\n\n if (siteVersion?.token) {\n requestUrl.searchParams.set('version', siteVersion.version)\n requestHeaders.set('makeswift-preview-token', siteVersion.token)\n }\n\n if (init?.headers) {\n new Headers(init.headers).forEach((value, key) => {\n requestHeaders.set(key, value)\n })\n }\n\n try {\n return await this._fetch(requestUrl.toString(), {\n ...init,\n headers: requestHeaders,\n ...(siteVersion != null ? { cache: 'no-store' } : {}),\n })\n } catch (error) {\n if (error instanceof HTTPError) return error.response\n throw error\n }\n }\n}\n\n// This function attempts to consume the response body of a failed response, and\n// returns either the parsed JSON or raw text. This is useful for logging more\n// detailed error information when an API request fails.\n//\n// Cloudflare Worker Note: The Cloudflare Worker runtime has automatic deadlock\n// prevention (in the form of auto-cancelling responses) that triggers when too\n// many response bodies are unconsumed. This applies for error responses as\n// well. As such, in this client we use this function to consume the response\n// body whenever the request fails, even if we don't end up logging the body\n// itself, to avoid hitting the deadlock prevention.\nexport async function failedResponseBody(response: Response): Promise<unknown> {\n try {\n const text = await response.text()\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n } catch (e) {\n return `Failed to extract response body: ${e}`\n }\n}\n\nfunction responseError(response: Response): string {\n return `${response.status} ${response.statusText}`\n}\n\nexport class RestApiClientError extends Error {\n readonly status: number\n\n constructor(message: string, response: Response, cause: Record<string, unknown>) {\n super(`${message}: ${responseError(response)}`, { cause })\n\n this.name = 'RestApiClientError'\n this.status = response.status\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/api/rest-api-client.ts"],"sourcesContent":["import ky, { HTTPError, isHTTPError, type KyInstance } from './ky'\n\nimport {\n type GlobalElement,\n type LocalizedGlobalElement,\n type PagePathnameSlice,\n type Swatch,\n type Typography,\n type HttpFetch,\n} from './types'\n\nimport { type SiteVersion } from './site-version'\nimport * as Schema from './schema'\n\nconst RetryBackoffConfig = {\n MaxAttempts: 3,\n MaxDelayMs: 5_000,\n}\n\nexport class MakeswiftRestAPIClient {\n private _fetch: KyInstance\n\n readonly apiKey: string\n readonly apiOrigin: string\n\n constructor({\n fetch,\n apiKey,\n apiOrigin,\n }: {\n fetch: HttpFetch\n apiKey: string\n apiOrigin: string\n }) {\n this._fetch = ky.create({\n fetch,\n timeout: false,\n retry: {\n statusCodes: [429],\n limit: RetryBackoffConfig.MaxAttempts,\n backoffLimit: RetryBackoffConfig.MaxDelayMs,\n delay: attemptCount => 2 ** (attemptCount - 1) * 1000,\n jitter: true,\n },\n hooks: {\n beforeRetry: [\n async ({ request, error, retryCount }) => {\n console.warn(\n `Request to ${request.url} failed with ${error}. Retrying (${retryCount}/${RetryBackoffConfig.MaxAttempts})`,\n )\n // Drain the response body before retrying so we don't leak unconsumed\n // response bodies (see the comment on `failedResponseBody` below).\n if (isHTTPError(error)) await failedResponseBody(error.response)\n },\n ],\n },\n })\n\n this.apiKey = apiKey\n this.apiOrigin = apiOrigin\n }\n\n async getSwatch(swatchId: string, siteVersion: SiteVersion | null): Promise<Swatch | null> {\n const response = await this.fetch(`v3/swatches/${swatchId}`, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(`Failed to get swatch '${swatchId}'`, response, {\n body: failedBody,\n siteVersion,\n })\n }\n\n const swatch = await response.json()\n\n return swatch\n }\n\n async getTypography(\n typographyId: string,\n siteVersion: SiteVersion | null,\n ): Promise<Typography | null> {\n const response = await this.fetch(`v3/typographies/${typographyId}`, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(`Failed to get typography '${typographyId}'`, response, {\n body: failedBody,\n siteVersion,\n })\n }\n\n const typography = await response.json()\n\n return typography\n }\n\n async getGlobalElement(\n globalElementId: string,\n siteVersion: SiteVersion | null,\n ): Promise<GlobalElement | null> {\n const response = await this.fetch(`v3/global-elements/${globalElementId}`, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(`Failed to get global element '${globalElementId}'`, response, {\n body: failedBody,\n siteVersion,\n })\n }\n\n const globalElement = await response.json()\n\n return globalElement\n }\n\n async getLocalizedGlobalElement(\n globalElementId: string,\n locale: string,\n siteVersion: SiteVersion | null,\n ): Promise<LocalizedGlobalElement | null> {\n const response = await this.fetch(\n `v3/localized-global-elements/${globalElementId}?locale=${locale}`,\n siteVersion,\n )\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return null\n\n throw new RestApiClientError(\n `Failed to get localized global element '${globalElementId}'`,\n response,\n { body: failedBody, siteVersion, locale },\n )\n }\n\n const localizedGlobalElement = await response.json()\n\n return localizedGlobalElement\n }\n\n async getPagePathnameSlices(\n pageIds: string[],\n siteVersion: SiteVersion | null,\n { locale }: { locale?: string | null },\n ): Promise<(PagePathnameSlice | null)[]> {\n if (pageIds.length === 0) return []\n\n const url = new URL(`v3/page-pathname-slices/bulk`, this.apiOrigin)\n\n pageIds.forEach(id => url.searchParams.append('ids', id))\n if (locale != null) url.searchParams.set('locale', locale)\n\n const response = await this.fetch(url.pathname + url.search, siteVersion)\n\n if (!response.ok) {\n const failedBody = await failedResponseBody(response)\n if (response.status === 404) return []\n\n throw new RestApiClientError(\n `Failed to get page pathname slice(s) for ${pageIds.join(', ')}`,\n response,\n { body: failedBody, siteVersion, locale },\n )\n }\n\n const json = await response.json()\n\n const pagePathnameSlices = Schema.pagePathnameSlices.parse(json)\n\n // We're mapping the basePageId to be the id, because we're still using the GraphQL\n // fragment as our APIResource. The id on the APIResource needs to match the pageId\n // so that we can find the corresponding page pathname slice when we call getPagePathnameSlice(pageId).\n // TODO: Update this once we move away from the GraphQL fragments.\n return pagePathnameSlices.map(pagePathnameSlice => {\n if (pagePathnameSlice == null) return null\n\n return {\n ...pagePathnameSlice,\n id: pagePathnameSlice.basePageId,\n localizedPathname: pagePathnameSlice.localizedPathname ?? null,\n }\n })\n }\n\n async getPagePathnameSlice(\n pageId: string,\n siteVersion: SiteVersion | null,\n { locale }: { locale?: string | null } = {},\n ): Promise<PagePathnameSlice | null> {\n const pagePathnameSlices = await this.getPagePathnameSlices([pageId], siteVersion, { locale })\n\n return pagePathnameSlices.at(0) ?? null\n }\n\n protected async fetch(\n path: string,\n siteVersion: SiteVersion | null,\n init?: RequestInit,\n ): Promise<Response> {\n const requestUrl = new URL(path, this.apiOrigin)\n\n const requestHeaders = new Headers({\n 'x-api-key': this.apiKey,\n 'makeswift-site-api-key': this.apiKey,\n 'makeswift-runtime-version': PACKAGE_VERSION,\n })\n\n if (siteVersion?.token) {\n requestUrl.searchParams.set('version', siteVersion.version)\n requestHeaders.set('makeswift-preview-token', siteVersion.token)\n }\n\n if (init?.headers) {\n new Headers(init.headers).forEach((value, key) => {\n requestHeaders.set(key, value)\n })\n }\n\n try {\n return await this._fetch(requestUrl.toString(), {\n ...init,\n headers: requestHeaders,\n ...(siteVersion != null ? { cache: 'no-store' } : {}),\n })\n } catch (error) {\n if (error instanceof HTTPError) return error.response\n throw error\n }\n }\n}\n\n// This function attempts to consume the response body of a failed response, and\n// returns either the parsed JSON or raw text. This is useful for logging more\n// detailed error information when an API request fails.\n//\n// Cloudflare Worker Note: The Cloudflare Worker runtime has automatic deadlock\n// prevention (in the form of auto-cancelling responses) that triggers when too\n// many response bodies are unconsumed. This applies for error responses as\n// well. As such, in this client we use this function to consume the response\n// body whenever the request fails, even if we don't end up logging the body\n// itself, to avoid hitting the deadlock prevention.\nexport async function failedResponseBody(response: Response): Promise<unknown> {\n try {\n const text = await response.text()\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n } catch (e) {\n return `Failed to extract response body: ${e}`\n }\n}\n\nfunction responseError(response: Response): string {\n return `${response.status} ${response.statusText}`\n}\n\nexport class RestApiClientError extends Error {\n readonly status: number\n\n constructor(message: string, response: Response, cause: Record<string, unknown>) {\n super(`${message}: ${responseError(response)}`, { cause })\n\n this.name = 'RestApiClientError'\n this.status = response.status\n }\n}\n"],"mappings":"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","names":[]}
@@ -8,7 +8,7 @@ async function manifestHandler(req, { apiKey, manifest }) {
8
8
  return ApiResponse.json({ message: "Unauthorized" }, { status: 401 });
9
9
  }
10
10
  return ApiResponse.json({
11
- version: "0.28.8",
11
+ version: "0.28.9-canary.0",
12
12
  interactionMode: true,
13
13
  clientSideNavigation: false,
14
14
  elementFromPoint: false,
@@ -0,0 +1,3 @@
1
+ export { default, HTTPError, isHTTPError } from 'ky';
2
+ export type { KyInstance } from 'ky';
3
+ //# sourceMappingURL=ky.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ky.d.ts","sourceRoot":"","sources":["../../../src/api/ky.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,IAAI,CAAA;AACpD,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makeswift/runtime",
3
- "version": "0.28.8",
3
+ "version": "0.28.9-canary.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "url": "makeswift/makeswift",