@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.
@@ -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 one. Use it to cache responses,
427
- * add logging, handle offline mode, or short-circuit requests etc. Multiple middleware
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: (fetchImpl) => async (input, init) => {
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: (fetchImpl) => async (input, init) => {
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?: (fetchImpl: FetchImpl) => FetchImpl;
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 InnerRetryKeys<TErrorData> = Exclude<keyof RetryOptions<TErrorData>, "~retryAttemptCount" | "retry">;
1087
- type InnerRetryOptions<TErrorData> = { [Key in InnerRetryKeys<TErrorData> as Key extends `retry${infer TRest}` ? Uncapitalize<TRest> extends "attempts" ? never : Uncapitalize<TRest> : Key]?: RetryOptions<TErrorData>[Key] } & {
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-CPTdKchS.d.ts.map
1799
+ //# sourceMappingURL=common-DBLyu1c5.d.ts.map
@@ -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-CPTdKchS.js";
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-CEcqiR7c.js";
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().responseType;
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().responseParser;
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 composeAllHooks = (hooksArray, hooksExecutionMode) => {
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().dedupeStrategy;
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
- if (globalOptions.dedupeKey) return isFunction(globalOptions.dedupeKey) ? globalOptions.dedupeKey(context) : globalOptions.dedupeKey;
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().dedupeCacheScope;
280
- const dedupeCacheScopeKey = globalOptions.dedupeCacheScopeKey ?? extraOptionDefaults().dedupeCacheScopeKey;
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}' as a new request was initiated`;
292
- return `Duplicate request detected - Aborted previous request to '${globalOptions.fullURL}' as a new request with identical options was initiated`;
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 composeAllMiddlewares = (middlewareArray) => {
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
- composedMiddleware = previousMiddleware ? (fetchImpl) => currentMiddleware(previousMiddleware(fetchImpl)) : currentMiddleware;
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] = composeAllHooks(flattenedHookArray, options.hooksExecutionMode ?? extraOptionDefaults().hooksExecutionMode);
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] = composeAllMiddlewares(middlewareArray);
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().retryDelay;
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().retryDelay;
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().retryMaxDelay;
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().retryStrategy;
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().retryCondition;
514
- const maximumRetryAttempts = options.retryAttempts ?? options.retry?.attempts ?? extraOptionDefaults().retryAttempts;
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().retryMethods);
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().retryStatusCodes);
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
- let options = {
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
- let request = {
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
- ...request,
633
- ...Boolean(validBody) && { body: validBody },
634
- ...Boolean(validHeaders) && { headers: validHeaders },
635
- ...Boolean(validMethod) && { method: validMethod }
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(options.customFetchImpl, options.fetchMiddleware),
652
+ fetchApi: getFetchImpl({
653
+ customFetchImpl: options.customFetchImpl,
654
+ fetchMiddleware: options.fetchMiddleware,
655
+ requestContext: readyRequestContext
656
+ }),
645
657
  options,
646
658
  request
647
659
  });