@zayne-labs/callapi 1.7.6 → 1.7.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { splitConfig, isFunction, splitBaseConfig, createTimeoutSignal, createCombinedSignal, commonDefaults, mergeAndResolveHeaders, isSerializable, HTTPError, resolveErrorResult, isHTTPErrorInstance, waitUntil, hookDefaults, dedupeDefaults, responseDefaults, omitKeys, retryDefaults, isArray, isPlainObject, isString, toQueryString, getFetchImpl, isReadableStream, isObject, requestOptionDefaults } from './chunk-UVFIGKZS.js';
2
- export { HTTPError } from './chunk-UVFIGKZS.js';
1
+ import { splitConfig, isFunction, splitBaseConfig, createTimeoutSignal, createCombinedSignal, commonDefaults, getHeaders, isSerializable, resolveResponseData, HTTPError, resolveSuccessResult, resolveErrorResult, isHTTPErrorInstance, getCustomizedErrorResult, waitUntil, hookDefaults, dedupeDefaults, retryDefaults, isArray, isPlainObject, isString, toQueryString, getFetchImpl, isReadableStream, requestOptionDefaults, isObject } from './chunk-SJZKYDA4.js';
2
+ export { HTTPError } from './chunk-SJZKYDA4.js';
3
3
 
4
4
  // src/hooks.ts
5
5
  var hookRegistries = {
@@ -29,7 +29,25 @@ var composeTwoHooks = (hooks, mergedHooksExecutionMode) => {
29
29
  };
30
30
  return mergedHook;
31
31
  };
32
- var executeHooks = (...hooks) => Promise.all(hooks);
32
+ var executeHooksInTryBlock = async (...hookResults) => {
33
+ await Promise.all(hookResults);
34
+ };
35
+ var createExecuteHooksFn = (info) => {
36
+ const { errorInfo, shouldThrowOnError } = info;
37
+ const executeHooksInCatchBlock = async (...hookResults) => {
38
+ try {
39
+ await Promise.all(hookResults);
40
+ return null;
41
+ } catch (hookError) {
42
+ const hookErrorResult = resolveErrorResult(hookError, errorInfo);
43
+ if (shouldThrowOnError) {
44
+ throw hookError;
45
+ }
46
+ return hookErrorResult;
47
+ }
48
+ };
49
+ return executeHooksInCatchBlock;
50
+ };
33
51
 
34
52
  // src/stream.ts
