@apifuse/provider-sdk 2.2.0-beta.7 → 2.2.0-beta.70
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 +943 -51
- package/CHANGELOG.md +273 -1
- package/LICENSE +21 -0
- package/README.md +117 -29
- package/SUBMISSION.md +3 -2
- package/bin/apifuse-check.ts +293 -13
- package/bin/apifuse-dev.ts +42 -19
- package/bin/apifuse-migrate-deployment.ts +200 -0
- package/bin/apifuse-migrate-operation-declaration.ts +55 -0
- package/bin/apifuse-migrate-shape.ts +202 -0
- package/bin/apifuse-pack-check.ts +19 -6
- package/bin/apifuse-pack-smoke.ts +57 -2
- package/bin/apifuse-pack-types.ts +736 -38
- package/bin/apifuse-perf.ts +59 -23
- package/bin/apifuse-record.ts +923 -94
- package/bin/apifuse-submit-check.ts +2313 -281
- package/bin/apifuse-test.ts +3 -1
- 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 +30 -0
- package/dist/cli/create.d.ts +1 -1
- package/dist/cli/create.js +8 -2
- package/dist/cli/deployment-intent.d.ts +178 -0
- package/dist/cli/deployment-intent.js +277 -0
- package/dist/cli/local-connection.d.ts +111 -0
- package/dist/cli/local-connection.js +151 -0
- package/dist/cli/migrate-deployment-intent.d.ts +132 -0
- package/dist/cli/migrate-deployment-intent.js +1552 -0
- package/dist/cli/migrate-operation-declaration.d.ts +70 -0
- package/dist/cli/migrate-operation-declaration.js +2206 -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 +56 -0
- package/dist/cli/migrate-provider-shape.js +580 -0
- package/dist/cli/resolver-runtime.d.ts +21 -0
- package/dist/cli/resolver-runtime.js +31 -0
- package/dist/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
- package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
- package/dist/cli/templates/provider/README.md.tpl +41 -19
- 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 +202 -16
- package/dist/config/loader.js +491 -141
- 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 +34 -0
- package/dist/declaration-validation.js +305 -0
- package/dist/define.d.ts +71 -29
- package/dist/define.js +807 -69
- package/dist/dev.d.ts +5 -0
- package/dist/dev.js +8 -1
- package/dist/engine.d.ts +129 -0
- package/dist/engine.js +209 -0
- package/dist/error-observability.d.ts +7 -0
- package/dist/error-observability.js +61 -0
- package/dist/error-resolution.d.ts +18 -0
- package/dist/error-resolution.js +243 -0
- package/dist/errors.d.ts +74 -0
- package/dist/errors.js +99 -0
- package/dist/fixture-sanitization.d.ts +28 -0
- package/dist/fixture-sanitization.js +371 -0
- package/dist/handle-meta.d.ts +90 -0
- package/dist/handle-meta.js +73 -0
- package/dist/handle.d.ts +226 -0
- package/dist/handle.js +345 -0
- package/dist/health-scenario.d.ts +1901 -0
- package/dist/health-scenario.js +653 -0
- package/dist/i18n/catalog.js +21 -1
- package/dist/i18n/error-messages.d.ts +86 -0
- package/dist/i18n/error-messages.js +192 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/keys.d.ts +12 -0
- package/dist/i18n/keys.js +76 -5
- package/dist/i18n/operation-locale-namespace.d.ts +2 -0
- package/dist/i18n/operation-locale-namespace.js +7 -0
- package/dist/index.d.ts +40 -15
- package/dist/index.js +29 -11
- package/dist/lint.d.ts +43 -11
- package/dist/lint.js +2512 -177
- 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 +18 -8
- package/dist/provider.js +11 -6
- package/dist/runtime/auth-flow.d.ts +6 -1
- package/dist/runtime/auth-flow.js +8 -0
- package/dist/runtime/bounded-expiring-map.d.ts +21 -0
- package/dist/runtime/bounded-expiring-map.js +64 -0
- package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
- package/dist/runtime/browser-telemetry-binding.js +83 -0
- package/dist/runtime/browser-telemetry.d.ts +76 -0
- package/dist/runtime/browser-telemetry.js +165 -0
- package/dist/runtime/browser.d.ts +4 -0
- package/dist/runtime/browser.js +688 -83
- package/dist/runtime/cache-telemetry.d.ts +71 -0
- package/dist/runtime/cache-telemetry.js +177 -0
- package/dist/runtime/cache.d.ts +3 -0
- package/dist/runtime/cache.js +245 -23
- package/dist/runtime/capability-response.d.ts +3 -0
- package/dist/runtime/capability-response.js +56 -0
- package/dist/runtime/capability-telemetry.d.ts +46 -0
- package/dist/runtime/capability-telemetry.js +68 -0
- package/dist/runtime/chrome149-header-order.d.ts +58 -0
- package/dist/runtime/chrome149-header-order.js +289 -0
- package/dist/runtime/diagnostic-env-values.d.ts +5 -0
- package/dist/runtime/diagnostic-env-values.js +57 -0
- package/dist/runtime/diagnostic-env.d.ts +14 -0
- package/dist/runtime/diagnostic-env.js +44 -0
- package/dist/runtime/diagnostic-redactor.d.ts +54 -0
- package/dist/runtime/diagnostic-redactor.js +571 -0
- package/dist/runtime/egress-lease.d.ts +65 -0
- package/dist/runtime/egress-lease.js +236 -0
- package/dist/runtime/engine-mode.d.ts +74 -0
- package/dist/runtime/engine-mode.js +152 -0
- package/dist/runtime/env.js +14 -1
- package/dist/runtime/executor.d.ts +3 -2
- package/dist/runtime/executor.js +23 -26
- package/dist/runtime/handle-wordlist.d.ts +43 -0
- package/dist/runtime/handle-wordlist.js +256 -0
- package/dist/runtime/handle.d.ts +71 -0
- package/dist/runtime/handle.js +908 -0
- 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 +16 -0
- package/dist/runtime/http-telemetry-guard.js +202 -0
- package/dist/runtime/http-telemetry.d.ts +104 -0
- package/dist/runtime/http-telemetry.js +190 -0
- package/dist/runtime/http.d.ts +34 -0
- package/dist/runtime/http.js +680 -121
- package/dist/runtime/insights.js +2 -2
- package/dist/runtime/instrumentation.d.ts +2 -2
- package/dist/runtime/instrumentation.js +462 -19
- 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 +105 -0
- package/dist/runtime/native-network.js +1433 -0
- package/dist/runtime/native-telemetry.d.ts +142 -0
- package/dist/runtime/native-telemetry.js +231 -0
- package/dist/runtime/ocr-telemetry.d.ts +82 -0
- package/dist/runtime/ocr-telemetry.js +192 -0
- package/dist/runtime/ocr.d.ts +29 -0
- package/dist/runtime/ocr.js +468 -0
- package/dist/runtime/otlp.d.ts +71 -2
- package/dist/runtime/otlp.js +398 -16
- package/dist/runtime/provider.d.ts +7 -0
- package/dist/runtime/provider.js +14 -0
- package/dist/runtime/proxy-errors.js +6 -2
- package/dist/runtime/proxy-nodemaven.d.ts +56 -0
- package/dist/runtime/proxy-nodemaven.js +147 -0
- package/dist/runtime/proxy-retry-policy.d.ts +4 -1
- package/dist/runtime/proxy-retry-policy.js +11 -2
- package/dist/runtime/proxy-telemetry.d.ts +133 -3
- package/dist/runtime/proxy-telemetry.js +218 -70
- package/dist/runtime/redirect-hop-headers.d.ts +19 -0
- package/dist/runtime/redirect-hop-headers.js +58 -0
- package/dist/runtime/redirects.d.ts +61 -0
- package/dist/runtime/redirects.js +149 -0
- package/dist/runtime/redis.d.ts +1 -1
- package/dist/runtime/redis.js +4 -2
- package/dist/runtime/request-options.d.ts +75 -1
- package/dist/runtime/request-options.js +588 -0
- package/dist/runtime/request-telemetry.d.ts +70 -0
- package/dist/runtime/request-telemetry.js +229 -0
- package/dist/runtime/resolver-config.d.ts +13 -0
- package/dist/runtime/resolver-config.js +14 -0
- package/dist/runtime/resolver-public.d.ts +3 -0
- package/dist/runtime/resolver-public.js +1 -0
- package/dist/runtime/resolver-runtime-options.d.ts +14 -0
- package/dist/runtime/resolver-runtime-options.js +33 -0
- package/dist/runtime/resolver-shared.d.ts +24 -0
- package/dist/runtime/resolver-shared.js +69 -0
- package/dist/runtime/resolver-span-attributes.d.ts +34 -0
- package/dist/runtime/resolver-span-attributes.js +93 -0
- package/dist/runtime/resolver-telemetry.d.ts +135 -0
- package/dist/runtime/resolver-telemetry.js +204 -0
- package/dist/runtime/resolver-usage.d.ts +32 -0
- package/dist/runtime/resolver-usage.js +54 -0
- package/dist/runtime/resolver-vendors/bindings.d.ts +53 -0
- package/dist/runtime/resolver-vendors/bindings.js +45 -0
- package/dist/runtime/resolver-vendors/browser.d.ts +24 -0
- package/dist/runtime/resolver-vendors/browser.js +423 -0
- package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
- package/dist/runtime/resolver-vendors/capsolver.js +544 -0
- package/dist/runtime/resolver-vendors/hosts.d.ts +23 -0
- package/dist/runtime/resolver-vendors/hosts.js +68 -0
- package/dist/runtime/resolver-vendors/hypersolutions.d.ts +27 -0
- package/dist/runtime/resolver-vendors/hypersolutions.js +369 -0
- package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
- package/dist/runtime/resolver-vendors/twocaptcha.js +425 -0
- package/dist/runtime/resolver-vendors/types.d.ts +125 -0
- package/dist/runtime/resolver-vendors/types.js +106 -0
- package/dist/runtime/resolver.d.ts +79 -0
- package/dist/runtime/resolver.js +1094 -0
- package/dist/runtime/state-telemetry.d.ts +79 -0
- package/dist/runtime/state-telemetry.js +194 -0
- package/dist/runtime/state.d.ts +10 -1
- package/dist/runtime/state.js +322 -82
- package/dist/runtime/stealth-akamai-sbsd.d.ts +54 -0
- package/dist/runtime/stealth-akamai-sbsd.js +142 -0
- package/dist/runtime/stealth-cookies.d.ts +24 -0
- package/dist/runtime/stealth-cookies.js +131 -0
- package/dist/runtime/stealth-owned-headers.d.ts +39 -0
- package/dist/runtime/stealth-owned-headers.js +57 -0
- package/dist/runtime/stealth-telemetry.d.ts +92 -0
- package/dist/runtime/stealth-telemetry.js +179 -0
- package/dist/runtime/stealth.d.ts +45 -6
- package/dist/runtime/stealth.js +1775 -320
- package/dist/runtime/stt-telemetry.d.ts +77 -0
- package/dist/runtime/stt-telemetry.js +176 -0
- package/dist/runtime/stt.js +18 -19
- 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 +17 -0
- package/dist/runtime/trace.js +176 -25
- package/dist/runtime-boundary-lint.d.ts +137 -0
- package/dist/runtime-boundary-lint.js +590 -0
- package/dist/schema.d.ts +20 -0
- package/dist/schema.js +72 -2
- 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/error-stack-frames.d.ts +35 -0
- package/dist/server/error-stack-frames.js +219 -0
- package/dist/server/index.d.ts +21 -2
- package/dist/server/index.js +11 -2
- package/dist/server/runtime-diagnostics.d.ts +165 -0
- package/dist/server/runtime-diagnostics.js +360 -0
- package/dist/server/sdk-version.d.ts +3 -0
- package/dist/server/sdk-version.js +19 -0
- 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-redaction.js +8 -33
- package/dist/server/self-test.d.ts +18 -3
- package/dist/server/self-test.js +139 -76
- package/dist/server/sensitive-values.d.ts +26 -0
- package/dist/server/sensitive-values.js +137 -0
- package/dist/server/serve-implementation.d.ts +285 -0
- package/dist/server/serve-implementation.js +3172 -0
- package/dist/server/serve.d.ts +1 -75
- package/dist/server/serve.js +1 -1170
- package/dist/server/state-backend-report.d.ts +70 -0
- package/dist/server/state-backend-report.js +113 -0
- package/dist/server/trace-output.d.ts +7 -0
- package/dist/server/trace-output.js +111 -0
- package/dist/server/types.d.ts +37 -5
- package/dist/server/types.js +34 -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 +237 -0
- package/dist/stateful/stateful-provider-runtime-context.d.ts +35 -0
- package/dist/stateful/stateful-provider-runtime-context.js +61 -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 +15 -4
- package/dist/stealth/profiles.js +169 -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 +509 -25
- package/dist/trace-sanitization.d.ts +6 -0
- package/dist/trace-sanitization.js +68 -0
- package/dist/types.d.ts +899 -210
- package/dist/types.js +1 -0
- package/dist/typescript-module.d.ts +39 -0
- package/dist/typescript-module.js +72 -0
- package/package.json +52 -6
- package/src/auth-turn/index.ts +1 -1
- package/src/auth.ts +118 -0
- package/src/ceremonies/index.ts +189 -46
- package/src/cli/commands.ts +37 -0
- package/src/cli/create.ts +8 -2
- package/src/cli/deployment-intent.ts +364 -0
- package/src/cli/local-connection.ts +221 -0
- package/src/cli/migrate-deployment-intent.ts +1908 -0
- package/src/cli/migrate-operation-declaration.ts +3026 -0
- package/src/cli/migrate-operation-shape.ts +184 -0
- package/src/cli/migrate-provider-shape.ts +778 -0
- package/src/cli/resolver-runtime.ts +72 -0
- package/src/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
- package/src/cli/templates/provider/Dockerfile.tpl +1 -1
- package/src/cli/templates/provider/README.md.tpl +41 -19
- 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 +774 -181
- 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 +376 -0
- package/src/define.ts +1105 -131
- package/src/dev.ts +13 -1
- package/src/engine.ts +390 -0
- package/src/error-observability.ts +64 -0
- package/src/error-resolution.ts +269 -0
- package/src/errors.ts +157 -0
- package/src/fixture-sanitization.ts +422 -0
- package/src/handle-meta.ts +143 -0
- package/src/handle.ts +694 -0
- package/src/health-scenario.ts +960 -0
- package/src/i18n/catalog.ts +23 -1
- package/src/i18n/error-messages.ts +255 -0
- package/src/i18n/index.ts +1 -0
- package/src/i18n/keys.ts +80 -6
- package/src/i18n/operation-locale-namespace.ts +10 -0
- package/src/index.ts +390 -23
- package/src/lint.ts +2975 -234
- 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 +207 -27
- package/src/runtime/auth-flow.ts +15 -0
- package/src/runtime/bounded-expiring-map.ts +67 -0
- package/src/runtime/browser-telemetry-binding.ts +92 -0
- package/src/runtime/browser-telemetry.ts +289 -0
- package/src/runtime/browser.ts +882 -99
- package/src/runtime/cache-telemetry.ts +247 -0
- package/src/runtime/cache.ts +258 -22
- package/src/runtime/capability-response.ts +53 -0
- package/src/runtime/capability-telemetry.ts +101 -0
- package/src/runtime/chrome149-header-order.ts +330 -0
- package/src/runtime/diagnostic-env-values.ts +56 -0
- package/src/runtime/diagnostic-env.ts +65 -0
- package/src/runtime/diagnostic-redactor.ts +668 -0
- package/src/runtime/egress-lease.ts +341 -0
- package/src/runtime/engine-mode.ts +233 -0
- package/src/runtime/env.ts +15 -1
- package/src/runtime/executor.ts +39 -32
- package/src/runtime/handle-wordlist.ts +266 -0
- package/src/runtime/handle.ts +1180 -0
- package/src/runtime/http-telemetry-binding.ts +162 -0
- package/src/runtime/http-telemetry-guard.ts +208 -0
- package/src/runtime/http-telemetry.ts +292 -0
- package/src/runtime/http.ts +896 -150
- package/src/runtime/insights.ts +2 -2
- package/src/runtime/instrumentation.ts +628 -28
- package/src/runtime/native-network-errors.ts +99 -0
- package/src/runtime/native-network.ts +1853 -0
- package/src/runtime/native-telemetry.ts +366 -0
- package/src/runtime/ocr-telemetry.ts +308 -0
- package/src/runtime/ocr.ts +564 -0
- package/src/runtime/otlp.ts +468 -21
- package/src/runtime/provider.ts +15 -0
- package/src/runtime/proxy-errors.ts +12 -4
- package/src/runtime/proxy-nodemaven.ts +222 -0
- package/src/runtime/proxy-retry-policy.ts +12 -1
- package/src/runtime/proxy-telemetry.ts +358 -103
- package/src/runtime/redirect-hop-headers.ts +71 -0
- package/src/runtime/redirects.ts +215 -0
- package/src/runtime/redis.ts +7 -2
- package/src/runtime/request-options.ts +728 -1
- package/src/runtime/request-telemetry.ts +375 -0
- package/src/runtime/resolver-config.ts +18 -0
- package/src/runtime/resolver-public.ts +44 -0
- package/src/runtime/resolver-runtime-options.ts +50 -0
- package/src/runtime/resolver-shared.ts +113 -0
- package/src/runtime/resolver-span-attributes.ts +139 -0
- package/src/runtime/resolver-telemetry.ts +362 -0
- package/src/runtime/resolver-usage.ts +99 -0
- package/src/runtime/resolver-vendors/bindings.ts +61 -0
- package/src/runtime/resolver-vendors/browser.ts +591 -0
- package/src/runtime/resolver-vendors/capsolver.ts +727 -0
- package/src/runtime/resolver-vendors/hosts.ts +81 -0
- package/src/runtime/resolver-vendors/hypersolutions.ts +480 -0
- package/src/runtime/resolver-vendors/twocaptcha.ts +555 -0
- package/src/runtime/resolver-vendors/types.ts +261 -0
- package/src/runtime/resolver.ts +1543 -0
- package/src/runtime/state-telemetry.ts +298 -0
- package/src/runtime/state.ts +435 -89
- package/src/runtime/stealth-akamai-sbsd.ts +207 -0
- package/src/runtime/stealth-cookies.ts +155 -0
- package/src/runtime/stealth-owned-headers.ts +67 -0
- package/src/runtime/stealth-telemetry.ts +309 -0
- package/src/runtime/stealth.ts +2275 -372
- package/src/runtime/stt-telemetry.ts +282 -0
- package/src/runtime/stt.ts +96 -91
- package/src/runtime/timeout.ts +18 -0
- package/src/runtime/trace-config.ts +78 -0
- package/src/runtime/trace.ts +257 -35
- package/src/runtime-boundary-lint.ts +707 -0
- package/src/schema.ts +80 -2
- package/src/serve.ts +6 -1
- package/src/server/error-observability.ts +1 -0
- package/src/server/error-stack-frames.ts +214 -0
- package/src/server/index.ts +184 -2
- package/src/server/runtime-diagnostics.ts +522 -0
- package/src/server/sdk-version.ts +22 -0
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/server/self-test-redaction.ts +10 -40
- package/src/server/self-test.ts +205 -89
- package/src/server/sensitive-values.ts +211 -0
- package/src/server/serve-implementation.ts +4596 -0
- package/src/server/serve.ts +1 -1685
- package/src/server/state-backend-report.ts +185 -0
- package/src/server/trace-output.ts +189 -0
- package/src/server/types.ts +34 -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 +310 -0
- package/src/stateful/stateful-provider-runtime-context.ts +96 -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 +212 -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 +685 -19
- package/src/trace-sanitization.ts +110 -0
- package/src/types.ts +1014 -273
- package/src/typescript-module.ts +100 -0
- package/dist/choice-token.d.ts +0 -24
- package/dist/choice-token.js +0 -74
- package/dist/runtime/choice.d.ts +0 -15
- package/dist/runtime/choice.js +0 -413
- package/src/choice-token.ts +0 -165
- package/src/runtime/choice.ts +0 -686
package/src/server/self-test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
3
2
|
|
|
4
3
|
import { TURN_KINDS } from "../auth-turn/index.js";
|
|
4
|
+
import { SDK_VERSION } from "./sdk-version.js";
|
|
5
5
|
|
|
6
6
|
import { type Context, Hono } from "hono";
|
|
7
7
|
import { z } from "zod";
|
|
@@ -77,11 +77,22 @@ export interface SelfTestResponse {
|
|
|
77
77
|
results: SelfTestCaseResult[];
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
export interface SelfTestCancellationLogEvent {
|
|
81
|
+
level: "info";
|
|
82
|
+
event: "self_test_run_cancelled";
|
|
83
|
+
providerId: string;
|
|
84
|
+
requestId: string;
|
|
85
|
+
operationId: string;
|
|
86
|
+
caseName: string;
|
|
87
|
+
reason: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
80
90
|
export type SelfTestOperationInvoke = (args: {
|
|
81
91
|
operationId: string;
|
|
82
92
|
input: unknown;
|
|
83
93
|
connection?: OperationConnection;
|
|
84
94
|
requestId: string;
|
|
95
|
+
signal?: AbortSignal;
|
|
85
96
|
}) => Promise<{
|
|
86
97
|
status: number;
|
|
87
98
|
data: unknown;
|
|
@@ -106,6 +117,9 @@ export type SelfTestAuthFlowInvoke = (args: {
|
|
|
106
117
|
externalRef?: string;
|
|
107
118
|
input?: Record<string, unknown>;
|
|
108
119
|
context?: Record<string, unknown>;
|
|
120
|
+
/** Opaque engine state from the previous turn (`engine` in the auth response), sent verbatim. */
|
|
121
|
+
engine?: { egressLease: string };
|
|
122
|
+
signal?: AbortSignal;
|
|
109
123
|
}) => Promise<{
|
|
110
124
|
status: number;
|
|
111
125
|
body: unknown;
|
|
@@ -165,28 +179,10 @@ export interface SelfTestAppOptions {
|
|
|
165
179
|
requestBudgetMs?: number;
|
|
166
180
|
/** Env override for secret collection + budget resolution (tests). */
|
|
167
181
|
env?: Readonly<Record<string, string | undefined>>;
|
|
182
|
+
/** Structured server logger; defaults to the same JSON console shape as the provider server. */
|
|
183
|
+
logger?: (event: SelfTestCancellationLogEvent) => void;
|
|
168
184
|
}
|
|
169
185
|
|
|
170
|
-
function resolveSdkVersion(): string {
|
|
171
|
-
try {
|
|
172
|
-
const packageJsonUrl = new URL("../../package.json", import.meta.url);
|
|
173
|
-
const parsed: unknown = JSON.parse(readFileSync(packageJsonUrl, "utf8"));
|
|
174
|
-
if (
|
|
175
|
-
parsed &&
|
|
176
|
-
typeof parsed === "object" &&
|
|
177
|
-
"version" in parsed &&
|
|
178
|
-
typeof (parsed as { version: unknown }).version === "string"
|
|
179
|
-
) {
|
|
180
|
-
return (parsed as { version: string }).version;
|
|
181
|
-
}
|
|
182
|
-
} catch {
|
|
183
|
-
// fall through to unknown
|
|
184
|
-
}
|
|
185
|
-
return "unknown";
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const SDK_VERSION = resolveSdkVersion();
|
|
189
|
-
|
|
190
186
|
type AnyHealthCheckSuite = HealthCheckSuite<unknown, unknown>;
|
|
191
187
|
type AnyHealthCheckCase = HealthCheckCase<unknown, unknown>;
|
|
192
188
|
|
|
@@ -231,33 +227,35 @@ export function computeSelfTestPlanDigest(provider: ProviderDefinition): string
|
|
|
231
227
|
|
|
232
228
|
/**
|
|
233
229
|
* Fail-closed read-only classification: an operation may self-test only when
|
|
234
|
-
* its
|
|
235
|
-
* toolRouter.riskClass "read") and nothing marks it side-effecting. Unclassified
|
|
236
|
-
* operations are refused so the endpoint cannot become a mutation oracle.
|
|
230
|
+
* its authored safety source of truth classifies it as read-only.
|
|
237
231
|
*/
|
|
238
232
|
export function isSelfTestReadOnlyOperation(operation: OperationDefinition): boolean {
|
|
239
|
-
|
|
240
|
-
if (annotations?.readOnly === false) return false;
|
|
241
|
-
if (annotations?.destructive === true) return false;
|
|
242
|
-
const riskClass = operation.toolRouter?.riskClass;
|
|
243
|
-
if (riskClass !== undefined && riskClass !== "read") return false;
|
|
244
|
-
return annotations?.readOnly === true || riskClass === "read";
|
|
233
|
+
return operation.riskClass === "read";
|
|
245
234
|
}
|
|
246
235
|
|
|
247
236
|
/** Binds the self-test executor to a tenant app's /v1 pipeline in-process. */
|
|
248
237
|
export function createSelfTestInvoke(app: {
|
|
249
238
|
request: (input: string, requestInit?: RequestInit) => Response | Promise<Response>;
|
|
250
239
|
}): SelfTestOperationInvoke {
|
|
251
|
-
return async ({ operationId, input, connection, requestId }) => {
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
240
|
+
return async ({ operationId, input, connection, requestId, signal }) => {
|
|
241
|
+
const responsePromise = Promise.resolve(
|
|
242
|
+
app.request(`/v1/${encodeURIComponent(operationId)}`, {
|
|
243
|
+
method: "POST",
|
|
244
|
+
headers: { "content-type": "application/json" },
|
|
245
|
+
body: JSON.stringify({
|
|
246
|
+
requestId,
|
|
247
|
+
input: input ?? {},
|
|
248
|
+
...(connection ? { connection } : {}),
|
|
249
|
+
}),
|
|
250
|
+
...(signal ? { signal } : {}),
|
|
259
251
|
}),
|
|
260
|
-
|
|
252
|
+
);
|
|
253
|
+
const response = await responsePromise;
|
|
254
|
+
if (signal?.aborted) {
|
|
255
|
+
await cancelSelfTestResponse(response);
|
|
256
|
+
signal.throwIfAborted();
|
|
257
|
+
}
|
|
258
|
+
// An abort after body consumption starts may let response.text() finish.
|
|
261
259
|
const text = await response.text();
|
|
262
260
|
let body: unknown = text;
|
|
263
261
|
try {
|
|
@@ -277,22 +275,75 @@ export function createSelfTestInvoke(app: {
|
|
|
277
275
|
};
|
|
278
276
|
}
|
|
279
277
|
|
|
278
|
+
async function cancelSelfTestResponse(response: Response): Promise<void> {
|
|
279
|
+
await response.body?.cancel().catch(() => undefined);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function selfTestAbortReason(reason: unknown, sensitiveValues: readonly string[]): string {
|
|
283
|
+
const text =
|
|
284
|
+
reason instanceof Error
|
|
285
|
+
? reason.message || reason.name
|
|
286
|
+
: reason === undefined
|
|
287
|
+
? "aborted"
|
|
288
|
+
: String(reason);
|
|
289
|
+
return redactSelfTestText(text, sensitiveValues);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function logSelfTestCancellation(
|
|
293
|
+
provider: ProviderDefinition,
|
|
294
|
+
options: SelfTestAppOptions,
|
|
295
|
+
requestId: string,
|
|
296
|
+
selected: SelectedCase,
|
|
297
|
+
signal: AbortSignal,
|
|
298
|
+
sensitiveValues: readonly string[],
|
|
299
|
+
): void {
|
|
300
|
+
const event: SelfTestCancellationLogEvent = {
|
|
301
|
+
level: "info",
|
|
302
|
+
event: "self_test_run_cancelled",
|
|
303
|
+
providerId: provider.id,
|
|
304
|
+
requestId,
|
|
305
|
+
operationId: selected.operationId,
|
|
306
|
+
caseName: selected.healthCase.name,
|
|
307
|
+
reason: selfTestAbortReason(signal.reason, sensitiveValues),
|
|
308
|
+
};
|
|
309
|
+
if (options.logger) {
|
|
310
|
+
options.logger(event);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
console.log(JSON.stringify(event));
|
|
314
|
+
}
|
|
315
|
+
|
|
280
316
|
/** Binds the self-test auth-flow driver to a tenant app's /auth pipeline in-process. */
|
|
281
317
|
export function createSelfTestAuthFlowInvoke(app: {
|
|
282
318
|
request: (input: string, requestInit?: RequestInit) => Response | Promise<Response>;
|
|
283
319
|
}): SelfTestAuthFlowInvoke {
|
|
284
|
-
return async ({
|
|
320
|
+
return async ({
|
|
321
|
+
route,
|
|
322
|
+
requestId,
|
|
323
|
+
flowId,
|
|
324
|
+
connectionId,
|
|
325
|
+
externalRef,
|
|
326
|
+
input,
|
|
327
|
+
context,
|
|
328
|
+
engine,
|
|
329
|
+
signal,
|
|
330
|
+
}) => {
|
|
285
331
|
const response = await app.request(`/auth/${route}`, {
|
|
286
332
|
method: "POST",
|
|
287
333
|
headers: { "content-type": "application/json" },
|
|
288
334
|
body: JSON.stringify({
|
|
289
335
|
requestId,
|
|
290
336
|
flowId,
|
|
337
|
+
// Engine ceremony leases are scoped to a tenant; the self-test has no
|
|
338
|
+
// customer tenant, so it presents a fixed one that never collides.
|
|
339
|
+
tenantId: "self-test",
|
|
291
340
|
...(connectionId ? { connectionId } : {}),
|
|
292
341
|
...(externalRef ? { externalRef } : {}),
|
|
293
342
|
...(input ? { input } : {}),
|
|
294
343
|
...(context ? { context } : {}),
|
|
344
|
+
...(engine ? { engine } : {}),
|
|
295
345
|
}),
|
|
346
|
+
...(signal ? { signal } : {}),
|
|
296
347
|
});
|
|
297
348
|
const text = await response.text();
|
|
298
349
|
let body: unknown = text;
|
|
@@ -312,17 +363,32 @@ class SelfTestCaseTimeoutError extends Error {
|
|
|
312
363
|
}
|
|
313
364
|
}
|
|
314
365
|
|
|
315
|
-
async function withCaseTimeout<T>(
|
|
366
|
+
async function withCaseTimeout<T>(
|
|
367
|
+
run: () => Promise<T>,
|
|
368
|
+
timeoutMs: number,
|
|
369
|
+
controller: AbortController,
|
|
370
|
+
): Promise<T> {
|
|
316
371
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
372
|
+
let onAbort: (() => void) | undefined;
|
|
317
373
|
try {
|
|
318
374
|
return await Promise.race([
|
|
319
375
|
run(),
|
|
320
376
|
new Promise<never>((_, reject) => {
|
|
321
|
-
timer = setTimeout(() =>
|
|
377
|
+
timer = setTimeout(() => {
|
|
378
|
+
const error = new SelfTestCaseTimeoutError(timeoutMs);
|
|
379
|
+
controller.abort(error);
|
|
380
|
+
reject(error);
|
|
381
|
+
}, timeoutMs);
|
|
382
|
+
}),
|
|
383
|
+
new Promise<never>((_, reject) => {
|
|
384
|
+
onAbort = () => reject(controller.signal.reason);
|
|
385
|
+
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
386
|
+
if (controller.signal.aborted) onAbort();
|
|
322
387
|
}),
|
|
323
388
|
]);
|
|
324
389
|
} finally {
|
|
325
390
|
if (timer !== undefined) clearTimeout(timer);
|
|
391
|
+
if (onAbort) controller.signal.removeEventListener("abort", onAbort);
|
|
326
392
|
}
|
|
327
393
|
}
|
|
328
394
|
|
|
@@ -471,6 +537,7 @@ type ParsedAuthFlowTurn =
|
|
|
471
537
|
ok: true;
|
|
472
538
|
turn: { kind: string; data?: unknown; expectedInput?: unknown };
|
|
473
539
|
contextPatch?: Record<string, unknown>;
|
|
540
|
+
engine?: { egressLease: string };
|
|
474
541
|
}
|
|
475
542
|
| { ok: false; code: string; message: string; httpStatus: number };
|
|
476
543
|
|
|
@@ -499,6 +566,7 @@ function parseAuthFlowResponse(result: { status: number; body: unknown }): Parse
|
|
|
499
566
|
};
|
|
500
567
|
}
|
|
501
568
|
const contextPatch = objectProperty(result.body, "contextPatch");
|
|
569
|
+
const egressLease = objectProperty(objectProperty(result.body, "engine"), "egressLease");
|
|
502
570
|
return {
|
|
503
571
|
ok: true,
|
|
504
572
|
turn: {
|
|
@@ -509,6 +577,7 @@ function parseAuthFlowResponse(result: { status: number; body: unknown }): Parse
|
|
|
509
577
|
...(contextPatch && typeof contextPatch === "object" && !Array.isArray(contextPatch)
|
|
510
578
|
? { contextPatch: contextPatch as Record<string, unknown> }
|
|
511
579
|
: {}),
|
|
580
|
+
...(typeof egressLease === "string" && egressLease ? { engine: { egressLease } } : {}),
|
|
512
581
|
};
|
|
513
582
|
}
|
|
514
583
|
|
|
@@ -595,6 +664,7 @@ async function materializeFlowCredential(
|
|
|
595
664
|
isAbandoned?: () => boolean;
|
|
596
665
|
connectionId?: string;
|
|
597
666
|
externalRef?: string;
|
|
667
|
+
signal?: AbortSignal;
|
|
598
668
|
} = {},
|
|
599
669
|
): Promise<
|
|
600
670
|
| { credential: Record<string, string> }
|
|
@@ -621,6 +691,7 @@ async function materializeFlowCredential(
|
|
|
621
691
|
flowId,
|
|
622
692
|
...(options.connectionId ? { connectionId: options.connectionId } : {}),
|
|
623
693
|
...(options.externalRef ? { externalRef: options.externalRef } : {}),
|
|
694
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
624
695
|
}),
|
|
625
696
|
);
|
|
626
697
|
if (!started.ok) {
|
|
@@ -696,6 +767,10 @@ async function materializeFlowCredential(
|
|
|
696
767
|
...(options.externalRef ? { externalRef: options.externalRef } : {}),
|
|
697
768
|
input: submitInputs,
|
|
698
769
|
...(Object.keys(flowContext).length > 0 ? { context: flowContext } : {}),
|
|
770
|
+
// The ceremony egress lease is engine state, not flow context: carry it the
|
|
771
|
+
// way the gateway does so the continue turn stays on the start turn's egress.
|
|
772
|
+
...(started.engine ? { engine: started.engine } : {}),
|
|
773
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
699
774
|
}),
|
|
700
775
|
);
|
|
701
776
|
if (!continued.ok) {
|
|
@@ -756,7 +831,7 @@ async function resolveSelfTestConnection(
|
|
|
756
831
|
execution: SelfTestExecutionContext,
|
|
757
832
|
operationId: string,
|
|
758
833
|
suite: AnyHealthCheckSuite,
|
|
759
|
-
options: { forceLogin?: boolean; isAbandoned?: () => boolean } = {},
|
|
834
|
+
options: { forceLogin?: boolean; isAbandoned?: () => boolean; signal?: AbortSignal } = {},
|
|
760
835
|
): Promise<SelfTestConnectionResolution> {
|
|
761
836
|
if (!suite.requiresConnection) return { kind: "connection" };
|
|
762
837
|
const inputs = execution.credentials ?? {};
|
|
@@ -861,6 +936,7 @@ async function resolveSelfTestConnection(
|
|
|
861
936
|
...(options.isAbandoned !== undefined ? { isAbandoned: options.isAbandoned } : {}),
|
|
862
937
|
connectionId,
|
|
863
938
|
externalRef: `${execution.provider.id}-${operationId}-self-test`,
|
|
939
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
864
940
|
});
|
|
865
941
|
if (!("credential" in materialized)) {
|
|
866
942
|
// Only the multi-turn SKIP is negative-cached. Flow ERRORS
|
|
@@ -879,10 +955,9 @@ async function resolveSelfTestConnection(
|
|
|
879
955
|
}
|
|
880
956
|
return materialized;
|
|
881
957
|
}
|
|
882
|
-
//
|
|
883
|
-
//
|
|
884
|
-
//
|
|
885
|
-
// reuse a login whose latency just failed the case, hiding the failure.
|
|
958
|
+
// Abort is cooperative: a flow may still complete after the case deadline
|
|
959
|
+
// if provider code ignores the signal. Never cache that late credential or
|
|
960
|
+
// let the next probe hide the timed-out login.
|
|
886
961
|
if (options.isAbandoned?.() === true) {
|
|
887
962
|
return {
|
|
888
963
|
kind: "flow_error",
|
|
@@ -913,6 +988,7 @@ async function executeSelfTestCase(
|
|
|
913
988
|
operationId: string,
|
|
914
989
|
suite: AnyHealthCheckSuite,
|
|
915
990
|
healthCase: AnyHealthCheckCase,
|
|
991
|
+
caseController: AbortController,
|
|
916
992
|
): Promise<SelfTestCaseResult> {
|
|
917
993
|
const { provider, invoke } = execution;
|
|
918
994
|
// execution.sensitiveValues may grow while the case runs (flow-issued
|
|
@@ -926,6 +1002,8 @@ async function executeSelfTestCase(
|
|
|
926
1002
|
const caseDeadlineAtMs = performance.now() + timeoutMs;
|
|
927
1003
|
const remainingCaseTimeoutMs = () =>
|
|
928
1004
|
Math.max(1, Math.ceil(caseDeadlineAtMs - performance.now()));
|
|
1005
|
+
const runWithCaseTimeout = <T>(run: () => Promise<T>, remainingMs: number) =>
|
|
1006
|
+
withCaseTimeout(run, remainingMs, caseController);
|
|
929
1007
|
|
|
930
1008
|
const beginCase = () => {
|
|
931
1009
|
const startedAt = new Date().toISOString();
|
|
@@ -959,16 +1037,17 @@ async function executeSelfTestCase(
|
|
|
959
1037
|
}
|
|
960
1038
|
|
|
961
1039
|
const resolveConnection = async (forceLogin: boolean): Promise<SelfTestConnectionResolution> => {
|
|
962
|
-
// The
|
|
963
|
-
//
|
|
964
|
-
//
|
|
1040
|
+
// The deadline aborts the in-process flow request. Keep the abandonment
|
|
1041
|
+
// guard as a backstop for provider code that ignores cancellation so a
|
|
1042
|
+
// late completion still cannot write the session cache.
|
|
965
1043
|
let abandoned = false;
|
|
966
1044
|
try {
|
|
967
|
-
return await
|
|
1045
|
+
return await runWithCaseTimeout(
|
|
968
1046
|
() =>
|
|
969
1047
|
resolveSelfTestConnection(execution, operationId, suite, {
|
|
970
1048
|
forceLogin,
|
|
971
1049
|
isAbandoned: () => abandoned,
|
|
1050
|
+
signal: caseController.signal,
|
|
972
1051
|
}),
|
|
973
1052
|
remainingCaseTimeoutMs(),
|
|
974
1053
|
);
|
|
@@ -1012,7 +1091,12 @@ async function executeSelfTestCase(
|
|
|
1012
1091
|
// operation attempt, or a slow login reads as a fast healthy case.
|
|
1013
1092
|
const { startedAtMs, finish } = caseScope;
|
|
1014
1093
|
try {
|
|
1015
|
-
return await
|
|
1094
|
+
return await runWithCaseTimeout(async () => {
|
|
1095
|
+
if (healthCase.assertions === undefined) {
|
|
1096
|
+
throw new Error(
|
|
1097
|
+
`Self-test cannot execute declarative health-check case "${healthCase.name}"; run its scenario through the health monitor.`,
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1016
1100
|
const resolvedInput = resolveHealthCheckInputDateTokens(healthCase.input);
|
|
1017
1101
|
const preparedInput = healthCase.prepareInput
|
|
1018
1102
|
? await healthCase.prepareInput({
|
|
@@ -1033,6 +1117,7 @@ async function executeSelfTestCase(
|
|
|
1033
1117
|
input: gatewayInput,
|
|
1034
1118
|
connection,
|
|
1035
1119
|
requestId: `${execution.requestId}-prepare-${randomUUID()}`,
|
|
1120
|
+
signal: caseController.signal,
|
|
1036
1121
|
});
|
|
1037
1122
|
if (executed.status === 401 || executed.status === 403) {
|
|
1038
1123
|
prepareAuthStatus = executed.status;
|
|
@@ -1053,6 +1138,7 @@ async function executeSelfTestCase(
|
|
|
1053
1138
|
input: preparedInput,
|
|
1054
1139
|
connection,
|
|
1055
1140
|
requestId: `${execution.requestId}-${randomUUID()}`,
|
|
1141
|
+
signal: caseController.signal,
|
|
1056
1142
|
});
|
|
1057
1143
|
const durationMs = performance.now() - startedAtMs;
|
|
1058
1144
|
|
|
@@ -1383,47 +1469,77 @@ export function createSelfTestApp(provider: ProviderDefinition, options: SelfTes
|
|
|
1383
1469
|
};
|
|
1384
1470
|
const deadline = performance.now() + requestBudgetMs;
|
|
1385
1471
|
const results: SelfTestCaseResult[] = [];
|
|
1472
|
+
const runSignal = c.req.raw.signal;
|
|
1473
|
+
let interruptedCase: SelectedCase | undefined;
|
|
1386
1474
|
// Sequential execution (parallelism 1): self-tests run on serving pods
|
|
1387
1475
|
// and must never compete with themselves for upstream quota.
|
|
1388
1476
|
for (const selected of selection.cases) {
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1477
|
+
const caseController = new AbortController();
|
|
1478
|
+
const abortFromRun = () => caseController.abort(runSignal.reason);
|
|
1479
|
+
runSignal.addEventListener("abort", abortFromRun, { once: true });
|
|
1480
|
+
if (runSignal.aborted) abortFromRun();
|
|
1481
|
+
try {
|
|
1482
|
+
if (runSignal.aborted) {
|
|
1483
|
+
interruptedCase = selected;
|
|
1484
|
+
break;
|
|
1485
|
+
}
|
|
1486
|
+
if (performance.now() >= deadline) {
|
|
1487
|
+
const now = new Date().toISOString();
|
|
1488
|
+
results.push({
|
|
1489
|
+
operationId: selected.operationId,
|
|
1490
|
+
caseName: selected.healthCase.name,
|
|
1491
|
+
status: "skipped",
|
|
1492
|
+
label: selected.healthCase.name,
|
|
1493
|
+
responseTimeMs: 0,
|
|
1494
|
+
skipReason: "budget_exhausted",
|
|
1495
|
+
startedAt: now,
|
|
1496
|
+
finishedAt: now,
|
|
1497
|
+
});
|
|
1498
|
+
continue;
|
|
1499
|
+
}
|
|
1500
|
+
if (!isSelfTestReadOnlyOperation(selected.operation)) {
|
|
1501
|
+
const now = new Date().toISOString();
|
|
1502
|
+
results.push({
|
|
1503
|
+
operationId: selected.operationId,
|
|
1504
|
+
caseName: selected.healthCase.name,
|
|
1505
|
+
status: "error",
|
|
1506
|
+
label: selected.healthCase.name,
|
|
1507
|
+
responseTimeMs: 0,
|
|
1508
|
+
error: {
|
|
1509
|
+
code: "operation_not_read_only",
|
|
1510
|
+
message: `Operation "${selected.operationId}" is not classified read-only; self-test refuses to execute it.`,
|
|
1511
|
+
},
|
|
1512
|
+
startedAt: now,
|
|
1513
|
+
finishedAt: now,
|
|
1514
|
+
});
|
|
1515
|
+
continue;
|
|
1516
|
+
}
|
|
1517
|
+
results.push(
|
|
1518
|
+
await executeSelfTestCase(
|
|
1519
|
+
execution,
|
|
1520
|
+
selected.operationId,
|
|
1521
|
+
selected.suite,
|
|
1522
|
+
selected.healthCase,
|
|
1523
|
+
caseController,
|
|
1524
|
+
),
|
|
1525
|
+
);
|
|
1526
|
+
if (runSignal.aborted) {
|
|
1527
|
+
interruptedCase = selected;
|
|
1528
|
+
break;
|
|
1529
|
+
}
|
|
1530
|
+
} finally {
|
|
1531
|
+
runSignal.removeEventListener("abort", abortFromRun);
|
|
1532
|
+
caseController.abort();
|
|
1419
1533
|
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1534
|
+
}
|
|
1535
|
+
if (interruptedCase) {
|
|
1536
|
+
logSelfTestCancellation(
|
|
1537
|
+
provider,
|
|
1538
|
+
options,
|
|
1539
|
+
request.requestId,
|
|
1540
|
+
interruptedCase,
|
|
1541
|
+
runSignal,
|
|
1542
|
+
execution.sensitiveValues,
|
|
1427
1543
|
);
|
|
1428
1544
|
}
|
|
1429
1545
|
const singleCase = request.operationId !== undefined && request.caseName !== undefined;
|