@zayne-labs/callapi 1.7.8 → 1.7.12

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-DLKKYMSL.js';
2
- export { HTTPError } from './chunk-DLKKYMSL.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, isHTTPError, 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;
@@ -342,14 +320,16 @@ var getLinearDelay = (currentAttemptCount, options) => {
342
320
  };
343
321
  var getExponentialDelay = (currentAttemptCount, options) => {
344
322
  const retryDelay = options.retryDelay ?? options.retry?.delay ?? retryDefaults.delay;
345
- const resolveRetryDelay = Number(isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay);
323
+ const resolvedRetryDelay = Number(
324
+ isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay
325
+ );
346
326
  const maxDelay = Number(options.retryMaxDelay ?? options.retry?.maxDelay ?? retryDefaults.maxDelay);
347
- const exponentialDelay = resolveRetryDelay * 2 ** currentAttemptCount;
327
+ const exponentialDelay = resolvedRetryDelay * 2 ** currentAttemptCount;
348
328
  return Math.min(exponentialDelay, maxDelay);
349
329
  };
350
330
  var createRetryStrategy = (ctx) => {
351
331
  const { options } = ctx;
352
- const currentAttemptCount = options["~retryAttemptCount"] ?? 0;
332
+ const currentAttemptCount = options["~retryAttemptCount"] ?? 1;
353
333
  const retryStrategy = options.retryStrategy ?? options.retry?.strategy ?? retryDefaults.strategy;
354
334
  const getDelay = () => {
355
335
  switch (retryStrategy) {
@@ -360,46 +340,33 @@ var createRetryStrategy = (ctx) => {
360
340
  return getLinearDelay(currentAttemptCount, options);
361
341
  }
362
342
  default: {
363
- throw new Error(`Invalid retry strategy: ${retryStrategy}`);
343
+ throw new Error(`Invalid retry strategy: ${String(retryStrategy)}`);
364
344
  }
365
345
  }
366
346
  };
367
347
  const shouldAttemptRetry = async () => {
368
348
  const retryCondition = options.retryCondition ?? options.retry?.condition ?? retryDefaults.condition;
369
- const maxRetryAttempts = options.retryAttempts ?? options.retry?.attempts ?? retryDefaults.attempts;
349
+ const maximumRetryAttempts = options.retryAttempts ?? options.retry?.attempts ?? retryDefaults.attempts;
370
350
  const customRetryCondition = await retryCondition(ctx);
371
- const baseShouldRetry = maxRetryAttempts > currentAttemptCount && customRetryCondition;
372
- if (ctx.error.name !== "HTTPError") {
373
- return baseShouldRetry;
351
+ const baseShouldRetry = maximumRetryAttempts >= currentAttemptCount && customRetryCondition;
352
+ if (!baseShouldRetry) {
353
+ return false;
374
354
  }
375
- const retryMethods = new Set(
376
- options.retryMethods ?? options.retry?.methods ?? retryDefaults.methods
377
- );
355
+ if (!isHTTPError(ctx.error)) {
356
+ return true;
357
+ }
358
+ const selectedMethodArray = options.retryMethods ?? options.retry?.methods ?? retryDefaults.methods;
359
+ const retryMethods = new Set(selectedMethodArray);
360
+ const method = ctx.request.method ?? requestOptionDefaults.method;
361
+ const includesMethod = Boolean(method) && retryMethods.has(method);
378
362
  const selectedStatusCodeArray = options.retryStatusCodes ?? options.retry?.statusCodes;
379
363
  const retryStatusCodes = selectedStatusCodeArray ? new Set(selectedStatusCodeArray) : null;
380
- const includesMethod = Boolean(ctx.request.method) && retryMethods.has(ctx.request.method);
381
364
  const includesStatusCodes = Boolean(ctx.response?.status) && (retryStatusCodes?.has(ctx.response.status) ?? true);
382
- const shouldRetry = baseShouldRetry && includesMethod && includesStatusCodes;
365
+ const shouldRetry = includesMethod && includesStatusCodes;
383
366
  return shouldRetry;
384
367
  };
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
368
  return {
402
- executeRetryHook,
369
+ currentAttemptCount,
403
370
  getDelay,
404
371
  shouldAttemptRetry
405
372
  };
@@ -507,7 +474,7 @@ var createFetchClient = (initBaseConfig = {}) => {
507
474
  const request = {
508
475
  ...resolvedRequestOptions,
509
476
  body: isSerializable(resolvedRequestOptions.body) ? bodySerializer(resolvedRequestOptions.body) : resolvedRequestOptions.body,
510
- headers: mergeAndResolveHeaders({
477
+ headers: await getHeaders({
511
478
  auth: options.auth,
512
479
  baseHeaders: baseFetchOptions.headers,
513
480
  body: resolvedRequestOptions.body,
@@ -530,16 +497,16 @@ var createFetchClient = (initBaseConfig = {}) => {
530
497
  });
531
498
  await handleRequestCancelStrategy();
532
499
  try {
533
- await executeHooks(options.onRequest?.({ baseConfig, config, options, request }));
534
- request.headers = mergeAndResolveHeaders({
500
+ await executeHooksInTryBlock(options.onRequest?.({ baseConfig, config, options, request }));
501
+ request.headers = await getHeaders({
535
502
  auth: options.auth,
536
503
  body: request.body,
537
504
  headers: request.headers
538
505
  });
539
506
  const response = await handleRequestDeferStrategy();
540
507
  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;
508
+ const schemas = isFunction(options.schemas) ? options.schemas({ baseSchemas: baseExtraOptions.schemas }) : options.schemas;
509
+ const validators = isFunction(options.validators) ? options.validators({ baseValidators: baseExtraOptions.validators }) : options.validators;
543
510
  if (!response.ok) {
544
511
  const errorData = await resolveResponseData(
545
512
  shouldCloneResponse ? response.clone() : response,
@@ -571,74 +538,89 @@ var createFetchClient = (initBaseConfig = {}) => {
571
538
  request,
572
539
  response
573
540
  };
574
- await executeHooks(
541
+ await executeHooksInTryBlock(
575
542
  options.onSuccess?.(successContext),
576
543
  options.onResponse?.({ ...successContext, error: null })
577
544
  );
578
- return await resolveSuccessResult({
579
- data: successContext.data,
545
+ const successResult = await resolveSuccessResult(successContext.data, {
580
546
  response: successContext.response,
581
547
  resultMode: options.resultMode
582
548
  });
549
+ return successResult;
583
550
  } catch (error) {
584
- const { apiDetails, getErrorResult } = resolveErrorResult({
551
+ const errorInfo = {
585
552
  cloneResponse: options.cloneResponse,
586
553
  defaultErrorMessage: options.defaultErrorMessage,
587
- error,
588
554
  resultMode: options.resultMode
589
- });
555
+ };
556
+ const generalErrorResult = resolveErrorResult(error, errorInfo);
590
557
  const errorContext = {
591
558
  baseConfig,
592
559
  config,
593
- error: apiDetails.error,
560
+ error: generalErrorResult?.error,
594
561
  options,
595
562
  request,
596
- response: apiDetails.response
563
+ response: generalErrorResult?.response
597
564
  };
598
565
  const shouldThrowOnError = isFunction(options.throwOnError) ? options.throwOnError(errorContext) : options.throwOnError;
599
- const handleRetryOrGetResult = async (customInfo) => {
600
- const { executeRetryHook, getDelay, shouldAttemptRetry } = createRetryStrategy(errorContext);
566
+ const executeHooksInCatchBlock = createExecuteHooksFn({ errorInfo, shouldThrowOnError });
567
+ const handleRetryOrGetErrorResult = async () => {
568
+ const { currentAttemptCount, getDelay, shouldAttemptRetry } = createRetryStrategy(errorContext);
601
569
  const shouldRetry = !combinedSignal.aborted && await shouldAttemptRetry();
602
570
  if (shouldRetry) {
603
- await executeRetryHook(shouldThrowOnError);
571
+ const retryContext = {
572
+ ...errorContext,
573
+ retryAttemptCount: currentAttemptCount
574
+ };
575
+ const hookError2 = await executeHooksInCatchBlock(options.onRetry?.(retryContext));
576
+ if (hookError2) {
577
+ return hookError2;
578
+ }
604
579
  const delay = getDelay();
605
580
  await waitUntil(delay);
606
581
  const updatedOptions = {
607
582
  ...config,
608
- "~retryAttemptCount": (options["~retryAttemptCount"] ?? 0) + 1
583
+ "~retryAttemptCount": currentAttemptCount + 1
609
584
  };
610
585
  return callApi2(initURL, updatedOptions);
611
586
  }
612
587
  if (shouldThrowOnError) {
613
588
  throw error;
614
589
  }
615
- return customInfo ? getErrorResult(customInfo) : getErrorResult();
590
+ return generalErrorResult;
616
591
  };
617
592
  if (isHTTPErrorInstance(error)) {
618
- await executeHooks(
593
+ const hookError2 = await executeHooksInCatchBlock(
619
594
  options.onResponseError?.(errorContext),
620
595
  options.onError?.(errorContext),
621
596
  options.onResponse?.({ ...errorContext, data: null })
622
597
  );
623
- return await handleRetryOrGetResult();
598
+ if (hookError2) {
599
+ return hookError2;
600
+ }
601
+ return await handleRetryOrGetErrorResult();
624
602
  }
625
603
  if (error instanceof DOMException && error.name === "AbortError") {
626
604
  const { message, name } = error;
627
605
  !shouldThrowOnError && console.error(`${name}:`, message);
628
- return await handleRetryOrGetResult();
606
+ return await handleRetryOrGetErrorResult();
629
607
  }
630
608
  if (error instanceof DOMException && error.name === "TimeoutError") {
631
609
  const message = `Request timed out after ${options.timeout}ms`;
632
610
  !shouldThrowOnError && console.error(`${error.name}:`, message);
633
- return await handleRetryOrGetResult({ message });
611
+ const errorResult = await handleRetryOrGetErrorResult();
612
+ return getCustomizedErrorResult(errorResult, { message });
634
613
  }
635
- await executeHooks(
614
+ const hookError = await executeHooksInCatchBlock(
636
615
  // == At this point only the request errors exist, so the request error hook is called
637
616
  options.onRequestError?.(errorContext),
638
617
  // == Also call the onError hook
639
618
  options.onError?.(errorContext)
640
619
  );
641
- return await handleRetryOrGetResult();
620
+ if (hookError) {
621
+ return hookError;
622
+ }
623
+ return await handleRetryOrGetErrorResult();
642
624
  } finally {
643
625
  removeDedupeKeyFromCache();
644
626
  }