bc-api-client 0.1.0-beta.1 → 0.1.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -37
- package/dist/auth.d.ts +13 -6
- package/dist/client.d.ts +119 -10
- package/dist/core.d.ts +9 -0
- package/dist/endpoints.d.ts +470 -0
- package/dist/endpoints.js +485 -0
- package/dist/endpoints.js.map +7 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +266 -1840
- package/dist/index.js.map +4 -4
- package/dist/net.d.ts +6 -1
- package/package.json +7 -5
package/dist/index.js
CHANGED
|
@@ -1,597 +1,15 @@
|
|
|
1
|
-
// node_modules/.pnpm/ky@1.8.1/node_modules/ky/distribution/errors/HTTPError.js
|
|
2
|
-
var HTTPError = class extends Error {
|
|
3
|
-
response;
|
|
4
|
-
request;
|
|
5
|
-
options;
|
|
6
|
-
constructor(response, request2, options) {
|
|
7
|
-
const code = response.status || response.status === 0 ? response.status : "";
|
|
8
|
-
const title = response.statusText || "";
|
|
9
|
-
const status = `${code} ${title}`.trim();
|
|
10
|
-
const reason = status ? `status code ${status}` : "an unknown error";
|
|
11
|
-
super(`Request failed with ${reason}: ${request2.method} ${request2.url}`);
|
|
12
|
-
this.name = "HTTPError";
|
|
13
|
-
this.response = response;
|
|
14
|
-
this.request = request2;
|
|
15
|
-
this.options = options;
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
// node_modules/.pnpm/ky@1.8.1/node_modules/ky/distribution/errors/TimeoutError.js
|
|
20
|
-
var TimeoutError = class extends Error {
|
|
21
|
-
request;
|
|
22
|
-
constructor(request2) {
|
|
23
|
-
super(`Request timed out: ${request2.method} ${request2.url}`);
|
|
24
|
-
this.name = "TimeoutError";
|
|
25
|
-
this.request = request2;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// node_modules/.pnpm/ky@1.8.1/node_modules/ky/distribution/core/constants.js
|
|
30
|
-
var supportsRequestStreams = (() => {
|
|
31
|
-
let duplexAccessed = false;
|
|
32
|
-
let hasContentType = false;
|
|
33
|
-
const supportsReadableStream = typeof globalThis.ReadableStream === "function";
|
|
34
|
-
const supportsRequest = typeof globalThis.Request === "function";
|
|
35
|
-
if (supportsReadableStream && supportsRequest) {
|
|
36
|
-
try {
|
|
37
|
-
hasContentType = new globalThis.Request("https://empty.invalid", {
|
|
38
|
-
body: new globalThis.ReadableStream(),
|
|
39
|
-
method: "POST",
|
|
40
|
-
// @ts-expect-error - Types are outdated.
|
|
41
|
-
get duplex() {
|
|
42
|
-
duplexAccessed = true;
|
|
43
|
-
return "half";
|
|
44
|
-
}
|
|
45
|
-
}).headers.has("Content-Type");
|
|
46
|
-
} catch (error) {
|
|
47
|
-
if (error instanceof Error && error.message === "unsupported BodyInit type") {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
throw error;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return duplexAccessed && !hasContentType;
|
|
54
|
-
})();
|
|
55
|
-
var supportsAbortController = typeof globalThis.AbortController === "function";
|
|
56
|
-
var supportsResponseStreams = typeof globalThis.ReadableStream === "function";
|
|
57
|
-
var supportsFormData = typeof globalThis.FormData === "function";
|
|
58
|
-
var requestMethods = ["get", "post", "put", "patch", "head", "delete"];
|
|
59
|
-
var validate = () => void 0;
|
|
60
|
-
validate();
|
|
61
|
-
var responseTypes = {
|
|
62
|
-
json: "application/json",
|
|
63
|
-
text: "text/*",
|
|
64
|
-
formData: "multipart/form-data",
|
|
65
|
-
arrayBuffer: "*/*",
|
|
66
|
-
blob: "*/*"
|
|
67
|
-
};
|
|
68
|
-
var maxSafeTimeout = 2147483647;
|
|
69
|
-
var usualFormBoundarySize = new TextEncoder().encode("------WebKitFormBoundaryaxpyiPgbbPti10Rw").length;
|
|
70
|
-
var stop = Symbol("stop");
|
|
71
|
-
var kyOptionKeys = {
|
|
72
|
-
json: true,
|
|
73
|
-
parseJson: true,
|
|
74
|
-
stringifyJson: true,
|
|
75
|
-
searchParams: true,
|
|
76
|
-
prefixUrl: true,
|
|
77
|
-
retry: true,
|
|
78
|
-
timeout: true,
|
|
79
|
-
hooks: true,
|
|
80
|
-
throwHttpErrors: true,
|
|
81
|
-
onDownloadProgress: true,
|
|
82
|
-
onUploadProgress: true,
|
|
83
|
-
fetch: true
|
|
84
|
-
};
|
|
85
|
-
var requestOptionsRegistry = {
|
|
86
|
-
method: true,
|
|
87
|
-
headers: true,
|
|
88
|
-
body: true,
|
|
89
|
-
mode: true,
|
|
90
|
-
credentials: true,
|
|
91
|
-
cache: true,
|
|
92
|
-
redirect: true,
|
|
93
|
-
referrer: true,
|
|
94
|
-
referrerPolicy: true,
|
|
95
|
-
integrity: true,
|
|
96
|
-
keepalive: true,
|
|
97
|
-
signal: true,
|
|
98
|
-
window: true,
|
|
99
|
-
dispatcher: true,
|
|
100
|
-
duplex: true,
|
|
101
|
-
priority: true
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
// node_modules/.pnpm/ky@1.8.1/node_modules/ky/distribution/utils/body.js
|
|
105
|
-
var getBodySize = (body) => {
|
|
106
|
-
if (!body) {
|
|
107
|
-
return 0;
|
|
108
|
-
}
|
|
109
|
-
if (body instanceof FormData) {
|
|
110
|
-
let size = 0;
|
|
111
|
-
for (const [key, value] of body) {
|
|
112
|
-
size += usualFormBoundarySize;
|
|
113
|
-
size += new TextEncoder().encode(`Content-Disposition: form-data; name="${key}"`).length;
|
|
114
|
-
size += typeof value === "string" ? new TextEncoder().encode(value).length : value.size;
|
|
115
|
-
}
|
|
116
|
-
return size;
|
|
117
|
-
}
|
|
118
|
-
if (body instanceof Blob) {
|
|
119
|
-
return body.size;
|
|
120
|
-
}
|
|
121
|
-
if (body instanceof ArrayBuffer) {
|
|
122
|
-
return body.byteLength;
|
|
123
|
-
}
|
|
124
|
-
if (typeof body === "string") {
|
|
125
|
-
return new TextEncoder().encode(body).length;
|
|
126
|
-
}
|
|
127
|
-
if (body instanceof URLSearchParams) {
|
|
128
|
-
return new TextEncoder().encode(body.toString()).length;
|
|
129
|
-
}
|
|
130
|
-
if ("byteLength" in body) {
|
|
131
|
-
return body.byteLength;
|
|
132
|
-
}
|
|
133
|
-
if (typeof body === "object" && body !== null) {
|
|
134
|
-
try {
|
|
135
|
-
const jsonString = JSON.stringify(body);
|
|
136
|
-
return new TextEncoder().encode(jsonString).length;
|
|
137
|
-
} catch {
|
|
138
|
-
return 0;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return 0;
|
|
142
|
-
};
|
|
143
|
-
var streamResponse = (response, onDownloadProgress) => {
|
|
144
|
-
const totalBytes = Number(response.headers.get("content-length")) || 0;
|
|
145
|
-
let transferredBytes = 0;
|
|
146
|
-
if (response.status === 204) {
|
|
147
|
-
if (onDownloadProgress) {
|
|
148
|
-
onDownloadProgress({ percent: 1, totalBytes, transferredBytes }, new Uint8Array());
|
|
149
|
-
}
|
|
150
|
-
return new Response(null, {
|
|
151
|
-
status: response.status,
|
|
152
|
-
statusText: response.statusText,
|
|
153
|
-
headers: response.headers
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
return new Response(new ReadableStream({
|
|
157
|
-
async start(controller) {
|
|
158
|
-
const reader = response.body.getReader();
|
|
159
|
-
if (onDownloadProgress) {
|
|
160
|
-
onDownloadProgress({ percent: 0, transferredBytes: 0, totalBytes }, new Uint8Array());
|
|
161
|
-
}
|
|
162
|
-
async function read() {
|
|
163
|
-
const { done, value } = await reader.read();
|
|
164
|
-
if (done) {
|
|
165
|
-
controller.close();
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
if (onDownloadProgress) {
|
|
169
|
-
transferredBytes += value.byteLength;
|
|
170
|
-
const percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes;
|
|
171
|
-
onDownloadProgress({ percent, transferredBytes, totalBytes }, value);
|
|
172
|
-
}
|
|
173
|
-
controller.enqueue(value);
|
|
174
|
-
await read();
|
|
175
|
-
}
|
|
176
|
-
await read();
|
|
177
|
-
}
|
|
178
|
-
}), {
|
|
179
|
-
status: response.status,
|
|
180
|
-
statusText: response.statusText,
|
|
181
|
-
headers: response.headers
|
|
182
|
-
});
|
|
183
|
-
};
|
|
184
|
-
var streamRequest = (request2, onUploadProgress) => {
|
|
185
|
-
const totalBytes = getBodySize(request2.body);
|
|
186
|
-
let transferredBytes = 0;
|
|
187
|
-
return new Request(request2, {
|
|
188
|
-
// @ts-expect-error - Types are outdated.
|
|
189
|
-
duplex: "half",
|
|
190
|
-
body: new ReadableStream({
|
|
191
|
-
async start(controller) {
|
|
192
|
-
const reader = request2.body instanceof ReadableStream ? request2.body.getReader() : new Response("").body.getReader();
|
|
193
|
-
async function read() {
|
|
194
|
-
const { done, value } = await reader.read();
|
|
195
|
-
if (done) {
|
|
196
|
-
if (onUploadProgress) {
|
|
197
|
-
onUploadProgress({ percent: 1, transferredBytes, totalBytes: Math.max(totalBytes, transferredBytes) }, new Uint8Array());
|
|
198
|
-
}
|
|
199
|
-
controller.close();
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
transferredBytes += value.byteLength;
|
|
203
|
-
let percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes;
|
|
204
|
-
if (totalBytes < transferredBytes || percent === 1) {
|
|
205
|
-
percent = 0.99;
|
|
206
|
-
}
|
|
207
|
-
if (onUploadProgress) {
|
|
208
|
-
onUploadProgress({ percent: Number(percent.toFixed(2)), transferredBytes, totalBytes }, value);
|
|
209
|
-
}
|
|
210
|
-
controller.enqueue(value);
|
|
211
|
-
await read();
|
|
212
|
-
}
|
|
213
|
-
await read();
|
|
214
|
-
}
|
|
215
|
-
})
|
|
216
|
-
});
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
// node_modules/.pnpm/ky@1.8.1/node_modules/ky/distribution/utils/is.js
|
|
220
|
-
var isObject = (value) => value !== null && typeof value === "object";
|
|
221
|
-
|
|
222
|
-
// node_modules/.pnpm/ky@1.8.1/node_modules/ky/distribution/utils/merge.js
|
|
223
|
-
var validateAndMerge = (...sources) => {
|
|
224
|
-
for (const source of sources) {
|
|
225
|
-
if ((!isObject(source) || Array.isArray(source)) && source !== void 0) {
|
|
226
|
-
throw new TypeError("The `options` argument must be an object");
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
return deepMerge({}, ...sources);
|
|
230
|
-
};
|
|
231
|
-
var mergeHeaders = (source1 = {}, source2 = {}) => {
|
|
232
|
-
const result = new globalThis.Headers(source1);
|
|
233
|
-
const isHeadersInstance = source2 instanceof globalThis.Headers;
|
|
234
|
-
const source = new globalThis.Headers(source2);
|
|
235
|
-
for (const [key, value] of source.entries()) {
|
|
236
|
-
if (isHeadersInstance && value === "undefined" || value === void 0) {
|
|
237
|
-
result.delete(key);
|
|
238
|
-
} else {
|
|
239
|
-
result.set(key, value);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
return result;
|
|
243
|
-
};
|
|
244
|
-
function newHookValue(original, incoming, property) {
|
|
245
|
-
return Object.hasOwn(incoming, property) && incoming[property] === void 0 ? [] : deepMerge(original[property] ?? [], incoming[property] ?? []);
|
|
246
|
-
}
|
|
247
|
-
var mergeHooks = (original = {}, incoming = {}) => ({
|
|
248
|
-
beforeRequest: newHookValue(original, incoming, "beforeRequest"),
|
|
249
|
-
beforeRetry: newHookValue(original, incoming, "beforeRetry"),
|
|
250
|
-
afterResponse: newHookValue(original, incoming, "afterResponse"),
|
|
251
|
-
beforeError: newHookValue(original, incoming, "beforeError")
|
|
252
|
-
});
|
|
253
|
-
var deepMerge = (...sources) => {
|
|
254
|
-
let returnValue = {};
|
|
255
|
-
let headers = {};
|
|
256
|
-
let hooks = {};
|
|
257
|
-
for (const source of sources) {
|
|
258
|
-
if (Array.isArray(source)) {
|
|
259
|
-
if (!Array.isArray(returnValue)) {
|
|
260
|
-
returnValue = [];
|
|
261
|
-
}
|
|
262
|
-
returnValue = [...returnValue, ...source];
|
|
263
|
-
} else if (isObject(source)) {
|
|
264
|
-
for (let [key, value] of Object.entries(source)) {
|
|
265
|
-
if (isObject(value) && key in returnValue) {
|
|
266
|
-
value = deepMerge(returnValue[key], value);
|
|
267
|
-
}
|
|
268
|
-
returnValue = { ...returnValue, [key]: value };
|
|
269
|
-
}
|
|
270
|
-
if (isObject(source.hooks)) {
|
|
271
|
-
hooks = mergeHooks(hooks, source.hooks);
|
|
272
|
-
returnValue.hooks = hooks;
|
|
273
|
-
}
|
|
274
|
-
if (isObject(source.headers)) {
|
|
275
|
-
headers = mergeHeaders(headers, source.headers);
|
|
276
|
-
returnValue.headers = headers;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
return returnValue;
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
// node_modules/.pnpm/ky@1.8.1/node_modules/ky/distribution/utils/normalize.js
|
|
284
|
-
var normalizeRequestMethod = (input) => requestMethods.includes(input) ? input.toUpperCase() : input;
|
|
285
|
-
var retryMethods = ["get", "put", "head", "delete", "options", "trace"];
|
|
286
|
-
var retryStatusCodes = [408, 413, 429, 500, 502, 503, 504];
|
|
287
|
-
var retryAfterStatusCodes = [413, 429, 503];
|
|
288
|
-
var defaultRetryOptions = {
|
|
289
|
-
limit: 2,
|
|
290
|
-
methods: retryMethods,
|
|
291
|
-
statusCodes: retryStatusCodes,
|
|
292
|
-
afterStatusCodes: retryAfterStatusCodes,
|
|
293
|
-
maxRetryAfter: Number.POSITIVE_INFINITY,
|
|
294
|
-
backoffLimit: Number.POSITIVE_INFINITY,
|
|
295
|
-
delay: (attemptCount) => 0.3 * 2 ** (attemptCount - 1) * 1e3
|
|
296
|
-
};
|
|
297
|
-
var normalizeRetryOptions = (retry = {}) => {
|
|
298
|
-
if (typeof retry === "number") {
|
|
299
|
-
return {
|
|
300
|
-
...defaultRetryOptions,
|
|
301
|
-
limit: retry
|
|
302
|
-
};
|
|
303
|
-
}
|
|
304
|
-
if (retry.methods && !Array.isArray(retry.methods)) {
|
|
305
|
-
throw new Error("retry.methods must be an array");
|
|
306
|
-
}
|
|
307
|
-
if (retry.statusCodes && !Array.isArray(retry.statusCodes)) {
|
|
308
|
-
throw new Error("retry.statusCodes must be an array");
|
|
309
|
-
}
|
|
310
|
-
return {
|
|
311
|
-
...defaultRetryOptions,
|
|
312
|
-
...retry
|
|
313
|
-
};
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
// node_modules/.pnpm/ky@1.8.1/node_modules/ky/distribution/utils/timeout.js
|
|
317
|
-
async function timeout(request2, init, abortController, options) {
|
|
318
|
-
return new Promise((resolve, reject) => {
|
|
319
|
-
const timeoutId = setTimeout(() => {
|
|
320
|
-
if (abortController) {
|
|
321
|
-
abortController.abort();
|
|
322
|
-
}
|
|
323
|
-
reject(new TimeoutError(request2));
|
|
324
|
-
}, options.timeout);
|
|
325
|
-
void options.fetch(request2, init).then(resolve).catch(reject).then(() => {
|
|
326
|
-
clearTimeout(timeoutId);
|
|
327
|
-
});
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// node_modules/.pnpm/ky@1.8.1/node_modules/ky/distribution/utils/delay.js
|
|
332
|
-
async function delay(ms, { signal }) {
|
|
333
|
-
return new Promise((resolve, reject) => {
|
|
334
|
-
if (signal) {
|
|
335
|
-
signal.throwIfAborted();
|
|
336
|
-
signal.addEventListener("abort", abortHandler, { once: true });
|
|
337
|
-
}
|
|
338
|
-
function abortHandler() {
|
|
339
|
-
clearTimeout(timeoutId);
|
|
340
|
-
reject(signal.reason);
|
|
341
|
-
}
|
|
342
|
-
const timeoutId = setTimeout(() => {
|
|
343
|
-
signal?.removeEventListener("abort", abortHandler);
|
|
344
|
-
resolve();
|
|
345
|
-
}, ms);
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// node_modules/.pnpm/ky@1.8.1/node_modules/ky/distribution/utils/options.js
|
|
350
|
-
var findUnknownOptions = (request2, options) => {
|
|
351
|
-
const unknownOptions = {};
|
|
352
|
-
for (const key in options) {
|
|
353
|
-
if (!(key in requestOptionsRegistry) && !(key in kyOptionKeys) && !(key in request2)) {
|
|
354
|
-
unknownOptions[key] = options[key];
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
return unknownOptions;
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
// node_modules/.pnpm/ky@1.8.1/node_modules/ky/distribution/core/Ky.js
|
|
361
|
-
var Ky = class _Ky {
|
|
362
|
-
static create(input, options) {
|
|
363
|
-
const ky2 = new _Ky(input, options);
|
|
364
|
-
const function_ = async () => {
|
|
365
|
-
if (typeof ky2._options.timeout === "number" && ky2._options.timeout > maxSafeTimeout) {
|
|
366
|
-
throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`);
|
|
367
|
-
}
|
|
368
|
-
await Promise.resolve();
|
|
369
|
-
let response = await ky2._fetch();
|
|
370
|
-
for (const hook of ky2._options.hooks.afterResponse) {
|
|
371
|
-
const modifiedResponse = await hook(ky2.request, ky2._options, ky2._decorateResponse(response.clone()));
|
|
372
|
-
if (modifiedResponse instanceof globalThis.Response) {
|
|
373
|
-
response = modifiedResponse;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
ky2._decorateResponse(response);
|
|
377
|
-
if (!response.ok && ky2._options.throwHttpErrors) {
|
|
378
|
-
let error = new HTTPError(response, ky2.request, ky2._options);
|
|
379
|
-
for (const hook of ky2._options.hooks.beforeError) {
|
|
380
|
-
error = await hook(error);
|
|
381
|
-
}
|
|
382
|
-
throw error;
|
|
383
|
-
}
|
|
384
|
-
if (ky2._options.onDownloadProgress) {
|
|
385
|
-
if (typeof ky2._options.onDownloadProgress !== "function") {
|
|
386
|
-
throw new TypeError("The `onDownloadProgress` option must be a function");
|
|
387
|
-
}
|
|
388
|
-
if (!supportsResponseStreams) {
|
|
389
|
-
throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");
|
|
390
|
-
}
|
|
391
|
-
return streamResponse(response.clone(), ky2._options.onDownloadProgress);
|
|
392
|
-
}
|
|
393
|
-
return response;
|
|
394
|
-
};
|
|
395
|
-
const isRetriableMethod = ky2._options.retry.methods.includes(ky2.request.method.toLowerCase());
|
|
396
|
-
const result = (isRetriableMethod ? ky2._retry(function_) : function_()).finally(async () => {
|
|
397
|
-
if (!ky2.request.bodyUsed) {
|
|
398
|
-
await ky2.request.body?.cancel();
|
|
399
|
-
}
|
|
400
|
-
});
|
|
401
|
-
for (const [type, mimeType] of Object.entries(responseTypes)) {
|
|
402
|
-
result[type] = async () => {
|
|
403
|
-
ky2.request.headers.set("accept", ky2.request.headers.get("accept") || mimeType);
|
|
404
|
-
const response = await result;
|
|
405
|
-
if (type === "json") {
|
|
406
|
-
if (response.status === 204) {
|
|
407
|
-
return "";
|
|
408
|
-
}
|
|
409
|
-
const arrayBuffer = await response.clone().arrayBuffer();
|
|
410
|
-
const responseSize = arrayBuffer.byteLength;
|
|
411
|
-
if (responseSize === 0) {
|
|
412
|
-
return "";
|
|
413
|
-
}
|
|
414
|
-
if (options.parseJson) {
|
|
415
|
-
return options.parseJson(await response.text());
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
return response[type]();
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
return result;
|
|
422
|
-
}
|
|
423
|
-
request;
|
|
424
|
-
abortController;
|
|
425
|
-
_retryCount = 0;
|
|
426
|
-
_input;
|
|
427
|
-
_options;
|
|
428
|
-
// eslint-disable-next-line complexity
|
|
429
|
-
constructor(input, options = {}) {
|
|
430
|
-
this._input = input;
|
|
431
|
-
this._options = {
|
|
432
|
-
...options,
|
|
433
|
-
headers: mergeHeaders(this._input.headers, options.headers),
|
|
434
|
-
hooks: mergeHooks({
|
|
435
|
-
beforeRequest: [],
|
|
436
|
-
beforeRetry: [],
|
|
437
|
-
beforeError: [],
|
|
438
|
-
afterResponse: []
|
|
439
|
-
}, options.hooks),
|
|
440
|
-
method: normalizeRequestMethod(options.method ?? this._input.method ?? "GET"),
|
|
441
|
-
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
442
|
-
prefixUrl: String(options.prefixUrl || ""),
|
|
443
|
-
retry: normalizeRetryOptions(options.retry),
|
|
444
|
-
throwHttpErrors: options.throwHttpErrors !== false,
|
|
445
|
-
timeout: options.timeout ?? 1e4,
|
|
446
|
-
fetch: options.fetch ?? globalThis.fetch.bind(globalThis)
|
|
447
|
-
};
|
|
448
|
-
if (typeof this._input !== "string" && !(this._input instanceof URL || this._input instanceof globalThis.Request)) {
|
|
449
|
-
throw new TypeError("`input` must be a string, URL, or Request");
|
|
450
|
-
}
|
|
451
|
-
if (this._options.prefixUrl && typeof this._input === "string") {
|
|
452
|
-
if (this._input.startsWith("/")) {
|
|
453
|
-
throw new Error("`input` must not begin with a slash when using `prefixUrl`");
|
|
454
|
-
}
|
|
455
|
-
if (!this._options.prefixUrl.endsWith("/")) {
|
|
456
|
-
this._options.prefixUrl += "/";
|
|
457
|
-
}
|
|
458
|
-
this._input = this._options.prefixUrl + this._input;
|
|
459
|
-
}
|
|
460
|
-
if (supportsAbortController) {
|
|
461
|
-
const originalSignal = this._options.signal ?? this._input.signal;
|
|
462
|
-
this.abortController = new globalThis.AbortController();
|
|
463
|
-
this._options.signal = originalSignal ? AbortSignal.any([originalSignal, this.abortController.signal]) : this.abortController.signal;
|
|
464
|
-
}
|
|
465
|
-
if (supportsRequestStreams) {
|
|
466
|
-
this._options.duplex = "half";
|
|
467
|
-
}
|
|
468
|
-
if (this._options.json !== void 0) {
|
|
469
|
-
this._options.body = this._options.stringifyJson?.(this._options.json) ?? JSON.stringify(this._options.json);
|
|
470
|
-
this._options.headers.set("content-type", this._options.headers.get("content-type") ?? "application/json");
|
|
471
|
-
}
|
|
472
|
-
this.request = new globalThis.Request(this._input, this._options);
|
|
473
|
-
if (this._options.searchParams) {
|
|
474
|
-
const textSearchParams = typeof this._options.searchParams === "string" ? this._options.searchParams.replace(/^\?/, "") : new URLSearchParams(this._options.searchParams).toString();
|
|
475
|
-
const searchParams = "?" + textSearchParams;
|
|
476
|
-
const url = this.request.url.replace(/(?:\?.*?)?(?=#|$)/, searchParams);
|
|
477
|
-
if ((supportsFormData && this._options.body instanceof globalThis.FormData || this._options.body instanceof URLSearchParams) && !(this._options.headers && this._options.headers["content-type"])) {
|
|
478
|
-
this.request.headers.delete("content-type");
|
|
479
|
-
}
|
|
480
|
-
this.request = new globalThis.Request(new globalThis.Request(url, { ...this.request }), this._options);
|
|
481
|
-
}
|
|
482
|
-
if (this._options.onUploadProgress) {
|
|
483
|
-
if (typeof this._options.onUploadProgress !== "function") {
|
|
484
|
-
throw new TypeError("The `onUploadProgress` option must be a function");
|
|
485
|
-
}
|
|
486
|
-
if (!supportsRequestStreams) {
|
|
487
|
-
throw new Error("Request streams are not supported in your environment. The `duplex` option for `Request` is not available.");
|
|
488
|
-
}
|
|
489
|
-
const originalBody = this.request.body;
|
|
490
|
-
if (originalBody) {
|
|
491
|
-
this.request = streamRequest(this.request, this._options.onUploadProgress);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
_calculateRetryDelay(error) {
|
|
496
|
-
this._retryCount++;
|
|
497
|
-
if (this._retryCount > this._options.retry.limit || error instanceof TimeoutError) {
|
|
498
|
-
throw error;
|
|
499
|
-
}
|
|
500
|
-
if (error instanceof HTTPError) {
|
|
501
|
-
if (!this._options.retry.statusCodes.includes(error.response.status)) {
|
|
502
|
-
throw error;
|
|
503
|
-
}
|
|
504
|
-
const retryAfter = error.response.headers.get("Retry-After") ?? error.response.headers.get("RateLimit-Reset") ?? error.response.headers.get("X-RateLimit-Reset") ?? error.response.headers.get("X-Rate-Limit-Reset");
|
|
505
|
-
if (retryAfter && this._options.retry.afterStatusCodes.includes(error.response.status)) {
|
|
506
|
-
let after = Number(retryAfter) * 1e3;
|
|
507
|
-
if (Number.isNaN(after)) {
|
|
508
|
-
after = Date.parse(retryAfter) - Date.now();
|
|
509
|
-
} else if (after >= Date.parse("2024-01-01")) {
|
|
510
|
-
after -= Date.now();
|
|
511
|
-
}
|
|
512
|
-
const max = this._options.retry.maxRetryAfter ?? after;
|
|
513
|
-
return after < max ? after : max;
|
|
514
|
-
}
|
|
515
|
-
if (error.response.status === 413) {
|
|
516
|
-
throw error;
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
const retryDelay = this._options.retry.delay(this._retryCount);
|
|
520
|
-
return Math.min(this._options.retry.backoffLimit, retryDelay);
|
|
521
|
-
}
|
|
522
|
-
_decorateResponse(response) {
|
|
523
|
-
if (this._options.parseJson) {
|
|
524
|
-
response.json = async () => this._options.parseJson(await response.text());
|
|
525
|
-
}
|
|
526
|
-
return response;
|
|
527
|
-
}
|
|
528
|
-
async _retry(function_) {
|
|
529
|
-
try {
|
|
530
|
-
return await function_();
|
|
531
|
-
} catch (error) {
|
|
532
|
-
const ms = Math.min(this._calculateRetryDelay(error), maxSafeTimeout);
|
|
533
|
-
if (this._retryCount < 1) {
|
|
534
|
-
throw error;
|
|
535
|
-
}
|
|
536
|
-
await delay(ms, { signal: this._options.signal });
|
|
537
|
-
for (const hook of this._options.hooks.beforeRetry) {
|
|
538
|
-
const hookResult = await hook({
|
|
539
|
-
request: this.request,
|
|
540
|
-
options: this._options,
|
|
541
|
-
error,
|
|
542
|
-
retryCount: this._retryCount
|
|
543
|
-
});
|
|
544
|
-
if (hookResult === stop) {
|
|
545
|
-
return;
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
return this._retry(function_);
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
async _fetch() {
|
|
552
|
-
for (const hook of this._options.hooks.beforeRequest) {
|
|
553
|
-
const result = await hook(this.request, this._options);
|
|
554
|
-
if (result instanceof Request) {
|
|
555
|
-
this.request = result;
|
|
556
|
-
break;
|
|
557
|
-
}
|
|
558
|
-
if (result instanceof Response) {
|
|
559
|
-
return result;
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
const nonRequestOptions = findUnknownOptions(this.request, this._options);
|
|
563
|
-
const mainRequest = this.request;
|
|
564
|
-
this.request = mainRequest.clone();
|
|
565
|
-
if (this._options.timeout === false) {
|
|
566
|
-
return this._options.fetch(mainRequest, nonRequestOptions);
|
|
567
|
-
}
|
|
568
|
-
return timeout(mainRequest, nonRequestOptions, this.abortController, this._options);
|
|
569
|
-
}
|
|
570
|
-
};
|
|
571
|
-
|
|
572
|
-
// node_modules/.pnpm/ky@1.8.1/node_modules/ky/distribution/index.js
|
|
573
|
-
var createInstance = (defaults) => {
|
|
574
|
-
const ky2 = (input, options) => Ky.create(input, validateAndMerge(defaults, options));
|
|
575
|
-
for (const method of requestMethods) {
|
|
576
|
-
ky2[method] = (input, options) => Ky.create(input, validateAndMerge(defaults, options, { method }));
|
|
577
|
-
}
|
|
578
|
-
ky2.create = (newDefaults) => createInstance(validateAndMerge(newDefaults));
|
|
579
|
-
ky2.extend = (newDefaults) => {
|
|
580
|
-
if (typeof newDefaults === "function") {
|
|
581
|
-
newDefaults = newDefaults(defaults ?? {});
|
|
582
|
-
}
|
|
583
|
-
return createInstance(validateAndMerge(defaults, newDefaults));
|
|
584
|
-
};
|
|
585
|
-
ky2.stop = stop;
|
|
586
|
-
return ky2;
|
|
587
|
-
};
|
|
588
|
-
var ky = createInstance();
|
|
589
|
-
var distribution_default = ky;
|
|
590
|
-
|
|
591
1
|
// src/net.ts
|
|
2
|
+
import ky, { HTTPError } from "ky";
|
|
3
|
+
var Methods = {
|
|
4
|
+
GET: "GET",
|
|
5
|
+
POST: "POST",
|
|
6
|
+
PUT: "PUT",
|
|
7
|
+
DELETE: "DELETE"
|
|
8
|
+
};
|
|
9
|
+
var BASE_URL = "https://api.bigcommerce.com/stores/";
|
|
592
10
|
var CONFIG = {
|
|
593
11
|
/** Base URL for BigCommerce API */
|
|
594
|
-
BASE_URL
|
|
12
|
+
BASE_URL,
|
|
595
13
|
/** Default API version to use */
|
|
596
14
|
DEFAULT_VERSION: "v3",
|
|
597
15
|
/** Maximum delay in milliseconds for rate limit retries */
|
|
@@ -603,26 +21,26 @@ var CONFIG = {
|
|
|
603
21
|
/** Rate limit header names */
|
|
604
22
|
HEADERS: {
|
|
605
23
|
/** Time window for rate limiting in milliseconds */
|
|
606
|
-
WINDOW: "
|
|
24
|
+
WINDOW: "x-rate-limit-time-window-ms",
|
|
607
25
|
/** Time to wait before retrying after rate limit in milliseconds */
|
|
608
|
-
RETRY_AFTER: "
|
|
26
|
+
RETRY_AFTER: "x-rate-limit-time-reset-ms",
|
|
609
27
|
/** Total request quota for the time window */
|
|
610
|
-
REQUEST_QUOTA: "
|
|
28
|
+
REQUEST_QUOTA: "x-rate-limit-requests-quota",
|
|
611
29
|
/** Number of requests remaining in the current window */
|
|
612
|
-
REQUESTS_LEFT: "
|
|
30
|
+
REQUESTS_LEFT: "x-rate-limit-requests-left"
|
|
613
31
|
}
|
|
614
32
|
};
|
|
615
33
|
var RequestError = class extends Error {
|
|
616
|
-
constructor(status,
|
|
617
|
-
super(
|
|
34
|
+
constructor(status, message, data, cause) {
|
|
35
|
+
super(message, { cause });
|
|
618
36
|
this.status = status;
|
|
619
|
-
this.message =
|
|
37
|
+
this.message = message;
|
|
620
38
|
this.data = data;
|
|
621
39
|
this.cause = cause;
|
|
622
40
|
}
|
|
623
41
|
};
|
|
624
42
|
var request = async (options) => {
|
|
625
|
-
const { maxDelay = CONFIG.DEFAULT_MAX_DELAY, maxRetries = CONFIG.DEFAULT_MAX_RETRIES } = options;
|
|
43
|
+
const { maxDelay = CONFIG.DEFAULT_MAX_DELAY, maxRetries = CONFIG.DEFAULT_MAX_RETRIES, logger } = options;
|
|
626
44
|
let retries = 0;
|
|
627
45
|
let lastError = null;
|
|
628
46
|
while (retries < maxRetries) {
|
|
@@ -634,6 +52,11 @@ var request = async (options) => {
|
|
|
634
52
|
if (err.status === 429 && typeof err.data === "object" && err.data !== null && "headers" in err.data) {
|
|
635
53
|
const headers = err.data.headers;
|
|
636
54
|
const retryAfter = Number.parseInt(headers[CONFIG.HEADERS.RETRY_AFTER]);
|
|
55
|
+
logger?.debug({
|
|
56
|
+
retryAfter,
|
|
57
|
+
retries,
|
|
58
|
+
remaining: headers[CONFIG.HEADERS.REQUESTS_LEFT]
|
|
59
|
+
}, "Rate limit hit, retrying");
|
|
637
60
|
if (Number.isNaN(retryAfter)) {
|
|
638
61
|
throw new RequestError(
|
|
639
62
|
err.status,
|
|
@@ -643,6 +66,10 @@ var request = async (options) => {
|
|
|
643
66
|
);
|
|
644
67
|
}
|
|
645
68
|
if (retryAfter > maxDelay) {
|
|
69
|
+
logger?.warn({
|
|
70
|
+
retryAfter,
|
|
71
|
+
maxDelay
|
|
72
|
+
}, "Rate limit delay exceeds maximum allowed delay");
|
|
646
73
|
throw new RequestError(
|
|
647
74
|
err.status,
|
|
648
75
|
`Rate limit exceeded: ${retryAfter}ms, ${err.message}`,
|
|
@@ -657,17 +84,30 @@ var request = async (options) => {
|
|
|
657
84
|
throw err;
|
|
658
85
|
}
|
|
659
86
|
}
|
|
87
|
+
logger?.error({
|
|
88
|
+
retries,
|
|
89
|
+
error: lastError
|
|
90
|
+
}, "Request failed after maximum retries");
|
|
660
91
|
throw lastError ?? new RequestError(500, "Failed to make request", "Too many retries after rate limit");
|
|
661
92
|
};
|
|
662
93
|
var safeRequest = async (options) => {
|
|
94
|
+
const { logger } = options;
|
|
663
95
|
let res;
|
|
664
96
|
try {
|
|
665
97
|
res = await call(options);
|
|
666
|
-
} catch (
|
|
667
|
-
if (
|
|
668
|
-
throw
|
|
98
|
+
} catch (error) {
|
|
99
|
+
if (error instanceof RequestError) {
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
if (!(error instanceof HTTPError)) {
|
|
103
|
+
logger?.error({
|
|
104
|
+
error: error instanceof Error ? {
|
|
105
|
+
name: error.name,
|
|
106
|
+
message: error.message
|
|
107
|
+
} : error
|
|
108
|
+
}, "Unexpected error during request");
|
|
109
|
+
throw error;
|
|
669
110
|
}
|
|
670
|
-
const error = _error;
|
|
671
111
|
let data;
|
|
672
112
|
let errorMessage = error.message;
|
|
673
113
|
try {
|
|
@@ -682,12 +122,16 @@ var safeRequest = async (options) => {
|
|
|
682
122
|
} catch {
|
|
683
123
|
data = "Failed to read error response";
|
|
684
124
|
}
|
|
125
|
+
logger?.error({
|
|
126
|
+
status: error?.response?.status,
|
|
127
|
+
errorMessage
|
|
128
|
+
}, "HTTP error during request");
|
|
685
129
|
throw new RequestError(
|
|
686
|
-
error
|
|
130
|
+
error?.response?.status ?? 500,
|
|
687
131
|
errorMessage,
|
|
688
132
|
{
|
|
689
133
|
data,
|
|
690
|
-
headers: Object.fromEntries(error
|
|
134
|
+
headers: Object.fromEntries(error?.response?.headers?.entries() ?? [])
|
|
691
135
|
},
|
|
692
136
|
error
|
|
693
137
|
);
|
|
@@ -699,6 +143,13 @@ var safeRequest = async (options) => {
|
|
|
699
143
|
try {
|
|
700
144
|
return JSON.parse(text);
|
|
701
145
|
} catch (error) {
|
|
146
|
+
logger?.error({
|
|
147
|
+
status: res.status,
|
|
148
|
+
error: error instanceof Error ? {
|
|
149
|
+
name: error.name,
|
|
150
|
+
message: error.message
|
|
151
|
+
} : error
|
|
152
|
+
}, "Failed to parse response");
|
|
702
153
|
throw new RequestError(
|
|
703
154
|
res.status,
|
|
704
155
|
`Failed to parse response: ${text}`,
|
|
@@ -707,12 +158,16 @@ var safeRequest = async (options) => {
|
|
|
707
158
|
);
|
|
708
159
|
}
|
|
709
160
|
};
|
|
710
|
-
var call = (options) => {
|
|
711
|
-
const { storeHash, accessToken, endpoint, method = "GET", body, version = CONFIG.DEFAULT_VERSION, query } = options;
|
|
161
|
+
var call = async (options) => {
|
|
162
|
+
const { storeHash, accessToken, endpoint, method = "GET", body, version = CONFIG.DEFAULT_VERSION, query, logger } = options;
|
|
712
163
|
const url = `${CONFIG.BASE_URL}${storeHash}/${version}/${endpoint.replace(/^\//, "")}`;
|
|
713
164
|
const searchParams = query ? new URLSearchParams(query).toString() : "";
|
|
714
165
|
const fullUrl = searchParams ? `${url}?${searchParams}` : url;
|
|
715
166
|
if (fullUrl.length > CONFIG.MAX_URL_LENGTH) {
|
|
167
|
+
logger?.error({
|
|
168
|
+
urlLength: fullUrl.length,
|
|
169
|
+
maxLength: CONFIG.MAX_URL_LENGTH
|
|
170
|
+
}, "URL length exceeds maximum allowed length");
|
|
716
171
|
throw new RequestError(
|
|
717
172
|
400,
|
|
718
173
|
"URL too long",
|
|
@@ -728,129 +183,10 @@ var call = (options) => {
|
|
|
728
183
|
},
|
|
729
184
|
json: body
|
|
730
185
|
};
|
|
731
|
-
|
|
186
|
+
const response = await ky(fullUrl, request2);
|
|
187
|
+
return response;
|
|
732
188
|
};
|
|
733
189
|
|
|
734
|
-
// node_modules/.pnpm/remeda@2.21.3/node_modules/remeda/dist/chunk-ANXBDSUI.js
|
|
735
|
-
var e = { done: true, hasNext: false };
|
|
736
|
-
var s = { done: false, hasNext: false };
|
|
737
|
-
var a = () => e;
|
|
738
|
-
|
|
739
|
-
// node_modules/.pnpm/remeda@2.21.3/node_modules/remeda/dist/chunk-3GOCSNFN.js
|
|
740
|
-
function C(t, ...o2) {
|
|
741
|
-
let n = t, u3 = o2.map((e2) => "lazy" in e2 ? y(e2) : void 0), p = 0;
|
|
742
|
-
for (; p < o2.length; ) {
|
|
743
|
-
if (u3[p] === void 0 || !B(n)) {
|
|
744
|
-
let i2 = o2[p];
|
|
745
|
-
n = i2(n), p += 1;
|
|
746
|
-
continue;
|
|
747
|
-
}
|
|
748
|
-
let r = [];
|
|
749
|
-
for (let i2 = p; i2 < o2.length; i2++) {
|
|
750
|
-
let l = u3[i2];
|
|
751
|
-
if (l === void 0 || (r.push(l), l.isSingle)) break;
|
|
752
|
-
}
|
|
753
|
-
let a3 = [];
|
|
754
|
-
for (let i2 of n) if (f(i2, a3, r)) break;
|
|
755
|
-
let { isSingle: s4 } = r.at(-1);
|
|
756
|
-
n = s4 ? a3[0] : a3, p += r.length;
|
|
757
|
-
}
|
|
758
|
-
return n;
|
|
759
|
-
}
|
|
760
|
-
function f(t, o2, n) {
|
|
761
|
-
if (n.length === 0) return o2.push(t), false;
|
|
762
|
-
let u3 = t, p = s, e2 = false;
|
|
763
|
-
for (let [r, a3] of n.entries()) {
|
|
764
|
-
let { index: s4, items: i2 } = a3;
|
|
765
|
-
if (i2.push(u3), p = a3(u3, s4, i2), a3.index += 1, p.hasNext) {
|
|
766
|
-
if (p.hasMany ?? false) {
|
|
767
|
-
for (let l of p.next) if (f(l, o2, n.slice(r + 1))) return true;
|
|
768
|
-
return e2;
|
|
769
|
-
}
|
|
770
|
-
u3 = p.next;
|
|
771
|
-
}
|
|
772
|
-
if (!p.hasNext) break;
|
|
773
|
-
p.done && (e2 = true);
|
|
774
|
-
}
|
|
775
|
-
return p.hasNext && o2.push(u3), e2;
|
|
776
|
-
}
|
|
777
|
-
function y(t) {
|
|
778
|
-
let { lazy: o2, lazyArgs: n } = t, u3 = o2(...n);
|
|
779
|
-
return Object.assign(u3, { isSingle: o2.single ?? false, index: 0, items: [] });
|
|
780
|
-
}
|
|
781
|
-
function B(t) {
|
|
782
|
-
return typeof t == "string" || typeof t == "object" && t !== null && Symbol.iterator in t;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
// node_modules/.pnpm/remeda@2.21.3/node_modules/remeda/dist/chunk-LFJW7BOT.js
|
|
786
|
-
function y2(t, i2) {
|
|
787
|
-
let a3 = i2.length - t.length;
|
|
788
|
-
if (a3 === 1) {
|
|
789
|
-
let [n, ...r] = i2;
|
|
790
|
-
return C(n, { lazy: t, lazyArgs: r });
|
|
791
|
-
}
|
|
792
|
-
if (a3 === 0) {
|
|
793
|
-
let n = { lazy: t, lazyArgs: i2 };
|
|
794
|
-
return Object.assign((e2) => C(e2, n), n);
|
|
795
|
-
}
|
|
796
|
-
throw new Error("Wrong number of arguments");
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
// node_modules/.pnpm/remeda@2.21.3/node_modules/remeda/dist/chunk-D6FCK2GA.js
|
|
800
|
-
function u(o2, n, a3) {
|
|
801
|
-
let t = (r) => o2(r, ...n);
|
|
802
|
-
return a3 === void 0 ? t : Object.assign(t, { lazy: a3, lazyArgs: n });
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
// node_modules/.pnpm/remeda@2.21.3/node_modules/remeda/dist/chunk-WIMGWYZL.js
|
|
806
|
-
function u2(r, n, o2) {
|
|
807
|
-
let a3 = r.length - n.length;
|
|
808
|
-
if (a3 === 0) return r(...n);
|
|
809
|
-
if (a3 === 1) return u(r, n, o2);
|
|
810
|
-
throw new Error("Wrong number of arguments");
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
// node_modules/.pnpm/remeda@2.21.3/node_modules/remeda/dist/chunk-ENS7GPLZ.js
|
|
814
|
-
function a2(...r) {
|
|
815
|
-
return u2(o, r);
|
|
816
|
-
}
|
|
817
|
-
function o(r, t) {
|
|
818
|
-
let e2 = [];
|
|
819
|
-
for (let n = r; n < t; n++) e2.push(n);
|
|
820
|
-
return e2;
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
// node_modules/.pnpm/remeda@2.21.3/node_modules/remeda/dist/chunk-ICBBHOCR.js
|
|
824
|
-
function s2(...t) {
|
|
825
|
-
return y2(i, t);
|
|
826
|
-
}
|
|
827
|
-
function i(t) {
|
|
828
|
-
if (t.length === 0) return a;
|
|
829
|
-
let n = /* @__PURE__ */ new Map();
|
|
830
|
-
for (let r of t) n.set(r, (n.get(r) ?? 0) + 1);
|
|
831
|
-
return (r) => {
|
|
832
|
-
let e2 = n.get(r);
|
|
833
|
-
return e2 === void 0 || e2 === 0 ? s : (e2 === 1 ? n.delete(r) : n.set(r, e2 - 1), { hasNext: true, next: r, done: n.size === 0 });
|
|
834
|
-
};
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
// node_modules/.pnpm/remeda@2.21.3/node_modules/remeda/dist/chunk-WFMWIRTS.js
|
|
838
|
-
function f2(...e2) {
|
|
839
|
-
return u2(s3, e2);
|
|
840
|
-
}
|
|
841
|
-
function s3(e2, n) {
|
|
842
|
-
if (n < 1) throw new RangeError(`chunk: A chunk size of '${n.toString()}' would result in an infinite array`);
|
|
843
|
-
if (e2.length === 0) return [];
|
|
844
|
-
if (n >= e2.length) return [[...e2]];
|
|
845
|
-
let i2 = Math.ceil(e2.length / n), u3 = new Array(i2);
|
|
846
|
-
if (n === 1) for (let [r, t] of e2.entries()) u3[r] = [t];
|
|
847
|
-
else for (let r = 0; r < i2; r += 1) {
|
|
848
|
-
let t = r * n;
|
|
849
|
-
u3[r] = e2.slice(t, t + n);
|
|
850
|
-
}
|
|
851
|
-
return u3;
|
|
852
|
-
}
|
|
853
|
-
|
|
854
190
|
// src/util.ts
|
|
855
191
|
var chunkStrLength = (items, options = {}) => {
|
|
856
192
|
const { maxLength = 2048, chunkLength = 250, offset = 0, separatorSize = 1 } = options;
|
|
@@ -883,42 +219,109 @@ var chunkStrLength = (items, options = {}) => {
|
|
|
883
219
|
|
|
884
220
|
// src/client.ts
|
|
885
221
|
var MAX_PAGE_SIZE = 250;
|
|
222
|
+
var DEFAULT_CONCURRENCY = 10;
|
|
223
|
+
function chunkArray(array, size) {
|
|
224
|
+
return Array.from(
|
|
225
|
+
{ length: Math.ceil(array.length / size) },
|
|
226
|
+
(_, i) => array.slice(i * size, i * size + size)
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
function rangeArray(start, end) {
|
|
230
|
+
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
231
|
+
}
|
|
886
232
|
var BigCommerceClient = class {
|
|
233
|
+
/**
|
|
234
|
+
* Creates a new BigCommerce client instance
|
|
235
|
+
* @param config - Configuration options for the client
|
|
236
|
+
* @param config.storeHash - The store hash to use for the client
|
|
237
|
+
* @param config.accessToken - The API access token to use for the client
|
|
238
|
+
* @param config.maxRetries - The maximum number of retries for rate limit errors (default: 5)
|
|
239
|
+
* @param config.maxDelay - Maximum time to wait to retry in case of rate limit errors in milliseconds (default: 60000 - 1 minute). If `X-Rate-Limit-Time-Reset-Ms` header is higher than `maxDelay`, the request will fail immediately.
|
|
240
|
+
* @param config.concurrency - The default concurrency for concurrent methods (default: 10)
|
|
241
|
+
* @param config.skipErrors - Whether to skip errors during concurrent requests (default: false)
|
|
242
|
+
* @param config.logger - Optional logger instance for debugging and error tracking
|
|
243
|
+
*/
|
|
887
244
|
constructor(config) {
|
|
888
245
|
this.config = config;
|
|
889
246
|
}
|
|
890
|
-
|
|
247
|
+
/**
|
|
248
|
+
* Makes a GET request to the BigCommerce API
|
|
249
|
+
* @param endpoint - The API endpoint to request
|
|
250
|
+
* @param options.query - Query parameters to include in the request
|
|
251
|
+
* @param options.version - API version to use (v2 or v3) (default: v3)
|
|
252
|
+
* @returns Promise resolving to the response data of type `R`
|
|
253
|
+
*/
|
|
254
|
+
async get(endpoint, options) {
|
|
891
255
|
return request({
|
|
892
|
-
|
|
256
|
+
endpoint,
|
|
893
257
|
method: "GET",
|
|
258
|
+
...options,
|
|
894
259
|
...this.config
|
|
895
260
|
});
|
|
896
261
|
}
|
|
897
|
-
|
|
262
|
+
/**
|
|
263
|
+
* Makes a POST request to the BigCommerce API
|
|
264
|
+
* @param endpoint - The API endpoint to request
|
|
265
|
+
* @param options.query - Query parameters to include in the request
|
|
266
|
+
* @param options.version - API version to use (v2 or v3) (default: v3)
|
|
267
|
+
* @param options.body - Request body data of type `T`
|
|
268
|
+
* @returns Promise resolving to the response data of type `R`
|
|
269
|
+
*/
|
|
270
|
+
async post(endpoint, options) {
|
|
898
271
|
return request({
|
|
899
|
-
|
|
272
|
+
endpoint,
|
|
900
273
|
method: "POST",
|
|
274
|
+
...options,
|
|
901
275
|
...this.config
|
|
902
276
|
});
|
|
903
277
|
}
|
|
904
|
-
|
|
278
|
+
/**
|
|
279
|
+
* Makes a PUT request to the BigCommerce API
|
|
280
|
+
* @param endpoint - The API endpoint to request
|
|
281
|
+
* @param options.query - Query parameters to include in the request
|
|
282
|
+
* @param options.version - API version to use (v2 or v3) (default: v3)
|
|
283
|
+
* @param options.body - Request body data of type `T`
|
|
284
|
+
* @returns Promise resolving to the response data of type `R`
|
|
285
|
+
*/
|
|
286
|
+
async put(endpoint, options) {
|
|
905
287
|
return request({
|
|
906
|
-
|
|
288
|
+
endpoint,
|
|
907
289
|
method: "PUT",
|
|
290
|
+
...options,
|
|
908
291
|
...this.config
|
|
909
292
|
});
|
|
910
293
|
}
|
|
911
|
-
|
|
294
|
+
/**
|
|
295
|
+
* Makes a DELETE request to the BigCommerce API
|
|
296
|
+
* @param endpoint - The API endpoint to delete
|
|
297
|
+
* @param options.version - API version to use (v2 or v3) (default: v3)
|
|
298
|
+
* @returns Promise resolving to void
|
|
299
|
+
*/
|
|
300
|
+
async delete(endpoint, options) {
|
|
912
301
|
await request({
|
|
913
302
|
endpoint,
|
|
914
303
|
method: "DELETE",
|
|
304
|
+
...options,
|
|
915
305
|
...this.config
|
|
916
306
|
});
|
|
917
307
|
}
|
|
308
|
+
/**
|
|
309
|
+
* Executes multiple requests concurrently with controlled concurrency
|
|
310
|
+
* @param requests - Array of request options to execute
|
|
311
|
+
* @param options.concurrency - Maximum number of concurrent requests, overrides the client's concurrency setting (default: 10)
|
|
312
|
+
* @param options.skipErrors - Whether to skip errors and continue processing, overrides the client's skipErrors setting (default: false)
|
|
313
|
+
* @returns Promise resolving to array of response data
|
|
314
|
+
*/
|
|
918
315
|
async concurrent(requests, options) {
|
|
919
|
-
const
|
|
920
|
-
const
|
|
316
|
+
const chunkSize = options?.concurrency ?? this.config.concurrency ?? DEFAULT_CONCURRENCY;
|
|
317
|
+
const chunks = chunkArray(requests, chunkSize);
|
|
318
|
+
const skipErrors = options?.skipErrors ?? this.config.skipErrors ?? false;
|
|
921
319
|
const results = [];
|
|
320
|
+
this.config.logger?.debug({
|
|
321
|
+
totalRequests: requests.length,
|
|
322
|
+
chunkSize,
|
|
323
|
+
chunks: chunks.length
|
|
324
|
+
}, "Starting concurrent requests");
|
|
922
325
|
for (const chunk of chunks) {
|
|
923
326
|
const responses = await Promise.allSettled(
|
|
924
327
|
chunk.map(
|
|
@@ -935,14 +338,28 @@ var BigCommerceClient = class {
|
|
|
935
338
|
if (!skipErrors) {
|
|
936
339
|
throw response.reason;
|
|
937
340
|
} else {
|
|
938
|
-
|
|
341
|
+
this.config.logger?.warn({
|
|
342
|
+
error: response.reason instanceof Error ? {
|
|
343
|
+
name: response.reason.name,
|
|
344
|
+
message: response.reason.message
|
|
345
|
+
} : response.reason
|
|
346
|
+
}, "Error in concurrent request");
|
|
939
347
|
}
|
|
940
348
|
}
|
|
941
349
|
});
|
|
942
350
|
}
|
|
943
351
|
return results;
|
|
944
352
|
}
|
|
945
|
-
|
|
353
|
+
/**
|
|
354
|
+
* Collects all pages of data from a paginated v3 API endpoint.
|
|
355
|
+
* This method pulls the first page and uses pagination meta to collect the remaining pages concurrently.
|
|
356
|
+
* @param endpoint - The API endpoint to request
|
|
357
|
+
* @param options.query - Query parameters to include in the request
|
|
358
|
+
* @param options.concurrency - Maximum number of concurrent requests, overrides the client's concurrency setting (default: 10)
|
|
359
|
+
* @param options.skipErrors - Whether to skip errors and continue processing, overrides the client's skipErrors setting (default: false)
|
|
360
|
+
* @returns Promise resolving to array of all items across all pages
|
|
361
|
+
*/
|
|
362
|
+
async collect(endpoint, options) {
|
|
946
363
|
if (options.query) {
|
|
947
364
|
if (!options.query.limit) {
|
|
948
365
|
options.query.limit = MAX_PAGE_SIZE.toString();
|
|
@@ -950,24 +367,44 @@ var BigCommerceClient = class {
|
|
|
950
367
|
} else {
|
|
951
368
|
options.query = { limit: MAX_PAGE_SIZE.toString() };
|
|
952
369
|
}
|
|
953
|
-
const first = await this.get(options);
|
|
370
|
+
const first = await this.get(endpoint, options);
|
|
954
371
|
if (!Array.isArray(first.data) || !first?.meta?.pagination?.total_pages) {
|
|
955
372
|
return first.data;
|
|
956
373
|
}
|
|
957
374
|
const results = [...first.data];
|
|
958
375
|
const pages = first.meta.pagination.total_pages;
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
376
|
+
if (pages > 1) {
|
|
377
|
+
this.config.logger?.debug({
|
|
378
|
+
totalPages: pages,
|
|
379
|
+
itemsPerPage: first.data.length
|
|
380
|
+
}, "Collecting remaining pages");
|
|
381
|
+
const pageRequests = rangeArray(2, pages).map((page) => ({
|
|
382
|
+
endpoint,
|
|
383
|
+
method: "GET",
|
|
384
|
+
query: {
|
|
385
|
+
...options.query,
|
|
386
|
+
page: page.toString()
|
|
387
|
+
}
|
|
388
|
+
}));
|
|
389
|
+
const remainingPages = await this.concurrent(pageRequests, options);
|
|
390
|
+
remainingPages.forEach((page) => {
|
|
391
|
+
if (Array.isArray(page.data)) {
|
|
392
|
+
results.push(...page.data);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
}
|
|
968
396
|
return results;
|
|
969
397
|
}
|
|
970
|
-
|
|
398
|
+
/**
|
|
399
|
+
* Collects all pages of data from a paginated v2 API endpoint.
|
|
400
|
+
* This method simply pulls all pages concurrently until a 204 is returned in a batch.
|
|
401
|
+
* @param endpoint - The API endpoint to request
|
|
402
|
+
* @param options.query - Query parameters to include in the request
|
|
403
|
+
* @param options.concurrency - Maximum number of concurrent requests, overrides the client's concurrency setting (default: 10)
|
|
404
|
+
* @param options.skipErrors - Whether to skip errors and continue processing, overrides the client's skipErrors setting (default: false)
|
|
405
|
+
* @returns Promise resolving to array of all items across all pages
|
|
406
|
+
*/
|
|
407
|
+
async collectV2(endpoint, options) {
|
|
971
408
|
if (options.query) {
|
|
972
409
|
if (!options.query.limit) {
|
|
973
410
|
options.query.limit = MAX_PAGE_SIZE.toString();
|
|
@@ -978,16 +415,17 @@ var BigCommerceClient = class {
|
|
|
978
415
|
let done = false;
|
|
979
416
|
const results = [];
|
|
980
417
|
let page = 1;
|
|
981
|
-
const concurrency = options.concurrency ??
|
|
418
|
+
const concurrency = options.concurrency ?? this.config.concurrency ?? DEFAULT_CONCURRENCY;
|
|
982
419
|
while (!done) {
|
|
983
|
-
const pages =
|
|
420
|
+
const pages = rangeArray(page, page + concurrency);
|
|
984
421
|
page += concurrency;
|
|
985
422
|
const requests = pages.map((page2) => ({
|
|
986
423
|
...options,
|
|
424
|
+
endpoint,
|
|
987
425
|
version: "v2",
|
|
988
426
|
query: { ...options.query, page: page2.toString() }
|
|
989
427
|
}));
|
|
990
|
-
const responses = await Promise.allSettled(requests.map((request2) => this.get(request2)));
|
|
428
|
+
const responses = await Promise.allSettled(requests.map((request2) => this.get(endpoint, request2)));
|
|
991
429
|
responses.forEach((response) => {
|
|
992
430
|
if (response.status === "fulfilled") {
|
|
993
431
|
if (response.value) {
|
|
@@ -999,10 +437,15 @@ var BigCommerceClient = class {
|
|
|
999
437
|
if (response.reason instanceof RequestError && response.reason.status === 404) {
|
|
1000
438
|
done = true;
|
|
1001
439
|
} else {
|
|
1002
|
-
if (!options.skipErrors) {
|
|
440
|
+
if (!(options.skipErrors ?? this.config.skipErrors ?? false)) {
|
|
1003
441
|
throw response.reason;
|
|
1004
442
|
} else {
|
|
1005
|
-
|
|
443
|
+
this.config.logger?.warn({
|
|
444
|
+
error: response.reason instanceof Error ? {
|
|
445
|
+
name: response.reason.name,
|
|
446
|
+
message: response.reason.message
|
|
447
|
+
} : response.reason
|
|
448
|
+
}, "Error in collectV2");
|
|
1006
449
|
}
|
|
1007
450
|
}
|
|
1008
451
|
}
|
|
@@ -1010,7 +453,20 @@ var BigCommerceClient = class {
|
|
|
1010
453
|
}
|
|
1011
454
|
return results;
|
|
1012
455
|
}
|
|
1013
|
-
|
|
456
|
+
/**
|
|
457
|
+
* Queries multiple values against a single field using the v3 API.
|
|
458
|
+
* If the url + query params are too long, the query will be chunked. Otherwise, this method acts like `collect`.
|
|
459
|
+
* This method does not check for uniqueness of the `values` array.
|
|
460
|
+
*
|
|
461
|
+
* @param endpoint - The API endpoint to request
|
|
462
|
+
* @param options.key - The field name to query against e.g. `sku:in`
|
|
463
|
+
* @param options.values - Array of values to query for e.g. `['123', '456', ...]`
|
|
464
|
+
* @param options.query - Additional query parameters
|
|
465
|
+
* @param options.concurrency - Maximum number of concurrent requests, overrides the client's concurrency setting (default: 10)
|
|
466
|
+
* @param options.skipErrors - Whether to skip errors and continue processing, overrides the client's skipErrors setting (default: false)
|
|
467
|
+
* @returns Promise resolving to array of matching items
|
|
468
|
+
*/
|
|
469
|
+
async query(endpoint, options) {
|
|
1014
470
|
if (options.query) {
|
|
1015
471
|
if (!options.query.limit) {
|
|
1016
472
|
options.query.limit = MAX_PAGE_SIZE.toString();
|
|
@@ -1018,12 +474,21 @@ var BigCommerceClient = class {
|
|
|
1018
474
|
} else {
|
|
1019
475
|
options.query = { limit: MAX_PAGE_SIZE.toString() };
|
|
1020
476
|
}
|
|
477
|
+
const { limit: _, ...restQuery } = options.query;
|
|
478
|
+
const fullUrl = `${BASE_URL}${this.config.storeHash}/v3/${endpoint}?${new URLSearchParams(restQuery).toString()}`;
|
|
1021
479
|
const queryStr = options.values.map((value) => `${value}`);
|
|
1022
480
|
const chunks = chunkStrLength(queryStr, {
|
|
1023
|
-
|
|
481
|
+
offset: fullUrl.length,
|
|
482
|
+
chunkLength: Number.parseInt(options.query?.limit) || MAX_PAGE_SIZE
|
|
1024
483
|
});
|
|
484
|
+
this.config.logger?.debug({
|
|
485
|
+
totalValues: options.values.length,
|
|
486
|
+
chunks: chunks.length,
|
|
487
|
+
valuesPerChunk: chunks[0]?.length
|
|
488
|
+
}, "Querying with chunked values");
|
|
1025
489
|
const requests = chunks.map((chunk) => ({
|
|
1026
490
|
...options,
|
|
491
|
+
endpoint,
|
|
1027
492
|
query: { ...options.query, [options.key]: chunk.join(",") }
|
|
1028
493
|
}));
|
|
1029
494
|
const responses = await this.concurrent(requests, options);
|
|
@@ -1031,1092 +496,38 @@ var BigCommerceClient = class {
|
|
|
1031
496
|
}
|
|
1032
497
|
};
|
|
1033
498
|
|
|
1034
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/buffer_utils.js
|
|
1035
|
-
var encoder = new TextEncoder();
|
|
1036
|
-
var decoder = new TextDecoder();
|
|
1037
|
-
var MAX_INT32 = 2 ** 32;
|
|
1038
|
-
function concat(...buffers) {
|
|
1039
|
-
const size = buffers.reduce((acc, { length }) => acc + length, 0);
|
|
1040
|
-
const buf = new Uint8Array(size);
|
|
1041
|
-
let i2 = 0;
|
|
1042
|
-
for (const buffer of buffers) {
|
|
1043
|
-
buf.set(buffer, i2);
|
|
1044
|
-
i2 += buffer.length;
|
|
1045
|
-
}
|
|
1046
|
-
return buf;
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/base64.js
|
|
1050
|
-
function decodeBase64(encoded) {
|
|
1051
|
-
if (Uint8Array.fromBase64) {
|
|
1052
|
-
return Uint8Array.fromBase64(encoded);
|
|
1053
|
-
}
|
|
1054
|
-
const binary = atob(encoded);
|
|
1055
|
-
const bytes = new Uint8Array(binary.length);
|
|
1056
|
-
for (let i2 = 0; i2 < binary.length; i2++) {
|
|
1057
|
-
bytes[i2] = binary.charCodeAt(i2);
|
|
1058
|
-
}
|
|
1059
|
-
return bytes;
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/util/base64url.js
|
|
1063
|
-
function decode(input) {
|
|
1064
|
-
if (Uint8Array.fromBase64) {
|
|
1065
|
-
return Uint8Array.fromBase64(typeof input === "string" ? input : decoder.decode(input), {
|
|
1066
|
-
alphabet: "base64url"
|
|
1067
|
-
});
|
|
1068
|
-
}
|
|
1069
|
-
let encoded = input;
|
|
1070
|
-
if (encoded instanceof Uint8Array) {
|
|
1071
|
-
encoded = decoder.decode(encoded);
|
|
1072
|
-
}
|
|
1073
|
-
encoded = encoded.replace(/-/g, "+").replace(/_/g, "/").replace(/\s/g, "");
|
|
1074
|
-
try {
|
|
1075
|
-
return decodeBase64(encoded);
|
|
1076
|
-
} catch {
|
|
1077
|
-
throw new TypeError("The input to be decoded is not correctly encoded.");
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/util/errors.js
|
|
1082
|
-
var JOSEError = class extends Error {
|
|
1083
|
-
static code = "ERR_JOSE_GENERIC";
|
|
1084
|
-
code = "ERR_JOSE_GENERIC";
|
|
1085
|
-
constructor(message2, options) {
|
|
1086
|
-
super(message2, options);
|
|
1087
|
-
this.name = this.constructor.name;
|
|
1088
|
-
Error.captureStackTrace?.(this, this.constructor);
|
|
1089
|
-
}
|
|
1090
|
-
};
|
|
1091
|
-
var JWTClaimValidationFailed = class extends JOSEError {
|
|
1092
|
-
static code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
|
|
1093
|
-
code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
|
|
1094
|
-
claim;
|
|
1095
|
-
reason;
|
|
1096
|
-
payload;
|
|
1097
|
-
constructor(message2, payload, claim = "unspecified", reason = "unspecified") {
|
|
1098
|
-
super(message2, { cause: { claim, reason, payload } });
|
|
1099
|
-
this.claim = claim;
|
|
1100
|
-
this.reason = reason;
|
|
1101
|
-
this.payload = payload;
|
|
1102
|
-
}
|
|
1103
|
-
};
|
|
1104
|
-
var JWTExpired = class extends JOSEError {
|
|
1105
|
-
static code = "ERR_JWT_EXPIRED";
|
|
1106
|
-
code = "ERR_JWT_EXPIRED";
|
|
1107
|
-
claim;
|
|
1108
|
-
reason;
|
|
1109
|
-
payload;
|
|
1110
|
-
constructor(message2, payload, claim = "unspecified", reason = "unspecified") {
|
|
1111
|
-
super(message2, { cause: { claim, reason, payload } });
|
|
1112
|
-
this.claim = claim;
|
|
1113
|
-
this.reason = reason;
|
|
1114
|
-
this.payload = payload;
|
|
1115
|
-
}
|
|
1116
|
-
};
|
|
1117
|
-
var JOSEAlgNotAllowed = class extends JOSEError {
|
|
1118
|
-
static code = "ERR_JOSE_ALG_NOT_ALLOWED";
|
|
1119
|
-
code = "ERR_JOSE_ALG_NOT_ALLOWED";
|
|
1120
|
-
};
|
|
1121
|
-
var JOSENotSupported = class extends JOSEError {
|
|
1122
|
-
static code = "ERR_JOSE_NOT_SUPPORTED";
|
|
1123
|
-
code = "ERR_JOSE_NOT_SUPPORTED";
|
|
1124
|
-
};
|
|
1125
|
-
var JWSInvalid = class extends JOSEError {
|
|
1126
|
-
static code = "ERR_JWS_INVALID";
|
|
1127
|
-
code = "ERR_JWS_INVALID";
|
|
1128
|
-
};
|
|
1129
|
-
var JWTInvalid = class extends JOSEError {
|
|
1130
|
-
static code = "ERR_JWT_INVALID";
|
|
1131
|
-
code = "ERR_JWT_INVALID";
|
|
1132
|
-
};
|
|
1133
|
-
var JWSSignatureVerificationFailed = class extends JOSEError {
|
|
1134
|
-
static code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
|
|
1135
|
-
code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
|
|
1136
|
-
constructor(message2 = "signature verification failed", options) {
|
|
1137
|
-
super(message2, options);
|
|
1138
|
-
}
|
|
1139
|
-
};
|
|
1140
|
-
|
|
1141
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/crypto_key.js
|
|
1142
|
-
function unusable(name, prop = "algorithm.name") {
|
|
1143
|
-
return new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
|
|
1144
|
-
}
|
|
1145
|
-
function isAlgorithm(algorithm, name) {
|
|
1146
|
-
return algorithm.name === name;
|
|
1147
|
-
}
|
|
1148
|
-
function getHashLength(hash) {
|
|
1149
|
-
return parseInt(hash.name.slice(4), 10);
|
|
1150
|
-
}
|
|
1151
|
-
function getNamedCurve(alg) {
|
|
1152
|
-
switch (alg) {
|
|
1153
|
-
case "ES256":
|
|
1154
|
-
return "P-256";
|
|
1155
|
-
case "ES384":
|
|
1156
|
-
return "P-384";
|
|
1157
|
-
case "ES512":
|
|
1158
|
-
return "P-521";
|
|
1159
|
-
default:
|
|
1160
|
-
throw new Error("unreachable");
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1163
|
-
function checkUsage(key, usage) {
|
|
1164
|
-
if (usage && !key.usages.includes(usage)) {
|
|
1165
|
-
throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
function checkSigCryptoKey(key, alg, usage) {
|
|
1169
|
-
switch (alg) {
|
|
1170
|
-
case "HS256":
|
|
1171
|
-
case "HS384":
|
|
1172
|
-
case "HS512": {
|
|
1173
|
-
if (!isAlgorithm(key.algorithm, "HMAC"))
|
|
1174
|
-
throw unusable("HMAC");
|
|
1175
|
-
const expected = parseInt(alg.slice(2), 10);
|
|
1176
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
1177
|
-
if (actual !== expected)
|
|
1178
|
-
throw unusable(`SHA-${expected}`, "algorithm.hash");
|
|
1179
|
-
break;
|
|
1180
|
-
}
|
|
1181
|
-
case "RS256":
|
|
1182
|
-
case "RS384":
|
|
1183
|
-
case "RS512": {
|
|
1184
|
-
if (!isAlgorithm(key.algorithm, "RSASSA-PKCS1-v1_5"))
|
|
1185
|
-
throw unusable("RSASSA-PKCS1-v1_5");
|
|
1186
|
-
const expected = parseInt(alg.slice(2), 10);
|
|
1187
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
1188
|
-
if (actual !== expected)
|
|
1189
|
-
throw unusable(`SHA-${expected}`, "algorithm.hash");
|
|
1190
|
-
break;
|
|
1191
|
-
}
|
|
1192
|
-
case "PS256":
|
|
1193
|
-
case "PS384":
|
|
1194
|
-
case "PS512": {
|
|
1195
|
-
if (!isAlgorithm(key.algorithm, "RSA-PSS"))
|
|
1196
|
-
throw unusable("RSA-PSS");
|
|
1197
|
-
const expected = parseInt(alg.slice(2), 10);
|
|
1198
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
1199
|
-
if (actual !== expected)
|
|
1200
|
-
throw unusable(`SHA-${expected}`, "algorithm.hash");
|
|
1201
|
-
break;
|
|
1202
|
-
}
|
|
1203
|
-
case "Ed25519":
|
|
1204
|
-
case "EdDSA": {
|
|
1205
|
-
if (!isAlgorithm(key.algorithm, "Ed25519"))
|
|
1206
|
-
throw unusable("Ed25519");
|
|
1207
|
-
break;
|
|
1208
|
-
}
|
|
1209
|
-
case "ES256":
|
|
1210
|
-
case "ES384":
|
|
1211
|
-
case "ES512": {
|
|
1212
|
-
if (!isAlgorithm(key.algorithm, "ECDSA"))
|
|
1213
|
-
throw unusable("ECDSA");
|
|
1214
|
-
const expected = getNamedCurve(alg);
|
|
1215
|
-
const actual = key.algorithm.namedCurve;
|
|
1216
|
-
if (actual !== expected)
|
|
1217
|
-
throw unusable(expected, "algorithm.namedCurve");
|
|
1218
|
-
break;
|
|
1219
|
-
}
|
|
1220
|
-
default:
|
|
1221
|
-
throw new TypeError("CryptoKey does not support this operation");
|
|
1222
|
-
}
|
|
1223
|
-
checkUsage(key, usage);
|
|
1224
|
-
}
|
|
1225
|
-
|
|
1226
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/invalid_key_input.js
|
|
1227
|
-
function message(msg, actual, ...types) {
|
|
1228
|
-
types = types.filter(Boolean);
|
|
1229
|
-
if (types.length > 2) {
|
|
1230
|
-
const last = types.pop();
|
|
1231
|
-
msg += `one of type ${types.join(", ")}, or ${last}.`;
|
|
1232
|
-
} else if (types.length === 2) {
|
|
1233
|
-
msg += `one of type ${types[0]} or ${types[1]}.`;
|
|
1234
|
-
} else {
|
|
1235
|
-
msg += `of type ${types[0]}.`;
|
|
1236
|
-
}
|
|
1237
|
-
if (actual == null) {
|
|
1238
|
-
msg += ` Received ${actual}`;
|
|
1239
|
-
} else if (typeof actual === "function" && actual.name) {
|
|
1240
|
-
msg += ` Received function ${actual.name}`;
|
|
1241
|
-
} else if (typeof actual === "object" && actual != null) {
|
|
1242
|
-
if (actual.constructor?.name) {
|
|
1243
|
-
msg += ` Received an instance of ${actual.constructor.name}`;
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
return msg;
|
|
1247
|
-
}
|
|
1248
|
-
var invalid_key_input_default = (actual, ...types) => {
|
|
1249
|
-
return message("Key must be ", actual, ...types);
|
|
1250
|
-
};
|
|
1251
|
-
function withAlg(alg, actual, ...types) {
|
|
1252
|
-
return message(`Key for the ${alg} algorithm must be `, actual, ...types);
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/is_key_like.js
|
|
1256
|
-
function isCryptoKey(key) {
|
|
1257
|
-
return key?.[Symbol.toStringTag] === "CryptoKey";
|
|
1258
|
-
}
|
|
1259
|
-
function isKeyObject(key) {
|
|
1260
|
-
return key?.[Symbol.toStringTag] === "KeyObject";
|
|
1261
|
-
}
|
|
1262
|
-
var is_key_like_default = (key) => {
|
|
1263
|
-
return isCryptoKey(key) || isKeyObject(key);
|
|
1264
|
-
};
|
|
1265
|
-
|
|
1266
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/is_disjoint.js
|
|
1267
|
-
var is_disjoint_default = (...headers) => {
|
|
1268
|
-
const sources = headers.filter(Boolean);
|
|
1269
|
-
if (sources.length === 0 || sources.length === 1) {
|
|
1270
|
-
return true;
|
|
1271
|
-
}
|
|
1272
|
-
let acc;
|
|
1273
|
-
for (const header of sources) {
|
|
1274
|
-
const parameters = Object.keys(header);
|
|
1275
|
-
if (!acc || acc.size === 0) {
|
|
1276
|
-
acc = new Set(parameters);
|
|
1277
|
-
continue;
|
|
1278
|
-
}
|
|
1279
|
-
for (const parameter of parameters) {
|
|
1280
|
-
if (acc.has(parameter)) {
|
|
1281
|
-
return false;
|
|
1282
|
-
}
|
|
1283
|
-
acc.add(parameter);
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
return true;
|
|
1287
|
-
};
|
|
1288
|
-
|
|
1289
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/is_object.js
|
|
1290
|
-
function isObjectLike(value) {
|
|
1291
|
-
return typeof value === "object" && value !== null;
|
|
1292
|
-
}
|
|
1293
|
-
var is_object_default = (input) => {
|
|
1294
|
-
if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") {
|
|
1295
|
-
return false;
|
|
1296
|
-
}
|
|
1297
|
-
if (Object.getPrototypeOf(input) === null) {
|
|
1298
|
-
return true;
|
|
1299
|
-
}
|
|
1300
|
-
let proto = input;
|
|
1301
|
-
while (Object.getPrototypeOf(proto) !== null) {
|
|
1302
|
-
proto = Object.getPrototypeOf(proto);
|
|
1303
|
-
}
|
|
1304
|
-
return Object.getPrototypeOf(input) === proto;
|
|
1305
|
-
};
|
|
1306
|
-
|
|
1307
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/check_key_length.js
|
|
1308
|
-
var check_key_length_default = (alg, key) => {
|
|
1309
|
-
if (alg.startsWith("RS") || alg.startsWith("PS")) {
|
|
1310
|
-
const { modulusLength } = key.algorithm;
|
|
1311
|
-
if (typeof modulusLength !== "number" || modulusLength < 2048) {
|
|
1312
|
-
throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
};
|
|
1316
|
-
|
|
1317
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/jwk_to_key.js
|
|
1318
|
-
function subtleMapping(jwk) {
|
|
1319
|
-
let algorithm;
|
|
1320
|
-
let keyUsages;
|
|
1321
|
-
switch (jwk.kty) {
|
|
1322
|
-
case "RSA": {
|
|
1323
|
-
switch (jwk.alg) {
|
|
1324
|
-
case "PS256":
|
|
1325
|
-
case "PS384":
|
|
1326
|
-
case "PS512":
|
|
1327
|
-
algorithm = { name: "RSA-PSS", hash: `SHA-${jwk.alg.slice(-3)}` };
|
|
1328
|
-
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1329
|
-
break;
|
|
1330
|
-
case "RS256":
|
|
1331
|
-
case "RS384":
|
|
1332
|
-
case "RS512":
|
|
1333
|
-
algorithm = { name: "RSASSA-PKCS1-v1_5", hash: `SHA-${jwk.alg.slice(-3)}` };
|
|
1334
|
-
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1335
|
-
break;
|
|
1336
|
-
case "RSA-OAEP":
|
|
1337
|
-
case "RSA-OAEP-256":
|
|
1338
|
-
case "RSA-OAEP-384":
|
|
1339
|
-
case "RSA-OAEP-512":
|
|
1340
|
-
algorithm = {
|
|
1341
|
-
name: "RSA-OAEP",
|
|
1342
|
-
hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}`
|
|
1343
|
-
};
|
|
1344
|
-
keyUsages = jwk.d ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"];
|
|
1345
|
-
break;
|
|
1346
|
-
default:
|
|
1347
|
-
throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
|
|
1348
|
-
}
|
|
1349
|
-
break;
|
|
1350
|
-
}
|
|
1351
|
-
case "EC": {
|
|
1352
|
-
switch (jwk.alg) {
|
|
1353
|
-
case "ES256":
|
|
1354
|
-
algorithm = { name: "ECDSA", namedCurve: "P-256" };
|
|
1355
|
-
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1356
|
-
break;
|
|
1357
|
-
case "ES384":
|
|
1358
|
-
algorithm = { name: "ECDSA", namedCurve: "P-384" };
|
|
1359
|
-
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1360
|
-
break;
|
|
1361
|
-
case "ES512":
|
|
1362
|
-
algorithm = { name: "ECDSA", namedCurve: "P-521" };
|
|
1363
|
-
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1364
|
-
break;
|
|
1365
|
-
case "ECDH-ES":
|
|
1366
|
-
case "ECDH-ES+A128KW":
|
|
1367
|
-
case "ECDH-ES+A192KW":
|
|
1368
|
-
case "ECDH-ES+A256KW":
|
|
1369
|
-
algorithm = { name: "ECDH", namedCurve: jwk.crv };
|
|
1370
|
-
keyUsages = jwk.d ? ["deriveBits"] : [];
|
|
1371
|
-
break;
|
|
1372
|
-
default:
|
|
1373
|
-
throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
|
|
1374
|
-
}
|
|
1375
|
-
break;
|
|
1376
|
-
}
|
|
1377
|
-
case "OKP": {
|
|
1378
|
-
switch (jwk.alg) {
|
|
1379
|
-
case "Ed25519":
|
|
1380
|
-
case "EdDSA":
|
|
1381
|
-
algorithm = { name: "Ed25519" };
|
|
1382
|
-
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
1383
|
-
break;
|
|
1384
|
-
case "ECDH-ES":
|
|
1385
|
-
case "ECDH-ES+A128KW":
|
|
1386
|
-
case "ECDH-ES+A192KW":
|
|
1387
|
-
case "ECDH-ES+A256KW":
|
|
1388
|
-
algorithm = { name: jwk.crv };
|
|
1389
|
-
keyUsages = jwk.d ? ["deriveBits"] : [];
|
|
1390
|
-
break;
|
|
1391
|
-
default:
|
|
1392
|
-
throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
|
|
1393
|
-
}
|
|
1394
|
-
break;
|
|
1395
|
-
}
|
|
1396
|
-
default:
|
|
1397
|
-
throw new JOSENotSupported('Invalid or unsupported JWK "kty" (Key Type) Parameter value');
|
|
1398
|
-
}
|
|
1399
|
-
return { algorithm, keyUsages };
|
|
1400
|
-
}
|
|
1401
|
-
var jwk_to_key_default = async (jwk) => {
|
|
1402
|
-
if (!jwk.alg) {
|
|
1403
|
-
throw new TypeError('"alg" argument is required when "jwk.alg" is not present');
|
|
1404
|
-
}
|
|
1405
|
-
const { algorithm, keyUsages } = subtleMapping(jwk);
|
|
1406
|
-
const keyData = { ...jwk };
|
|
1407
|
-
delete keyData.alg;
|
|
1408
|
-
delete keyData.use;
|
|
1409
|
-
return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? (jwk.d ? false : true), jwk.key_ops ?? keyUsages);
|
|
1410
|
-
};
|
|
1411
|
-
|
|
1412
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/validate_crit.js
|
|
1413
|
-
var validate_crit_default = (Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) => {
|
|
1414
|
-
if (joseHeader.crit !== void 0 && protectedHeader?.crit === void 0) {
|
|
1415
|
-
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
|
|
1416
|
-
}
|
|
1417
|
-
if (!protectedHeader || protectedHeader.crit === void 0) {
|
|
1418
|
-
return /* @__PURE__ */ new Set();
|
|
1419
|
-
}
|
|
1420
|
-
if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input !== "string" || input.length === 0)) {
|
|
1421
|
-
throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');
|
|
1422
|
-
}
|
|
1423
|
-
let recognized;
|
|
1424
|
-
if (recognizedOption !== void 0) {
|
|
1425
|
-
recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]);
|
|
1426
|
-
} else {
|
|
1427
|
-
recognized = recognizedDefault;
|
|
1428
|
-
}
|
|
1429
|
-
for (const parameter of protectedHeader.crit) {
|
|
1430
|
-
if (!recognized.has(parameter)) {
|
|
1431
|
-
throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
|
|
1432
|
-
}
|
|
1433
|
-
if (joseHeader[parameter] === void 0) {
|
|
1434
|
-
throw new Err(`Extension Header Parameter "${parameter}" is missing`);
|
|
1435
|
-
}
|
|
1436
|
-
if (recognized.get(parameter) && protectedHeader[parameter] === void 0) {
|
|
1437
|
-
throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
return new Set(protectedHeader.crit);
|
|
1441
|
-
};
|
|
1442
|
-
|
|
1443
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/validate_algorithms.js
|
|
1444
|
-
var validate_algorithms_default = (option, algorithms) => {
|
|
1445
|
-
if (algorithms !== void 0 && (!Array.isArray(algorithms) || algorithms.some((s4) => typeof s4 !== "string"))) {
|
|
1446
|
-
throw new TypeError(`"${option}" option must be an array of strings`);
|
|
1447
|
-
}
|
|
1448
|
-
if (!algorithms) {
|
|
1449
|
-
return void 0;
|
|
1450
|
-
}
|
|
1451
|
-
return new Set(algorithms);
|
|
1452
|
-
};
|
|
1453
|
-
|
|
1454
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/is_jwk.js
|
|
1455
|
-
function isJWK(key) {
|
|
1456
|
-
return is_object_default(key) && typeof key.kty === "string";
|
|
1457
|
-
}
|
|
1458
|
-
function isPrivateJWK(key) {
|
|
1459
|
-
return key.kty !== "oct" && typeof key.d === "string";
|
|
1460
|
-
}
|
|
1461
|
-
function isPublicJWK(key) {
|
|
1462
|
-
return key.kty !== "oct" && typeof key.d === "undefined";
|
|
1463
|
-
}
|
|
1464
|
-
function isSecretJWK(key) {
|
|
1465
|
-
return key.kty === "oct" && typeof key.k === "string";
|
|
1466
|
-
}
|
|
1467
|
-
|
|
1468
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/normalize_key.js
|
|
1469
|
-
var cache;
|
|
1470
|
-
var handleJWK = async (key, jwk, alg, freeze = false) => {
|
|
1471
|
-
cache ||= /* @__PURE__ */ new WeakMap();
|
|
1472
|
-
let cached = cache.get(key);
|
|
1473
|
-
if (cached?.[alg]) {
|
|
1474
|
-
return cached[alg];
|
|
1475
|
-
}
|
|
1476
|
-
const cryptoKey = await jwk_to_key_default({ ...jwk, alg });
|
|
1477
|
-
if (freeze)
|
|
1478
|
-
Object.freeze(key);
|
|
1479
|
-
if (!cached) {
|
|
1480
|
-
cache.set(key, { [alg]: cryptoKey });
|
|
1481
|
-
} else {
|
|
1482
|
-
cached[alg] = cryptoKey;
|
|
1483
|
-
}
|
|
1484
|
-
return cryptoKey;
|
|
1485
|
-
};
|
|
1486
|
-
var handleKeyObject = (keyObject, alg) => {
|
|
1487
|
-
cache ||= /* @__PURE__ */ new WeakMap();
|
|
1488
|
-
let cached = cache.get(keyObject);
|
|
1489
|
-
if (cached?.[alg]) {
|
|
1490
|
-
return cached[alg];
|
|
1491
|
-
}
|
|
1492
|
-
const isPublic = keyObject.type === "public";
|
|
1493
|
-
const extractable = isPublic ? true : false;
|
|
1494
|
-
let cryptoKey;
|
|
1495
|
-
if (keyObject.asymmetricKeyType === "x25519") {
|
|
1496
|
-
switch (alg) {
|
|
1497
|
-
case "ECDH-ES":
|
|
1498
|
-
case "ECDH-ES+A128KW":
|
|
1499
|
-
case "ECDH-ES+A192KW":
|
|
1500
|
-
case "ECDH-ES+A256KW":
|
|
1501
|
-
break;
|
|
1502
|
-
default:
|
|
1503
|
-
throw new TypeError("given KeyObject instance cannot be used for this algorithm");
|
|
1504
|
-
}
|
|
1505
|
-
cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, isPublic ? [] : ["deriveBits"]);
|
|
1506
|
-
}
|
|
1507
|
-
if (keyObject.asymmetricKeyType === "ed25519") {
|
|
1508
|
-
if (alg !== "EdDSA" && alg !== "Ed25519") {
|
|
1509
|
-
throw new TypeError("given KeyObject instance cannot be used for this algorithm");
|
|
1510
|
-
}
|
|
1511
|
-
cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [
|
|
1512
|
-
isPublic ? "verify" : "sign"
|
|
1513
|
-
]);
|
|
1514
|
-
}
|
|
1515
|
-
if (keyObject.asymmetricKeyType === "rsa") {
|
|
1516
|
-
let hash;
|
|
1517
|
-
switch (alg) {
|
|
1518
|
-
case "RSA-OAEP":
|
|
1519
|
-
hash = "SHA-1";
|
|
1520
|
-
break;
|
|
1521
|
-
case "RS256":
|
|
1522
|
-
case "PS256":
|
|
1523
|
-
case "RSA-OAEP-256":
|
|
1524
|
-
hash = "SHA-256";
|
|
1525
|
-
break;
|
|
1526
|
-
case "RS384":
|
|
1527
|
-
case "PS384":
|
|
1528
|
-
case "RSA-OAEP-384":
|
|
1529
|
-
hash = "SHA-384";
|
|
1530
|
-
break;
|
|
1531
|
-
case "RS512":
|
|
1532
|
-
case "PS512":
|
|
1533
|
-
case "RSA-OAEP-512":
|
|
1534
|
-
hash = "SHA-512";
|
|
1535
|
-
break;
|
|
1536
|
-
default:
|
|
1537
|
-
throw new TypeError("given KeyObject instance cannot be used for this algorithm");
|
|
1538
|
-
}
|
|
1539
|
-
if (alg.startsWith("RSA-OAEP")) {
|
|
1540
|
-
return keyObject.toCryptoKey({
|
|
1541
|
-
name: "RSA-OAEP",
|
|
1542
|
-
hash
|
|
1543
|
-
}, extractable, isPublic ? ["encrypt"] : ["decrypt"]);
|
|
1544
|
-
}
|
|
1545
|
-
cryptoKey = keyObject.toCryptoKey({
|
|
1546
|
-
name: alg.startsWith("PS") ? "RSA-PSS" : "RSASSA-PKCS1-v1_5",
|
|
1547
|
-
hash
|
|
1548
|
-
}, extractable, [isPublic ? "verify" : "sign"]);
|
|
1549
|
-
}
|
|
1550
|
-
if (keyObject.asymmetricKeyType === "ec") {
|
|
1551
|
-
const nist = /* @__PURE__ */ new Map([
|
|
1552
|
-
["prime256v1", "P-256"],
|
|
1553
|
-
["secp384r1", "P-384"],
|
|
1554
|
-
["secp521r1", "P-521"]
|
|
1555
|
-
]);
|
|
1556
|
-
const namedCurve = nist.get(keyObject.asymmetricKeyDetails?.namedCurve);
|
|
1557
|
-
if (!namedCurve) {
|
|
1558
|
-
throw new TypeError("given KeyObject instance cannot be used for this algorithm");
|
|
1559
|
-
}
|
|
1560
|
-
if (alg === "ES256" && namedCurve === "P-256") {
|
|
1561
|
-
cryptoKey = keyObject.toCryptoKey({
|
|
1562
|
-
name: "ECDSA",
|
|
1563
|
-
namedCurve
|
|
1564
|
-
}, extractable, [isPublic ? "verify" : "sign"]);
|
|
1565
|
-
}
|
|
1566
|
-
if (alg === "ES384" && namedCurve === "P-384") {
|
|
1567
|
-
cryptoKey = keyObject.toCryptoKey({
|
|
1568
|
-
name: "ECDSA",
|
|
1569
|
-
namedCurve
|
|
1570
|
-
}, extractable, [isPublic ? "verify" : "sign"]);
|
|
1571
|
-
}
|
|
1572
|
-
if (alg === "ES512" && namedCurve === "P-521") {
|
|
1573
|
-
cryptoKey = keyObject.toCryptoKey({
|
|
1574
|
-
name: "ECDSA",
|
|
1575
|
-
namedCurve
|
|
1576
|
-
}, extractable, [isPublic ? "verify" : "sign"]);
|
|
1577
|
-
}
|
|
1578
|
-
if (alg.startsWith("ECDH-ES")) {
|
|
1579
|
-
cryptoKey = keyObject.toCryptoKey({
|
|
1580
|
-
name: "ECDH",
|
|
1581
|
-
namedCurve
|
|
1582
|
-
}, extractable, isPublic ? [] : ["deriveBits"]);
|
|
1583
|
-
}
|
|
1584
|
-
}
|
|
1585
|
-
if (!cryptoKey) {
|
|
1586
|
-
throw new TypeError("given KeyObject instance cannot be used for this algorithm");
|
|
1587
|
-
}
|
|
1588
|
-
if (!cached) {
|
|
1589
|
-
cache.set(keyObject, { [alg]: cryptoKey });
|
|
1590
|
-
} else {
|
|
1591
|
-
cached[alg] = cryptoKey;
|
|
1592
|
-
}
|
|
1593
|
-
return cryptoKey;
|
|
1594
|
-
};
|
|
1595
|
-
var normalize_key_default = async (key, alg) => {
|
|
1596
|
-
if (key instanceof Uint8Array) {
|
|
1597
|
-
return key;
|
|
1598
|
-
}
|
|
1599
|
-
if (isCryptoKey(key)) {
|
|
1600
|
-
return key;
|
|
1601
|
-
}
|
|
1602
|
-
if (isKeyObject(key)) {
|
|
1603
|
-
if (key.type === "secret") {
|
|
1604
|
-
return key.export();
|
|
1605
|
-
}
|
|
1606
|
-
if ("toCryptoKey" in key && typeof key.toCryptoKey === "function") {
|
|
1607
|
-
try {
|
|
1608
|
-
return handleKeyObject(key, alg);
|
|
1609
|
-
} catch (err) {
|
|
1610
|
-
if (err instanceof TypeError) {
|
|
1611
|
-
throw err;
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1614
|
-
}
|
|
1615
|
-
let jwk = key.export({ format: "jwk" });
|
|
1616
|
-
return handleJWK(key, jwk, alg);
|
|
1617
|
-
}
|
|
1618
|
-
if (isJWK(key)) {
|
|
1619
|
-
if (key.k) {
|
|
1620
|
-
return decode(key.k);
|
|
1621
|
-
}
|
|
1622
|
-
return handleJWK(key, key, alg, true);
|
|
1623
|
-
}
|
|
1624
|
-
throw new Error("unreachable");
|
|
1625
|
-
};
|
|
1626
|
-
|
|
1627
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/check_key_type.js
|
|
1628
|
-
var tag = (key) => key?.[Symbol.toStringTag];
|
|
1629
|
-
var jwkMatchesOp = (alg, key, usage) => {
|
|
1630
|
-
if (key.use !== void 0) {
|
|
1631
|
-
let expected;
|
|
1632
|
-
switch (usage) {
|
|
1633
|
-
case "sign":
|
|
1634
|
-
case "verify":
|
|
1635
|
-
expected = "sig";
|
|
1636
|
-
break;
|
|
1637
|
-
case "encrypt":
|
|
1638
|
-
case "decrypt":
|
|
1639
|
-
expected = "enc";
|
|
1640
|
-
break;
|
|
1641
|
-
}
|
|
1642
|
-
if (key.use !== expected) {
|
|
1643
|
-
throw new TypeError(`Invalid key for this operation, its "use" must be "${expected}" when present`);
|
|
1644
|
-
}
|
|
1645
|
-
}
|
|
1646
|
-
if (key.alg !== void 0 && key.alg !== alg) {
|
|
1647
|
-
throw new TypeError(`Invalid key for this operation, its "alg" must be "${alg}" when present`);
|
|
1648
|
-
}
|
|
1649
|
-
if (Array.isArray(key.key_ops)) {
|
|
1650
|
-
let expectedKeyOp;
|
|
1651
|
-
switch (true) {
|
|
1652
|
-
case (usage === "sign" || usage === "verify"):
|
|
1653
|
-
case alg === "dir":
|
|
1654
|
-
case alg.includes("CBC-HS"):
|
|
1655
|
-
expectedKeyOp = usage;
|
|
1656
|
-
break;
|
|
1657
|
-
case alg.startsWith("PBES2"):
|
|
1658
|
-
expectedKeyOp = "deriveBits";
|
|
1659
|
-
break;
|
|
1660
|
-
case /^A\d{3}(?:GCM)?(?:KW)?$/.test(alg):
|
|
1661
|
-
if (!alg.includes("GCM") && alg.endsWith("KW")) {
|
|
1662
|
-
expectedKeyOp = usage === "encrypt" ? "wrapKey" : "unwrapKey";
|
|
1663
|
-
} else {
|
|
1664
|
-
expectedKeyOp = usage;
|
|
1665
|
-
}
|
|
1666
|
-
break;
|
|
1667
|
-
case (usage === "encrypt" && alg.startsWith("RSA")):
|
|
1668
|
-
expectedKeyOp = "wrapKey";
|
|
1669
|
-
break;
|
|
1670
|
-
case usage === "decrypt":
|
|
1671
|
-
expectedKeyOp = alg.startsWith("RSA") ? "unwrapKey" : "deriveBits";
|
|
1672
|
-
break;
|
|
1673
|
-
}
|
|
1674
|
-
if (expectedKeyOp && key.key_ops?.includes?.(expectedKeyOp) === false) {
|
|
1675
|
-
throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${expectedKeyOp}" when present`);
|
|
1676
|
-
}
|
|
1677
|
-
}
|
|
1678
|
-
return true;
|
|
1679
|
-
};
|
|
1680
|
-
var symmetricTypeCheck = (alg, key, usage) => {
|
|
1681
|
-
if (key instanceof Uint8Array)
|
|
1682
|
-
return;
|
|
1683
|
-
if (isJWK(key)) {
|
|
1684
|
-
if (isSecretJWK(key) && jwkMatchesOp(alg, key, usage))
|
|
1685
|
-
return;
|
|
1686
|
-
throw new TypeError(`JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present`);
|
|
1687
|
-
}
|
|
1688
|
-
if (!is_key_like_default(key)) {
|
|
1689
|
-
throw new TypeError(withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key", "Uint8Array"));
|
|
1690
|
-
}
|
|
1691
|
-
if (key.type !== "secret") {
|
|
1692
|
-
throw new TypeError(`${tag(key)} instances for symmetric algorithms must be of type "secret"`);
|
|
1693
|
-
}
|
|
1694
|
-
};
|
|
1695
|
-
var asymmetricTypeCheck = (alg, key, usage) => {
|
|
1696
|
-
if (isJWK(key)) {
|
|
1697
|
-
switch (usage) {
|
|
1698
|
-
case "decrypt":
|
|
1699
|
-
case "sign":
|
|
1700
|
-
if (isPrivateJWK(key) && jwkMatchesOp(alg, key, usage))
|
|
1701
|
-
return;
|
|
1702
|
-
throw new TypeError(`JSON Web Key for this operation be a private JWK`);
|
|
1703
|
-
case "encrypt":
|
|
1704
|
-
case "verify":
|
|
1705
|
-
if (isPublicJWK(key) && jwkMatchesOp(alg, key, usage))
|
|
1706
|
-
return;
|
|
1707
|
-
throw new TypeError(`JSON Web Key for this operation be a public JWK`);
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
if (!is_key_like_default(key)) {
|
|
1711
|
-
throw new TypeError(withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key"));
|
|
1712
|
-
}
|
|
1713
|
-
if (key.type === "secret") {
|
|
1714
|
-
throw new TypeError(`${tag(key)} instances for asymmetric algorithms must not be of type "secret"`);
|
|
1715
|
-
}
|
|
1716
|
-
if (key.type === "public") {
|
|
1717
|
-
switch (usage) {
|
|
1718
|
-
case "sign":
|
|
1719
|
-
throw new TypeError(`${tag(key)} instances for asymmetric algorithm signing must be of type "private"`);
|
|
1720
|
-
case "decrypt":
|
|
1721
|
-
throw new TypeError(`${tag(key)} instances for asymmetric algorithm decryption must be of type "private"`);
|
|
1722
|
-
default:
|
|
1723
|
-
break;
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
if (key.type === "private") {
|
|
1727
|
-
switch (usage) {
|
|
1728
|
-
case "verify":
|
|
1729
|
-
throw new TypeError(`${tag(key)} instances for asymmetric algorithm verifying must be of type "public"`);
|
|
1730
|
-
case "encrypt":
|
|
1731
|
-
throw new TypeError(`${tag(key)} instances for asymmetric algorithm encryption must be of type "public"`);
|
|
1732
|
-
default:
|
|
1733
|
-
break;
|
|
1734
|
-
}
|
|
1735
|
-
}
|
|
1736
|
-
};
|
|
1737
|
-
var check_key_type_default = (alg, key, usage) => {
|
|
1738
|
-
const symmetric = alg.startsWith("HS") || alg === "dir" || alg.startsWith("PBES2") || /^A(?:128|192|256)(?:GCM)?(?:KW)?$/.test(alg) || /^A(?:128|192|256)CBC-HS(?:256|384|512)$/.test(alg);
|
|
1739
|
-
if (symmetric) {
|
|
1740
|
-
symmetricTypeCheck(alg, key, usage);
|
|
1741
|
-
} else {
|
|
1742
|
-
asymmetricTypeCheck(alg, key, usage);
|
|
1743
|
-
}
|
|
1744
|
-
};
|
|
1745
|
-
|
|
1746
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/subtle_dsa.js
|
|
1747
|
-
var subtle_dsa_default = (alg, algorithm) => {
|
|
1748
|
-
const hash = `SHA-${alg.slice(-3)}`;
|
|
1749
|
-
switch (alg) {
|
|
1750
|
-
case "HS256":
|
|
1751
|
-
case "HS384":
|
|
1752
|
-
case "HS512":
|
|
1753
|
-
return { hash, name: "HMAC" };
|
|
1754
|
-
case "PS256":
|
|
1755
|
-
case "PS384":
|
|
1756
|
-
case "PS512":
|
|
1757
|
-
return { hash, name: "RSA-PSS", saltLength: parseInt(alg.slice(-3), 10) >> 3 };
|
|
1758
|
-
case "RS256":
|
|
1759
|
-
case "RS384":
|
|
1760
|
-
case "RS512":
|
|
1761
|
-
return { hash, name: "RSASSA-PKCS1-v1_5" };
|
|
1762
|
-
case "ES256":
|
|
1763
|
-
case "ES384":
|
|
1764
|
-
case "ES512":
|
|
1765
|
-
return { hash, name: "ECDSA", namedCurve: algorithm.namedCurve };
|
|
1766
|
-
case "Ed25519":
|
|
1767
|
-
case "EdDSA":
|
|
1768
|
-
return { name: "Ed25519" };
|
|
1769
|
-
default:
|
|
1770
|
-
throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
|
|
1771
|
-
}
|
|
1772
|
-
};
|
|
1773
|
-
|
|
1774
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/get_sign_verify_key.js
|
|
1775
|
-
var get_sign_verify_key_default = async (alg, key, usage) => {
|
|
1776
|
-
if (key instanceof Uint8Array) {
|
|
1777
|
-
if (!alg.startsWith("HS")) {
|
|
1778
|
-
throw new TypeError(invalid_key_input_default(key, "CryptoKey", "KeyObject", "JSON Web Key"));
|
|
1779
|
-
}
|
|
1780
|
-
return crypto.subtle.importKey("raw", key, { hash: `SHA-${alg.slice(-3)}`, name: "HMAC" }, false, [usage]);
|
|
1781
|
-
}
|
|
1782
|
-
checkSigCryptoKey(key, alg, usage);
|
|
1783
|
-
return key;
|
|
1784
|
-
};
|
|
1785
|
-
|
|
1786
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/verify.js
|
|
1787
|
-
var verify_default = async (alg, key, signature, data) => {
|
|
1788
|
-
const cryptoKey = await get_sign_verify_key_default(alg, key, "verify");
|
|
1789
|
-
check_key_length_default(alg, cryptoKey);
|
|
1790
|
-
const algorithm = subtle_dsa_default(alg, cryptoKey.algorithm);
|
|
1791
|
-
try {
|
|
1792
|
-
return await crypto.subtle.verify(algorithm, cryptoKey, signature, data);
|
|
1793
|
-
} catch {
|
|
1794
|
-
return false;
|
|
1795
|
-
}
|
|
1796
|
-
};
|
|
1797
|
-
|
|
1798
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/jws/flattened/verify.js
|
|
1799
|
-
async function flattenedVerify(jws, key, options) {
|
|
1800
|
-
if (!is_object_default(jws)) {
|
|
1801
|
-
throw new JWSInvalid("Flattened JWS must be an object");
|
|
1802
|
-
}
|
|
1803
|
-
if (jws.protected === void 0 && jws.header === void 0) {
|
|
1804
|
-
throw new JWSInvalid('Flattened JWS must have either of the "protected" or "header" members');
|
|
1805
|
-
}
|
|
1806
|
-
if (jws.protected !== void 0 && typeof jws.protected !== "string") {
|
|
1807
|
-
throw new JWSInvalid("JWS Protected Header incorrect type");
|
|
1808
|
-
}
|
|
1809
|
-
if (jws.payload === void 0) {
|
|
1810
|
-
throw new JWSInvalid("JWS Payload missing");
|
|
1811
|
-
}
|
|
1812
|
-
if (typeof jws.signature !== "string") {
|
|
1813
|
-
throw new JWSInvalid("JWS Signature missing or incorrect type");
|
|
1814
|
-
}
|
|
1815
|
-
if (jws.header !== void 0 && !is_object_default(jws.header)) {
|
|
1816
|
-
throw new JWSInvalid("JWS Unprotected Header incorrect type");
|
|
1817
|
-
}
|
|
1818
|
-
let parsedProt = {};
|
|
1819
|
-
if (jws.protected) {
|
|
1820
|
-
try {
|
|
1821
|
-
const protectedHeader = decode(jws.protected);
|
|
1822
|
-
parsedProt = JSON.parse(decoder.decode(protectedHeader));
|
|
1823
|
-
} catch {
|
|
1824
|
-
throw new JWSInvalid("JWS Protected Header is invalid");
|
|
1825
|
-
}
|
|
1826
|
-
}
|
|
1827
|
-
if (!is_disjoint_default(parsedProt, jws.header)) {
|
|
1828
|
-
throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");
|
|
1829
|
-
}
|
|
1830
|
-
const joseHeader = {
|
|
1831
|
-
...parsedProt,
|
|
1832
|
-
...jws.header
|
|
1833
|
-
};
|
|
1834
|
-
const extensions = validate_crit_default(JWSInvalid, /* @__PURE__ */ new Map([["b64", true]]), options?.crit, parsedProt, joseHeader);
|
|
1835
|
-
let b64 = true;
|
|
1836
|
-
if (extensions.has("b64")) {
|
|
1837
|
-
b64 = parsedProt.b64;
|
|
1838
|
-
if (typeof b64 !== "boolean") {
|
|
1839
|
-
throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
|
|
1840
|
-
}
|
|
1841
|
-
}
|
|
1842
|
-
const { alg } = joseHeader;
|
|
1843
|
-
if (typeof alg !== "string" || !alg) {
|
|
1844
|
-
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
|
|
1845
|
-
}
|
|
1846
|
-
const algorithms = options && validate_algorithms_default("algorithms", options.algorithms);
|
|
1847
|
-
if (algorithms && !algorithms.has(alg)) {
|
|
1848
|
-
throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter value not allowed');
|
|
1849
|
-
}
|
|
1850
|
-
if (b64) {
|
|
1851
|
-
if (typeof jws.payload !== "string") {
|
|
1852
|
-
throw new JWSInvalid("JWS Payload must be a string");
|
|
1853
|
-
}
|
|
1854
|
-
} else if (typeof jws.payload !== "string" && !(jws.payload instanceof Uint8Array)) {
|
|
1855
|
-
throw new JWSInvalid("JWS Payload must be a string or an Uint8Array instance");
|
|
1856
|
-
}
|
|
1857
|
-
let resolvedKey = false;
|
|
1858
|
-
if (typeof key === "function") {
|
|
1859
|
-
key = await key(parsedProt, jws);
|
|
1860
|
-
resolvedKey = true;
|
|
1861
|
-
}
|
|
1862
|
-
check_key_type_default(alg, key, "verify");
|
|
1863
|
-
const data = concat(encoder.encode(jws.protected ?? ""), encoder.encode("."), typeof jws.payload === "string" ? encoder.encode(jws.payload) : jws.payload);
|
|
1864
|
-
let signature;
|
|
1865
|
-
try {
|
|
1866
|
-
signature = decode(jws.signature);
|
|
1867
|
-
} catch {
|
|
1868
|
-
throw new JWSInvalid("Failed to base64url decode the signature");
|
|
1869
|
-
}
|
|
1870
|
-
const k = await normalize_key_default(key, alg);
|
|
1871
|
-
const verified = await verify_default(alg, k, signature, data);
|
|
1872
|
-
if (!verified) {
|
|
1873
|
-
throw new JWSSignatureVerificationFailed();
|
|
1874
|
-
}
|
|
1875
|
-
let payload;
|
|
1876
|
-
if (b64) {
|
|
1877
|
-
try {
|
|
1878
|
-
payload = decode(jws.payload);
|
|
1879
|
-
} catch {
|
|
1880
|
-
throw new JWSInvalid("Failed to base64url decode the payload");
|
|
1881
|
-
}
|
|
1882
|
-
} else if (typeof jws.payload === "string") {
|
|
1883
|
-
payload = encoder.encode(jws.payload);
|
|
1884
|
-
} else {
|
|
1885
|
-
payload = jws.payload;
|
|
1886
|
-
}
|
|
1887
|
-
const result = { payload };
|
|
1888
|
-
if (jws.protected !== void 0) {
|
|
1889
|
-
result.protectedHeader = parsedProt;
|
|
1890
|
-
}
|
|
1891
|
-
if (jws.header !== void 0) {
|
|
1892
|
-
result.unprotectedHeader = jws.header;
|
|
1893
|
-
}
|
|
1894
|
-
if (resolvedKey) {
|
|
1895
|
-
return { ...result, key: k };
|
|
1896
|
-
}
|
|
1897
|
-
return result;
|
|
1898
|
-
}
|
|
1899
|
-
|
|
1900
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/jws/compact/verify.js
|
|
1901
|
-
async function compactVerify(jws, key, options) {
|
|
1902
|
-
if (jws instanceof Uint8Array) {
|
|
1903
|
-
jws = decoder.decode(jws);
|
|
1904
|
-
}
|
|
1905
|
-
if (typeof jws !== "string") {
|
|
1906
|
-
throw new JWSInvalid("Compact JWS must be a string or Uint8Array");
|
|
1907
|
-
}
|
|
1908
|
-
const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split(".");
|
|
1909
|
-
if (length !== 3) {
|
|
1910
|
-
throw new JWSInvalid("Invalid Compact JWS");
|
|
1911
|
-
}
|
|
1912
|
-
const verified = await flattenedVerify({ payload, protected: protectedHeader, signature }, key, options);
|
|
1913
|
-
const result = { payload: verified.payload, protectedHeader: verified.protectedHeader };
|
|
1914
|
-
if (typeof key === "function") {
|
|
1915
|
-
return { ...result, key: verified.key };
|
|
1916
|
-
}
|
|
1917
|
-
return result;
|
|
1918
|
-
}
|
|
1919
|
-
|
|
1920
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/epoch.js
|
|
1921
|
-
var epoch_default = (date) => Math.floor(date.getTime() / 1e3);
|
|
1922
|
-
|
|
1923
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/secs.js
|
|
1924
|
-
var minute = 60;
|
|
1925
|
-
var hour = minute * 60;
|
|
1926
|
-
var day = hour * 24;
|
|
1927
|
-
var week = day * 7;
|
|
1928
|
-
var year = day * 365.25;
|
|
1929
|
-
var REGEX = /^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;
|
|
1930
|
-
var secs_default = (str) => {
|
|
1931
|
-
const matched = REGEX.exec(str);
|
|
1932
|
-
if (!matched || matched[4] && matched[1]) {
|
|
1933
|
-
throw new TypeError("Invalid time period format");
|
|
1934
|
-
}
|
|
1935
|
-
const value = parseFloat(matched[2]);
|
|
1936
|
-
const unit = matched[3].toLowerCase();
|
|
1937
|
-
let numericDate;
|
|
1938
|
-
switch (unit) {
|
|
1939
|
-
case "sec":
|
|
1940
|
-
case "secs":
|
|
1941
|
-
case "second":
|
|
1942
|
-
case "seconds":
|
|
1943
|
-
case "s":
|
|
1944
|
-
numericDate = Math.round(value);
|
|
1945
|
-
break;
|
|
1946
|
-
case "minute":
|
|
1947
|
-
case "minutes":
|
|
1948
|
-
case "min":
|
|
1949
|
-
case "mins":
|
|
1950
|
-
case "m":
|
|
1951
|
-
numericDate = Math.round(value * minute);
|
|
1952
|
-
break;
|
|
1953
|
-
case "hour":
|
|
1954
|
-
case "hours":
|
|
1955
|
-
case "hr":
|
|
1956
|
-
case "hrs":
|
|
1957
|
-
case "h":
|
|
1958
|
-
numericDate = Math.round(value * hour);
|
|
1959
|
-
break;
|
|
1960
|
-
case "day":
|
|
1961
|
-
case "days":
|
|
1962
|
-
case "d":
|
|
1963
|
-
numericDate = Math.round(value * day);
|
|
1964
|
-
break;
|
|
1965
|
-
case "week":
|
|
1966
|
-
case "weeks":
|
|
1967
|
-
case "w":
|
|
1968
|
-
numericDate = Math.round(value * week);
|
|
1969
|
-
break;
|
|
1970
|
-
default:
|
|
1971
|
-
numericDate = Math.round(value * year);
|
|
1972
|
-
break;
|
|
1973
|
-
}
|
|
1974
|
-
if (matched[1] === "-" || matched[4] === "ago") {
|
|
1975
|
-
return -numericDate;
|
|
1976
|
-
}
|
|
1977
|
-
return numericDate;
|
|
1978
|
-
};
|
|
1979
|
-
|
|
1980
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/lib/jwt_claims_set.js
|
|
1981
|
-
var normalizeTyp = (value) => {
|
|
1982
|
-
if (value.includes("/")) {
|
|
1983
|
-
return value.toLowerCase();
|
|
1984
|
-
}
|
|
1985
|
-
return `application/${value.toLowerCase()}`;
|
|
1986
|
-
};
|
|
1987
|
-
var checkAudiencePresence = (audPayload, audOption) => {
|
|
1988
|
-
if (typeof audPayload === "string") {
|
|
1989
|
-
return audOption.includes(audPayload);
|
|
1990
|
-
}
|
|
1991
|
-
if (Array.isArray(audPayload)) {
|
|
1992
|
-
return audOption.some(Set.prototype.has.bind(new Set(audPayload)));
|
|
1993
|
-
}
|
|
1994
|
-
return false;
|
|
1995
|
-
};
|
|
1996
|
-
function validateClaimsSet(protectedHeader, encodedPayload, options = {}) {
|
|
1997
|
-
let payload;
|
|
1998
|
-
try {
|
|
1999
|
-
payload = JSON.parse(decoder.decode(encodedPayload));
|
|
2000
|
-
} catch {
|
|
2001
|
-
}
|
|
2002
|
-
if (!is_object_default(payload)) {
|
|
2003
|
-
throw new JWTInvalid("JWT Claims Set must be a top-level JSON object");
|
|
2004
|
-
}
|
|
2005
|
-
const { typ } = options;
|
|
2006
|
-
if (typ && (typeof protectedHeader.typ !== "string" || normalizeTyp(protectedHeader.typ) !== normalizeTyp(typ))) {
|
|
2007
|
-
throw new JWTClaimValidationFailed('unexpected "typ" JWT header value', payload, "typ", "check_failed");
|
|
2008
|
-
}
|
|
2009
|
-
const { requiredClaims = [], issuer, subject, audience, maxTokenAge } = options;
|
|
2010
|
-
const presenceCheck = [...requiredClaims];
|
|
2011
|
-
if (maxTokenAge !== void 0)
|
|
2012
|
-
presenceCheck.push("iat");
|
|
2013
|
-
if (audience !== void 0)
|
|
2014
|
-
presenceCheck.push("aud");
|
|
2015
|
-
if (subject !== void 0)
|
|
2016
|
-
presenceCheck.push("sub");
|
|
2017
|
-
if (issuer !== void 0)
|
|
2018
|
-
presenceCheck.push("iss");
|
|
2019
|
-
for (const claim of new Set(presenceCheck.reverse())) {
|
|
2020
|
-
if (!(claim in payload)) {
|
|
2021
|
-
throw new JWTClaimValidationFailed(`missing required "${claim}" claim`, payload, claim, "missing");
|
|
2022
|
-
}
|
|
2023
|
-
}
|
|
2024
|
-
if (issuer && !(Array.isArray(issuer) ? issuer : [issuer]).includes(payload.iss)) {
|
|
2025
|
-
throw new JWTClaimValidationFailed('unexpected "iss" claim value', payload, "iss", "check_failed");
|
|
2026
|
-
}
|
|
2027
|
-
if (subject && payload.sub !== subject) {
|
|
2028
|
-
throw new JWTClaimValidationFailed('unexpected "sub" claim value', payload, "sub", "check_failed");
|
|
2029
|
-
}
|
|
2030
|
-
if (audience && !checkAudiencePresence(payload.aud, typeof audience === "string" ? [audience] : audience)) {
|
|
2031
|
-
throw new JWTClaimValidationFailed('unexpected "aud" claim value', payload, "aud", "check_failed");
|
|
2032
|
-
}
|
|
2033
|
-
let tolerance;
|
|
2034
|
-
switch (typeof options.clockTolerance) {
|
|
2035
|
-
case "string":
|
|
2036
|
-
tolerance = secs_default(options.clockTolerance);
|
|
2037
|
-
break;
|
|
2038
|
-
case "number":
|
|
2039
|
-
tolerance = options.clockTolerance;
|
|
2040
|
-
break;
|
|
2041
|
-
case "undefined":
|
|
2042
|
-
tolerance = 0;
|
|
2043
|
-
break;
|
|
2044
|
-
default:
|
|
2045
|
-
throw new TypeError("Invalid clockTolerance option type");
|
|
2046
|
-
}
|
|
2047
|
-
const { currentDate } = options;
|
|
2048
|
-
const now = epoch_default(currentDate || /* @__PURE__ */ new Date());
|
|
2049
|
-
if ((payload.iat !== void 0 || maxTokenAge) && typeof payload.iat !== "number") {
|
|
2050
|
-
throw new JWTClaimValidationFailed('"iat" claim must be a number', payload, "iat", "invalid");
|
|
2051
|
-
}
|
|
2052
|
-
if (payload.nbf !== void 0) {
|
|
2053
|
-
if (typeof payload.nbf !== "number") {
|
|
2054
|
-
throw new JWTClaimValidationFailed('"nbf" claim must be a number', payload, "nbf", "invalid");
|
|
2055
|
-
}
|
|
2056
|
-
if (payload.nbf > now + tolerance) {
|
|
2057
|
-
throw new JWTClaimValidationFailed('"nbf" claim timestamp check failed', payload, "nbf", "check_failed");
|
|
2058
|
-
}
|
|
2059
|
-
}
|
|
2060
|
-
if (payload.exp !== void 0) {
|
|
2061
|
-
if (typeof payload.exp !== "number") {
|
|
2062
|
-
throw new JWTClaimValidationFailed('"exp" claim must be a number', payload, "exp", "invalid");
|
|
2063
|
-
}
|
|
2064
|
-
if (payload.exp <= now - tolerance) {
|
|
2065
|
-
throw new JWTExpired('"exp" claim timestamp check failed', payload, "exp", "check_failed");
|
|
2066
|
-
}
|
|
2067
|
-
}
|
|
2068
|
-
if (maxTokenAge) {
|
|
2069
|
-
const age = now - payload.iat;
|
|
2070
|
-
const max = typeof maxTokenAge === "number" ? maxTokenAge : secs_default(maxTokenAge);
|
|
2071
|
-
if (age - tolerance > max) {
|
|
2072
|
-
throw new JWTExpired('"iat" claim timestamp check failed (too far in the past)', payload, "iat", "check_failed");
|
|
2073
|
-
}
|
|
2074
|
-
if (age < 0 - tolerance) {
|
|
2075
|
-
throw new JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', payload, "iat", "check_failed");
|
|
2076
|
-
}
|
|
2077
|
-
}
|
|
2078
|
-
return payload;
|
|
2079
|
-
}
|
|
2080
|
-
|
|
2081
|
-
// node_modules/.pnpm/jose@6.0.11/node_modules/jose/dist/webapi/jwt/verify.js
|
|
2082
|
-
async function jwtVerify(jwt, key, options) {
|
|
2083
|
-
const verified = await compactVerify(jwt, key, options);
|
|
2084
|
-
if (verified.protectedHeader.crit?.includes("b64") && verified.protectedHeader.b64 === false) {
|
|
2085
|
-
throw new JWTInvalid("JWTs MUST NOT use unencoded payload");
|
|
2086
|
-
}
|
|
2087
|
-
const payload = validateClaimsSet(verified.protectedHeader, verified.payload, options);
|
|
2088
|
-
const result = { payload, protectedHeader: verified.protectedHeader };
|
|
2089
|
-
if (typeof key === "function") {
|
|
2090
|
-
return { ...result, key: verified.key };
|
|
2091
|
-
}
|
|
2092
|
-
return result;
|
|
2093
|
-
}
|
|
2094
|
-
|
|
2095
499
|
// src/auth.ts
|
|
500
|
+
import ky2 from "ky";
|
|
501
|
+
import * as jose from "jose";
|
|
2096
502
|
var GRANT_TYPE = "authorization_code";
|
|
2097
503
|
var TOKEN_ENDPOINT = "https://login.bigcommerce.com/oauth2/token";
|
|
2098
504
|
var ISSUER = "bc";
|
|
2099
505
|
var BigCommerceAuth = class {
|
|
2100
506
|
/**
|
|
2101
|
-
* Creates a new BigCommerceAuth instance
|
|
507
|
+
* Creates a new BigCommerceAuth instance for handling OAuth authentication
|
|
2102
508
|
* @param config - Configuration options for BigCommerce authentication
|
|
509
|
+
* @param config.clientId - The OAuth client ID from BigCommerce
|
|
510
|
+
* @param config.secret - The OAuth client secret from BigCommerce
|
|
511
|
+
* @param config.redirectUri - The redirect URI registered with BigCommerce
|
|
512
|
+
* @param config.scopes - Optional array of scopes to validate during auth callback
|
|
513
|
+
* @param config.logger - Optional logger instance for debugging and error tracking
|
|
2103
514
|
* @throws {Error} If the redirect URI is invalid
|
|
2104
515
|
*/
|
|
2105
516
|
constructor(config) {
|
|
2106
517
|
this.config = config;
|
|
2107
518
|
try {
|
|
2108
|
-
URL
|
|
519
|
+
new URL(this.config.redirectUri);
|
|
2109
520
|
} catch (error) {
|
|
2110
521
|
throw new Error("Invalid redirect URI", { cause: error });
|
|
2111
522
|
}
|
|
2112
523
|
}
|
|
2113
524
|
/**
|
|
2114
525
|
* Requests an access token from BigCommerce
|
|
2115
|
-
* @param data - Either a query string or AuthQuery object containing auth callback data
|
|
526
|
+
* @param data - Either a query string, URLSearchParams, or AuthQuery object containing auth callback data
|
|
2116
527
|
* @returns Promise resolving to the token response
|
|
2117
528
|
*/
|
|
2118
529
|
async requestToken(data) {
|
|
2119
|
-
const query = typeof data === "string" ? this.parseQueryString(data) : data;
|
|
530
|
+
const query = typeof data === "string" || data instanceof URLSearchParams ? this.parseQueryString(data) : data;
|
|
2120
531
|
const tokenRequest = {
|
|
2121
532
|
client_id: this.config.clientId,
|
|
2122
533
|
client_secret: this.config.secret,
|
|
@@ -2124,27 +535,44 @@ var BigCommerceAuth = class {
|
|
|
2124
535
|
grant_type: GRANT_TYPE,
|
|
2125
536
|
redirect_uri: this.config.redirectUri
|
|
2126
537
|
};
|
|
2127
|
-
|
|
538
|
+
this.config.logger?.debug({
|
|
539
|
+
clientId: this.config.clientId,
|
|
540
|
+
context: query.context,
|
|
541
|
+
scopes: query.scope
|
|
542
|
+
}, "Requesting OAuth token");
|
|
543
|
+
const res = await ky2(TOKEN_ENDPOINT, {
|
|
2128
544
|
method: "POST",
|
|
2129
545
|
json: tokenRequest
|
|
2130
|
-
})
|
|
546
|
+
});
|
|
547
|
+
return res.json();
|
|
2131
548
|
}
|
|
2132
549
|
/**
|
|
2133
550
|
* Verifies a JWT payload from BigCommerce
|
|
2134
551
|
* @param jwtPayload - The JWT string to verify
|
|
552
|
+
* @param storeHash - The store hash for the BigCommerce store
|
|
2135
553
|
* @returns Promise resolving to the verified JWT claims
|
|
2136
554
|
* @throws {Error} If the JWT is invalid
|
|
2137
555
|
*/
|
|
2138
|
-
async verify(jwtPayload) {
|
|
556
|
+
async verify(jwtPayload, storeHash) {
|
|
2139
557
|
try {
|
|
2140
558
|
const secret = new TextEncoder().encode(this.config.secret);
|
|
2141
|
-
const { payload } = await jwtVerify(jwtPayload, secret, {
|
|
559
|
+
const { payload } = await jose.jwtVerify(jwtPayload, secret, {
|
|
2142
560
|
audience: this.config.clientId,
|
|
2143
561
|
issuer: ISSUER,
|
|
2144
|
-
subject: `stores/${
|
|
562
|
+
subject: `stores/${storeHash}`
|
|
2145
563
|
});
|
|
564
|
+
this.config.logger?.debug({
|
|
565
|
+
userId: payload.user?.id,
|
|
566
|
+
storeHash: payload.sub.split("/")[1]
|
|
567
|
+
}, "JWT verified successfully");
|
|
2146
568
|
return payload;
|
|
2147
569
|
} catch (error) {
|
|
570
|
+
this.config.logger?.error({
|
|
571
|
+
error: error instanceof Error ? {
|
|
572
|
+
name: error.name,
|
|
573
|
+
message: error.message
|
|
574
|
+
} : error
|
|
575
|
+
});
|
|
2148
576
|
throw new Error("Invalid JWT payload", { cause: error });
|
|
2149
577
|
}
|
|
2150
578
|
}
|
|
@@ -2155,7 +583,7 @@ var BigCommerceAuth = class {
|
|
|
2155
583
|
* @throws {Error} If required parameters are missing or scopes are invalid
|
|
2156
584
|
*/
|
|
2157
585
|
parseQueryString(queryString) {
|
|
2158
|
-
const params = new URLSearchParams(queryString);
|
|
586
|
+
const params = typeof queryString === "string" ? new URLSearchParams(queryString) : queryString;
|
|
2159
587
|
const code = params.get("code");
|
|
2160
588
|
const scope = params.get("scope");
|
|
2161
589
|
const context = params.get("context");
|
|
@@ -2187,22 +615,20 @@ var BigCommerceAuth = class {
|
|
|
2187
615
|
* @throws {Error} If the scopes don't match the expected scopes
|
|
2188
616
|
*/
|
|
2189
617
|
validateScopes(scopes) {
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
618
|
+
if (!this.config.scopes) {
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
const grantedScopes = scopes.split(" ");
|
|
622
|
+
const requiredScopes = this.config.scopes;
|
|
623
|
+
const missingScopes = requiredScopes.filter((scope) => !grantedScopes.includes(scope));
|
|
624
|
+
if (missingScopes.length) {
|
|
625
|
+
throw new Error(`Scope mismatch: ${scopes}; expected: ${this.config.scopes.join(" ")}`);
|
|
2196
626
|
}
|
|
2197
627
|
}
|
|
2198
628
|
};
|
|
2199
629
|
export {
|
|
2200
630
|
BigCommerceAuth,
|
|
2201
|
-
BigCommerceClient
|
|
631
|
+
BigCommerceClient,
|
|
632
|
+
Methods
|
|
2202
633
|
};
|
|
2203
|
-
/*! Bundled license information:
|
|
2204
|
-
|
|
2205
|
-
ky/distribution/index.js:
|
|
2206
|
-
(*! MIT License © Sindre Sorhus *)
|
|
2207
|
-
*/
|
|
2208
634
|
//# sourceMappingURL=index.js.map
|