@zayne-labs/callapi 1.14.1 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{conditional-types-BFeM4YSg.d.ts → conditional-types-DaKFU9_F.d.ts} +13 -4
- package/dist/constants/index.d.ts +7 -6
- package/dist/constants/index.js +1 -1
- package/dist/{constants-DB6Z7gFB.js → constants-Cm0RTgJ0.js} +148 -106
- package/dist/constants-Cm0RTgJ0.js.map +1 -0
- package/dist/{index-DuBaw9km.d.ts → index-CAOA5J63.d.ts} +6 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.js +23 -9
- package/dist/index.js.map +1 -1
- package/dist/utils/external/index.d.ts +2 -2
- package/dist/utils/external/index.js +2 -2
- package/package.json +19 -19
- package/dist/constants-DB6Z7gFB.js.map +0 -1
|
@@ -125,7 +125,8 @@ type AllowedQueryParamValues = UnmaskType<boolean | number | string>;
|
|
|
125
125
|
type RecordStyleParams = UnmaskType<Record<string, AllowedQueryParamValues>>;
|
|
126
126
|
type TupleStyleParams = UnmaskType<AllowedQueryParamValues[]>;
|
|
127
127
|
type Params = UnmaskType<RecordStyleParams | TupleStyleParams>;
|
|
128
|
-
type
|
|
128
|
+
type StructuredQueryValues = Record<string, unknown> | unknown[] | null | undefined;
|
|
129
|
+
type Query = UnmaskType<Record<string, AllowedQueryParamValues | StructuredQueryValues> | URLSearchParams>;
|
|
129
130
|
type InitURLOrURLObject = AnyString | RouteKeyMethodsURLUnion | URL;
|
|
130
131
|
interface URLOptions {
|
|
131
132
|
/**
|
|
@@ -617,8 +618,8 @@ declare const toFormData: <TSchema extends CallApiSchemaType<BodyType>>(data: In
|
|
|
617
618
|
//#endregion
|
|
618
619
|
//#region src/utils/external/define.d.ts
|
|
619
620
|
declare const defineSchema: <const TBaseSchemaRoutes extends BaseCallApiSchemaRoutes, const TSchemaConfig extends CallApiSchemaConfig>(routes: TBaseSchemaRoutes, config?: Satisfies<TSchemaConfig, CallApiSchemaConfig>) => {
|
|
620
|
-
config: Writeable<Satisfies<TSchemaConfig, CallApiSchemaConfig>, "deep">;
|
|
621
621
|
routes: Writeable<TBaseSchemaRoutes, "deep">;
|
|
622
|
+
config: Writeable<Satisfies<TSchemaConfig, CallApiSchemaConfig>, "deep">;
|
|
622
623
|
};
|
|
623
624
|
declare const defineSchemaRoutes: <const TSchemaRoutes extends BaseCallApiSchemaRoutes>(routes: TSchemaRoutes) => Writeable<typeof routes, "deep">;
|
|
624
625
|
declare const defineMainSchema: <const TSchema extends CallApiSchema>(mainSchema: Satisfies<TSchema, CallApiSchema>) => Writeable<typeof mainSchema, "deep">;
|
|
@@ -632,6 +633,9 @@ type DefineBaseConfig = {
|
|
|
632
633
|
};
|
|
633
634
|
declare const defineBaseConfig: DefineBaseConfig;
|
|
634
635
|
declare const defineInstanceConfig: <const TInstanceConfig extends CallApiConfig>(config: TInstanceConfig) => Writeable<typeof config, "deep">;
|
|
636
|
+
declare const defineFallbackRouteSchema: <const TSchema extends CallApiSchema>(schema: TSchema) => {
|
|
637
|
+
"@default": NonNullable<TSchema> extends Record<string | number | symbol, unknown> | unknown[] | readonly unknown[] ? Writeable<TSchema, "deep"> : TSchema;
|
|
638
|
+
};
|
|
635
639
|
//#endregion
|
|
636
640
|
//#region src/utils/external/guards.d.ts
|
|
637
641
|
declare const isHTTPError: <TErrorData>(error: CallApiResultErrorVariant<TErrorData>["error"] | null) => error is PossibleHTTPError<TErrorData>;
|
|
@@ -666,6 +670,11 @@ interface RetryOptions<TErrorData> {
|
|
|
666
670
|
* @deprecated **WARNING**: This property is used internally to track retries. Please abstain from reading or modifying it.
|
|
667
671
|
*/
|
|
668
672
|
readonly ["~retryAttemptCount"]?: number;
|
|
673
|
+
/**
|
|
674
|
+
* Use a valid `Retry-After` response header instead of the configured retry delay
|
|
675
|
+
* @default false
|
|
676
|
+
*/
|
|
677
|
+
respectRetryAfter?: boolean;
|
|
669
678
|
/**
|
|
670
679
|
* Number of allowed retry attempts on HTTP errors
|
|
671
680
|
* @default 0
|
|
@@ -1911,5 +1920,5 @@ type ThrowOnErrorOption<TErrorData, TThrowOnError extends ThrowOnErrorBoolean> =
|
|
|
1911
1920
|
throwOnError?: ThrowOnErrorType<TErrorData, TThrowOnError>;
|
|
1912
1921
|
};
|
|
1913
1922
|
//#endregion
|
|
1914
|
-
export {
|
|
1915
|
-
//# sourceMappingURL=conditional-types-
|
|
1923
|
+
export { defineInstanceConfig as $, Register as A, ValidationError as At, ResponseErrorContext as B, FallBackRouteSchemaKey as Bt, CallApiResultLoose as C, PossibleHTTPError as Ct, GetCallApiContextRequired as D, ResponseTypeType as Dt, GetCallApiContext as E, ResponseTypeMap as Et, Hooks as F, CallApiSchemaConfig as Ft, objectifyHeaders as G, DistributiveOmit as Gt, SuccessContext as H, AnyString as Ht, HooksOrHooksArray as I, InferSchemaInput as It, isJavascriptError as J, fetchSpecificKeys as Jt, isHTTPError as K, NoInferUnMasked as Kt, RequestContext as L, InferSchemaOutput as Lt, CallApiExtraOptionsForHooks as M, BaseCallApiSchemaRoutes as Mt, CallApiRequestOptionsForHooks as N, BaseSchemaRouteKeyPrefixes as Nt, GlobalMeta as O, ResultModeType as Ot, ErrorContext as P, CallApiSchema as Pt, defineFallbackRouteSchema as Q, RequestStreamContext as R, InferSchemaResult as Rt, CallApiResult as S, InferCallApiResult as St, GetBaseSchemaRoutes as T, PossibleValidationError as Tt, RefetchOptions as U, CommonContentTypes as Ut, ResponseStreamContext as V, fallBackRouteSchemaKey as Vt, RetryOptions as W, CommonRequestHeaders as Wt, isValidationErrorInstance as X, isValidationError as Y, defineBaseConfig as Z, CallApiConfig as _, Middlewares as _t, GetCurrentRouteSchemaKey as a, toFormData as at, CallApiParameters as b, CallApiResultSuccessVariant as bt, InferAllMainRoutes as c, DefaultCallApiContext as ct, SerializableArray as d, CallApiPlugin as dt, defineMainSchema as et, SerializableObject as f, PluginHooks as ft, BaseCallApiExtraOptions as g, FetchMiddlewareContext as gt, BaseCallApiConfig as h, FetchImpl as ht, GetCurrentRouteSchema as i, defineSchemaRoutes as it, DedupeOptions as j, BaseCallApiSchemaAndConfig as jt, InstanceContext as k, HTTPError as kt, InferInitURL as l, DefaultDataType as lt, AuthOption as m, PluginSetupContext as mt, ApplyURLBasedConfig as n, defineSchema as nt, HeadersOption as o, toQueryString as ot, ThrowOnErrorBoolean as p, PluginMiddlewares as pt, isHTTPErrorInstance as q, Writeable as qt, Body as r, defineSchemaConfig as rt, InferAllMainRouteKeys as s, toSearchParams as st, ApplyStrictConfig as t, definePlugin as tt, InferParamsFromRoute as u, DefaultPluginArray as ut, CallApiContext as v, CallApiResultErrorVariant as vt, GetBaseSchemaConfig as w, PossibleJavaScriptError as wt, CallApiRequestOptions as x, GetResponseType as xt, CallApiExtraOptions as y, CallApiResultSuccessOrErrorVariant as yt, ResponseContext as z, URLOptions as zt };
|
|
1924
|
+
//# sourceMappingURL=conditional-types-DaKFU9_F.d.ts.map
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { Bt as
|
|
1
|
+
import { Bt as FallBackRouteSchemaKey, Jt as fetchSpecificKeys, L as RequestContext, Vt as fallBackRouteSchemaKey } from "../conditional-types-DaKFU9_F.js";
|
|
2
2
|
//#region src/constants/defaults.d.ts
|
|
3
|
-
declare const extraOptionDefaults: Readonly<Readonly<{
|
|
3
|
+
export declare const extraOptionDefaults: Readonly<Readonly<{
|
|
4
4
|
bodySerializer: {
|
|
5
5
|
(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
|
|
6
6
|
(value: any, replacer?: (number | string)[] | null, space?: string | number): string;
|
|
7
7
|
};
|
|
8
8
|
debugMode: true;
|
|
9
|
-
defaultHTTPErrorMessage: "Request failed unexpectedly";
|
|
10
9
|
dedupeCacheScope: "local";
|
|
11
|
-
dedupeKey: (ctx: RequestContext) => string;
|
|
12
10
|
dedupeCacheScopeKey: "default";
|
|
11
|
+
dedupeKey: (ctx: RequestContext) => string;
|
|
13
12
|
dedupeStrategy: "cancel";
|
|
13
|
+
defaultHTTPErrorMessage: "Request failed unexpectedly";
|
|
14
14
|
hooksExecutionMode: "parallel";
|
|
15
|
+
respectRetryAfter: false;
|
|
15
16
|
responseParser: (text: string, reviver?: (this: any, key: string, value: any) => any) => any;
|
|
16
17
|
responseType: "json";
|
|
17
18
|
resultMode: "all";
|
|
@@ -23,9 +24,9 @@ declare const extraOptionDefaults: Readonly<Readonly<{
|
|
|
23
24
|
retryStatusCodes: [];
|
|
24
25
|
retryStrategy: "linear";
|
|
25
26
|
}>>;
|
|
26
|
-
declare const requestOptionDefaults: Readonly<Readonly<{
|
|
27
|
+
export declare const requestOptionDefaults: Readonly<Readonly<{
|
|
27
28
|
method: "GET";
|
|
28
29
|
}>>;
|
|
29
30
|
//#endregion
|
|
30
|
-
export { FallBackRouteSchemaKey,
|
|
31
|
+
export { FallBackRouteSchemaKey, fallBackRouteSchemaKey, fetchSpecificKeys };
|
|
31
32
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/constants/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as fetchSpecificKeys, I as fallBackRouteSchemaKey, n as requestOptionDefaults, t as extraOptionDefaults } from "../constants-Cm0RTgJ0.js";
|
|
2
2
|
export { extraOptionDefaults, fallBackRouteSchemaKey, fetchSpecificKeys, requestOptionDefaults };
|
|
@@ -65,32 +65,33 @@ const isPromise = (value) => value instanceof Promise;
|
|
|
65
65
|
//#endregion
|
|
66
66
|
//#region src/auth.ts
|
|
67
67
|
const resolveAuthValue = (value) => isFunction(value) ? value() : value;
|
|
68
|
+
const isMissingAuthValue = (value) => value == null;
|
|
68
69
|
const getAuthHeader = async (auth) => {
|
|
69
70
|
if (auth === void 0) return;
|
|
70
71
|
if (isPromise(auth) || isFunction(auth) || !isObject(auth)) {
|
|
71
72
|
const authValue = await resolveAuthValue(auth);
|
|
72
|
-
if (authValue
|
|
73
|
+
if (isMissingAuthValue(authValue)) return;
|
|
73
74
|
return { Authorization: `Bearer ${authValue}` };
|
|
74
75
|
}
|
|
75
76
|
switch (auth.type) {
|
|
76
77
|
case "Basic": {
|
|
77
78
|
const [username, password] = await Promise.all([resolveAuthValue(auth.username), resolveAuthValue(auth.password)]);
|
|
78
|
-
if (username
|
|
79
|
+
if (isMissingAuthValue(username) || isMissingAuthValue(password)) return;
|
|
79
80
|
return { Authorization: `Basic ${globalThis.btoa(`${username}:${password}`)}` };
|
|
80
81
|
}
|
|
81
82
|
case "Bearer": {
|
|
82
83
|
const value = await resolveAuthValue(auth.value);
|
|
83
|
-
if (value
|
|
84
|
+
if (isMissingAuthValue(value)) return;
|
|
84
85
|
return { Authorization: `Bearer ${value}` };
|
|
85
86
|
}
|
|
86
87
|
case "Custom": {
|
|
87
88
|
const [prefix, value] = await Promise.all([resolveAuthValue(auth.prefix), resolveAuthValue(auth.value)]);
|
|
88
|
-
if (
|
|
89
|
+
if (isMissingAuthValue(prefix) || isMissingAuthValue(value)) return;
|
|
89
90
|
return { Authorization: `${prefix} ${value}` };
|
|
90
91
|
}
|
|
91
92
|
case "Token": {
|
|
92
93
|
const value = await resolveAuthValue(auth.value);
|
|
93
|
-
if (value
|
|
94
|
+
if (isMissingAuthValue(value)) return;
|
|
94
95
|
return { Authorization: `Token ${value}` };
|
|
95
96
|
}
|
|
96
97
|
default: return;
|
|
@@ -348,90 +349,6 @@ const getCurrentRouteSchemaKeyAndMainInitURL = (context) => {
|
|
|
348
349
|
};
|
|
349
350
|
};
|
|
350
351
|
//#endregion
|
|
351
|
-
//#region src/url.ts
|
|
352
|
-
const handleArrayParams = (url, params) => {
|
|
353
|
-
let newUrl = url;
|
|
354
|
-
const urlParts = newUrl.split("/");
|
|
355
|
-
const matchedParamsArray = [];
|
|
356
|
-
for (const part of urlParts) {
|
|
357
|
-
if (!(part.startsWith(":") || part.startsWith("{") && part.endsWith("}"))) continue;
|
|
358
|
-
matchedParamsArray.push(part);
|
|
359
|
-
}
|
|
360
|
-
for (const [paramIndex, matchedParam] of matchedParamsArray.entries()) {
|
|
361
|
-
const stringParamValue = String(params[paramIndex]);
|
|
362
|
-
newUrl = newUrl.replace(matchedParam, stringParamValue);
|
|
363
|
-
}
|
|
364
|
-
return newUrl;
|
|
365
|
-
};
|
|
366
|
-
const handleObjectParams = (url, params) => {
|
|
367
|
-
let newUrl = url;
|
|
368
|
-
for (const [paramKey, paramValue] of Object.entries(params)) {
|
|
369
|
-
const colonPattern = `:${paramKey}`;
|
|
370
|
-
const bracePattern = `{${paramKey}}`;
|
|
371
|
-
const stringValue = String(paramValue);
|
|
372
|
-
newUrl = newUrl.replace(colonPattern, stringValue);
|
|
373
|
-
newUrl = newUrl.replace(bracePattern, stringValue);
|
|
374
|
-
}
|
|
375
|
-
return newUrl;
|
|
376
|
-
};
|
|
377
|
-
const mergeUrlWithParams = (url, params) => {
|
|
378
|
-
if (!params) return url;
|
|
379
|
-
return isArray(params) ? handleArrayParams(url, params) : handleObjectParams(url, params);
|
|
380
|
-
};
|
|
381
|
-
const mergeUrlWithQuery = (url, query) => {
|
|
382
|
-
if (!query) return url;
|
|
383
|
-
const queryString = new URLSearchParams(query).toString();
|
|
384
|
-
if (queryString.length === 0) return url;
|
|
385
|
-
if (url.endsWith("?")) return `${url}${queryString}`;
|
|
386
|
-
if (url.includes("?")) return `${url}&${queryString}`;
|
|
387
|
-
return `${url}?${queryString}`;
|
|
388
|
-
};
|
|
389
|
-
/**
|
|
390
|
-
* @description Extracts the HTTP method from method-prefixed route patterns.
|
|
391
|
-
*
|
|
392
|
-
* Analyzes URLs that start with method modifiers (e.g., "@get/", "@post/") and extracts
|
|
393
|
-
* the HTTP method for use in API requests. This enables method specification directly
|
|
394
|
-
* in route definitions.
|
|
395
|
-
*
|
|
396
|
-
* @param initURL - The URL string to analyze for method modifiers
|
|
397
|
-
* @returns The extracted HTTP method (lowercase) if found, otherwise undefined
|
|
398
|
-
*
|
|
399
|
-
* @example
|
|
400
|
-
* ```typescript
|
|
401
|
-
* extractMethodFromURL("@get/users"); // Returns: "get"
|
|
402
|
-
* extractMethodFromURL("@post/users"); // Returns: "post"
|
|
403
|
-
* ```
|
|
404
|
-
*/
|
|
405
|
-
const extractMethodFromURL = (initURL) => {
|
|
406
|
-
if (!initURL?.startsWith("@")) return;
|
|
407
|
-
const methodFromURL = routeKeyMethods.find((method) => initURL.startsWith(`@${method}/`));
|
|
408
|
-
if (!methodFromURL) return;
|
|
409
|
-
return methodFromURL;
|
|
410
|
-
};
|
|
411
|
-
const normalizeURL = (initURL, options = {}) => {
|
|
412
|
-
const { retainLeadingSlashForRelativeURLs = true } = options;
|
|
413
|
-
const methodFromURL = extractMethodFromURL(initURL);
|
|
414
|
-
if (!methodFromURL) return initURL;
|
|
415
|
-
return retainLeadingSlashForRelativeURLs && !initURL.includes("http") ? initURL.replace(`@${methodFromURL}`, "") : initURL.replace(`@${methodFromURL}/`, "");
|
|
416
|
-
};
|
|
417
|
-
const getFullURL = (initURL, baseURL) => {
|
|
418
|
-
if (!baseURL || initURL.startsWith("http")) return initURL;
|
|
419
|
-
return initURL.length > 0 && !initURL.startsWith("/") && !baseURL.endsWith("/") ? `${baseURL}/${initURL}` : `${baseURL}${initURL}`;
|
|
420
|
-
};
|
|
421
|
-
const getFullAndNormalizedURL = (options) => {
|
|
422
|
-
const { baseURL, debugMode, initURL, params, query } = options;
|
|
423
|
-
const normalizedInitURL = normalizeURL(initURL);
|
|
424
|
-
const fullURL = getFullURL(mergeUrlWithQuery(mergeUrlWithParams(normalizedInitURL, params), query), baseURL);
|
|
425
|
-
if ((debugMode ?? extraOptionDefaults.debugMode) && !URL.canParse(fullURL)) {
|
|
426
|
-
const errorMessage = !baseURL ? `Invalid URL '${initURL}'. Are you passing a relative url to CallApi without setting the 'baseURL' option?` : `Invalid URL '${fullURL}'. Please validate that you are passing the correct url.`;
|
|
427
|
-
console.error(errorMessage);
|
|
428
|
-
}
|
|
429
|
-
return {
|
|
430
|
-
fullURL,
|
|
431
|
-
normalizedInitURL
|
|
432
|
-
};
|
|
433
|
-
};
|
|
434
|
-
//#endregion
|
|
435
352
|
//#region src/utils/external/body.ts
|
|
436
353
|
const toStringOrStringify = (value) => {
|
|
437
354
|
return isString(value) ? value : JSON.stringify(value);
|
|
@@ -443,6 +360,7 @@ const toSearchParams = (data, schema) => {
|
|
|
443
360
|
issues: result.issues,
|
|
444
361
|
response: null
|
|
445
362
|
});
|
|
363
|
+
if (result.value instanceof URLSearchParams) return new URLSearchParams(result.value);
|
|
446
364
|
const searchParams = new URLSearchParams();
|
|
447
365
|
for (const [key, value] of Object.entries(result.value)) {
|
|
448
366
|
if (value == null) continue;
|
|
@@ -521,8 +439,8 @@ const toFormData = (data, schema) => {
|
|
|
521
439
|
//#region src/utils/external/define.ts
|
|
522
440
|
const defineSchema = (routes, config) => {
|
|
523
441
|
return {
|
|
524
|
-
|
|
525
|
-
|
|
442
|
+
routes: defineSchemaRoutes(routes),
|
|
443
|
+
config: defineSchemaConfig(config)
|
|
526
444
|
};
|
|
527
445
|
};
|
|
528
446
|
const defineSchemaRoutes = (routes) => {
|
|
@@ -543,6 +461,9 @@ const defineBaseConfig = (baseConfig) => {
|
|
|
543
461
|
const defineInstanceConfig = (config) => {
|
|
544
462
|
return config;
|
|
545
463
|
};
|
|
464
|
+
const defineFallbackRouteSchema = (schema) => {
|
|
465
|
+
return defineSchemaRoutes({ [fallBackRouteSchemaKey]: schema });
|
|
466
|
+
};
|
|
546
467
|
//#endregion
|
|
547
468
|
//#region src/utils/external/guards.ts
|
|
548
469
|
const isHTTPError = (error) => {
|
|
@@ -568,6 +489,121 @@ const objectifyHeaders = (headers) => {
|
|
|
568
489
|
return Object.fromEntries(headers);
|
|
569
490
|
};
|
|
570
491
|
//#endregion
|
|
492
|
+
//#region src/url.ts
|
|
493
|
+
const isReservedPathSegment = (value) => value === "." || value === "..";
|
|
494
|
+
const encodeParamValue = (value) => {
|
|
495
|
+
const stringValue = String(value);
|
|
496
|
+
if (isReservedPathSegment(stringValue)) throw new TypeError("Path parameters cannot be reserved path segments");
|
|
497
|
+
return encodeURIComponent(stringValue);
|
|
498
|
+
};
|
|
499
|
+
const isColonPathParam = (segment) => Boolean(segment?.startsWith(":"));
|
|
500
|
+
const isBracePathParam = (segment) => {
|
|
501
|
+
return Boolean(segment?.startsWith("{") && segment.endsWith("}"));
|
|
502
|
+
};
|
|
503
|
+
const handleArrayParams = (url, params) => {
|
|
504
|
+
const placeholders = [];
|
|
505
|
+
const urlSegments = url.split("/");
|
|
506
|
+
for (const segment of urlSegments) {
|
|
507
|
+
if (!isColonPathParam(segment) && !isBracePathParam(segment)) continue;
|
|
508
|
+
placeholders.push(segment);
|
|
509
|
+
}
|
|
510
|
+
let resolvedURL = url;
|
|
511
|
+
for (const index of placeholders.keys()) {
|
|
512
|
+
const placeholder = placeholders[index];
|
|
513
|
+
if (placeholder === void 0) continue;
|
|
514
|
+
const paramValue = params[index];
|
|
515
|
+
resolvedURL = resolvedURL.replace(placeholder, encodeParamValue(paramValue));
|
|
516
|
+
}
|
|
517
|
+
return resolvedURL;
|
|
518
|
+
};
|
|
519
|
+
const getPathParamKey = (segment) => {
|
|
520
|
+
if (isColonPathParam(segment)) return segment.slice(1);
|
|
521
|
+
if (isBracePathParam(segment)) return segment.slice(1, -1);
|
|
522
|
+
return null;
|
|
523
|
+
};
|
|
524
|
+
const handleObjectParams = (url, params) => {
|
|
525
|
+
const urlSegments = url.split("/");
|
|
526
|
+
for (const segmentIndex of urlSegments.keys()) {
|
|
527
|
+
const segment = urlSegments[segmentIndex];
|
|
528
|
+
if (segment === void 0) continue;
|
|
529
|
+
const paramKey = getPathParamKey(segment);
|
|
530
|
+
if (paramKey === null || !Object.hasOwn(params, paramKey)) continue;
|
|
531
|
+
const paramValue = params[paramKey];
|
|
532
|
+
urlSegments[segmentIndex] = encodeParamValue(paramValue);
|
|
533
|
+
}
|
|
534
|
+
return urlSegments.join("/");
|
|
535
|
+
};
|
|
536
|
+
const mergeUrlWithParams = (url, params) => {
|
|
537
|
+
if (!params) return url;
|
|
538
|
+
return isArray(params) ? handleArrayParams(url, params) : handleObjectParams(url, params);
|
|
539
|
+
};
|
|
540
|
+
const splitURLFragment = (url) => {
|
|
541
|
+
const fragmentIndex = url.indexOf("#");
|
|
542
|
+
if (fragmentIndex === -1) return [url, ""];
|
|
543
|
+
return [url.slice(0, fragmentIndex), url.slice(fragmentIndex)];
|
|
544
|
+
};
|
|
545
|
+
const mergeUrlWithQuery = (url, query) => {
|
|
546
|
+
if (!query) return url;
|
|
547
|
+
const incomingSearchParams = toSearchParams(query);
|
|
548
|
+
if (incomingSearchParams.size === 0) return url;
|
|
549
|
+
const [urlWithoutFragment, fragment] = splitURLFragment(url);
|
|
550
|
+
if (!urlWithoutFragment.includes("?")) return `${urlWithoutFragment}?${incomingSearchParams}${fragment}`;
|
|
551
|
+
if (urlWithoutFragment.endsWith("?")) return `${urlWithoutFragment}${incomingSearchParams}${fragment}`;
|
|
552
|
+
const [mainUrl, existingQueryString] = urlWithoutFragment.split("?");
|
|
553
|
+
const searchParams = new URLSearchParams(existingQueryString);
|
|
554
|
+
for (const key of incomingSearchParams.keys()) searchParams.delete(key);
|
|
555
|
+
for (const entry of incomingSearchParams) searchParams.append(...entry);
|
|
556
|
+
return `${mainUrl}?${searchParams}${fragment}`;
|
|
557
|
+
};
|
|
558
|
+
/**
|
|
559
|
+
* @description Extracts the HTTP method from method-prefixed route patterns.
|
|
560
|
+
*
|
|
561
|
+
* Analyzes URLs that start with method modifiers (e.g., "@get/", "@post/") and extracts
|
|
562
|
+
* the HTTP method for use in API requests. This enables method specification directly
|
|
563
|
+
* in route definitions.
|
|
564
|
+
*
|
|
565
|
+
* @param initURL - The URL string to analyze for method modifiers
|
|
566
|
+
* @returns The extracted HTTP method (lowercase) if found, otherwise undefined
|
|
567
|
+
*
|
|
568
|
+
* @example
|
|
569
|
+
* ```typescript
|
|
570
|
+
* extractMethodFromURL("@get/users"); // Returns: "get"
|
|
571
|
+
* extractMethodFromURL("@post/users"); // Returns: "post"
|
|
572
|
+
* ```
|
|
573
|
+
*/
|
|
574
|
+
const extractMethodFromURL = (initURL) => {
|
|
575
|
+
if (!initURL?.startsWith("@")) return;
|
|
576
|
+
const methodFromURL = routeKeyMethods.find((method) => initURL.startsWith(`@${method}/`));
|
|
577
|
+
if (!methodFromURL) return;
|
|
578
|
+
return methodFromURL;
|
|
579
|
+
};
|
|
580
|
+
const isAbsoluteHTTPURL = (value) => {
|
|
581
|
+
return value.startsWith("http://") || value.startsWith("https://");
|
|
582
|
+
};
|
|
583
|
+
const normalizeURL = (initURL, options = {}) => {
|
|
584
|
+
const { retainLeadingSlashForRelativeURLs = true } = options;
|
|
585
|
+
const methodFromURL = extractMethodFromURL(initURL);
|
|
586
|
+
if (!methodFromURL) return initURL;
|
|
587
|
+
const initURLWithoutMethod = initURL.replace(`@${methodFromURL}/`, "");
|
|
588
|
+
return retainLeadingSlashForRelativeURLs && !isAbsoluteHTTPURL(initURLWithoutMethod) ? `/${initURLWithoutMethod}` : initURLWithoutMethod;
|
|
589
|
+
};
|
|
590
|
+
const getFullURL = (initURL, baseURL) => {
|
|
591
|
+
if (!baseURL || isAbsoluteHTTPURL(initURL)) return initURL;
|
|
592
|
+
const normalizedBaseURL = baseURL.replace(/\/+$/, "");
|
|
593
|
+
const normalizedInitURL = initURL.replace(/^\/+/, "");
|
|
594
|
+
return normalizedInitURL ? `${normalizedBaseURL}/${normalizedInitURL}` : normalizedBaseURL;
|
|
595
|
+
};
|
|
596
|
+
const getFullAndNormalizedURL = (options) => {
|
|
597
|
+
const { baseURL, debugMode, initURL, params, query } = options;
|
|
598
|
+
const normalizedInitURL = normalizeURL(initURL);
|
|
599
|
+
const fullURL = getFullURL(mergeUrlWithQuery(mergeUrlWithParams(normalizedInitURL, params), query), baseURL);
|
|
600
|
+
if ((debugMode ?? extraOptionDefaults.debugMode) && !isAbsoluteHTTPURL(fullURL) && !URL.canParse(fullURL)) console.error(`Relative URL '${fullURL}' may fail during SSR. Set an absolute 'baseURL' for server-side requests.`);
|
|
601
|
+
return {
|
|
602
|
+
fullURL,
|
|
603
|
+
normalizedInitURL
|
|
604
|
+
};
|
|
605
|
+
};
|
|
606
|
+
//#endregion
|
|
571
607
|
//#region src/utils/common.ts
|
|
572
608
|
const omitKeys = (initialObject, keysToOmit) => {
|
|
573
609
|
const updatedObject = {};
|
|
@@ -582,7 +618,8 @@ const pickKeys = (initialObject, keysToPick) => {
|
|
|
582
618
|
const splitConfig = (config) => [pickKeys(config, fetchSpecificKeys), omitKeys(config, fetchSpecificKeys)];
|
|
583
619
|
const getResolvedHeaders = (options) => {
|
|
584
620
|
const { baseHeaders, headers } = options;
|
|
585
|
-
|
|
621
|
+
const resolvedHeaders = isFunction(headers) ? headers({ baseHeaders: objectifyHeaders(baseHeaders) }) : headers ?? baseHeaders;
|
|
622
|
+
return objectifyHeaders(resolvedHeaders);
|
|
586
623
|
};
|
|
587
624
|
const detectContentTypeHeader = (body) => {
|
|
588
625
|
if (isQueryString(body)) return { "Content-Type": "application/x-www-form-urlencoded" };
|
|
@@ -594,21 +631,24 @@ const detectContentTypeHeader = (body) => {
|
|
|
594
631
|
};
|
|
595
632
|
const getHeaders = async (options) => {
|
|
596
633
|
const { auth, body, resolvedHeaders } = options;
|
|
597
|
-
const authHeaderObject = await getAuthHeader(auth);
|
|
598
634
|
const resolvedHeadersObject = objectifyHeaders(resolvedHeaders);
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
contentTypeHeader && Object.assign(resolvedHeadersObject, contentTypeHeader);
|
|
602
|
-
}
|
|
603
|
-
return {
|
|
604
|
-
...authHeaderObject,
|
|
635
|
+
const headersObject = {
|
|
636
|
+
...await getAuthHeader(auth),
|
|
605
637
|
...resolvedHeadersObject
|
|
606
638
|
};
|
|
639
|
+
if (!new Headers(headersObject).has("Content-Type")) {
|
|
640
|
+
const contentTypeHeader = detectContentTypeHeader(body);
|
|
641
|
+
contentTypeHeader && Object.assign(headersObject, contentTypeHeader);
|
|
642
|
+
}
|
|
643
|
+
return headersObject;
|
|
607
644
|
};
|
|
608
645
|
const getMethod = (ctx) => {
|
|
609
646
|
const { initURL, method } = ctx;
|
|
610
647
|
return method?.toUpperCase() ?? extractMethodFromURL(initURL)?.toUpperCase() ?? requestOptionDefaults.method;
|
|
611
648
|
};
|
|
649
|
+
const getMediaType = (contentType) => {
|
|
650
|
+
return contentType.split(";", 1)[0]?.trim().toLowerCase();
|
|
651
|
+
};
|
|
612
652
|
const getBody = (options) => {
|
|
613
653
|
const { body, bodySerializer, bodyTransformer, resolvedHeaders } = options;
|
|
614
654
|
const headers = new Headers(resolvedHeaders);
|
|
@@ -616,9 +656,10 @@ const getBody = (options) => {
|
|
|
616
656
|
body,
|
|
617
657
|
headers
|
|
618
658
|
});
|
|
619
|
-
const
|
|
620
|
-
|
|
621
|
-
if (
|
|
659
|
+
const contentTypeHeader = headers.get("content-type");
|
|
660
|
+
const existingMediaType = contentTypeHeader ? getMediaType(contentTypeHeader) : null;
|
|
661
|
+
if ((!existingMediaType || existingMediaType === "application/json") && isSerializableObject(body)) return (bodySerializer ?? extraOptionDefaults.bodySerializer)(body);
|
|
662
|
+
if (existingMediaType === "application/x-www-form-urlencoded" && isSerializableObject(body)) return new URLSearchParams(body).toString();
|
|
622
663
|
return body;
|
|
623
664
|
};
|
|
624
665
|
const getInitFetchImpl = (customFetchImpl) => {
|
|
@@ -662,15 +703,16 @@ const deterministicHashFn = (value) => {
|
|
|
662
703
|
const extraOptionDefaults = Object.freeze(defineEnum({
|
|
663
704
|
bodySerializer: JSON.stringify,
|
|
664
705
|
debugMode: true,
|
|
665
|
-
defaultHTTPErrorMessage: "Request failed unexpectedly",
|
|
666
706
|
dedupeCacheScope: "local",
|
|
707
|
+
dedupeCacheScopeKey: "default",
|
|
667
708
|
dedupeKey: (ctx) => `${ctx.options.fullURL}-${deterministicHashFn({
|
|
668
709
|
options: ctx.options,
|
|
669
710
|
request: ctx.request
|
|
670
711
|
})}`,
|
|
671
|
-
dedupeCacheScopeKey: "default",
|
|
672
712
|
dedupeStrategy: "cancel",
|
|
713
|
+
defaultHTTPErrorMessage: "Request failed unexpectedly",
|
|
673
714
|
hooksExecutionMode: "parallel",
|
|
715
|
+
respectRetryAfter: false,
|
|
674
716
|
responseParser: JSON.parse,
|
|
675
717
|
responseType: "json",
|
|
676
718
|
resultMode: "all",
|
|
@@ -684,6 +726,6 @@ const extraOptionDefaults = Object.freeze(defineEnum({
|
|
|
684
726
|
}));
|
|
685
727
|
const requestOptionDefaults = Object.freeze(defineEnum({ method: "GET" }));
|
|
686
728
|
//#endregion
|
|
687
|
-
export {
|
|
729
|
+
export { toSearchParams as A, fetchSpecificKeys as B, defineMainSchema as C, defineSchemaRoutes as D, defineSchemaConfig as E, ValidationError as F, fallBackRouteSchemaKey as I, isArray as L, handleConfigValidation as M, handleSchemaValidation as N, toFormData as O, HTTPError as P, isFunction as R, defineInstanceConfig as S, defineSchema as T, isJavascriptError as _, getBody as a, defineBaseConfig as b, getMethod as c, splitConfig as d, waitFor as f, isHTTPErrorInstance as g, isHTTPError as h, createTimeoutSignal as i, getCurrentRouteSchemaKeyAndMainInitURL as j, toQueryString as k, getResolvedHeaders as l, objectifyHeaders as m, requestOptionDefaults as n, getFetchImpl as o, getFullAndNormalizedURL as p, createCombinedSignal as r, getHeaders as s, extraOptionDefaults as t, omitKeys as u, isValidationError as v, definePlugin as w, defineFallbackRouteSchema as x, isValidationErrorInstance as y, isString as z };
|
|
688
730
|
|
|
689
|
-
//# sourceMappingURL=constants-
|
|
731
|
+
//# sourceMappingURL=constants-Cm0RTgJ0.js.map
|