@zayne-labs/callapi 1.8.22 → 1.9.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/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { HTTPError, ValidationError, createCombinedSignal, createTimeoutSignal, dedupeDefaults, defineEnum, deterministicHashFn, getBody, getFetchImpl, getHeaders, hookDefaults, isArray, isFunction, isHTTPErrorInstance, isObject, isPlainObject, isReadableStream, isString, isValidationErrorInstance, requestOptionDefaults, responseDefaults, retryDefaults, splitBaseConfig, splitConfig, toQueryString, waitFor } from "./utils-DZe23qYR.js";
1
+ import { HTTPError, ValidationError, createCombinedSignal, createTimeoutSignal, defineEnum, deterministicHashFn, extraOptionDefaults, getBody, getFetchImpl, getHeaders, isArray, isFunction, isHTTPErrorInstance, isObject, isPlainObject, isReadableStream, isString, isValidationErrorInstance, requestOptionDefaults, splitBaseConfig, splitConfig, toQueryString, waitFor } from "./utils-DUbIqsYh.js";
2
2
 
3
3
  //#region src/result.ts
4
4
  const getResponseType = (response, parser) => ({
@@ -13,8 +13,8 @@ const getResponseType = (response, parser) => ({
13
13
  text: () => response.text()
14
14
  });
15
15
  const resolveResponseData = (response, responseType, parser) => {
16
- const selectedParser = parser ?? responseDefaults.responseParser;
17
- const selectedResponseType = responseType ?? responseDefaults.responseType;
16
+ const selectedParser = parser ?? extraOptionDefaults().responseParser;
17
+ const selectedResponseType = responseType ?? extraOptionDefaults().responseType;
18
18
  const RESPONSE_TYPE_LOOKUP = getResponseType(response, selectedParser);
19
19
  if (!Object.hasOwn(RESPONSE_TYPE_LOOKUP, selectedResponseType)) throw new Error(`Invalid response type: ${responseType}`);
20
20
  return RESPONSE_TYPE_LOOKUP[selectedResponseType]();
@@ -243,9 +243,10 @@ const toStreamableResponse = async (context) => {
243
243
  //#region src/dedupe.ts
244
244
  const createDedupeStrategy = async (context) => {
245
245
  const { $GlobalRequestInfoCache: $GlobalRequestInfoCache$1, $LocalRequestInfoCache, baseConfig, config, newFetchController, options: globalOptions, request: globalRequest } = context;
246
- const dedupeStrategy = globalOptions.dedupeStrategy ?? dedupeDefaults.dedupeStrategy;
246
+ const dedupeStrategy = globalOptions.dedupeStrategy ?? extraOptionDefaults().dedupeStrategy;
247
+ const resolvedDedupeStrategy = isFunction(dedupeStrategy) ? dedupeStrategy(context) : dedupeStrategy;
247
248
  const getDedupeKey = () => {
248
- const shouldHaveDedupeKey = dedupeStrategy === "cancel" || dedupeStrategy === "defer";
249
+ const shouldHaveDedupeKey = resolvedDedupeStrategy === "cancel" || resolvedDedupeStrategy === "defer";
249
250
  if (!shouldHaveDedupeKey) return null;
250
251
  if (globalOptions.dedupeKey) {
251
252
  const resolvedDedupeKey = isFunction(globalOptions.dedupeKey) ? globalOptions.dedupeKey(context) : globalOptions.dedupeKey;
@@ -257,8 +258,8 @@ const createDedupeStrategy = async (context) => {
257
258
  })}`;
258
259
  };
259
260
  const dedupeKey = getDedupeKey();
260
- const dedupeCacheScope = globalOptions.dedupeCacheScope ?? dedupeDefaults.dedupeCacheScope;
261
- const dedupeCacheScopeKey = globalOptions.dedupeCacheScopeKey ?? dedupeDefaults.dedupeCacheScopeKey;
261
+ const dedupeCacheScope = globalOptions.dedupeCacheScope ?? extraOptionDefaults().dedupeCacheScope;
262
+ const dedupeCacheScopeKey = globalOptions.dedupeCacheScopeKey ?? extraOptionDefaults().dedupeCacheScopeKey;
262
263
  if (dedupeCacheScope === "global" && !$GlobalRequestInfoCache$1.has(dedupeCacheScopeKey)) $GlobalRequestInfoCache$1.set(dedupeCacheScopeKey, /* @__PURE__ */ new Map());
263
264
  const $RequestInfoCache = dedupeCacheScope === "global" ? $GlobalRequestInfoCache$1.get(dedupeCacheScopeKey) : $LocalRequestInfoCache;
264
265
  const $RequestInfoCacheOrNull = dedupeKey !== null ? $RequestInfoCache : null;
@@ -269,11 +270,11 @@ const createDedupeStrategy = async (context) => {
269
270
  if (dedupeKey !== null) await waitFor(.1);
270
271
  const prevRequestInfo = $RequestInfoCacheOrNull?.get(dedupeKey);
271
272
  const getAbortErrorMessage = () => {
272
- if (dedupeKey) return `Duplicate request detected - Aborted previous request with key '${dedupeKey}' as a new request was initiated`;
273
+ if (globalOptions.dedupeKey) return `Duplicate request detected - Aborted previous request with key '${dedupeKey}' as a new request was initiated`;
273
274
  return `Duplicate request detected - Aborted previous request to '${globalOptions.fullURL}' as a new request with identical options was initiated`;
274
275
  };
275
276
  const handleRequestCancelStrategy = () => {
276
- const shouldCancelRequest = prevRequestInfo && dedupeStrategy === "cancel";
277
+ const shouldCancelRequest = prevRequestInfo && resolvedDedupeStrategy === "cancel";
277
278
  if (!shouldCancelRequest) return;
278
279
  const message = getAbortErrorMessage();
279
280
  const reason = new DOMException(message, "AbortError");
@@ -283,7 +284,7 @@ const createDedupeStrategy = async (context) => {
283
284
  const handleRequestDeferStrategy = async (deferContext) => {
284
285
  const { options: localOptions, request: localRequest } = deferContext;
285
286
  const fetchApi = getFetchImpl(localOptions.customFetchImpl);
286
- const shouldUsePromiseFromCache = prevRequestInfo && dedupeStrategy === "defer";
287
+ const shouldUsePromiseFromCache = prevRequestInfo && resolvedDedupeStrategy === "defer";
287
288
  const streamableContext = {
288
289
  baseConfig,
289
290
  config,
@@ -306,11 +307,11 @@ const createDedupeStrategy = async (context) => {
306
307
  $RequestInfoCacheOrNull?.delete(dedupeKey);
307
308
  };
308
309
  return {
309
- dedupeStrategy,
310
310
  getAbortErrorMessage,
311
311
  handleRequestCancelStrategy,
312
312
  handleRequestDeferStrategy,
313
- removeDedupeKeyFromCache
313
+ removeDedupeKeyFromCache,
314
+ resolvedDedupeStrategy
314
315
  };
315
316
  };
316
317
 
@@ -492,7 +493,7 @@ const initializePlugins = async (context) => {
492
493
  clonedHookRegistries[key].add(pluginHook);
493
494
  }
494
495
  };
495
- const hookRegistrationOrder = options.hooksRegistrationOrder ?? hookDefaults.hooksRegistrationOrder;
496
+ const hookRegistrationOrder = options.hooksRegistrationOrder ?? extraOptionDefaults().hooksRegistrationOrder;
496
497
  if (hookRegistrationOrder === "mainFirst") addMainHooks();
497
498
  const { currentRouteSchemaKey, mainInitURL } = getCurrentRouteSchemaKeyAndMainInitURL({
498
499
  baseExtraOptions: baseConfig,
@@ -503,9 +504,9 @@ const initializePlugins = async (context) => {
503
504
  let resolvedInitURL = mainInitURL;
504
505
  let resolvedOptions = options;
505
506
  let resolvedRequestOptions = request;
506
- const executePluginInit = async (pluginInit) => {
507
- if (!pluginInit) return;
508
- const initResult = await pluginInit({
507
+ const executePluginSetupFn = async (pluginSetupFn) => {
508
+ if (!pluginSetupFn) return;
509
+ const initResult = await pluginSetupFn({
509
510
  baseConfig,
510
511
  config,
511
512
  initURL,
@@ -531,7 +532,7 @@ const initializePlugins = async (context) => {
531
532
  options
532
533
  });
533
534
  for (const plugin of resolvedPlugins) {
534
- await executePluginInit(plugin.init);
535
+ await executePluginSetupFn(plugin.setup);
535
536
  if (!plugin.hooks) continue;
536
537
  addPluginHooks(plugin.hooks);
537
538
  }
@@ -541,7 +542,7 @@ const initializePlugins = async (context) => {
541
542
  if (hookRegistry.size === 0) continue;
542
543
  const flattenedHookArray = [...hookRegistry].flat();
543
544
  if (flattenedHookArray.length === 0) continue;
544
- const hooksExecutionMode = options.hooksExecutionMode ?? hookDefaults.hooksExecutionMode;
545
+ const hooksExecutionMode = options.hooksExecutionMode ?? extraOptionDefaults().hooksExecutionMode;
545
546
  const composedHook = composeAllHooks(flattenedHookArray, hooksExecutionMode);
546
547
  resolvedHooks[key] = composedHook;
547
548
  }
@@ -558,20 +559,20 @@ const initializePlugins = async (context) => {
558
559
  //#region src/retry.ts
559
560
  const getLinearDelay = (currentAttemptCount, options) => {
560
561
  const retryDelay = options.retryDelay ?? options.retry?.delay;
561
- const resolveRetryDelay = (isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay) ?? retryDefaults.delay;
562
+ const resolveRetryDelay = (isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay) ?? extraOptionDefaults().retryDelay;
562
563
  return resolveRetryDelay;
563
564
  };
564
565
  const getExponentialDelay = (currentAttemptCount, options) => {
565
- const retryDelay = options.retryDelay ?? options.retry?.delay ?? retryDefaults.delay;
566
+ const retryDelay = options.retryDelay ?? options.retry?.delay ?? extraOptionDefaults().retryDelay;
566
567
  const resolvedRetryDelay = isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay;
567
- const maxDelay = options.retryMaxDelay ?? options.retry?.maxDelay ?? retryDefaults.maxDelay;
568
+ const maxDelay = options.retryMaxDelay ?? options.retry?.maxDelay ?? extraOptionDefaults().retryMaxDelay;
568
569
  const exponentialDelay = resolvedRetryDelay * 2 ** currentAttemptCount;
569
570
  return Math.min(exponentialDelay, maxDelay);
570
571
  };
571
572
  const createRetryStrategy = (ctx) => {
572
573
  const { options } = ctx;
573
574
  const currentAttemptCount = options["~retryAttemptCount"] ?? 1;
574
- const retryStrategy = options.retryStrategy ?? options.retry?.strategy ?? retryDefaults.strategy;
575
+ const retryStrategy = options.retryStrategy ?? options.retry?.strategy ?? extraOptionDefaults().retryStrategy;
575
576
  const getDelay = () => {
576
577
  switch (retryStrategy) {
577
578
  case "exponential": return getExponentialDelay(currentAttemptCount, options);
@@ -580,14 +581,13 @@ const createRetryStrategy = (ctx) => {
580
581
  }
581
582
  };
582
583
  const shouldAttemptRetry = async () => {
583
- const retryCondition = options.retryCondition ?? options.retry?.condition ?? retryDefaults.condition;
584
- const maximumRetryAttempts = options.retryAttempts ?? options.retry?.attempts ?? retryDefaults.attempts;
584
+ const retryCondition = options.retryCondition ?? options.retry?.condition ?? extraOptionDefaults().retryCondition;
585
+ const maximumRetryAttempts = options.retryAttempts ?? options.retry?.attempts ?? extraOptionDefaults().retryAttempts;
585
586
  const customRetryCondition = await retryCondition(ctx);
586
587
  const baseShouldRetry = maximumRetryAttempts >= currentAttemptCount && customRetryCondition;
587
588
  if (!baseShouldRetry) return false;
588
- const retryMethods = new Set(options.retryMethods ?? options.retry?.methods ?? retryDefaults.methods);
589
- const resolvedMethod = ctx.request.method ?? requestOptionDefaults.method;
590
- const includesMethod = retryMethods.has(resolvedMethod);
589
+ const retryMethods = new Set(options.retryMethods ?? options.retry?.methods ?? extraOptionDefaults().retryMethods);
590
+ const includesMethod = retryMethods.has(ctx.request.method);
591
591
  const retryStatusCodes = new Set(options.retryStatusCodes ?? options.retry?.statusCodes ?? []);
592
592
  const includesStatusCodes = Boolean(ctx.response?.status) && (retryStatusCodes.size > 0 ? retryStatusCodes.has(ctx.response.status) : true);
593
593
  const shouldRetry = includesMethod && includesStatusCodes;
@@ -603,19 +603,28 @@ const createRetryStrategy = (ctx) => {
603
603
  //#endregion
604
604
  //#region src/url.ts
605
605
  const slash = "/";
606
- const column = ":";
606
+ const colon = ":";
607
+ const openBrace = "{";
608
+ const closeBrace = "}";
607
609
  const mergeUrlWithParams = (url, params) => {
608
610
  if (!params) return url;
609
611
  let newUrl = url;
610
612
  if (isArray(params)) {
611
- const matchedParamArray = newUrl.split(slash).filter((param) => param.startsWith(column));
612
- for (const [index, matchedParam] of matchedParamArray.entries()) {
613
+ const urlParts = newUrl.split(slash);
614
+ const matchedParamsArray = urlParts.filter((part) => part.startsWith(colon) || part.startsWith(openBrace) && part.endsWith(closeBrace));
615
+ for (const [index, matchedParam] of matchedParamsArray.entries()) {
613
616
  const realParam = params[index];
614
617
  newUrl = newUrl.replace(matchedParam, realParam);
615
618
  }
616
619
  return newUrl;
617
620
  }
618
- for (const [key, value] of Object.entries(params)) newUrl = newUrl.replace(`${column}${key}`, String(value));
621
+ for (const [key, value] of Object.entries(params)) {
622
+ const stringValue = String(value);
623
+ const colonPattern = `${colon}${key}`;
624
+ const bracePattern = `${openBrace}${key}${closeBrace}`;
625
+ if (newUrl.includes(colonPattern)) newUrl = newUrl.replace(colonPattern, stringValue);
626
+ else if (newUrl.includes(bracePattern)) newUrl = newUrl.replace(bracePattern, stringValue);
627
+ }
619
628
  return newUrl;
620
629
  };
621
630
  const questionMark = "?";
@@ -666,10 +675,9 @@ const extractMethodFromURL = (initURL) => {
666
675
  if (!method || !routeKeyMethods.includes(method)) return;
667
676
  return method;
668
677
  };
669
- const getMethod = (options) => {
670
- const { initURL, method, schemaConfig } = options;
671
- if (schemaConfig?.requireMethodProvision === true) return method?.toUpperCase() ?? requestOptionDefaults.method;
672
- return method?.toUpperCase() ?? extractMethodFromURL(initURL)?.toUpperCase() ?? requestOptionDefaults.method;
678
+ const getMethod = (ctx) => {
679
+ const { initURL, method } = ctx;
680
+ return method?.toUpperCase() ?? extractMethodFromURL(initURL)?.toUpperCase() ?? requestOptionDefaults().method;
673
681
  };
674
682
  const normalizeURL = (initURL) => {
675
683
  const methodFromURL = extractMethodFromURL(initURL);
@@ -682,8 +690,8 @@ const getFullAndNormalizedURL = (options) => {
682
690
  const normalizedInitURL = normalizeURL(initURL);
683
691
  const urlWithMergedParams = mergeUrlWithParams(normalizedInitURL, params);
684
692
  const urlWithMergedQueryAndParams = mergeUrlWithQuery(urlWithMergedParams, query);
685
- const shouldNotPrependBaseURL = urlWithMergedQueryAndParams.startsWith("http") || !baseURL;
686
- const fullURL = shouldNotPrependBaseURL ? urlWithMergedQueryAndParams : `${baseURL}${urlWithMergedQueryAndParams}`;
693
+ const shouldPrependBaseURL = !urlWithMergedQueryAndParams.startsWith("http") && baseURL;
694
+ const fullURL = shouldPrependBaseURL ? `${baseURL}${urlWithMergedQueryAndParams}` : urlWithMergedQueryAndParams;
687
695
  return {
688
696
  fullURL,
689
697
  normalizedInitURL
@@ -744,7 +752,7 @@ const createFetchClient = (initBaseConfig = {}) => {
744
752
  ...resolvedRequestOptions,
745
753
  signal: combinedSignal
746
754
  };
747
- const { dedupeStrategy, getAbortErrorMessage, handleRequestCancelStrategy, handleRequestDeferStrategy, removeDedupeKeyFromCache } = await createDedupeStrategy({
755
+ const { getAbortErrorMessage, handleRequestCancelStrategy, handleRequestDeferStrategy, removeDedupeKeyFromCache, resolvedDedupeStrategy } = await createDedupeStrategy({
748
756
  $GlobalRequestInfoCache,
749
757
  $LocalRequestInfoCache,
750
758
  baseConfig,
@@ -797,7 +805,7 @@ const createFetchClient = (initBaseConfig = {}) => {
797
805
  options,
798
806
  request
799
807
  });
800
- const shouldCloneResponse = dedupeStrategy === "defer" || options.cloneResponse;
808
+ const shouldCloneResponse = resolvedDedupeStrategy === "defer" || options.cloneResponse;
801
809
  if (!response.ok) {
802
810
  const errorData = await resolveResponseData(shouldCloneResponse ? response.clone() : response, options.responseType, options.responseParser);
803
811
  const validErrorData = await handleValidation(resolvedSchema?.errorData, {