@apifuse/provider-sdk 2.2.0-beta.61 → 2.2.0-beta.62
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/bin/apifuse-pack-types.ts +16 -12
- package/dist/handle-meta.d.ts +18 -2
- package/dist/handle-meta.js +30 -2
- package/dist/handle.d.ts +33 -12
- package/dist/handle.js +69 -24
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/lint.js +28 -8
- package/dist/provider.d.ts +2 -0
- package/dist/provider.js +2 -0
- package/dist/runtime/handle.js +15 -10
- package/dist/runtime/http-telemetry-binding.d.ts +10 -0
- package/dist/runtime/http-telemetry-binding.js +152 -0
- package/dist/runtime/http-telemetry-guard.d.ts +6 -0
- package/dist/runtime/http-telemetry-guard.js +150 -0
- package/dist/runtime/http-telemetry.d.ts +104 -0
- package/dist/runtime/http-telemetry.js +190 -0
- package/dist/runtime/http.d.ts +31 -0
- package/dist/runtime/http.js +222 -146
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +1 -0
- package/dist/server/serve-implementation.d.ts +2 -0
- package/dist/server/serve-implementation.js +34 -35
- package/package.json +1 -1
- package/src/handle-meta.ts +39 -4
- package/src/handle.ts +121 -38
- package/src/index.ts +19 -0
- package/src/lint.ts +30 -7
- package/src/provider.ts +10 -0
- package/src/runtime/handle.ts +20 -10
- package/src/runtime/http-telemetry-binding.ts +162 -0
- package/src/runtime/http-telemetry-guard.ts +155 -0
- package/src/runtime/http-telemetry.ts +292 -0
- package/src/runtime/http.ts +295 -173
- package/src/server/index.ts +13 -0
- package/src/server/serve-implementation.ts +41 -58
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { NativeTelemetryCollector } from "../runtime/native-telemetry.js";
|
|
2
1
|
import { STATUS_CODES } from "node:http";
|
|
3
2
|
import { readDiagnosticEnv, withDiagnosticEnv } from "../runtime/diagnostic-env.js";
|
|
4
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -77,6 +76,13 @@ import {
|
|
|
77
76
|
import { createEnvContext } from "../runtime/env.js";
|
|
78
77
|
import { executeOperation } from "../runtime/executor.js";
|
|
79
78
|
import { createHttpClient } from "../runtime/http.js";
|
|
79
|
+
import { NativeTelemetryCollector } from "../runtime/native-telemetry.js";
|
|
80
|
+
import {
|
|
81
|
+
bindHttpTelemetry,
|
|
82
|
+
isSupportedHttpBinding,
|
|
83
|
+
warnUnsupportedHttpBinding,
|
|
84
|
+
} from "../runtime/http-telemetry-binding.js";
|
|
85
|
+
import { HttpTelemetryCollector, type HttpTelemetryLogPayload } from "../runtime/http-telemetry.js";
|
|
80
86
|
import { wrapWithInstrumentation } from "../runtime/instrumentation.js";
|
|
81
87
|
import type * as NativeNetworkRuntimeModule from "../runtime/native-network.js";
|
|
82
88
|
import { createOcrClientFromEnv } from "../runtime/ocr.js";
|
|
@@ -153,7 +159,6 @@ import type {
|
|
|
153
159
|
BrowserClient,
|
|
154
160
|
FlowContext,
|
|
155
161
|
FlowContextStore,
|
|
156
|
-
HttpRetrySummary,
|
|
157
162
|
OcrContext,
|
|
158
163
|
OperationDefinition,
|
|
159
164
|
OperationErrorCode,
|
|
@@ -234,29 +239,7 @@ function providerErrorCode(error: unknown): string | undefined {
|
|
|
234
239
|
}
|
|
235
240
|
|
|
236
241
|
const AUTH_FLOW_LOCALES = ["en", "ko", "ja"] as const;
|
|
237
|
-
const retryResponseMeta = new WeakMap<ProviderContext,
|
|
238
|
-
type RetryLastErrorCode =
|
|
239
|
-
// runtime/http.ts:178-179 preserves ambient cancellation.
|
|
240
|
-
| "transport_cancelled"
|
|
241
|
-
// runtime/http.ts:180-196 normalizes timeout aborts and timeout-shaped errors.
|
|
242
|
-
| "transport_timeout"
|
|
243
|
-
// runtime/http.ts:198-225 normalizes other native fetch failures.
|
|
244
|
-
| "transport_network_error"
|
|
245
|
-
// runtime/http.ts:119-126,763-771,829-837 creates upstream status errors.
|
|
246
|
-
| "upstream_http_error"
|
|
247
|
-
// runtime/proxy-retry-policy.ts:64-84 forwards other coded TransportErrors; the builder closes them.
|
|
248
|
-
| "other";
|
|
249
|
-
const RETRY_LAST_ERROR_CODES = [
|
|
250
|
-
"transport_cancelled",
|
|
251
|
-
"transport_timeout",
|
|
252
|
-
"transport_network_error",
|
|
253
|
-
"upstream_http_error",
|
|
254
|
-
"other",
|
|
255
|
-
] as const satisfies readonly RetryLastErrorCode[];
|
|
256
|
-
|
|
257
|
-
function tenantRetryLastErrorCode(value: string): RetryLastErrorCode {
|
|
258
|
-
return RETRY_LAST_ERROR_CODES.find((candidate) => candidate === value) ?? "other";
|
|
259
|
-
}
|
|
242
|
+
const retryResponseMeta = new WeakMap<ProviderContext, HttpTelemetryCollector>();
|
|
260
243
|
const STATEFUL_INTERNAL_OPERATIONS_ROUTE = "/__apifuse/stateful/operations";
|
|
261
244
|
const STATEFUL_FORWARDING_SOURCE_POD_HEADER = "x-apifuse-stateful-source-pod";
|
|
262
245
|
const DEFAULT_STATEFUL_FORWARDING_MAX_SKEW_MS = 5 * 60_000;
|
|
@@ -845,6 +828,7 @@ type RequestScopeContext = {
|
|
|
845
828
|
telemetry: RequestTelemetry;
|
|
846
829
|
resolverTelemetry: ResolverTelemetryCollector;
|
|
847
830
|
nativeTelemetry: NativeTelemetryCollector;
|
|
831
|
+
httpTelemetry: HttpTelemetryCollector;
|
|
848
832
|
};
|
|
849
833
|
|
|
850
834
|
function createProviderContext(
|
|
@@ -873,7 +857,6 @@ function createProviderContext(
|
|
|
873
857
|
request.requestId,
|
|
874
858
|
);
|
|
875
859
|
const cache = createProviderCache({ providerId: provider.id });
|
|
876
|
-
let wrappedContext: ProviderContext | undefined;
|
|
877
860
|
const { capabilityModules } = options;
|
|
878
861
|
const resolverOptions = createResolverRuntimeOptions(
|
|
879
862
|
provider,
|
|
@@ -941,10 +924,7 @@ function createProviderContext(
|
|
|
941
924
|
http: createHttpClient(baseUrl, {
|
|
942
925
|
...proxyClientOptions,
|
|
943
926
|
...(signal ? { signal } : {}),
|
|
944
|
-
|
|
945
|
-
if (summary.attempts <= 1 || !wrappedContext) return;
|
|
946
|
-
retryResponseMeta.set(wrappedContext, summary);
|
|
947
|
-
},
|
|
927
|
+
httpTelemetry: scope.httpTelemetry,
|
|
948
928
|
}),
|
|
949
929
|
cache,
|
|
950
930
|
state: requestState,
|
|
@@ -1015,10 +995,30 @@ function createProviderContext(
|
|
|
1015
995
|
}),
|
|
1016
996
|
}),
|
|
1017
997
|
};
|
|
1018
|
-
const
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
998
|
+
const candidateHttp = bindings.http;
|
|
999
|
+
const attached = options.engine.attach({ provider, bindings }) as ProviderContext;
|
|
1000
|
+
const hostHttp = provider.http ? attached.http : undefined;
|
|
1001
|
+
const supportedHostHttp = provider.http && isSupportedHttpBinding(hostHttp);
|
|
1002
|
+
if (provider.http && !supportedHostHttp) warnUnsupportedHttpBinding();
|
|
1003
|
+
const observedHttp =
|
|
1004
|
+
supportedHostHttp && hostHttp !== candidateHttp
|
|
1005
|
+
? bindHttpTelemetry(hostHttp, scope.httpTelemetry)
|
|
1006
|
+
: undefined;
|
|
1007
|
+
const contextTarget = observedHttp
|
|
1008
|
+
? new Proxy(attached, {
|
|
1009
|
+
get(target, property, receiver) {
|
|
1010
|
+
return property === "http" ? observedHttp : Reflect.get(target, property, receiver);
|
|
1011
|
+
},
|
|
1012
|
+
})
|
|
1013
|
+
: provider.http && !supportedHostHttp
|
|
1014
|
+
? new Proxy(attached, {
|
|
1015
|
+
get(target, property, receiver) {
|
|
1016
|
+
return property === "http" ? undefined : Reflect.get(target, property, receiver);
|
|
1017
|
+
},
|
|
1018
|
+
})
|
|
1019
|
+
: attached;
|
|
1020
|
+
const context = wrapWithInstrumentation(contextTarget);
|
|
1021
|
+
retryResponseMeta.set(context, scope.httpTelemetry);
|
|
1022
1022
|
return context;
|
|
1023
1023
|
}
|
|
1024
1024
|
|
|
@@ -1199,6 +1199,7 @@ function createAuthFlowContext(
|
|
|
1199
1199
|
http: createHttpClient(baseUrl, {
|
|
1200
1200
|
...proxyClientOptions,
|
|
1201
1201
|
...(signal ? { signal } : {}),
|
|
1202
|
+
httpTelemetry: scope.httpTelemetry,
|
|
1202
1203
|
}),
|
|
1203
1204
|
state: state.forConnection(resolveOperationConnectionId(request)),
|
|
1204
1205
|
stealth: stealthBaseUrl
|
|
@@ -1288,6 +1289,7 @@ type ProviderServerLogEventBase = ProviderRequestCost & {
|
|
|
1288
1289
|
status: number;
|
|
1289
1290
|
proxy?: ProxyTelemetryLogPayload;
|
|
1290
1291
|
resolver?: ResolverTelemetryLogPayload;
|
|
1292
|
+
http?: HttpTelemetryLogPayload;
|
|
1291
1293
|
};
|
|
1292
1294
|
|
|
1293
1295
|
export type ProviderServerLogEvent =
|
|
@@ -2276,10 +2278,12 @@ function createRequestScope(input: {
|
|
|
2276
2278
|
const proxyCollector = new ProxyTelemetryCollector();
|
|
2277
2279
|
const resolverCollector = new ResolverTelemetryCollector({ redact });
|
|
2278
2280
|
const nativeCollector = new NativeTelemetryCollector({ redact });
|
|
2281
|
+
const httpCollector = new HttpTelemetryCollector({ redact });
|
|
2279
2282
|
const telemetry = new RequestTelemetry(trace);
|
|
2280
2283
|
telemetry.register(proxyCollector);
|
|
2281
2284
|
telemetry.register(resolverCollector);
|
|
2282
2285
|
telemetry.register(nativeCollector);
|
|
2286
|
+
telemetry.register(httpCollector);
|
|
2283
2287
|
let rootRunner: <T>(fn: () => Promise<T>) => Promise<T> = (fn) => fn();
|
|
2284
2288
|
let resolveRoot!: (outcome: RequestTerminalOutcome) => void;
|
|
2285
2289
|
const rootTerminal = new Promise<RequestTerminalOutcome>((resolve) => {
|
|
@@ -2362,6 +2366,7 @@ function createRequestScope(input: {
|
|
|
2362
2366
|
telemetry,
|
|
2363
2367
|
resolverTelemetry: resolverCollector,
|
|
2364
2368
|
nativeTelemetry: nativeCollector,
|
|
2369
|
+
httpTelemetry: httpCollector,
|
|
2365
2370
|
seedCredentials(rawBody, kind): void {
|
|
2366
2371
|
const harvested = rawRequestCredentials(rawBody, kind);
|
|
2367
2372
|
sensitiveRegistry.add(harvested.values);
|
|
@@ -2581,21 +2586,13 @@ function toJsonSuccessResponse(
|
|
|
2581
2586
|
}
|
|
2582
2587
|
|
|
2583
2588
|
const cacheMeta = ctx && "cache" in ctx ? ctx.cache.responseMeta() : undefined;
|
|
2584
|
-
const
|
|
2589
|
+
const retry = ctx ? retryResponseMeta.get(ctx)?.toTenantRetryPayload() : undefined;
|
|
2585
2590
|
type TenantCacheMeta = {
|
|
2586
2591
|
hit: boolean;
|
|
2587
2592
|
stale: boolean;
|
|
2588
2593
|
keys: TenantOpaqueKeys;
|
|
2589
2594
|
source?: ClosedEnum<NonNullable<ProviderCacheResponseMeta["source"]>>;
|
|
2590
2595
|
};
|
|
2591
|
-
type TenantRetryMeta = {
|
|
2592
|
-
attempts: number;
|
|
2593
|
-
retries: number;
|
|
2594
|
-
preset?: ClosedEnum<NonNullable<HttpRetrySummary["preset"]>>;
|
|
2595
|
-
transport: ClosedEnum<HttpRetrySummary["transport"]>;
|
|
2596
|
-
lastErrorCode?: ClosedEnum<RetryLastErrorCode>;
|
|
2597
|
-
lastStatus?: number;
|
|
2598
|
-
};
|
|
2599
2596
|
const cache: TenantNeutral<TenantCacheMeta> | undefined = cacheMeta
|
|
2600
2597
|
? {
|
|
2601
2598
|
hit: cacheMeta.hit,
|
|
@@ -2605,22 +2602,8 @@ function toJsonSuccessResponse(
|
|
|
2605
2602
|
...(cacheMeta.source ? { source: closedEnum(cacheMeta.source) } : {}),
|
|
2606
2603
|
}
|
|
2607
2604
|
: undefined;
|
|
2608
|
-
const retry: TenantNeutral<TenantRetryMeta> | undefined = retryMeta
|
|
2609
|
-
? {
|
|
2610
|
-
attempts: retryMeta.attempts,
|
|
2611
|
-
retries: retryMeta.retries,
|
|
2612
|
-
...(retryMeta.preset ? { preset: closedEnum(retryMeta.preset) } : {}),
|
|
2613
|
-
transport: closedEnum(retryMeta.transport),
|
|
2614
|
-
...(retryMeta.lastErrorCode
|
|
2615
|
-
? {
|
|
2616
|
-
lastErrorCode: closedEnum(tenantRetryLastErrorCode(retryMeta.lastErrorCode)),
|
|
2617
|
-
}
|
|
2618
|
-
: {}),
|
|
2619
|
-
...(retryMeta.lastStatus ? { lastStatus: retryMeta.lastStatus } : {}),
|
|
2620
|
-
}
|
|
2621
|
-
: undefined;
|
|
2622
2605
|
const meta =
|
|
2623
|
-
cacheMeta ||
|
|
2606
|
+
cacheMeta || retry
|
|
2624
2607
|
? {
|
|
2625
2608
|
...(cache
|
|
2626
2609
|
? {
|