@zayne-labs/callapi 1.8.20 → 1.8.22

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.
@@ -1,30 +1,30 @@
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, HTTPError, Hooks, HooksOrHooksArray, InferInitURL, InferParamsFromRoute, InferSchemaResult, PluginExtraOptions, PluginHooks, PluginHooksWithMoreOptions, PluginInitContext, PossibleHTTPError, PossibleJavaScriptError, PossibleJavaScriptOrValidationError, PossibleValidationError, Register, RequestContext, RequestStreamContext, ResponseContext, ResponseErrorContext, ResponseStreamContext, ResponseTypeUnion, ResultModeUnion, RetryOptions, SuccessContext, ThrowOnErrorUnion, URLOptions, ValidationError, Writeable } from "./common-Vd9i_nPc.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, HTTPError, Hooks, HooksOrHooksArray, InferInitURL, InferParamsFromRoute, InferSchemaResult, PluginExtraOptions, PluginHooks, PluginHooksWithMoreOptions, PluginInitContext, PossibleHTTPError, PossibleJavaScriptError, PossibleJavaScriptOrValidationError, PossibleValidationError, Register, RequestContext, RequestStreamContext, ResponseContext, ResponseErrorContext, ResponseStreamContext, ResponseTypeUnion, ResultModeUnion, RetryOptions, SuccessContext, ThrowOnErrorUnion, URLOptions, ValidationError, Writeable } from "./common-C-kIzPcz.js";
2
2
 
3
3
  //#region src/createFetchClient.d.ts
4
4
 
5
5
  declare const createFetchClient: <TBaseData = DefaultDataType, TBaseErrorData = DefaultDataType, TBaseResultMode extends ResultModeUnion = ResultModeUnion, TBaseThrowOnError extends ThrowOnErrorUnion = DefaultThrowOnError, TBaseResponseType extends ResponseTypeUnion = ResponseTypeUnion, const TBaseSchemaAndConfig extends BaseCallApiSchemaAndConfig = BaseCallApiSchemaAndConfig, const TBasePluginArray extends CallApiPlugin[] = DefaultPluginArray, TComputedBaseSchemaConfig extends CallApiSchemaConfig = NonNullable<Writeable<TBaseSchemaAndConfig["config"], "deep">>, TComputedBaseSchemaRoutes extends BaseCallApiSchemaRoutes = Writeable<TBaseSchemaAndConfig["routes"], "deep">>(initBaseConfig?: BaseCallApiConfig<TBaseData, TBaseErrorData, TBaseResultMode, TBaseThrowOnError, TBaseResponseType, TBaseSchemaAndConfig, TBasePluginArray>) => <TData = TBaseData, TErrorData = TBaseErrorData, TResultMode extends ResultModeUnion = TBaseResultMode, TThrowOnError extends ThrowOnErrorUnion = TBaseThrowOnError, TResponseType extends ResponseTypeUnion = TBaseResponseType, const TSchemaConfig extends CallApiSchemaConfig = TComputedBaseSchemaConfig, TInitURL extends InferInitURL<TComputedBaseSchemaRoutes, TSchemaConfig> = InferInitURL<TComputedBaseSchemaRoutes, TSchemaConfig>, TCurrentRouteSchemaKey extends GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL> = GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL>, const TSchema extends CallApiSchema = GetCurrentRouteSchema<TComputedBaseSchemaRoutes, TCurrentRouteSchemaKey>, const TPluginArray extends CallApiPlugin[] = TBasePluginArray>(initURL: TInitURL, config?: CallApiConfig<InferSchemaResult<TSchema["data"], TData>, InferSchemaResult<TSchema["errorData"], TErrorData>, TResultMode, TThrowOnError, TResponseType, TComputedBaseSchemaRoutes, TSchema, TComputedBaseSchemaConfig, TSchemaConfig, TInitURL, TCurrentRouteSchemaKey, TBasePluginArray, TPluginArray> | undefined) => CallApiResult<InferSchemaResult<TSchema["data"], TData>, InferSchemaResult<TSchema["errorData"], TErrorData>, TResultMode, TThrowOnError, TResponseType>;
