@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
|
@@ -1,20 +1,80 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { runCapabilitySpan } from "./capability-telemetry.js";
|
|
2
|
+
import { registerDiagnosticSensitiveValues } from "./diagnostic-redactor.js";
|
|
3
|
+
import type {
|
|
4
|
+
HttpStreamResponse,
|
|
5
|
+
ProviderContext,
|
|
6
|
+
RequestOptions,
|
|
7
|
+
SseMessage,
|
|
8
|
+
StealthSession,
|
|
9
|
+
StealthRedirectRunResult,
|
|
10
|
+
} from "../types.js";
|
|
11
|
+
import { readableBytes, readableLines, readableTextChunks } from "../stream.js";
|
|
12
|
+
import {
|
|
13
|
+
parseHttpRequestInvocation,
|
|
14
|
+
isSensitiveKey,
|
|
15
|
+
redactSensitiveError,
|
|
16
|
+
redactSensitiveText,
|
|
17
|
+
redactUrlQueryParams,
|
|
18
|
+
requestOptionsFromHttpInvocation,
|
|
19
|
+
serializeRequestUrl,
|
|
20
|
+
type SerializedRequestUrl,
|
|
21
|
+
} from "./request-options.js";
|
|
2
22
|
import {
|
|
3
23
|
type CreateTraceContextOptions,
|
|
4
24
|
createTraceContext,
|
|
5
25
|
getTraceRecorder,
|
|
6
26
|
type TraceContext,
|
|
7
27
|
} from "./trace.js";
|
|
28
|
+
import { RESOLVER_INSTRUMENTATION_METADATA } from "./resolver-shared.js";
|
|
29
|
+
import { resolverSpanAttributes } from "./resolver-span-attributes.js";
|
|
8
30
|
|
|
9
31
|
export interface InstrumentationOptions extends CreateTraceContextOptions {}
|
|
10
32
|
|
|
11
|
-
export type InstrumentedProviderContext<T extends ProviderContext
|
|
33
|
+
export type InstrumentedProviderContext<T extends Pick<ProviderContext, "trace">> = Omit<
|
|
34
|
+
T,
|
|
35
|
+
"trace"
|
|
36
|
+
> & {
|
|
12
37
|
trace: TraceContext;
|
|
13
38
|
};
|
|
14
39
|
|
|
15
|
-
type InstrumentedNamespace =
|
|
40
|
+
type InstrumentedNamespace =
|
|
41
|
+
| "http"
|
|
42
|
+
| "stealth"
|
|
43
|
+
| "browser"
|
|
44
|
+
| "session"
|
|
45
|
+
| "state"
|
|
46
|
+
| "resolver"
|
|
47
|
+
| "ocr"
|
|
48
|
+
| "stt";
|
|
49
|
+
|
|
50
|
+
const BROWSER_PAGE_METHODS = new Set([
|
|
51
|
+
"goto",
|
|
52
|
+
"fill",
|
|
53
|
+
"click",
|
|
54
|
+
"type",
|
|
55
|
+
"waitForSelector",
|
|
56
|
+
"evaluate",
|
|
57
|
+
"content",
|
|
58
|
+
"screenshot",
|
|
59
|
+
]);
|
|
60
|
+
const DIAGNOSTIC_BASE_URL = "http://apifuse-instrumentation.invalid";
|
|
61
|
+
|
|
62
|
+
type RequestDiagnostics = {
|
|
63
|
+
diagnosticUrlDegraded?: boolean;
|
|
64
|
+
requestId?: string;
|
|
65
|
+
serializedUrl?: SerializedRequestUrl;
|
|
66
|
+
sensitiveParamNames: readonly string[];
|
|
67
|
+
sensitiveValues: readonly string[];
|
|
68
|
+
traceUrl?: string;
|
|
69
|
+
};
|
|
16
70
|
|
|
17
|
-
|
|
71
|
+
function isThenable(value: unknown): value is PromiseLike<unknown> {
|
|
72
|
+
return (
|
|
73
|
+
(typeof value === "object" || typeof value === "function") &&
|
|
74
|
+
value !== null &&
|
|
75
|
+
typeof (value as { then?: unknown }).then === "function"
|
|
76
|
+
);
|
|
77
|
+
}
|
|
18
78
|
|
|
19
79
|
function getErrorStatus(error: unknown): number | undefined {
|
|
20
80
|
if (
|
|
@@ -84,12 +144,231 @@ function getUrl(
|
|
|
84
144
|
return undefined;
|
|
85
145
|
}
|
|
86
146
|
|
|
147
|
+
function requestOptionsForInvocation(
|
|
148
|
+
namespace: InstrumentedNamespace,
|
|
149
|
+
methodName: string,
|
|
150
|
+
args: readonly unknown[],
|
|
151
|
+
): RequestOptions | undefined {
|
|
152
|
+
if (namespace === "http") {
|
|
153
|
+
const invocation = parseHttpRequestInvocation(methodName, [...args]);
|
|
154
|
+
return invocation ? requestOptionsFromHttpInvocation(invocation) : undefined;
|
|
155
|
+
}
|
|
156
|
+
if (namespace !== "stealth" || methodName !== "fetch" || typeof args[0] !== "string") {
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
const options = args[1];
|
|
160
|
+
return options !== null && typeof options === "object" && !Array.isArray(options)
|
|
161
|
+
? (options as RequestOptions)
|
|
162
|
+
: undefined;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function fallbackSensitiveValues(options?: RequestOptions): readonly string[] {
|
|
166
|
+
const sensitiveParams = options?.sensitiveParams;
|
|
167
|
+
if (!sensitiveParams || typeof sensitiveParams !== "object") return [];
|
|
168
|
+
return Object.values(sensitiveParams).map(String);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function stripDiagnosticBase(url: string): string {
|
|
172
|
+
return url.startsWith(DIAGNOSTIC_BASE_URL) ? url.slice(DIAGNOSTIC_BASE_URL.length) || "/" : url;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function serializeDiagnosticUrl(
|
|
176
|
+
url: string,
|
|
177
|
+
options?: RequestOptions,
|
|
178
|
+
): { degraded: boolean; serializedUrl: SerializedRequestUrl } {
|
|
179
|
+
try {
|
|
180
|
+
return {
|
|
181
|
+
degraded: false,
|
|
182
|
+
serializedUrl: serializeRequestUrl(url, options?.params, options?.sensitiveParams),
|
|
183
|
+
};
|
|
184
|
+
} catch {
|
|
185
|
+
try {
|
|
186
|
+
const absoluteUrl = new URL(url, DIAGNOSTIC_BASE_URL).toString();
|
|
187
|
+
const serialized = serializeRequestUrl(
|
|
188
|
+
absoluteUrl,
|
|
189
|
+
options?.params,
|
|
190
|
+
options?.sensitiveParams,
|
|
191
|
+
);
|
|
192
|
+
return {
|
|
193
|
+
degraded: false,
|
|
194
|
+
serializedUrl: {
|
|
195
|
+
requestUrl: stripDiagnosticBase(serialized.requestUrl),
|
|
196
|
+
redactedUrl: stripDiagnosticBase(serialized.redactedUrl),
|
|
197
|
+
sensitiveValues: serialized.sensitiveValues,
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
} catch {
|
|
201
|
+
const sensitiveParamNames = Object.keys(options?.sensitiveParams ?? {});
|
|
202
|
+
const structural = redactUrlQueryParams(url, sensitiveParamNames);
|
|
203
|
+
return {
|
|
204
|
+
degraded: true,
|
|
205
|
+
serializedUrl: {
|
|
206
|
+
requestUrl: url,
|
|
207
|
+
redactedUrl: structural.redactedUrl,
|
|
208
|
+
sensitiveValues: [
|
|
209
|
+
...new Set([...fallbackSensitiveValues(options), ...structural.sensitiveValues]),
|
|
210
|
+
],
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function snapshotRequestDiagnostics(
|
|
218
|
+
namespace: InstrumentedNamespace,
|
|
219
|
+
methodName: string,
|
|
220
|
+
args: readonly unknown[],
|
|
221
|
+
): RequestDiagnostics {
|
|
222
|
+
const options = requestOptionsForInvocation(namespace, methodName, args);
|
|
223
|
+
const url = typeof args[0] === "string" ? args[0] : undefined;
|
|
224
|
+
const hasSensitiveParams = Boolean(
|
|
225
|
+
options?.sensitiveParams && Object.keys(options.sensitiveParams).length > 0,
|
|
226
|
+
);
|
|
227
|
+
const sensitiveParamNames = Object.keys(options?.sensitiveParams ?? {});
|
|
228
|
+
const diagnosticUrl =
|
|
229
|
+
hasSensitiveParams && url ? serializeDiagnosticUrl(url, options) : undefined;
|
|
230
|
+
const traceUrl =
|
|
231
|
+
hasSensitiveParams && url
|
|
232
|
+
? serializeDiagnosticUrl(url, { sensitiveParams: options?.sensitiveParams }).serializedUrl
|
|
233
|
+
.redactedUrl
|
|
234
|
+
: undefined;
|
|
235
|
+
return {
|
|
236
|
+
...(diagnosticUrl?.degraded ? { diagnosticUrlDegraded: true } : {}),
|
|
237
|
+
...(hasSensitiveParams ? { requestId: crypto.randomUUID() } : {}),
|
|
238
|
+
serializedUrl: diagnosticUrl?.serializedUrl,
|
|
239
|
+
sensitiveParamNames,
|
|
240
|
+
sensitiveValues:
|
|
241
|
+
diagnosticUrl?.serializedUrl.sensitiveValues ?? fallbackSensitiveValues(options),
|
|
242
|
+
traceUrl,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function sanitizeRequestError(error: unknown, diagnostics: RequestDiagnostics): unknown {
|
|
247
|
+
return redactSensitiveError(
|
|
248
|
+
error,
|
|
249
|
+
diagnostics.sensitiveValues,
|
|
250
|
+
diagnostics.serializedUrl?.requestUrl,
|
|
251
|
+
diagnostics.serializedUrl?.redactedUrl,
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function isHttpStreamResponse(value: unknown): value is HttpStreamResponse {
|
|
256
|
+
return (
|
|
257
|
+
typeof value === "object" &&
|
|
258
|
+
value !== null &&
|
|
259
|
+
"body" in value &&
|
|
260
|
+
value.body instanceof ReadableStream
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function instrumentHttpStreamConsumption(
|
|
265
|
+
value: HttpStreamResponse,
|
|
266
|
+
recorder: NonNullable<ReturnType<typeof getTraceRecorder>>,
|
|
267
|
+
args: unknown[],
|
|
268
|
+
diagnostics: RequestDiagnostics,
|
|
269
|
+
): HttpStreamResponse {
|
|
270
|
+
const source = value.body;
|
|
271
|
+
let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;
|
|
272
|
+
const body = new ReadableStream<Uint8Array>(
|
|
273
|
+
{
|
|
274
|
+
async pull(controller) {
|
|
275
|
+
try {
|
|
276
|
+
reader ??= source.getReader();
|
|
277
|
+
const chunk = await reader.read();
|
|
278
|
+
if (chunk.done) {
|
|
279
|
+
controller.close();
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
controller.enqueue(chunk.value);
|
|
283
|
+
} catch (error) {
|
|
284
|
+
const sanitizedError = sanitizeRequestError(error, diagnostics);
|
|
285
|
+
try {
|
|
286
|
+
await recorder.runSpan(
|
|
287
|
+
"http.stream.consume",
|
|
288
|
+
() => {
|
|
289
|
+
throw sanitizedError;
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
onError: (spanError) =>
|
|
293
|
+
buildSpanAttributes("http", "stream", args, undefined, spanError, diagnostics),
|
|
294
|
+
},
|
|
295
|
+
);
|
|
296
|
+
} catch (recordedError) {
|
|
297
|
+
controller.error(recordedError);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
async cancel(reason) {
|
|
302
|
+
try {
|
|
303
|
+
await (reader ? reader.cancel(reason) : source.cancel(reason));
|
|
304
|
+
} catch (error) {
|
|
305
|
+
throw sanitizeRequestError(error, diagnostics);
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
{ highWaterMark: 0 },
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
const instrumented = {
|
|
313
|
+
...value,
|
|
314
|
+
body,
|
|
315
|
+
bytes: () => readableBytes(body),
|
|
316
|
+
textChunks: () => readableTextChunks(body),
|
|
317
|
+
lines: () => readableLines(body),
|
|
318
|
+
} satisfies HttpStreamResponse;
|
|
319
|
+
try {
|
|
320
|
+
Object.assign(value, instrumented);
|
|
321
|
+
return value;
|
|
322
|
+
} catch {
|
|
323
|
+
return instrumented;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function isAsyncIterable<T = unknown>(value: unknown): value is AsyncIterable<T> {
|
|
328
|
+
return (
|
|
329
|
+
typeof value === "object" &&
|
|
330
|
+
value !== null &&
|
|
331
|
+
Symbol.asyncIterator in value &&
|
|
332
|
+
typeof value[Symbol.asyncIterator] === "function"
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function instrumentHttpSseConsumption(
|
|
337
|
+
value: AsyncIterable<SseMessage>,
|
|
338
|
+
recorder: NonNullable<ReturnType<typeof getTraceRecorder>>,
|
|
339
|
+
args: unknown[],
|
|
340
|
+
diagnostics: RequestDiagnostics,
|
|
341
|
+
): AsyncIterable<SseMessage> {
|
|
342
|
+
const source = value;
|
|
343
|
+
return {
|
|
344
|
+
async *[Symbol.asyncIterator]() {
|
|
345
|
+
try {
|
|
346
|
+
for await (const event of source) yield event;
|
|
347
|
+
} catch (error) {
|
|
348
|
+
const sanitizedError = sanitizeRequestError(error, diagnostics);
|
|
349
|
+
return await recorder.runSpan(
|
|
350
|
+
"http.sse.consume",
|
|
351
|
+
() => {
|
|
352
|
+
throw sanitizedError;
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
onError: (spanError) =>
|
|
356
|
+
buildSpanAttributes("http", "sse", args, undefined, spanError, diagnostics),
|
|
357
|
+
},
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
87
364
|
function getMethod(
|
|
88
365
|
namespace: InstrumentedNamespace,
|
|
89
366
|
methodName: string,
|
|
90
367
|
args: unknown[],
|
|
91
368
|
): string | undefined {
|
|
92
369
|
if (namespace === "http") {
|
|
370
|
+
// Preserve the original instrumentation contract: generic entry points are
|
|
371
|
+
// reported as REQUEST/STREAM/SSE, independent of transport options.
|
|
93
372
|
return methodName.toUpperCase();
|
|
94
373
|
}
|
|
95
374
|
|
|
@@ -111,9 +390,19 @@ function buildSpanAttributes(
|
|
|
111
390
|
args: unknown[],
|
|
112
391
|
result?: unknown,
|
|
113
392
|
error?: unknown,
|
|
393
|
+
diagnostics: RequestDiagnostics = { sensitiveParamNames: [], sensitiveValues: [] },
|
|
114
394
|
): Record<string, string | number | boolean> {
|
|
115
395
|
const attributes: Record<string, string | number | boolean> = {};
|
|
116
|
-
const
|
|
396
|
+
const rawUrl = getUrl(namespace, args, result);
|
|
397
|
+
const structuralUrl = diagnostics.traceUrl ?? rawUrl;
|
|
398
|
+
const url = structuralUrl
|
|
399
|
+
? redactSensitiveText(
|
|
400
|
+
structuralUrl,
|
|
401
|
+
diagnostics.sensitiveValues,
|
|
402
|
+
diagnostics.serializedUrl?.requestUrl,
|
|
403
|
+
diagnostics.serializedUrl?.redactedUrl,
|
|
404
|
+
)
|
|
405
|
+
: undefined;
|
|
117
406
|
const method = getMethod(namespace, methodName, args);
|
|
118
407
|
const status = error ? getErrorStatus(error) : getResponseStatus(namespace, result);
|
|
119
408
|
const duration = error ? undefined : getResponseDuration(result);
|
|
@@ -121,14 +410,26 @@ function buildSpanAttributes(
|
|
|
121
410
|
if (url) {
|
|
122
411
|
attributes.url = url;
|
|
123
412
|
}
|
|
413
|
+
if (diagnostics.requestId) attributes.request_id = diagnostics.requestId;
|
|
414
|
+
if (diagnostics.diagnosticUrlDegraded) attributes.redaction_degraded = true;
|
|
124
415
|
|
|
125
416
|
if (method) {
|
|
126
417
|
attributes.method = method;
|
|
127
418
|
}
|
|
128
419
|
|
|
129
|
-
if (
|
|
420
|
+
if (
|
|
421
|
+
status !== undefined &&
|
|
422
|
+
(namespace === "http" || namespace === "stealth" || namespace === "ocr" || namespace === "stt")
|
|
423
|
+
) {
|
|
130
424
|
attributes.status = status;
|
|
131
425
|
}
|
|
426
|
+
if ((namespace === "ocr" || namespace === "stt") && result && typeof result === "object") {
|
|
427
|
+
if ("model" in result && typeof result.model === "string") attributes.model = result.model;
|
|
428
|
+
if ("durationMs" in result && typeof result.durationMs === "number")
|
|
429
|
+
attributes.duration_ms = result.durationMs;
|
|
430
|
+
if ("warnings" in result && Array.isArray(result.warnings))
|
|
431
|
+
attributes.warnings = result.warnings.length;
|
|
432
|
+
}
|
|
132
433
|
|
|
133
434
|
if (duration !== undefined) {
|
|
134
435
|
attributes.duration_ms = duration;
|
|
@@ -145,6 +446,64 @@ function buildSpanAttributes(
|
|
|
145
446
|
return attributes;
|
|
146
447
|
}
|
|
147
448
|
|
|
449
|
+
function isStealthRedirectRunResult(value: unknown): value is StealthRedirectRunResult {
|
|
450
|
+
return (
|
|
451
|
+
typeof value === "object" &&
|
|
452
|
+
value !== null &&
|
|
453
|
+
"reason" in value &&
|
|
454
|
+
typeof value.reason === "string" &&
|
|
455
|
+
"hops" in value &&
|
|
456
|
+
Array.isArray(value.hops) &&
|
|
457
|
+
"final" in value &&
|
|
458
|
+
typeof value.final === "object" &&
|
|
459
|
+
value.final !== null
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
function buildStealthRedirectAttributes(
|
|
464
|
+
args: unknown[],
|
|
465
|
+
result: unknown,
|
|
466
|
+
error: unknown,
|
|
467
|
+
diagnostics: RequestDiagnostics,
|
|
468
|
+
): Record<string, string | number | boolean> {
|
|
469
|
+
const attributes = buildSpanAttributes("stealth", "fetch", args, undefined, error, diagnostics);
|
|
470
|
+
if (!isStealthRedirectRunResult(result)) return attributes;
|
|
471
|
+
|
|
472
|
+
attributes.redirect_reason = result.reason;
|
|
473
|
+
attributes.redirect_hop_count = result.hops.length;
|
|
474
|
+
attributes.status = result.final.status;
|
|
475
|
+
if (result.hops.length > 0) {
|
|
476
|
+
const sensitiveValues = new Set(diagnostics.sensitiveValues);
|
|
477
|
+
const path = result.hops
|
|
478
|
+
.map((hop) => {
|
|
479
|
+
const hopUrl = hop.nextUrl ?? hop.url;
|
|
480
|
+
const responseSensitiveParamNames = [...queryParamNames(hopUrl)].filter(isSensitiveKey);
|
|
481
|
+
const structural = redactUrlQueryParams(hopUrl, [
|
|
482
|
+
...new Set([...diagnostics.sensitiveParamNames, ...responseSensitiveParamNames]),
|
|
483
|
+
]);
|
|
484
|
+
for (const value of structural.sensitiveValues) sensitiveValues.add(value);
|
|
485
|
+
const safeUrl = redactSensitiveText(structural.redactedUrl, [...sensitiveValues]);
|
|
486
|
+
return `${hop.method} ${hop.status} ${safeUrl}`;
|
|
487
|
+
})
|
|
488
|
+
.join(" -> ");
|
|
489
|
+
attributes.redirect_path = redactSensitiveText(
|
|
490
|
+
path,
|
|
491
|
+
[...sensitiveValues],
|
|
492
|
+
diagnostics.serializedUrl?.requestUrl,
|
|
493
|
+
diagnostics.serializedUrl?.redactedUrl,
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
return attributes;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function queryParamNames(url: string): Set<string> {
|
|
500
|
+
const queryStart = url.indexOf("?");
|
|
501
|
+
if (queryStart === -1) return new Set();
|
|
502
|
+
const fragmentStart = url.indexOf("#", queryStart);
|
|
503
|
+
const query = url.slice(queryStart + 1, fragmentStart === -1 ? undefined : fragmentStart);
|
|
504
|
+
return new Set(new URLSearchParams(query).keys());
|
|
505
|
+
}
|
|
506
|
+
|
|
148
507
|
function getBrowserPageAttributes(
|
|
149
508
|
methodName: string,
|
|
150
509
|
args: unknown[],
|
|
@@ -208,18 +567,33 @@ function wrapPage<T extends object>(page: T, trace: TraceContext): T {
|
|
|
208
567
|
const methodName = String(property);
|
|
209
568
|
const wrapped = (...args: unknown[]) => {
|
|
210
569
|
let elapsedMs = 0;
|
|
570
|
+
const diagnostics = snapshotRequestDiagnostics("browser", methodName, args);
|
|
571
|
+
registerDiagnosticSensitiveValues(trace, diagnostics.sensitiveValues);
|
|
211
572
|
|
|
212
573
|
return recorder.runSpan(
|
|
213
|
-
|
|
574
|
+
["evaluate", "content", "screenshot"].includes(methodName)
|
|
575
|
+
? `browser.${methodName}`
|
|
576
|
+
: `browser.page.${methodName}`,
|
|
214
577
|
async () => {
|
|
215
578
|
const startedAt = Date.now();
|
|
216
|
-
|
|
579
|
+
let result: unknown;
|
|
580
|
+
try {
|
|
581
|
+
result = await Reflect.apply(value, pageTarget, args);
|
|
582
|
+
} catch (error) {
|
|
583
|
+
throw sanitizeRequestError(error, diagnostics);
|
|
584
|
+
}
|
|
217
585
|
elapsedMs = Date.now() - startedAt;
|
|
218
586
|
return result;
|
|
219
587
|
},
|
|
220
588
|
{
|
|
221
|
-
onSuccess: () =>
|
|
222
|
-
|
|
589
|
+
onSuccess: () => ({
|
|
590
|
+
...getBrowserPageAttributes(methodName, args, elapsedMs),
|
|
591
|
+
...(diagnostics.traceUrl ? { url: diagnostics.traceUrl } : {}),
|
|
592
|
+
}),
|
|
593
|
+
onError: (error) => ({
|
|
594
|
+
...getBrowserPageAttributes(methodName, args, undefined, error),
|
|
595
|
+
...(diagnostics.traceUrl ? { url: diagnostics.traceUrl } : {}),
|
|
596
|
+
}),
|
|
223
597
|
},
|
|
224
598
|
);
|
|
225
599
|
};
|
|
@@ -230,26 +604,121 @@ function wrapPage<T extends object>(page: T, trace: TraceContext): T {
|
|
|
230
604
|
});
|
|
231
605
|
}
|
|
232
606
|
|
|
607
|
+
function wrapStealthRedirects(
|
|
608
|
+
redirects: StealthSession["redirects"],
|
|
609
|
+
trace: TraceContext,
|
|
610
|
+
): StealthSession["redirects"] {
|
|
611
|
+
const recorder = getTraceRecorder(trace);
|
|
612
|
+
if (!recorder) return redirects;
|
|
613
|
+
|
|
614
|
+
return {
|
|
615
|
+
run(...args: Parameters<StealthSession["redirects"]["run"]>) {
|
|
616
|
+
const diagnosticArgs = [args[0].url, args[0]];
|
|
617
|
+
const diagnostics = snapshotRequestDiagnostics("stealth", "fetch", diagnosticArgs);
|
|
618
|
+
registerDiagnosticSensitiveValues(trace, diagnostics.sensitiveValues);
|
|
619
|
+
let result: ReturnType<StealthSession["redirects"]["run"]>;
|
|
620
|
+
try {
|
|
621
|
+
result = redirects.run(...args);
|
|
622
|
+
} catch (error) {
|
|
623
|
+
const sanitizedError = sanitizeRequestError(error, diagnostics);
|
|
624
|
+
recorder
|
|
625
|
+
.runSpan(
|
|
626
|
+
"stealth.redirects.run",
|
|
627
|
+
() => {
|
|
628
|
+
throw sanitizedError;
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
onError: (spanError) =>
|
|
632
|
+
buildStealthRedirectAttributes(diagnosticArgs, undefined, spanError, diagnostics),
|
|
633
|
+
},
|
|
634
|
+
)
|
|
635
|
+
.catch(() => undefined);
|
|
636
|
+
throw sanitizedError;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
const sanitizedResult = Promise.resolve(result).catch((error: unknown) => {
|
|
640
|
+
throw sanitizeRequestError(error, diagnostics);
|
|
641
|
+
});
|
|
642
|
+
return recorder.runSpan("stealth.redirects.run", () => sanitizedResult, {
|
|
643
|
+
onSuccess: (spanResult) =>
|
|
644
|
+
buildStealthRedirectAttributes(diagnosticArgs, spanResult, undefined, diagnostics),
|
|
645
|
+
onError: (error) =>
|
|
646
|
+
buildStealthRedirectAttributes(diagnosticArgs, undefined, error, diagnostics),
|
|
647
|
+
});
|
|
648
|
+
},
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
function wrapStealthSession(session: StealthSession, trace: TraceContext): StealthSession {
|
|
653
|
+
const wrappedSession = wrapNamespace("stealth", session, trace);
|
|
654
|
+
const redirects = wrapStealthRedirects(session.redirects, trace);
|
|
655
|
+
return new Proxy(wrappedSession, {
|
|
656
|
+
get(target, property, receiver) {
|
|
657
|
+
return property === "redirects" ? redirects : Reflect.get(target, property, receiver);
|
|
658
|
+
},
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
|
|
233
662
|
function wrapNamespace<T extends object>(
|
|
234
663
|
namespace: InstrumentedNamespace,
|
|
235
664
|
target: T,
|
|
236
665
|
trace: TraceContext,
|
|
666
|
+
shouldInstrument?: (methodName: string, args: unknown[]) => boolean,
|
|
237
667
|
): T {
|
|
238
|
-
const
|
|
239
|
-
if (!
|
|
240
|
-
|
|
241
|
-
|
|
668
|
+
const baseRecorder = getTraceRecorder(trace);
|
|
669
|
+
if (!baseRecorder) return target;
|
|
670
|
+
const recorder: NonNullable<ReturnType<typeof getTraceRecorder>> =
|
|
671
|
+
namespace === "ocr" || namespace === "stt"
|
|
672
|
+
? {
|
|
673
|
+
runSpan: (name, fn, options) =>
|
|
674
|
+
runCapabilitySpan(target, () => baseRecorder.runSpan(name, fn, options)),
|
|
675
|
+
}
|
|
676
|
+
: baseRecorder;
|
|
242
677
|
|
|
243
678
|
const wrappedMethods = new Map<PropertyKey, unknown>();
|
|
679
|
+
const resolverMetadata =
|
|
680
|
+
namespace === "resolver" ? { target, traceRecorder: recorder } : undefined;
|
|
244
681
|
|
|
245
682
|
return new Proxy(target, {
|
|
246
683
|
get(namespaceTarget, property, receiver) {
|
|
684
|
+
if (property === RESOLVER_INSTRUMENTATION_METADATA && resolverMetadata) {
|
|
685
|
+
return resolverMetadata;
|
|
686
|
+
}
|
|
247
687
|
const value = Reflect.get(namespaceTarget, property, receiver);
|
|
248
688
|
|
|
249
689
|
if (typeof value !== "function" || property === "constructor") {
|
|
250
690
|
return value;
|
|
251
691
|
}
|
|
252
692
|
|
|
693
|
+
if (namespace === "resolver" && property === "solve") {
|
|
694
|
+
if (wrappedMethods.has(property)) {
|
|
695
|
+
return wrappedMethods.get(property);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
const wrapped = (...args: unknown[]) => {
|
|
699
|
+
const challenge = args[0];
|
|
700
|
+
const challengeKind =
|
|
701
|
+
typeof challenge === "object" &&
|
|
702
|
+
challenge !== null &&
|
|
703
|
+
"kind" in challenge &&
|
|
704
|
+
typeof challenge.kind === "string"
|
|
705
|
+
? challenge.kind
|
|
706
|
+
: undefined;
|
|
707
|
+
return recorder.runSpan(
|
|
708
|
+
"resolver.solve",
|
|
709
|
+
() => Reflect.apply(value, namespaceTarget, [args[0], args[1], recorder]),
|
|
710
|
+
{
|
|
711
|
+
attributes: challengeKind
|
|
712
|
+
? resolverSpanAttributes({ challenge_kind: challengeKind })
|
|
713
|
+
: undefined,
|
|
714
|
+
},
|
|
715
|
+
);
|
|
716
|
+
};
|
|
717
|
+
|
|
718
|
+
wrappedMethods.set(property, wrapped);
|
|
719
|
+
return wrapped;
|
|
720
|
+
}
|
|
721
|
+
|
|
253
722
|
if (namespace === "browser" && property === "newPage") {
|
|
254
723
|
if (wrappedMethods.has(property)) {
|
|
255
724
|
return wrappedMethods.get(property);
|
|
@@ -301,6 +770,32 @@ function wrapNamespace<T extends object>(
|
|
|
301
770
|
return wrapped;
|
|
302
771
|
}
|
|
303
772
|
|
|
773
|
+
if (namespace === "browser" && property === "rawPage") {
|
|
774
|
+
if (wrappedMethods.has(property)) return wrappedMethods.get(property);
|
|
775
|
+
const wrapped = (...args: unknown[]) =>
|
|
776
|
+
recorder.runSpan("browser.rawPage", async () => {
|
|
777
|
+
const page = await Reflect.apply(value, namespaceTarget, args);
|
|
778
|
+
return wrapPage(page, trace);
|
|
779
|
+
});
|
|
780
|
+
wrappedMethods.set(property, wrapped);
|
|
781
|
+
return wrapped;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (namespace === "browser" && property === "withIsolatedContext") {
|
|
785
|
+
if (wrappedMethods.has(property)) return wrappedMethods.get(property);
|
|
786
|
+
const wrapped = (handler: unknown, ...args: unknown[]) =>
|
|
787
|
+
recorder.runSpan("browser.withIsolatedContext", async () => {
|
|
788
|
+
if (typeof handler !== "function")
|
|
789
|
+
return Reflect.apply(value, namespaceTarget, [handler, ...args]);
|
|
790
|
+
return Reflect.apply(value, namespaceTarget, [
|
|
791
|
+
(page: object) => Reflect.apply(handler, undefined, [wrapPage(page, trace)]),
|
|
792
|
+
...args,
|
|
793
|
+
]);
|
|
794
|
+
});
|
|
795
|
+
wrappedMethods.set(property, wrapped);
|
|
796
|
+
return wrapped;
|
|
797
|
+
}
|
|
798
|
+
|
|
304
799
|
if (wrappedMethods.has(property)) {
|
|
305
800
|
return wrappedMethods.get(property);
|
|
306
801
|
}
|
|
@@ -309,18 +804,31 @@ function wrapNamespace<T extends object>(
|
|
|
309
804
|
if (namespace === "browser") {
|
|
310
805
|
const wrapped = (...args: unknown[]) => {
|
|
311
806
|
let elapsedMs = 0;
|
|
807
|
+
const diagnostics = snapshotRequestDiagnostics("browser", methodName, args);
|
|
808
|
+
registerDiagnosticSensitiveValues(trace, diagnostics.sensitiveValues);
|
|
312
809
|
|
|
313
810
|
return recorder.runSpan(
|
|
314
811
|
`browser.${methodName}`,
|
|
315
812
|
async () => {
|
|
316
813
|
const startedAt = Date.now();
|
|
317
|
-
|
|
814
|
+
let result: unknown;
|
|
815
|
+
try {
|
|
816
|
+
result = await Reflect.apply(value, namespaceTarget, args);
|
|
817
|
+
} catch (error) {
|
|
818
|
+
throw sanitizeRequestError(error, diagnostics);
|
|
819
|
+
}
|
|
318
820
|
elapsedMs = Date.now() - startedAt;
|
|
319
821
|
return result;
|
|
320
822
|
},
|
|
321
823
|
{
|
|
322
|
-
onSuccess: () =>
|
|
323
|
-
|
|
824
|
+
onSuccess: () => ({
|
|
825
|
+
...getBrowserPageAttributes(methodName, args, elapsedMs),
|
|
826
|
+
...(diagnostics.traceUrl ? { url: diagnostics.traceUrl } : {}),
|
|
827
|
+
}),
|
|
828
|
+
onError: (error) => ({
|
|
829
|
+
...getBrowserPageAttributes(methodName, args, undefined, error),
|
|
830
|
+
...(diagnostics.traceUrl ? { url: diagnostics.traceUrl } : {}),
|
|
831
|
+
}),
|
|
324
832
|
},
|
|
325
833
|
);
|
|
326
834
|
};
|
|
@@ -329,15 +837,104 @@ function wrapNamespace<T extends object>(
|
|
|
329
837
|
return wrapped;
|
|
330
838
|
}
|
|
331
839
|
|
|
332
|
-
const wrapped = (...args: unknown[]) =>
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
)
|
|
840
|
+
const wrapped = (...args: unknown[]) => {
|
|
841
|
+
if (shouldInstrument && !shouldInstrument(methodName, args)) {
|
|
842
|
+
return Reflect.apply(value, namespaceTarget, args);
|
|
843
|
+
}
|
|
844
|
+
const requestDiagnostics = snapshotRequestDiagnostics(namespace, methodName, args);
|
|
845
|
+
registerDiagnosticSensitiveValues(trace, requestDiagnostics.sensitiveValues);
|
|
846
|
+
// Invoke first and decide by the RETURN VALUE. `runSpan` always
|
|
847
|
+
// returns a Promise, so unconditionally span-wrapping every member
|
|
848
|
+
// silently rewrote synchronous contracts: `ctx.state.namespace()`
|
|
849
|
+
// (a sync factory) came back as a Promise, and every method call on
|
|
850
|
+
// it threw a raw TypeError — surfaced in production as catchtable's
|
|
851
|
+
// deterministic CONFIRM_STATE_UNAVAILABLE on 2026-07-27 (and the
|
|
852
|
+
// 2026-07-22 reserve internal_error loop before it). Sync members
|
|
853
|
+
// keep their sync contract; only genuinely async operations are
|
|
854
|
+
// recorded as spans.
|
|
855
|
+
let result: unknown;
|
|
856
|
+
try {
|
|
857
|
+
result = Reflect.apply(value, namespaceTarget, args);
|
|
858
|
+
} catch (error) {
|
|
859
|
+
const sanitizedError = sanitizeRequestError(error, requestDiagnostics);
|
|
860
|
+
// A promise-returning implementation may still throw
|
|
861
|
+
// SYNCHRONOUSLY during pre-flight validation. Preserve the
|
|
862
|
+
// synchronous throw contract, but keep recording the failure
|
|
863
|
+
// span (the pre-fidelity wrapper captured these).
|
|
864
|
+
recorder
|
|
865
|
+
.runSpan(
|
|
866
|
+
`${namespace}.${methodName}`,
|
|
867
|
+
() => {
|
|
868
|
+
throw sanitizedError;
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
onError: (spanError) =>
|
|
872
|
+
buildSpanAttributes(
|
|
873
|
+
namespace,
|
|
874
|
+
methodName,
|
|
875
|
+
args,
|
|
876
|
+
undefined,
|
|
877
|
+
spanError,
|
|
878
|
+
requestDiagnostics,
|
|
879
|
+
),
|
|
880
|
+
},
|
|
881
|
+
)
|
|
882
|
+
.catch(() => undefined);
|
|
883
|
+
throw sanitizedError;
|
|
884
|
+
}
|
|
885
|
+
if (!isThenable(result)) {
|
|
886
|
+
// The state namespace factory returns the object whose METHODS
|
|
887
|
+
// are the operations worth tracing — instrument that object so
|
|
888
|
+
// `state.get`/`state.compareAndSet`/… spans exist (they never
|
|
889
|
+
// could before: the factory's return value was destroyed).
|
|
890
|
+
if (
|
|
891
|
+
namespace === "state" &&
|
|
892
|
+
methodName === "namespace" &&
|
|
893
|
+
typeof result === "object" &&
|
|
894
|
+
result !== null
|
|
895
|
+
) {
|
|
896
|
+
return wrapNamespace(namespace, result, trace);
|
|
897
|
+
}
|
|
898
|
+
if (
|
|
899
|
+
namespace === "stealth" &&
|
|
900
|
+
methodName === "createSession" &&
|
|
901
|
+
typeof result === "object" &&
|
|
902
|
+
result !== null
|
|
903
|
+
) {
|
|
904
|
+
return wrapStealthSession(result as StealthSession, trace);
|
|
905
|
+
}
|
|
906
|
+
return result;
|
|
907
|
+
}
|
|
908
|
+
const sanitizedResult = Promise.resolve(result).catch((error: unknown) => {
|
|
909
|
+
throw sanitizeRequestError(error, requestDiagnostics);
|
|
910
|
+
});
|
|
911
|
+
const tracedResult = recorder.runSpan(`${namespace}.${methodName}`, () => sanitizedResult, {
|
|
912
|
+
onSuccess: (spanResult) =>
|
|
913
|
+
buildSpanAttributes(
|
|
914
|
+
namespace,
|
|
915
|
+
methodName,
|
|
916
|
+
args,
|
|
917
|
+
spanResult,
|
|
918
|
+
undefined,
|
|
919
|
+
requestDiagnostics,
|
|
920
|
+
),
|
|
921
|
+
onError: (error) =>
|
|
922
|
+
buildSpanAttributes(namespace, methodName, args, undefined, error, requestDiagnostics),
|
|
923
|
+
});
|
|
924
|
+
return namespace === "http" && methodName === "stream"
|
|
925
|
+
? tracedResult.then((spanResult) =>
|
|
926
|
+
isHttpStreamResponse(spanResult)
|
|
927
|
+
? instrumentHttpStreamConsumption(spanResult, recorder, args, requestDiagnostics)
|
|
928
|
+
: spanResult,
|
|
929
|
+
)
|
|
930
|
+
: namespace === "http" && methodName === "sse"
|
|
931
|
+
? tracedResult.then((spanResult) =>
|
|
932
|
+
isAsyncIterable<SseMessage>(spanResult)
|
|
933
|
+
? instrumentHttpSseConsumption(spanResult, recorder, args, requestDiagnostics)
|
|
934
|
+
: spanResult,
|
|
935
|
+
)
|
|
936
|
+
: tracedResult;
|
|
937
|
+
};
|
|
341
938
|
|
|
342
939
|
wrappedMethods.set(property, wrapped);
|
|
343
940
|
return wrapped;
|
|
@@ -349,7 +946,7 @@ function hasTraceOverrides(options: InstrumentationOptions): boolean {
|
|
|
349
946
|
return options.maxSpans !== undefined || options.onSpan !== undefined;
|
|
350
947
|
}
|
|
351
948
|
|
|
352
|
-
export function wrapWithInstrumentation<T extends ProviderContext
|
|
949
|
+
export function wrapWithInstrumentation<T extends Pick<ProviderContext, "trace">>(
|
|
353
950
|
ctx: T,
|
|
354
951
|
options: InstrumentationOptions = {},
|
|
355
952
|
): InstrumentedProviderContext<T> {
|
|
@@ -370,7 +967,10 @@ export function wrapWithInstrumentation<T extends ProviderContext>(
|
|
|
370
967
|
property === "stealth" ||
|
|
371
968
|
property === "browser" ||
|
|
372
969
|
property === "session" ||
|
|
373
|
-
property === "state"
|
|
970
|
+
property === "state" ||
|
|
971
|
+
property === "resolver" ||
|
|
972
|
+
property === "ocr" ||
|
|
973
|
+
property === "stt"
|
|
374
974
|
) {
|
|
375
975
|
const namespace = property;
|
|
376
976
|
if (wrappedTargets.has(namespace)) {
|