@zayne-labs/callapi 1.10.4 → 1.10.6
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/{common-Bk1Hh1hR.d.ts → common-0nTMuN7U.d.ts} +8 -2
- package/dist/esm/{utils-Bm4Dvem6.js → common-BFea9qeg.js} +254 -2
- package/dist/esm/common-BFea9qeg.js.map +1 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +19 -261
- 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/utils-Bm4Dvem6.js.map +0 -1
package/dist/esm/index.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { HTTPError, ValidationError, createCombinedSignal, createTimeoutSignal,
|
1
|
+
import { HTTPError, ValidationError, createCombinedSignal, createTimeoutSignal, deterministicHashFn, extraOptionDefaults, fallBackRouteSchemaKey, getBody, getCurrentRouteSchemaKeyAndMainInitURL, getFetchImpl, getFullAndNormalizedURL, getHeaders, getMethod, handleConfigValidation, handleSchemaValidation, isArray, isBoolean, isFunction, isHTTPErrorInstance, isObject, isPlainObject, isReadableStream, isString, isValidationErrorInstance, splitBaseConfig, splitConfig, waitFor } from "./common-BFea9qeg.js";
|
2
2
|
|
3
3
|
//#region src/result.ts
|
4
4
|
const getResponseType = (response, parser) => ({
|
@@ -112,6 +112,7 @@ const getHookRegistries = () => {
|
|
112
112
|
onError: /* @__PURE__ */ new Set(),
|
113
113
|
onRequest: /* @__PURE__ */ new Set(),
|
114
114
|
onRequestError: /* @__PURE__ */ new Set(),
|
115
|
+
onRequestReady: /* @__PURE__ */ new Set(),
|
115
116
|
onRequestStream: /* @__PURE__ */ new Set(),
|
116
117
|
onResponse: /* @__PURE__ */ new Set(),
|
117
118
|
onResponseError: /* @__PURE__ */ new Set(),
|
@@ -327,164 +328,6 @@ const createDedupeStrategy = async (context) => {
|
|
327
328
|
};
|
328
329
|
};
|
329
330
|
|
330
|
-
//#endregion
|
331
|
-
//#region src/validation.ts
|
332
|
-
const handleValidatorFunction = async (validator, inputData) => {
|
333
|
-
try {
|
334
|
-
return {
|
335
|
-
issues: void 0,
|
336
|
-
value: await validator(inputData)
|
337
|
-
};
|
338
|
-
} catch (error) {
|
339
|
-
return {
|
340
|
-
issues: toArray(error),
|
341
|
-
value: void 0
|
342
|
-
};
|
343
|
-
}
|
344
|
-
};
|
345
|
-
const standardSchemaParser = async (fullSchema, schemaName, inputData, response) => {
|
346
|
-
const schema = fullSchema?.[schemaName];
|
347
|
-
if (!schema) return inputData;
|
348
|
-
const result = isFunction(schema) ? await handleValidatorFunction(schema, inputData) : await schema["~standard"].validate(inputData);
|
349
|
-
if (result.issues) throw new ValidationError({
|
350
|
-
issueCause: schemaName,
|
351
|
-
issues: result.issues,
|
352
|
-
response: response ?? null
|
353
|
-
});
|
354
|
-
return result.value;
|
355
|
-
};
|
356
|
-
const routeKeyMethods = defineEnum([
|
357
|
-
"delete",
|
358
|
-
"get",
|
359
|
-
"patch",
|
360
|
-
"post",
|
361
|
-
"put"
|
362
|
-
]);
|
363
|
-
const handleSchemaValidation = async (fullSchema, schemaName, validationOptions) => {
|
364
|
-
const { inputValue, response, schemaConfig } = validationOptions;
|
365
|
-
if (schemaConfig?.disableRuntimeValidation) return inputValue;
|
366
|
-
return await standardSchemaParser(fullSchema, schemaName, inputValue, response);
|
367
|
-
};
|
368
|
-
const extraOptionsToBeValidated = [
|
369
|
-
"meta",
|
370
|
-
"params",
|
371
|
-
"query"
|
372
|
-
];
|
373
|
-
const handleExtraOptionsValidation = async (validationOptions) => {
|
374
|
-
const { options, schema, schemaConfig } = validationOptions;
|
375
|
-
const validationResultArray = await Promise.all(extraOptionsToBeValidated.map((schemaName) => handleSchemaValidation(schema, schemaName, {
|
376
|
-
inputValue: options[schemaName],
|
377
|
-
schemaConfig
|
378
|
-
})));
|
379
|
-
const validatedResultObject = {};
|
380
|
-
for (const [index, schemaName] of extraOptionsToBeValidated.entries()) {
|
381
|
-
const validationResult = validationResultArray[index];
|
382
|
-
if (validationResult === void 0) continue;
|
383
|
-
validatedResultObject[schemaName] = validationResult;
|
384
|
-
}
|
385
|
-
return validatedResultObject;
|
386
|
-
};
|
387
|
-
const requestOptionsToBeValidated = [
|
388
|
-
"body",
|
389
|
-
"headers",
|
390
|
-
"method"
|
391
|
-
];
|
392
|
-
const handleRequestOptionsValidation = async (validationOptions) => {
|
393
|
-
const { requestOptions, schema, schemaConfig } = validationOptions;
|
394
|
-
const validationResultArray = await Promise.all(requestOptionsToBeValidated.map((schemaName) => handleSchemaValidation(schema, schemaName, {
|
395
|
-
inputValue: requestOptions[schemaName],
|
396
|
-
schemaConfig
|
397
|
-
})));
|
398
|
-
const validatedResultObject = {};
|
399
|
-
for (const [index, propertyKey] of requestOptionsToBeValidated.entries()) {
|
400
|
-
const validationResult = validationResultArray[index];
|
401
|
-
if (validationResult === void 0) continue;
|
402
|
-
validatedResultObject[propertyKey] = validationResult;
|
403
|
-
}
|
404
|
-
return validatedResultObject;
|
405
|
-
};
|
406
|
-
const handleConfigValidation = async (validationOptions) => {
|
407
|
-
const { baseExtraOptions, currentRouteSchemaKey, extraOptions, options, requestOptions } = validationOptions;
|
408
|
-
const { currentRouteSchema, resolvedSchema } = getResolvedSchema({
|
409
|
-
baseExtraOptions,
|
410
|
-
currentRouteSchemaKey,
|
411
|
-
extraOptions
|
412
|
-
});
|
413
|
-
const resolvedSchemaConfig = getResolvedSchemaConfig({
|
414
|
-
baseExtraOptions,
|
415
|
-
extraOptions
|
416
|
-
});
|
417
|
-
if (resolvedSchemaConfig?.strict === true && !currentRouteSchema) throw new ValidationError({
|
418
|
-
issueCause: "schemaConfig-(strict)",
|
419
|
-
issues: [{ message: `Strict Mode - No schema found for route '${currentRouteSchemaKey}' ` }],
|
420
|
-
response: null
|
421
|
-
});
|
422
|
-
if (resolvedSchemaConfig?.disableRuntimeValidation) return {
|
423
|
-
extraOptionsValidationResult: null,
|
424
|
-
requestOptionsValidationResult: null,
|
425
|
-
resolvedSchema,
|
426
|
-
resolvedSchemaConfig,
|
427
|
-
shouldApplySchemaOutput: false
|
428
|
-
};
|
429
|
-
const [extraOptionsValidationResult, requestOptionsValidationResult] = await Promise.all([handleExtraOptionsValidation({
|
430
|
-
options,
|
431
|
-
schema: resolvedSchema,
|
432
|
-
schemaConfig: resolvedSchemaConfig
|
433
|
-
}), handleRequestOptionsValidation({
|
434
|
-
requestOptions,
|
435
|
-
schema: resolvedSchema,
|
436
|
-
schemaConfig: resolvedSchemaConfig
|
437
|
-
})]);
|
438
|
-
const shouldApplySchemaOutput = (Boolean(extraOptionsValidationResult) || Boolean(requestOptionsValidationResult)) && !resolvedSchemaConfig?.disableValidationOutputApplication;
|
439
|
-
return {
|
440
|
-
extraOptionsValidationResult,
|
441
|
-
requestOptionsValidationResult,
|
442
|
-
resolvedSchema,
|
443
|
-
resolvedSchemaConfig,
|
444
|
-
shouldApplySchemaOutput
|
445
|
-
};
|
446
|
-
};
|
447
|
-
const fallBackRouteSchemaKey = ".";
|
448
|
-
const getResolvedSchema = (context) => {
|
449
|
-
const { baseExtraOptions, currentRouteSchemaKey, extraOptions } = context;
|
450
|
-
const fallbackRouteSchema = baseExtraOptions.schema?.routes[fallBackRouteSchemaKey];
|
451
|
-
const currentRouteSchema = baseExtraOptions.schema?.routes[currentRouteSchemaKey];
|
452
|
-
const resolvedRouteSchema = {
|
453
|
-
...fallbackRouteSchema,
|
454
|
-
...currentRouteSchema
|
455
|
-
};
|
456
|
-
const resolvedSchema = isFunction(extraOptions.schema) ? extraOptions.schema({
|
457
|
-
baseSchemaRoutes: baseExtraOptions.schema?.routes ?? {},
|
458
|
-
currentRouteSchema: resolvedRouteSchema ?? {}
|
459
|
-
}) : extraOptions.schema ?? resolvedRouteSchema;
|
460
|
-
return {
|
461
|
-
currentRouteSchema,
|
462
|
-
resolvedSchema
|
463
|
-
};
|
464
|
-
};
|
465
|
-
const getResolvedSchemaConfig = (context) => {
|
466
|
-
const { baseExtraOptions, extraOptions } = context;
|
467
|
-
return isFunction(extraOptions.schemaConfig) ? extraOptions.schemaConfig({ baseSchemaConfig: baseExtraOptions.schema?.config ?? {} }) : extraOptions.schemaConfig ?? baseExtraOptions.schema?.config;
|
468
|
-
};
|
469
|
-
const getCurrentRouteSchemaKeyAndMainInitURL = (context) => {
|
470
|
-
const { baseExtraOptions, extraOptions, initURL } = context;
|
471
|
-
const schemaConfig = getResolvedSchemaConfig({
|
472
|
-
baseExtraOptions,
|
473
|
-
extraOptions
|
474
|
-
});
|
475
|
-
let currentRouteSchemaKey = initURL;
|
476
|
-
let mainInitURL = initURL;
|
477
|
-
if (schemaConfig?.prefix && currentRouteSchemaKey.startsWith(schemaConfig.prefix)) {
|
478
|
-
currentRouteSchemaKey = currentRouteSchemaKey.replace(schemaConfig.prefix, "");
|
479
|
-
mainInitURL = mainInitURL.replace(schemaConfig.prefix, schemaConfig.baseURL ?? "");
|
480
|
-
}
|
481
|
-
if (schemaConfig?.baseURL && currentRouteSchemaKey.startsWith(schemaConfig.baseURL)) currentRouteSchemaKey = currentRouteSchemaKey.replace(schemaConfig.baseURL, "");
|
482
|
-
return {
|
483
|
-
currentRouteSchemaKey,
|
484
|
-
mainInitURL
|
485
|
-
};
|
486
|
-
};
|
487
|
-
|
488
331
|
//#endregion
|
489
332
|
//#region src/plugins.ts
|
490
333
|
const getResolvedPlugins = (context) => {
|
@@ -616,100 +459,6 @@ const createRetryStrategy = (ctx) => {
|
|
616
459
|
};
|
617
460
|
};
|
618
461
|
|
619
|
-
//#endregion
|
620
|
-
//#region src/url.ts
|
621
|
-
const slash = "/";
|
622
|
-
const colon = ":";
|
623
|
-
const openBrace = "{";
|
624
|
-
const closeBrace = "}";
|
625
|
-
const mergeUrlWithParams = (url, params) => {
|
626
|
-
if (!params) return url;
|
627
|
-
let newUrl = url;
|
628
|
-
if (isArray(params)) {
|
629
|
-
const matchedParamsArray = newUrl.split(slash).filter((part) => part.startsWith(colon) || part.startsWith(openBrace) && part.endsWith(closeBrace));
|
630
|
-
for (const [paramIndex, matchedParam] of matchedParamsArray.entries()) {
|
631
|
-
const stringParamValue = String(params[paramIndex]);
|
632
|
-
newUrl = newUrl.replace(matchedParam, stringParamValue);
|
633
|
-
}
|
634
|
-
return newUrl;
|
635
|
-
}
|
636
|
-
for (const [paramKey, paramValue] of Object.entries(params)) {
|
637
|
-
const colonPattern = `${colon}${paramKey}`;
|
638
|
-
const bracePattern = `${openBrace}${paramKey}${closeBrace}`;
|
639
|
-
const stringValue = String(paramValue);
|
640
|
-
newUrl = newUrl.replace(colonPattern, stringValue);
|
641
|
-
newUrl = newUrl.replace(bracePattern, stringValue);
|
642
|
-
}
|
643
|
-
return newUrl;
|
644
|
-
};
|
645
|
-
const questionMark = "?";
|
646
|
-
const ampersand = "&";
|
647
|
-
const mergeUrlWithQuery = (url, query) => {
|
648
|
-
if (!query) return url;
|
649
|
-
const queryString = toQueryString(query);
|
650
|
-
if (queryString?.length === 0) return url;
|
651
|
-
if (url.endsWith(questionMark)) return `${url}${queryString}`;
|
652
|
-
if (url.includes(questionMark)) return `${url}${ampersand}${queryString}`;
|
653
|
-
return `${url}${questionMark}${queryString}`;
|
654
|
-
};
|
655
|
-
/**
|
656
|
-
* @description Extracts the HTTP method from method-prefixed route patterns.
|
657
|
-
*
|
658
|
-
* Analyzes URLs that start with method modifiers (e.g., "@get/", "@post/") and extracts
|
659
|
-
* the HTTP method for use in API requests. This enables method specification directly
|
660
|
-
* in route definitions.
|
661
|
-
*
|
662
|
-
* @param initURL - The URL string to analyze for method modifiers
|
663
|
-
* @returns The extracted HTTP method (lowercase) if found, otherwise undefined
|
664
|
-
*
|
665
|
-
* @example
|
666
|
-
* ```typescript
|
667
|
-
* // Method extraction from prefixed routes
|
668
|
-
* extractMethodFromURL("@get/users"); // Returns: "get"
|
669
|
-
* extractMethodFromURL("@post/users"); // Returns: "post"
|
670
|
-
* extractMethodFromURL("@put/users/:id"); // Returns: "put"
|
671
|
-
* extractMethodFromURL("@delete/users/:id"); // Returns: "delete"
|
672
|
-
* extractMethodFromURL("@patch/users/:id"); // Returns: "patch"
|
673
|
-
*
|
674
|
-
* // No method modifier
|
675
|
-
* extractMethodFromURL("/users"); // Returns: undefined
|
676
|
-
* extractMethodFromURL("users"); // Returns: undefined
|
677
|
-
*
|
678
|
-
* // Invalid or unsupported methods
|
679
|
-
* extractMethodFromURL("@invalid/users"); // Returns: undefined
|
680
|
-
* extractMethodFromURL("@/users"); // Returns: undefined
|
681
|
-
*
|
682
|
-
* // Edge cases
|
683
|
-
* extractMethodFromURL(undefined); // Returns: undefined
|
684
|
-
* extractMethodFromURL(""); // Returns: undefined
|
685
|
-
* ```
|
686
|
-
*/
|
687
|
-
const extractMethodFromURL = (initURL) => {
|
688
|
-
if (!initURL?.startsWith("@")) return;
|
689
|
-
const method = initURL.split("@")[1]?.split("/")[0];
|
690
|
-
if (!method || !routeKeyMethods.includes(method)) return;
|
691
|
-
return method;
|
692
|
-
};
|
693
|
-
const getMethod = (ctx) => {
|
694
|
-
const { initURL, method } = ctx;
|
695
|
-
return method?.toUpperCase() ?? extractMethodFromURL(initURL)?.toUpperCase() ?? requestOptionDefaults().method;
|
696
|
-
};
|
697
|
-
const normalizeURL = (initURL) => {
|
698
|
-
const methodFromURL = extractMethodFromURL(initURL);
|
699
|
-
if (!methodFromURL) return initURL;
|
700
|
-
return initURL.replace(`@${methodFromURL}/`, "/");
|
701
|
-
};
|
702
|
-
const getFullAndNormalizedURL = (options) => {
|
703
|
-
const { baseURL, initURL, params, query } = options;
|
704
|
-
const normalizedInitURL = normalizeURL(initURL);
|
705
|
-
const urlWithMergedParams = mergeUrlWithParams(normalizedInitURL, params);
|
706
|
-
const urlWithMergedQueryAndParams = mergeUrlWithQuery(urlWithMergedParams, query);
|
707
|
-
return {
|
708
|
-
fullURL: !urlWithMergedQueryAndParams.startsWith("http") && baseURL ? `${baseURL}${urlWithMergedQueryAndParams}` : urlWithMergedQueryAndParams,
|
709
|
-
normalizedInitURL
|
710
|
-
};
|
711
|
-
};
|
712
|
-
|
713
462
|
//#endregion
|
714
463
|
//#region src/createFetchClient.ts
|
715
464
|
const $GlobalRequestInfoCache = /* @__PURE__ */ new Map();
|
@@ -759,8 +508,13 @@ const createFetchClient = (initBaseConfig = {}) => {
|
|
759
508
|
const newFetchController = new AbortController();
|
760
509
|
const timeoutSignal = options.timeout != null ? createTimeoutSignal(options.timeout) : null;
|
761
510
|
const combinedSignal = createCombinedSignal(resolvedRequestOptions.signal, timeoutSignal, newFetchController.signal);
|
511
|
+
const initMethod = getMethod({
|
512
|
+
initURL: resolvedInitURL,
|
513
|
+
method: resolvedRequestOptions.method
|
514
|
+
});
|
762
515
|
let request = {
|
763
516
|
...resolvedRequestOptions,
|
517
|
+
method: initMethod,
|
764
518
|
signal: combinedSignal
|
765
519
|
};
|
766
520
|
const { getAbortErrorMessage, handleRequestCancelStrategy, handleRequestDeferStrategy, removeDedupeKeyFromCache, resolvedDedupeStrategy } = await createDedupeStrategy({
|
@@ -791,28 +545,32 @@ const createFetchClient = (initBaseConfig = {}) => {
|
|
791
545
|
...options,
|
792
546
|
...extraOptionsValidationResult
|
793
547
|
};
|
794
|
-
const
|
548
|
+
const validMethod = getMethod({
|
549
|
+
initURL: resolvedInitURL,
|
550
|
+
method: shouldApplySchemaOutput ? requestOptionsValidationResult?.method : request.method
|
551
|
+
});
|
795
552
|
const validBody = getBody({
|
796
|
-
body:
|
553
|
+
body: shouldApplySchemaOutput ? requestOptionsValidationResult?.body : request.body,
|
797
554
|
bodySerializer: options.bodySerializer
|
798
555
|
});
|
799
556
|
const resolvedHeaders = isFunction(fetchOptions.headers) ? fetchOptions.headers({ baseHeaders: baseFetchOptions.headers ?? {} }) : fetchOptions.headers ?? baseFetchOptions.headers;
|
800
557
|
const validHeaders = await getHeaders({
|
801
558
|
auth: options.auth,
|
802
|
-
body:
|
559
|
+
body: validBody,
|
803
560
|
headers: shouldApplySchemaOutput ? requestOptionsValidationResult?.headers : resolvedHeaders
|
804
561
|
});
|
805
|
-
const validMethod = getMethod({
|
806
|
-
initURL: resolvedInitURL,
|
807
|
-
method: shouldApplySchemaOutput ? requestOptionsValidationResult?.method : request.method,
|
808
|
-
schemaConfig: resolvedSchemaConfig
|
809
|
-
});
|
810
562
|
request = {
|
811
563
|
...request,
|
812
564
|
...Boolean(validBody) && { body: validBody },
|
813
565
|
...Boolean(validHeaders) && { headers: validHeaders },
|
814
566
|
...Boolean(validMethod) && { method: validMethod }
|
815
567
|
};
|
568
|
+
await executeHooksInTryBlock(options.onRequestReady?.({
|
569
|
+
baseConfig,
|
570
|
+
config,
|
571
|
+
options,
|
572
|
+
request
|
573
|
+
}));
|
816
574
|
const response = await handleRequestDeferStrategy({
|
817
575
|
options,
|
818
576
|
request
|