6
- declare const callApi: <TData = unknown, TErrorData = unknown, TResultMode extends ResultModeUnion = ResultModeUnion, TThrowOnError extends ThrowOnErrorUnion = boolean, TResponseType extends ResponseTypeUnion = ResponseTypeUnion, const TSchemaConfig extends CallApiSchemaConfig = CallApiSchemaConfig, TInitURL extends ApplyStrictConfig<TSchemaConfig, ApplyURLBasedConfig<TSchemaConfig, AnyString | "delete/" | "get/" | "patch/" | "post/" | "put/">> = ApplyStrictConfig<TSchemaConfig, ApplyURLBasedConfig<TSchemaConfig, AnyString | "delete/" | "get/" | "patch/" | "post/" | "put/">>, TCurrentRouteSchemaKey extends GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL> = GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL>, const TSchema extends CallApiSchema = GetCurrentRouteSchema<{
6
+ declare const callApi: <TData = unknown, TErrorData = unknown, TResultMode extends ResultModeUnion = ResultModeUnion, TThrowOnError extends ThrowOnErrorUnion = boolean, TResponseType extends ResponseTypeUnion = ResponseTypeUnion, const TSchemaConfig extends CallApiSchemaConfig = CallApiSchemaConfig, TInitURL extends ApplyStrictConfig<TSchemaConfig, ApplyURLBasedConfig<TSchemaConfig, AnyString | "@delete/" | "@get/" | "@patch/" | "@post/" | "@put/">> = ApplyStrictConfig<TSchemaConfig, ApplyURLBasedConfig<TSchemaConfig, AnyString | "@delete/" | "@get/" | "@patch/" | "@post/" | "@put/">>, TCurrentRouteSchemaKey extends GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL> = GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL>, const TSchema extends CallApiSchema = GetCurrentRouteSchema<{
7
7
  [x: AnyString]: CallApiSchema | undefined;
8
- "delete/"?: CallApiSchema | undefined;
9
- "get/"?: CallApiSchema | undefined;
10
- "patch/"?: CallApiSchema | undefined;
11
- "post/"?: CallApiSchema | undefined;
12
- "put/"?: CallApiSchema | undefined;
8
+ "@delete/"?: CallApiSchema | undefined;
9
+ "@get/"?: CallApiSchema | undefined;
10
+ "@patch/"?: CallApiSchema | undefined;
11
+ "@post/"?: CallApiSchema | undefined;
12
+ "@put/"?: CallApiSchema | undefined;
13
13
  }, TCurrentRouteSchemaKey>, const TPluginArray extends CallApiPlugin[] = DefaultPluginArray>(initURL: TInitURL, config?: CallApiConfig<InferSchemaResult<TSchema["data"], TData>, InferSchemaResult<TSchema["errorData"], TErrorData>, TResultMode, TThrowOnError, TResponseType, {
14
14
  [x: AnyString]: CallApiSchema | undefined;
15
- "delete/"?: CallApiSchema | undefined;
16
- "get/"?: CallApiSchema | undefined;
17
- "patch/"?: CallApiSchema | undefined;
18
- "post/"?: CallApiSchema | undefined;
19
- "put/"?: CallApiSchema | undefined;
15
+ "@delete/"?: CallApiSchema | undefined;
16
+ "@get/"?: CallApiSchema | undefined;
17
+ "@patch/"?: CallApiSchema | undefined;
18
+ "@post/"?: CallApiSchema | undefined;
19
+ "@put/"?: CallApiSchema | undefined;
20
20
  }, TSchema, CallApiSchemaConfig, TSchemaConfig, TInitURL, TCurrentRouteSchemaKey, DefaultPluginArray, TPluginArray> | undefined) => CallApiResult<InferSchemaResult<TSchema["data"], TData>, InferSchemaResult<TSchema["errorData"], TErrorData>, TResultMode, TThrowOnError, TResponseType>;
21
21
  //#endregion
22
22
  //#region src/defineHelpers.d.ts
23
23
  declare const defineSchema: <const TBaseSchemaRoutes extends BaseCallApiSchemaRoutes, const TSchemaConfig extends CallApiSchemaConfig>(routes: TBaseSchemaRoutes, config?: TSchemaConfig) => {
24
- config: TSchemaConfig | undefined;
25
- routes: Writeable<typeof routes, "deep">;
24
+ config: Writeable<TSchemaConfig, "deep"> & {};
25
+ routes: Writeable<TBaseSchemaRoutes, "deep">;
26
26
  };
27
- declare const defineSchemaConfig: <const TConfig extends CallApiExtraOptions["schemaConfig"]>(config: TConfig) => Writeable<typeof config, "deep">;
27
+ declare const defineSchemaConfig: <const TConfig extends CallApiExtraOptions["schemaConfig"]>(config: TConfig) => NonNullable<Writeable<typeof config, "deep">>;
28
28
  declare const defineSchemaRoutes: <const TBaseSchemaRoutes extends BaseCallApiSchemaRoutes>(routes: TBaseSchemaRoutes) => Writeable<typeof routes, "deep">;
29
29
  declare const definePlugin: <const TPlugin extends CallApiPlugin | AnyFunction<CallApiPlugin>>(plugin: TPlugin) => Writeable<TPlugin, "deep">;
30
30
  declare const defineBaseConfig: <const TBaseConfig extends BaseCallApiConfig>(baseConfig: TBaseConfig) => Writeable<typeof baseConfig, "deep">;
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-C4H57FX_.js";
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";
2
2
 
3
3
  //#region src/result.ts
4
4
  const getResponseType = (response, parser) => ({
@@ -107,13 +107,13 @@ const hookRegistries = {
107
107
  onSuccess: /* @__PURE__ */ new Set(),
108
108
  onValidationError: /* @__PURE__ */ new Set()
109
109
  };
110
- const composeAllHooks = (hooksArray, mergedHooksExecutionMode) => {
110
+ const composeAllHooks = (hooksArray, hooksExecutionMode) => {
111
111
  const mergedHook = async (ctx) => {
112
- if (mergedHooksExecutionMode === "sequential") {
112
+ if (hooksExecutionMode === "sequential") {
113
113
  for (const hook of hooksArray) await hook?.(ctx);
114
114
  return;
115
115
  }
116
- if (mergedHooksExecutionMode === "parallel") await Promise.all(hooksArray.map((uniqueHook) => uniqueHook?.(ctx)));
116
+ if (hooksExecutionMode === "parallel") await Promise.all(hooksArray.map((uniqueHook) => uniqueHook?.(ctx)));
117
117
  };
118
118
  return mergedHook;
119
119
  };
@@ -241,21 +241,22 @@ const toStreamableResponse = async (context) => {
241
241
 
242
242
  //#endregion
243
243
  //#region src/dedupe.ts
244
- const getAbortErrorMessage = (dedupeKey, fullURL) => {
245
- return dedupeKey ? `Duplicate request detected - Aborted previous request with key '${dedupeKey}' as a new request was initiated` : `Duplicate request detected - Aborted previous request to '${fullURL}' as a new request with identical options was initiated`;
246
- };
247
244
  const createDedupeStrategy = async (context) => {
248
245
  const { $GlobalRequestInfoCache: $GlobalRequestInfoCache$1, $LocalRequestInfoCache, baseConfig, config, newFetchController, options: globalOptions, request: globalRequest } = context;
249
246
  const dedupeStrategy = globalOptions.dedupeStrategy ?? dedupeDefaults.dedupeStrategy;
250
- const generateDedupeKey = () => {
247
+ const getDedupeKey = () => {
251
248
  const shouldHaveDedupeKey = dedupeStrategy === "cancel" || dedupeStrategy === "defer";
252
249
  if (!shouldHaveDedupeKey) return null;
250
+ if (globalOptions.dedupeKey) {
251
+ const resolvedDedupeKey = isFunction(globalOptions.dedupeKey) ? globalOptions.dedupeKey(context) : globalOptions.dedupeKey;
252
+ return resolvedDedupeKey;
253
+ }
253
254
  return `${globalOptions.fullURL}-${deterministicHashFn({
254
255
  options: globalOptions,
255
256
  request: globalRequest
256
257
  })}`;
257
258
  };
258
- const dedupeKey = globalOptions.dedupeKey ?? generateDedupeKey();
259
+ const dedupeKey = getDedupeKey();
259
260
  const dedupeCacheScope = globalOptions.dedupeCacheScope ?? dedupeDefaults.dedupeCacheScope;
260
261
  const dedupeCacheScopeKey = globalOptions.dedupeCacheScopeKey ?? dedupeDefaults.dedupeCacheScopeKey;
261
262
  if (dedupeCacheScope === "global" && !$GlobalRequestInfoCache$1.has(dedupeCacheScopeKey)) $GlobalRequestInfoCache$1.set(dedupeCacheScopeKey, /* @__PURE__ */ new Map());
@@ -267,10 +268,14 @@ const createDedupeStrategy = async (context) => {
267
268
  ******/
268
269
  if (dedupeKey !== null) await waitFor(.1);
269
270
  const prevRequestInfo = $RequestInfoCacheOrNull?.get(dedupeKey);
271
+ const getAbortErrorMessage = () => {
272
+ if (dedupeKey) return `Duplicate request detected - Aborted previous request with key '${dedupeKey}' as a new request was initiated`;
273
+ return `Duplicate request detected - Aborted previous request to '${globalOptions.fullURL}' as a new request with identical options was initiated`;
274
+ };
270
275
  const handleRequestCancelStrategy = () => {
271
276
  const shouldCancelRequest = prevRequestInfo && dedupeStrategy === "cancel";
272
277
  if (!shouldCancelRequest) return;
273
- const message = getAbortErrorMessage(globalOptions.dedupeKey, globalOptions.fullURL);
278
+ const message = getAbortErrorMessage();
274
279
  const reason = new DOMException(message, "AbortError");
275
280
  prevRequestInfo.controller.abort(reason);
276
281
  return Promise.resolve();
@@ -302,6 +307,7 @@ const createDedupeStrategy = async (context) => {
302
307
  };
303
308
  return {
304
309
  dedupeStrategy,
310
+ getAbortErrorMessage,
305
311
  handleRequestCancelStrategy,
306
312
  handleRequestDeferStrategy,
307
313
  removeDedupeKeyFromCache
@@ -486,8 +492,8 @@ const initializePlugins = async (context) => {
486
492
  clonedHookRegistries[key].add(pluginHook);
487
493
  }
488
494
  };
489
- const mergedHooksExecutionOrder = options.mergedHooksExecutionOrder ?? hookDefaults.mergedHooksExecutionOrder;
490
- if (mergedHooksExecutionOrder === "mainHooksBeforePlugins") addMainHooks();
495
+ const hookRegistrationOrder = options.hooksRegistrationOrder ?? hookDefaults.hooksRegistrationOrder;
496
+ if (hookRegistrationOrder === "mainFirst") addMainHooks();
491
497
  const { currentRouteSchemaKey, mainInitURL } = getCurrentRouteSchemaKeyAndMainInitURL({
492
498
  baseExtraOptions: baseConfig,
493
499
  extraOptions: config,
@@ -529,14 +535,14 @@ const initializePlugins = async (context) => {
529
535
  if (!plugin.hooks) continue;
530
536
  addPluginHooks(plugin.hooks);
531
537
  }
532
- if (mergedHooksExecutionOrder === "mainHooksAfterPlugins") addMainHooks();
538
+ if (hookRegistrationOrder === "pluginsFirst") addMainHooks();
533
539
  const resolvedHooks = {};
534
540
  for (const [key, hookRegistry] of Object.entries(clonedHookRegistries)) {
535
541
  if (hookRegistry.size === 0) continue;
536
542
  const flattenedHookArray = [...hookRegistry].flat();
537
543
  if (flattenedHookArray.length === 0) continue;
538
- const mergedHooksExecutionMode = options.mergedHooksExecutionMode ?? hookDefaults.mergedHooksExecutionMode;
539
- const composedHook = composeAllHooks(flattenedHookArray, mergedHooksExecutionMode);
544
+ const hooksExecutionMode = options.hooksExecutionMode ?? hookDefaults.hooksExecutionMode;
545
+ const composedHook = composeAllHooks(flattenedHookArray, hooksExecutionMode);
540
546
  resolvedHooks[key] = composedHook;
541
547
  }
542
548
  return {
@@ -623,14 +629,39 @@ const mergeUrlWithQuery = (url, query) => {
623
629
  return `${url}${questionMark}${queryString}`;
624
630
  };
625
631
  /**
626
- * @description
627
- * Extracts the method from the URL if it is a schema modifier.
632
+ * @description Extracts the HTTP method from method-prefixed route patterns.
633
+ *
634
+ * Analyzes URLs that start with method modifiers (e.g., "@get/", "@post/") and extracts
635
+ * the HTTP method for use in API requests. This enables method specification directly
636
+ * in route definitions.
637
+ *
638
+ * @param initURL - The URL string to analyze for method modifiers
639
+ * @returns The extracted HTTP method (lowercase) if found, otherwise undefined
640
+ *
641
+ * @example
642
+ * ```typescript
643
+ * // Method extraction from prefixed routes
644
+ * extractMethodFromURL("@get/users"); // Returns: "get"
645
+ * extractMethodFromURL("@post/users"); // Returns: "post"
646
+ * extractMethodFromURL("@put/users/:id"); // Returns: "put"
647
+ * extractMethodFromURL("@delete/users/:id"); // Returns: "delete"
648
+ * extractMethodFromURL("@patch/users/:id"); // Returns: "patch"
649
+ *
650
+ * // No method modifier
651
+ * extractMethodFromURL("/users"); // Returns: undefined
652
+ * extractMethodFromURL("users"); // Returns: undefined
653
+ *
654
+ * // Invalid or unsupported methods
655
+ * extractMethodFromURL("@invalid/users"); // Returns: undefined
656
+ * extractMethodFromURL("@/users"); // Returns: undefined
628
657
  *
629
- * @param initURL - The URL to extract the method from.
630
- * @returns The method if it is a schema modifier, otherwise undefined.
658
+ * // Edge cases
659
+ * extractMethodFromURL(undefined); // Returns: undefined
660
+ * extractMethodFromURL(""); // Returns: undefined
661
+ * ```
631
662
  */
632
663
  const extractMethodFromURL = (initURL) => {
633
- if (!initURL?.startsWith("@")) return;
664
+ if (!initURL || initURL.startsWith("@")) return;
634
665
  const method = initURL.split("@")[1]?.split("/")[0];
635
666
  if (!method || !routeKeyMethods.includes(method)) return;
636
667
  return method;
@@ -646,7 +677,7 @@ const normalizeURL = (initURL) => {
646
677
  const normalizedURL = initURL.replace(`@${methodFromURL}/`, "/");
647
678
  return normalizedURL;
648
679
  };
649
- const getFullURL = (options) => {
680
+ const getFullAndNormalizedURL = (options) => {
650
681
  const { baseURL, initURL, params, query } = options;
651
682
  const normalizedInitURL = normalizeURL(initURL);
652
683
  const urlWithMergedParams = mergeUrlWithParams(normalizedInitURL, params);
@@ -693,7 +724,7 @@ const createFetchClient = (initBaseConfig = {}) => {
693
724
  options: mergedExtraOptions,
694
725
  request: mergedRequestOptions
695
726
  });
696
- const { fullURL, normalizedInitURL } = getFullURL({
727
+ const { fullURL, normalizedInitURL } = getFullAndNormalizedURL({
697
728
  baseURL: resolvedOptions.baseURL,
698
729
  initURL: resolvedInitURL,
699
730
  params: resolvedOptions.params,
@@ -713,7 +744,7 @@ const createFetchClient = (initBaseConfig = {}) => {
713
744
  ...resolvedRequestOptions,
714
745
  signal: combinedSignal
715
746
  };
716
- const { dedupeStrategy, handleRequestCancelStrategy, handleRequestDeferStrategy, removeDedupeKeyFromCache } = await createDedupeStrategy({
747
+ const { dedupeStrategy, getAbortErrorMessage, handleRequestCancelStrategy, handleRequestDeferStrategy, removeDedupeKeyFromCache } = await createDedupeStrategy({
717
748
  $GlobalRequestInfoCache,
718
749
  $LocalRequestInfoCache,
719
750
  baseConfig,
@@ -864,7 +895,7 @@ const createFetchClient = (initBaseConfig = {}) => {
864
895
  }
865
896
  let message = error?.message;
866
897
  if (error instanceof DOMException && error.name === "AbortError") {
867
- message = getAbortErrorMessage(options.dedupeKey, options.fullURL);
898
+ message = getAbortErrorMessage();
868
899
  !shouldThrowOnError && console.error(`${error.name}:`, message);
869
900
  }
870
901
  if (error instanceof DOMException && error.name === "TimeoutError") {
@@ -885,8 +916,8 @@ const callApi = createFetchClient();
885
916
  //#region src/defineHelpers.ts
886
917
  const defineSchema = (routes, config) => {
887
918
  return {
888
- config,
889
- routes
919
+ config: defineSchemaConfig(config),
920
+ routes: defineSchemaRoutes(routes)
890
921
  };
891
922
  };
892
923
  const defineSchemaConfig = (config) => {