@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
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import type { ChallengeSolution, ProviderChallenge, StealthResponse } from "../types.js";
|
|
2
|
+
import { normalizedResolverHostname } from "./resolver-vendors/hosts.js";
|
|
3
|
+
import type { ResolverVendorTransport } from "./resolver-vendors/types.js";
|
|
4
|
+
import type { StealthCookieJar } from "./stealth-cookies.js";
|
|
5
|
+
|
|
6
|
+
export type AkamaiSbsdChallenge = Extract<ProviderChallenge, { readonly kind: "akamai_sbsd" }>;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* SDK-owned response detection and solve wiring derived from the provider declaration.
|
|
10
|
+
* The server attaches it to the stealth client options it builds; it is deliberately not
|
|
11
|
+
* part of the public `StealthClientOptions` type.
|
|
12
|
+
*/
|
|
13
|
+
export type StealthChallengeRuntime = {
|
|
14
|
+
readonly akamaiSbsd?: {
|
|
15
|
+
readonly allowedHosts: readonly string[];
|
|
16
|
+
/** Resolver-declared client profile; must name the initiating session's browser family. */
|
|
17
|
+
readonly clientProfile?: string;
|
|
18
|
+
readonly solve?: (
|
|
19
|
+
challenge: AkamaiSbsdChallenge,
|
|
20
|
+
transport: ResolverVendorTransport,
|
|
21
|
+
signal: AbortSignal,
|
|
22
|
+
) => Promise<ChallengeSolution>;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type AkamaiSbsdSessionState = {
|
|
27
|
+
/**
|
|
28
|
+
* Latest v-only script for this session; Phase 2 deliberately has no wall-clock TTL.
|
|
29
|
+
* Challenge-state expiry belongs to the Phase 3 ceremony/solve lease handle
|
|
30
|
+
* (ADR-0010 v1.1), not to the stealth session.
|
|
31
|
+
*/
|
|
32
|
+
rememberedScript?: URL;
|
|
33
|
+
/** In-flight solves keyed by akamaiSbsdChallengeKey; an entry leaves only when it settles. */
|
|
34
|
+
readonly transactions: Map<
|
|
35
|
+
string,
|
|
36
|
+
{
|
|
37
|
+
readonly result: Promise<
|
|
38
|
+
{ readonly solved: true } | { readonly solved: false; error: unknown }
|
|
39
|
+
>;
|
|
40
|
+
}
|
|
41
|
+
>;
|
|
42
|
+
/**
|
|
43
|
+
* Key of the last automatic (safe-method) solve whose refetch was not challenged again.
|
|
44
|
+
* An explicit replay for the same key reuses the solved cookies once instead of solving
|
|
45
|
+
* again; any newer solve or lease expiry clears it.
|
|
46
|
+
*/
|
|
47
|
+
completedSuccessKey?: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Live SBSD `<script src>` paths are per-site obfuscated (zozo.jp captures, 2026-08-28:
|
|
52
|
+
* `/EdTyEb8Lyxqf/9iGcpl/GmKux0/DXObrkm53w/B1p4AQ/ZCF5f/VoJN08X?v=<uuid>` on the
|
|
53
|
+
* `Access Denied` shape, `/SHO9K/...?v=<uuid>&t=<token>` on the behavioral-tile hard shape).
|
|
54
|
+
* `/.well-known/sbsd` is only the POST endpoint string inside the deobfuscated
|
|
55
|
+
* script, never the page's script path. The stable shape is a same-origin script whose `v`
|
|
56
|
+
* is a UUID; cache-busted bundles (`?v=abc123`, hashes, semver) never match it.
|
|
57
|
+
*/
|
|
58
|
+
const SBSD_SCRIPT_VERSION = /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/iu;
|
|
59
|
+
const SBSD_INTERSTITIAL_MAX_BYTES = 4_000;
|
|
60
|
+
const SBSD_SCRIPT_DISCOVERY_MAX_BYTES = 4 * 1_024 * 1_024;
|
|
61
|
+
const SBSD_CHALLENGE_TOKEN_MAX_BYTES = 1_024;
|
|
62
|
+
const SBSD_INTERSTITIAL_MARKER =
|
|
63
|
+
/sec-bc-tile-container|Access Denied|Reference #\d|Pardon Our Interruption|cpr_chlge/iu;
|
|
64
|
+
|
|
65
|
+
function htmlAttribute(value: string): string {
|
|
66
|
+
return value.replace(/&/giu, "&");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function isDeclaredHost(url: URL, allowedHosts: readonly string[]): boolean {
|
|
70
|
+
const hostname = normalizedResolverHostname(url.hostname);
|
|
71
|
+
return allowedHosts.some((host) => normalizedResolverHostname(host) === hostname);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function findAkamaiSbsdScript(body: string, page: URL): URL | undefined {
|
|
75
|
+
// Only markup carries the script tag; JSON and binary bodies skip the scan entirely.
|
|
76
|
+
if (!/^\s*</u.test(body) || Buffer.byteLength(body) > SBSD_SCRIPT_DISCOVERY_MAX_BYTES) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
let passiveScript: URL | undefined;
|
|
80
|
+
for (const match of body.matchAll(/<script\b[^>]*\bsrc\s*=\s*["']([^"']+)["'][^>]*>/giu)) {
|
|
81
|
+
let script: URL;
|
|
82
|
+
try {
|
|
83
|
+
// Relative sources resolve against the page URL, as the browser would.
|
|
84
|
+
script = new URL(htmlAttribute(match[1]!), page);
|
|
85
|
+
} catch {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const version = script.searchParams.get("v")?.trim();
|
|
89
|
+
if (script.origin !== page.origin || !version || !SBSD_SCRIPT_VERSION.test(version)) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (script.searchParams.get("t")?.trim()) return script;
|
|
93
|
+
passiveScript ??= script;
|
|
94
|
+
}
|
|
95
|
+
return passiveScript;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function isAkamaiSbsdInterstitial(body: string): boolean {
|
|
99
|
+
return (
|
|
100
|
+
Buffer.byteLength(body) < SBSD_INTERSTITIAL_MAX_BYTES && SBSD_INTERSTITIAL_MARKER.test(body)
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function parseAkamaiSbsdChallengeToken(body: string): string | undefined {
|
|
105
|
+
if (Buffer.byteLength(body) >= SBSD_INTERSTITIAL_MAX_BYTES) return undefined;
|
|
106
|
+
let parsed: unknown;
|
|
107
|
+
try {
|
|
108
|
+
parsed = JSON.parse(body);
|
|
109
|
+
} catch {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
if (
|
|
113
|
+
!parsed ||
|
|
114
|
+
typeof parsed !== "object" ||
|
|
115
|
+
Array.isArray(parsed) ||
|
|
116
|
+
!("cpr_chlge" in parsed) ||
|
|
117
|
+
parsed.cpr_chlge !== "true" ||
|
|
118
|
+
!("t" in parsed) ||
|
|
119
|
+
typeof parsed.t !== "string"
|
|
120
|
+
) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
const token = parsed.t.trim();
|
|
124
|
+
return token && Buffer.byteLength(token) <= SBSD_CHALLENGE_TOKEN_MAX_BYTES ? token : undefined;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function detectAkamaiSbsdChallenge(
|
|
128
|
+
response: Pick<StealthResponse, "url" | "body">,
|
|
129
|
+
pageUrl: string,
|
|
130
|
+
jar: Pick<StealthCookieJar, "has">,
|
|
131
|
+
allowedHosts: readonly string[],
|
|
132
|
+
state: AkamaiSbsdSessionState,
|
|
133
|
+
): AkamaiSbsdChallenge | undefined {
|
|
134
|
+
let page: URL;
|
|
135
|
+
try {
|
|
136
|
+
page = new URL(response.url ?? pageUrl);
|
|
137
|
+
} catch {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
if (!isDeclaredHost(page, allowedHosts)) return undefined;
|
|
141
|
+
const stateCookieName = jar.has("sbsd_o", page.toString())
|
|
142
|
+
? "sbsd_o"
|
|
143
|
+
: jar.has("bm_so", page.toString())
|
|
144
|
+
? "bm_so"
|
|
145
|
+
: undefined;
|
|
146
|
+
const interstitial = isAkamaiSbsdInterstitial(response.body);
|
|
147
|
+
// Without the state cookie (the jar already holds the Set-Cookie of this very response;
|
|
148
|
+
// the live capture sets bm_so on the page that carries the script) or an interstitial,
|
|
149
|
+
// nothing here is Akamai's: do not scan, and do not let an unrelated UUID-versioned
|
|
150
|
+
// bundle become the remembered script.
|
|
151
|
+
if (!stateCookieName && !interstitial) return undefined;
|
|
152
|
+
const currentScript = findAkamaiSbsdScript(response.body, page);
|
|
153
|
+
if (currentScript) {
|
|
154
|
+
const version = currentScript.searchParams.get("v")?.trim();
|
|
155
|
+
if (version) {
|
|
156
|
+
// Clone rather than re-parse the pathname: a `//x` path would re-parse as a host.
|
|
157
|
+
const rememberedScript = new URL(currentScript);
|
|
158
|
+
rememberedScript.search = "";
|
|
159
|
+
rememberedScript.hash = "";
|
|
160
|
+
rememberedScript.searchParams.set("v", version);
|
|
161
|
+
state.rememberedScript = rememberedScript;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (!stateCookieName) return undefined;
|
|
165
|
+
|
|
166
|
+
const laterToken = parseAkamaiSbsdChallengeToken(response.body);
|
|
167
|
+
const rememberedScript = state.rememberedScript;
|
|
168
|
+
if (laterToken && rememberedScript && rememberedScript.origin === page.origin) {
|
|
169
|
+
return {
|
|
170
|
+
kind: "akamai_sbsd",
|
|
171
|
+
pageUrl: page.toString(),
|
|
172
|
+
scriptUrl: rememberedScript.toString(),
|
|
173
|
+
stateCookieName,
|
|
174
|
+
challengeToken: laterToken,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (!currentScript || !interstitial) return undefined;
|
|
178
|
+
return {
|
|
179
|
+
kind: "akamai_sbsd",
|
|
180
|
+
pageUrl: page.toString(),
|
|
181
|
+
scriptUrl: currentScript.toString(),
|
|
182
|
+
stateCookieName,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* One in-flight solve per session, challenge, and bound identity: requests on one session
|
|
188
|
+
* may still pick a different wreq browser/OS or proxy, and a solve is only valid for the
|
|
189
|
+
* identity that ran it.
|
|
190
|
+
*/
|
|
191
|
+
export function akamaiSbsdChallengeKey(
|
|
192
|
+
challenge: AkamaiSbsdChallenge,
|
|
193
|
+
identity: {
|
|
194
|
+
readonly wreqBrowser: string;
|
|
195
|
+
readonly wreqOs: string;
|
|
196
|
+
readonly proxyUrl: string | undefined;
|
|
197
|
+
},
|
|
198
|
+
): string {
|
|
199
|
+
return JSON.stringify([
|
|
200
|
+
new URL(challenge.scriptUrl).toString(),
|
|
201
|
+
challenge.challengeToken ?? "",
|
|
202
|
+
challenge.stateCookieName,
|
|
203
|
+
identity.wreqBrowser,
|
|
204
|
+
identity.wreqOs,
|
|
205
|
+
identity.proxyUrl ?? "",
|
|
206
|
+
]);
|
|
207
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { Cookie, CookieJar as ToughCookieJar } from "tough-cookie";
|
|
2
|
+
|
|
3
|
+
import { SDKError, StealthCookieStoreVersionError } from "../errors.js";
|
|
4
|
+
import type {
|
|
5
|
+
CookieJar,
|
|
6
|
+
StealthCookieStore,
|
|
7
|
+
StealthCookieStoreV1,
|
|
8
|
+
StealthSessionCookies,
|
|
9
|
+
} from "../types.js";
|
|
10
|
+
|
|
11
|
+
function isRecord(value: unknown): value is Record<PropertyKey, unknown> {
|
|
12
|
+
return typeof value === "object" && value !== null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const LEGACY_COOKIE_ORIGIN = "https://legacy-cookie.invalid/";
|
|
16
|
+
|
|
17
|
+
/** Extract cookie values from Set-Cookie/header strings for request-scoped registration. */
|
|
18
|
+
export function cookieValuesFromHeaders(headers: string | readonly string[]): string[] {
|
|
19
|
+
const values: string[] = [];
|
|
20
|
+
for (const header of typeof headers === "string" ? [headers] : headers) {
|
|
21
|
+
const cookie = Cookie.parse(header);
|
|
22
|
+
if (cookie?.value) values.push(cookie.value);
|
|
23
|
+
}
|
|
24
|
+
return values;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class StealthCookieJar implements CookieJar, StealthSessionCookies {
|
|
28
|
+
private cookies: ToughCookieJar;
|
|
29
|
+
private readonly defaultUrl: string;
|
|
30
|
+
private readonly register: ((value: string) => void) | undefined;
|
|
31
|
+
|
|
32
|
+
constructor(
|
|
33
|
+
cookieStrings: readonly string[],
|
|
34
|
+
defaultUrl = LEGACY_COOKIE_ORIGIN,
|
|
35
|
+
register?: (value: string) => void,
|
|
36
|
+
) {
|
|
37
|
+
this.cookies = new ToughCookieJar(undefined, {
|
|
38
|
+
allowSecureOnLocal: false,
|
|
39
|
+
rejectPublicSuffixes: true,
|
|
40
|
+
});
|
|
41
|
+
this.defaultUrl = this.normalizeUrl(defaultUrl) ?? LEGACY_COOKIE_ORIGIN;
|
|
42
|
+
this.register = register;
|
|
43
|
+
this.setFromCookieStrings(cookieStrings);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
setFromCookieStrings(cookieStrings: readonly string[], url = this.defaultUrl): void {
|
|
47
|
+
const cookieUrl = this.normalizeUrl(url);
|
|
48
|
+
if (!cookieUrl) return;
|
|
49
|
+
for (const cookieString of cookieStrings) {
|
|
50
|
+
for (const value of cookieValuesFromHeaders(cookieString)) this.register?.(value);
|
|
51
|
+
this.cookies.setCookieSync(cookieString, cookieUrl, { ignoreError: true });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get(name: string, url?: string): string | undefined {
|
|
56
|
+
return this.getAll(url)[name];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getAll(url?: string): Record<string, string> {
|
|
60
|
+
return Object.fromEntries(
|
|
61
|
+
this.getUniqueCookies(url ?? this.defaultUrl).map((cookie) => [cookie.key, cookie.value]),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
has(name: string, url?: string): boolean {
|
|
66
|
+
return Object.hasOwn(this.getAll(url), name);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
toString(url?: string): string {
|
|
70
|
+
return this.getUniqueCookies(url ?? this.defaultUrl)
|
|
71
|
+
.map((cookie) => cookie.cookieString())
|
|
72
|
+
.join("; ");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
toHeader(url?: string): string {
|
|
76
|
+
return this.toString(url);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
snapshot(): Record<string, string> {
|
|
80
|
+
const entries: [string, string][] = [];
|
|
81
|
+
for (const cookie of this.serialize().jar.cookies) {
|
|
82
|
+
if (typeof cookie.key === "string" && typeof cookie.value === "string" && cookie.key) {
|
|
83
|
+
entries.push([cookie.key, cookie.value]);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return Object.fromEntries(entries);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
restore(cookies: Record<string, string>): void {
|
|
90
|
+
this.clear();
|
|
91
|
+
for (const [name, value] of Object.entries(cookies)) {
|
|
92
|
+
if (!name) continue;
|
|
93
|
+
this.register?.(value);
|
|
94
|
+
this.cookies.setCookieSync(new Cookie({ key: name, path: "/", value }), this.defaultUrl, {
|
|
95
|
+
ignoreError: true,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
serialize(): StealthCookieStoreV1 {
|
|
101
|
+
const jar = this.cookies.serializeSync();
|
|
102
|
+
if (!jar) {
|
|
103
|
+
throw new SDKError("Stealth cookie store could not be serialized", {
|
|
104
|
+
code: "stealth_cookie_store_serialize_failed",
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return { version: 1, jar };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
deserialize(state: StealthCookieStore): void {
|
|
111
|
+
const version = isRecord(state) ? state.version : undefined;
|
|
112
|
+
if (version !== 1) {
|
|
113
|
+
throw new StealthCookieStoreVersionError(version);
|
|
114
|
+
}
|
|
115
|
+
const restored = ToughCookieJar.deserializeSync(state.jar);
|
|
116
|
+
Reflect.set(restored, "allowSecureOnLocal", false);
|
|
117
|
+
this.cookies = restored;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
clear(): void {
|
|
121
|
+
this.cookies.removeAllCookiesSync();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
find(predicate: (cookie: string) => boolean, url?: string): string | undefined {
|
|
125
|
+
for (const cookie of this.getUniqueCookies(url ?? this.defaultUrl)) {
|
|
126
|
+
const cookieString = cookie.cookieString();
|
|
127
|
+
if (predicate(cookieString)) return cookieString;
|
|
128
|
+
}
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
names(url?: string): string[] {
|
|
133
|
+
return this.getUniqueCookies(url ?? this.defaultUrl).map((cookie) => cookie.key);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private normalizeUrl(url: string): string | undefined {
|
|
137
|
+
try {
|
|
138
|
+
return new URL(url).toString();
|
|
139
|
+
} catch {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private getUniqueCookies(url: string): Cookie[] {
|
|
145
|
+
const cookieUrl = this.normalizeUrl(url);
|
|
146
|
+
if (!cookieUrl) return [];
|
|
147
|
+
const names = new Set<string>();
|
|
148
|
+
return this.cookies.getCookiesSync(cookieUrl).filter((cookie) => {
|
|
149
|
+
if (cookie.value) this.register?.(cookie.value);
|
|
150
|
+
if (names.has(cookie.key)) return false;
|
|
151
|
+
names.add(cookie.key);
|
|
152
|
+
return true;
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { SDKError } from "../errors.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Header names the stealth transport owns.
|
|
5
|
+
*
|
|
6
|
+
* `ctx.stealth` composes these from the Chrome emulation and the request class,
|
|
7
|
+
* so a caller value is rejected at request time with `SDKError` code
|
|
8
|
+
* `STEALTH_HEADER_OVERRIDE_UNSUPPORTED` ({@link assertCallerHeadersSupported}).
|
|
9
|
+
* The offline test harness (`runStandardTests`) calls the same function on
|
|
10
|
+
* every `ctx.stealth` request it serves, so a provider test fails exactly where
|
|
11
|
+
* production would, whichever file or variable the header came from. That is
|
|
12
|
+
* the cross-file enforcement.
|
|
13
|
+
*
|
|
14
|
+
* The `browser-version-literal` lint reports a subset of these names — the
|
|
15
|
+
* `sec-fetch-*` and `sec-ch-ua*` families — in files that use `ctx.stealth`
|
|
16
|
+
* (`isReportedOwnedHeaderName` in lint.ts). Both read this module, so the lint
|
|
17
|
+
* cannot claim a rejection the runtime does not perform; it reports
|
|
18
|
+
* deliberately less than the runtime rejects (host, connection,
|
|
19
|
+
* accept-encoding and a non-literal user-agent stay silent — see that
|
|
20
|
+
* predicate for why), so a green `apifuse check` is not proof that no owned
|
|
21
|
+
* header is set.
|
|
22
|
+
*
|
|
23
|
+
* Kept off the stealth runtime: the only import is `errors.js`, whose own
|
|
24
|
+
* imports are type-only, so the lazily loaded CLI lint path does not pull the
|
|
25
|
+
* stealth runtime in.
|
|
26
|
+
*/
|
|
27
|
+
export const SDK_OWNED_EXACT_CHROME_HEADERS: ReadonlySet<string> = new Set([
|
|
28
|
+
"host",
|
|
29
|
+
"connection",
|
|
30
|
+
"user-agent",
|
|
31
|
+
"sec-ch-ua",
|
|
32
|
+
"sec-ch-ua-mobile",
|
|
33
|
+
"sec-ch-ua-platform",
|
|
34
|
+
"accept-encoding",
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
export const SDK_OWNED_CHROME_HEADER_PREFIX = "sec-fetch-";
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* True when `ctx.stealth` rejects a caller value for `name` (case-insensitive):
|
|
41
|
+
* an exact member of {@link SDK_OWNED_EXACT_CHROME_HEADERS} or any
|
|
42
|
+
* `sec-fetch-*` name.
|
|
43
|
+
*/
|
|
44
|
+
export function isStealthOwnedHeaderName(name: string): boolean {
|
|
45
|
+
const lower = name.toLowerCase();
|
|
46
|
+
return (
|
|
47
|
+
SDK_OWNED_EXACT_CHROME_HEADERS.has(lower) || lower.startsWith(SDK_OWNED_CHROME_HEADER_PREFIX)
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Throws `SDKError` `STEALTH_HEADER_OVERRIDE_UNSUPPORTED` for the first caller
|
|
53
|
+
* header `ctx.stealth` owns. An `undefined` value is skipped, as the transport
|
|
54
|
+
* drops it before sending. The stealth runtime and the offline test harness
|
|
55
|
+
* both call this, so the two cannot disagree about what is rejected.
|
|
56
|
+
*/
|
|
57
|
+
export function assertCallerHeadersSupported(
|
|
58
|
+
headers: Readonly<Record<string, string | readonly string[] | undefined>>,
|
|
59
|
+
): void {
|
|
60
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
61
|
+
if (value === undefined || !isStealthOwnedHeaderName(name)) continue;
|
|
62
|
+
throw new SDKError(
|
|
63
|
+
`Stealth transport owns the "${name.toLowerCase()}" header; remove it from headers.`,
|
|
64
|
+
{ code: "STEALTH_HEADER_OVERRIDE_UNSUPPORTED" },
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|