@zayne-labs/callapi 1.6.15 → 1.6.16

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
  ```
@@ -115,23 +115,75 @@ interface CallApiValidators<TData = unknown, TErrorData = unknown> {
115
115
  }
116
116
  type InferSchemaResult<TSchema, TData> = TSchema extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<TSchema> : TData;
117
117
 
118
- type Params = UnmaskType<Record<string, boolean | number | string> | Array<boolean | number | string>>;
119
- type Query = UnmaskType<Record<string, boolean | number | string>>;
120
- type InitURL = UnmaskType<string | URL>;
121
- interface UrlOptions<TSchemas extends CallApiSchemas> {
118
+ /**
119
+ * @description Makes a type required if TSchema type is undefined or if the output type of TSchema contains undefined, otherwise keeps it as is
120
+ */
121
+ type MakeSchemaOptionRequired<TSchema extends StandardSchemaV1 | undefined, TObject> = undefined extends TSchema ? TObject : undefined extends InferSchemaResult<TSchema, NonNullable<unknown>> ? TObject : Required<TObject>;
122
+ type JsonPrimitive = boolean | number | string | null | undefined;
123
+ type SerializableObject = Record<keyof object, unknown>;
124
+ type SerializableArray = Array<JsonPrimitive | SerializableArray | SerializableObject> | ReadonlyArray<JsonPrimitive | SerializableArray | SerializableObject>;
125
+ type Body = UnmaskType<RequestInit["body"] | SerializableArray | SerializableObject>;
126
+ type BodyOption<TSchemas extends CallApiSchemas> = MakeSchemaOptionRequired<TSchemas["body"], {
122
127
  /**
123
- * URL to be used in the request.
128
+ * Body of the request, can be a object or any other supported body type.
124
129
  */
125
- readonly initURL?: string;
130
+ body?: InferSchemaResult<TSchemas["body"], Body>;
131
+ }>;
132
+ type Method = UnmaskType<"CONNECT" | "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PUT" | "TRACE" | AnyString>;
133
+ type MethodOption<TSchemas extends CallApiSchemas> = MakeSchemaOptionRequired<TSchemas["method"], {
126
134
  /**
127
- * Parameters to be appended to the URL (i.e: /:id)
135
+ * HTTP method for the request.
136
+ * @default "GET"
128
137
  */
129
- params?: InferSchemaResult<TSchemas["params"], Params>;
138
+ method?: InferSchemaResult<TSchemas["method"], Method>;
139
+ }>;
140
+ type Headers = UnmaskType<Record<"Authorization", CommonAuthorizationHeaders> | Record<"Content-Type", CommonContentTypes> | Record<CommonRequestHeaders, string | undefined> | Record<string, string | undefined> | RequestInit["headers"]>;
141
+ type HeadersOption<TSchemas extends CallApiSchemas> = MakeSchemaOptionRequired<TSchemas["headers"], {
130
142
  /**
131
- * Query parameters to append to the URL.
143
+ * Headers to be used in the request.
132
144
  */
133
- query?: InferSchemaResult<TSchemas["query"], Query>;
145
+ headers?: InferSchemaResult<TSchemas["headers"], Headers>;
146
+ }>;
147
+ interface Register {
134
148
  }
149
+ type GlobalMeta = Register extends {
150
+ meta?: infer TMeta extends Record<string, unknown>;
151
+ } ? TMeta : never;
152
+ type MetaOption<TSchemas extends CallApiSchemas> = {
153
+ /**
154
+ * - An optional field you can fill with additional information,
155
+ * to associate with the request, typically used for logging or tracing.
156
+ *
157
+ * - A good use case for this, would be to use the info to handle specific cases in any of the shared interceptors.
158
+ *
159
+ * @example
160
+ * ```ts
161
+ * const callMainApi = callApi.create({
162
+ * baseURL: "https://main-api.com",
163
+ * onResponseError: ({ response, options }) => {
164
+ * if (options.meta?.userId) {
165
+ * console.error(`User ${options.meta.userId} made an error`);
166
+ * }
167
+ * },
168
+ * });
169
+ *
170
+ * const response = await callMainApi({
171
+ * url: "https://example.com/api/data",
172
+ * meta: { userId: "123" },
173
+ * });
174
+ * ```
175
+ */
176
+ meta?: InferSchemaResult<TSchemas["meta"], GlobalMeta>;
177
+ };
178
+ type ResultModeOption<TErrorData, TResultMode extends ResultModeUnion> = TErrorData extends false ? {
179
+ resultMode: "onlySuccessWithException";
180
+ } : TErrorData extends false | undefined ? {
181
+ resultMode?: "onlySuccessWithException";
182
+ } : undefined extends TResultMode ? {
183
+ resultMode?: TResultMode;
184
+ } : {
185
+ resultMode: TResultMode;
186
+ };
135
187
 
136
188
  type RetryCondition<TErrorData> = (context: ErrorContext<TErrorData>) => boolean | Promise<boolean>;
137
189
  interface RetryOptions<TErrorData> {
@@ -201,6 +253,8 @@ type UnionToIntersection<TUnion> = (TUnion extends unknown ? (param: TUnion) =>
201
253
  type InferSchema<TResult> = TResult extends StandardSchemaV1 ? InferSchemaResult<TResult, NonNullable<unknown>> : TResult;
202
254
  type InferPluginOptions<TPluginArray extends CallApiPlugin[]> = UnionToIntersection<InferSchema<ReturnType<NonNullable<TPluginArray[number]["createExtraOptions"]>>>>;
203
255
  type PluginInitContext<TMoreOptions = DefaultMoreOptions> = WithMoreOptions<TMoreOptions> & {
256
+ baseConfig: BaseCallApiExtraOptions & CallApiRequestOptions;
257
+ config: CallApiExtraOptions & CallApiRequestOptions;
204
258
  initURL: InitURL | undefined;
205
259
  options: CombinedCallApiExtraOptions;
206
260
  request: CallApiRequestOptionsForHooks;
@@ -239,79 +293,12 @@ interface CallApiPlugin<TData = never, TErrorData = never> {
239
293
  version?: string;
240
294
  }
241
295
  declare const definePlugin: <TPlugin extends CallApiPlugin | AnyFunction<CallApiPlugin>>(plugin: TPlugin) => TPlugin;
242
- type Plugins<TPluginArray extends CallApiPlugin[]> = TPluginArray | ((context: PluginInitContext) => TPluginArray);
296
+ type Plugins<TPluginArray extends CallApiPlugin[]> = TPluginArray;
243
297
 
244
298
  declare const fetchSpecificKeys: ("body" | "cache" | "credentials" | "headers" | "integrity" | "keepalive" | "method" | "mode" | "priority" | "redirect" | "referrer" | "referrerPolicy" | "signal" | "window")[];
245
299
  declare const defaultRetryMethods: ("GET" | "POST")[];
246
300
  declare const defaultRetryStatusCodes: Required<BaseCallApiExtraOptions>["retryStatusCodes"];
247
301
 
248
- /**
249
- * @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
- */
251
- 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"]>;
253
- type BodyOption<TSchemas extends CallApiSchemas> = MakeSchemaOptionRequired<TSchemas["body"], {
254
- /**
255
- * Body of the request, can be a object or any other supported body type.
256
- */
257
- body?: InferSchemaResult<TSchemas["body"], Body>;
258
- }>;
259
- type Method = UnmaskType<"CONNECT" | "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PUT" | "TRACE" | AnyString>;
260
- type MethodOption<TSchemas extends CallApiSchemas> = MakeSchemaOptionRequired<TSchemas["method"], {
261
- /**
262
- * HTTP method for the request.
263
- * @default "GET"
264
- */
265
- method?: InferSchemaResult<TSchemas["method"], Method>;
266
- }>;
267
- type Headers = UnmaskType<Record<"Authorization", CommonAuthorizationHeaders> | Record<"Content-Type", CommonContentTypes> | Record<CommonRequestHeaders, string | undefined> | Record<string, string | undefined> | RequestInit["headers"]>;
268
- type HeadersOption<TSchemas extends CallApiSchemas> = MakeSchemaOptionRequired<TSchemas["headers"], {
269
- /**
270
- * Headers to be used in the request.
271
- */
272
- headers?: InferSchemaResult<TSchemas["headers"], Headers>;
273
- }>;
274
- interface Register {
275
- }
276
- type GlobalMeta = Register extends {
277
- meta?: infer TMeta extends Record<string, unknown>;
278
- } ? TMeta : never;
279
- type MetaOption<TSchemas extends CallApiSchemas> = {
280
- /**
281
- * - An optional field you can fill with additional information,
282
- * to associate with the request, typically used for logging or tracing.
283
- *
284
- * - A good use case for this, would be to use the info to handle specific cases in any of the shared interceptors.
285
- *
286
- * @example
287
- * ```ts
288
- * const callMainApi = callApi.create({
289
- * baseURL: "https://main-api.com",
290
- * onResponseError: ({ response, options }) => {
291
- * if (options.meta?.userId) {
292
- * console.error(`User ${options.meta.userId} made an error`);
293
- * }
294
- * },
295
- * });
296
- *
297
- * const response = await callMainApi({
298
- * url: "https://example.com/api/data",
299
- * meta: { userId: "123" },
300
- * });
301
- * ```
302
- */
303
- meta?: InferSchemaResult<TSchemas["meta"], GlobalMeta>;
304
- };
305
- type ResultModeOption<TErrorData, TResultMode extends ResultModeUnion> = TErrorData extends false ? {
306
- resultMode: "onlySuccessWithException";
307
- } : TErrorData extends false | undefined ? {
308
- resultMode?: "onlySuccessWithException";
309
- } : undefined extends TResultMode ? {
310
- resultMode?: TResultMode;
311
- } : {
312
- resultMode: TResultMode;
313
- };
314
-
315
302
  type FetchSpecificKeysUnion = Exclude<(typeof fetchSpecificKeys)[number], "body" | "headers" | "method">;
316
303
  type CallApiRequestOptions<TSchemas extends CallApiSchemas = DefaultMoreOptions> = BodyOption<TSchemas> & HeadersOption<TSchemas> & MethodOption<TSchemas> & Pick<RequestInit, FetchSpecificKeysUnion>;
317
304
  type CallApiRequestOptionsForHooks<TSchemas extends CallApiSchemas = DefaultMoreOptions> = Omit<CallApiRequestOptions<TSchemas>, "headers"> & {
@@ -451,7 +438,7 @@ type ExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType, TResult
451
438
  validators?: CallApiValidators<TData, TErrorData>;
452
439
  } & InterceptorsOrInterceptorArray<TData, TErrorData> & Partial<InferPluginOptions<TPluginArray>> & MetaOption<TSchemas> & RetryOptions<TErrorData> & ResultModeOption<TErrorData, TResultMode> & UrlOptions<TSchemas>;
453
440
  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> & {
441
+ 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
442
  /**
456
443
  * Options that should extend the base options.
457
444
  */
@@ -460,9 +447,14 @@ type CallApiExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType,
460
447
  declare const optionsEnumToOmitFromBase: ("dedupeKey" | "extend")[];
461
448
  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
449
  type CombinedCallApiExtraOptions = BaseCallApiExtraOptions & CallApiExtraOptions;
450
+ 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: {
451
+ initURL: string;
452
+ options: CallApiExtraOptions;
453
+ request: CallApiRequestOptions;
454
+ }) => CallApiRequestOptions<TBaseSchemas> & BaseCallApiExtraOptions<TBaseData, TBaseErrorData, TBaseResultMode, TBaseThrowOnError, TBaseResponseType, TBasePluginArray, TBaseSchemas>);
463
455
  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
456
  initURL: InferSchemaResult<TSchemas["initURL"], InitURL>,
465
- config?: CallApiExtraOptions<TData, TErrorData, TResultMode, TThrowOnError, TResponseType, TPluginArray, TSchemas>
457
+ config?: CallApiRequestOptions<TSchemas> & CallApiExtraOptions<TData, TErrorData, TResultMode, TThrowOnError, TResponseType, TPluginArray, TSchemas>
466
458
  ];
467
459
  type RequestContext = UnmaskType<{
468
460
  options: CombinedCallApiExtraOptions;
@@ -548,6 +540,24 @@ type ResultModeMap<TData = DefaultDataType, TErrorData = DefaultDataType, TRespo
548
540
  type ResultModeUnion = keyof ResultModeMap | undefined;
549
541
  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;
550
542
 
543
+ type Params = UnmaskType<Record<string, boolean | number | string> | Array<boolean | number | string>>;
544
+ type Query = UnmaskType<Record<string, boolean | number | string>>;
545
+ type InitURL = UnmaskType<string | URL>;
546
+ interface UrlOptions<TSchemas extends CallApiSchemas> {
547
+ /**
548
+ * URL to be used in the request.
549
+ */
550
+ readonly initURL?: string;
551
+ /**
552
+ * Parameters to be appended to the URL (i.e: /:id)
553
+ */
554
+ params?: InferSchemaResult<TSchemas["params"], Params>;
555
+ /**
556
+ * Query parameters to append to the URL.
557
+ */
558
+ query?: InferSchemaResult<TSchemas["query"], Query>;
559
+ }
560
+
551
561
  type ErrorDetails<TErrorResponse> = {
552
562
  defaultErrorMessage: string;
553
563
  errorData: TErrorResponse;
@@ -564,4 +574,4 @@ declare class HTTPError<TErrorResponse = Record<string, unknown>> extends Error
564
574
  constructor(errorDetails: ErrorDetails<TErrorResponse>, errorOptions?: ErrorOptions);
565
575
  }
566
576
 
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 };
577
+ export { type AnyString as A, type BaseCallApiConfig as B, type CallApiPlugin as C, type DefaultPluginArray as D, type ExtraOptions as E, type Interceptors as F, type GetCallApiResult as G, HTTPError as H, type InferSchemaResult as I, type PossibleJavascriptErrorNames as J, type Register as K, type RequestContext as L, type MetaOption as M, type RequestErrorContext as N, type ResponseContext as O, type PossibleJavaScriptError as P, type ResponseErrorContext as Q, type ResultModeUnion as R, type SerializableArray as S, type SuccessContext as T, type UrlOptions as U, defaultRetryMethods as V, defaultRetryStatusCodes as W, type ResponseTypeUnion as a, type CallApiSchemas as b, type SerializableObject as c, type CommonContentTypes as d, type CommonRequestHeaders as e, type Auth as f, type Awaitable as g, type CombinedCallApiExtraOptions as h, type CallApiRequestOptionsForHooks as i, type CallApiValidators as j, type InterceptorsOrInterceptorArray as k, type RetryOptions as l, type ResultModeOption as m, type DefaultDataType as n, type DefaultThrowOnError as o, type DefaultMoreOptions as p, type CallApiParameters as q, definePlugin as r, type PluginInitContext as s, type BaseCallApiExtraOptions as t, type CallApiExtraOptions as u, type PossibleHTTPError as v, type CallApiRequestOptions as w, type CallApiResultErrorVariant as x, type CallApiResultSuccessVariant as y, type ErrorContext 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 });
@@ -646,12 +667,12 @@ var createFetchClient = (baseConfig) => {
646
667
  request.headers = mergeAndResolveHeaders({
647
668
  auth: options.auth,
648
669
  baseHeaders: baseFetchOptions.headers,
649
- body,
670
+ body: request.body,
650
671
  headers: request.headers
651
672
  });
652
673
  const response = await handleRequestDeferStrategy();
653
- const shouldCloneResponse = options.dedupeStrategy === "defer" || options.cloneResponse;
654
674
  const { schemas, validators } = createExtensibleSchemasAndValidators(options);
675
+ const shouldCloneResponse = options.dedupeStrategy === "defer" || options.cloneResponse;
655
676
  if (!response.ok) {
656
677
  const errorData = await resolveResponseData(
657
678
  shouldCloneResponse ? response.clone() : response,
@@ -753,7 +774,6 @@ var createFetchClient = (baseConfig) => {
753
774
  removeDedupeKeyFromCache();
754
775
  }
755
776
  };
756
- callApi2.create = createFetchClient;
757
777
  return callApi2;
758
778
  };
759
779
  var callApi = createFetchClient();