@finueva/auth 0.18.0 → 0.18.1
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/dist/device.js +425 -403
- package/dist/index.js +35 -7
- package/dist/server.js +1827 -1827
- package/package.json +1 -1
package/dist/device.js
CHANGED
|
@@ -213,426 +213,99 @@ var AuthError = class extends Error {
|
|
|
213
213
|
}
|
|
214
214
|
};
|
|
215
215
|
//#endregion
|
|
216
|
-
//#region src/
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
//#region src/shared.ts
|
|
217
|
+
const DRIVE_CREDENTIAL_LIFETIME_SECONDS = 840;
|
|
218
|
+
const id = /^[A-Za-z0-9_-]{1,128}$/;
|
|
219
|
+
const email = /^[^\s@]+@[^\s@]+$/;
|
|
220
|
+
const MAX_SOCIAL_ID_TOKEN_BYTES = 16 * 1024;
|
|
221
|
+
function normalizeEmail(value) {
|
|
222
|
+
if (typeof value !== "string") throw new TypeError("email is invalid");
|
|
223
|
+
const normalized = value.trim().toLowerCase();
|
|
224
|
+
if (normalized.length === 0 || normalized.length > 320 || !email.test(normalized)) throw new TypeError("email is invalid");
|
|
225
|
+
return normalized;
|
|
220
226
|
}
|
|
221
|
-
function
|
|
222
|
-
if (
|
|
227
|
+
function normalizePassword(value, name = "password", minLength = 8) {
|
|
228
|
+
if (typeof value !== "string" || value.length < minLength || value.length > 128) throw new TypeError(`${name} is invalid`);
|
|
229
|
+
return value;
|
|
230
|
+
}
|
|
231
|
+
function normalizeSocialIdTokenInput(value) {
|
|
232
|
+
if (!isObject(value)) throw new TypeError("social ID token input is invalid");
|
|
233
|
+
const keys = Object.keys(value);
|
|
234
|
+
if (keys.length !== 3 && keys.length !== 4 || keys.some((key) => key !== "provider" && key !== "idToken" && key !== "nonce" && key !== "signUp") || value.provider !== "google" && value.provider !== "apple" || typeof value.signUp !== "boolean" || typeof value.idToken !== "string" || value.idToken.length < 1 || new TextEncoder().encode(value.idToken).byteLength > MAX_SOCIAL_ID_TOKEN_BYTES || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.idToken) || value.nonce !== void 0 && (typeof value.nonce !== "string" || value.nonce.length < 1 || value.nonce.length > 256 || !/^[\x20-\x7e]+$/.test(value.nonce))) throw new TypeError("social ID token input is invalid");
|
|
223
235
|
return {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
236
|
+
provider: value.provider,
|
|
237
|
+
idToken: value.idToken,
|
|
238
|
+
...value.nonce === void 0 ? {} : { nonce: value.nonce },
|
|
239
|
+
signUp: value.signUp
|
|
227
240
|
};
|
|
228
241
|
}
|
|
229
|
-
function
|
|
230
|
-
let generation = 0;
|
|
231
|
-
let cached;
|
|
232
|
-
let pending;
|
|
233
|
-
const copy = (value) => ({
|
|
234
|
-
...value,
|
|
235
|
-
expiresAt: new Date(value.expiresAt)
|
|
236
|
-
});
|
|
242
|
+
function socialIdTokenRequest(value) {
|
|
237
243
|
return {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
pending = void 0;
|
|
244
|
+
provider: value.provider,
|
|
245
|
+
idToken: {
|
|
246
|
+
token: value.idToken,
|
|
247
|
+
...value.nonce === void 0 ? {} : { nonce: value.nonce }
|
|
243
248
|
},
|
|
244
|
-
|
|
245
|
-
const applicationId = userApiApplication(input);
|
|
246
|
-
if (pending) {
|
|
247
|
-
if (pending.applicationId !== applicationId) throw new AuthError("state_conflict", 409);
|
|
248
|
-
return copy(await pending.request);
|
|
249
|
-
}
|
|
250
|
-
const startedAt = now();
|
|
251
|
-
if (!input.forceRefresh && cached?.applicationId === applicationId && cached.expiresAt - startedAt > 12e4) return {
|
|
252
|
-
tokenType: "Bearer",
|
|
253
|
-
token: cached.token,
|
|
254
|
-
expiresAt: new Date(cached.expiresAt)
|
|
255
|
-
};
|
|
256
|
-
cached = void 0;
|
|
257
|
-
const epoch = generation;
|
|
258
|
-
const request = (async () => {
|
|
259
|
-
const value = normalizeUserApiCredential(await issue(applicationId), startedAt);
|
|
260
|
-
if (epoch !== generation) throw new AuthError("state_conflict", 409);
|
|
261
|
-
if (now() < startedAt || value.expiresAt.getTime() <= now()) throw new AuthError("authentication_required", 401);
|
|
262
|
-
cached = {
|
|
263
|
-
applicationId,
|
|
264
|
-
token: value.token,
|
|
265
|
-
expiresAt: value.expiresAt.getTime()
|
|
266
|
-
};
|
|
267
|
-
return value;
|
|
268
|
-
})().finally(() => {
|
|
269
|
-
if (pending?.request === request) pending = void 0;
|
|
270
|
-
});
|
|
271
|
-
pending = {
|
|
272
|
-
applicationId,
|
|
273
|
-
request
|
|
274
|
-
};
|
|
275
|
-
return copy(await request);
|
|
276
|
-
}
|
|
249
|
+
requestSignUp: value.signUp
|
|
277
250
|
};
|
|
278
251
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
function jsonParseTransform(key, value) {
|
|
285
|
-
if (key === "__proto__" || key === "constructor" && value && typeof value === "object" && "prototype" in value) {
|
|
286
|
-
warnKeyDropped(key);
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
return value;
|
|
252
|
+
function normalizeName(value) {
|
|
253
|
+
if (typeof value !== "string") throw new TypeError("name is invalid");
|
|
254
|
+
const normalized = value.trim();
|
|
255
|
+
if (normalized.length === 0 || normalized.length > 256) throw new TypeError("name is invalid");
|
|
256
|
+
return normalized;
|
|
290
257
|
}
|
|
291
|
-
function
|
|
292
|
-
|
|
258
|
+
function normalizeProfileInput(value) {
|
|
259
|
+
if (!isObject(value)) throw new TypeError("profile input is invalid");
|
|
260
|
+
const keys = Object.keys(value);
|
|
261
|
+
if (keys.length === 0 || keys.length > 2 || keys.some((key) => key !== "name" && key !== "image") || value.name === void 0 && value.image === void 0) throw new TypeError("profile input is invalid");
|
|
262
|
+
const result = {};
|
|
263
|
+
if (value.name !== void 0) result.name = normalizeName(value.name);
|
|
264
|
+
if (value.image !== void 0) result.image = value.image === null ? null : normalizeProfileImage(value.image);
|
|
265
|
+
return result;
|
|
293
266
|
}
|
|
294
|
-
function
|
|
295
|
-
if (
|
|
296
|
-
|
|
297
|
-
const _value = value.trim();
|
|
298
|
-
if (_value.length <= 9) switch (_value.toLowerCase()) {
|
|
299
|
-
case "true": return true;
|
|
300
|
-
case "false": return false;
|
|
301
|
-
case "undefined": return;
|
|
302
|
-
case "null": return null;
|
|
303
|
-
case "nan": return NaN;
|
|
304
|
-
case "infinity": return Number.POSITIVE_INFINITY;
|
|
305
|
-
case "-infinity": return Number.NEGATIVE_INFINITY;
|
|
306
|
-
}
|
|
307
|
-
if (!JsonSigRx.test(value)) {
|
|
308
|
-
if (options.strict) throw new SyntaxError("[destr] Invalid JSON");
|
|
309
|
-
return value;
|
|
310
|
-
}
|
|
267
|
+
function normalizeOrigin(value, name) {
|
|
268
|
+
if (value.length === 0 || value.length > 2048 || /[^\x20-\x7e]/.test(value)) throw new TypeError(`${name} must be an ASCII HTTP origin`);
|
|
269
|
+
let url;
|
|
311
270
|
try {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
return JSON.parse(value);
|
|
317
|
-
} catch (error) {
|
|
318
|
-
if (options.strict) throw error;
|
|
319
|
-
return value;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
//#endregion
|
|
323
|
-
//#region ../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/shared/ofetch.CWycOUEr.mjs
|
|
324
|
-
var FetchError = class extends Error {
|
|
325
|
-
constructor(message, opts) {
|
|
326
|
-
super(message, opts);
|
|
327
|
-
this.name = "FetchError";
|
|
328
|
-
if (opts?.cause && !this.cause) this.cause = opts.cause;
|
|
271
|
+
url = new URL(value);
|
|
272
|
+
} catch {
|
|
273
|
+
throw new TypeError(`${name} must be an ASCII HTTP origin`);
|
|
329
274
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
const method = ctx.request?.method || ctx.options?.method || "GET";
|
|
334
|
-
const url = ctx.request?.url || String(ctx.request) || "/";
|
|
335
|
-
const fetchError = new FetchError(`${`[${method}] ${JSON.stringify(url)}`}: ${ctx.response ? `${ctx.response.status} ${ctx.response.statusText}` : "<no response>"}${errorMessage ? ` ${errorMessage}` : ""}`, ctx.error ? { cause: ctx.error } : void 0);
|
|
336
|
-
for (const key of [
|
|
337
|
-
"request",
|
|
338
|
-
"options",
|
|
339
|
-
"response"
|
|
340
|
-
]) Object.defineProperty(fetchError, key, { get() {
|
|
341
|
-
return ctx[key];
|
|
342
|
-
} });
|
|
343
|
-
for (const [key, refKey] of [
|
|
344
|
-
["data", "_data"],
|
|
345
|
-
["status", "status"],
|
|
346
|
-
["statusCode", "status"],
|
|
347
|
-
["statusText", "statusText"],
|
|
348
|
-
["statusMessage", "statusText"]
|
|
349
|
-
]) Object.defineProperty(fetchError, key, { get() {
|
|
350
|
-
return ctx.response && ctx.response[refKey];
|
|
351
|
-
} });
|
|
352
|
-
return fetchError;
|
|
353
|
-
}
|
|
354
|
-
const payloadMethods = new Set(Object.freeze([
|
|
355
|
-
"PATCH",
|
|
356
|
-
"POST",
|
|
357
|
-
"PUT",
|
|
358
|
-
"DELETE"
|
|
359
|
-
]));
|
|
360
|
-
function isPayloadMethod(method = "GET") {
|
|
361
|
-
return payloadMethods.has(method.toUpperCase());
|
|
362
|
-
}
|
|
363
|
-
function isJSONSerializable(value) {
|
|
364
|
-
if (value === void 0) return false;
|
|
365
|
-
const t = typeof value;
|
|
366
|
-
if (t === "string" || t === "number" || t === "boolean" || t === null) return true;
|
|
367
|
-
if (t !== "object") return false;
|
|
368
|
-
if (Array.isArray(value)) return true;
|
|
369
|
-
if (value.buffer) return false;
|
|
370
|
-
if (value instanceof FormData || value instanceof URLSearchParams) return false;
|
|
371
|
-
return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
|
|
275
|
+
const local = url.hostname === "localhost" || url.hostname.endsWith(".localhost") || url.hostname === "127.0.0.1";
|
|
276
|
+
if (url.protocol !== "https:" && !(local && url.protocol === "http:") || url.username || url.password || url.pathname !== "/" || url.search || url.hash || url.origin !== value) throw new TypeError(`${name} must be an ASCII HTTP origin`);
|
|
277
|
+
return url.origin;
|
|
372
278
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
"
|
|
376
|
-
|
|
377
|
-
"application/html"
|
|
378
|
-
]);
|
|
379
|
-
const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
|
|
380
|
-
function detectResponseType(_contentType = "") {
|
|
381
|
-
if (!_contentType) return "json";
|
|
382
|
-
const contentType = _contentType.split(";").shift() || "";
|
|
383
|
-
if (JSON_RE.test(contentType)) return "json";
|
|
384
|
-
if (contentType === "text/event-stream") return "stream";
|
|
385
|
-
if (textTypes.has(contentType) || contentType.startsWith("text/")) return "text";
|
|
386
|
-
return "blob";
|
|
279
|
+
function normalizeTimeout(value) {
|
|
280
|
+
const timeout = value ?? 1e4;
|
|
281
|
+
if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 6e4) throw new TypeError("timeoutMs must be an integer from 1 to 60000");
|
|
282
|
+
return timeout;
|
|
387
283
|
}
|
|
388
|
-
function
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
...input?.params,
|
|
395
|
-
...input?.query
|
|
396
|
-
};
|
|
284
|
+
function normalizeSession(value) {
|
|
285
|
+
if (value === null) return null;
|
|
286
|
+
if (!isObject(value) || !isObject(value.session) || !isObject(value.user)) throw authorityUnavailable();
|
|
287
|
+
const expiresAt = toDate(value.session.expiresAt);
|
|
288
|
+
const image = value.user.image;
|
|
289
|
+
if (!isId(value.session.id) || !expiresAt || !isId(value.user.id) || typeof value.user.name !== "string" || value.user.name.length > 256 || typeof value.user.email !== "string" || value.user.email.length > 320 || !email.test(value.user.email) || typeof value.user.emailVerified !== "boolean" || image !== null && image !== void 0 && (typeof image !== "string" || image.length > 2048)) throw authorityUnavailable();
|
|
397
290
|
return {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
291
|
+
id: value.session.id,
|
|
292
|
+
expiresAt,
|
|
293
|
+
user: {
|
|
294
|
+
id: value.user.id,
|
|
295
|
+
name: value.user.name,
|
|
296
|
+
email: value.user.email,
|
|
297
|
+
emailVerified: value.user.emailVerified,
|
|
298
|
+
image: image ?? null
|
|
299
|
+
}
|
|
403
300
|
};
|
|
404
301
|
}
|
|
405
|
-
function
|
|
406
|
-
if (!
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
if (hooks) if (Array.isArray(hooks)) for (const hook of hooks) await hook(context);
|
|
413
|
-
else await hooks(context);
|
|
414
|
-
}
|
|
415
|
-
const retryStatusCodes = new Set([
|
|
416
|
-
408,
|
|
417
|
-
409,
|
|
418
|
-
425,
|
|
419
|
-
429,
|
|
420
|
-
500,
|
|
421
|
-
502,
|
|
422
|
-
503,
|
|
423
|
-
504
|
|
424
|
-
]);
|
|
425
|
-
const nullBodyResponses = new Set([
|
|
426
|
-
101,
|
|
427
|
-
204,
|
|
428
|
-
205,
|
|
429
|
-
304
|
|
430
|
-
]);
|
|
431
|
-
function createFetch(globalOptions = {}) {
|
|
432
|
-
const { fetch = globalThis.fetch, Headers = globalThis.Headers, AbortController = globalThis.AbortController } = globalOptions;
|
|
433
|
-
async function onError(context) {
|
|
434
|
-
const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false;
|
|
435
|
-
if (context.options.retry !== false && !isAbort) {
|
|
436
|
-
let retries;
|
|
437
|
-
if (typeof context.options.retry === "number") retries = context.options.retry;
|
|
438
|
-
else retries = isPayloadMethod(context.options.method) ? 0 : 1;
|
|
439
|
-
const responseCode = context.response && context.response.status || 500;
|
|
440
|
-
if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) {
|
|
441
|
-
const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0;
|
|
442
|
-
if (retryDelay > 0) await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
443
|
-
return $fetchRaw(context.request, {
|
|
444
|
-
...context.options,
|
|
445
|
-
retry: retries - 1
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
const error = createFetchError(context);
|
|
450
|
-
if (Error.captureStackTrace) Error.captureStackTrace(error, $fetchRaw);
|
|
451
|
-
throw error;
|
|
452
|
-
}
|
|
453
|
-
const $fetchRaw = async function $fetchRaw2(_request, _options = {}) {
|
|
454
|
-
const context = {
|
|
455
|
-
request: _request,
|
|
456
|
-
options: resolveFetchOptions(_request, _options, globalOptions.defaults, Headers),
|
|
457
|
-
response: void 0,
|
|
458
|
-
error: void 0
|
|
459
|
-
};
|
|
460
|
-
if (context.options.method) context.options.method = context.options.method.toUpperCase();
|
|
461
|
-
if (context.options.onRequest) {
|
|
462
|
-
await callHooks(context, context.options.onRequest);
|
|
463
|
-
if (!(context.options.headers instanceof Headers)) context.options.headers = new Headers(context.options.headers || {});
|
|
464
|
-
}
|
|
465
|
-
if (typeof context.request === "string") {
|
|
466
|
-
if (context.options.baseURL) context.request = withBase(context.request, context.options.baseURL);
|
|
467
|
-
if (context.options.query) {
|
|
468
|
-
context.request = withQuery(context.request, context.options.query);
|
|
469
|
-
delete context.options.query;
|
|
470
|
-
}
|
|
471
|
-
if ("query" in context.options) delete context.options.query;
|
|
472
|
-
if ("params" in context.options) delete context.options.params;
|
|
473
|
-
}
|
|
474
|
-
if (context.options.body && isPayloadMethod(context.options.method)) {
|
|
475
|
-
if (isJSONSerializable(context.options.body)) {
|
|
476
|
-
const contentType = context.options.headers.get("content-type");
|
|
477
|
-
if (typeof context.options.body !== "string") context.options.body = contentType === "application/x-www-form-urlencoded" ? new URLSearchParams(context.options.body).toString() : JSON.stringify(context.options.body);
|
|
478
|
-
if (!contentType) context.options.headers.set("content-type", "application/json");
|
|
479
|
-
if (!context.options.headers.has("accept")) context.options.headers.set("accept", "application/json");
|
|
480
|
-
} else if ("pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || typeof context.options.body.pipe === "function") {
|
|
481
|
-
if (!("duplex" in context.options)) context.options.duplex = "half";
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
let abortTimeout;
|
|
485
|
-
if (!context.options.signal && context.options.timeout) {
|
|
486
|
-
const controller = new AbortController();
|
|
487
|
-
abortTimeout = setTimeout(() => {
|
|
488
|
-
const error = new Error("[TimeoutError]: The operation was aborted due to timeout");
|
|
489
|
-
error.name = "TimeoutError";
|
|
490
|
-
error.code = 23;
|
|
491
|
-
controller.abort(error);
|
|
492
|
-
}, context.options.timeout);
|
|
493
|
-
context.options.signal = controller.signal;
|
|
494
|
-
}
|
|
495
|
-
try {
|
|
496
|
-
context.response = await fetch(context.request, context.options);
|
|
497
|
-
} catch (error) {
|
|
498
|
-
context.error = error;
|
|
499
|
-
if (context.options.onRequestError) await callHooks(context, context.options.onRequestError);
|
|
500
|
-
return await onError(context);
|
|
501
|
-
} finally {
|
|
502
|
-
if (abortTimeout) clearTimeout(abortTimeout);
|
|
503
|
-
}
|
|
504
|
-
if ((context.response.body || context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD") {
|
|
505
|
-
const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || "");
|
|
506
|
-
switch (responseType) {
|
|
507
|
-
case "json": {
|
|
508
|
-
const data = await context.response.text();
|
|
509
|
-
const parseFunction = context.options.parseResponse || destr;
|
|
510
|
-
context.response._data = parseFunction(data);
|
|
511
|
-
break;
|
|
512
|
-
}
|
|
513
|
-
case "stream":
|
|
514
|
-
context.response._data = context.response.body || context.response._bodyInit;
|
|
515
|
-
break;
|
|
516
|
-
default: context.response._data = await context.response[responseType]();
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
if (context.options.onResponse) await callHooks(context, context.options.onResponse);
|
|
520
|
-
if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) {
|
|
521
|
-
if (context.options.onResponseError) await callHooks(context, context.options.onResponseError);
|
|
522
|
-
return await onError(context);
|
|
523
|
-
}
|
|
524
|
-
return context.response;
|
|
525
|
-
};
|
|
526
|
-
const $fetch = async function $fetch2(request, options) {
|
|
527
|
-
return (await $fetchRaw(request, options))._data;
|
|
528
|
-
};
|
|
529
|
-
$fetch.raw = $fetchRaw;
|
|
530
|
-
$fetch.native = (...args) => fetch(...args);
|
|
531
|
-
$fetch.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({
|
|
532
|
-
...globalOptions,
|
|
533
|
-
...customGlobalOptions,
|
|
534
|
-
defaults: {
|
|
535
|
-
...globalOptions.defaults,
|
|
536
|
-
...customGlobalOptions.defaults,
|
|
537
|
-
...defaultOptions
|
|
538
|
-
}
|
|
539
|
-
});
|
|
540
|
-
return $fetch;
|
|
541
|
-
}
|
|
542
|
-
//#endregion
|
|
543
|
-
//#region src/shared.ts
|
|
544
|
-
const DRIVE_CREDENTIAL_LIFETIME_SECONDS = 840;
|
|
545
|
-
const id = /^[A-Za-z0-9_-]{1,128}$/;
|
|
546
|
-
const email = /^[^\s@]+@[^\s@]+$/;
|
|
547
|
-
const MAX_SOCIAL_ID_TOKEN_BYTES = 16 * 1024;
|
|
548
|
-
function normalizeEmail(value) {
|
|
549
|
-
if (typeof value !== "string") throw new TypeError("email is invalid");
|
|
550
|
-
const normalized = value.trim().toLowerCase();
|
|
551
|
-
if (normalized.length === 0 || normalized.length > 320 || !email.test(normalized)) throw new TypeError("email is invalid");
|
|
552
|
-
return normalized;
|
|
553
|
-
}
|
|
554
|
-
function normalizePassword(value, name = "password", minLength = 8) {
|
|
555
|
-
if (typeof value !== "string" || value.length < minLength || value.length > 128) throw new TypeError(`${name} is invalid`);
|
|
556
|
-
return value;
|
|
557
|
-
}
|
|
558
|
-
function normalizeSocialIdTokenInput(value) {
|
|
559
|
-
if (!isObject(value)) throw new TypeError("social ID token input is invalid");
|
|
560
|
-
const keys = Object.keys(value);
|
|
561
|
-
if (keys.length !== 3 && keys.length !== 4 || keys.some((key) => key !== "provider" && key !== "idToken" && key !== "nonce" && key !== "signUp") || value.provider !== "google" && value.provider !== "apple" || typeof value.signUp !== "boolean" || typeof value.idToken !== "string" || value.idToken.length < 1 || new TextEncoder().encode(value.idToken).byteLength > MAX_SOCIAL_ID_TOKEN_BYTES || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.idToken) || value.nonce !== void 0 && (typeof value.nonce !== "string" || value.nonce.length < 1 || value.nonce.length > 256 || !/^[\x20-\x7e]+$/.test(value.nonce))) throw new TypeError("social ID token input is invalid");
|
|
562
|
-
return {
|
|
563
|
-
provider: value.provider,
|
|
564
|
-
idToken: value.idToken,
|
|
565
|
-
...value.nonce === void 0 ? {} : { nonce: value.nonce },
|
|
566
|
-
signUp: value.signUp
|
|
567
|
-
};
|
|
568
|
-
}
|
|
569
|
-
function socialIdTokenRequest(value) {
|
|
570
|
-
return {
|
|
571
|
-
provider: value.provider,
|
|
572
|
-
idToken: {
|
|
573
|
-
token: value.idToken,
|
|
574
|
-
...value.nonce === void 0 ? {} : { nonce: value.nonce }
|
|
575
|
-
},
|
|
576
|
-
requestSignUp: value.signUp
|
|
577
|
-
};
|
|
578
|
-
}
|
|
579
|
-
function normalizeName(value) {
|
|
580
|
-
if (typeof value !== "string") throw new TypeError("name is invalid");
|
|
581
|
-
const normalized = value.trim();
|
|
582
|
-
if (normalized.length === 0 || normalized.length > 256) throw new TypeError("name is invalid");
|
|
583
|
-
return normalized;
|
|
584
|
-
}
|
|
585
|
-
function normalizeProfileInput(value) {
|
|
586
|
-
if (!isObject(value)) throw new TypeError("profile input is invalid");
|
|
587
|
-
const keys = Object.keys(value);
|
|
588
|
-
if (keys.length === 0 || keys.length > 2 || keys.some((key) => key !== "name" && key !== "image") || value.name === void 0 && value.image === void 0) throw new TypeError("profile input is invalid");
|
|
589
|
-
const result = {};
|
|
590
|
-
if (value.name !== void 0) result.name = normalizeName(value.name);
|
|
591
|
-
if (value.image !== void 0) result.image = value.image === null ? null : normalizeProfileImage(value.image);
|
|
592
|
-
return result;
|
|
593
|
-
}
|
|
594
|
-
function normalizeOrigin(value, name) {
|
|
595
|
-
if (value.length === 0 || value.length > 2048 || /[^\x20-\x7e]/.test(value)) throw new TypeError(`${name} must be an ASCII HTTP origin`);
|
|
596
|
-
let url;
|
|
597
|
-
try {
|
|
598
|
-
url = new URL(value);
|
|
599
|
-
} catch {
|
|
600
|
-
throw new TypeError(`${name} must be an ASCII HTTP origin`);
|
|
601
|
-
}
|
|
602
|
-
const local = url.hostname === "localhost" || url.hostname.endsWith(".localhost") || url.hostname === "127.0.0.1";
|
|
603
|
-
if (url.protocol !== "https:" && !(local && url.protocol === "http:") || url.username || url.password || url.pathname !== "/" || url.search || url.hash || url.origin !== value) throw new TypeError(`${name} must be an ASCII HTTP origin`);
|
|
604
|
-
return url.origin;
|
|
605
|
-
}
|
|
606
|
-
function normalizeTimeout(value) {
|
|
607
|
-
const timeout = value ?? 1e4;
|
|
608
|
-
if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 6e4) throw new TypeError("timeoutMs must be an integer from 1 to 60000");
|
|
609
|
-
return timeout;
|
|
610
|
-
}
|
|
611
|
-
function normalizeSession(value) {
|
|
612
|
-
if (value === null) return null;
|
|
613
|
-
if (!isObject(value) || !isObject(value.session) || !isObject(value.user)) throw authorityUnavailable();
|
|
614
|
-
const expiresAt = toDate(value.session.expiresAt);
|
|
615
|
-
const image = value.user.image;
|
|
616
|
-
if (!isId(value.session.id) || !expiresAt || !isId(value.user.id) || typeof value.user.name !== "string" || value.user.name.length > 256 || typeof value.user.email !== "string" || value.user.email.length > 320 || !email.test(value.user.email) || typeof value.user.emailVerified !== "boolean" || image !== null && image !== void 0 && (typeof image !== "string" || image.length > 2048)) throw authorityUnavailable();
|
|
617
|
-
return {
|
|
618
|
-
id: value.session.id,
|
|
619
|
-
expiresAt,
|
|
620
|
-
user: {
|
|
621
|
-
id: value.user.id,
|
|
622
|
-
name: value.user.name,
|
|
623
|
-
email: value.user.email,
|
|
624
|
-
emailVerified: value.user.emailVerified,
|
|
625
|
-
image: image ?? null
|
|
626
|
-
}
|
|
627
|
-
};
|
|
628
|
-
}
|
|
629
|
-
function normalizeDriveCredential(value, now) {
|
|
630
|
-
if (!isObject(value) || value.tokenType !== "Bearer" || value.expiresIn !== DRIVE_CREDENTIAL_LIFETIME_SECONDS || typeof value.token !== "string" || value.token.length === 0 || new TextEncoder().encode(`Bearer ${value.token}`).byteLength > 16 * 1024) throw authorityUnavailable();
|
|
631
|
-
return {
|
|
632
|
-
tokenType: "Bearer",
|
|
633
|
-
token: value.token,
|
|
634
|
-
expiresAt: new Date(now + value.expiresIn * 1e3)
|
|
635
|
-
};
|
|
302
|
+
function normalizeDriveCredential(value, now) {
|
|
303
|
+
if (!isObject(value) || value.tokenType !== "Bearer" || value.expiresIn !== DRIVE_CREDENTIAL_LIFETIME_SECONDS || typeof value.token !== "string" || value.token.length === 0 || new TextEncoder().encode(`Bearer ${value.token}`).byteLength > 16 * 1024) throw authorityUnavailable();
|
|
304
|
+
return {
|
|
305
|
+
tokenType: "Bearer",
|
|
306
|
+
token: value.token,
|
|
307
|
+
expiresAt: new Date(now + value.expiresIn * 1e3)
|
|
308
|
+
};
|
|
636
309
|
}
|
|
637
310
|
function normalizeOrganizationPageInput(value) {
|
|
638
311
|
if (value === void 0) return new URLSearchParams();
|
|
@@ -1136,10 +809,359 @@ function unique(items, key) {
|
|
|
1136
809
|
if (new Set(items.map(key)).size !== items.length) throw authorityUnavailable();
|
|
1137
810
|
return items;
|
|
1138
811
|
}
|
|
812
|
+
function credentialSessionId(token) {
|
|
813
|
+
const parts = token.split(".");
|
|
814
|
+
if (parts.length !== 3 || !/^[A-Za-z0-9_-]+$/.test(parts[1])) return void 0;
|
|
815
|
+
try {
|
|
816
|
+
const base64 = parts[1].replaceAll("-", "+").replaceAll("_", "/");
|
|
817
|
+
const decoded = atob(base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "="));
|
|
818
|
+
const payload = JSON.parse(decoded);
|
|
819
|
+
return isObject(payload) && typeof payload.sid === "string" && payload.sid.length > 0 ? payload.sid : void 0;
|
|
820
|
+
} catch {
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
1139
824
|
function isObject(value) {
|
|
1140
825
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1141
826
|
}
|
|
1142
827
|
//#endregion
|
|
828
|
+
//#region src/user-api/credential.ts
|
|
829
|
+
function userApiApplication(input) {
|
|
830
|
+
if (!input || typeof input.applicationId !== "string" || !/^[A-Za-z0-9_-]{1,128}$(?![\s\S])/.test(input.applicationId) || input.forceRefresh !== void 0 && typeof input.forceRefresh !== "boolean") throw new TypeError("User API credential input is invalid");
|
|
831
|
+
return input.applicationId;
|
|
832
|
+
}
|
|
833
|
+
function normalizeUserApiCredential(value, startedAt) {
|
|
834
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || !("tokenType" in value) || value.tokenType !== "Bearer" || !("token" in value) || typeof value.token !== "string" || value.token.length + 7 > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.token) || !("expiresIn" in value) || typeof value.expiresIn !== "number" || !Number.isInteger(value.expiresIn) || value.expiresIn < 1 || value.expiresIn > 840 || Object.keys(value).sort().join(",") !== "expiresIn,token,tokenType") throw new AuthError("identity_authority_unavailable", 503);
|
|
835
|
+
return {
|
|
836
|
+
tokenType: "Bearer",
|
|
837
|
+
token: value.token,
|
|
838
|
+
expiresAt: new Date(startedAt + value.expiresIn * 1e3)
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
function createUserApiCredentialCache(issue, now, currentSessionId = () => void 0) {
|
|
842
|
+
let generation = 0;
|
|
843
|
+
let cached;
|
|
844
|
+
let pending;
|
|
845
|
+
const copy = (value) => ({
|
|
846
|
+
...value,
|
|
847
|
+
expiresAt: new Date(value.expiresAt)
|
|
848
|
+
});
|
|
849
|
+
return {
|
|
850
|
+
hasAuthority: () => Boolean(cached || pending),
|
|
851
|
+
retainSession(sessionId) {
|
|
852
|
+
if (cached?.sessionId === sessionId && !pending) return;
|
|
853
|
+
generation += 1;
|
|
854
|
+
cached = void 0;
|
|
855
|
+
pending = void 0;
|
|
856
|
+
},
|
|
857
|
+
clear() {
|
|
858
|
+
generation += 1;
|
|
859
|
+
cached = void 0;
|
|
860
|
+
pending = void 0;
|
|
861
|
+
},
|
|
862
|
+
async get(input) {
|
|
863
|
+
const applicationId = userApiApplication(input);
|
|
864
|
+
if (pending) {
|
|
865
|
+
if (pending.applicationId !== applicationId) throw new AuthError("state_conflict", 409);
|
|
866
|
+
return copy(await pending.request);
|
|
867
|
+
}
|
|
868
|
+
const startedAt = now();
|
|
869
|
+
if (!input.forceRefresh && cached?.applicationId === applicationId && cached.expiresAt - startedAt > 12e4) return {
|
|
870
|
+
tokenType: "Bearer",
|
|
871
|
+
token: cached.token,
|
|
872
|
+
expiresAt: new Date(cached.expiresAt)
|
|
873
|
+
};
|
|
874
|
+
cached = void 0;
|
|
875
|
+
const epoch = generation;
|
|
876
|
+
const request = (async () => {
|
|
877
|
+
const value = normalizeUserApiCredential(await issue(applicationId), startedAt);
|
|
878
|
+
if (epoch !== generation) throw new AuthError("state_conflict", 409);
|
|
879
|
+
if (now() < startedAt || value.expiresAt.getTime() <= now()) throw new AuthError("authentication_required", 401);
|
|
880
|
+
const sessionId = credentialSessionId(value.token);
|
|
881
|
+
const observed = currentSessionId();
|
|
882
|
+
if (observed !== void 0 && sessionId !== void 0 && sessionId !== observed) throw new AuthError("authentication_required", 401);
|
|
883
|
+
cached = {
|
|
884
|
+
applicationId,
|
|
885
|
+
token: value.token,
|
|
886
|
+
expiresAt: value.expiresAt.getTime(),
|
|
887
|
+
sessionId
|
|
888
|
+
};
|
|
889
|
+
return value;
|
|
890
|
+
})().finally(() => {
|
|
891
|
+
if (pending?.request === request) pending = void 0;
|
|
892
|
+
});
|
|
893
|
+
pending = {
|
|
894
|
+
applicationId,
|
|
895
|
+
request
|
|
896
|
+
};
|
|
897
|
+
return copy(await request);
|
|
898
|
+
}
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
//#endregion
|
|
902
|
+
//#region ../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs
|
|
903
|
+
const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/;
|
|
904
|
+
const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
|
|
905
|
+
const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
|
|
906
|
+
function jsonParseTransform(key, value) {
|
|
907
|
+
if (key === "__proto__" || key === "constructor" && value && typeof value === "object" && "prototype" in value) {
|
|
908
|
+
warnKeyDropped(key);
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
return value;
|
|
912
|
+
}
|
|
913
|
+
function warnKeyDropped(key) {
|
|
914
|
+
console.warn(`[destr] Dropping "${key}" key to prevent prototype pollution.`);
|
|
915
|
+
}
|
|
916
|
+
function destr(value, options = {}) {
|
|
917
|
+
if (typeof value !== "string") return value;
|
|
918
|
+
if (value[0] === "\"" && value[value.length - 1] === "\"" && value.indexOf("\\") === -1) return value.slice(1, -1);
|
|
919
|
+
const _value = value.trim();
|
|
920
|
+
if (_value.length <= 9) switch (_value.toLowerCase()) {
|
|
921
|
+
case "true": return true;
|
|
922
|
+
case "false": return false;
|
|
923
|
+
case "undefined": return;
|
|
924
|
+
case "null": return null;
|
|
925
|
+
case "nan": return NaN;
|
|
926
|
+
case "infinity": return Number.POSITIVE_INFINITY;
|
|
927
|
+
case "-infinity": return Number.NEGATIVE_INFINITY;
|
|
928
|
+
}
|
|
929
|
+
if (!JsonSigRx.test(value)) {
|
|
930
|
+
if (options.strict) throw new SyntaxError("[destr] Invalid JSON");
|
|
931
|
+
return value;
|
|
932
|
+
}
|
|
933
|
+
try {
|
|
934
|
+
if (suspectProtoRx.test(value) || suspectConstructorRx.test(value)) {
|
|
935
|
+
if (options.strict) throw new Error("[destr] Possible prototype pollution");
|
|
936
|
+
return JSON.parse(value, jsonParseTransform);
|
|
937
|
+
}
|
|
938
|
+
return JSON.parse(value);
|
|
939
|
+
} catch (error) {
|
|
940
|
+
if (options.strict) throw error;
|
|
941
|
+
return value;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
//#endregion
|
|
945
|
+
//#region ../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/shared/ofetch.CWycOUEr.mjs
|
|
946
|
+
var FetchError = class extends Error {
|
|
947
|
+
constructor(message, opts) {
|
|
948
|
+
super(message, opts);
|
|
949
|
+
this.name = "FetchError";
|
|
950
|
+
if (opts?.cause && !this.cause) this.cause = opts.cause;
|
|
951
|
+
}
|
|
952
|
+
};
|
|
953
|
+
function createFetchError(ctx) {
|
|
954
|
+
const errorMessage = ctx.error?.message || ctx.error?.toString() || "";
|
|
955
|
+
const method = ctx.request?.method || ctx.options?.method || "GET";
|
|
956
|
+
const url = ctx.request?.url || String(ctx.request) || "/";
|
|
957
|
+
const fetchError = new FetchError(`${`[${method}] ${JSON.stringify(url)}`}: ${ctx.response ? `${ctx.response.status} ${ctx.response.statusText}` : "<no response>"}${errorMessage ? ` ${errorMessage}` : ""}`, ctx.error ? { cause: ctx.error } : void 0);
|
|
958
|
+
for (const key of [
|
|
959
|
+
"request",
|
|
960
|
+
"options",
|
|
961
|
+
"response"
|
|
962
|
+
]) Object.defineProperty(fetchError, key, { get() {
|
|
963
|
+
return ctx[key];
|
|
964
|
+
} });
|
|
965
|
+
for (const [key, refKey] of [
|
|
966
|
+
["data", "_data"],
|
|
967
|
+
["status", "status"],
|
|
968
|
+
["statusCode", "status"],
|
|
969
|
+
["statusText", "statusText"],
|
|
970
|
+
["statusMessage", "statusText"]
|
|
971
|
+
]) Object.defineProperty(fetchError, key, { get() {
|
|
972
|
+
return ctx.response && ctx.response[refKey];
|
|
973
|
+
} });
|
|
974
|
+
return fetchError;
|
|
975
|
+
}
|
|
976
|
+
const payloadMethods = new Set(Object.freeze([
|
|
977
|
+
"PATCH",
|
|
978
|
+
"POST",
|
|
979
|
+
"PUT",
|
|
980
|
+
"DELETE"
|
|
981
|
+
]));
|
|
982
|
+
function isPayloadMethod(method = "GET") {
|
|
983
|
+
return payloadMethods.has(method.toUpperCase());
|
|
984
|
+
}
|
|
985
|
+
function isJSONSerializable(value) {
|
|
986
|
+
if (value === void 0) return false;
|
|
987
|
+
const t = typeof value;
|
|
988
|
+
if (t === "string" || t === "number" || t === "boolean" || t === null) return true;
|
|
989
|
+
if (t !== "object") return false;
|
|
990
|
+
if (Array.isArray(value)) return true;
|
|
991
|
+
if (value.buffer) return false;
|
|
992
|
+
if (value instanceof FormData || value instanceof URLSearchParams) return false;
|
|
993
|
+
return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
|
|
994
|
+
}
|
|
995
|
+
const textTypes = new Set([
|
|
996
|
+
"image/svg",
|
|
997
|
+
"application/xml",
|
|
998
|
+
"application/xhtml",
|
|
999
|
+
"application/html"
|
|
1000
|
+
]);
|
|
1001
|
+
const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
|
|
1002
|
+
function detectResponseType(_contentType = "") {
|
|
1003
|
+
if (!_contentType) return "json";
|
|
1004
|
+
const contentType = _contentType.split(";").shift() || "";
|
|
1005
|
+
if (JSON_RE.test(contentType)) return "json";
|
|
1006
|
+
if (contentType === "text/event-stream") return "stream";
|
|
1007
|
+
if (textTypes.has(contentType) || contentType.startsWith("text/")) return "text";
|
|
1008
|
+
return "blob";
|
|
1009
|
+
}
|
|
1010
|
+
function resolveFetchOptions(request, input, defaults, Headers) {
|
|
1011
|
+
const headers = mergeHeaders(input?.headers ?? request?.headers, defaults?.headers, Headers);
|
|
1012
|
+
let query;
|
|
1013
|
+
if (defaults?.query || defaults?.params || input?.params || input?.query) query = {
|
|
1014
|
+
...defaults?.params,
|
|
1015
|
+
...defaults?.query,
|
|
1016
|
+
...input?.params,
|
|
1017
|
+
...input?.query
|
|
1018
|
+
};
|
|
1019
|
+
return {
|
|
1020
|
+
...defaults,
|
|
1021
|
+
...input,
|
|
1022
|
+
query,
|
|
1023
|
+
params: query,
|
|
1024
|
+
headers
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
function mergeHeaders(input, defaults, Headers) {
|
|
1028
|
+
if (!defaults) return new Headers(input);
|
|
1029
|
+
const headers = new Headers(defaults);
|
|
1030
|
+
if (input) for (const [key, value] of Symbol.iterator in input || Array.isArray(input) ? input : new Headers(input)) headers.set(key, value);
|
|
1031
|
+
return headers;
|
|
1032
|
+
}
|
|
1033
|
+
async function callHooks(context, hooks) {
|
|
1034
|
+
if (hooks) if (Array.isArray(hooks)) for (const hook of hooks) await hook(context);
|
|
1035
|
+
else await hooks(context);
|
|
1036
|
+
}
|
|
1037
|
+
const retryStatusCodes = new Set([
|
|
1038
|
+
408,
|
|
1039
|
+
409,
|
|
1040
|
+
425,
|
|
1041
|
+
429,
|
|
1042
|
+
500,
|
|
1043
|
+
502,
|
|
1044
|
+
503,
|
|
1045
|
+
504
|
|
1046
|
+
]);
|
|
1047
|
+
const nullBodyResponses = new Set([
|
|
1048
|
+
101,
|
|
1049
|
+
204,
|
|
1050
|
+
205,
|
|
1051
|
+
304
|
|
1052
|
+
]);
|
|
1053
|
+
function createFetch(globalOptions = {}) {
|
|
1054
|
+
const { fetch = globalThis.fetch, Headers = globalThis.Headers, AbortController = globalThis.AbortController } = globalOptions;
|
|
1055
|
+
async function onError(context) {
|
|
1056
|
+
const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false;
|
|
1057
|
+
if (context.options.retry !== false && !isAbort) {
|
|
1058
|
+
let retries;
|
|
1059
|
+
if (typeof context.options.retry === "number") retries = context.options.retry;
|
|
1060
|
+
else retries = isPayloadMethod(context.options.method) ? 0 : 1;
|
|
1061
|
+
const responseCode = context.response && context.response.status || 500;
|
|
1062
|
+
if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) {
|
|
1063
|
+
const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0;
|
|
1064
|
+
if (retryDelay > 0) await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
1065
|
+
return $fetchRaw(context.request, {
|
|
1066
|
+
...context.options,
|
|
1067
|
+
retry: retries - 1
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
const error = createFetchError(context);
|
|
1072
|
+
if (Error.captureStackTrace) Error.captureStackTrace(error, $fetchRaw);
|
|
1073
|
+
throw error;
|
|
1074
|
+
}
|
|
1075
|
+
const $fetchRaw = async function $fetchRaw2(_request, _options = {}) {
|
|
1076
|
+
const context = {
|
|
1077
|
+
request: _request,
|
|
1078
|
+
options: resolveFetchOptions(_request, _options, globalOptions.defaults, Headers),
|
|
1079
|
+
response: void 0,
|
|
1080
|
+
error: void 0
|
|
1081
|
+
};
|
|
1082
|
+
if (context.options.method) context.options.method = context.options.method.toUpperCase();
|
|
1083
|
+
if (context.options.onRequest) {
|
|
1084
|
+
await callHooks(context, context.options.onRequest);
|
|
1085
|
+
if (!(context.options.headers instanceof Headers)) context.options.headers = new Headers(context.options.headers || {});
|
|
1086
|
+
}
|
|
1087
|
+
if (typeof context.request === "string") {
|
|
1088
|
+
if (context.options.baseURL) context.request = withBase(context.request, context.options.baseURL);
|
|
1089
|
+
if (context.options.query) {
|
|
1090
|
+
context.request = withQuery(context.request, context.options.query);
|
|
1091
|
+
delete context.options.query;
|
|
1092
|
+
}
|
|
1093
|
+
if ("query" in context.options) delete context.options.query;
|
|
1094
|
+
if ("params" in context.options) delete context.options.params;
|
|
1095
|
+
}
|
|
1096
|
+
if (context.options.body && isPayloadMethod(context.options.method)) {
|
|
1097
|
+
if (isJSONSerializable(context.options.body)) {
|
|
1098
|
+
const contentType = context.options.headers.get("content-type");
|
|
1099
|
+
if (typeof context.options.body !== "string") context.options.body = contentType === "application/x-www-form-urlencoded" ? new URLSearchParams(context.options.body).toString() : JSON.stringify(context.options.body);
|
|
1100
|
+
if (!contentType) context.options.headers.set("content-type", "application/json");
|
|
1101
|
+
if (!context.options.headers.has("accept")) context.options.headers.set("accept", "application/json");
|
|
1102
|
+
} else if ("pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || typeof context.options.body.pipe === "function") {
|
|
1103
|
+
if (!("duplex" in context.options)) context.options.duplex = "half";
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
let abortTimeout;
|
|
1107
|
+
if (!context.options.signal && context.options.timeout) {
|
|
1108
|
+
const controller = new AbortController();
|
|
1109
|
+
abortTimeout = setTimeout(() => {
|
|
1110
|
+
const error = new Error("[TimeoutError]: The operation was aborted due to timeout");
|
|
1111
|
+
error.name = "TimeoutError";
|
|
1112
|
+
error.code = 23;
|
|
1113
|
+
controller.abort(error);
|
|
1114
|
+
}, context.options.timeout);
|
|
1115
|
+
context.options.signal = controller.signal;
|
|
1116
|
+
}
|
|
1117
|
+
try {
|
|
1118
|
+
context.response = await fetch(context.request, context.options);
|
|
1119
|
+
} catch (error) {
|
|
1120
|
+
context.error = error;
|
|
1121
|
+
if (context.options.onRequestError) await callHooks(context, context.options.onRequestError);
|
|
1122
|
+
return await onError(context);
|
|
1123
|
+
} finally {
|
|
1124
|
+
if (abortTimeout) clearTimeout(abortTimeout);
|
|
1125
|
+
}
|
|
1126
|
+
if ((context.response.body || context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD") {
|
|
1127
|
+
const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || "");
|
|
1128
|
+
switch (responseType) {
|
|
1129
|
+
case "json": {
|
|
1130
|
+
const data = await context.response.text();
|
|
1131
|
+
const parseFunction = context.options.parseResponse || destr;
|
|
1132
|
+
context.response._data = parseFunction(data);
|
|
1133
|
+
break;
|
|
1134
|
+
}
|
|
1135
|
+
case "stream":
|
|
1136
|
+
context.response._data = context.response.body || context.response._bodyInit;
|
|
1137
|
+
break;
|
|
1138
|
+
default: context.response._data = await context.response[responseType]();
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
if (context.options.onResponse) await callHooks(context, context.options.onResponse);
|
|
1142
|
+
if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) {
|
|
1143
|
+
if (context.options.onResponseError) await callHooks(context, context.options.onResponseError);
|
|
1144
|
+
return await onError(context);
|
|
1145
|
+
}
|
|
1146
|
+
return context.response;
|
|
1147
|
+
};
|
|
1148
|
+
const $fetch = async function $fetch2(request, options) {
|
|
1149
|
+
return (await $fetchRaw(request, options))._data;
|
|
1150
|
+
};
|
|
1151
|
+
$fetch.raw = $fetchRaw;
|
|
1152
|
+
$fetch.native = (...args) => fetch(...args);
|
|
1153
|
+
$fetch.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({
|
|
1154
|
+
...globalOptions,
|
|
1155
|
+
...customGlobalOptions,
|
|
1156
|
+
defaults: {
|
|
1157
|
+
...globalOptions.defaults,
|
|
1158
|
+
...customGlobalOptions.defaults,
|
|
1159
|
+
...defaultOptions
|
|
1160
|
+
}
|
|
1161
|
+
});
|
|
1162
|
+
return $fetch;
|
|
1163
|
+
}
|
|
1164
|
+
//#endregion
|
|
1143
1165
|
//#region src/http.ts
|
|
1144
1166
|
const MAX_RESPONSE_BYTES = 64 * 1024;
|
|
1145
1167
|
async function requestJsonResponse(url, options) {
|