@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/{chunk-UVFIGKZS.js → chunk-SJZKYDA4.js} +94 -56
- package/dist/esm/chunk-SJZKYDA4.js.map +1 -0
- package/dist/esm/{common-BwOrtpui.d.ts → common-CUR8HxVd.d.ts} +120 -138
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +72 -95
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils/index.d.ts +1 -1
- package/dist/esm/utils/index.js +1 -1
- package/package.json +1 -1
- package/dist/esm/chunk-UVFIGKZS.js.map +0 -1
package/dist/esm/index.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import { splitConfig, isFunction, splitBaseConfig, createTimeoutSignal, createCombinedSignal, commonDefaults,
|
2
|
-
export { HTTPError } from './chunk-
|
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
|
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
|
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
|
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
|
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
|
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"] ??
|
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
|
349
|
+
const baseShouldRetry = maxRetryAttempts >= currentAttemptCount && customRetryCondition;
|
372
350
|
if (ctx.error.name !== "HTTPError") {
|
373
351
|
return baseShouldRetry;
|
374
352
|
}
|
375
|
-
const
|
376
|
-
|
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
|
-
|
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:
|
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
|
534
|
-
request.headers =
|
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
|
542
|
-
const validators = isFunction(options.validators) ? options.validators({ baseValidators: baseExtraOptions.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
|
536
|
+
await executeHooksInTryBlock(
|
575
537
|
options.onSuccess?.(successContext),
|
576
538
|
options.onResponse?.({ ...successContext, error: null })
|
577
539
|
);
|
578
|
-
|
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
|
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:
|
555
|
+
error: generalErrorResult?.error,
|
594
556
|
options,
|
595
557
|
request,
|
596
|
-
response:
|
558
|
+
response: generalErrorResult?.response
|
597
559
|
};
|
598
560
|
const shouldThrowOnError = isFunction(options.throwOnError) ? options.throwOnError(errorContext) : options.throwOnError;
|
599
|
-
const
|
600
|
-
|
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
|
-
|
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":
|
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
|
585
|
+
return generalErrorResult;
|
616
586
|
};
|
617
587
|
if (isHTTPErrorInstance(error)) {
|
618
|
-
await
|
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
|
-
|
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
|
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
|
-
|
606
|
+
const errorResult = await handleRetryOrGetErrorResult();
|
607
|
+
return getCustomizedErrorResult(errorResult, { message });
|
634
608
|
}
|
635
|
-
await
|
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
|
-
|
615
|
+
if (hookError) {
|
616
|
+
return hookError;
|
617
|
+
}
|
618
|
+
return await handleRetryOrGetErrorResult();
|
642
619
|
} finally {
|
643
620
|
removeDedupeKeyFromCache();
|
644
621
|
}
|