@apifuse/provider-sdk 2.1.0-beta.19 → 2.1.0-beta.20
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/CHANGELOG.md +4 -0
- package/dist/runtime/http.js +24 -7
- package/package.json +1 -1
- package/src/runtime/http.ts +40 -6
package/CHANGELOG.md
CHANGED
package/dist/runtime/http.js
CHANGED
|
@@ -477,12 +477,18 @@ function isAbsoluteUrl(url) {
|
|
|
477
477
|
function resolveHttpUrl(baseUrl, url) {
|
|
478
478
|
return new URL(url, baseUrl ?? DEFAULT_HTTP_BASE_URL).toString();
|
|
479
479
|
}
|
|
480
|
-
async function resolveNativeProxy(options, clientOptions, warn) {
|
|
480
|
+
async function resolveNativeProxy(options, clientOptions, warn, proxyAttemptOffset = 0) {
|
|
481
|
+
const baseProxyAttempt = clientOptions.proxyAttempt === undefined ||
|
|
482
|
+
!Number.isFinite(clientOptions.proxyAttempt)
|
|
483
|
+
? 0
|
|
484
|
+
: Math.max(0, Math.floor(clientOptions.proxyAttempt));
|
|
481
485
|
const resolvedProxy = await resolveProxyConfigAsync({
|
|
482
486
|
proxy: options.proxy ?? clientOptions.proxy,
|
|
483
487
|
upstream: clientOptions.upstream,
|
|
484
488
|
apifuseConfig: clientOptions.apifuseConfig,
|
|
489
|
+
proxyPolicy: clientOptions.proxyPolicy,
|
|
485
490
|
affinityKey: clientOptions.affinityKey,
|
|
491
|
+
proxyAttempt: baseProxyAttempt + proxyAttemptOffset,
|
|
486
492
|
telemetry: clientOptions.telemetry,
|
|
487
493
|
});
|
|
488
494
|
if (resolvedProxy.shouldWarn) {
|
|
@@ -504,14 +510,15 @@ function normalizeNativeFetchBody(body) {
|
|
|
504
510
|
copied.set(normalized);
|
|
505
511
|
return copied.buffer;
|
|
506
512
|
}
|
|
507
|
-
async function fetchNativeHttp(baseUrl, url, method, options, clientOptions, warn, statusRetryCodes) {
|
|
513
|
+
async function fetchNativeHttp(baseUrl, url, method, options, clientOptions, warn, statusRetryCodes, proxyAttemptOffset = 0) {
|
|
508
514
|
const requestUrl = appendQueryParams(resolveHttpUrl(baseUrl, url), options.params);
|
|
509
515
|
const controller = options.timeout ? new AbortController() : undefined;
|
|
510
516
|
const timeoutHandle = options.timeout
|
|
511
517
|
? setTimeout(() => controller?.abort(), options.timeout)
|
|
512
518
|
: undefined;
|
|
519
|
+
let proxy;
|
|
513
520
|
try {
|
|
514
|
-
|
|
521
|
+
proxy = await resolveNativeProxy(options, clientOptions, warn, proxyAttemptOffset);
|
|
515
522
|
const requestInit = {
|
|
516
523
|
headers: options.headers,
|
|
517
524
|
method,
|
|
@@ -532,6 +539,7 @@ async function fetchNativeHttp(baseUrl, url, method, options, clientOptions, war
|
|
|
532
539
|
status: response.status,
|
|
533
540
|
headers,
|
|
534
541
|
retryable: statusRetryCodes.includes(response.status),
|
|
542
|
+
proxyUsed: Boolean(proxy),
|
|
535
543
|
};
|
|
536
544
|
}
|
|
537
545
|
if (response.status >= 400 && options.throwOnHttpError !== false) {
|
|
@@ -547,7 +555,9 @@ async function fetchNativeHttp(baseUrl, url, method, options, clientOptions, war
|
|
|
547
555
|
if (error instanceof SyntaxError) {
|
|
548
556
|
throw error;
|
|
549
557
|
}
|
|
550
|
-
|
|
558
|
+
const transportError = toHttpTransportError(error);
|
|
559
|
+
transportError.proxyUsed = Boolean(proxy);
|
|
560
|
+
throw transportError;
|
|
551
561
|
}
|
|
552
562
|
finally {
|
|
553
563
|
if (timeoutHandle)
|
|
@@ -611,20 +621,25 @@ export function createHttpClient(baseUrl, clientOptions = {}) {
|
|
|
611
621
|
assertNoHttpTransportOverrides(options);
|
|
612
622
|
const headersOptions = withClientHeaders(options, clientOptions, options.body);
|
|
613
623
|
const methodName = normalizeHttpMethod(method);
|
|
614
|
-
const
|
|
624
|
+
const explicitRetry = headersOptions.retry !== undefined;
|
|
625
|
+
const retryOptions = normalizeRetryOptions(headersOptions.retry) ??
|
|
626
|
+
(explicitRetry
|
|
627
|
+
? undefined
|
|
628
|
+
: createRetryOptions(HttpRetryPreset.TransportTransient));
|
|
615
629
|
if (retryOptions)
|
|
616
630
|
validateUnsafeRetryMethods(retryOptions);
|
|
617
631
|
const retryEnabled = Boolean(retryOptions &&
|
|
618
632
|
retryOptions.attempts > 1 &&
|
|
619
633
|
isMethodRetryable(methodName, retryOptions));
|
|
620
634
|
const statusRetryEnabled = Boolean(retryEnabled &&
|
|
635
|
+
explicitRetry &&
|
|
621
636
|
retryOptions &&
|
|
622
637
|
retryOptions.statusCodes.length > 0 &&
|
|
623
638
|
headersOptions.throwOnHttpError !== false);
|
|
624
639
|
const attemptOptions = statusRetryEnabled
|
|
625
640
|
? { ...headersOptions, throwOnHttpError: false }
|
|
626
641
|
: headersOptions;
|
|
627
|
-
const executeOnce = () => fetchNativeHttp(baseUrl, url, methodName, attemptOptions, clientOptions, warnOnce, statusRetryEnabled ? retryOptions?.statusCodes : undefined);
|
|
642
|
+
const executeOnce = (proxyAttemptOffset = 0) => fetchNativeHttp(baseUrl, url, methodName, attemptOptions, clientOptions, warnOnce, statusRetryEnabled ? retryOptions?.statusCodes : undefined, proxyAttemptOffset);
|
|
628
643
|
if (!retryEnabled || !retryOptions) {
|
|
629
644
|
const outcome = await executeOnce();
|
|
630
645
|
if (isHttpStatusOutcome(outcome)) {
|
|
@@ -636,7 +651,7 @@ export function createHttpClient(baseUrl, clientOptions = {}) {
|
|
|
636
651
|
let lastStatus;
|
|
637
652
|
for (let attempt = 1; attempt <= retryOptions.attempts; attempt += 1) {
|
|
638
653
|
try {
|
|
639
|
-
const outcome = await executeOnce();
|
|
654
|
+
const outcome = await executeOnce(attempt - 1);
|
|
640
655
|
if (isHttpStatusOutcome(outcome)) {
|
|
641
656
|
lastStatus = outcome.status;
|
|
642
657
|
if (outcome.retryable && attempt < retryOptions.attempts) {
|
|
@@ -666,7 +681,9 @@ export function createHttpClient(baseUrl, clientOptions = {}) {
|
|
|
666
681
|
catch (error) {
|
|
667
682
|
lastErrorCode = retryErrorCode(error);
|
|
668
683
|
lastStatus = retryErrorStatus(error);
|
|
684
|
+
const proxyUsed = Boolean(error.proxyUsed);
|
|
669
685
|
if (attempt < retryOptions.attempts &&
|
|
686
|
+
(explicitRetry || proxyUsed) &&
|
|
670
687
|
shouldRetryTransportError(error, retryOptions)) {
|
|
671
688
|
await sleep(computeRetryDelayMs(retryOptions, attempt));
|
|
672
689
|
continue;
|
package/package.json
CHANGED
package/src/runtime/http.ts
CHANGED
|
@@ -58,8 +58,13 @@ type HttpStatusOutcome = {
|
|
|
58
58
|
status: number;
|
|
59
59
|
headers: Record<string, string>;
|
|
60
60
|
retryable: boolean;
|
|
61
|
+
proxyUsed: boolean;
|
|
61
62
|
};
|
|
62
63
|
|
|
64
|
+
type NativeHttpAttemptOutcome = HttpResponse | HttpStatusOutcome;
|
|
65
|
+
|
|
66
|
+
type NativeHttpAttemptError = TransportError & { proxyUsed?: boolean };
|
|
67
|
+
|
|
63
68
|
function isHttpStatusOutcome(
|
|
64
69
|
outcome: HttpResponse | HttpStatusOutcome,
|
|
65
70
|
): outcome is HttpStatusOutcome {
|
|
@@ -685,12 +690,20 @@ async function resolveNativeProxy(
|
|
|
685
690
|
options: RequestOptions,
|
|
686
691
|
clientOptions: HttpClientOptions,
|
|
687
692
|
warn: (message: string) => void,
|
|
693
|
+
proxyAttemptOffset = 0,
|
|
688
694
|
): Promise<string | undefined> {
|
|
695
|
+
const baseProxyAttempt =
|
|
696
|
+
clientOptions.proxyAttempt === undefined ||
|
|
697
|
+
!Number.isFinite(clientOptions.proxyAttempt)
|
|
698
|
+
? 0
|
|
699
|
+
: Math.max(0, Math.floor(clientOptions.proxyAttempt));
|
|
689
700
|
const resolvedProxy = await resolveProxyConfigAsync({
|
|
690
701
|
proxy: options.proxy ?? clientOptions.proxy,
|
|
691
702
|
upstream: clientOptions.upstream,
|
|
692
703
|
apifuseConfig: clientOptions.apifuseConfig,
|
|
704
|
+
proxyPolicy: clientOptions.proxyPolicy,
|
|
693
705
|
affinityKey: clientOptions.affinityKey,
|
|
706
|
+
proxyAttempt: baseProxyAttempt + proxyAttemptOffset,
|
|
694
707
|
telemetry: clientOptions.telemetry,
|
|
695
708
|
});
|
|
696
709
|
if (resolvedProxy.shouldWarn) {
|
|
@@ -730,7 +743,8 @@ async function fetchNativeHttp(
|
|
|
730
743
|
clientOptions: HttpClientOptions,
|
|
731
744
|
warn: (message: string) => void,
|
|
732
745
|
statusRetryCodes?: readonly number[],
|
|
733
|
-
|
|
746
|
+
proxyAttemptOffset = 0,
|
|
747
|
+
): Promise<NativeHttpAttemptOutcome> {
|
|
734
748
|
const requestUrl = appendQueryParams(
|
|
735
749
|
resolveHttpUrl(baseUrl, url),
|
|
736
750
|
options.params,
|
|
@@ -740,8 +754,14 @@ async function fetchNativeHttp(
|
|
|
740
754
|
? setTimeout(() => controller?.abort(), options.timeout)
|
|
741
755
|
: undefined;
|
|
742
756
|
|
|
757
|
+
let proxy: string | undefined;
|
|
743
758
|
try {
|
|
744
|
-
|
|
759
|
+
proxy = await resolveNativeProxy(
|
|
760
|
+
options,
|
|
761
|
+
clientOptions,
|
|
762
|
+
warn,
|
|
763
|
+
proxyAttemptOffset,
|
|
764
|
+
);
|
|
745
765
|
const requestInit: NativeFetchInit = {
|
|
746
766
|
headers: options.headers,
|
|
747
767
|
method,
|
|
@@ -763,6 +783,7 @@ async function fetchNativeHttp(
|
|
|
763
783
|
status: response.status,
|
|
764
784
|
headers,
|
|
765
785
|
retryable: statusRetryCodes.includes(response.status),
|
|
786
|
+
proxyUsed: Boolean(proxy),
|
|
766
787
|
};
|
|
767
788
|
}
|
|
768
789
|
|
|
@@ -782,7 +803,9 @@ async function fetchNativeHttp(
|
|
|
782
803
|
if (error instanceof SyntaxError) {
|
|
783
804
|
throw error;
|
|
784
805
|
}
|
|
785
|
-
|
|
806
|
+
const transportError = toHttpTransportError(error) as NativeHttpAttemptError;
|
|
807
|
+
transportError.proxyUsed = Boolean(proxy);
|
|
808
|
+
throw transportError;
|
|
786
809
|
} finally {
|
|
787
810
|
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
788
811
|
}
|
|
@@ -874,7 +897,12 @@ export function createHttpClient(
|
|
|
874
897
|
options.body,
|
|
875
898
|
);
|
|
876
899
|
const methodName = normalizeHttpMethod(method);
|
|
877
|
-
const
|
|
900
|
+
const explicitRetry = headersOptions.retry !== undefined;
|
|
901
|
+
const retryOptions =
|
|
902
|
+
normalizeRetryOptions(headersOptions.retry) ??
|
|
903
|
+
(explicitRetry
|
|
904
|
+
? undefined
|
|
905
|
+
: createRetryOptions(HttpRetryPreset.TransportTransient));
|
|
878
906
|
if (retryOptions) validateUnsafeRetryMethods(retryOptions);
|
|
879
907
|
const retryEnabled = Boolean(
|
|
880
908
|
retryOptions &&
|
|
@@ -883,6 +911,7 @@ export function createHttpClient(
|
|
|
883
911
|
);
|
|
884
912
|
const statusRetryEnabled = Boolean(
|
|
885
913
|
retryEnabled &&
|
|
914
|
+
explicitRetry &&
|
|
886
915
|
retryOptions &&
|
|
887
916
|
retryOptions.statusCodes.length > 0 &&
|
|
888
917
|
headersOptions.throwOnHttpError !== false,
|
|
@@ -892,7 +921,9 @@ export function createHttpClient(
|
|
|
892
921
|
? { ...headersOptions, throwOnHttpError: false }
|
|
893
922
|
: headersOptions;
|
|
894
923
|
|
|
895
|
-
const executeOnce = (
|
|
924
|
+
const executeOnce = (
|
|
925
|
+
proxyAttemptOffset = 0,
|
|
926
|
+
): Promise<NativeHttpAttemptOutcome> =>
|
|
896
927
|
fetchNativeHttp(
|
|
897
928
|
baseUrl,
|
|
898
929
|
url,
|
|
@@ -901,6 +932,7 @@ export function createHttpClient(
|
|
|
901
932
|
clientOptions,
|
|
902
933
|
warnOnce,
|
|
903
934
|
statusRetryEnabled ? retryOptions?.statusCodes : undefined,
|
|
935
|
+
proxyAttemptOffset,
|
|
904
936
|
);
|
|
905
937
|
|
|
906
938
|
if (!retryEnabled || !retryOptions) {
|
|
@@ -915,7 +947,7 @@ export function createHttpClient(
|
|
|
915
947
|
let lastStatus: number | undefined;
|
|
916
948
|
for (let attempt = 1; attempt <= retryOptions.attempts; attempt += 1) {
|
|
917
949
|
try {
|
|
918
|
-
const outcome = await executeOnce();
|
|
950
|
+
const outcome = await executeOnce(attempt - 1);
|
|
919
951
|
if (isHttpStatusOutcome(outcome)) {
|
|
920
952
|
lastStatus = outcome.status;
|
|
921
953
|
if (outcome.retryable && attempt < retryOptions.attempts) {
|
|
@@ -950,8 +982,10 @@ export function createHttpClient(
|
|
|
950
982
|
} catch (error) {
|
|
951
983
|
lastErrorCode = retryErrorCode(error);
|
|
952
984
|
lastStatus = retryErrorStatus(error);
|
|
985
|
+
const proxyUsed = Boolean((error as NativeHttpAttemptError).proxyUsed);
|
|
953
986
|
if (
|
|
954
987
|
attempt < retryOptions.attempts &&
|
|
988
|
+
(explicitRetry || proxyUsed) &&
|
|
955
989
|
shouldRetryTransportError(error, retryOptions)
|
|
956
990
|
) {
|
|
957
991
|
await sleep(computeRetryDelayMs(retryOptions, attempt));
|