@zayne-labs/callapi 1.7.2 → 1.7.5

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.
@@ -29,118 +29,35 @@ __export(index_exports, {
29
29
  });
30
30
  module.exports = __toCommonJS(index_exports);
31
31
 
32
- // src/error.ts
33
- var resolveErrorResult = (info) => {
34
- const { cloneResponse, defaultErrorMessage, error, message: customErrorMessage, resultMode } = info;
35
- let apiDetails = {
36
- data: null,
37
- error: {
38
- errorData: error,
39
- message: customErrorMessage ?? error.message,
40
- name: error.name
41
- },
42
- response: null
43
- };
44
- if (isHTTPErrorInstance(error)) {
45
- const { errorData, message = defaultErrorMessage, name, response } = error;
46
- apiDetails = {
47
- data: null,
48
- error: {
49
- errorData,
50
- message,
51
- name
52
- },
53
- response: cloneResponse ? response.clone() : response
54
- };
55
- }
56
- const resultModeMap = {
57
- all: apiDetails,
58
- allWithException: apiDetails,
59
- allWithoutResponse: omitKeys(apiDetails, ["response"]),
60
- onlyError: apiDetails.error,
61
- onlyResponse: apiDetails.response,
62
- onlyResponseWithException: apiDetails.response,
63
- onlySuccess: apiDetails.data,
64
- onlySuccessWithException: apiDetails.data
65
- };
66
- const getErrorResult = (customErrorInfo) => {
67
- const errorVariantResult = resultModeMap[resultMode ?? "all"];
68
- return customErrorInfo ? {
69
- ...errorVariantResult,
70
- error: {
71
- ...errorVariantResult.error,
72
- ...customErrorInfo
32
+ // src/hooks.ts
33
+ var hookRegistries = {
34
+ onError: /* @__PURE__ */ new Set(),
35
+ onRequest: /* @__PURE__ */ new Set(),
36
+ onRequestError: /* @__PURE__ */ new Set(),
37
+ onRequestStream: /* @__PURE__ */ new Set(),
38
+ onResponse: /* @__PURE__ */ new Set(),
39
+ onResponseError: /* @__PURE__ */ new Set(),
40
+ onResponseStream: /* @__PURE__ */ new Set(),
41
+ onRetry: /* @__PURE__ */ new Set(),
42
+ onSuccess: /* @__PURE__ */ new Set()
43
+ };
44
+ var composeTwoHooks = (hooks, mergedHooksExecutionMode) => {
45
+ if (hooks.length === 0) return;
46
+ const mergedHook = async (ctx) => {
47
+ if (mergedHooksExecutionMode === "sequential") {
48
+ for (const hook of hooks) {
49
+ await hook?.(ctx);
73
50
  }
74
- } : errorVariantResult;
51
+ return;
52
+ }
53
+ if (mergedHooksExecutionMode === "parallel") {
54
+ const hookArray = [...hooks];
55
+ await Promise.all(hookArray.map((uniqueHook) => uniqueHook?.(ctx)));
56
+ }
75
57
  };
76
- return { apiDetails, getErrorResult };
77
- };
78
- var HTTPError = class extends Error {
79
- errorData;
80
- isHTTPError = true;
81
- name = "HTTPError";
82
- response;
83
- constructor(errorDetails, errorOptions) {
84
- const { defaultErrorMessage, errorData, response } = errorDetails;
85
- super(errorData?.message ?? defaultErrorMessage, errorOptions);
86
- this.errorData = errorData;
87
- this.response = response;
88
- Error.captureStackTrace(this, this.constructor);
89
- }
90
- };
91
-
92
- // src/utils/guards.ts
93
- var isHTTPErrorInstance = (error) => {
94
- return (
95
- // prettier-ignore
96
- error instanceof HTTPError || isPlainObject(error) && error.name === "HTTPError" && error.isHTTPError === true
97
- );
98
- };
99
- var isArray = (value) => Array.isArray(value);
100
- var isObject = (value) => typeof value === "object" && value !== null;
101
- var hasObjectPrototype = (value) => {
102
- return Object.prototype.toString.call(value) === "[object Object]";
103
- };
104
- var isPlainObject = (value) => {
105
- if (!hasObjectPrototype(value)) {
106
- return false;
107
- }
108
- const constructor = value?.constructor;
109
- if (constructor === void 0) {
110
- return true;
111
- }
112
- const prototype = constructor.prototype;
113
- if (!hasObjectPrototype(prototype)) {
114
- return false;
115
- }
116
- if (!Object.hasOwn(prototype, "isPrototypeOf")) {
117
- return false;
118
- }
119
- if (Object.getPrototypeOf(value) !== Object.prototype) {
120
- return false;
121
- }
122
- return true;
123
- };
124
- var isJsonString = (value) => {
125
- if (!isString(value)) {
126
- return false;
127
- }
128
- try {
129
- JSON.parse(value);
130
- return true;
131
- } catch {
132
- return false;
133
- }
134
- };
135
- var isSerializable = (value) => {
136
- return isPlainObject(value) || isArray(value) || typeof value?.toJSON === "function";
137
- };
138
- var isFunction = (value) => typeof value === "function";
139
- var isQueryString = (value) => isString(value) && value.includes("=");
140
- var isString = (value) => typeof value === "string";
141
- var isReadableStream = (value) => {
142
- return value instanceof ReadableStream;
58
+ return mergedHook;
143
59
  };
60
+ var executeHooks = (...hooks) => Promise.all(hooks);
144
61
 
145
62
  // src/auth.ts
146
63
  var getValue = (value) => {
@@ -183,8 +100,7 @@ var getAuthHeader = (auth) => {
183
100
  var defineEnum = (value) => value;
184
101
 
185
102
  // src/types/common.ts
186
- var optionsEnumToExtendFromBase = defineEnum(["plugins", "validators", "schemas"]);
187
- var optionsEnumToOmitFromBase = defineEnum(["extend", "dedupeKey"]);
103
+ var optionsEnumToOmitFromBase = defineEnum(["dedupeKey"]);
188
104
 
189
105
  // src/utils/constants.ts
190
106
  var fetchSpecificKeys = defineEnum([
@@ -301,12 +217,6 @@ var mergeAndResolveHeaders = (options) => {
301
217
  }
302
218
  return headersObject;
303
219
  };
304
- var combineHooks = (baseInterceptor, interceptor) => {
305
- if (isArray(baseInterceptor)) {
306
- return [baseInterceptor, interceptor].flat();
307
- }
308
- return interceptor ?? baseInterceptor;
309
- };
310
220
  var getFetchImpl = (customFetchImpl) => {
311
221
  if (customFetchImpl) {
312
222
  return customFetchImpl;
@@ -316,7 +226,6 @@ var getFetchImpl = (customFetchImpl) => {
316
226
  }
317
227
  throw new Error("No fetch implementation found");
318
228
  };
319
- var executeHooks = (...interceptors) => Promise.all(interceptors);
320
229
  var PromiseWithResolvers = () => {
321
230
  let reject;
322
231
  let resolve;
@@ -332,6 +241,124 @@ var waitUntil = (delay) => {
332
241
  setTimeout(resolve, delay);
333
242
  return promise;
334
243
  };
244
+ var createCombinedSignal = (...signals) => AbortSignal.any(signals.filter(Boolean));
245
+ var createTimeoutSignal = (milliseconds) => AbortSignal.timeout(milliseconds);
246
+
247
+ // src/error.ts
248
+ var resolveErrorResult = (info) => {
249
+ const { cloneResponse, defaultErrorMessage, error, message: customErrorMessage, resultMode } = info;
250
+ let apiDetails = {
251
+ data: null,
252
+ error: {
253
+ errorData: error,
254
+ message: customErrorMessage ?? error.message,
255
+ name: error.name
256
+ },
257
+ response: null
258
+ };
259
+ if (isHTTPErrorInstance(error)) {
260
+ const { errorData, message = defaultErrorMessage, name, response } = error;
261
+ apiDetails = {
262
+ data: null,
263
+ error: {
264
+ errorData,
265
+ message,
266
+ name
267
+ },
268
+ response: cloneResponse ? response.clone() : response
269
+ };
270
+ }
271
+ const resultModeMap = {
272
+ all: apiDetails,
273
+ allWithException: apiDetails,
274
+ allWithoutResponse: omitKeys(apiDetails, ["response"]),
275
+ onlyError: apiDetails.error,
276
+ onlyResponse: apiDetails.response,
277
+ onlyResponseWithException: apiDetails.response,
278
+ onlySuccess: apiDetails.data,
279
+ onlySuccessWithException: apiDetails.data
280
+ };
281
+ const getErrorResult = (customErrorInfo) => {
282
+ const errorVariantResult = resultModeMap[resultMode ?? "all"];
283
+ return customErrorInfo ? {
284
+ ...errorVariantResult,
285
+ error: {
286
+ ...errorVariantResult.error,
287
+ ...customErrorInfo
288
+ }
289
+ } : errorVariantResult;
290
+ };
291
+ return { apiDetails, getErrorResult };
292
+ };
293
+ var HTTPError = class {
294
+ cause;
295
+ errorData;
296
+ isHTTPError = true;
297
+ message;
298
+ name = "HTTPError";
299
+ response;
300
+ constructor(errorDetails, errorOptions) {
301
+ const { defaultErrorMessage, errorData, response } = errorDetails;
302
+ this.message = errorData?.message ?? defaultErrorMessage;
303
+ errorOptions?.cause && (this.cause = errorOptions.cause);
304
+ this.errorData = errorData;
305
+ this.response = response;
306
+ Error.captureStackTrace(this, this.constructor);
307
+ }
308
+ };
309
+
310
+ // src/utils/guards.ts
311
+ var isHTTPErrorInstance = (error) => {
312
+ return (
313
+ // prettier-ignore
314
+ error instanceof HTTPError || isPlainObject(error) && error.name === "HTTPError" && error.isHTTPError === true
315
+ );
316
+ };
317
+ var isArray = (value) => Array.isArray(value);
318
+ var isObject = (value) => typeof value === "object" && value !== null;
319
+ var hasObjectPrototype = (value) => {
320
+ return Object.prototype.toString.call(value) === "[object Object]";
321
+ };
322
+ var isPlainObject = (value) => {
323
+ if (!hasObjectPrototype(value)) {
324
+ return false;
325
+ }
326
+ const constructor = value?.constructor;
327
+ if (constructor === void 0) {
328
+ return true;
329
+ }
330
+ const prototype = constructor.prototype;
331
+ if (!hasObjectPrototype(prototype)) {
332
+ return false;
333
+ }
334
+ if (!Object.hasOwn(prototype, "isPrototypeOf")) {
335
+ return false;
336
+ }
337
+ if (Object.getPrototypeOf(value) !== Object.prototype) {
338
+ return false;
339
+ }
340
+ return true;
341
+ };
342
+ var isJsonString = (value) => {
343
+ if (!isString(value)) {
344
+ return false;
345
+ }
346
+ try {
347
+ JSON.parse(value);
348
+ return true;
349
+ } catch {
350
+ return false;
351
+ }
352
+ };
353
+ var isSerializable = (value) => {
354
+ return isPlainObject(value) || isArray(value) || typeof value?.toJSON === "function";
355
+ };
356
+ var isFunction = (value) => typeof value === "function";
357
+ var isQueryString = (value) => isString(value) && value.includes("=");
358
+ var isString = (value) => typeof value === "string";
359
+ var isReadableStream = (value) => {
360
+ return value instanceof ReadableStream;
361
+ };
335
362
 
336
363
  // src/stream.ts
337
364
  var createProgressEvent = (options) => {
@@ -354,17 +381,19 @@ var calculateTotalBytesFromBody = async (requestBody, existingTotalBytes) => {
354
381
  return totalBytes;
355
382
  };
356
383
  var toStreamableRequest = async (context) => {
357
- const { options, request, requestInstance } = context;
384
+ const { baseConfig, config, options, request, requestInstance } = context;
358
385
  if (!options.onRequestStream || !requestInstance.body) return;
359
386
  const contentLength = requestInstance.headers.get("content-length") ?? new Headers(request.headers).get("content-length") ?? request.body?.size;
360
387
  let totalBytes = Number(contentLength ?? 0);
361
- const shouldForceContentLengthCalc = isObject(options.forceStreamSizeCalc) ? options.forceStreamSizeCalc.request : options.forceStreamSizeCalc;
388
+ const shouldForceContentLengthCalc = isObject(options.forceCalculateStreamSize) ? options.forceCalculateStreamSize.request : options.forceCalculateStreamSize;
362
389
  if (!contentLength && shouldForceContentLengthCalc) {
363
390
  totalBytes = await calculateTotalBytesFromBody(requestInstance.clone().body, totalBytes);
364
391
  }
365
392
  let transferredBytes = 0;
366
393
  await executeHooks(
367
394
  options.onRequestStream({
395
+ baseConfig,
396
+ config,
368
397
  event: createProgressEvent({ chunk: new Uint8Array(), totalBytes, transferredBytes }),
369
398
  options,
370
399
  request,
@@ -380,6 +409,8 @@ var toStreamableRequest = async (context) => {
380
409
  totalBytes = Math.max(totalBytes, transferredBytes);
381
410
  await executeHooks(
382
411
  options.onRequestStream?.({
412
+ baseConfig,
413
+ config,
383
414
  event: createProgressEvent({ chunk, totalBytes, transferredBytes }),
384
415
  options,
385
416
  request,
@@ -393,19 +424,21 @@ var toStreamableRequest = async (context) => {
393
424
  });
394
425
  };
395
426
  var toStreamableResponse = async (context) => {
396
- const { options, request, response } = context;
427
+ const { baseConfig, config, options, request, response } = context;
397
428
  if (!options.onResponseStream || !response.body) {
398
429
  return response;
399
430
  }
400
431
  const contentLength = response.headers.get("content-length");
401
432
  let totalBytes = Number(contentLength ?? 0);
402
- const shouldForceContentLengthCalc = isObject(options.forceStreamSizeCalc) ? options.forceStreamSizeCalc.response : options.forceStreamSizeCalc;
433
+ const shouldForceContentLengthCalc = isObject(options.forceCalculateStreamSize) ? options.forceCalculateStreamSize.response : options.forceCalculateStreamSize;
403
434
  if (!contentLength && shouldForceContentLengthCalc) {
404
435
  totalBytes = await calculateTotalBytesFromBody(response.clone().body, totalBytes);
405
436
  }
406
437
  let transferredBytes = 0;
407
438
  await executeHooks(
408
439
  options.onResponseStream({
440
+ baseConfig,
441
+ config,
409
442
  event: createProgressEvent({ chunk: new Uint8Array(), totalBytes, transferredBytes }),
410
443
  options,
411
444
  request,
@@ -421,6 +454,8 @@ var toStreamableResponse = async (context) => {
421
454
  totalBytes = Math.max(totalBytes, transferredBytes);
422
455
  await executeHooks(
423
456
  options.onResponseStream?.({
457
+ baseConfig,
458
+ config,
424
459
  event: createProgressEvent({ chunk, totalBytes, transferredBytes }),
425
460
  options,
426
461
  request,
@@ -436,16 +471,16 @@ var toStreamableResponse = async (context) => {
436
471
  };
437
472
 
438
473
  // src/dedupe.ts
474
+ var generateDedupeKey = (options, request) => {
475
+ const shouldHaveDedupeKey = options.dedupeStrategy === "cancel" || options.dedupeStrategy === "defer";
476
+ if (!shouldHaveDedupeKey) {
477
+ return null;
478
+ }
479
+ return `${options.fullURL}-${JSON.stringify({ options, request })}`;
480
+ };
439
481
  var createDedupeStrategy = async (context) => {
440
- const { $RequestInfoCache, newFetchController, options, request } = context;
441
- const generateDedupeKey = () => {
442
- const shouldHaveDedupeKey = options.dedupeStrategy === "cancel" || options.dedupeStrategy === "defer";
443
- if (!shouldHaveDedupeKey) {
444
- return null;
445
- }
446
- return `${options.fullURL}-${JSON.stringify({ options, request })}`;
447
- };
448
- const dedupeKey = options.dedupeKey ?? generateDedupeKey();
482
+ const { $RequestInfoCache, baseConfig, config, newFetchController, options, request } = context;
483
+ const dedupeKey = options.dedupeKey ?? generateDedupeKey(options, request);
449
484
  const $RequestInfoCacheOrNull = dedupeKey !== null ? $RequestInfoCache : null;
450
485
  if (dedupeKey !== null) {
451
486
  await waitUntil(0.1);
@@ -466,24 +501,33 @@ var createDedupeStrategy = async (context) => {
466
501
  options.fullURL,
467
502
  isReadableStream(request.body) && !request.duplex ? { ...request, duplex: "half" } : request
468
503
  );
469
- void toStreamableRequest({
504
+ await toStreamableRequest({
505
+ baseConfig,
506
+ config,
470
507
  options,
471
508
  request,
472
509
  requestInstance: requestInstance.clone()
473
510
  });
474
- const responsePromise = shouldUsePromiseFromCache ? prevRequestInfo.responsePromise : (
475
- // eslint-disable-next-line unicorn/no-nested-ternary -- Allow
476
- isReadableStream(request.body) ? fetchApi(requestInstance.clone()) : fetchApi(options.fullURL, request)
477
- );
511
+ const getFetchApiPromise = () => {
512
+ if (isReadableStream(request.body)) {
513
+ return fetchApi(requestInstance.clone());
514
+ }
515
+ return fetchApi(options.fullURL, request);
516
+ };
517
+ const responsePromise = shouldUsePromiseFromCache ? prevRequestInfo.responsePromise : getFetchApiPromise();
478
518
  $RequestInfoCacheOrNull?.set(dedupeKey, { controller: newFetchController, responsePromise });
479
519
  const streamableResponse = toStreamableResponse({
520
+ baseConfig,
521
+ config,
480
522
  options,
481
523
  request,
482
524
  response: await responsePromise
483
525
  });
484
526
  return streamableResponse;
485
527
  };
486
- const removeDedupeKeyFromCache = () => $RequestInfoCacheOrNull?.delete(dedupeKey);
528
+ const removeDedupeKeyFromCache = () => {
529
+ $RequestInfoCacheOrNull?.delete(dedupeKey);
530
+ };
487
531
  return {
488
532
  handleRequestCancelStrategy,
489
533
  handleRequestDeferStrategy,
@@ -495,61 +539,34 @@ var createDedupeStrategy = async (context) => {
495
539
  var definePlugin = (plugin) => {
496
540
  return plugin;
497
541
  };
498
- var createMergedHook = (hooks, mergedHooksExecutionMode) => {
499
- if (hooks.length === 0) return;
500
- const mergedHook = async (ctx) => {
501
- if (mergedHooksExecutionMode === "sequential") {
502
- for (const hook of hooks) {
503
- await hook?.(ctx);
504
- }
505
- return;
506
- }
507
- if (mergedHooksExecutionMode === "parallel") {
508
- const hookArray = [...hooks];
509
- await Promise.all(hookArray.map((uniqueHook) => uniqueHook?.(ctx)));
510
- }
511
- };
512
- return mergedHook;
513
- };
514
- var hooksEnum = {
515
- onError: /* @__PURE__ */ new Set(),
516
- onRequest: /* @__PURE__ */ new Set(),
517
- onRequestError: /* @__PURE__ */ new Set(),
518
- onRequestStream: /* @__PURE__ */ new Set(),
519
- onResponse: /* @__PURE__ */ new Set(),
520
- onResponseError: /* @__PURE__ */ new Set(),
521
- onResponseStream: /* @__PURE__ */ new Set(),
522
- onRetry: /* @__PURE__ */ new Set(),
523
- onSuccess: /* @__PURE__ */ new Set()
524
- };
525
- var getPluginArray = (plugins) => {
542
+ var resolvePluginArray = (plugins, basePlugins) => {
526
543
  if (!plugins) {
527
544
  return [];
528
545
  }
546
+ if (isFunction(plugins)) {
547
+ return plugins({ basePlugins: basePlugins ?? [] });
548
+ }
529
549
  return plugins;
530
550
  };
531
551
  var initializePlugins = async (context) => {
532
552
  const { baseConfig, config, initURL, options, request } = context;
533
- const hookRegistries = structuredClone(hooksEnum);
553
+ const clonedHookRegistries = structuredClone(hookRegistries);
534
554
  const addMainHooks = () => {
535
- for (const key of Object.keys(hooksEnum)) {
555
+ for (const key of Object.keys(clonedHookRegistries)) {
536
556
  const mainHook = options[key];
537
- hookRegistries[key].add(mainHook);
557
+ clonedHookRegistries[key].add(mainHook);
538
558
  }
539
559
  };
540
560
  const addPluginHooks = (pluginHooks) => {
541
- for (const key of Object.keys(hooksEnum)) {
561
+ for (const key of Object.keys(clonedHookRegistries)) {
542
562
  const pluginHook = pluginHooks[key];
543
- hookRegistries[key].add(pluginHook);
563
+ clonedHookRegistries[key].add(pluginHook);
544
564
  }
545
565
  };
546
566
  if (options.mergedHooksExecutionOrder === "mainHooksBeforePlugins") {
547
567
  addMainHooks();
548
568
  }
549
- const resolvedPlugins = [
550
- ...getPluginArray(options.plugins),
551
- ...getPluginArray(options.extend?.plugins)
552
- ];
569
+ const resolvedPlugins = resolvePluginArray(options.plugins, baseConfig.plugins);
553
570
  let resolvedUrl = initURL;
554
571
  let resolvedOptions = options;
555
572
  let resolvedRequestOptions = request;
@@ -582,10 +599,10 @@ var initializePlugins = async (context) => {
582
599
  addMainHooks();
583
600
  }
584
601
  const resolvedHooks = {};
585
- for (const [key, hookRegistry] of Object.entries(hookRegistries)) {
602
+ for (const [key, hookRegistry] of Object.entries(clonedHookRegistries)) {
586
603
  const flattenedHookArray = [...hookRegistry].flat().filter(Boolean);
587
- const mergedHook = createMergedHook(flattenedHookArray, options.mergedHooksExecutionMode);
588
- resolvedHooks[key] = mergedHook;
604
+ const composedHook = composeTwoHooks(flattenedHookArray, options.mergedHooksExecutionMode);
605
+ resolvedHooks[key] = composedHook;
589
606
  }
590
607
  return {
591
608
  resolvedHooks,
@@ -612,6 +629,9 @@ var getResponseType = (response, parser) => ({
612
629
  });
613
630
  var resolveResponseData = async (response, responseType, parser) => {
614
631
  const RESPONSE_TYPE_LOOKUP = getResponseType(response, parser);
632
+ if (!responseType) {
633
+ return RESPONSE_TYPE_LOOKUP.json();
634
+ }
615
635
  if (!Object.hasOwn(RESPONSE_TYPE_LOOKUP, responseType)) {
616
636
  throw new Error(`Invalid response type: ${responseType}`);
617
637
  }
@@ -738,10 +758,6 @@ var mergeUrlWithParamsAndQuery = (url, params, query) => {
738
758
  return mergeUrlWithQuery(urlWithMergedParams, query);
739
759
  };
740
760
 
741
- // src/utils/polyfills.ts
742
- var createCombinedSignal = (...signals) => AbortSignal.any(signals.filter(Boolean));
743
- var createTimeoutSignal = (milliseconds) => AbortSignal.timeout(milliseconds);
744
-
745
761
  // src/validation.ts
746
762
  var standardSchemaParser = async (schema, inputData) => {
747
763
  const result = await schema["~standard"].validate(inputData);
@@ -750,11 +766,6 @@ var standardSchemaParser = async (schema, inputData) => {
750
766
  }
751
767
  return result.value;
752
768
  };
753
- var createExtensibleSchemasAndValidators = (options) => {
754
- const schemas = options.schemas && { ...options.schemas, ...options.extend?.schemas };
755
- const validators = options.validators && { ...options.validators, ...options.extend?.validators };
756
- return { schemas, validators };
757
- };
758
769
  var handleValidation = async (responseData, schema, validator) => {
759
770
  const validResponseData = validator ? validator(responseData) : responseData;
760
771
  const schemaValidResponseData = schema ? await standardSchemaParser(schema, validResponseData) : validResponseData;
@@ -762,37 +773,27 @@ var handleValidation = async (responseData, schema, validator) => {
762
773
  };
763
774
 
764
775
  // src/createFetchClient.ts
765
- var createFetchClient = (baseConfig = {}) => {
776
+ var createFetchClient = (initBaseConfig = {}) => {
766
777
  const $RequestInfoCache = /* @__PURE__ */ new Map();
767
778
  const callApi2 = async (...parameters) => {
768
- const [initURL, config = {}] = parameters;
769
- const [fetchOptions, extraOptions] = splitConfig(config);
770
- const resolvedBaseConfig = isFunction(baseConfig) ? baseConfig({
771
- initURL: initURL.toString(),
772
- options: extraOptions,
773
- request: fetchOptions
774
- }) : baseConfig;
779
+ const [initURL, initConfig = {}] = parameters;
780
+ const [fetchOptions, extraOptions] = splitConfig(initConfig);
781
+ const resolvedBaseConfig = isFunction(initBaseConfig) ? initBaseConfig({ initURL: initURL.toString(), options: extraOptions, request: fetchOptions }) : initBaseConfig;
775
782
  const [baseFetchOptions, baseExtraOptions] = splitBaseConfig(resolvedBaseConfig);
776
- const initCombinedHooks = {};
777
- for (const key of Object.keys(hooksEnum)) {
778
- const combinedHook = combineHooks(
779
- baseExtraOptions[key],
780
- extraOptions[key]
781
- );
782
- initCombinedHooks[key] = combinedHook;
783
- }
784
783
  const mergedExtraOptions = {
785
784
  ...defaultExtraOptions,
786
785
  ...baseExtraOptions,
787
- ...!baseExtraOptions.mergeMainOptionsManuallyFromBase && extraOptions
786
+ ...baseExtraOptions.skipAutoMergeFor !== "all" && baseExtraOptions.skipAutoMergeFor !== "options" && extraOptions
788
787
  };
789
788
  const mergedRequestOptions = {
790
789
  ...defaultRequestOptions,
791
790
  ...baseFetchOptions,
792
- ...fetchOptions
791
+ ...baseExtraOptions.skipAutoMergeFor !== "all" && baseExtraOptions.skipAutoMergeFor !== "request" && fetchOptions
793
792
  };
793
+ const baseConfig = resolvedBaseConfig;
794
+ const config = initConfig;
794
795
  const { resolvedHooks, resolvedOptions, resolvedRequestOptions, url } = await initializePlugins({
795
- baseConfig: resolvedBaseConfig,
796
+ baseConfig,
796
797
  config,
797
798
  initURL,
798
799
  options: mergedExtraOptions,
@@ -823,18 +824,26 @@ var createFetchClient = (baseConfig = {}) => {
823
824
  }),
824
825
  signal: combinedSignal
825
826
  };
826
- const { handleRequestCancelStrategy, handleRequestDeferStrategy, removeDedupeKeyFromCache } = await createDedupeStrategy({ $RequestInfoCache, newFetchController, options, request });
827
+ const { handleRequestCancelStrategy, handleRequestDeferStrategy, removeDedupeKeyFromCache } = await createDedupeStrategy({
828
+ $RequestInfoCache,
829
+ baseConfig,
830
+ config,
831
+ newFetchController,
832
+ options,
833
+ request
834
+ });
827
835
  await handleRequestCancelStrategy();
828
836
  try {
829
- await executeHooks(options.onRequest?.({ options, request }));
837
+ await executeHooks(options.onRequest?.({ baseConfig, config, options, request }));
830
838
  request.headers = mergeAndResolveHeaders({
831
839
  auth: options.auth,
832
840
  body: request.body,
833
841
  headers: request.headers
834
842
  });
835
843
  const response = await handleRequestDeferStrategy();
836
- const { schemas, validators } = createExtensibleSchemasAndValidators(options);
837
844
  const shouldCloneResponse = options.dedupeStrategy === "defer" || options.cloneResponse;
845
+ const schemas = isFunction(options.schemas) ? options.schemas({ baseSchemas: baseExtraOptions.schemas ?? {} }) : options.schemas;
846
+ const validators = isFunction(options.validators) ? options.validators({ baseValidators: baseExtraOptions.validators ?? {} }) : options.validators;
838
847
  if (!response.ok) {
839
848
  const errorData = await resolveResponseData(
840
849
  shouldCloneResponse ? response.clone() : response,
@@ -859,6 +868,8 @@ var createFetchClient = (baseConfig = {}) => {
859
868
  );
860
869
  const validSuccessData = await handleValidation(successData, schemas?.data, validators?.data);
861
870
  const successContext = {
871
+ baseConfig,
872
+ config,
862
873
  data: validSuccessData,
863
874
  options,
864
875
  request,
@@ -881,6 +892,8 @@ var createFetchClient = (baseConfig = {}) => {
881
892
  resultMode: options.resultMode
882
893
  });
883
894
  const errorContext = {
895
+ baseConfig,
896
+ config,
884
897
  error: apiDetails.error,
885
898
  options,
886
899
  request,
@@ -924,9 +937,9 @@ var createFetchClient = (baseConfig = {}) => {
924
937
  return await handleRetryOrGetResult({ message });
925
938
  }
926
939
  await executeHooks(
927
- // == At this point only the request errors exist, so the request error interceptor is called
940
+ // == At this point only the request errors exist, so the request error hook is called
928
941
  options.onRequestError?.(errorContext),
929
- // == Also call the onError interceptor
942
+ // == Also call the onError hook
930
943
  options.onError?.(errorContext)
931
944
  );
932
945
  return await handleRetryOrGetResult();