@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
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
// 3. A Node (not bun) ESM runtime import — node does not tolerate
|
|
19
19
|
// extensionless relative specifiers, bun does.
|
|
20
20
|
//
|
|
21
|
-
//
|
|
21
|
+
// Deliberate negative controls prove the fixture compiler actually fails on
|
|
22
22
|
// type errors, so this check cannot rot into a false-positive green.
|
|
23
23
|
|
|
24
24
|
import { execFileSync, spawnSync } from "node:child_process";
|
|
25
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
25
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
26
26
|
import { tmpdir } from "node:os";
|
|
27
27
|
import { join, resolve } from "node:path";
|
|
28
28
|
import { z } from "zod";
|
|
@@ -36,6 +36,631 @@ const PACK_RESULT_SCHEMA = z.array(
|
|
|
36
36
|
const KEEP_TEMP = process.env.APIFUSE__PACK_TYPES__KEEP_TEMP === "1";
|
|
37
37
|
const sdkRoot = process.cwd();
|
|
38
38
|
|
|
39
|
+
const NEGATIVE_CONTROLS = [
|
|
40
|
+
{
|
|
41
|
+
filename: "negative-control-provider-error-name.ts",
|
|
42
|
+
expectedCode: "TS2322",
|
|
43
|
+
description: "ProviderError.name remains a string",
|
|
44
|
+
source: [
|
|
45
|
+
'import { ProviderError } from "@apifuse/provider-sdk";',
|
|
46
|
+
"",
|
|
47
|
+
"// Intentionally wrong: name is a string. If this file compiles, the",
|
|
48
|
+
"// fixture consumer is not actually type-checking and the guard is void.",
|
|
49
|
+
'export const mustNotCompile: number = new ProviderError("boom").name;',
|
|
50
|
+
"",
|
|
51
|
+
].join("\n"),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
filename: "negative-control-unknown-resolver-vendor.ts",
|
|
55
|
+
expectedCode: "TS2322",
|
|
56
|
+
description: "ProviderResolverConfig rejects an unknown vendor",
|
|
57
|
+
source: [
|
|
58
|
+
'import type { ProviderResolverConfig } from "@apifuse/provider-sdk";',
|
|
59
|
+
"",
|
|
60
|
+
"export const mustNotCompile: ProviderResolverConfig = {",
|
|
61
|
+
'\tvendors: ["unknown-vendor"],',
|
|
62
|
+
'\tkinds: ["turnstile"],',
|
|
63
|
+
"};",
|
|
64
|
+
"",
|
|
65
|
+
].join("\n"),
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
filename: "negative-control-define-provider-resolver-vendor.ts",
|
|
69
|
+
expectedCode: "TS2322",
|
|
70
|
+
description: "defineProvider rejects an unknown resolver vendor",
|
|
71
|
+
source: [
|
|
72
|
+
'import { defineProvider, z } from "@apifuse/provider-sdk";',
|
|
73
|
+
"",
|
|
74
|
+
"export const mustNotCompile = defineProvider({",
|
|
75
|
+
'\tid: "invalid-resolver-vendor",',
|
|
76
|
+
'\tversion: "1.0.0",',
|
|
77
|
+
'\truntime: "standard",',
|
|
78
|
+
'\tresolver: { vendors: ["unknown-vendor"], kinds: ["turnstile"] },',
|
|
79
|
+
'\tmeta: { displayName: "Invalid Resolver Vendor", descriptionKey: "meta.description", category: "test" },',
|
|
80
|
+
"})({",
|
|
81
|
+
"\toperations: {",
|
|
82
|
+
"\t\tprobe: {",
|
|
83
|
+
'\t\t\triskClass: "read",',
|
|
84
|
+
"\t\t\tinput: z.object({}),",
|
|
85
|
+
"\t\t\toutput: z.object({ ok: z.boolean() }),",
|
|
86
|
+
"\t\t\thandler: async () => ({ ok: true }),",
|
|
87
|
+
'\t\t\thealthCheckUnsupported: { reason: "type fixture" },',
|
|
88
|
+
"\t\t},",
|
|
89
|
+
"\t},",
|
|
90
|
+
"});",
|
|
91
|
+
"",
|
|
92
|
+
].join("\n"),
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
filename: "negative-control-unknown-challenge-kind.ts",
|
|
96
|
+
expectedCode: "TS2820",
|
|
97
|
+
description: "ProviderChallenge rejects an unknown challenge kind",
|
|
98
|
+
source: [
|
|
99
|
+
'import type { ProviderChallenge } from "@apifuse/provider-sdk";',
|
|
100
|
+
"",
|
|
101
|
+
"export const mustNotCompile: ProviderChallenge = {",
|
|
102
|
+
'\tkind: "funcaptcha",',
|
|
103
|
+
'\tsiteKey: "key",',
|
|
104
|
+
'\tpageUrl: "https://example.com",',
|
|
105
|
+
"};",
|
|
106
|
+
"",
|
|
107
|
+
].join("\n"),
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
filename: "negative-control-provider-challenge-kind.ts",
|
|
111
|
+
expectedCode: "TS2820",
|
|
112
|
+
description: "ProviderChallengeKind rejects an unknown challenge kind",
|
|
113
|
+
source: [
|
|
114
|
+
'import type { ProviderChallengeKind } from "@apifuse/provider-sdk";',
|
|
115
|
+
"",
|
|
116
|
+
'export const mustNotCompile: ProviderChallengeKind = "funcaptcha";',
|
|
117
|
+
"",
|
|
118
|
+
].join("\n"),
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
filename: "negative-control-cookie-solution-token-read.ts",
|
|
122
|
+
expectedCode: "TS2339",
|
|
123
|
+
description: "ChallengeSolution requires narrowing before reading token",
|
|
124
|
+
source: [
|
|
125
|
+
'import type { ChallengeSolution } from "@apifuse/provider-sdk";',
|
|
126
|
+
"",
|
|
127
|
+
"export function mustNotCompile(solution: ChallengeSolution): string {",
|
|
128
|
+
"\treturn solution.token;",
|
|
129
|
+
"}",
|
|
130
|
+
"",
|
|
131
|
+
].join("\n"),
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
filename: "negative-control-cookie-challenge-site-key.ts",
|
|
135
|
+
expectedCode: "TS2353",
|
|
136
|
+
description: "cookie-family challenges reject token-family fields",
|
|
137
|
+
source: [
|
|
138
|
+
'import type { ProviderChallenge } from "@apifuse/provider-sdk";',
|
|
139
|
+
"",
|
|
140
|
+
"export const mustNotCompile: ProviderChallenge = {",
|
|
141
|
+
'\tkind: "cloudflare_interstitial",',
|
|
142
|
+
'\tpageUrl: "https://example.com",',
|
|
143
|
+
'\tsiteKey: "not-allowed",',
|
|
144
|
+
"};",
|
|
145
|
+
"",
|
|
146
|
+
].join("\n"),
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
filename: "negative-control-aws-waf-site-key-type.ts",
|
|
150
|
+
expectedCode: "TS2322",
|
|
151
|
+
description: "aws_waf siteKey must be a string",
|
|
152
|
+
source: [
|
|
153
|
+
'import type { ProviderChallenge } from "@apifuse/provider-sdk";',
|
|
154
|
+
"",
|
|
155
|
+
"export const mustNotCompile: ProviderChallenge = {",
|
|
156
|
+
'\tkind: "aws_waf",',
|
|
157
|
+
'\tpageUrl: "https://example.com",',
|
|
158
|
+
"\tsiteKey: 123,",
|
|
159
|
+
"};",
|
|
160
|
+
"",
|
|
161
|
+
].join("\n"),
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
filename: "negative-control-aws-waf-context-type.ts",
|
|
165
|
+
expectedCode: "TS2322",
|
|
166
|
+
description: "aws_waf context must be a string",
|
|
167
|
+
source: [
|
|
168
|
+
'import type { ProviderChallenge } from "@apifuse/provider-sdk";',
|
|
169
|
+
"",
|
|
170
|
+
"export const mustNotCompile: ProviderChallenge = {",
|
|
171
|
+
'\tkind: "aws_waf",',
|
|
172
|
+
'\tpageUrl: "https://example.com",',
|
|
173
|
+
"\tcontext: 123,",
|
|
174
|
+
"};",
|
|
175
|
+
"",
|
|
176
|
+
].join("\n"),
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
filename: "negative-control-aws-waf-unknown-field.ts",
|
|
180
|
+
expectedCode: "TS2353",
|
|
181
|
+
description: "aws_waf rejects fields it does not declare",
|
|
182
|
+
source: [
|
|
183
|
+
'import type { ProviderChallenge } from "@apifuse/provider-sdk";',
|
|
184
|
+
"",
|
|
185
|
+
"export const mustNotCompile: ProviderChallenge = {",
|
|
186
|
+
'\tkind: "aws_waf",',
|
|
187
|
+
'\tpageUrl: "https://example.com",',
|
|
188
|
+
"\tunknownField: 1,",
|
|
189
|
+
"};",
|
|
190
|
+
"",
|
|
191
|
+
].join("\n"),
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
filename: "negative-control-recaptcha-v3-action.ts",
|
|
195
|
+
expectedCode: "TS2322",
|
|
196
|
+
description: "recaptcha_v3 challenges require action",
|
|
197
|
+
source: [
|
|
198
|
+
'import type { ProviderChallenge } from "@apifuse/provider-sdk";',
|
|
199
|
+
"",
|
|
200
|
+
"export const mustNotCompile: ProviderChallenge = {",
|
|
201
|
+
'\tkind: "recaptcha_v3",',
|
|
202
|
+
'\tsiteKey: "key",',
|
|
203
|
+
'\tpageUrl: "https://example.com",',
|
|
204
|
+
"};",
|
|
205
|
+
"",
|
|
206
|
+
].join("\n"),
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
filename: "negative-control-browser-cookie-expires.ts",
|
|
210
|
+
expectedCode: "TS2322",
|
|
211
|
+
description: "BrowserCookie.expires remains optional for session cookies",
|
|
212
|
+
source: [
|
|
213
|
+
'import type { BrowserCookie } from "@apifuse/provider-sdk";',
|
|
214
|
+
"",
|
|
215
|
+
"export function mustNotCompile(cookie: BrowserCookie): number {",
|
|
216
|
+
"\treturn cookie.expires;",
|
|
217
|
+
"}",
|
|
218
|
+
"",
|
|
219
|
+
].join("\n"),
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
filename: "negative-control-resolver-runtime-identity.ts",
|
|
223
|
+
expectedCode: "TS2353",
|
|
224
|
+
description: "ResolverRuntimeOptions does not accept caller-synthesized identity",
|
|
225
|
+
source: [
|
|
226
|
+
'import type { ResolverRuntimeOptions } from "@apifuse/provider-sdk";',
|
|
227
|
+
"",
|
|
228
|
+
"export const mustNotCompile: ResolverRuntimeOptions = {",
|
|
229
|
+
'\tidentity: "caller-controlled",',
|
|
230
|
+
"};",
|
|
231
|
+
"",
|
|
232
|
+
].join("\n"),
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
filename: "negative-control-resolver-runtime-adapter-factories.ts",
|
|
236
|
+
expectedCode: "TS2353",
|
|
237
|
+
description: "ResolverRuntimeOptions does not accept caller-supplied adapter factories",
|
|
238
|
+
source: [
|
|
239
|
+
'import type { ResolverRuntimeOptions } from "@apifuse/provider-sdk";',
|
|
240
|
+
"",
|
|
241
|
+
"export const mustNotCompile: ResolverRuntimeOptions = {",
|
|
242
|
+
"\tadapterFactories: {},",
|
|
243
|
+
"};",
|
|
244
|
+
"",
|
|
245
|
+
].join("\n"),
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
filename: "negative-control-resolver-default-user-agent-test-seam.ts",
|
|
249
|
+
expectedCode: "TS2305",
|
|
250
|
+
description: "the resolver subpath does not expose its default user-agent test seam",
|
|
251
|
+
source: [
|
|
252
|
+
'import { swapResolverDefaultUserAgentForTests } from "@apifuse/provider-sdk/runtime/resolver";',
|
|
253
|
+
"",
|
|
254
|
+
"export const mustNotCompile = swapResolverDefaultUserAgentForTests;",
|
|
255
|
+
"",
|
|
256
|
+
].join("\n"),
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
filename: "negative-control-cache-reset-test-seam.ts",
|
|
260
|
+
expectedCode: "TS2305",
|
|
261
|
+
description: "the package root does not expose its cache-reset test seam",
|
|
262
|
+
source: [
|
|
263
|
+
'import { resetProviderCacheForTests } from "@apifuse/provider-sdk";',
|
|
264
|
+
"",
|
|
265
|
+
"export const mustNotCompile = resetProviderCacheForTests;",
|
|
266
|
+
"",
|
|
267
|
+
].join("\n"),
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
filename: "negative-control-resolver-runtime-allowed-hosts.ts",
|
|
271
|
+
expectedCode: "TS2322",
|
|
272
|
+
description: "ResolverRuntimeOptions.allowedHosts accepts only host strings",
|
|
273
|
+
source: [
|
|
274
|
+
'import type { ResolverRuntimeOptions } from "@apifuse/provider-sdk";',
|
|
275
|
+
"",
|
|
276
|
+
"export const mustNotCompile: ResolverRuntimeOptions = {",
|
|
277
|
+
'\tallowedHosts: ["example.com", 42],',
|
|
278
|
+
"};",
|
|
279
|
+
"",
|
|
280
|
+
].join("\n"),
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
filename: "negative-control-resolver-signal.ts",
|
|
284
|
+
expectedCode: "TS2345",
|
|
285
|
+
description: "ResolverContext.solve accepts only AbortSignal as its optional signal",
|
|
286
|
+
source: [
|
|
287
|
+
'import type { ProviderChallenge, ResolverContext } from "@apifuse/provider-sdk";',
|
|
288
|
+
"",
|
|
289
|
+
"declare const resolver: ResolverContext;",
|
|
290
|
+
"declare const challenge: ProviderChallenge;",
|
|
291
|
+
"resolver.solve(challenge, { aborted: false });",
|
|
292
|
+
"",
|
|
293
|
+
].join("\n"),
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
filename: "negative-control-proxy-telemetry-vendor.ts",
|
|
297
|
+
expectedCode: "TS2322",
|
|
298
|
+
description: "proxy gateway telemetry rejects an unbranded vendor string",
|
|
299
|
+
source: [
|
|
300
|
+
'import type { TelemetryContributor } from "@apifuse/provider-sdk";',
|
|
301
|
+
"",
|
|
302
|
+
"const bad: TelemetryContributor<{}, { vendor: string }> = {",
|
|
303
|
+
'\tkey: "proxy",',
|
|
304
|
+
"\ttoLogPayload: () => ({}),",
|
|
305
|
+
'\ttoHeaderPayload: () => ({ vendor: "free-text" }),',
|
|
306
|
+
"};",
|
|
307
|
+
"",
|
|
308
|
+
].join("\n"),
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
filename: "negative-control-telemetry-header-host.ts",
|
|
312
|
+
expectedCode: "TS2322",
|
|
313
|
+
description: "gateway telemetry headers reject an unbranded host string",
|
|
314
|
+
source: [
|
|
315
|
+
'import type { TelemetryContributor } from "@apifuse/provider-sdk";',
|
|
316
|
+
"",
|
|
317
|
+
"const bad: TelemetryContributor<{}, { host: string }> = {",
|
|
318
|
+
'\tkey: "http",',
|
|
319
|
+
"\ttoLogPayload: () => ({}),",
|
|
320
|
+
'\ttoHeaderPayload: () => ({ host: "x.example" }),',
|
|
321
|
+
"};",
|
|
322
|
+
"",
|
|
323
|
+
].join("\n"),
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
filename: "negative-control-telemetry-tenant-vendor.ts",
|
|
327
|
+
expectedCode: "TS2322",
|
|
328
|
+
description: "tenant-neutral projections reject vendor identities",
|
|
329
|
+
source: [
|
|
330
|
+
'import type { TenantNeutral } from "@apifuse/provider-sdk";',
|
|
331
|
+
"",
|
|
332
|
+
'export const bad: TenantNeutral<{ vendorUsed: "smartproxy" }> = { vendorUsed: "smartproxy" };',
|
|
333
|
+
"",
|
|
334
|
+
].join("\n"),
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
filename: "negative-control-telemetry-header-any.ts",
|
|
338
|
+
expectedCode: "TS2322",
|
|
339
|
+
description: "gateway telemetry projections reject any-valued properties",
|
|
340
|
+
source: [
|
|
341
|
+
'import type { GatewayIngestible } from "@apifuse/provider-sdk";',
|
|
342
|
+
"",
|
|
343
|
+
'export const bad: GatewayIngestible<{ x: any }> = { x: "free-text" };',
|
|
344
|
+
"",
|
|
345
|
+
].join("\n"),
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
filename: "negative-control-telemetry-header-union-array.ts",
|
|
349
|
+
expectedCode: "TS2322",
|
|
350
|
+
description: "gateway telemetry projections reject arrays mixing numbers and strings",
|
|
351
|
+
source: [
|
|
352
|
+
'import type { TelemetryContributor } from "@apifuse/provider-sdk";',
|
|
353
|
+
"",
|
|
354
|
+
"const bad: TelemetryContributor<{}, { values: (number | string)[] }> = {",
|
|
355
|
+
'\tkey: "resolver",',
|
|
356
|
+
"\ttoLogPayload: () => ({}),",
|
|
357
|
+
'\ttoHeaderPayload: () => ({ values: [1, "free prose"] }),',
|
|
358
|
+
"};",
|
|
359
|
+
"",
|
|
360
|
+
].join("\n"),
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
filename: "negative-control-telemetry-opaque-identity.ts",
|
|
364
|
+
expectedCode: "TS2322",
|
|
365
|
+
description: "tenant opaque array brands are not accepted outside the cache keys property",
|
|
366
|
+
source: [
|
|
367
|
+
'import type { TenantNeutral } from "@apifuse/provider-sdk";',
|
|
368
|
+
"",
|
|
369
|
+
"type LocalOpaque = string[] & { readonly __tenantOpaqueCacheKeys: true };",
|
|
370
|
+
"declare const opaque: LocalOpaque;",
|
|
371
|
+
"export const bad: TenantNeutral<{ identity: LocalOpaque }> = { identity: opaque };",
|
|
372
|
+
"",
|
|
373
|
+
].join("\n"),
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
filename: "negative-control-telemetry-meta-vendor.ts",
|
|
377
|
+
expectedCode: "TS2322",
|
|
378
|
+
description: "success metadata rejects tenant-visible vendor identity keys",
|
|
379
|
+
source: [
|
|
380
|
+
'import { closedEnum, type ClosedEnum, type TenantNeutral } from "@apifuse/provider-sdk";',
|
|
381
|
+
"",
|
|
382
|
+
'type Meta = { cached: boolean; detail: { vendorUsed: ClosedEnum<"smartproxy"> } };',
|
|
383
|
+
'export const bad: TenantNeutral<Meta> = { cached: false, detail: { vendorUsed: closedEnum("smartproxy") } };',
|
|
384
|
+
"",
|
|
385
|
+
].join("\n"),
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
filename: "positive-control-proxy-telemetry-contributor.ts",
|
|
389
|
+
expectedCode: "",
|
|
390
|
+
description: "proxy telemetry contributor satisfies the public contributor contract",
|
|
391
|
+
source: [
|
|
392
|
+
'import { closedEnum, type ClosedEnum, type GatewayIngestible, type ProxyTelemetryHeaderPayload, type ProxyTelemetryLogPayload, type TelemetryContributor } from "@apifuse/provider-sdk";',
|
|
393
|
+
"",
|
|
394
|
+
"export const proxy: TelemetryContributor<ProxyTelemetryLogPayload, ProxyTelemetryHeaderPayload> = {",
|
|
395
|
+
'\tkey: "proxy",',
|
|
396
|
+
'\ttoLogPayload: () => ({ kind: "unresolved", vendors: [] }),',
|
|
397
|
+
'\ttoHeaderPayload: () => ({ kind: closedEnum("unresolved"), vendors: [] }),',
|
|
398
|
+
"};",
|
|
399
|
+
'type Values = { values: ClosedEnum<"a" | "b">[] };',
|
|
400
|
+
'export const values: GatewayIngestible<Values> = { values: [closedEnum("a"), closedEnum("b")] };',
|
|
401
|
+
"",
|
|
402
|
+
].join("\n"),
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
filename: "negative-control-resolver-telemetry-description.ts",
|
|
406
|
+
expectedCode: "TS2353",
|
|
407
|
+
description: "resolver gateway telemetry rejects vendor error descriptions",
|
|
408
|
+
source: [
|
|
409
|
+
'import type { ResolverTelemetryHeaderPayload } from "@apifuse/provider-sdk";',
|
|
410
|
+
"",
|
|
411
|
+
"export const mustNotCompile: ResolverTelemetryHeaderPayload = {",
|
|
412
|
+
"\tattempts: 0,",
|
|
413
|
+
"\tfailovers: 0,",
|
|
414
|
+
"\tvendorChain: [],",
|
|
415
|
+
"\tpollCount: 0,",
|
|
416
|
+
'\tvendorErrorDescription: "free text must stay log-only",',
|
|
417
|
+
"};",
|
|
418
|
+
"",
|
|
419
|
+
].join("\n"),
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
filename: "negative-control-resolver-telemetry-phase.ts",
|
|
423
|
+
expectedCode: "TS2322",
|
|
424
|
+
description: "resolver gateway telemetry rejects phases outside its closed vocabulary",
|
|
425
|
+
source: [
|
|
426
|
+
'import { closedEnum, type ResolverTelemetryHeaderPayload } from "@apifuse/provider-sdk";',
|
|
427
|
+
"",
|
|
428
|
+
"export const mustNotCompile: ResolverTelemetryHeaderPayload = {",
|
|
429
|
+
"\tattempts: 1,",
|
|
430
|
+
"\tfailovers: 0,",
|
|
431
|
+
'\tvendorChain: [closedEnum("hypersolutions")],',
|
|
432
|
+
"\tpollCount: 0,",
|
|
433
|
+
'\tattemptSamples: [{ v: closedEnum("hypersolutions"), p: closedEnum("solve_exchange"), o: closedEnum("error"), ms: 1 }],',
|
|
434
|
+
"};",
|
|
435
|
+
"",
|
|
436
|
+
].join("\n"),
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
filename: "positive-control-resolver-telemetry-contributor.ts",
|
|
440
|
+
expectedCode: "",
|
|
441
|
+
description: "resolver telemetry contributor satisfies the gateway-ingestible contract",
|
|
442
|
+
source: [
|
|
443
|
+
'import { closedEnum, ResolverTelemetryCollector, type GatewayIngestible, type ResolverTelemetryHeaderPayload, type ResolverTelemetryLogPayload, type ResolverTelemetryPhase, type TelemetryContributor } from "@apifuse/provider-sdk";',
|
|
444
|
+
"",
|
|
445
|
+
"export const resolver: TelemetryContributor<ResolverTelemetryLogPayload, ResolverTelemetryHeaderPayload> = new ResolverTelemetryCollector();",
|
|
446
|
+
'const hyperPhases: ResolverTelemetryPhase[] = ["measure_ip", "fetch_script", "generate_payload", "post_payload"];',
|
|
447
|
+
'export const hyperPhaseHeader: ResolverTelemetryHeaderPayload = { attempts: 1, failovers: 0, vendorChain: [closedEnum("hypersolutions")], pollCount: 0, attemptSamples: hyperPhases.map((phase) => ({ v: closedEnum("hypersolutions"), p: closedEnum(phase), o: closedEnum("ok"), ms: 1 })) };',
|
|
448
|
+
"declare const header: ResolverTelemetryHeaderPayload;",
|
|
449
|
+
"export const ingestible: GatewayIngestible<ResolverTelemetryHeaderPayload> = header;",
|
|
450
|
+
"",
|
|
451
|
+
].join("\n"),
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
filename: "negative-control-native-telemetry-description.ts",
|
|
455
|
+
expectedCode: "TS2322",
|
|
456
|
+
description: "native gateway telemetry rejects free-string diagnostic fields",
|
|
457
|
+
source: [
|
|
458
|
+
'import type { GatewayIngestible, NativeTelemetryHeaderPayload } from "@apifuse/provider-sdk";',
|
|
459
|
+
"type UnsafeHeader = NativeTelemetryHeaderPayload & { vendorErrorMessage: string };",
|
|
460
|
+
"declare const header: NativeTelemetryHeaderPayload;",
|
|
461
|
+
'export const mustNotCompile: GatewayIngestible<UnsafeHeader> = { ...header, vendorErrorMessage: "free text stays log-only" };',
|
|
462
|
+
].join("\n"),
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
filename: "positive-control-native-telemetry-contributor.ts",
|
|
466
|
+
expectedCode: "",
|
|
467
|
+
description: "native telemetry contributor satisfies the gateway-ingestible contract",
|
|
468
|
+
source: [
|
|
469
|
+
'import { NativeTelemetryCollector, type GatewayIngestible, type NativeTelemetryHeaderPayload, type NativeTelemetryLogPayload, type TelemetryContributor } from "@apifuse/provider-sdk";',
|
|
470
|
+
"export const native: TelemetryContributor<NativeTelemetryLogPayload, NativeTelemetryHeaderPayload> = new NativeTelemetryCollector();",
|
|
471
|
+
"declare const header: NativeTelemetryHeaderPayload;",
|
|
472
|
+
"export const ingestible: GatewayIngestible<NativeTelemetryHeaderPayload> = header;",
|
|
473
|
+
].join("\n"),
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
filename: "negative-control-http-telemetry-free-text.ts",
|
|
477
|
+
expectedCode: "TS2322",
|
|
478
|
+
description: "HTTP gateway telemetry rejects a free-string diagnostic field",
|
|
479
|
+
source: [
|
|
480
|
+
'import type { HttpTelemetryHeaderPayload, GatewayIngestible } from "@apifuse/provider-sdk";',
|
|
481
|
+
"type UnsafeHttpHeader = HttpTelemetryHeaderPayload & { message: string };",
|
|
482
|
+
"declare const header: HttpTelemetryHeaderPayload;",
|
|
483
|
+
'export const mustNotCompile: GatewayIngestible<UnsafeHttpHeader> = { ...header, message: "upstream free text" };',
|
|
484
|
+
"",
|
|
485
|
+
].join("\n"),
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
filename: "positive-control-http-telemetry-contributor.ts",
|
|
489
|
+
expectedCode: "",
|
|
490
|
+
description: "HTTP contributor satisfies the gateway and tenant projection contracts",
|
|
491
|
+
source: [
|
|
492
|
+
'import { HttpTelemetryCollector, type HttpTelemetryHeaderPayload, type HttpTelemetryLogPayload, type HttpTelemetryRetryPayload, type GatewayIngestible, type TenantNeutral, type TelemetryContributor } from "@apifuse/provider-sdk";',
|
|
493
|
+
'import { HttpTelemetryCollector as ServerHttpCollector } from "@apifuse/provider-sdk/server";',
|
|
494
|
+
"export const http: TelemetryContributor<HttpTelemetryLogPayload, HttpTelemetryHeaderPayload> = new HttpTelemetryCollector();",
|
|
495
|
+
"declare const header: HttpTelemetryHeaderPayload;",
|
|
496
|
+
"export const ingestible: GatewayIngestible<HttpTelemetryHeaderPayload> = header;",
|
|
497
|
+
"export const retry: TenantNeutral<HttpTelemetryRetryPayload> | undefined = new ServerHttpCollector().toTenantRetryPayload();",
|
|
498
|
+
"",
|
|
499
|
+
].join("\n"),
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
filename: "negative-control-stealth-telemetry-diagnostics.ts",
|
|
503
|
+
expectedCode: "TS2322",
|
|
504
|
+
description: "stealth gateway telemetry rejects a free-string header field",
|
|
505
|
+
source: [
|
|
506
|
+
'import { type GatewayIngestible, type StealthTelemetryHeaderPayload } from "@apifuse/provider-sdk";',
|
|
507
|
+
"type UnsafeHeader = StealthTelemetryHeaderPayload & { diagnostics: string };",
|
|
508
|
+
"declare const unsafeHeader: UnsafeHeader;",
|
|
509
|
+
"export const mustNotCompile: GatewayIngestible<UnsafeHeader> = unsafeHeader;",
|
|
510
|
+
"",
|
|
511
|
+
].join("\n"),
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
filename: "positive-control-stealth-telemetry-contributor.ts",
|
|
515
|
+
expectedCode: "",
|
|
516
|
+
description: "stealth telemetry contributor satisfies the gateway-ingestible contract",
|
|
517
|
+
source: [
|
|
518
|
+
'import { StealthTelemetryCollector, type GatewayIngestible, type StealthTelemetryHeaderPayload, type StealthTelemetryLogPayload, type TelemetryContributor } from "@apifuse/provider-sdk";',
|
|
519
|
+
"",
|
|
520
|
+
"export const stealth: TelemetryContributor<StealthTelemetryLogPayload, StealthTelemetryHeaderPayload> = new StealthTelemetryCollector();",
|
|
521
|
+
"declare const header: StealthTelemetryHeaderPayload;",
|
|
522
|
+
"export const ingestible: GatewayIngestible<StealthTelemetryHeaderPayload> = header;",
|
|
523
|
+
"",
|
|
524
|
+
].join("\n"),
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
filename: "negative-control-ocr-telemetry-free-text.ts",
|
|
528
|
+
expectedCode: "TS2322",
|
|
529
|
+
description: "ocr gateway telemetry rejects a free-string field",
|
|
530
|
+
source: [
|
|
531
|
+
'import type { GatewayIngestible, OcrTelemetryHeaderPayload } from "@apifuse/provider-sdk";',
|
|
532
|
+
"type Unsafe = OcrTelemetryHeaderPayload & { message: string };",
|
|
533
|
+
"declare const value: Unsafe;",
|
|
534
|
+
"export const bad: GatewayIngestible<Unsafe> = value;",
|
|
535
|
+
].join("\n"),
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
filename: "positive-control-ocr-telemetry-contributor.ts",
|
|
539
|
+
expectedCode: "",
|
|
540
|
+
description: "ocr telemetry contributor satisfies the gateway-ingestible contract",
|
|
541
|
+
source: [
|
|
542
|
+
'import { OcrTelemetryCollector, type TelemetryContributor, type OcrTelemetryLogPayload, type OcrTelemetryHeaderPayload } from "@apifuse/provider-sdk";',
|
|
543
|
+
"export const ocr: TelemetryContributor<OcrTelemetryLogPayload, OcrTelemetryHeaderPayload> = new OcrTelemetryCollector();",
|
|
544
|
+
].join("\n"),
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
filename: "negative-control-stt-telemetry-free-text.ts",
|
|
548
|
+
expectedCode: "TS2322",
|
|
549
|
+
description: "stt gateway telemetry rejects a free-string field",
|
|
550
|
+
source: [
|
|
551
|
+
'import type { GatewayIngestible, SttTelemetryHeaderPayload } from "@apifuse/provider-sdk";',
|
|
552
|
+
"type Unsafe = SttTelemetryHeaderPayload & { message: string };",
|
|
553
|
+
"declare const value: Unsafe;",
|
|
554
|
+
"export const bad: GatewayIngestible<Unsafe> = value;",
|
|
555
|
+
].join("\n"),
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
filename: "positive-control-stt-telemetry-contributor.ts",
|
|
559
|
+
expectedCode: "",
|
|
560
|
+
description: "stt telemetry contributor satisfies the gateway-ingestible contract",
|
|
561
|
+
source: [
|
|
562
|
+
'import { SttTelemetryCollector, type TelemetryContributor, type SttTelemetryLogPayload, type SttTelemetryHeaderPayload } from "@apifuse/provider-sdk";',
|
|
563
|
+
"export const stt: TelemetryContributor<SttTelemetryLogPayload, SttTelemetryHeaderPayload> = new SttTelemetryCollector();",
|
|
564
|
+
].join("\n"),
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
filename: "negative-control-browser-telemetry-free-text.ts",
|
|
568
|
+
expectedCode: "TS2322",
|
|
569
|
+
description: "browser gateway telemetry rejects a free-string field",
|
|
570
|
+
source: [
|
|
571
|
+
'import type { BrowserTelemetryHeaderPayload, GatewayIngestible } from "@apifuse/provider-sdk";',
|
|
572
|
+
"declare const header: BrowserTelemetryHeaderPayload;",
|
|
573
|
+
"type Unsafe = BrowserTelemetryHeaderPayload & { message: string };",
|
|
574
|
+
'export const bad: GatewayIngestible<Unsafe> = { ...header, message: "free text" };',
|
|
575
|
+
].join("\n"),
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
filename: "positive-control-browser-telemetry-contributor.ts",
|
|
579
|
+
expectedCode: "",
|
|
580
|
+
description: "browser telemetry contributor satisfies the gateway-ingestible contract",
|
|
581
|
+
source: [
|
|
582
|
+
'import { BrowserTelemetryCollector, type BrowserTelemetryHeaderPayload, type BrowserTelemetryLogPayload, type TelemetryContributor } from "@apifuse/provider-sdk";',
|
|
583
|
+
"export const browser: TelemetryContributor<BrowserTelemetryLogPayload, BrowserTelemetryHeaderPayload> = new BrowserTelemetryCollector();",
|
|
584
|
+
].join("\n"),
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
filename: "negative-control-cache-telemetry-free-text.ts",
|
|
588
|
+
expectedCode: "TS2322",
|
|
589
|
+
description: "cache gateway telemetry rejects raw cache-key samples",
|
|
590
|
+
source: [
|
|
591
|
+
'import type { TelemetryContributor } from "@apifuse/provider-sdk";',
|
|
592
|
+
"const bad: TelemetryContributor<{}, { key: string }> = {",
|
|
593
|
+
'\tkey: "cache",',
|
|
594
|
+
"\ttoLogPayload: () => ({}),",
|
|
595
|
+
'\ttoHeaderPayload: () => ({ key: "raw" }),',
|
|
596
|
+
"};",
|
|
597
|
+
].join("\n"),
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
filename: "positive-control-cache-telemetry-contributor.ts",
|
|
601
|
+
expectedCode: "",
|
|
602
|
+
description: "cache telemetry contributor satisfies the public contributor contract",
|
|
603
|
+
source: [
|
|
604
|
+
'import { CacheTelemetryCollector, type TelemetryContributor, type CacheTelemetryHeaderPayload, type CacheTelemetryLogPayload } from "@apifuse/provider-sdk";',
|
|
605
|
+
"export const cache: TelemetryContributor<CacheTelemetryLogPayload, CacheTelemetryHeaderPayload> = new CacheTelemetryCollector();",
|
|
606
|
+
].join("\n"),
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
filename: "negative-control-state-telemetry-free-text.ts",
|
|
610
|
+
expectedCode: "TS2322",
|
|
611
|
+
description: "state gateway telemetry rejects raw state-key samples",
|
|
612
|
+
source: [
|
|
613
|
+
'import type { TelemetryContributor } from "@apifuse/provider-sdk";',
|
|
614
|
+
"const bad: TelemetryContributor<{}, { key: string }> = {",
|
|
615
|
+
'\tkey: "state",',
|
|
616
|
+
"\ttoLogPayload: () => ({}),",
|
|
617
|
+
'\ttoHeaderPayload: () => ({ key: "raw" }),',
|
|
618
|
+
"};",
|
|
619
|
+
].join("\n"),
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
filename: "positive-control-state-telemetry-contributor.ts",
|
|
623
|
+
expectedCode: "",
|
|
624
|
+
description: "state telemetry contributor satisfies the public contributor contract",
|
|
625
|
+
source: [
|
|
626
|
+
'import { StateTelemetryCollector, type TelemetryContributor, type StateTelemetryHeaderPayload, type StateTelemetryLogPayload } from "@apifuse/provider-sdk";',
|
|
627
|
+
"export const state: TelemetryContributor<StateTelemetryLogPayload, StateTelemetryHeaderPayload> = new StateTelemetryCollector();",
|
|
628
|
+
].join("\n"),
|
|
629
|
+
},
|
|
630
|
+
] as const;
|
|
631
|
+
|
|
632
|
+
assertTelemetryContributorControls();
|
|
633
|
+
|
|
634
|
+
function assertTelemetryContributorControls(): void {
|
|
635
|
+
const requestTelemetry = readFileSync(join(sdkRoot, "src/runtime/request-telemetry.ts"), "utf8");
|
|
636
|
+
const priorityMatch = requestTelemetry.match(
|
|
637
|
+
/const HEADER_PRIORITY = \[([\s\S]*?)\] as const satisfies/,
|
|
638
|
+
);
|
|
639
|
+
if (!priorityMatch) throw new Error("Could not read request telemetry header priority list");
|
|
640
|
+
|
|
641
|
+
const priority = [...priorityMatch[1].matchAll(/"([a-z]+)"/g)].map((match) => match[1]);
|
|
642
|
+
const shipped = priority.filter((name) =>
|
|
643
|
+
existsSync(join(sdkRoot, "src/runtime", `${name}-telemetry.ts`)),
|
|
644
|
+
);
|
|
645
|
+
const missing: string[] = [];
|
|
646
|
+
for (const name of shipped) {
|
|
647
|
+
const hasPositive = NEGATIVE_CONTROLS.some(
|
|
648
|
+
({ filename }) => filename === `positive-control-${name}-telemetry-contributor.ts`,
|
|
649
|
+
);
|
|
650
|
+
const hasNegative = NEGATIVE_CONTROLS.some(({ filename }) =>
|
|
651
|
+
filename.startsWith(`negative-control-${name}-telemetry-`),
|
|
652
|
+
);
|
|
653
|
+
if (!hasNegative || !hasPositive) {
|
|
654
|
+
missing.push(
|
|
655
|
+
`${name} (${hasNegative ? "negative" : "missing negative"}, ${hasPositive ? "positive" : "missing positive"})`,
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
if (missing.length > 0) {
|
|
660
|
+
throw new Error(`Missing telemetry contributor pack controls: ${missing.join(", ")}`);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
39
664
|
const tempRoot = mkdtempSync(join(tmpdir(), "apifuse-provider-sdk-pack-types-"));
|
|
40
665
|
const packDir = join(tempRoot, "pack");
|
|
41
666
|
const consumerDir = join(tempRoot, "consumer");
|
|
@@ -123,12 +748,16 @@ function setUpFixtureConsumer(consumerDir: string, tarballPath: string): void {
|
|
|
123
748
|
writeFileSync(
|
|
124
749
|
join(consumerDir, "consumer.ts"),
|
|
125
750
|
[
|
|
126
|
-
'import { ProviderError, SessionExpiredError, z } from "@apifuse/provider-sdk";',
|
|
751
|
+
'import { defineProvider, ProviderError, resolveProxy, SessionExpiredError, z } from "@apifuse/provider-sdk";',
|
|
752
|
+
'import { invalidateResolverSolution } from "@apifuse/provider-sdk/runtime/resolver";',
|
|
753
|
+
'import type { BrowserCookie, ChallengeSolution, NativeContext, NativeNetworkClient, NativeNetworkConnection, NativeProviderConfig, NativeTcpEgressGrant, ProviderChallenge, ProviderContext, ProviderFileRef, ProviderFilesContext, ProviderResolvedFile, ProviderResolverConfig, ResolverContext, ResolverRuntimeOptions } from "@apifuse/provider-sdk";',
|
|
754
|
+
'import type { ProxyProtocol, ProxyResolutionOptions, ProxyResolutionSource, ProxyVendorName, RequestOptions, ResolvedProxyConfig } from "@apifuse/provider-sdk";',
|
|
127
755
|
'import { defineCredentialsAuth } from "@apifuse/provider-sdk/provider";',
|
|
756
|
+
'import type { NativeNetworkClient as ProviderEntryNativeNetworkClient, ProviderFilesContext as ProviderEntryFilesContext } from "@apifuse/provider-sdk/provider";',
|
|
128
757
|
'import { extractProviderContract } from "@apifuse/provider-sdk/contract";',
|
|
129
758
|
'import { AUTH_TURN_SCHEMA } from "@apifuse/provider-sdk/auth-turn";',
|
|
130
759
|
'import { serve } from "@apifuse/provider-sdk/server";',
|
|
131
|
-
'import { runStandardTests } from "@apifuse/provider-sdk/testing";',
|
|
760
|
+
'import { resetProviderCacheForTests, runStandardTests } from "@apifuse/provider-sdk/testing";',
|
|
132
761
|
"",
|
|
133
762
|
"// ProviderError must keep its inherited Error members under nodenext.",
|
|
134
763
|
"// When dist d.ts imports fail to resolve, the class type degrades and",
|
|
@@ -143,6 +772,44 @@ function setUpFixtureConsumer(consumerDir: string, tarballPath: string): void {
|
|
|
143
772
|
"// Re-exported zod must keep .refine() callback parameter inference.",
|
|
144
773
|
"const refined = z.object({ shopId: z.string() }).refine((value) => value.shopId.length > 0);",
|
|
145
774
|
'const refinedString = z.string().refine((value) => value.startsWith("tabelog:"));',
|
|
775
|
+
'const proxyOptions: ProxyResolutionOptions = { proxyPolicy: { mode: "disabled" } };',
|
|
776
|
+
'const proxyProtocol: ProxyProtocol = "http";',
|
|
777
|
+
"const proxyResult: Promise<ResolvedProxyConfig> = resolveProxy(proxyOptions);",
|
|
778
|
+
'const proxySource: ProxyResolutionSource = "smartproxy-allocator";',
|
|
779
|
+
'const proxyVendor: ProxyVendorName = "smartproxy";',
|
|
780
|
+
'const requestFile: ProviderFileRef = { type: "request_file", id: "photo", filename: "photo.jpg", mime_type: "image/jpeg", size: 4 };',
|
|
781
|
+
'const resolvedFile: ProviderResolvedFile = { type: "request_file", id: requestFile.id, filename: requestFile.filename, size: requestFile.size, sha256: requestFile.sha256, mimeType: requestFile.mime_type, arrayBuffer: async () => new ArrayBuffer(0), bytes: async () => new Uint8Array(), stream: () => new ReadableStream<Uint8Array>() };',
|
|
782
|
+
"const files: ProviderFilesContext = { has: () => true, resolve: async () => resolvedFile };",
|
|
783
|
+
"const providerEntryFiles: ProviderEntryFilesContext = files;",
|
|
784
|
+
"const connection: NativeNetworkConnection = { read: async () => null, write: async () => {}, close: async () => {} };",
|
|
785
|
+
"const network: NativeNetworkClient = { connectTcp: async () => connection, connectTls: async () => connection, grantTcpEgress: () => ({ revoke() {} }) };",
|
|
786
|
+
"const providerEntryNetwork: ProviderEntryNativeNetworkClient = network;",
|
|
787
|
+
"const nativeContext: NativeContext = { network };",
|
|
788
|
+
'const grant: NativeTcpEgressGrant = network.grantTcpEgress({ sourceHost: "booking-loco.kakao.com", sourcePort: 443, host: "loco.kakao.com", port: 5228, tls: "disabled" });',
|
|
789
|
+
'const nativeConfig: NativeProviderConfig = { network: { tcp: [{ host: "booking-loco.kakao.com", ports: [443], tls: "required" }] } };',
|
|
790
|
+
"const providerContext = undefined as unknown as ProviderContext;",
|
|
791
|
+
"const optionalFiles: ProviderFilesContext | undefined = providerContext.files;",
|
|
792
|
+
"const native: NativeContext = providerContext.native;",
|
|
793
|
+
"export const providerResolver: ResolverContext = providerContext.resolver;",
|
|
794
|
+
'export const resolverRuntimeOptions: ResolverRuntimeOptions = { allowedHosts: ["example.com"], cache: providerContext.cache };',
|
|
795
|
+
"",
|
|
796
|
+
'export const turnstileChallenge: ProviderChallenge = { kind: "turnstile", siteKey: "key", pageUrl: "https://example.com" };',
|
|
797
|
+
"export const abortableResolverSolve = providerResolver.solve(turnstileChallenge, new AbortController().signal);",
|
|
798
|
+
'export const recaptchaV2Challenge: ProviderChallenge = { kind: "recaptcha_v2", siteKey: "key", pageUrl: "https://example.com" };',
|
|
799
|
+
'export const recaptchaV3Challenge: ProviderChallenge = { kind: "recaptcha_v3", siteKey: "key", pageUrl: "https://example.com", action: "login" };',
|
|
800
|
+
'export const hcaptchaChallenge: ProviderChallenge = { kind: "hcaptcha", siteKey: "key", pageUrl: "https://example.com" };',
|
|
801
|
+
'export const cloudflareInterstitialChallenge: ProviderChallenge = { kind: "cloudflare_interstitial", pageUrl: "https://example.com", blockedHtml: "<html></html>" };',
|
|
802
|
+
'export const awsWafChallenge: ProviderChallenge = { kind: "aws_waf", pageUrl: "https://example.com", captchaScript: "script" };',
|
|
803
|
+
'export const tokenSolution: ChallengeSolution = { form: "token", token: "solved-token" };',
|
|
804
|
+
'export const cookieSolution: ChallengeSolution = { form: "cookies", cookies: { cf_clearance: "clearance" }, userAgent: "fixture-agent" };',
|
|
805
|
+
"export const invalidation = invalidateResolverSolution(providerContext.resolver, awsWafChallenge, cookieSolution);",
|
|
806
|
+
'export const resolverConfig: ProviderResolverConfig = { vendors: ["browser", "capsolver"], kinds: ["cloudflare_interstitial", "turnstile"] };',
|
|
807
|
+
'export const resolverProvider = defineProvider({ id: "pack-types-resolver", version: "1.0.0", runtime: "standard", resolver: resolverConfig, meta: { displayName: "Pack Types Resolver", descriptionKey: "meta.description", category: "test" } })({ operations: { probe: { riskClass: "read", input: z.object({}), output: z.object({ ok: z.boolean() }), handler: async () => ({ ok: true }), healthCheckUnsupported: { reason: "type fixture" } } } });',
|
|
808
|
+
"export const resolverContext: ResolverContext = { solve: async () => tokenSolution };",
|
|
809
|
+
'export const browserCookie: BrowserCookie = { name: "persistent-id", value: "persistent-token", domain: "example.com", path: "/", expires: 1786698176, httpOnly: true, secure: true };',
|
|
810
|
+
'const browserPage = undefined as unknown as Awaited<ReturnType<ProviderContext["browser"]["newPage"]>>;',
|
|
811
|
+
"export const browserCookies: Promise<readonly BrowserCookie[]> = browserPage.cookies();",
|
|
812
|
+
'const queryCredentialOptions: RequestOptions = { sensitiveParams: { serviceKey: "type-test-key" } };',
|
|
146
813
|
"",
|
|
147
814
|
"export const witnesses = {",
|
|
148
815
|
" inheritedName,",
|
|
@@ -152,27 +819,39 @@ function setUpFixtureConsumer(consumerDir: string, tarballPath: string): void {
|
|
|
152
819
|
" sessionExpired,",
|
|
153
820
|
" refined,",
|
|
154
821
|
" refinedString,",
|
|
822
|
+
" proxyResult,",
|
|
823
|
+
" proxyProtocol,",
|
|
824
|
+
" proxySource,",
|
|
825
|
+
" proxyVendor,",
|
|
826
|
+
" requestFile,",
|
|
827
|
+
" resolvedFile,",
|
|
828
|
+
" files,",
|
|
829
|
+
" providerEntryFiles,",
|
|
830
|
+
" connection,",
|
|
831
|
+
" network,",
|
|
832
|
+
" providerEntryNetwork,",
|
|
833
|
+
" nativeContext,",
|
|
834
|
+
" grant,",
|
|
835
|
+
" nativeConfig,",
|
|
836
|
+
" optionalFiles,",
|
|
837
|
+
" native,",
|
|
838
|
+
" browserCookie,",
|
|
839
|
+
" browserCookies,",
|
|
840
|
+
" queryCredentialOptions,",
|
|
155
841
|
" defineCredentialsAuth,",
|
|
156
842
|
" extractProviderContract,",
|
|
157
843
|
" AUTH_TURN_SCHEMA,",
|
|
158
844
|
" serve,",
|
|
845
|
+
" resetProviderCacheForTests,",
|
|
159
846
|
" runStandardTests,",
|
|
160
847
|
"};",
|
|
161
848
|
"",
|
|
162
849
|
].join("\n"),
|
|
163
850
|
);
|
|
164
851
|
|
|
165
|
-
|
|
166
|
-
join(consumerDir,
|
|
167
|
-
|
|
168
|
-
'import { ProviderError } from "@apifuse/provider-sdk";',
|
|
169
|
-
"",
|
|
170
|
-
"// Intentionally wrong: name is a string. If this file compiles, the",
|
|
171
|
-
"// fixture consumer is not actually type-checking and the guard is void.",
|
|
172
|
-
'export const mustNotCompile: number = new ProviderError("boom").name;',
|
|
173
|
-
"",
|
|
174
|
-
].join("\n"),
|
|
175
|
-
);
|
|
852
|
+
for (const negativeControl of NEGATIVE_CONTROLS) {
|
|
853
|
+
writeFileSync(join(consumerDir, negativeControl.filename), negativeControl.source);
|
|
854
|
+
}
|
|
176
855
|
}
|
|
177
856
|
|
|
178
857
|
function compileFixtureConsumer(consumerDir: string): void {
|
|
@@ -184,30 +863,49 @@ function compileFixtureConsumer(consumerDir: string): void {
|
|
|
184
863
|
}
|
|
185
864
|
|
|
186
865
|
function assertNegativeControlFails(consumerDir: string): void {
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if (result.status === 0) {
|
|
204
|
-
throw new Error(
|
|
205
|
-
"Negative control compiled cleanly: the fixture consumer is not detecting type errors, so the nodenext guard proves nothing.",
|
|
866
|
+
for (const negativeControl of NEGATIVE_CONTROLS) {
|
|
867
|
+
const result = spawnSync(
|
|
868
|
+
"bun",
|
|
869
|
+
[
|
|
870
|
+
join(consumerDir, "node_modules", ".bin", "tsc"),
|
|
871
|
+
"--target",
|
|
872
|
+
"ES2022",
|
|
873
|
+
"--module",
|
|
874
|
+
"nodenext",
|
|
875
|
+
"--moduleResolution",
|
|
876
|
+
"nodenext",
|
|
877
|
+
"--strict",
|
|
878
|
+
"--noEmit",
|
|
879
|
+
negativeControl.filename,
|
|
880
|
+
],
|
|
881
|
+
{ cwd: consumerDir, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] },
|
|
206
882
|
);
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
883
|
+
if (negativeControl.expectedCode === "") {
|
|
884
|
+
if (result.status !== 0) {
|
|
885
|
+
throw new Error(
|
|
886
|
+
`Positive control "${negativeControl.description}" failed to compile:\n${result.stdout}\n${result.stderr}`,
|
|
887
|
+
);
|
|
888
|
+
}
|
|
889
|
+
console.log(`Positive control accepted: ${negativeControl.description}`);
|
|
890
|
+
continue;
|
|
891
|
+
}
|
|
892
|
+
if (result.status === 0) {
|
|
893
|
+
throw new Error(
|
|
894
|
+
'Negative control "' +
|
|
895
|
+
negativeControl.description +
|
|
896
|
+
'" (' +
|
|
897
|
+
negativeControl.filename +
|
|
898
|
+
") compiled cleanly: the fixture consumer is not detecting its error, so the guard proves nothing.",
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
const output = `${result.stdout}\n${result.stderr}`;
|
|
902
|
+
if (!output.includes(negativeControl.expectedCode)) {
|
|
903
|
+
throw new Error(
|
|
904
|
+
`Negative control "${negativeControl.description}" (${negativeControl.filename}) failed for an unexpected reason (wanted ${negativeControl.expectedCode}):\n${output}`,
|
|
905
|
+
);
|
|
906
|
+
}
|
|
907
|
+
console.log(
|
|
908
|
+
`Negative control rejected (${negativeControl.expectedCode}): ${negativeControl.description}`,
|
|
211
909
|
);
|
|
212
910
|
}
|
|
213
911
|
}
|