@zayne-labs/callapi 1.6.15 → 1.6.17

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 CHANGED
@@ -36,11 +36,11 @@ To do this, you first need to set your `script`'s type to `module`, then import
36
36
 
37
37
  ```html
38
38
  <script type="module">
39
- import { callApi } from "https://esm.run/@zayne-labs/callapi";
39
+ import { callApi } from "https://esm.run/@zayne-labs/callapi";
40
40
  </script>
41
41
 
42
42
  <!-- Locked to a specific version -->
43
43
  <script type="module">
44
- import { callApi } from "https://esm.run/@zayne-labs/callapi@0.3.2";
44
+ import { callApi } from "https://esm.run/@zayne-labs/callapi@0.3.2";
45
45
  </script>
46
46
  ```
@@ -102,7 +102,7 @@ interface CallApiSchemas {
102
102
  */
103
103
  query?: StandardSchemaV1<Query>;
104
104
  }
105
- interface CallApiValidators<TData = unknown, TErrorData = unknown> {
105
+ interface CallApiValidators<TData = never, TErrorData = never> {
106
106
  /**
107
107
  * Custom function to validate the response data.
108
108
  */
@@ -201,6 +201,8 @@ type UnionToIntersection<TUnion> = (TUnion extends unknown ? (param: TUnion) =>
201
201
  type InferSchema<TResult> = TResult extends StandardSchemaV1 ? InferSchemaResult<TResult, NonNullable<unknown>> : TResult;
202
202
  type InferPluginOptions<TPluginArray extends CallApiPlugin[]> = UnionToIntersection<InferSchema<ReturnType<NonNullable<TPluginArray[number]["createExtraOptions"]>>>>;
203
203
  type PluginInitContext<TMoreOptions = DefaultMoreOptions> = WithMoreOptions<TMoreOptions> & {
204
+ baseConfig: BaseCallApiExtraOptions & CallApiRequestOptions;
205
+ config: CallApiExtraOptions & CallApiRequestOptions;
204
206
  initURL: InitURL | undefined;
205
207
  options: CombinedCallApiExtraOptions;
206
208
  request: CallApiRequestOptionsForHooks;
@@ -239,7 +241,7 @@ interface CallApiPlugin<TData = never, TErrorData = never> {
239
241
  version?: string;
240
242
  }
241
243
  declare const definePlugin: <TPlugin extends CallApiPlugin | AnyFunction<CallApiPlugin>>(plugin: TPlugin) => TPlugin;
242
- type Plugins<TPluginArray extends CallApiPlugin[]> = TPluginArray | ((context: PluginInitContext) => TPluginArray);
244
+ type Plugins<TPluginArray extends CallApiPlugin[]> = TPluginArray;
243
245
 
244
246
  declare const fetchSpecificKeys: ("body" | "cache" | "credentials" | "headers" | "integrity" | "keepalive" | "method" | "mode" | "priority" | "redirect" | "referrer" | "referrerPolicy" | "signal" | "window")[];
245
247
  declare const defaultRetryMethods: ("GET" | "POST")[];
@@ -249,7 +251,10 @@ declare const defaultRetryStatusCodes: Required<BaseCallApiExtraOptions>["retryS
249
251
  * @description Makes a type required if TSchema type is undefined or if the output type of TSchema contains undefined, otherwise keeps it as is
250
252
  */
251
253
  type MakeSchemaOptionRequired<TSchema extends StandardSchemaV1 | undefined, TObject> = undefined extends TSchema ? TObject : undefined extends InferSchemaResult<TSchema, NonNullable<unknown>> ? TObject : Required<TObject>;
252
- type Body = UnmaskType<Record<string, unknown> | RequestInit["body"]>;
254
+ type JsonPrimitive = boolean | number | string | null | undefined;
255
+ type SerializableObject = Record<keyof object, unknown>;
256
+ type SerializableArray = Array<JsonPrimitive | SerializableArray | SerializableObject> | ReadonlyArray<JsonPrimitive | SerializableArray | SerializableObject>;
257
+ type Body = UnmaskType<RequestInit["body"] | SerializableArray | SerializableObject>;
253
258
  type BodyOption<TSchemas extends CallApiSchemas> = MakeSchemaOptionRequired<TSchemas["body"], {
254
259
  /**
255
260
  * Body of the request, can be a object or any other supported body type.
@@ -451,7 +456,7 @@ type ExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType, TResult
451
456
  validators?: CallApiValidators<TData, TErrorData>;
452
457
  } & InterceptorsOrInterceptorArray<TData, TErrorData> & Partial<InferPluginOptions<TPluginArray>> & MetaOption<TSchemas> & RetryOptions<TErrorData> & ResultModeOption<TErrorData, TResultMode> & UrlOptions<TSchemas>;
453
458
  declare const optionsEnumToExtendFromBase: ("plugins" | "schemas" | "validators")[];
454
- type CallApiExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TThrowOnError extends boolean = DefaultThrowOnError, TResponseType extends ResponseTypeUnion = ResponseTypeUnion, TPluginArray extends CallApiPlugin[] = DefaultPluginArray, TSchemas extends CallApiSchemas = DefaultMoreOptions> = CallApiRequestOptions<TSchemas> & ExtraOptions<TData, TErrorData, TResultMode, TThrowOnError, TResponseType, TPluginArray, TSchemas> & {
459
+ type CallApiExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TThrowOnError extends boolean = DefaultThrowOnError, TResponseType extends ResponseTypeUnion = ResponseTypeUnion, TPluginArray extends CallApiPlugin[] = DefaultPluginArray, TSchemas extends CallApiSchemas = DefaultMoreOptions> = ExtraOptions<TData, TErrorData, TResultMode, TThrowOnError, TResponseType, TPluginArray, TSchemas> & {
455
460
  /**
456
461
  * Options that should extend the base options.
457
462
  */
@@ -460,9 +465,15 @@ type CallApiExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType,
460
465
  declare const optionsEnumToOmitFromBase: ("dedupeKey" | "extend")[];
461
466
  type BaseCallApiExtraOptions<TBaseData = DefaultDataType, TBaseErrorData = DefaultDataType, TBaseResultMode extends ResultModeUnion = ResultModeUnion, TBaseThrowOnError extends boolean = DefaultThrowOnError, TBaseResponseType extends ResponseTypeUnion = ResponseTypeUnion, TBasePluginArray extends CallApiPlugin[] = DefaultPluginArray, TBaseSchemas extends CallApiSchemas = DefaultMoreOptions> = Omit<Partial<CallApiExtraOptions<TBaseData, TBaseErrorData, TBaseResultMode, TBaseThrowOnError, TBaseResponseType, TBasePluginArray, TBaseSchemas>>, (typeof optionsEnumToOmitFromBase)[number]>;
462
467
  type CombinedCallApiExtraOptions = BaseCallApiExtraOptions & CallApiExtraOptions;
468
+ type BaseCallApiConfig<TBaseData = DefaultDataType, TBaseErrorData = DefaultDataType, TBaseResultMode extends ResultModeUnion = ResultModeUnion, TBaseThrowOnError extends boolean = DefaultThrowOnError, TBaseResponseType extends ResponseTypeUnion = ResponseTypeUnion, TBasePluginArray extends CallApiPlugin[] = DefaultPluginArray, TBaseSchemas extends CallApiSchemas = DefaultMoreOptions> = (CallApiRequestOptions<TBaseSchemas> & BaseCallApiExtraOptions<TBaseData, TBaseErrorData, TBaseResultMode, TBaseThrowOnError, TBaseResponseType, TBasePluginArray, TBaseSchemas>) | ((context: {
469
+ initURL: string;
470
+ options: CallApiExtraOptions;
471
+ request: CallApiRequestOptions;
472
+ }) => CallApiRequestOptions<TBaseSchemas> & BaseCallApiExtraOptions<TBaseData, TBaseErrorData, TBaseResultMode, TBaseThrowOnError, TBaseResponseType, TBasePluginArray, TBaseSchemas>);
473
+ type CallApiConfig<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TThrowOnError extends boolean = DefaultThrowOnError, TResponseType extends ResponseTypeUnion = ResponseTypeUnion, TPluginArray extends CallApiPlugin[] = DefaultPluginArray, TSchemas extends CallApiSchemas = DefaultMoreOptions> = CallApiRequestOptions<TSchemas> & CallApiExtraOptions<TData, TErrorData, TResultMode, TThrowOnError, TResponseType, TPluginArray, TSchemas>;
463
474
  type CallApiParameters<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TThrowOnError extends boolean = DefaultThrowOnError, TResponseType extends ResponseTypeUnion = ResponseTypeUnion, TPluginArray extends CallApiPlugin[] = DefaultPluginArray, TSchemas extends CallApiSchemas = DefaultMoreOptions> = [
464
475
  initURL: InferSchemaResult<TSchemas["initURL"], InitURL>,
465
- config?: CallApiExtraOptions<TData, TErrorData, TResultMode, TThrowOnError, TResponseType, TPluginArray, TSchemas>
476
+ config?: CallApiConfig<TData, TErrorData, TResultMode, TThrowOnError, TResponseType, TPluginArray, TSchemas>
466
477
  ];
467
478
  type RequestContext = UnmaskType<{
468
479
  options: CombinedCallApiExtraOptions;
@@ -547,6 +558,7 @@ type ResultModeMap<TData = DefaultDataType, TErrorData = DefaultDataType, TRespo
547
558
  }>;
548
559
  type ResultModeUnion = keyof ResultModeMap | undefined;
549
560
  type GetCallApiResult<TData, TErrorData, TResultMode extends ResultModeUnion, TThrowOnError extends boolean, TResponseType extends ResponseTypeUnion> = TErrorData extends false | undefined ? ResultModeMap<TData, TErrorData, TResponseType>["onlySuccessWithException"] : ResultModeUnion | undefined extends TResultMode ? TThrowOnError extends true ? ResultModeMap<TData, TErrorData, TResponseType>["allWithException"] : ResultModeMap<TData, TErrorData, TResponseType>["all"] : TResultMode extends NonNullable<ResultModeUnion> ? TResultMode extends "onlySuccess" ? ResultModeMap<TData, TErrorData, TResponseType>["onlySuccessWithException"] : TResultMode extends "onlyResponse" ? ResultModeMap<TData, TErrorData, TResponseType>["onlyResponseWithException"] : ResultModeMap<TData, TErrorData, TResponseType>[TResultMode] : never;
561
+ type CallApiResult<TData, TErrorData, TResultMode extends ResultModeUnion, TThrowOnError extends boolean, TResponseType extends ResponseTypeUnion> = Promise<GetCallApiResult<TData, TErrorData, TResultMode, TThrowOnError, TResponseType>>;
550
562
 
551
563
  type ErrorDetails<TErrorResponse> = {
552
564
  defaultErrorMessage: string;
@@ -564,4 +576,4 @@ declare class HTTPError<TErrorResponse = Record<string, unknown>> extends Error
564
576
  constructor(errorDetails: ErrorDetails<TErrorResponse>, errorOptions?: ErrorOptions);
565
577
  }
566
578
 
567
- export { type BaseCallApiExtraOptions as B, type CallApiPlugin as C, type DefaultPluginArray as D, type ErrorContext as E, type GetCallApiResult as G, HTTPError as H, type InferSchemaResult as I, type PluginInitContext as P, type ResultModeUnion as R, type SuccessContext as S, type ResponseTypeUnion as a, type CallApiSchemas as b, type CallApiExtraOptions as c, type DefaultDataType as d, type DefaultThrowOnError as e, type DefaultMoreOptions as f, type CallApiParameters as g, definePlugin as h, type PossibleJavaScriptError as i, type PossibleHTTPError as j, type CallApiRequestOptions as k, type CallApiRequestOptionsForHooks as l, type CallApiResultErrorVariant as m, type CallApiResultSuccessVariant as n, type CombinedCallApiExtraOptions as o, type Interceptors as p, type InterceptorsOrInterceptorArray as q, type PossibleJavascriptErrorNames as r, type Register as s, type RequestContext as t, type RequestErrorContext as u, type ResponseContext as v, type ResponseErrorContext as w, defaultRetryMethods as x, defaultRetryStatusCodes as y };
579
+ export { defaultRetryMethods as A, type BaseCallApiConfig as B, type CallApiPlugin as C, type DefaultPluginArray as D, type ErrorContext as E, defaultRetryStatusCodes as F, HTTPError as H, type InferSchemaResult as I, type PluginInitContext as P, type ResultModeUnion as R, type SuccessContext as S, type ResponseTypeUnion as a, type CallApiSchemas as b, type CallApiConfig as c, type CallApiResult as d, type DefaultDataType as e, type DefaultThrowOnError as f, type DefaultMoreOptions as g, type CallApiParameters as h, definePlugin as i, type BaseCallApiExtraOptions as j, type CallApiExtraOptions as k, type PossibleJavaScriptError as l, type PossibleHTTPError as m, type CallApiRequestOptions as n, type CallApiRequestOptionsForHooks as o, type CallApiResultErrorVariant as p, type CallApiResultSuccessVariant as q, type CombinedCallApiExtraOptions as r, type Interceptors as s, type InterceptorsOrInterceptorArray as t, type PossibleJavascriptErrorNames as u, type Register as v, type RequestContext as w, type RequestErrorContext as x, type ResponseContext as y, type ResponseErrorContext as z };
@@ -114,6 +114,20 @@ var isPlainObject = (value) => {
114
114
  }
115
115
  return true;
116
116
  };
117
+ var isJsonString = (value) => {
118
+ if (!isString(value)) {
119
+ return false;
120
+ }
121
+ try {
122
+ JSON.parse(value);
123
+ return true;
124
+ } catch {
125
+ return false;
126
+ }
127
+ };
128
+ var isSerializable = (value) => {
129
+ return isPlainObject(value) || isArray(value) || typeof value?.toJSON === "function";
130
+ };
117
131
  var isFunction = (value) => typeof value === "function";
118
132
  var isQueryString = (value) => isString(value) && value.includes("=");
119
133
  var isString = (value) => typeof value === "string";
@@ -224,12 +238,6 @@ var splitConfig = (config) => [
224
238
  pickKeys(config, fetchSpecificKeys),
225
239
  omitKeys(config, fetchSpecificKeys)
226
240
  ];
227
- var objectifyHeaders = (headers) => {
228
- if (!headers || isPlainObject(headers)) {
229
- return headers;
230
- }
231
- return Object.fromEntries(headers);
232
- };
233
241
  var toQueryString = (params) => {
234
242
  if (!params) {
235
243
  console.error("toQueryString:", "No query params provided!");
@@ -237,6 +245,12 @@ var toQueryString = (params) => {
237
245
  }
238
246
  return new URLSearchParams(params).toString();
239
247
  };
248
+ var objectifyHeaders = (headers) => {
249
+ if (!headers || isPlainObject(headers)) {
250
+ return headers;
251
+ }
252
+ return Object.fromEntries(headers);
253
+ };
240
254
  var mergeAndResolveHeaders = (options) => {
241
255
  const { auth, baseHeaders, body, headers } = options;
242
256
  const shouldResolveHeaders = Boolean(baseHeaders || headers || body || auth);
@@ -250,7 +264,7 @@ var mergeAndResolveHeaders = (options) => {
250
264
  headersObject["Content-Type"] = "application/x-www-form-urlencoded";
251
265
  return headersObject;
252
266
  }
253
- if (isPlainObject(body) || isString(body) && body.startsWith("{")) {
267
+ if (isSerializable(body) || isJsonString(body)) {
254
268
  headersObject["Content-Type"] = "application/json";
255
269
  headersObject.Accept = "application/json";
256
270
  }
@@ -354,14 +368,14 @@ var hooksEnum = {
354
368
  onRetry: /* @__PURE__ */ new Set(),
355
369
  onSuccess: /* @__PURE__ */ new Set()
356
370
  };
357
- var getPluginArray = (plugins, context) => {
371
+ var getPluginArray = (plugins) => {
358
372
  if (!plugins) {
359
373
  return [];
360
374
  }
361
- return isFunction(plugins) ? plugins(context) : plugins;
375
+ return plugins;
362
376
  };
363
377
  var initializePlugins = async (context) => {
364
- const { initURL, options, request } = context;
378
+ const { baseConfig, config, initURL, options, request } = context;
365
379
  const hookRegistries = structuredClone(hooksEnum);
366
380
  const addMainHooks = () => {
367
381
  for (const key of Object.keys(hooksEnum)) {
@@ -379,15 +393,21 @@ var initializePlugins = async (context) => {
379
393
  addMainHooks();
380
394
  }
381
395
  const resolvedPlugins = [
382
- ...getPluginArray(options.plugins, context),
383
- ...getPluginArray(options.extend?.plugins, context)
396
+ ...getPluginArray(options.plugins),
397
+ ...getPluginArray(options.extend?.plugins)
384
398
  ];
385
399
  let resolvedUrl = initURL;
386
400
  let resolvedOptions = options;
387
401
  let resolvedRequestOptions = request;
388
402
  const executePluginInit = async (pluginInit) => {
389
403
  if (!pluginInit) return;
390
- const initResult = await pluginInit({ initURL, options, request });
404
+ const initResult = await pluginInit({
405
+ baseConfig,
406
+ config,
407
+ initURL,
408
+ options,
409
+ request
410
+ });
391
411
  if (!isPlainObject(initResult)) return;
392
412
  if (isString(initResult.initURL)) {
393
413
  resolvedUrl = initResult.initURL;
@@ -570,12 +590,13 @@ var handleValidation = async (responseData, schema, validator) => {
570
590
  };
571
591
 
572
592
  // src/createFetchClient.ts
573
- var createFetchClient = (baseConfig) => {
574
- const [baseFetchOptions, baseExtraOptions] = splitBaseConfig(baseConfig ?? {});
593
+ var createFetchClient = (baseConfig = {}) => {
575
594
  const $RequestInfoCache = /* @__PURE__ */ new Map();
576
595
  const callApi2 = async (...parameters) => {
577
596
  const [initURL, config = {}] = parameters;
578
597
  const [fetchOptions, extraOptions] = splitConfig(config);
598
+ const resolvedBaseConfig = isFunction(baseConfig) ? baseConfig({ initURL: initURL.toString(), options: extraOptions, request: fetchOptions }) : baseConfig;
599
+ const [baseFetchOptions, baseExtraOptions] = splitBaseConfig(resolvedBaseConfig);
579
600
  const initCombinedHooks = {};
580
601
  for (const key of Object.keys(hooksEnum)) {
581
602
  const combinedHook = combineHooks(
@@ -603,20 +624,13 @@ var createFetchClient = (baseConfig) => {
603
624
  ...extraOptions,
604
625
  ...initCombinedHooks
605
626
  };
606
- const body = fetchOptions.body ?? baseFetchOptions.body;
607
627
  const defaultRequestOptions = {
608
628
  ...baseFetchOptions,
609
- ...fetchOptions,
610
- body: isPlainObject(body) ? defaultExtraOptions.bodySerializer(body) : body,
611
- headers: mergeAndResolveHeaders({
612
- auth: defaultExtraOptions.auth,
613
- baseHeaders: baseFetchOptions.headers,
614
- body,
615
- headers: fetchOptions.headers
616
- }),
617
- signal: fetchOptions.signal ?? baseFetchOptions.signal
629
+ ...fetchOptions
618
630
  };
619
631
  const { resolvedHooks, resolvedOptions, resolvedRequestOptions, url } = await initializePlugins({
632
+ baseConfig: resolvedBaseConfig,
633
+ config,
620
634
  initURL,
621
635
  options: defaultExtraOptions,
622
636
  request: defaultRequestOptions
@@ -637,6 +651,13 @@ var createFetchClient = (baseConfig) => {
637
651
  );
638
652
  const request = {
639
653
  ...resolvedRequestOptions,
654
+ body: isPlainObject(resolvedRequestOptions.body) ? options.bodySerializer(resolvedRequestOptions.body) : resolvedRequestOptions.body,
655
+ headers: mergeAndResolveHeaders({
656
+ auth: options.auth,
657
+ baseHeaders: baseFetchOptions.headers,
658
+ body: resolvedRequestOptions.body,
659
+ headers: fetchOptions.headers
660
+ }),
640
661
  signal: combinedSignal
641
662
  };
642
663
  const { handleRequestCancelStrategy, handleRequestDeferStrategy, removeDedupeKeyFromCache } = await createDedupeStrategy({ $RequestInfoCache, newFetchController, options, request });
@@ -645,13 +666,12 @@ var createFetchClient = (baseConfig) => {
645
666
  await executeHooks(options.onRequest({ options, request }));
646
667
  request.headers = mergeAndResolveHeaders({
647
668
  auth: options.auth,
648
- baseHeaders: baseFetchOptions.headers,
649
- body,
669
+ body: request.body,
650
670
  headers: request.headers
651
671
  });
652
672
  const response = await handleRequestDeferStrategy();
653
- const shouldCloneResponse = options.dedupeStrategy === "defer" || options.cloneResponse;
654
673
  const { schemas, validators } = createExtensibleSchemasAndValidators(options);
674
+ const shouldCloneResponse = options.dedupeStrategy === "defer" || options.cloneResponse;
655
675
  if (!response.ok) {
656
676
  const errorData = await resolveResponseData(
657
677
  shouldCloneResponse ? response.clone() : response,
@@ -674,7 +694,11 @@ var createFetchClient = (baseConfig) => {
674
694
  options.responseType,
675
695
  options.responseParser
676
696
  );
677
- const validSuccessData = await handleValidation(successData, schemas?.data, validators?.data);
697
+ const validSuccessData = await handleValidation(
698
+ successData,
699
+ schemas?.data,
700
+ validators?.data
701
+ );
678
702
  const successContext = {
679
703
  data: validSuccessData,
680
704
  options,
@@ -753,7 +777,6 @@ var createFetchClient = (baseConfig) => {
753
777
  removeDedupeKeyFromCache();
754
778
  }
755
779
  };
756
- callApi2.create = createFetchClient;
757
780
  return callApi2;
758
781
  };
759
782
  var callApi = createFetchClient();