35
53
  var createProgressEvent = (options) => {
@@ -61,7 +79,7 @@ var toStreamableRequest = async (context) => {
61
79
  totalBytes = await calculateTotalBytesFromBody(requestInstance.clone().body, totalBytes);
62
80
  }
63
81
  let transferredBytes = 0;
64
- await executeHooks(
82
+ await executeHooksInTryBlock(
65
83
  options.onRequestStream({
66
84
  baseConfig,
67
85
  config,
@@ -78,7 +96,7 @@ var toStreamableRequest = async (context) => {
78
96
  for await (const chunk of body) {
79
97
  transferredBytes += chunk.byteLength;
80
98
  totalBytes = Math.max(totalBytes, transferredBytes);
81
- await executeHooks(
99
+ await executeHooksInTryBlock(
82
100
  options.onRequestStream?.({
83
101
  baseConfig,
84
102
  config,
@@ -106,7 +124,7 @@ var toStreamableResponse = async (context) => {
106
124
  totalBytes = await calculateTotalBytesFromBody(response.clone().body, totalBytes);
107
125
  }
108
126
  let transferredBytes = 0;
109
- await executeHooks(
127
+ await executeHooksInTryBlock(
110
128
  options.onResponseStream({
111
129
  baseConfig,
112
130
  config,
@@ -123,7 +141,7 @@ var toStreamableResponse = async (context) => {
123
141
  for await (const chunk of body) {
124
142
  transferredBytes += chunk.byteLength;
125
143
  totalBytes = Math.max(totalBytes, transferredBytes);
126
- await executeHooks(
144
+ await executeHooksInTryBlock(
127
145
  options.onResponseStream?.({
128
146
  baseConfig,
129
147
  config,
@@ -284,7 +302,7 @@ var initializePlugins = async (context) => {
284
302
  const flattenedHookArray = [...hookRegistry].flat();
285
303
  const mergedHooksExecutionMode = options.mergedHooksExecutionMode ?? hookDefaults.mergedHooksExecutionMode;
286
304
  const composedHook = composeTwoHooks(flattenedHookArray, mergedHooksExecutionMode);
287
- resolvedHooks[key] = composedHook;
305
+ composedHook && (resolvedHooks[key] = composedHook);
288
306
  }
289
307
  return {
290
308
  resolvedHooks,
@@ -294,46 +312,6 @@ var initializePlugins = async (context) => {
294
312
  };
295
313
  };
296
314
 
297
- // src/response.ts
298
- var getResponseType = (response, parser) => ({
299
- arrayBuffer: () => response.arrayBuffer(),
300
- blob: () => response.blob(),
301
- formData: () => response.formData(),
302
- json: async () => {
303
- const text = await response.text();
304
- return parser(text);
305
- },
306
- stream: () => response.body,
307
- text: () => response.text()
308
- });
309
- var resolveResponseData = (response, responseType, parser) => {
310
- const selectedParser = parser ?? responseDefaults.responseParser;
311
- const selectedResponseType = responseType ?? responseDefaults.responseType;
312
- const RESPONSE_TYPE_LOOKUP = getResponseType(response, selectedParser);
313
- if (!Object.hasOwn(RESPONSE_TYPE_LOOKUP, selectedResponseType)) {
314
- throw new Error(`Invalid response type: ${responseType}`);
315
- }
316
- return RESPONSE_TYPE_LOOKUP[selectedResponseType]();
317
- };
318
- var resolveSuccessResult = (info) => {
319
- const { data, response, resultMode } = info;
320
- const apiDetails = { data, error: null, response };
321
- if (!resultMode) {
322
- return apiDetails;
323
- }
324
- const resultModeMap = {
325
- all: apiDetails,
326
- allWithException: apiDetails,
327
- allWithoutResponse: omitKeys(apiDetails, ["response"]),
328
- onlyError: apiDetails.error,
329
- onlyResponse: apiDetails.response,
330
- onlyResponseWithException: apiDetails.response,
331
- onlySuccess: apiDetails.data,
332
- onlySuccessWithException: apiDetails.data
333
- };
334
- return resultModeMap[resultMode];
335
- };
336
-
337
315
  // src/retry.ts
338
316
  var getLinearDelay = (currentAttemptCount, options) => {
339
317
  const retryDelay = options.retryDelay ?? options.retry?.delay;
@@ -349,7 +327,7 @@ var getExponentialDelay = (currentAttemptCount, options) => {
349
327
  };
350
328
  var createRetryStrategy = (ctx) => {
351
329
  const { options } = ctx;
352
- const currentAttemptCount = options["~retryAttemptCount"] ?? 0;
330
+ const currentAttemptCount = options["~retryAttemptCount"] ?? 1;
353
331
  const retryStrategy = options.retryStrategy ?? options.retry?.strategy ?? retryDefaults.strategy;
354
332
  const getDelay = () => {
355
333
  switch (retryStrategy) {
@@ -368,38 +346,22 @@ var createRetryStrategy = (ctx) => {
368
346
  const retryCondition = options.retryCondition ?? options.retry?.condition ?? retryDefaults.condition;
369
347
  const maxRetryAttempts = options.retryAttempts ?? options.retry?.attempts ?? retryDefaults.attempts;
370
348
  const customRetryCondition = await retryCondition(ctx);
371
- const baseShouldRetry = maxRetryAttempts > currentAttemptCount && customRetryCondition;
349
+ const baseShouldRetry = maxRetryAttempts >= currentAttemptCount && customRetryCondition;
372
350
  if (ctx.error.name !== "HTTPError") {
373
351
  return baseShouldRetry;
374
352
  }
375
- const retryMethods = new Set(
376
- options.retryMethods ?? options.retry?.methods ?? retryDefaults.methods
377
- );
353
+ const selectedMethodArray = options.retryMethods ?? options.retry?.methods ?? retryDefaults.methods;
354
+ const retryMethods = new Set(selectedMethodArray);
355
+ const method = ctx.request.method ?? requestOptionDefaults.method;
356
+ const includesMethod = Boolean(method) && retryMethods.has(method);
378
357
  const selectedStatusCodeArray = options.retryStatusCodes ?? options.retry?.statusCodes;
379
358
  const retryStatusCodes = selectedStatusCodeArray ? new Set(selectedStatusCodeArray) : null;
380
- const includesMethod = Boolean(ctx.request.method) && retryMethods.has(ctx.request.method);
381
359
  const includesStatusCodes = Boolean(ctx.response?.status) && (retryStatusCodes?.has(ctx.response.status) ?? true);
382
360
  const shouldRetry = baseShouldRetry && includesMethod && includesStatusCodes;
383
361
  return shouldRetry;
384
362
  };
385
- const executeRetryHook = async (shouldThrowOnError) => {
386
- try {
387
- return await executeHooks(options.onRetry?.(ctx));
388
- } catch (error) {
389
- const { apiDetails } = resolveErrorResult({
390
- cloneResponse: options.cloneResponse,
391
- defaultErrorMessage: options.defaultErrorMessage,
392
- error,
393
- resultMode: options.resultMode
394
- });
395
- if (shouldThrowOnError) {
396
- throw error;
397
- }
398
- return apiDetails;
399
- }
400
- };
401
363
  return {
402
- executeRetryHook,
364
+ currentAttemptCount,
403
365
  getDelay,
404
366
  shouldAttemptRetry
405
367
  };
@@ -507,7 +469,7 @@ var createFetchClient = (initBaseConfig = {}) => {
507
469
  const request = {
508
470
  ...resolvedRequestOptions,
509
471
  body: isSerializable(resolvedRequestOptions.body) ? bodySerializer(resolvedRequestOptions.body) : resolvedRequestOptions.body,
510
- headers: mergeAndResolveHeaders({
472
+ headers: await getHeaders({
511
473
  auth: options.auth,
512
474
  baseHeaders: baseFetchOptions.headers,
513
475
  body: resolvedRequestOptions.body,
@@ -530,16 +492,16 @@ var createFetchClient = (initBaseConfig = {}) => {
530
492
  });
531
493
  await handleRequestCancelStrategy();
532
494
  try {
533
- await executeHooks(options.onRequest?.({ baseConfig, config, options, request }));
534
- request.headers = mergeAndResolveHeaders({
495
+ await executeHooksInTryBlock(options.onRequest?.({ baseConfig, config, options, request }));
496
+ request.headers = await getHeaders({
535
497
  auth: options.auth,
536
498
  body: request.body,
537
499
  headers: request.headers
538
500
  });
539
501
  const response = await handleRequestDeferStrategy();
540
502
  const shouldCloneResponse = dedupeStrategy === "defer" || options.cloneResponse;
541
- const schemas = isFunction(options.schemas) ? options.schemas({ baseSchemas: baseExtraOptions.schemas ?? {} }) : options.schemas;
542
- const validators = isFunction(options.validators) ? options.validators({ baseValidators: baseExtraOptions.validators ?? {} }) : options.validators;
503
+ const schemas = isFunction(options.schemas) ? options.schemas({ baseSchemas: baseExtraOptions.schemas }) : options.schemas;
504
+ const validators = isFunction(options.validators) ? options.validators({ baseValidators: baseExtraOptions.validators }) : options.validators;
543
505
  if (!response.ok) {
544
506
  const errorData = await resolveResponseData(
545
507
  shouldCloneResponse ? response.clone() : response,
@@ -571,74 +533,89 @@ var createFetchClient = (initBaseConfig = {}) => {
571
533
  request,
572
534
  response
573
535
  };
574
- await executeHooks(
536
+ await executeHooksInTryBlock(
575
537
  options.onSuccess?.(successContext),
576
538
  options.onResponse?.({ ...successContext, error: null })
577
539
  );
578
- return await resolveSuccessResult({
579
- data: successContext.data,
540
+ const successResult = await resolveSuccessResult(successContext.data, {
580
541
  response: successContext.response,
581
542
  resultMode: options.resultMode
582
543
  });
544
+ return successResult;
583
545
  } catch (error) {
584
- const { apiDetails, getErrorResult } = resolveErrorResult({
546
+ const errorInfo = {
585
547
  cloneResponse: options.cloneResponse,
586
548
  defaultErrorMessage: options.defaultErrorMessage,
587
- error,
588
549
  resultMode: options.resultMode
589
- });
550
+ };
551
+ const generalErrorResult = resolveErrorResult(error, errorInfo);
590
552
  const errorContext = {
591
553
  baseConfig,
592
554
  config,
593
- error: apiDetails.error,
555
+ error: generalErrorResult?.error,
594
556
  options,
595
557
  request,
596
- response: apiDetails.response
558
+ response: generalErrorResult?.response
597
559
  };
598
560
  const shouldThrowOnError = isFunction(options.throwOnError) ? options.throwOnError(errorContext) : options.throwOnError;
599
- const handleRetryOrGetResult = async (customInfo) => {
600
- const { executeRetryHook, getDelay, shouldAttemptRetry } = createRetryStrategy(errorContext);
561
+ const executeHooksInCatchBlock = createExecuteHooksFn({ errorInfo, shouldThrowOnError });
562
+ const handleRetryOrGetErrorResult = async () => {
563
+ const { currentAttemptCount, getDelay, shouldAttemptRetry } = createRetryStrategy(errorContext);
601
564
  const shouldRetry = !combinedSignal.aborted && await shouldAttemptRetry();
602
565
  if (shouldRetry) {
603
- await executeRetryHook(shouldThrowOnError);
566
+ const retryContext = {
567
+ ...errorContext,
568
+ retryAttemptCount: currentAttemptCount
569
+ };
570
+ const hookError2 = await executeHooksInCatchBlock(options.onRetry?.(retryContext));
571
+ if (hookError2) {
572
+ return hookError2;
573
+ }
604
574
  const delay = getDelay();
605
575
  await waitUntil(delay);
606
576
  const updatedOptions = {
607
577
  ...config,
608
- "~retryAttemptCount": (options["~retryAttemptCount"] ?? 0) + 1
578
+ "~retryAttemptCount": currentAttemptCount + 1
609
579
  };
610
580
  return callApi2(initURL, updatedOptions);
611
581
  }
612
582
  if (shouldThrowOnError) {
613
583
  throw error;
614
584
  }
615
- return customInfo ? getErrorResult(customInfo) : getErrorResult();
585
+ return generalErrorResult;
616
586
  };
617
587
  if (isHTTPErrorInstance(error)) {
618
- await executeHooks(
588
+ const hookError2 = await executeHooksInCatchBlock(
619
589
  options.onResponseError?.(errorContext),
620
590
  options.onError?.(errorContext),
621
591
  options.onResponse?.({ ...errorContext, data: null })
622
592
  );
623
- return await handleRetryOrGetResult();
593
+ if (hookError2) {
594
+ return hookError2;
595
+ }
596
+ return await handleRetryOrGetErrorResult();
624
597
  }
625
598
  if (error instanceof DOMException && error.name === "AbortError") {
626
599
  const { message, name } = error;
627
600
  !shouldThrowOnError && console.error(`${name}:`, message);
628
- return await handleRetryOrGetResult();
601
+ return await handleRetryOrGetErrorResult();
629
602
  }
630
603
  if (error instanceof DOMException && error.name === "TimeoutError") {
631
604
  const message = `Request timed out after ${options.timeout}ms`;
632
605
  !shouldThrowOnError && console.error(`${error.name}:`, message);
633
- return await handleRetryOrGetResult({ message });
606
+ const errorResult = await handleRetryOrGetErrorResult();
607
+ return getCustomizedErrorResult(errorResult, { message });
634
608
  }
635
- await executeHooks(
609
+ const hookError = await executeHooksInCatchBlock(
636
610
  // == At this point only the request errors exist, so the request error hook is called
637
611
  options.onRequestError?.(errorContext),
638
612
  // == Also call the onError hook
639
613
  options.onError?.(errorContext)
640
614
  );
641
- return await handleRetryOrGetResult();
615
+ if (hookError) {
616
+ return hookError;
617
+ }
618
+ return await handleRetryOrGetErrorResult();
642
619
  } finally {
643
620
  removeDedupeKeyFromCache();
644
621
  }