@apifuse/provider-sdk 2.2.0-beta.5 → 2.2.0-beta.50
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/AUTHORING.md +537 -33
- package/CHANGELOG.md +201 -1
- package/README.md +83 -22
- package/SUBMISSION.md +2 -2
- package/bin/apifuse-check.ts +165 -11
- package/bin/apifuse-dev.ts +57 -13
- package/bin/apifuse-migrate-operation-declaration.ts +55 -0
- package/bin/apifuse-migrate-shape.ts +202 -0
- package/bin/apifuse-pack-check.ts +22 -2
- package/bin/apifuse-pack-smoke.ts +57 -2
- package/bin/apifuse-pack-types.ts +357 -38
- package/bin/apifuse-perf.ts +14 -13
- package/bin/apifuse-record.ts +709 -72
- package/bin/apifuse-submit-check.ts +2344 -324
- package/bin/apifuse-sync-assets.ts +117 -0
- package/bin/submit-check-delimited-text.ts +50 -0
- package/dist/auth-turn/index.d.ts +3 -3
- package/dist/auth-turn/index.js +1 -1
- package/dist/auth.d.ts +14 -0
- package/dist/auth.js +67 -0
- package/dist/ceremonies/index.d.ts +16 -0
- package/dist/ceremonies/index.js +141 -36
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +27 -0
- package/dist/cli/create.d.ts +4 -1
- package/dist/cli/create.js +42 -37
- package/dist/cli/migrate-operation-declaration.d.ts +59 -0
- package/dist/cli/migrate-operation-declaration.js +1178 -0
- package/dist/cli/migrate-operation-shape.d.ts +44 -0
- package/dist/cli/migrate-operation-shape.js +113 -0
- package/dist/cli/migrate-provider-shape.d.ts +52 -0
- package/dist/cli/migrate-provider-shape.js +578 -0
- package/dist/cli/prompt-assets.d.ts +80 -0
- package/dist/cli/prompt-assets.js +743 -0
- package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
- package/dist/cli/templates/provider/README.md.tpl +5 -5
- package/dist/cli/templates/provider/index.ts.tpl +6 -3
- package/dist/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/dist/cli/templates/provider/provider.json.tpl +6 -0
- package/dist/config/loader.d.ts +179 -16
- package/dist/config/loader.js +435 -127
- package/dist/contract-serialization.js +4 -8
- package/dist/contract-types.d.ts +12 -5
- package/dist/contract.js +24 -10
- package/dist/declaration-validation.d.ts +33 -0
- package/dist/declaration-validation.js +266 -0
- package/dist/define.d.ts +66 -29
- package/dist/define.js +778 -69
- package/dist/dev.d.ts +3 -0
- package/dist/dev.js +1 -1
- package/dist/engine.d.ts +78 -0
- package/dist/engine.js +133 -0
- package/dist/error-observability.d.ts +7 -0
- package/dist/error-observability.js +61 -0
- package/dist/error-resolution.d.ts +4 -0
- package/dist/error-resolution.js +122 -0
- package/dist/errors.d.ts +33 -0
- package/dist/errors.js +40 -0
- package/dist/fixture-sanitization.d.ts +28 -0
- package/dist/fixture-sanitization.js +227 -0
- package/dist/health-scenario.d.ts +1842 -0
- package/dist/health-scenario.js +624 -0
- package/dist/index.d.ts +21 -10
- package/dist/index.js +12 -7
- package/dist/lint.d.ts +23 -11
- package/dist/lint.js +572 -69
- package/dist/native-address.d.ts +43 -0
- package/dist/native-address.js +281 -0
- package/dist/native-egress-policy.d.ts +31 -0
- package/dist/native-egress-policy.js +288 -0
- package/dist/observability.d.ts +5 -2
- package/dist/observability.js +48 -1
- package/dist/provider.d.ts +10 -2
- package/dist/provider.js +4 -1
- package/dist/runtime/auth-flow.d.ts +5 -1
- package/dist/runtime/auth-flow.js +6 -0
- package/dist/runtime/browser.d.ts +1 -0
- package/dist/runtime/browser.js +492 -49
- package/dist/runtime/cache.d.ts +1 -0
- package/dist/runtime/cache.js +169 -15
- package/dist/runtime/choice-wordlist.d.ts +9 -0
- package/dist/runtime/choice-wordlist.js +138 -0
- package/dist/runtime/choice.d.ts +13 -1
- package/dist/runtime/choice.js +490 -102
- package/dist/runtime/chrome149-header-order.d.ts +58 -0
- package/dist/runtime/chrome149-header-order.js +289 -0
- package/dist/runtime/env.js +12 -0
- package/dist/runtime/executor.d.ts +3 -2
- package/dist/runtime/executor.js +26 -25
- package/dist/runtime/http.d.ts +1 -0
- package/dist/runtime/http.js +515 -53
- package/dist/runtime/insights.js +2 -2
- package/dist/runtime/instrumentation.d.ts +2 -2
- package/dist/runtime/instrumentation.js +366 -8
- package/dist/runtime/native-network-errors.d.ts +33 -0
- package/dist/runtime/native-network-errors.js +69 -0
- package/dist/runtime/native-network.d.ts +96 -0
- package/dist/runtime/native-network.js +1232 -0
- package/dist/runtime/ocr.d.ts +29 -0
- package/dist/runtime/ocr.js +440 -0
- package/dist/runtime/otlp.d.ts +71 -2
- package/dist/runtime/otlp.js +397 -16
- package/dist/runtime/proxy-errors.js +6 -2
- package/dist/runtime/proxy-nodemaven.d.ts +56 -0
- package/dist/runtime/proxy-nodemaven.js +146 -0
- package/dist/runtime/proxy-telemetry.d.ts +80 -1
- package/dist/runtime/proxy-telemetry.js +154 -47
- package/dist/runtime/redirects.d.ts +29 -0
- package/dist/runtime/redirects.js +36 -0
- package/dist/runtime/redis.d.ts +1 -1
- package/dist/runtime/redis.js +4 -2
- package/dist/runtime/request-options.d.ts +68 -1
- package/dist/runtime/request-options.js +548 -0
- package/dist/runtime/resolver-config.d.ts +6 -0
- package/dist/runtime/resolver-config.js +6 -0
- package/dist/runtime/resolver-public.d.ts +1 -0
- package/dist/runtime/resolver-public.js +1 -0
- package/dist/runtime/resolver-shared.d.ts +14 -0
- package/dist/runtime/resolver-shared.js +12 -0
- package/dist/runtime/resolver-vendors/bindings.d.ts +48 -0
- package/dist/runtime/resolver-vendors/bindings.js +40 -0
- package/dist/runtime/resolver-vendors/browser.d.ts +22 -0
- package/dist/runtime/resolver-vendors/browser.js +377 -0
- package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
- package/dist/runtime/resolver-vendors/capsolver.js +531 -0
- package/dist/runtime/resolver-vendors/hosts.d.ts +2 -0
- package/dist/runtime/resolver-vendors/hosts.js +33 -0
- package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
- package/dist/runtime/resolver-vendors/twocaptcha.js +408 -0
- package/dist/runtime/resolver-vendors/types.d.ts +94 -0
- package/dist/runtime/resolver-vendors/types.js +96 -0
- package/dist/runtime/resolver.d.ts +72 -0
- package/dist/runtime/resolver.js +771 -0
- package/dist/runtime/secrets.d.ts +27 -0
- package/dist/runtime/secrets.js +51 -0
- package/dist/runtime/state.d.ts +3 -0
- package/dist/runtime/state.js +277 -71
- package/dist/runtime/stealth-cookies.d.ts +20 -0
- package/dist/runtime/stealth-cookies.js +111 -0
- package/dist/runtime/stealth.d.ts +41 -5
- package/dist/runtime/stealth.js +997 -291
- package/dist/runtime/stt.js +1 -12
- package/dist/runtime/timeout.d.ts +5 -0
- package/dist/runtime/timeout.js +12 -0
- package/dist/runtime/trace-config.d.ts +12 -0
- package/dist/runtime/trace-config.js +62 -0
- package/dist/runtime/trace.d.ts +5 -0
- package/dist/runtime/trace.js +43 -10
- package/dist/serve.d.ts +1 -1
- package/dist/serve.js +1 -1
- package/dist/server/error-observability.d.ts +1 -0
- package/dist/server/error-observability.js +1 -0
- package/dist/server/index.d.ts +5 -2
- package/dist/server/index.js +2 -2
- package/dist/server/self-test-input-tokens.d.ts +2 -1
- package/dist/server/self-test-input-tokens.js +18 -14
- package/dist/server/self-test.d.ts +14 -3
- package/dist/server/self-test.js +129 -58
- package/dist/server/serve-implementation.d.ts +230 -0
- package/dist/server/serve-implementation.js +2265 -0
- package/dist/server/serve.d.ts +1 -70
- package/dist/server/serve.js +1 -1131
- package/dist/server/trace-output.d.ts +6 -0
- package/dist/server/trace-output.js +79 -0
- package/dist/server/types.d.ts +30 -5
- package/dist/server/types.js +13 -1
- package/dist/stateful/errors.d.ts +19 -0
- package/dist/stateful/errors.js +24 -0
- package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
- package/dist/stateful/http-provider-event-emitter.js +237 -0
- package/dist/stateful/http-session-owner-registry.d.ts +44 -0
- package/dist/stateful/http-session-owner-registry.js +210 -0
- package/dist/stateful/index.d.ts +18 -0
- package/dist/stateful/index.js +18 -0
- package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
- package/dist/stateful/provider-event-delivery-failures.js +43 -0
- package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
- package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
- package/dist/stateful/provider-event-pipeline.d.ts +50 -0
- package/dist/stateful/provider-event-pipeline.js +1 -0
- package/dist/stateful/provider-events.d.ts +101 -0
- package/dist/stateful/provider-events.js +289 -0
- package/dist/stateful/session-key.d.ts +15 -0
- package/dist/stateful/session-key.js +86 -0
- package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
- package/dist/stateful/stateful-provider-adapter-context.js +42 -0
- package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
- package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
- package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
- package/dist/stateful/stateful-provider-adapter.js +287 -0
- package/dist/stateful/stateful-provider-observability.d.ts +62 -0
- package/dist/stateful/stateful-provider-observability.js +161 -0
- package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
- package/dist/stateful/stateful-provider-owner-forwarder.js +215 -0
- package/dist/stateful/stateful-provider-runtime-context.d.ts +32 -0
- package/dist/stateful/stateful-provider-runtime-context.js +60 -0
- package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
- package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
- package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
- package/dist/stateful/stateful-provider-session-routing.js +345 -0
- package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
- package/dist/stateful/stateful-provider-session-runtime.js +245 -0
- package/dist/stateful-signing.d.ts +18 -0
- package/dist/stateful-signing.js +27 -0
- package/dist/stealth/profiles.d.ts +9 -4
- package/dist/stealth/profiles.js +160 -211
- package/dist/stream-evidence.d.ts +74 -0
- package/dist/stream-evidence.js +785 -0
- package/dist/stream.js +7 -1
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.js +2 -1
- package/dist/testing/run.d.ts +32 -2
- package/dist/testing/run.js +489 -21
- package/dist/trace-sanitization.d.ts +5 -0
- package/dist/trace-sanitization.js +45 -0
- package/dist/types.d.ts +673 -131
- package/dist/types.js +1 -0
- package/package.json +45 -5
- package/src/auth-turn/index.ts +1 -1
- package/src/auth.ts +118 -0
- package/src/ceremonies/index.ts +189 -46
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +3 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +10 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +8 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +5 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +16 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +3 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +31 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +21 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +14 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +15 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +4 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +12 -0
- package/src/cli/commands.ts +33 -0
- package/src/cli/create.ts +50 -37
- package/src/cli/migrate-operation-declaration.ts +1654 -0
- package/src/cli/migrate-operation-shape.ts +184 -0
- package/src/cli/migrate-provider-shape.ts +772 -0
- package/src/cli/prompt-assets.ts +865 -0
- package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/src/cli/templates/provider/Dockerfile.tpl +1 -1
- package/src/cli/templates/provider/README.md.tpl +5 -5
- package/src/cli/templates/provider/index.ts.tpl +6 -3
- package/src/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/src/cli/templates/provider/provider.json.tpl +6 -0
- package/src/config/loader.ts +690 -163
- package/src/contract-serialization.ts +5 -7
- package/src/contract-types.ts +12 -5
- package/src/contract.ts +24 -10
- package/src/declaration-validation.ts +330 -0
- package/src/define.ts +1048 -131
- package/src/dev.ts +4 -1
- package/src/engine.ts +279 -0
- package/src/error-observability.ts +64 -0
- package/src/error-resolution.ts +127 -0
- package/src/errors.ts +68 -0
- package/src/fixture-sanitization.ts +264 -0
- package/src/health-scenario.ts +875 -0
- package/src/index.ts +220 -13
- package/src/lint.ts +698 -90
- package/src/native-address.ts +340 -0
- package/src/native-egress-policy.ts +358 -0
- package/src/observability.ts +51 -1
- package/src/provider.ts +161 -3
- package/src/runtime/auth-flow.ts +12 -0
- package/src/runtime/browser.ts +661 -63
- package/src/runtime/cache.ts +189 -14
- package/src/runtime/choice-wordlist.ts +145 -0
- package/src/runtime/choice.ts +631 -120
- package/src/runtime/chrome149-header-order.ts +330 -0
- package/src/runtime/env.ts +13 -0
- package/src/runtime/executor.ts +43 -31
- package/src/runtime/http.ts +641 -61
- package/src/runtime/insights.ts +2 -2
- package/src/runtime/instrumentation.ts +520 -15
- package/src/runtime/native-network-errors.ts +99 -0
- package/src/runtime/native-network.ts +1605 -0
- package/src/runtime/ocr.ts +523 -0
- package/src/runtime/otlp.ts +467 -21
- package/src/runtime/proxy-errors.ts +12 -4
- package/src/runtime/proxy-nodemaven.ts +221 -0
- package/src/runtime/proxy-telemetry.ts +244 -75
- package/src/runtime/redirects.ts +66 -0
- package/src/runtime/redis.ts +7 -2
- package/src/runtime/request-options.ts +680 -1
- package/src/runtime/resolver-config.ts +6 -0
- package/src/runtime/resolver-public.ts +23 -0
- package/src/runtime/resolver-shared.ts +33 -0
- package/src/runtime/resolver-vendors/bindings.ts +56 -0
- package/src/runtime/resolver-vendors/browser.ts +533 -0
- package/src/runtime/resolver-vendors/capsolver.ts +707 -0
- package/src/runtime/resolver-vendors/hosts.ts +38 -0
- package/src/runtime/resolver-vendors/twocaptcha.ts +540 -0
- package/src/runtime/resolver-vendors/types.ts +212 -0
- package/src/runtime/resolver.ts +1157 -0
- package/src/runtime/secrets.ts +64 -0
- package/src/runtime/state.ts +394 -77
- package/src/runtime/stealth-cookies.ts +132 -0
- package/src/runtime/stealth.ts +1280 -336
- package/src/runtime/stt.ts +1 -19
- package/src/runtime/timeout.ts +18 -0
- package/src/runtime/trace-config.ts +78 -0
- package/src/runtime/trace.ts +57 -17
- package/src/serve.ts +6 -1
- package/src/server/error-observability.ts +1 -0
- package/src/server/index.ts +34 -2
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/server/self-test.ts +191 -68
- package/src/server/serve-implementation.ts +3378 -0
- package/src/server/serve.ts +1 -1632
- package/src/server/trace-output.ts +129 -0
- package/src/server/types.ts +13 -1
- package/src/stateful/README.md +146 -0
- package/src/stateful/errors.ts +35 -0
- package/src/stateful/http-provider-event-emitter.ts +314 -0
- package/src/stateful/http-session-owner-registry.ts +306 -0
- package/src/stateful/index.ts +18 -0
- package/src/stateful/provider-event-delivery-failures.ts +80 -0
- package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
- package/src/stateful/provider-event-pipeline.ts +61 -0
- package/src/stateful/provider-events.ts +462 -0
- package/src/stateful/session-key.ts +111 -0
- package/src/stateful/stateful-provider-adapter-context.ts +59 -0
- package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
- package/src/stateful/stateful-provider-adapter.ts +562 -0
- package/src/stateful/stateful-provider-observability.ts +261 -0
- package/src/stateful/stateful-provider-owner-forwarder.ts +287 -0
- package/src/stateful/stateful-provider-runtime-context.ts +92 -0
- package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
- package/src/stateful/stateful-provider-session-routing.ts +546 -0
- package/src/stateful/stateful-provider-session-runtime.ts +403 -0
- package/src/stateful-signing.ts +46 -0
- package/src/stealth/profiles.ts +202 -231
- package/src/stream-evidence.ts +988 -0
- package/src/stream.ts +8 -1
- package/src/testing/index.ts +10 -1
- package/src/testing/run.ts +658 -15
- package/src/trace-sanitization.ts +63 -0
- package/src/types.ts +788 -174
- package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
- package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
- /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
package/src/dev.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { serve } from "./server/serve.js";
|
|
2
|
+
import type { ProviderEngine } from "./engine.js";
|
|
2
3
|
import type { ProviderDefinition } from "./types.js";
|
|
3
4
|
|
|
4
5
|
export interface DevServerOptions {
|
|
5
6
|
port?: number;
|
|
6
7
|
sessionDbPath?: string;
|
|
8
|
+
/** Override the default in-process engine attachment. */
|
|
9
|
+
engine?: ProviderEngine;
|
|
7
10
|
}
|
|
8
11
|
|
|
9
12
|
export function createDevServer(
|
|
@@ -14,7 +17,7 @@ export function createDevServer(
|
|
|
14
17
|
|
|
15
18
|
return {
|
|
16
19
|
start: () => {
|
|
17
|
-
void serve(provider, { port });
|
|
20
|
+
void serve(provider, { port, engine: options?.engine });
|
|
18
21
|
console.log(
|
|
19
22
|
`[apifuse dev] ${provider.id}@${provider.version} running at http://localhost:${port}`,
|
|
20
23
|
);
|
package/src/engine.ts
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import { ProviderError } from "./errors.js";
|
|
2
|
+
import {
|
|
3
|
+
OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
4
|
+
OTEL_EXPORTER_OTLP_HEADERS,
|
|
5
|
+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
|
|
6
|
+
OTEL_EXPORTER_OTLP_TRACES_HEADERS,
|
|
7
|
+
OTEL_RESOURCE_ATTRIBUTES,
|
|
8
|
+
OTEL_SERVICE_NAME,
|
|
9
|
+
} from "./runtime/otlp.js";
|
|
10
|
+
import type {
|
|
11
|
+
AuthContext,
|
|
12
|
+
BrowserClient,
|
|
13
|
+
CredentialContext,
|
|
14
|
+
EnvContext,
|
|
15
|
+
HttpClient,
|
|
16
|
+
NativeContext,
|
|
17
|
+
OcrContext,
|
|
18
|
+
ProviderCache,
|
|
19
|
+
ProviderChoiceContext,
|
|
20
|
+
ProviderContext,
|
|
21
|
+
ProviderDefinition,
|
|
22
|
+
ProviderFilesContext,
|
|
23
|
+
ProviderRequestContext,
|
|
24
|
+
ProviderRuntimeState,
|
|
25
|
+
ResolverContext,
|
|
26
|
+
StealthClient,
|
|
27
|
+
SttContext,
|
|
28
|
+
TraceContext,
|
|
29
|
+
} from "./types.js";
|
|
30
|
+
|
|
31
|
+
/** Versioned envelope protocol used by out-of-process engine transports. */
|
|
32
|
+
export const PROVIDER_ENGINE_PROTOCOL_VERSION = "provider-engine.v1" as const;
|
|
33
|
+
|
|
34
|
+
/** Credential names owned by the engine and forbidden in provider declarations. */
|
|
35
|
+
export const ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES = [
|
|
36
|
+
"APIFUSE__PROXY__SMARTPROXY_APP_KEY",
|
|
37
|
+
"APIFUSE__PROXY__NODEMAVEN_USERNAME",
|
|
38
|
+
"APIFUSE__PROXY__NODEMAVEN_PASSWORD",
|
|
39
|
+
] as const;
|
|
40
|
+
|
|
41
|
+
const ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAME_SET = new Set<string>(
|
|
42
|
+
ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Environment names are compared case-insensitively: Windows resolves `otel_exporter_otlp_headers`
|
|
47
|
+
* to the same variable as `OTEL_EXPORTER_OTLP_HEADERS`, so a mixed-case alias must be treated as
|
|
48
|
+
* the engine-owned name it resolves to.
|
|
49
|
+
*/
|
|
50
|
+
function canonicalEnvName(name: string): string {
|
|
51
|
+
return name.toUpperCase();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function isEngineOwnedProxyCredentialName(name: string): boolean {
|
|
55
|
+
return ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAME_SET.has(canonicalEnvName(name));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Trace-export configuration owned by the engine and forbidden in provider
|
|
60
|
+
* declarations. The header variables carry collector credentials; the rest are
|
|
61
|
+
* engine deployment settings a provider has no reason to read.
|
|
62
|
+
*/
|
|
63
|
+
export const ENGINE_OWNED_TELEMETRY_ENV_NAMES = [
|
|
64
|
+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
|
|
65
|
+
OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
66
|
+
OTEL_EXPORTER_OTLP_TRACES_HEADERS,
|
|
67
|
+
OTEL_EXPORTER_OTLP_HEADERS,
|
|
68
|
+
OTEL_SERVICE_NAME,
|
|
69
|
+
OTEL_RESOURCE_ATTRIBUTES,
|
|
70
|
+
] as const;
|
|
71
|
+
|
|
72
|
+
const ENGINE_OWNED_TELEMETRY_ENV_NAME_SET = new Set<string>(ENGINE_OWNED_TELEMETRY_ENV_NAMES);
|
|
73
|
+
|
|
74
|
+
export function isEngineOwnedTelemetryEnvName(name: string): boolean {
|
|
75
|
+
return ENGINE_OWNED_TELEMETRY_ENV_NAME_SET.has(canonicalEnvName(name));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Every environment name the engine owns: rejected in declarations and filtered from provider projections. */
|
|
79
|
+
export function isEngineOwnedEnvName(name: string): boolean {
|
|
80
|
+
return isEngineOwnedProxyCredentialName(name) || isEngineOwnedTelemetryEnvName(name);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Capture credentials in the engine host before constructing provider bindings. */
|
|
84
|
+
export function readEngineProxyCredentials(
|
|
85
|
+
environment: Readonly<Record<string, string | undefined>> = process.env,
|
|
86
|
+
): Readonly<Record<string, string>> {
|
|
87
|
+
return Object.fromEntries(
|
|
88
|
+
ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES.flatMap((name) => {
|
|
89
|
+
const value = environment[name]?.trim();
|
|
90
|
+
return value ? [[name, value] as const] : [];
|
|
91
|
+
}),
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Build the exact environment projection permitted to enter a provider runtime. */
|
|
96
|
+
export function createProviderEnvironment(
|
|
97
|
+
environment: Readonly<Record<string, string | undefined>>,
|
|
98
|
+
declaredNames: readonly string[],
|
|
99
|
+
): Readonly<Record<string, string>> {
|
|
100
|
+
return Object.fromEntries(
|
|
101
|
+
declaredNames.flatMap((name) => {
|
|
102
|
+
if (isEngineOwnedEnvName(name)) return [];
|
|
103
|
+
const value = environment[name];
|
|
104
|
+
return value === undefined ? [] : [[name, value] as const];
|
|
105
|
+
}),
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Request/response is the first remote transport lane. Stream and session
|
|
111
|
+
* handles are separate lanes so lifecycle-bearing capabilities are never
|
|
112
|
+
* disguised as ordinary JSON calls.
|
|
113
|
+
*/
|
|
114
|
+
export interface ProviderEngineTransport {
|
|
115
|
+
request<TResponse = unknown>(request: ProviderEngineRequest): Promise<TResponse>;
|
|
116
|
+
openStream?(request: ProviderEngineRequest): Promise<ReadableStream<Uint8Array>>;
|
|
117
|
+
openSession?(request: ProviderEngineRequest): Promise<ProviderEngineSession>;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface ProviderEngineRequest {
|
|
121
|
+
readonly version: typeof PROVIDER_ENGINE_PROTOCOL_VERSION;
|
|
122
|
+
readonly providerId: string;
|
|
123
|
+
readonly requestId: string;
|
|
124
|
+
readonly capability: ProviderCapabilityKey;
|
|
125
|
+
readonly method: string;
|
|
126
|
+
readonly payload: unknown;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface ProviderEngineSession {
|
|
130
|
+
request<TResponse = unknown>(method: string, payload: unknown): Promise<TResponse>;
|
|
131
|
+
close(): Promise<void>;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Capability implementations owned by the engine rather than provider code. */
|
|
135
|
+
export interface ProviderEngineCapabilitySurface {
|
|
136
|
+
readonly http: HttpClient;
|
|
137
|
+
readonly browser: BrowserClient;
|
|
138
|
+
readonly stealth: StealthClient;
|
|
139
|
+
readonly stt: SttContext;
|
|
140
|
+
readonly ocr: OcrContext;
|
|
141
|
+
readonly resolver: ResolverContext;
|
|
142
|
+
readonly cache: ProviderCache;
|
|
143
|
+
readonly state: ProviderRuntimeState;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Engine-resident-only capabilities, kept separate from the portable surface. */
|
|
147
|
+
export interface ProviderEngineResidentSurface {
|
|
148
|
+
readonly native: NativeContext;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export const PROVIDER_CAPABILITY_KEYS = [
|
|
152
|
+
"env",
|
|
153
|
+
"credential",
|
|
154
|
+
"http",
|
|
155
|
+
"files",
|
|
156
|
+
"native",
|
|
157
|
+
"cache",
|
|
158
|
+
"state",
|
|
159
|
+
"stealth",
|
|
160
|
+
"browser",
|
|
161
|
+
"auth",
|
|
162
|
+
"ocr",
|
|
163
|
+
"stt",
|
|
164
|
+
"resolver",
|
|
165
|
+
"choice",
|
|
166
|
+
] as const;
|
|
167
|
+
|
|
168
|
+
export type ProviderCapabilityKey = (typeof PROVIDER_CAPABILITY_KEYS)[number];
|
|
169
|
+
|
|
170
|
+
export type ProviderEngineBindingCandidates = Partial<
|
|
171
|
+
ProviderEngineCapabilitySurface &
|
|
172
|
+
ProviderEngineResidentSurface & {
|
|
173
|
+
readonly env: EnvContext;
|
|
174
|
+
readonly credential: CredentialContext;
|
|
175
|
+
readonly files: ProviderFilesContext;
|
|
176
|
+
readonly auth: AuthContext;
|
|
177
|
+
readonly choice: ProviderChoiceContext;
|
|
178
|
+
}
|
|
179
|
+
> & {
|
|
180
|
+
readonly request?: ProviderRequestContext;
|
|
181
|
+
readonly trace: TraceContext;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export interface ProviderEngineAttachmentInput {
|
|
185
|
+
readonly provider: ProviderDefinition;
|
|
186
|
+
readonly bindings: ProviderEngineBindingCandidates;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Attachment boundary shared by in-process development and remote RPC bridges. */
|
|
190
|
+
export interface ProviderEngine {
|
|
191
|
+
attach<TDeclaration extends object = Record<string, unknown>>(
|
|
192
|
+
input: ProviderEngineAttachmentInput,
|
|
193
|
+
): ProviderContext<TDeclaration>;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const CAPABILITY_KEY_SET = new Set<string>(PROVIDER_CAPABILITY_KEYS);
|
|
197
|
+
|
|
198
|
+
function declaresCapability(
|
|
199
|
+
provider: ProviderDefinition,
|
|
200
|
+
capability: ProviderCapabilityKey,
|
|
201
|
+
): boolean {
|
|
202
|
+
return Object.hasOwn(provider, capability) && provider[capability] !== undefined;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function attachmentError(
|
|
206
|
+
provider: ProviderDefinition,
|
|
207
|
+
capability: ProviderCapabilityKey,
|
|
208
|
+
): ProviderError {
|
|
209
|
+
return new ProviderError(
|
|
210
|
+
`Provider engine could not attach declared capability "${capability}" for provider "${provider.id}"`,
|
|
211
|
+
{
|
|
212
|
+
code: "PROVIDER_ENGINE_ATTACHMENT_FAILED",
|
|
213
|
+
details: { providerId: provider.id, capability },
|
|
214
|
+
fix: `Configure the engine binding for "${capability}" before starting the provider.`,
|
|
215
|
+
},
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function undeclaredCapabilityError(
|
|
220
|
+
provider: ProviderDefinition,
|
|
221
|
+
capability: ProviderCapabilityKey,
|
|
222
|
+
): ProviderError {
|
|
223
|
+
return new ProviderError(
|
|
224
|
+
`Provider "${provider.id}" accessed undeclared capability "${capability}"; add the "${capability}" declaration`,
|
|
225
|
+
{
|
|
226
|
+
code: "PROVIDER_CAPABILITY_UNDECLARED",
|
|
227
|
+
details: { providerId: provider.id, capability },
|
|
228
|
+
fix: `Add ${capability}: {} to the provider declaration, or remove the access.`,
|
|
229
|
+
},
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function attachInProcess<TDeclaration extends object>(
|
|
234
|
+
input: ProviderEngineAttachmentInput,
|
|
235
|
+
): ProviderContext<TDeclaration> {
|
|
236
|
+
const { provider, bindings } = input;
|
|
237
|
+
if (provider.runtimeTarget === "vanilla" && declaresCapability(provider, "native")) {
|
|
238
|
+
throw new ProviderError(
|
|
239
|
+
`Provider "${provider.id}" cannot attach capability "native" to runtime target "vanilla"; native requires an engine-resident runtime`,
|
|
240
|
+
{
|
|
241
|
+
code: "PROVIDER_RUNTIME_CAPABILITY_CONFLICT",
|
|
242
|
+
details: { providerId: provider.id, capability: "native", runtimeTarget: "vanilla" },
|
|
243
|
+
},
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const context: Record<PropertyKey, unknown> = { trace: bindings.trace };
|
|
248
|
+
if (bindings.request !== undefined) context.request = bindings.request;
|
|
249
|
+
for (const capability of PROVIDER_CAPABILITY_KEYS) {
|
|
250
|
+
if (!declaresCapability(provider, capability)) continue;
|
|
251
|
+
const binding = bindings[capability];
|
|
252
|
+
if (binding === undefined || binding === null) throw attachmentError(provider, capability);
|
|
253
|
+
context[capability] = binding;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return new Proxy(context, {
|
|
257
|
+
get(target, property, receiver) {
|
|
258
|
+
if (
|
|
259
|
+
typeof property === "string" &&
|
|
260
|
+
CAPABILITY_KEY_SET.has(property) &&
|
|
261
|
+
!declaresCapability(provider, property as ProviderCapabilityKey)
|
|
262
|
+
) {
|
|
263
|
+
throw undeclaredCapabilityError(provider, property as ProviderCapabilityKey);
|
|
264
|
+
}
|
|
265
|
+
return Reflect.get(target, property, receiver);
|
|
266
|
+
},
|
|
267
|
+
has(target, property) {
|
|
268
|
+
if (typeof property === "string" && CAPABILITY_KEY_SET.has(property)) {
|
|
269
|
+
return declaresCapability(provider, property as ProviderCapabilityKey);
|
|
270
|
+
}
|
|
271
|
+
return Reflect.has(target, property);
|
|
272
|
+
},
|
|
273
|
+
}) as ProviderContext<TDeclaration>;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/** Local engine attachment; deployed bridges implement the same interface with RPC clients. */
|
|
277
|
+
export function createInProcessProviderEngine(): ProviderEngine {
|
|
278
|
+
return { attach: attachInProcess };
|
|
279
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { isProviderError, type ProviderErrorObservability } from "./errors.js";
|
|
2
|
+
|
|
3
|
+
const PROVIDER_OBSERVABILITY_TOKEN_PATTERN = /^[A-Za-z0-9_.-]{1,64}$/;
|
|
4
|
+
const PROVIDER_OBSERVABILITY_FINGERPRINT_PATTERN = /^[A-Fa-f0-9]{12}$/;
|
|
5
|
+
const MAX_PROVIDER_OBSERVABILITY_MESSAGE_LENGTH = 10_000_000;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Extracts only own data properties from branded provider errors. In
|
|
9
|
+
* particular, descriptor reads reject options/observability accessors without
|
|
10
|
+
* invoking provider-controlled getters.
|
|
11
|
+
*/
|
|
12
|
+
export function safeProviderErrorObservability(
|
|
13
|
+
error: unknown,
|
|
14
|
+
): ProviderErrorObservability | undefined {
|
|
15
|
+
if (!isProviderError(error)) return undefined;
|
|
16
|
+
let candidate: unknown;
|
|
17
|
+
let reason: unknown;
|
|
18
|
+
let fingerprint: unknown;
|
|
19
|
+
let messageLength: unknown;
|
|
20
|
+
try {
|
|
21
|
+
const optionsDescriptor = Object.getOwnPropertyDescriptor(error, "options");
|
|
22
|
+
if (optionsDescriptor === undefined || !Object.hasOwn(optionsDescriptor, "value")) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
const options = optionsDescriptor.value;
|
|
26
|
+
if (options === null || typeof options !== "object" || Array.isArray(options)) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
const observabilityDescriptor = Object.getOwnPropertyDescriptor(options, "observability");
|
|
30
|
+
if (observabilityDescriptor === undefined || !Object.hasOwn(observabilityDescriptor, "value")) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
candidate = observabilityDescriptor.value;
|
|
34
|
+
if (candidate === null || typeof candidate !== "object" || Array.isArray(candidate)) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
const ownValue = (key: keyof ProviderErrorObservability): unknown => {
|
|
38
|
+
const descriptor = Object.getOwnPropertyDescriptor(candidate as object, key);
|
|
39
|
+
return descriptor && Object.hasOwn(descriptor, "value") ? descriptor.value : undefined;
|
|
40
|
+
};
|
|
41
|
+
reason = ownValue("reason");
|
|
42
|
+
fingerprint = ownValue("fingerprint");
|
|
43
|
+
messageLength = ownValue("messageLength");
|
|
44
|
+
} catch {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const safe: ProviderErrorObservability = {
|
|
48
|
+
...(typeof reason === "string" && PROVIDER_OBSERVABILITY_TOKEN_PATTERN.test(reason)
|
|
49
|
+
? { reason }
|
|
50
|
+
: {}),
|
|
51
|
+
...(typeof fingerprint === "string" &&
|
|
52
|
+
PROVIDER_OBSERVABILITY_FINGERPRINT_PATTERN.test(fingerprint)
|
|
53
|
+
? { fingerprint }
|
|
54
|
+
: {}),
|
|
55
|
+
...(typeof messageLength === "number" &&
|
|
56
|
+
Number.isInteger(messageLength) &&
|
|
57
|
+
messageLength >= 0 &&
|
|
58
|
+
messageLength <= MAX_PROVIDER_OBSERVABILITY_MESSAGE_LENGTH
|
|
59
|
+
? { messageLength }
|
|
60
|
+
: {}),
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return Object.keys(safe).length > 0 ? safe : undefined;
|
|
64
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { ProviderErrorStatus } from "./types.js";
|
|
2
|
+
|
|
3
|
+
// This set suppresses the unregistered-provider-error-code signal for codes
|
|
4
|
+
// intentionally emitted by SDK paths. It is not the complete authority for
|
|
5
|
+
// runtime error resolution: branded errors and additional canonical SDK codes
|
|
6
|
+
// must also remain immune to provider-declared status/retryability overrides.
|
|
7
|
+
export const SDK_OWNED_PROVIDER_ERROR_CODES = new Set([
|
|
8
|
+
"MISSING_SECRET",
|
|
9
|
+
"AUTH_PROMPT_UNAVAILABLE",
|
|
10
|
+
"BROWSER_CDP_POOL_REQUIRED",
|
|
11
|
+
"BROWSER_RUNTIME_UNSUPPORTED",
|
|
12
|
+
"STEALTH_RUNTIME_UNSUPPORTED",
|
|
13
|
+
"SSE_EVENT_UNDECLARED",
|
|
14
|
+
"STREAM_EVENT_TOO_LARGE",
|
|
15
|
+
"STREAM_CHUNK_TOO_LARGE",
|
|
16
|
+
"SSE_RESULT_UNSUPPORTED",
|
|
17
|
+
"STREAM_RESULT_UNSUPPORTED",
|
|
18
|
+
"AUTH_FLOW_NOT_CONFIGURED",
|
|
19
|
+
"refresh_not_supported",
|
|
20
|
+
"RUNTIME_UNSUPPORTED",
|
|
21
|
+
"PROVIDER_STATE_UNSUPPORTED",
|
|
22
|
+
"CHOICE_TOKEN_MASTER_SECRET_NOT_CONFIGURED",
|
|
23
|
+
"CHOICE_STATE_PAYLOAD_TOO_LARGE",
|
|
24
|
+
"CHOICE_STATE_UNAVAILABLE",
|
|
25
|
+
"CHOICE_CONTEXT_REQUIRED",
|
|
26
|
+
"unsupported_stealth_cookie_store_version",
|
|
27
|
+
"provider_secret_error",
|
|
28
|
+
"credential_key_error",
|
|
29
|
+
"credential_mode_error",
|
|
30
|
+
"flow_expired",
|
|
31
|
+
"turn_validation_error",
|
|
32
|
+
"context_access_error",
|
|
33
|
+
"OCR_UPSTREAM_FAILED",
|
|
34
|
+
"UNSUPPORTED_STT_OPTION",
|
|
35
|
+
"INVALID_STT_AUDIO",
|
|
36
|
+
"STT_AUDIO_TOO_LARGE",
|
|
37
|
+
"STT_UPSTREAM_FAILED",
|
|
38
|
+
"INVALID_STT_VERIFICATION_CODE_OPTIONS",
|
|
39
|
+
"NO_CODE_FOUND",
|
|
40
|
+
"AMBIGUOUS_CODE",
|
|
41
|
+
"retry_invalid_policy",
|
|
42
|
+
"retry_unsafe_method",
|
|
43
|
+
"stealth_cookie_store_serialize_failed",
|
|
44
|
+
"response_too_large",
|
|
45
|
+
"transport_stream_unavailable",
|
|
46
|
+
"transport_invalid_method",
|
|
47
|
+
"http_transport_override_unsupported",
|
|
48
|
+
"http_redirect_policy_invalid",
|
|
49
|
+
"http_redirect_stopped",
|
|
50
|
+
"http_redirect_max_hops",
|
|
51
|
+
"http_redirect_missing_location",
|
|
52
|
+
"http_redirect_loop",
|
|
53
|
+
"transport_invalid_url",
|
|
54
|
+
"retry_exhausted",
|
|
55
|
+
"auth_abort_unsafe_data",
|
|
56
|
+
"credentials_auth_missing_credential_keys",
|
|
57
|
+
"credentials_auth_missing_credential",
|
|
58
|
+
"credentials_auth_invalid_login_result",
|
|
59
|
+
"credentials_auth_unknown_challenge",
|
|
60
|
+
"credentials_auth_unknown_pending_challenge",
|
|
61
|
+
"STATEFUL_FORWARDING_NOT_CONFIGURED",
|
|
62
|
+
"STATEFUL_FORWARDING_SIGNATURE_MISSING",
|
|
63
|
+
"STATEFUL_FORWARDING_NONCE_INVALID",
|
|
64
|
+
"STATEFUL_FORWARDING_TIMESTAMP_INVALID",
|
|
65
|
+
"STATEFUL_FORWARDING_SIGNATURE_INVALID",
|
|
66
|
+
"STATEFUL_FORWARDING_REPLAY_DETECTED",
|
|
67
|
+
"STATEFUL_FORWARDING_REPLAY_CACHE_FULL",
|
|
68
|
+
"STATEFUL_FORWARDING_ENVELOPE_INVALID",
|
|
69
|
+
"STATEFUL_FORWARDING_PROVIDER_MISMATCH",
|
|
70
|
+
"STATEFUL_FORWARDING_SOURCE_POD_MISMATCH",
|
|
71
|
+
"STATEFUL_FORWARDING_OWNER_FENCE_INVALID",
|
|
72
|
+
"STATEFUL_FORWARDING_REQUEST_FAILED",
|
|
73
|
+
"STATEFUL_FORWARDING_CONTEXT_MISSING",
|
|
74
|
+
"STATEFUL_FORWARDING_BAD_RESPONSE",
|
|
75
|
+
"STATEFUL_INTERNAL_EXECUTOR_NOT_CONFIGURED",
|
|
76
|
+
"STATEFUL_FILE_FORWARDING_UNSUPPORTED",
|
|
77
|
+
"STATEFUL_CONTROL_PLANE_OPERATION_AMBIGUOUS",
|
|
78
|
+
"STATEFUL_CONTROL_PLANE_REQUEST_FAILED",
|
|
79
|
+
"STATEFUL_CONTROL_PLANE_HTTP_ERROR",
|
|
80
|
+
"STATEFUL_CONTROL_PLANE_INVALID_RESPONSE",
|
|
81
|
+
]);
|
|
82
|
+
|
|
83
|
+
// Complete code authority for provider-declared runtime resolution. Keep this
|
|
84
|
+
// separate from signal suppression: declarations may document these codes, but
|
|
85
|
+
// their status and retryability can never override the SDK's canonical result.
|
|
86
|
+
export const SDK_RUNTIME_OWNED_ERROR_CODES = new Set([
|
|
87
|
+
...SDK_OWNED_PROVIDER_ERROR_CODES,
|
|
88
|
+
"reauth_required",
|
|
89
|
+
"OCR_UNAVAILABLE",
|
|
90
|
+
"UNSUPPORTED_OCR_BACKEND",
|
|
91
|
+
"STT_UNAVAILABLE",
|
|
92
|
+
"UNSUPPORTED_STT_BACKEND",
|
|
93
|
+
"OUTPUT_VALIDATION_FAILED",
|
|
94
|
+
"NOT_FOUND",
|
|
95
|
+
"not_found",
|
|
96
|
+
]);
|
|
97
|
+
|
|
98
|
+
// Canonical SDK status mapping for recognized provider-thrown error codes.
|
|
99
|
+
// serve.ts toStatusCode consults this map (after operation-declared overrides
|
|
100
|
+
// for non-SDK-owned codes), and the authoring lint treats these codes as
|
|
101
|
+
// SDK-registered. Add new codes here instead of duplicating literals in
|
|
102
|
+
// either consumer.
|
|
103
|
+
export const SDK_STATUS_MAPPED_PROVIDER_ERROR_CODES: ReadonlyMap<string, ProviderErrorStatus> =
|
|
104
|
+
new Map<string, ProviderErrorStatus>([
|
|
105
|
+
["AUTH_REQUIRED", 401],
|
|
106
|
+
["reauth_required", 401],
|
|
107
|
+
// Unprovisioned declared secret: a deployment/config defect, never an
|
|
108
|
+
// upstream failure — explicit 400.
|
|
109
|
+
["MISSING_SECRET", 400],
|
|
110
|
+
["NOT_FOUND", 404],
|
|
111
|
+
["not_found", 404],
|
|
112
|
+
["NO_DATA", 404],
|
|
113
|
+
["RATE_LIMITED", 429],
|
|
114
|
+
["UPSTREAM_RATE_LIMIT", 429],
|
|
115
|
+
["LIMITED_NUMBER_OF_SERVICE_REQUESTS_EXCEEDS_ERROR", 429],
|
|
116
|
+
// Deterministic upstream business refusal (honest-provider-error-
|
|
117
|
+
// contract): the upstream evaluated the request and said no under its
|
|
118
|
+
// own rules — a conflict with upstream state, never a 5xx.
|
|
119
|
+
["UPSTREAM_REJECTED", 409],
|
|
120
|
+
["UPSTREAM_ERROR", 502],
|
|
121
|
+
["BLOCKED", 502],
|
|
122
|
+
["OCR_UNAVAILABLE", 503],
|
|
123
|
+
["UNSUPPORTED_OCR_BACKEND", 503],
|
|
124
|
+
["STT_UNAVAILABLE", 503],
|
|
125
|
+
["UNSUPPORTED_STT_BACKEND", 503],
|
|
126
|
+
["STATEFUL_FORWARDING_REPLAY_CACHE_FULL", 503],
|
|
127
|
+
]);
|
package/src/errors.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ProviderErrorCategory } from "./observability.js";
|
|
2
|
+
import type { HttpRedirectFailureReason } from "./types.js";
|
|
2
3
|
|
|
3
4
|
// Versioned, cross-realm brands. `Symbol.for` resolves to the same symbol in
|
|
4
5
|
// any copy/entrypoint of this SDK major version, so an error created by a
|
|
@@ -10,6 +11,7 @@ const PROVIDER_ERROR_BRAND = Symbol.for("@apifuse/provider-sdk/error-brand@1");
|
|
|
10
11
|
const PROVIDER_ERROR_BRAND_VALUE = 1;
|
|
11
12
|
const SESSION_EXPIRED_BRAND = Symbol.for("@apifuse/provider-sdk/error-kind/session-expired@1");
|
|
12
13
|
const TRANSPORT_BRAND = Symbol.for("@apifuse/provider-sdk/error-kind/transport@1");
|
|
14
|
+
const VALIDATION_BRAND = Symbol.for("@apifuse/provider-sdk/error-kind/validation@1");
|
|
13
15
|
|
|
14
16
|
// Defines a non-enumerable, non-writable, non-configurable own data property.
|
|
15
17
|
// Immutable + own means a guard can trust it via a single descriptor read
|
|
@@ -44,6 +46,22 @@ export type ProviderErrorOptions = {
|
|
|
44
46
|
cause?: Error;
|
|
45
47
|
category?: ProviderErrorCategory;
|
|
46
48
|
retryable?: boolean;
|
|
49
|
+
/** Provider-authored, bounded metadata safe for operational logs and error headers. */
|
|
50
|
+
observability?: ProviderErrorObservability;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Provider-authored error diagnostics whose runtime values are validated before emission.
|
|
55
|
+
* Classification tokens such as `reason` are source literals, not runtime user input or
|
|
56
|
+
* credentials. The gateway removes the observability header from tenant responses.
|
|
57
|
+
*/
|
|
58
|
+
export type ProviderErrorObservability = {
|
|
59
|
+
/** A 1-64 character `[A-Za-z0-9_.-]` classification token, for example `LOGIN_COMPLETE_FAILED`. */
|
|
60
|
+
reason?: string;
|
|
61
|
+
/** A provider-computed 12-hex-character fingerprint of private diagnostic input. */
|
|
62
|
+
fingerprint?: string;
|
|
63
|
+
/** The non-negative length of the private diagnostic input, capped at 10,000,000. */
|
|
64
|
+
messageLength?: number;
|
|
47
65
|
};
|
|
48
66
|
|
|
49
67
|
export class ProviderError extends Error {
|
|
@@ -79,6 +97,21 @@ export class SDKError extends ProviderError {
|
|
|
79
97
|
}
|
|
80
98
|
}
|
|
81
99
|
|
|
100
|
+
/** Raised when persisted stealth cookies use a store version this SDK cannot read. */
|
|
101
|
+
export class StealthCookieStoreVersionError extends SDKError {
|
|
102
|
+
constructor(public readonly version: unknown) {
|
|
103
|
+
const displayedVersion =
|
|
104
|
+
typeof version === "string" || typeof version === "number"
|
|
105
|
+
? String(version)
|
|
106
|
+
: "missing or invalid";
|
|
107
|
+
super(`Unsupported stealth cookie store version: ${displayedVersion}`, {
|
|
108
|
+
code: "unsupported_stealth_cookie_store_version",
|
|
109
|
+
details: { receivedVersion: version, supportedVersions: [1] },
|
|
110
|
+
});
|
|
111
|
+
this.name = "StealthCookieStoreVersionError";
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
82
115
|
export class AuthError extends ProviderError {
|
|
83
116
|
constructor(message: string, options?: ProviderErrorOptions) {
|
|
84
117
|
super(message, options);
|
|
@@ -110,6 +143,7 @@ export class ValidationError extends ProviderError {
|
|
|
110
143
|
super(message, options);
|
|
111
144
|
this.name = "ValidationError";
|
|
112
145
|
this.zodError = options?.zodError;
|
|
146
|
+
defineErrorBrand(this, VALIDATION_BRAND, true);
|
|
113
147
|
}
|
|
114
148
|
}
|
|
115
149
|
|
|
@@ -131,6 +165,33 @@ export class TransportError extends ProviderError {
|
|
|
131
165
|
}
|
|
132
166
|
}
|
|
133
167
|
|
|
168
|
+
export type HttpRedirectErrorOptions = TransportErrorOptions & {
|
|
169
|
+
reason: HttpRedirectFailureReason;
|
|
170
|
+
/** Redacted redirect target suitable for provider diagnostics. */
|
|
171
|
+
target?: string;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/** Raised when an opt-in ctx.http redirect policy refuses or cannot resolve a hop. */
|
|
175
|
+
export class HttpRedirectError extends TransportError {
|
|
176
|
+
readonly reason: HttpRedirectFailureReason;
|
|
177
|
+
readonly target?: string;
|
|
178
|
+
|
|
179
|
+
constructor(message: string, options: HttpRedirectErrorOptions) {
|
|
180
|
+
const { reason, target, ...transportOptions } = options;
|
|
181
|
+
super(message, {
|
|
182
|
+
...transportOptions,
|
|
183
|
+
code: `http_redirect_${reason}`,
|
|
184
|
+
details: {
|
|
185
|
+
reason,
|
|
186
|
+
...(target ? { target } : {}),
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
this.name = "HttpRedirectError";
|
|
190
|
+
this.reason = reason;
|
|
191
|
+
this.target = target;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
134
195
|
// Cross-module type guards. Prefer these over `instanceof` at any boundary that
|
|
135
196
|
// may receive an error from a different copy/entrypoint of the SDK (see the HTTP
|
|
136
197
|
// server error boundary). They recognize branded errors regardless of which
|
|
@@ -147,6 +208,13 @@ export function isTransportError(value: unknown): value is TransportError {
|
|
|
147
208
|
return isProviderError(value) && hasOwnBrand(value, TRANSPORT_BRAND, true);
|
|
148
209
|
}
|
|
149
210
|
|
|
211
|
+
export function isValidationError(value: unknown): value is ValidationError {
|
|
212
|
+
return (
|
|
213
|
+
isProviderError(value) &&
|
|
214
|
+
(hasOwnBrand(value, VALIDATION_BRAND, true) || value.name === "ValidationError")
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
150
218
|
export class ProviderSecretError extends ProviderError {
|
|
151
219
|
constructor(message: string, options?: ProviderErrorOptions) {
|
|
152
220
|
super(message, { code: "provider_secret_error", ...options });
|