@zayne-labs/callapi 1.11.0 → 1.11.2
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 +107 -103
- package/dist/esm/{common-CEcqiR7c.js → common-CNM4LjFu.js} +35 -32
- package/dist/esm/common-CNM4LjFu.js.map +1 -0
- package/dist/esm/{common-CPTdKchS.d.ts → common-DBLyu1c5.d.ts} +24 -17
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +49 -37
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils/index.d.ts +1 -1
- package/dist/esm/utils/index.js +1 -1
- package/package.json +4 -4
- package/dist/esm/common-CEcqiR7c.js.map +0 -1
|
@@ -16,6 +16,7 @@ type UnionToIntersection<TUnion> = (TUnion extends unknown ? (param: TUnion) =>
|
|
|
16
16
|
type UnmaskType<TValue> = {
|
|
17
17
|
_: TValue;
|
|
18
18
|
}["_"];
|
|
19
|
+
type RemovePrefix<TPrefix extends "dedupe" | "retry", TKey extends string> = TKey extends `${TPrefix}${infer TRest}` ? Uncapitalize<TRest> : TKey;
|
|
19
20
|
type Awaitable<TValue> = Promise<TValue> | TValue;
|
|
20
21
|
type CommonRequestHeaders = "Access-Control-Allow-Credentials" | "Access-Control-Allow-Headers" | "Access-Control-Allow-Methods" | "Access-Control-Allow-Origin" | "Access-Control-Expose-Headers" | "Access-Control-Max-Age" | "Age" | "Allow" | "Cache-Control" | "Clear-Site-Data" | "Content-Disposition" | "Content-Encoding" | "Content-Language" | "Content-Length" | "Content-Location" | "Content-Range" | "Content-Security-Policy-Report-Only" | "Content-Security-Policy" | "Cookie" | "Cross-Origin-Embedder-Policy" | "Cross-Origin-Opener-Policy" | "Cross-Origin-Resource-Policy" | "Date" | "ETag" | "Expires" | "Last-Modified" | "Location" | "Permissions-Policy" | "Pragma" | "Retry-After" | "Save-Data" | "Sec-CH-Prefers-Color-Scheme" | "Sec-CH-Prefers-Reduced-Motion" | "Sec-CH-UA-Arch" | "Sec-CH-UA-Bitness" | "Sec-CH-UA-Form-Factor" | "Sec-CH-UA-Full-Version-List" | "Sec-CH-UA-Full-Version" | "Sec-CH-UA-Mobile" | "Sec-CH-UA-Model" | "Sec-CH-UA-Platform-Version" | "Sec-CH-UA-Platform" | "Sec-CH-UA-WoW64" | "Sec-CH-UA" | "Sec-Fetch-Dest" | "Sec-Fetch-Mode" | "Sec-Fetch-Site" | "Sec-Fetch-User" | "Sec-GPC" | "Server-Timing" | "Server" | "Service-Worker-Navigation-Preload" | "Set-Cookie" | "Strict-Transport-Security" | "Timing-Allow-Origin" | "Trailer" | "Transfer-Encoding" | "Upgrade" | "Vary" | "Warning" | "WWW-Authenticate" | "X-Content-Type-Options" | "X-DNS-Prefetch-Control" | "X-Frame-Options" | "X-Permitted-Cross-Domain-Policies" | "X-Powered-By" | "X-Robots-Tag" | "X-XSS-Protection" | AnyString;
|
|
21
22
|
type CommonAuthorizationHeaders = `${"Basic" | "Bearer" | "Token"} ${string}`;
|
|
@@ -61,7 +62,7 @@ type CustomAuth = {
|
|
|
61
62
|
type Auth = PossibleAuthValueOrGetter | BearerOrTokenAuth | BasicAuth | CustomAuth;
|
|
62
63
|
//#endregion
|
|
63
64
|
//#region src/constants/common.d.ts
|
|
64
|
-
declare const fetchSpecificKeys: (keyof RequestInit | "duplex")[];
|
|
65
|
+
declare const fetchSpecificKeys: readonly (keyof RequestInit | "duplex")[];
|
|
65
66
|
//#endregion
|
|
66
67
|
//#region src/types/standard-schema.d.ts
|
|
67
68
|
/**
|
|
@@ -356,7 +357,7 @@ interface CallApiSchema {
|
|
|
356
357
|
*/
|
|
357
358
|
query?: StandardSchemaV1<Query | undefined> | ((query: Query) => Awaitable<Query | undefined>);
|
|
358
359
|
}
|
|
359
|
-
declare const routeKeyMethods: ["delete", "get", "patch", "post", "put"];
|
|
360
|
+
declare const routeKeyMethods: readonly ["delete", "get", "patch", "post", "put"];
|
|
360
361
|
type RouteKeyMethods = (typeof routeKeyMethods)[number];
|
|
361
362
|
type RouteKeyMethodsURLUnion = `@${RouteKeyMethods}/`;
|
|
362
363
|
type BaseCallApiSchemaRoutes = Partial<Record<AnyString | RouteKeyMethodsURLUnion, CallApiSchema>>;
|
|
@@ -423,9 +424,9 @@ interface Middlewares {
|
|
|
423
424
|
/**
|
|
424
425
|
* Wraps the fetch implementation to intercept requests at the network layer.
|
|
425
426
|
*
|
|
426
|
-
* Takes the current fetch function and returns a new
|
|
427
|
-
* add logging, handle offline mode, or short-circuit requests etc.
|
|
428
|
-
* compose in order: plugins → base config → per-request.
|
|
427
|
+
* Takes a context object containing the current fetch function and returns a new fetch function.
|
|
428
|
+
* Use it to cache responses, add logging, handle offline mode, or short-circuit requests etc.
|
|
429
|
+
* Multiple middleware compose in order: plugins → base config → per-request.
|
|
429
430
|
*
|
|
430
431
|
* Unlike `customFetchImpl`, middleware can call through to the original fetch.
|
|
431
432
|
*
|
|
@@ -433,25 +434,27 @@ interface Middlewares {
|
|
|
433
434
|
* ```ts
|
|
434
435
|
* // Cache responses
|
|
435
436
|
* const cache = new Map();
|
|
436
|
-
* fetchMiddleware: (
|
|
437
|
+
* fetchMiddleware: (ctx) => async (input, init) => {
|
|
437
438
|
* const key = input.toString();
|
|
438
439
|
* if (cache.has(key)) return cache.get(key).clone();
|
|
439
440
|
*
|
|
440
|
-
* const response = await fetchImpl(input, init);
|
|
441
|
+
* const response = await ctx.fetchImpl(input, init);
|
|
441
442
|
* cache.set(key, response.clone());
|
|
442
443
|
* return response;
|
|
443
444
|
* }
|
|
444
445
|
*
|
|
445
446
|
* // Handle offline
|
|
446
|
-
* fetchMiddleware: (
|
|
447
|
+
* fetchMiddleware: (ctx) => async (input, init) => {
|
|
447
448
|
* if (!navigator.onLine) {
|
|
448
449
|
* return new Response('{"error": "offline"}', { status: 503 });
|
|
449
450
|
* }
|
|
450
|
-
* return fetchImpl(input, init);
|
|
451
|
+
* return ctx.fetchImpl(input, init);
|
|
451
452
|
* }
|
|
452
453
|
* ```
|
|
453
454
|
*/
|
|
454
|
-
fetchMiddleware?: (
|
|
455
|
+
fetchMiddleware?: (context: RequestContext & {
|
|
456
|
+
fetchImpl: FetchImpl;
|
|
457
|
+
}) => FetchImpl;
|
|
455
458
|
}
|
|
456
459
|
//#endregion
|
|
457
460
|
//#region src/plugins.d.ts
|
|
@@ -862,7 +865,13 @@ type ResponseStreamContext = UnmaskType<RequestContext & {
|
|
|
862
865
|
//#endregion
|
|
863
866
|
//#region src/dedupe.d.ts
|
|
864
867
|
type DedupeStrategyUnion = UnmaskType<"cancel" | "defer" | "none">;
|
|
868
|
+
type DedupeOptionKeys = Exclude<keyof DedupeOptions, "dedupe">;
|
|
869
|
+
type InnerDedupeOptions = { [Key in DedupeOptionKeys as RemovePrefix<"dedupe", Key>]?: DedupeOptions[Key] };
|
|
865
870
|
type DedupeOptions = {
|
|
871
|
+
/**
|
|
872
|
+
* All dedupe options in a single object instead of separate properties
|
|
873
|
+
*/
|
|
874
|
+
dedupe?: InnerDedupeOptions;
|
|
866
875
|
/**
|
|
867
876
|
* Controls the scope of request deduplication caching.
|
|
868
877
|
*
|
|
@@ -1071,7 +1080,7 @@ type DedupeOptions = {
|
|
|
1071
1080
|
};
|
|
1072
1081
|
//#endregion
|
|
1073
1082
|
//#region src/retry.d.ts
|
|
1074
|
-
declare const defaultRetryStatusCodesLookup: () => {
|
|
1083
|
+
declare const defaultRetryStatusCodesLookup: () => Readonly<{
|
|
1075
1084
|
408: "Request Timeout";
|
|
1076
1085
|
409: "Conflict";
|
|
1077
1086
|
425: "Too Early";
|
|
@@ -1080,13 +1089,11 @@ declare const defaultRetryStatusCodesLookup: () => {
|
|
|
1080
1089
|
502: "Bad Gateway";
|
|
1081
1090
|
503: "Service Unavailable";
|
|
1082
1091
|
504: "Gateway Timeout";
|
|
1083
|
-
}
|
|
1092
|
+
}>;
|
|
1084
1093
|
type RetryStatusCodes = UnmaskType<AnyNumber | keyof ReturnType<typeof defaultRetryStatusCodesLookup>>;
|
|
1085
1094
|
type RetryCondition<TErrorData> = (context: ErrorContext<TErrorData>) => Awaitable<boolean>;
|
|
1086
|
-
type
|
|
1087
|
-
type InnerRetryOptions<TErrorData> = { [Key in
|
|
1088
|
-
attempts: NonNullable<RetryOptions<TErrorData>["retryAttempts"]>;
|
|
1089
|
-
};
|
|
1095
|
+
type RetryOptionKeys<TErrorData> = Exclude<keyof RetryOptions<TErrorData>, "~retryAttemptCount" | "retry">;
|
|
1096
|
+
type InnerRetryOptions<TErrorData> = { [Key in RetryOptionKeys<TErrorData> as RemovePrefix<"retry", Key>]?: RetryOptions<TErrorData>[Key] };
|
|
1090
1097
|
interface RetryOptions<TErrorData> {
|
|
1091
1098
|
/**
|
|
1092
1099
|
* Keeps track of the number of times the request has already been retried
|
|
@@ -1789,4 +1796,4 @@ type CallApiParameters<TData = DefaultDataType, TErrorData = DefaultDataType, TR
|
|
|
1789
1796
|
type CallApiResult<TData, TErrorData, TResultMode extends ResultModeUnion, TThrowOnError extends ThrowOnErrorUnion, TResponseType extends ResponseTypeUnion> = Promise<GetCallApiResult<TData, TErrorData, TResultMode, TThrowOnError, TResponseType>>;
|
|
1790
1797
|
//#endregion
|
|
1791
1798
|
export { AnyFunction, AnyString, ApplyStrictConfig, ApplyURLBasedConfig, BaseCallApiConfig, BaseCallApiExtraOptions, BaseCallApiSchemaAndConfig, BaseCallApiSchemaRoutes, CallApiConfig, CallApiExtraOptions, CallApiExtraOptionsForHooks, CallApiParameters, CallApiPlugin, CallApiRequestOptions, CallApiRequestOptionsForHooks, CallApiResult, CallApiResultErrorVariant, CallApiResultSuccessVariant, CallApiSchema, CallApiSchemaConfig, DedupeOptions, DefaultDataType, DefaultPluginArray, DefaultThrowOnError, ErrorContext, GetCurrentRouteSchema, GetCurrentRouteSchemaKey, GetResponseType, HTTPError, Hooks, HooksOrHooksArray, InferInitURL, InferParamsFromRoute, InferSchemaOutputResult, PluginExtraOptions, PluginHooks, PluginHooksWithMoreOptions, PluginSetupContext, PossibleHTTPError, PossibleJavaScriptError, PossibleJavaScriptOrValidationError, PossibleValidationError, Register, RequestContext, RequestStreamContext, ResponseContext, ResponseErrorContext, ResponseStreamContext, ResponseTypeMap, ResponseTypeUnion, ResultModeUnion, RetryOptions, SuccessContext, ThrowOnErrorUnion, URLOptions, ValidationError, Writeable, fallBackRouteSchemaKey };
|
|
1792
|
-
//# sourceMappingURL=common-
|
|
1799
|
+
//# sourceMappingURL=common-DBLyu1c5.d.ts.map
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyFunction, AnyString, ApplyStrictConfig, ApplyURLBasedConfig, BaseCallApiConfig, BaseCallApiExtraOptions, BaseCallApiSchemaAndConfig, BaseCallApiSchemaRoutes, CallApiConfig, CallApiExtraOptions, CallApiExtraOptionsForHooks, CallApiParameters, CallApiPlugin, CallApiRequestOptions, CallApiRequestOptionsForHooks, CallApiResult, CallApiResultErrorVariant, CallApiResultSuccessVariant, CallApiSchema, CallApiSchemaConfig, DedupeOptions, DefaultDataType, DefaultPluginArray, DefaultThrowOnError, ErrorContext, GetCurrentRouteSchema, GetCurrentRouteSchemaKey, GetResponseType, HTTPError, Hooks, HooksOrHooksArray, InferInitURL, InferParamsFromRoute, InferSchemaOutputResult, PluginExtraOptions, PluginHooks, PluginHooksWithMoreOptions, PluginSetupContext, PossibleHTTPError, PossibleJavaScriptError, PossibleJavaScriptOrValidationError, PossibleValidationError, Register, RequestContext, RequestStreamContext, ResponseContext, ResponseErrorContext, ResponseStreamContext, ResponseTypeMap, ResponseTypeUnion, ResultModeUnion, RetryOptions, SuccessContext, ThrowOnErrorUnion, URLOptions, ValidationError, Writeable, fallBackRouteSchemaKey } from "./common-
|
|
1
|
+
import { AnyFunction, AnyString, ApplyStrictConfig, ApplyURLBasedConfig, BaseCallApiConfig, BaseCallApiExtraOptions, BaseCallApiSchemaAndConfig, BaseCallApiSchemaRoutes, CallApiConfig, CallApiExtraOptions, CallApiExtraOptionsForHooks, CallApiParameters, CallApiPlugin, CallApiRequestOptions, CallApiRequestOptionsForHooks, CallApiResult, CallApiResultErrorVariant, CallApiResultSuccessVariant, CallApiSchema, CallApiSchemaConfig, DedupeOptions, DefaultDataType, DefaultPluginArray, DefaultThrowOnError, ErrorContext, GetCurrentRouteSchema, GetCurrentRouteSchemaKey, GetResponseType, HTTPError, Hooks, HooksOrHooksArray, InferInitURL, InferParamsFromRoute, InferSchemaOutputResult, PluginExtraOptions, PluginHooks, PluginHooksWithMoreOptions, PluginSetupContext, PossibleHTTPError, PossibleJavaScriptError, PossibleJavaScriptOrValidationError, PossibleValidationError, Register, RequestContext, RequestStreamContext, ResponseContext, ResponseErrorContext, ResponseStreamContext, ResponseTypeMap, ResponseTypeUnion, ResultModeUnion, RetryOptions, SuccessContext, ThrowOnErrorUnion, URLOptions, ValidationError, Writeable, fallBackRouteSchemaKey } from "./common-DBLyu1c5.js";
|
|
2
2
|
|
|
3
3
|
//#region src/createFetchClient.d.ts
|
|
4
4
|
|
package/dist/esm/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HTTPError, ValidationError, createCombinedSignal, createTimeoutSignal, deterministicHashFn, extraOptionDefaults, fallBackRouteSchemaKey, getBody, getCurrentRouteSchemaKeyAndMainInitURL, getFetchImpl, getFullAndNormalizedURL, getHeaders, getMethod, handleConfigValidation, handleSchemaValidation, isArray, isBoolean, isFunction, isHTTPErrorInstance, isObject, isPlainObject, isReadableStream, isString, isValidationErrorInstance, splitBaseConfig, splitConfig, waitFor } from "./common-
|
|
1
|
+
import { HTTPError, ValidationError, createCombinedSignal, createTimeoutSignal, deterministicHashFn, extraOptionDefaults, fallBackRouteSchemaKey, getBody, getCurrentRouteSchemaKeyAndMainInitURL, getFetchImpl, getFullAndNormalizedURL, getHeaders, getMethod, handleConfigValidation, handleSchemaValidation, isArray, isBoolean, isFunction, isHTTPErrorInstance, isObject, isPlainObject, isReadableStream, isString, isValidationErrorInstance, splitBaseConfig, splitConfig, waitFor } from "./common-CNM4LjFu.js";
|
|
2
2
|
|
|
3
3
|
//#region src/result.ts
|
|
4
4
|
const getResponseType = (response, parser) => ({
|
|
@@ -20,14 +20,14 @@ const textTypes = new Set([
|
|
|
20
20
|
const JSON_REGEX = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
|
|
21
21
|
const detectResponseType = (response) => {
|
|
22
22
|
const initContentType = response.headers.get("content-type");
|
|
23
|
-
if (!initContentType) return extraOptionDefaults
|
|
23
|
+
if (!initContentType) return extraOptionDefaults.responseType;
|
|
24
24
|
const contentType = initContentType.split(";")[0] ?? "";
|
|
25
25
|
if (JSON_REGEX.test(contentType)) return "json";
|
|
26
26
|
if (textTypes.has(contentType) || contentType.startsWith("text/")) return "text";
|
|
27
27
|
return "blob";
|
|
28
28
|
};
|
|
29
29
|
const resolveResponseData = (response, responseType, parser) => {
|
|
30
|
-
const selectedParser = parser ?? extraOptionDefaults
|
|
30
|
+
const selectedParser = parser ?? extraOptionDefaults.responseParser;
|
|
31
31
|
const selectedResponseType = responseType ?? detectResponseType(response);
|
|
32
32
|
const RESPONSE_TYPE_LOOKUP = getResponseType(response, selectedParser);
|
|
33
33
|
if (!Object.hasOwn(RESPONSE_TYPE_LOOKUP, selectedResponseType)) throw new Error(`Invalid response type: ${responseType}`);
|
|
@@ -125,7 +125,7 @@ const getHookRegistriesAndKeys = () => {
|
|
|
125
125
|
hookRegistryKeys: Object.keys(hookRegistries)
|
|
126
126
|
};
|
|
127
127
|
};
|
|
128
|
-
const
|
|
128
|
+
const composeHooksFromArray = (hooksArray, hooksExecutionMode) => {
|
|
129
129
|
const composedHook = async (ctx) => {
|
|
130
130
|
switch (hooksExecutionMode) {
|
|
131
131
|
case "parallel":
|
|
@@ -265,19 +265,20 @@ const toStreamableResponse = async (context) => {
|
|
|
265
265
|
//#region src/dedupe.ts
|
|
266
266
|
const createDedupeStrategy = async (context) => {
|
|
267
267
|
const { $GlobalRequestInfoCache: $GlobalRequestInfoCache$1, $LocalRequestInfoCache, baseConfig, config, newFetchController, options: globalOptions, request: globalRequest } = context;
|
|
268
|
-
const dedupeStrategy = globalOptions.dedupeStrategy ?? extraOptionDefaults
|
|
268
|
+
const dedupeStrategy = globalOptions.dedupeStrategy ?? globalOptions.dedupe?.strategy ?? extraOptionDefaults.dedupeStrategy;
|
|
269
269
|
const resolvedDedupeStrategy = isFunction(dedupeStrategy) ? dedupeStrategy(context) : dedupeStrategy;
|
|
270
270
|
const getDedupeKey = () => {
|
|
271
271
|
if (!(resolvedDedupeStrategy === "cancel" || resolvedDedupeStrategy === "defer")) return null;
|
|
272
|
-
|
|
272
|
+
const dedupeKey$1 = globalOptions.dedupeKey ?? globalOptions.dedupe?.key;
|
|
273
|
+
if (dedupeKey$1) return isFunction(dedupeKey$1) ? dedupeKey$1(context) : dedupeKey$1;
|
|
273
274
|
return `${globalOptions.fullURL}-${deterministicHashFn({
|
|
274
275
|
options: globalOptions,
|
|
275
276
|
request: globalRequest
|
|
276
277
|
})}`;
|
|
277
278
|
};
|
|
278
279
|
const dedupeKey = getDedupeKey();
|
|
279
|
-
const dedupeCacheScope = globalOptions.dedupeCacheScope ?? extraOptionDefaults
|
|
280
|
-
const dedupeCacheScopeKey = globalOptions.dedupeCacheScopeKey ?? extraOptionDefaults
|
|
280
|
+
const dedupeCacheScope = globalOptions.dedupeCacheScope ?? globalOptions.dedupe?.cacheScope ?? extraOptionDefaults.dedupeCacheScope;
|
|
281
|
+
const dedupeCacheScopeKey = globalOptions.dedupeCacheScopeKey ?? globalOptions.dedupe?.cacheScopeKey ?? extraOptionDefaults.dedupeCacheScopeKey;
|
|
281
282
|
if (dedupeCacheScope === "global" && !$GlobalRequestInfoCache$1.has(dedupeCacheScopeKey)) $GlobalRequestInfoCache$1.set(dedupeCacheScopeKey, /* @__PURE__ */ new Map());
|
|
282
283
|
const $RequestInfoCache = dedupeCacheScope === "global" ? $GlobalRequestInfoCache$1.get(dedupeCacheScopeKey) : $LocalRequestInfoCache;
|
|
283
284
|
const $RequestInfoCacheOrNull = dedupeKey !== null ? $RequestInfoCache : null;
|
|
@@ -288,8 +289,8 @@ const createDedupeStrategy = async (context) => {
|
|
|
288
289
|
if (dedupeKey !== null) await waitFor(.1);
|
|
289
290
|
const prevRequestInfo = $RequestInfoCacheOrNull?.get(dedupeKey);
|
|
290
291
|
const getAbortErrorMessage = () => {
|
|
291
|
-
if (globalOptions.dedupeKey) return `Duplicate request detected - Aborted previous request with key '${dedupeKey}'
|
|
292
|
-
return `Duplicate request
|
|
292
|
+
if (globalOptions.dedupeKey) return `Duplicate request detected - Aborted previous request with key '${dedupeKey}'`;
|
|
293
|
+
return `Duplicate request aborted - Aborted previous request to '${globalOptions.fullURL}'`;
|
|
293
294
|
};
|
|
294
295
|
const handleRequestCancelStrategy = () => {
|
|
295
296
|
if (!(prevRequestInfo && resolvedDedupeStrategy === "cancel")) return;
|
|
@@ -339,12 +340,22 @@ const getMiddlewareRegistriesAndKeys = () => {
|
|
|
339
340
|
middlewareRegistryKeys: Object.keys(middlewareRegistries)
|
|
340
341
|
};
|
|
341
342
|
};
|
|
342
|
-
const
|
|
343
|
+
const composeMiddlewaresFromArray = (middlewareArray) => {
|
|
343
344
|
let composedMiddleware;
|
|
344
345
|
for (const currentMiddleware of middlewareArray) {
|
|
345
346
|
if (!currentMiddleware) continue;
|
|
346
347
|
const previousMiddleware = composedMiddleware;
|
|
347
|
-
|
|
348
|
+
if (!previousMiddleware) {
|
|
349
|
+
composedMiddleware = currentMiddleware;
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
composedMiddleware = (context) => {
|
|
353
|
+
const prevFetchImpl = previousMiddleware(context);
|
|
354
|
+
return currentMiddleware({
|
|
355
|
+
...context,
|
|
356
|
+
fetchImpl: prevFetchImpl
|
|
357
|
+
});
|
|
358
|
+
};
|
|
348
359
|
}
|
|
349
360
|
return composedMiddleware;
|
|
350
361
|
};
|
|
@@ -460,7 +471,7 @@ const setupHooksAndMiddlewares = (context) => {
|
|
|
460
471
|
if (hookRegistry.size === 0) continue;
|
|
461
472
|
const flattenedHookArray = [...hookRegistry].flat();
|
|
462
473
|
if (flattenedHookArray.length === 0) continue;
|
|
463
|
-
resolvedHooks[hookName] =
|
|
474
|
+
resolvedHooks[hookName] = composeHooksFromArray(flattenedHookArray, options.hooksExecutionMode ?? extraOptionDefaults.hooksExecutionMode);
|
|
464
475
|
}
|
|
465
476
|
return resolvedHooks;
|
|
466
477
|
};
|
|
@@ -470,7 +481,7 @@ const setupHooksAndMiddlewares = (context) => {
|
|
|
470
481
|
if (middlewareRegistry.size === 0) continue;
|
|
471
482
|
const middlewareArray = [...middlewareRegistry];
|
|
472
483
|
if (middlewareArray.length === 0) continue;
|
|
473
|
-
resolvedMiddlewares[middlewareName] =
|
|
484
|
+
resolvedMiddlewares[middlewareName] = composeMiddlewaresFromArray(middlewareArray);
|
|
474
485
|
}
|
|
475
486
|
return resolvedMiddlewares;
|
|
476
487
|
};
|
|
@@ -488,19 +499,19 @@ const setupHooksAndMiddlewares = (context) => {
|
|
|
488
499
|
//#region src/retry.ts
|
|
489
500
|
const getLinearDelay = (currentAttemptCount, options) => {
|
|
490
501
|
const retryDelay = options.retryDelay ?? options.retry?.delay;
|
|
491
|
-
return (isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay) ?? extraOptionDefaults
|
|
502
|
+
return (isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay) ?? extraOptionDefaults.retryDelay;
|
|
492
503
|
};
|
|
493
504
|
const getExponentialDelay = (currentAttemptCount, options) => {
|
|
494
|
-
const retryDelay = options.retryDelay ?? options.retry?.delay ?? extraOptionDefaults
|
|
505
|
+
const retryDelay = options.retryDelay ?? options.retry?.delay ?? extraOptionDefaults.retryDelay;
|
|
495
506
|
const resolvedRetryDelay = isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay;
|
|
496
|
-
const maxDelay = options.retryMaxDelay ?? options.retry?.maxDelay ?? extraOptionDefaults
|
|
507
|
+
const maxDelay = options.retryMaxDelay ?? options.retry?.maxDelay ?? extraOptionDefaults.retryMaxDelay;
|
|
497
508
|
const exponentialDelay = resolvedRetryDelay * 2 ** currentAttemptCount;
|
|
498
509
|
return Math.min(exponentialDelay, maxDelay);
|
|
499
510
|
};
|
|
500
511
|
const createRetryStrategy = (ctx) => {
|
|
501
512
|
const { options, request } = ctx;
|
|
502
513
|
const currentAttemptCount = options["~retryAttemptCount"] ?? 1;
|
|
503
|
-
const retryStrategy = options.retryStrategy ?? options.retry?.strategy ?? extraOptionDefaults
|
|
514
|
+
const retryStrategy = options.retryStrategy ?? options.retry?.strategy ?? extraOptionDefaults.retryStrategy;
|
|
504
515
|
const getDelay = () => {
|
|
505
516
|
switch (retryStrategy) {
|
|
506
517
|
case "exponential": return getExponentialDelay(currentAttemptCount, options);
|
|
@@ -510,13 +521,13 @@ const createRetryStrategy = (ctx) => {
|
|
|
510
521
|
};
|
|
511
522
|
const shouldAttemptRetry = async () => {
|
|
512
523
|
if (isBoolean(request.signal) && request.signal.aborted) return false;
|
|
513
|
-
const retryCondition = options.retryCondition ?? options.retry?.condition ?? extraOptionDefaults
|
|
514
|
-
const maximumRetryAttempts = options.retryAttempts ?? options.retry?.attempts ?? extraOptionDefaults
|
|
524
|
+
const retryCondition = options.retryCondition ?? options.retry?.condition ?? extraOptionDefaults.retryCondition;
|
|
525
|
+
const maximumRetryAttempts = options.retryAttempts ?? options.retry?.attempts ?? extraOptionDefaults.retryAttempts;
|
|
515
526
|
const customRetryCondition = await retryCondition(ctx);
|
|
516
527
|
if (!(currentAttemptCount <= maximumRetryAttempts && customRetryCondition)) return false;
|
|
517
|
-
const retryMethods = new Set(options.retryMethods ?? options.retry?.methods ?? extraOptionDefaults
|
|
528
|
+
const retryMethods = new Set(options.retryMethods ?? options.retry?.methods ?? extraOptionDefaults.retryMethods);
|
|
518
529
|
const includesMethod = isString(ctx.request.method) && retryMethods.size > 0 ? retryMethods.has(ctx.request.method) : true;
|
|
519
|
-
const retryStatusCodes = new Set(options.retryStatusCodes ?? options.retry?.statusCodes ?? extraOptionDefaults
|
|
530
|
+
const retryStatusCodes = new Set(options.retryStatusCodes ?? options.retry?.statusCodes ?? extraOptionDefaults.retryStatusCodes);
|
|
520
531
|
const includesStatusCodes = ctx.response != null && retryStatusCodes.size > 0 ? retryStatusCodes.has(ctx.response.status) : true;
|
|
521
532
|
return includesMethod && includesStatusCodes;
|
|
522
533
|
};
|
|
@@ -566,7 +577,7 @@ const createFetchClient = (initBaseConfig = {}) => {
|
|
|
566
577
|
params: resolvedOptions.params,
|
|
567
578
|
query: resolvedOptions.query
|
|
568
579
|
});
|
|
569
|
-
|
|
580
|
+
const options = {
|
|
570
581
|
...resolvedOptions,
|
|
571
582
|
...resolvedHooks,
|
|
572
583
|
...resolvedMiddlewares,
|
|
@@ -581,7 +592,7 @@ const createFetchClient = (initBaseConfig = {}) => {
|
|
|
581
592
|
initURL: resolvedInitURL,
|
|
582
593
|
method: resolvedRequestOptions.method
|
|
583
594
|
});
|
|
584
|
-
|
|
595
|
+
const request = {
|
|
585
596
|
...resolvedRequestOptions,
|
|
586
597
|
method: initMethod,
|
|
587
598
|
signal: combinedSignal
|
|
@@ -610,10 +621,7 @@ const createFetchClient = (initBaseConfig = {}) => {
|
|
|
610
621
|
options,
|
|
611
622
|
requestOptions: request
|
|
612
623
|
});
|
|
613
|
-
if (shouldApplySchemaOutput) options
|
|
614
|
-
...options,
|
|
615
|
-
...extraOptionsValidationResult
|
|
616
|
-
};
|
|
624
|
+
if (shouldApplySchemaOutput) Object.assign(options, extraOptionsValidationResult);
|
|
617
625
|
const validMethod = getMethod({
|
|
618
626
|
initURL: resolvedInitURL,
|
|
619
627
|
method: shouldApplySchemaOutput ? requestOptionsValidationResult?.method : request.method
|
|
@@ -628,20 +636,24 @@ const createFetchClient = (initBaseConfig = {}) => {
|
|
|
628
636
|
body: validBody,
|
|
629
637
|
headers: shouldApplySchemaOutput ? requestOptionsValidationResult?.headers : resolvedHeaders
|
|
630
638
|
});
|
|
631
|
-
request
|
|
632
|
-
...
|
|
633
|
-
...
|
|
634
|
-
...
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
await executeHooks(options.onRequestReady?.({
|
|
639
|
+
Object.assign(request, {
|
|
640
|
+
...validBody && { body: validBody },
|
|
641
|
+
...validHeaders && { headers: validHeaders },
|
|
642
|
+
...validMethod && { method: validMethod }
|
|
643
|
+
});
|
|
644
|
+
const readyRequestContext = {
|
|
638
645
|
baseConfig,
|
|
639
646
|
config,
|
|
640
647
|
options,
|
|
641
648
|
request
|
|
642
|
-
}
|
|
649
|
+
};
|
|
650
|
+
await executeHooks(options.onRequestReady?.(readyRequestContext));
|
|
643
651
|
const response = await handleRequestDeferStrategy({
|
|
644
|
-
fetchApi: getFetchImpl(
|
|
652
|
+
fetchApi: getFetchImpl({
|
|
653
|
+
customFetchImpl: options.customFetchImpl,
|
|
654
|
+
fetchMiddleware: options.fetchMiddleware,
|
|
655
|
+
requestContext: readyRequestContext
|
|
656
|
+
}),
|
|
645
657
|
options,
|
|
646
658
|
request
|
|
647
659
|
});
|