@apifuse/provider-sdk 2.2.0-beta.7 → 2.2.0-beta.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUTHORING.md +943 -51
- package/CHANGELOG.md +273 -1
- package/LICENSE +21 -0
- package/README.md +117 -29
- package/SUBMISSION.md +3 -2
- package/bin/apifuse-check.ts +293 -13
- package/bin/apifuse-dev.ts +42 -19
- package/bin/apifuse-migrate-deployment.ts +200 -0
- package/bin/apifuse-migrate-operation-declaration.ts +55 -0
- package/bin/apifuse-migrate-shape.ts +202 -0
- package/bin/apifuse-pack-check.ts +19 -6
- package/bin/apifuse-pack-smoke.ts +57 -2
- package/bin/apifuse-pack-types.ts +736 -38
- package/bin/apifuse-perf.ts +59 -23
- package/bin/apifuse-record.ts +923 -94
- package/bin/apifuse-submit-check.ts +2313 -281
- package/bin/apifuse-test.ts +3 -1
- package/bin/submit-check-delimited-text.ts +50 -0
- package/dist/auth-turn/index.d.ts +3 -3
- package/dist/auth-turn/index.js +1 -1
- package/dist/auth.d.ts +14 -0
- package/dist/auth.js +67 -0
- package/dist/ceremonies/index.d.ts +16 -0
- package/dist/ceremonies/index.js +141 -36
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +30 -0
- package/dist/cli/create.d.ts +1 -1
- package/dist/cli/create.js +8 -2
- package/dist/cli/deployment-intent.d.ts +178 -0
- package/dist/cli/deployment-intent.js +277 -0
- package/dist/cli/local-connection.d.ts +111 -0
- package/dist/cli/local-connection.js +151 -0
- package/dist/cli/migrate-deployment-intent.d.ts +132 -0
- package/dist/cli/migrate-deployment-intent.js +1552 -0
- package/dist/cli/migrate-operation-declaration.d.ts +70 -0
- package/dist/cli/migrate-operation-declaration.js +2206 -0
- package/dist/cli/migrate-operation-shape.d.ts +44 -0
- package/dist/cli/migrate-operation-shape.js +113 -0
- package/dist/cli/migrate-provider-shape.d.ts +56 -0
- package/dist/cli/migrate-provider-shape.js +580 -0
- package/dist/cli/resolver-runtime.d.ts +21 -0
- package/dist/cli/resolver-runtime.js +31 -0
- package/dist/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
- package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
- package/dist/cli/templates/provider/README.md.tpl +41 -19
- package/dist/cli/templates/provider/index.ts.tpl +6 -3
- package/dist/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/dist/cli/templates/provider/provider.json.tpl +6 -0
- package/dist/config/loader.d.ts +202 -16
- package/dist/config/loader.js +491 -141
- package/dist/contract-serialization.js +4 -8
- package/dist/contract-types.d.ts +12 -5
- package/dist/contract.js +24 -10
- package/dist/declaration-validation.d.ts +34 -0
- package/dist/declaration-validation.js +305 -0
- package/dist/define.d.ts +71 -29
- package/dist/define.js +807 -69
- package/dist/dev.d.ts +5 -0
- package/dist/dev.js +8 -1
- package/dist/engine.d.ts +129 -0
- package/dist/engine.js +209 -0
- package/dist/error-observability.d.ts +7 -0
- package/dist/error-observability.js +61 -0
- package/dist/error-resolution.d.ts +18 -0
- package/dist/error-resolution.js +243 -0
- package/dist/errors.d.ts +74 -0
- package/dist/errors.js +99 -0
- package/dist/fixture-sanitization.d.ts +28 -0
- package/dist/fixture-sanitization.js +371 -0
- package/dist/handle-meta.d.ts +90 -0
- package/dist/handle-meta.js +73 -0
- package/dist/handle.d.ts +226 -0
- package/dist/handle.js +345 -0
- package/dist/health-scenario.d.ts +1901 -0
- package/dist/health-scenario.js +653 -0
- package/dist/i18n/catalog.js +21 -1
- package/dist/i18n/error-messages.d.ts +86 -0
- package/dist/i18n/error-messages.js +192 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/keys.d.ts +12 -0
- package/dist/i18n/keys.js +76 -5
- package/dist/i18n/operation-locale-namespace.d.ts +2 -0
- package/dist/i18n/operation-locale-namespace.js +7 -0
- package/dist/index.d.ts +40 -15
- package/dist/index.js +29 -11
- package/dist/lint.d.ts +43 -11
- package/dist/lint.js +2512 -177
- package/dist/native-address.d.ts +43 -0
- package/dist/native-address.js +281 -0
- package/dist/native-egress-policy.d.ts +31 -0
- package/dist/native-egress-policy.js +288 -0
- package/dist/observability.d.ts +5 -2
- package/dist/observability.js +48 -1
- package/dist/provider.d.ts +18 -8
- package/dist/provider.js +11 -6
- package/dist/runtime/auth-flow.d.ts +6 -1
- package/dist/runtime/auth-flow.js +8 -0
- package/dist/runtime/bounded-expiring-map.d.ts +21 -0
- package/dist/runtime/bounded-expiring-map.js +64 -0
- package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
- package/dist/runtime/browser-telemetry-binding.js +83 -0
- package/dist/runtime/browser-telemetry.d.ts +76 -0
- package/dist/runtime/browser-telemetry.js +165 -0
- package/dist/runtime/browser.d.ts +4 -0
- package/dist/runtime/browser.js +688 -83
- package/dist/runtime/cache-telemetry.d.ts +71 -0
- package/dist/runtime/cache-telemetry.js +177 -0
- package/dist/runtime/cache.d.ts +3 -0
- package/dist/runtime/cache.js +245 -23
- package/dist/runtime/capability-response.d.ts +3 -0
- package/dist/runtime/capability-response.js +56 -0
- package/dist/runtime/capability-telemetry.d.ts +46 -0
- package/dist/runtime/capability-telemetry.js +68 -0
- package/dist/runtime/chrome149-header-order.d.ts +58 -0
- package/dist/runtime/chrome149-header-order.js +289 -0
- package/dist/runtime/diagnostic-env-values.d.ts +5 -0
- package/dist/runtime/diagnostic-env-values.js +57 -0
- package/dist/runtime/diagnostic-env.d.ts +14 -0
- package/dist/runtime/diagnostic-env.js +44 -0
- package/dist/runtime/diagnostic-redactor.d.ts +54 -0
- package/dist/runtime/diagnostic-redactor.js +571 -0
- package/dist/runtime/egress-lease.d.ts +65 -0
- package/dist/runtime/egress-lease.js +236 -0
- package/dist/runtime/engine-mode.d.ts +74 -0
- package/dist/runtime/engine-mode.js +152 -0
- package/dist/runtime/env.js +14 -1
- package/dist/runtime/executor.d.ts +3 -2
- package/dist/runtime/executor.js +23 -26
- package/dist/runtime/handle-wordlist.d.ts +43 -0
- package/dist/runtime/handle-wordlist.js +256 -0
- package/dist/runtime/handle.d.ts +71 -0
- package/dist/runtime/handle.js +908 -0
- package/dist/runtime/http-telemetry-binding.d.ts +10 -0
- package/dist/runtime/http-telemetry-binding.js +152 -0
- package/dist/runtime/http-telemetry-guard.d.ts +16 -0
- package/dist/runtime/http-telemetry-guard.js +202 -0
- package/dist/runtime/http-telemetry.d.ts +104 -0
- package/dist/runtime/http-telemetry.js +190 -0
- package/dist/runtime/http.d.ts +34 -0
- package/dist/runtime/http.js +680 -121
- package/dist/runtime/insights.js +2 -2
- package/dist/runtime/instrumentation.d.ts +2 -2
- package/dist/runtime/instrumentation.js +462 -19
- package/dist/runtime/native-network-errors.d.ts +33 -0
- package/dist/runtime/native-network-errors.js +69 -0
- package/dist/runtime/native-network.d.ts +105 -0
- package/dist/runtime/native-network.js +1433 -0
- package/dist/runtime/native-telemetry.d.ts +142 -0
- package/dist/runtime/native-telemetry.js +231 -0
- package/dist/runtime/ocr-telemetry.d.ts +82 -0
- package/dist/runtime/ocr-telemetry.js +192 -0
- package/dist/runtime/ocr.d.ts +29 -0
- package/dist/runtime/ocr.js +468 -0
- package/dist/runtime/otlp.d.ts +71 -2
- package/dist/runtime/otlp.js +398 -16
- package/dist/runtime/provider.d.ts +7 -0
- package/dist/runtime/provider.js +14 -0
- package/dist/runtime/proxy-errors.js +6 -2
- package/dist/runtime/proxy-nodemaven.d.ts +56 -0
- package/dist/runtime/proxy-nodemaven.js +147 -0
- package/dist/runtime/proxy-retry-policy.d.ts +4 -1
- package/dist/runtime/proxy-retry-policy.js +11 -2
- package/dist/runtime/proxy-telemetry.d.ts +133 -3
- package/dist/runtime/proxy-telemetry.js +218 -70
- package/dist/runtime/redirect-hop-headers.d.ts +19 -0
- package/dist/runtime/redirect-hop-headers.js +58 -0
- package/dist/runtime/redirects.d.ts +61 -0
- package/dist/runtime/redirects.js +149 -0
- package/dist/runtime/redis.d.ts +1 -1
- package/dist/runtime/redis.js +4 -2
- package/dist/runtime/request-options.d.ts +75 -1
- package/dist/runtime/request-options.js +588 -0
- package/dist/runtime/request-telemetry.d.ts +70 -0
- package/dist/runtime/request-telemetry.js +229 -0
- package/dist/runtime/resolver-config.d.ts +13 -0
- package/dist/runtime/resolver-config.js +14 -0
- package/dist/runtime/resolver-public.d.ts +3 -0
- package/dist/runtime/resolver-public.js +1 -0
- package/dist/runtime/resolver-runtime-options.d.ts +14 -0
- package/dist/runtime/resolver-runtime-options.js +33 -0
- package/dist/runtime/resolver-shared.d.ts +24 -0
- package/dist/runtime/resolver-shared.js +69 -0
- package/dist/runtime/resolver-span-attributes.d.ts +34 -0
- package/dist/runtime/resolver-span-attributes.js +93 -0
- package/dist/runtime/resolver-telemetry.d.ts +135 -0
- package/dist/runtime/resolver-telemetry.js +204 -0
- package/dist/runtime/resolver-usage.d.ts +32 -0
- package/dist/runtime/resolver-usage.js +54 -0
- package/dist/runtime/resolver-vendors/bindings.d.ts +53 -0
- package/dist/runtime/resolver-vendors/bindings.js +45 -0
- package/dist/runtime/resolver-vendors/browser.d.ts +24 -0
- package/dist/runtime/resolver-vendors/browser.js +423 -0
- package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
- package/dist/runtime/resolver-vendors/capsolver.js +544 -0
- package/dist/runtime/resolver-vendors/hosts.d.ts +23 -0
- package/dist/runtime/resolver-vendors/hosts.js +68 -0
- package/dist/runtime/resolver-vendors/hypersolutions.d.ts +27 -0
- package/dist/runtime/resolver-vendors/hypersolutions.js +369 -0
- package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
- package/dist/runtime/resolver-vendors/twocaptcha.js +425 -0
- package/dist/runtime/resolver-vendors/types.d.ts +125 -0
- package/dist/runtime/resolver-vendors/types.js +106 -0
- package/dist/runtime/resolver.d.ts +79 -0
- package/dist/runtime/resolver.js +1094 -0
- package/dist/runtime/state-telemetry.d.ts +79 -0
- package/dist/runtime/state-telemetry.js +194 -0
- package/dist/runtime/state.d.ts +10 -1
- package/dist/runtime/state.js +322 -82
- package/dist/runtime/stealth-akamai-sbsd.d.ts +54 -0
- package/dist/runtime/stealth-akamai-sbsd.js +142 -0
- package/dist/runtime/stealth-cookies.d.ts +24 -0
- package/dist/runtime/stealth-cookies.js +131 -0
- package/dist/runtime/stealth-owned-headers.d.ts +39 -0
- package/dist/runtime/stealth-owned-headers.js +57 -0
- package/dist/runtime/stealth-telemetry.d.ts +92 -0
- package/dist/runtime/stealth-telemetry.js +179 -0
- package/dist/runtime/stealth.d.ts +45 -6
- package/dist/runtime/stealth.js +1775 -320
- package/dist/runtime/stt-telemetry.d.ts +77 -0
- package/dist/runtime/stt-telemetry.js +176 -0
- package/dist/runtime/stt.js +18 -19
- package/dist/runtime/timeout.d.ts +5 -0
- package/dist/runtime/timeout.js +12 -0
- package/dist/runtime/trace-config.d.ts +12 -0
- package/dist/runtime/trace-config.js +62 -0
- package/dist/runtime/trace.d.ts +17 -0
- package/dist/runtime/trace.js +176 -25
- package/dist/runtime-boundary-lint.d.ts +137 -0
- package/dist/runtime-boundary-lint.js +590 -0
- package/dist/schema.d.ts +20 -0
- package/dist/schema.js +72 -2
- package/dist/serve.d.ts +1 -1
- package/dist/serve.js +1 -1
- package/dist/server/error-observability.d.ts +1 -0
- package/dist/server/error-observability.js +1 -0
- package/dist/server/error-stack-frames.d.ts +35 -0
- package/dist/server/error-stack-frames.js +219 -0
- package/dist/server/index.d.ts +21 -2
- package/dist/server/index.js +11 -2
- package/dist/server/runtime-diagnostics.d.ts +165 -0
- package/dist/server/runtime-diagnostics.js +360 -0
- package/dist/server/sdk-version.d.ts +3 -0
- package/dist/server/sdk-version.js +19 -0
- package/dist/server/self-test-input-tokens.d.ts +2 -1
- package/dist/server/self-test-input-tokens.js +18 -14
- package/dist/server/self-test-redaction.js +8 -33
- package/dist/server/self-test.d.ts +18 -3
- package/dist/server/self-test.js +139 -76
- package/dist/server/sensitive-values.d.ts +26 -0
- package/dist/server/sensitive-values.js +137 -0
- package/dist/server/serve-implementation.d.ts +285 -0
- package/dist/server/serve-implementation.js +3172 -0
- package/dist/server/serve.d.ts +1 -75
- package/dist/server/serve.js +1 -1170
- package/dist/server/state-backend-report.d.ts +70 -0
- package/dist/server/state-backend-report.js +113 -0
- package/dist/server/trace-output.d.ts +7 -0
- package/dist/server/trace-output.js +111 -0
- package/dist/server/types.d.ts +37 -5
- package/dist/server/types.js +34 -1
- package/dist/stateful/errors.d.ts +19 -0
- package/dist/stateful/errors.js +24 -0
- package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
- package/dist/stateful/http-provider-event-emitter.js +237 -0
- package/dist/stateful/http-session-owner-registry.d.ts +44 -0
- package/dist/stateful/http-session-owner-registry.js +210 -0
- package/dist/stateful/index.d.ts +18 -0
- package/dist/stateful/index.js +18 -0
- package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
- package/dist/stateful/provider-event-delivery-failures.js +43 -0
- package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
- package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
- package/dist/stateful/provider-event-pipeline.d.ts +50 -0
- package/dist/stateful/provider-event-pipeline.js +1 -0
- package/dist/stateful/provider-events.d.ts +101 -0
- package/dist/stateful/provider-events.js +289 -0
- package/dist/stateful/session-key.d.ts +15 -0
- package/dist/stateful/session-key.js +86 -0
- package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
- package/dist/stateful/stateful-provider-adapter-context.js +42 -0
- package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
- package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
- package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
- package/dist/stateful/stateful-provider-adapter.js +287 -0
- package/dist/stateful/stateful-provider-observability.d.ts +62 -0
- package/dist/stateful/stateful-provider-observability.js +161 -0
- package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
- package/dist/stateful/stateful-provider-owner-forwarder.js +237 -0
- package/dist/stateful/stateful-provider-runtime-context.d.ts +35 -0
- package/dist/stateful/stateful-provider-runtime-context.js +61 -0
- package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
- package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
- package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
- package/dist/stateful/stateful-provider-session-routing.js +345 -0
- package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
- package/dist/stateful/stateful-provider-session-runtime.js +245 -0
- package/dist/stateful-signing.d.ts +18 -0
- package/dist/stateful-signing.js +27 -0
- package/dist/stealth/profiles.d.ts +15 -4
- package/dist/stealth/profiles.js +169 -211
- package/dist/stream-evidence.d.ts +74 -0
- package/dist/stream-evidence.js +785 -0
- package/dist/stream.js +7 -1
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.js +2 -1
- package/dist/testing/run.d.ts +32 -2
- package/dist/testing/run.js +509 -25
- package/dist/trace-sanitization.d.ts +6 -0
- package/dist/trace-sanitization.js +68 -0
- package/dist/types.d.ts +899 -210
- package/dist/types.js +1 -0
- package/dist/typescript-module.d.ts +39 -0
- package/dist/typescript-module.js +72 -0
- package/package.json +52 -6
- package/src/auth-turn/index.ts +1 -1
- package/src/auth.ts +118 -0
- package/src/ceremonies/index.ts +189 -46
- package/src/cli/commands.ts +37 -0
- package/src/cli/create.ts +8 -2
- package/src/cli/deployment-intent.ts +364 -0
- package/src/cli/local-connection.ts +221 -0
- package/src/cli/migrate-deployment-intent.ts +1908 -0
- package/src/cli/migrate-operation-declaration.ts +3026 -0
- package/src/cli/migrate-operation-shape.ts +184 -0
- package/src/cli/migrate-provider-shape.ts +778 -0
- package/src/cli/resolver-runtime.ts +72 -0
- package/src/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
- package/src/cli/templates/provider/Dockerfile.tpl +1 -1
- package/src/cli/templates/provider/README.md.tpl +41 -19
- package/src/cli/templates/provider/index.ts.tpl +6 -3
- package/src/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/src/cli/templates/provider/provider.json.tpl +6 -0
- package/src/config/loader.ts +774 -181
- package/src/contract-serialization.ts +5 -7
- package/src/contract-types.ts +12 -5
- package/src/contract.ts +24 -10
- package/src/declaration-validation.ts +376 -0
- package/src/define.ts +1105 -131
- package/src/dev.ts +13 -1
- package/src/engine.ts +390 -0
- package/src/error-observability.ts +64 -0
- package/src/error-resolution.ts +269 -0
- package/src/errors.ts +157 -0
- package/src/fixture-sanitization.ts +422 -0
- package/src/handle-meta.ts +143 -0
- package/src/handle.ts +694 -0
- package/src/health-scenario.ts +960 -0
- package/src/i18n/catalog.ts +23 -1
- package/src/i18n/error-messages.ts +255 -0
- package/src/i18n/index.ts +1 -0
- package/src/i18n/keys.ts +80 -6
- package/src/i18n/operation-locale-namespace.ts +10 -0
- package/src/index.ts +390 -23
- package/src/lint.ts +2975 -234
- package/src/native-address.ts +340 -0
- package/src/native-egress-policy.ts +358 -0
- package/src/observability.ts +51 -1
- package/src/provider.ts +207 -27
- package/src/runtime/auth-flow.ts +15 -0
- package/src/runtime/bounded-expiring-map.ts +67 -0
- package/src/runtime/browser-telemetry-binding.ts +92 -0
- package/src/runtime/browser-telemetry.ts +289 -0
- package/src/runtime/browser.ts +882 -99
- package/src/runtime/cache-telemetry.ts +247 -0
- package/src/runtime/cache.ts +258 -22
- package/src/runtime/capability-response.ts +53 -0
- package/src/runtime/capability-telemetry.ts +101 -0
- package/src/runtime/chrome149-header-order.ts +330 -0
- package/src/runtime/diagnostic-env-values.ts +56 -0
- package/src/runtime/diagnostic-env.ts +65 -0
- package/src/runtime/diagnostic-redactor.ts +668 -0
- package/src/runtime/egress-lease.ts +341 -0
- package/src/runtime/engine-mode.ts +233 -0
- package/src/runtime/env.ts +15 -1
- package/src/runtime/executor.ts +39 -32
- package/src/runtime/handle-wordlist.ts +266 -0
- package/src/runtime/handle.ts +1180 -0
- package/src/runtime/http-telemetry-binding.ts +162 -0
- package/src/runtime/http-telemetry-guard.ts +208 -0
- package/src/runtime/http-telemetry.ts +292 -0
- package/src/runtime/http.ts +896 -150
- package/src/runtime/insights.ts +2 -2
- package/src/runtime/instrumentation.ts +628 -28
- package/src/runtime/native-network-errors.ts +99 -0
- package/src/runtime/native-network.ts +1853 -0
- package/src/runtime/native-telemetry.ts +366 -0
- package/src/runtime/ocr-telemetry.ts +308 -0
- package/src/runtime/ocr.ts +564 -0
- package/src/runtime/otlp.ts +468 -21
- package/src/runtime/provider.ts +15 -0
- package/src/runtime/proxy-errors.ts +12 -4
- package/src/runtime/proxy-nodemaven.ts +222 -0
- package/src/runtime/proxy-retry-policy.ts +12 -1
- package/src/runtime/proxy-telemetry.ts +358 -103
- package/src/runtime/redirect-hop-headers.ts +71 -0
- package/src/runtime/redirects.ts +215 -0
- package/src/runtime/redis.ts +7 -2
- package/src/runtime/request-options.ts +728 -1
- package/src/runtime/request-telemetry.ts +375 -0
- package/src/runtime/resolver-config.ts +18 -0
- package/src/runtime/resolver-public.ts +44 -0
- package/src/runtime/resolver-runtime-options.ts +50 -0
- package/src/runtime/resolver-shared.ts +113 -0
- package/src/runtime/resolver-span-attributes.ts +139 -0
- package/src/runtime/resolver-telemetry.ts +362 -0
- package/src/runtime/resolver-usage.ts +99 -0
- package/src/runtime/resolver-vendors/bindings.ts +61 -0
- package/src/runtime/resolver-vendors/browser.ts +591 -0
- package/src/runtime/resolver-vendors/capsolver.ts +727 -0
- package/src/runtime/resolver-vendors/hosts.ts +81 -0
- package/src/runtime/resolver-vendors/hypersolutions.ts +480 -0
- package/src/runtime/resolver-vendors/twocaptcha.ts +555 -0
- package/src/runtime/resolver-vendors/types.ts +261 -0
- package/src/runtime/resolver.ts +1543 -0
- package/src/runtime/state-telemetry.ts +298 -0
- package/src/runtime/state.ts +435 -89
- package/src/runtime/stealth-akamai-sbsd.ts +207 -0
- package/src/runtime/stealth-cookies.ts +155 -0
- package/src/runtime/stealth-owned-headers.ts +67 -0
- package/src/runtime/stealth-telemetry.ts +309 -0
- package/src/runtime/stealth.ts +2275 -372
- package/src/runtime/stt-telemetry.ts +282 -0
- package/src/runtime/stt.ts +96 -91
- package/src/runtime/timeout.ts +18 -0
- package/src/runtime/trace-config.ts +78 -0
- package/src/runtime/trace.ts +257 -35
- package/src/runtime-boundary-lint.ts +707 -0
- package/src/schema.ts +80 -2
- package/src/serve.ts +6 -1
- package/src/server/error-observability.ts +1 -0
- package/src/server/error-stack-frames.ts +214 -0
- package/src/server/index.ts +184 -2
- package/src/server/runtime-diagnostics.ts +522 -0
- package/src/server/sdk-version.ts +22 -0
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/server/self-test-redaction.ts +10 -40
- package/src/server/self-test.ts +205 -89
- package/src/server/sensitive-values.ts +211 -0
- package/src/server/serve-implementation.ts +4596 -0
- package/src/server/serve.ts +1 -1685
- package/src/server/state-backend-report.ts +185 -0
- package/src/server/trace-output.ts +189 -0
- package/src/server/types.ts +34 -1
- package/src/stateful/README.md +146 -0
- package/src/stateful/errors.ts +35 -0
- package/src/stateful/http-provider-event-emitter.ts +314 -0
- package/src/stateful/http-session-owner-registry.ts +306 -0
- package/src/stateful/index.ts +18 -0
- package/src/stateful/provider-event-delivery-failures.ts +80 -0
- package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
- package/src/stateful/provider-event-pipeline.ts +61 -0
- package/src/stateful/provider-events.ts +462 -0
- package/src/stateful/session-key.ts +111 -0
- package/src/stateful/stateful-provider-adapter-context.ts +59 -0
- package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
- package/src/stateful/stateful-provider-adapter.ts +562 -0
- package/src/stateful/stateful-provider-observability.ts +261 -0
- package/src/stateful/stateful-provider-owner-forwarder.ts +310 -0
- package/src/stateful/stateful-provider-runtime-context.ts +96 -0
- package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
- package/src/stateful/stateful-provider-session-routing.ts +546 -0
- package/src/stateful/stateful-provider-session-runtime.ts +403 -0
- package/src/stateful-signing.ts +46 -0
- package/src/stealth/profiles.ts +212 -231
- package/src/stream-evidence.ts +988 -0
- package/src/stream.ts +8 -1
- package/src/testing/index.ts +10 -1
- package/src/testing/run.ts +685 -19
- package/src/trace-sanitization.ts +110 -0
- package/src/types.ts +1014 -273
- package/src/typescript-module.ts +100 -0
- package/dist/choice-token.d.ts +0 -24
- package/dist/choice-token.js +0 -74
- package/dist/runtime/choice.d.ts +0 -15
- package/dist/runtime/choice.js +0 -413
- package/src/choice-token.ts +0 -165
- package/src/runtime/choice.ts +0 -686
package/dist/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl
CHANGED
|
@@ -1,37 +1,145 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: health-checks-and-fail-closed
|
|
3
|
-
description: Writing health checks
|
|
3
|
+
description: Writing health checks the platform monitor actually executes, and fail-closed guards at envelope and row level. Load before writing healthCheck blocks or error handling.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Health checks and fail-closed guards
|
|
7
7
|
|
|
8
|
-
##
|
|
9
|
-
`Array.isArray(data.items)` alone can never fail. Every list operation's
|
|
10
|
-
health check must be able to detect the zero-rows regression.
|
|
8
|
+
## Only `scenario` is monitored in production
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
A `healthCheck` case takes one of two mutually exclusive shapes, and they do
|
|
11
|
+
not run in the same place:
|
|
12
|
+
|
|
13
|
+
| field | executed by | when |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| `scenario` | the platform health monitor | every suite interval, in production |
|
|
16
|
+
| `assertions` | the provider runtime's own self-test | only when that endpoint is called |
|
|
17
|
+
|
|
18
|
+
The monitor runs a case's SERIALIZED scenario and nothing else: a closure
|
|
19
|
+
cannot cross the registry's serialization boundary. A case that carries only
|
|
20
|
+
`assertions` is still published as a probe, but its outcome is permanently
|
|
21
|
+
`unknown` / `monitoring_unavailable` — the operation reads as monitored on the
|
|
22
|
+
status page while nothing is ever checked. `apifuse check` warns about this
|
|
23
|
+
(`health-check-assertions-not-monitored`).
|
|
24
|
+
|
|
25
|
+
Anything that must be caught in production belongs in `scenario`. Keep
|
|
26
|
+
`assertions` for a local self-test, or drop it.
|
|
27
|
+
|
|
28
|
+
## A scenario that can actually fail
|
|
29
|
+
|
|
30
|
+
`Array.isArray(data.items)` alone can never fail. Every list operation's probe
|
|
31
|
+
must be able to detect the zero-rows regression AND a mapper regression that
|
|
32
|
+
empties fields on a present row.
|
|
33
|
+
|
|
34
|
+
Step kinds: `operation` invokes, `assert` FAILS the probe (recorded `down`),
|
|
35
|
+
`guard` DEGRADES without failing it.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
// health-scenarios.ts
|
|
39
|
+
import { type AssertionExpression, defineHealthScenario } from "@apifuse/provider-sdk/provider";
|
|
40
|
+
|
|
41
|
+
export const PROBE_INPUT = { district: "<a guaranteed-dense, stable id>" } as const;
|
|
42
|
+
|
|
43
|
+
const response = (path: readonly (string | number)[]) => ({
|
|
44
|
+
ref: { namespace: "steps" as const, binding: "response", path: [...path] },
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const evidence: AssertionExpression = {
|
|
48
|
+
kind: "all",
|
|
49
|
+
clauses: [
|
|
50
|
+
{ kind: "predicate", operator: "status_2xx", actual: response(["status_code"]) },
|
|
51
|
+
// Dense query MUST return rows; zero rows = upstream contract drift.
|
|
52
|
+
{ kind: "predicate", operator: "array_length_gte", actual: response(["data", "items"]), expected: 1 },
|
|
53
|
+
// A semantic field on a real row, so an emptying mapper regression fails too.
|
|
54
|
+
{ kind: "predicate", operator: "non_empty", actual: response(["data", "items", 0, "name"]) },
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const listItemsScenario = defineHealthScenario({
|
|
59
|
+
scenarioVersion: 2,
|
|
60
|
+
id: "list-items.dense-district",
|
|
61
|
+
display: {
|
|
62
|
+
titleKey: "health.operations.list-items.dense-district.title",
|
|
63
|
+
descriptionKey: "health.operations.list-items.dense-district.description",
|
|
64
|
+
},
|
|
65
|
+
schedule: { kind: "interval", intervalMs: 60 * 60_000, jitterMs: 0 },
|
|
66
|
+
timeoutMs: 15_000,
|
|
67
|
+
coversOperations: ["list-items"],
|
|
68
|
+
credentialRefs: [],
|
|
69
|
+
steps: [
|
|
70
|
+
{ id: "read", result: "response", kind: "operation", operationId: "list-items", inputTemplate: { ...PROBE_INPUT } },
|
|
71
|
+
{ id: "verify", result: "verified", kind: "assert", coversOperations: ["list-items"], expression: evidence },
|
|
72
|
+
],
|
|
73
|
+
});
|
|
74
|
+
```
|
|
15
75
|
|
|
16
76
|
```ts
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
throw new Error("<op> missing items array");
|
|
23
|
-
}
|
|
24
|
-
// Dense query MUST return rows; zero rows = upstream contract drift
|
|
25
|
-
if (data.items.length === 0) {
|
|
26
|
-
return { status: "degraded", label: "<op> dense query returned 0 rows" };
|
|
27
|
-
}
|
|
77
|
+
// operations/list-items.ts
|
|
78
|
+
healthCheck: {
|
|
79
|
+
interval: "1h",
|
|
80
|
+
timeoutMs: 15_000,
|
|
81
|
+
cases: [{ name: "dense-district", input: { ...PROBE_INPUT }, scenario: listItemsScenario }],
|
|
28
82
|
}
|
|
29
83
|
```
|
|
30
84
|
|
|
31
|
-
- Choose
|
|
32
|
-
|
|
33
|
-
-
|
|
34
|
-
|
|
85
|
+
- Choose probe inputs that are guaranteed-dense (major city district, a stable
|
|
86
|
+
well-known entity id). Verify the id still exists when picking it.
|
|
87
|
+
- `scenario.coversOperations` may only name the operation that owns the case.
|
|
88
|
+
|
|
89
|
+
## Stale-if-error serves must be guarded, or an outage reads green
|
|
90
|
+
|
|
91
|
+
If the operation reads its upstream through `ctx.cache.getOrSet(..., {
|
|
92
|
+
staleIfErrorMs })`, an upstream outage is answered with HTTP 200 and a
|
|
93
|
+
well-formed, fully schema-valid body for the whole stale window. Every clause
|
|
94
|
+
over `status_code` and `data` still passes, so the probe rolls up `ok` while
|
|
95
|
+
the upstream is down, and only flips to `down` after the window expires — the
|
|
96
|
+
first minutes of every outage are reported as healthy.
|
|
97
|
+
|
|
98
|
+
`served_stale_cache` on the operation step result is the only operand that
|
|
99
|
+
separates a stale serve from a live read. It is always present, so the
|
|
100
|
+
reference resolves to `false` rather than raising `reference_unresolvable`.
|
|
101
|
+
Add ONE guard step per stale-if-error probe:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
{
|
|
105
|
+
id: "guard-list-items-freshness",
|
|
106
|
+
result: "freshness-guarded",
|
|
107
|
+
kind: "guard",
|
|
108
|
+
condition: {
|
|
109
|
+
kind: "predicate",
|
|
110
|
+
operator: "not_equals",
|
|
111
|
+
actual: { ref: { namespace: "steps" as const, binding: "response", path: ["served_stale_cache"] } },
|
|
112
|
+
expected: true,
|
|
113
|
+
},
|
|
114
|
+
onFail: {
|
|
115
|
+
attribute: [
|
|
116
|
+
{
|
|
117
|
+
operationId: "list-items",
|
|
118
|
+
status: "degraded",
|
|
119
|
+
reasonCode: "served_stale_cache",
|
|
120
|
+
reasonKey: "health.operations.list-items.dense-district.servedStaleCache",
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
stop: "scenario",
|
|
124
|
+
},
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
- `degraded`, not `down`: the cache policy is behaving as promised and callers
|
|
129
|
+
are still served; it is the upstream that is unavailable, and that has to be
|
|
130
|
+
visible instead of green.
|
|
131
|
+
- `served_stale_cache`, not `expected_absence`: the platform publishes a
|
|
132
|
+
stale serve as `degraded` (an upstream fault that opens incidents), while
|
|
133
|
+
`expected_absence` is published as a non-incident status — neither ok nor
|
|
134
|
+
degraded, excluded from uptime — for an absence the provider declares in
|
|
135
|
+
advance (no alert today, a closed shelf, a feed outside its hours). The
|
|
136
|
+
tenant-facing wording lives in the localized `reasonKey`.
|
|
137
|
+
- Place the freshness guard BEFORE any row or emptiness guard. A stale serve
|
|
138
|
+
that happens to be empty would otherwise be attributed to the emptiness
|
|
139
|
+
reason, which is a confident answer to the wrong question.
|
|
140
|
+
- Do not change the handler for this. The envelope's `meta.stale` is written
|
|
141
|
+
by the serve layer, so `return result.value` discarding `result.meta` does
|
|
142
|
+
not suppress the signal.
|
|
35
143
|
|
|
36
144
|
## Fail-closed: envelope level
|
|
37
145
|
- Upstream error headers/codes → structured `ProviderError` with a stable
|
|
@@ -51,6 +159,14 @@ array is non-empty, but every row normalizes to nothing.
|
|
|
51
159
|
- Regression-test both layers separately: a bad envelope AND a good envelope
|
|
52
160
|
with unmappable rows.
|
|
53
161
|
|
|
162
|
+
## Self-test assertions (optional, not monitored)
|
|
163
|
+
A case without a `scenario` may carry an `assertions` lambda, executed only by
|
|
164
|
+
the provider runtime's own self-test. THROW to fail the case (recorded
|
|
165
|
+
`down`); return `{ status: "degraded", label }` to flag without failing;
|
|
166
|
+
return nothing for `ok`. There is no `"down"` return value. It MUST NOT touch
|
|
167
|
+
the scheduler, recorder, or any runtime type. Never use it as the only check
|
|
168
|
+
on an operation you need monitored.
|
|
169
|
+
|
|
54
170
|
## Error message hygiene
|
|
55
171
|
`ProviderError.message` reaches the tenant verbatim. Never interpolate
|
|
56
172
|
upstream free text that may contain personal data (names, phone numbers,
|
|
@@ -58,8 +174,10 @@ addresses); allowlist known code tokens and keep raw bodies in server-side
|
|
|
58
174
|
details/logs only.
|
|
59
175
|
|
|
60
176
|
## Checklist
|
|
61
|
-
- [ ] Every
|
|
177
|
+
- [ ] Every monitored operation's case carries `scenario` (not only `assertions`)
|
|
178
|
+
- [ ] Every list op probe fails on 0 rows for a dense query
|
|
62
179
|
- [ ] One semantic field asserted on a real row
|
|
180
|
+
- [ ] Every `staleIfErrorMs` read has a `served_stale_cache` guard, placed first
|
|
63
181
|
- [ ] Swallowed-error test exists (non-ok mock → handler rejects)
|
|
64
182
|
- [ ] Non-empty upstream → zero normalized rows throws
|
|
65
183
|
- [ ] No upstream free text in customer-facing error messages
|
|
@@ -97,9 +97,21 @@ The `POST /v1/{operation}` body is a request envelope:
|
|
|
97
97
|
- `requestId` is required and can be any unique local debugging string.
|
|
98
98
|
- `input` contains the operation input shape.
|
|
99
99
|
- `headers` is optional.
|
|
100
|
-
- `
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
- `connectionId` is optional connection identity only and does not include
|
|
101
|
+
credentials. The gateway sends it for `optional` connection mode, and only
|
|
102
|
+
when the caller supplied a connection that passed authorization. It is
|
|
103
|
+
exposed as `ctx.request.connectionId`.
|
|
104
|
+
- `connection` is optional credential-bearing connection data. The gateway
|
|
105
|
+
sends it for `required` connection mode; omit it for no-auth/public (`none`
|
|
106
|
+
mode) operations. For local debugging, pass
|
|
107
|
+
`{ "id", "mode", "secrets", "metadata", "externalRef" }` with local-only
|
|
108
|
+
secret values.
|
|
109
|
+
|
|
110
|
+
The gateway sends only `connection` for `required` mode, only `connectionId`
|
|
111
|
+
for `optional` mode (and nothing when the caller passed no connection), and
|
|
112
|
+
neither field for `none` mode. If a malformed or manually constructed envelope
|
|
113
|
+
contains both, a non-empty nested `connection.id` takes precedence over the
|
|
114
|
+
top-level `connectionId`; an empty string is treated as absent.
|
|
103
115
|
|
|
104
116
|
Structured errors return an `error` object with `code`, `message`,
|
|
105
117
|
`requestId`, and optional `details`; validation failures include field paths in
|
|
@@ -109,22 +121,24 @@ Structured errors return an `error` object with `code`, `message`,
|
|
|
109
121
|
|
|
110
122
|
- `invalid_request`: include `requestId` and `input`; omit `connection` for
|
|
111
123
|
public/no-auth operations and never send `connection: null`.
|
|
112
|
-
- Credentials: declare `credential.keys
|
|
113
|
-
|
|
124
|
+
- Credentials: declare `credential.keys` unless `auth.mode` is `platform-managed`;
|
|
125
|
+
that mode implies an unfiltered credential capability and forbids key declarations.
|
|
126
|
+
Pass local-only values through `connection.secrets` and read them with
|
|
127
|
+
`ctx.credential`.
|
|
114
128
|
- Auth flow: call `/auth/start`, then `/auth/continue` with the same `flowId`;
|
|
115
129
|
carry returned `contextPatch` values into the next request's `context`.
|
|
116
|
-
- Stealth/browser runtime: keep access-sensitive operations on `ctx.stealth.fetch()` with
|
|
117
|
-
SDK stealth `
|
|
118
|
-
`
|
|
119
|
-
|
|
120
|
-
(`nodriver` is Python-runtime only)
|
|
130
|
+
- Stealth/browser runtime: keep access-sensitive operations on `ctx.stealth.fetch()` with
|
|
131
|
+
structured SDK `stealth: { browser, os }` selection; the TypeScript stealth runtime uses
|
|
132
|
+
`wreq-js` internally and supports Chrome, Firefox, and Safari. Use `ctx.browser` only when
|
|
133
|
+
the provider needs browser execution; TypeScript browser Providers use
|
|
134
|
+
`browser.engine: "playwright-stealth"` (`nodriver` is Python-runtime only). Install local Chromium with
|
|
121
135
|
`bunx playwright install chromium` or set `APIFUSE__CDP_POOL__URL`.
|
|
122
136
|
|
|
123
137
|
## Next steps
|
|
124
138
|
|
|
125
139
|
1. Replace the sample `ping` operation with real upstream logic.
|
|
126
|
-
2. Once the real operation
|
|
127
|
-
`
|
|
140
|
+
2. Once the real operation calls the upstream through `ctx.http` or `ctx.stealth`
|
|
141
|
+
(absolute URLs, or relative ones under its `upstream.baseUrl`), record a fixture with:
|
|
128
142
|
`bun run record -- --operation <operation> --params '<json-input>'`.
|
|
129
143
|
3. Replace the starter `healthCheckUnsupported` with a real `healthCheck` for read-only upstream operations when safe.
|
|
130
144
|
4. Extend tests and operation metadata until the provider is bounty-ready.
|
|
@@ -144,8 +158,14 @@ Every operation must declare exactly one of:
|
|
|
144
158
|
The generated `ping` operation uses `healthCheckUnsupported` only because it is
|
|
145
159
|
a local scaffold check, not a real upstream API probe.
|
|
146
160
|
|
|
147
|
-
`
|
|
148
|
-
|
|
161
|
+
A case carries either `scenario` or `assertions`, and only `scenario` is
|
|
162
|
+
executed in production: the platform health monitor runs a case's serialized
|
|
163
|
+
scenario and nothing else, because a closure cannot cross the registry's
|
|
164
|
+
serialization boundary. A case with only `assertions` still publishes a probe,
|
|
165
|
+
but its outcome is permanently `unknown` / `monitoring_unavailable` — the
|
|
166
|
+
operation reads as monitored while nothing is checked, and `apifuse check`
|
|
167
|
+
warns about it (`health-check-assertions-not-monitored`). Use this shape in
|
|
168
|
+
real operations:
|
|
149
169
|
|
|
150
170
|
```ts
|
|
151
171
|
healthCheck: {
|
|
@@ -153,11 +173,13 @@ healthCheck: {
|
|
|
153
173
|
cases: [{
|
|
154
174
|
name: "lookup baseline",
|
|
155
175
|
input: { q: "btc" },
|
|
156
|
-
|
|
157
|
-
if (status !== 200 || data.results.length === 0 || durationMs > 3000) {
|
|
158
|
-
return { status: "degraded", label: "lookup baseline changed" };
|
|
159
|
-
}
|
|
160
|
-
},
|
|
176
|
+
scenario: lookupBaselineScenario, // defineHealthScenario({ ... })
|
|
161
177
|
}],
|
|
162
178
|
}
|
|
163
179
|
```
|
|
180
|
+
|
|
181
|
+
If the operation reads through `ctx.cache.getOrSet(..., { staleIfErrorMs })`,
|
|
182
|
+
add a guard step on the operation step result's `served_stale_cache` as well —
|
|
183
|
+
otherwise an upstream outage is answered with a schema-valid 200 and the probe
|
|
184
|
+
reports `ok` for the whole stale window. See
|
|
185
|
+
`.agents/skills/health-checks-and-fail-closed/SKILL.md` for both shapes.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { defineProvider } from "@apifuse/provider-sdk/provider";
|
|
1
|
+
import { defineProvider, type ProviderContextOf } from "@apifuse/provider-sdk/provider";
|
|
2
2
|
|
|
3
3
|
import { providerMeta } from "./meta";
|
|
4
4
|
import { operations } from "./operations";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const buildProvider = defineProvider({
|
|
7
7
|
id: "{{PROVIDER_ID}}",
|
|
8
8
|
version: "1.0.0",
|
|
9
9
|
runtime: "{{RUNTIME}}"{{BROWSER_BLOCK}},
|
|
@@ -11,5 +11,8 @@ export default defineProvider({
|
|
|
11
11
|
reviewed: "community",
|
|
12
12
|
{{SECRETS_BLOCK}}{{CREDENTIAL_BLOCK}}auth: {{AUTH_BLOCK}},
|
|
13
13
|
meta: providerMeta,
|
|
14
|
-
operations: operations,
|
|
15
14
|
});
|
|
15
|
+
|
|
16
|
+
export type ProviderContext = ProviderContextOf<typeof buildProvider>;
|
|
17
|
+
|
|
18
|
+
export default buildProvider({ operations });
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { defineOperation } from "@apifuse/provider-sdk/provider";
|
|
2
|
+
import type { ProviderContext } from "../index";
|
|
2
3
|
|
|
3
4
|
import { pingInputSchema, pingOutputSchema } from "../schemas/ping";
|
|
4
5
|
|
|
5
|
-
export const pingOperation = defineOperation({
|
|
6
|
+
export const pingOperation = defineOperation<ProviderContext>()({
|
|
7
|
+
connectionMode: "none",
|
|
8
|
+
riskClass: "read",
|
|
6
9
|
descriptionKey: "operations.ping.description",
|
|
7
10
|
input: pingInputSchema,
|
|
8
11
|
output: pingOutputSchema,
|
package/dist/config/loader.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { Redis } from "ioredis";
|
|
1
|
+
import type { Redis } from "ioredis";
|
|
2
2
|
import type { ProviderProxyPolicy, TraceConfig } from "../types.js";
|
|
3
|
+
import { type ProxyProtocol } from "../runtime/proxy-nodemaven.js";
|
|
4
|
+
export type { ProxyProtocol } from "../runtime/proxy-nodemaven.js";
|
|
5
|
+
/** Proxy vendors with SDK-managed resolution. */
|
|
6
|
+
export type ProxyVendorName = "smartproxy" | "nodemaven";
|
|
3
7
|
export declare const SMARTPROXY_APP_KEY_ENV = "APIFUSE__PROXY__SMARTPROXY_APP_KEY";
|
|
4
8
|
export declare const SMARTPROXY_MAX_LIFETIME_MINUTES = 2000;
|
|
5
9
|
export declare const DEFAULT_SMARTPROXY_POOL_SIZE = 20;
|
|
@@ -10,13 +14,6 @@ export declare const DEFAULT_PROXY_LIFETIME_ENV = "APIFUSE__PROXY__DEFAULT_LIFET
|
|
|
10
14
|
export declare const PROVIDER_CACHE_REDIS_URL_ENV = "APIFUSE__PROVIDER__CACHE_REDIS_URL";
|
|
11
15
|
export declare const PROVIDER_STATE_REDIS_URL_ENV = "APIFUSE__PROVIDER__STATE_REDIS_URL";
|
|
12
16
|
export declare const REDIS_URL_ENV = "APIFUSE__REDIS__URL";
|
|
13
|
-
export type ProxyOptions = {
|
|
14
|
-
url: string;
|
|
15
|
-
};
|
|
16
|
-
export type ProxyConfig = Partial<ProxyOptions> & {
|
|
17
|
-
provider?: string;
|
|
18
|
-
apiKey?: string;
|
|
19
|
-
};
|
|
20
17
|
export type BrowserConfig = {
|
|
21
18
|
executablePath?: string;
|
|
22
19
|
headless?: boolean;
|
|
@@ -26,7 +23,6 @@ export type SessionConfig = {
|
|
|
26
23
|
path?: string;
|
|
27
24
|
};
|
|
28
25
|
export type ApiFuseConfig = {
|
|
29
|
-
proxy?: ProxyConfig;
|
|
30
26
|
browser?: BrowserConfig;
|
|
31
27
|
session?: SessionConfig;
|
|
32
28
|
trace?: TraceConfig;
|
|
@@ -37,17 +33,43 @@ export type ProxyResolutionOptions = {
|
|
|
37
33
|
upstream?: {
|
|
38
34
|
proxy?: boolean | ProviderProxyPolicy;
|
|
39
35
|
};
|
|
40
|
-
apifuseConfig?: Pick<ApiFuseConfig, "proxy">;
|
|
41
36
|
proxyPolicy?: ProviderProxyPolicy;
|
|
42
37
|
affinityKey?: string;
|
|
43
38
|
/** Zero-based proxy-pool attempt index used by SDK transports for failover. */
|
|
44
39
|
proxyAttempt?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Tunnelling protocols the calling transport can use. When a resolved
|
|
42
|
+
* protocol is not in this set the resolver fails with
|
|
43
|
+
* `PROXY_PROTOCOL_UNSUPPORTED` instead of silently downgrading. Unset means
|
|
44
|
+
* permissive (both protocols allowed).
|
|
45
|
+
*/
|
|
46
|
+
transportProtocols?: readonly ProxyProtocol[];
|
|
47
|
+
/**
|
|
48
|
+
* Explicit protocol override. Internal — for the verification harness and
|
|
49
|
+
* tests, or an advanced caller. Normal callers omit it and each vendor uses
|
|
50
|
+
* its own benchmarked default protocol (see VENDOR_DEFAULT_PROTOCOL). Not an
|
|
51
|
+
* env var and not a provider-policy field.
|
|
52
|
+
*/
|
|
53
|
+
protocol?: ProxyProtocol;
|
|
54
|
+
/**
|
|
55
|
+
* Gateway pool "refresh" generation. Bumped by transports on pool refresh to
|
|
56
|
+
* derive a fresh gateway session set (ignored by allocation-style vendors,
|
|
57
|
+
* whose refresh is driven by cache invalidation).
|
|
58
|
+
*/
|
|
59
|
+
proxyRefreshEpoch?: number;
|
|
45
60
|
telemetry?: ProxyTelemetrySink;
|
|
61
|
+
/** Engine-owned credential snapshot. Provider code must never populate this field. */
|
|
62
|
+
engineCredentials?: Readonly<Record<string, string>>;
|
|
46
63
|
};
|
|
47
64
|
export type ProxyCacheStatus = "memory_hit" | "redis_hit" | "allocator" | "soft_stale_refresh" | "lock_wait" | "redis_error" | "redis_corrupt" | "disabled";
|
|
48
65
|
export type SmartproxyAllocatorBodyClass = "network_error" | "http_error" | "empty" | "json_without_proxies" | "text_without_proxies" | "usable_proxy_endpoints";
|
|
66
|
+
export type ProxyUserAgentSource = "declared" | "defaulted";
|
|
49
67
|
export type ProxyResolutionTelemetryEvent = {
|
|
50
|
-
provider:
|
|
68
|
+
provider: ProxyVendorName;
|
|
69
|
+
/** Defaults to `"ok"` when omitted. */
|
|
70
|
+
outcome?: "ok" | "error";
|
|
71
|
+
userAgentSource?: ProxyUserAgentSource;
|
|
72
|
+
protocol?: ProxyProtocol;
|
|
51
73
|
cacheStatus: ProxyCacheStatus;
|
|
52
74
|
cacheHit: boolean;
|
|
53
75
|
resolutionMs: number;
|
|
@@ -64,7 +86,7 @@ export type ProxyResolutionTelemetryEvent = {
|
|
|
64
86
|
refreshes?: number;
|
|
65
87
|
};
|
|
66
88
|
export type ProxyAttemptTelemetryEvent = {
|
|
67
|
-
provider:
|
|
89
|
+
provider: ProxyVendorName;
|
|
68
90
|
attempt: number;
|
|
69
91
|
poolIndex?: number;
|
|
70
92
|
proxyHash?: string;
|
|
@@ -73,35 +95,199 @@ export type ProxyAttemptTelemetryEvent = {
|
|
|
73
95
|
status?: number;
|
|
74
96
|
durationMs?: number;
|
|
75
97
|
};
|
|
98
|
+
export type ProxyVendorFailoverTelemetryEvent = {
|
|
99
|
+
/** Vendor that failed or was skipped. */
|
|
100
|
+
vendor: ProxyVendorName;
|
|
101
|
+
/** Vendor tried next, or undefined when the chain is exhausted. */
|
|
102
|
+
nextVendor?: ProxyVendorName;
|
|
103
|
+
phase: "resolution" | "transport";
|
|
104
|
+
reason: "no_credentials" | "allocation_failed" | "pool_exhausted" | "protocol_unsupported";
|
|
105
|
+
attempt?: number;
|
|
106
|
+
};
|
|
76
107
|
export type ProxyTelemetrySink = {
|
|
77
108
|
recordProxyResolution(event: ProxyResolutionTelemetryEvent): void;
|
|
78
109
|
recordProxyAttempt?(event: ProxyAttemptTelemetryEvent): void;
|
|
110
|
+
recordProxyVendorFailover?(event: ProxyVendorFailoverTelemetryEvent): void;
|
|
79
111
|
};
|
|
112
|
+
export type ProxyResolutionSource = "explicit" | "env" | "config" | "smartproxy-allocator" | "nodemaven-gateway";
|
|
80
113
|
export type ResolvedProxyConfig = {
|
|
81
114
|
shouldWarn: boolean;
|
|
82
115
|
url?: string;
|
|
83
|
-
|
|
116
|
+
/** SDK-native vendor that supplied the URL, when applicable. */
|
|
117
|
+
vendor?: ProxyVendorName;
|
|
118
|
+
source?: ProxyResolutionSource;
|
|
119
|
+
protocol?: ProxyProtocol;
|
|
84
120
|
diagnostics?: Record<string, string | number | boolean>;
|
|
85
121
|
};
|
|
122
|
+
export type ProxyResolutionErrorCode = "PROXY_REQUIRED" | "PROXY_ALLOCATION_FAILED" | "PROXY_PROTOCOL_UNSUPPORTED";
|
|
86
123
|
export declare class ProxyResolutionError extends Error {
|
|
87
|
-
readonly code:
|
|
124
|
+
readonly code: ProxyResolutionErrorCode;
|
|
88
125
|
readonly telemetry?: ProxyResolutionTelemetryEvent;
|
|
89
|
-
|
|
126
|
+
readonly vendor?: ProxyVendorName;
|
|
127
|
+
readonly vendorChain?: ProxyVendorName[];
|
|
128
|
+
readonly protocol?: ProxyProtocol;
|
|
129
|
+
constructor(code: ProxyResolutionErrorCode, message: string, options?: {
|
|
90
130
|
cause?: unknown;
|
|
91
131
|
telemetry?: ProxyResolutionTelemetryEvent;
|
|
132
|
+
vendor?: ProxyVendorName;
|
|
133
|
+
vendorChain?: ProxyVendorName[];
|
|
134
|
+
protocol?: ProxyProtocol;
|
|
92
135
|
});
|
|
93
136
|
}
|
|
94
137
|
type ProxyRedisClient = Pick<Redis, "connect" | "del" | "eval" | "get" | "on" | "pttl" | "set" | "status">;
|
|
138
|
+
/** Env names that can supply a provider store's Redis URL. */
|
|
139
|
+
export type ProviderRedisUrlEnvName = typeof PROVIDER_STATE_REDIS_URL_ENV | typeof PROVIDER_CACHE_REDIS_URL_ENV | typeof REDIS_URL_ENV;
|
|
140
|
+
/** Which env name supplied a store's Redis URL, alongside the URL itself. */
|
|
141
|
+
export type ProviderRedisUrlResolution = {
|
|
142
|
+
readonly url: string;
|
|
143
|
+
/** The env name that actually supplied `url`. */
|
|
144
|
+
readonly envName: ProviderRedisUrlEnvName;
|
|
145
|
+
/**
|
|
146
|
+
* True when `url` came from a shared fallback env rather than the store's
|
|
147
|
+
* own. A state store on `fallback: true` is sharing an instance that was
|
|
148
|
+
* provisioned for something else (apifuse#2144).
|
|
149
|
+
*/
|
|
150
|
+
readonly fallback: boolean;
|
|
151
|
+
};
|
|
152
|
+
export declare function providerCacheRedisResolutionFromEnv(): ProviderRedisUrlResolution | undefined;
|
|
153
|
+
export declare function providerStateRedisResolutionFromEnv(): ProviderRedisUrlResolution | undefined;
|
|
95
154
|
export declare function providerCacheRedisUrlFromEnv(): string | undefined;
|
|
96
155
|
export declare function providerStateRedisUrlFromEnv(): string | undefined;
|
|
97
156
|
/** @internal Test-only hook for exercising shared proxy-cache behavior. */
|
|
98
157
|
export declare function __setProxyRedisForTests(redis: ProxyRedisClient | undefined): void;
|
|
99
158
|
export declare function __setSmartproxyAllocatorDeadlineMsForTests(deadlineMs: number | undefined): void;
|
|
159
|
+
/** @internal Test-only hook for exercising the pool-cache capacity bound at a small size. */
|
|
160
|
+
export declare function __setSmartproxyPoolCacheMaxEntriesForTests(maxEntries: number | undefined): void;
|
|
161
|
+
/** @internal Test-only view of the in-memory Smartproxy cache sizes. */
|
|
162
|
+
export declare function __getSmartproxyCacheSizesForTests(): {
|
|
163
|
+
pools: number;
|
|
164
|
+
tombstones: number;
|
|
165
|
+
};
|
|
100
166
|
export declare function resolveProxyConfig(options?: ProxyResolutionOptions): ResolvedProxyConfig;
|
|
101
167
|
export declare function resolveProxyConfigAsync(options?: ProxyResolutionOptions): Promise<ResolvedProxyConfig>;
|
|
168
|
+
/**
|
|
169
|
+
* Resolve the proxy URL for a provider-owned consumer such as a CAPTCHA solver.
|
|
170
|
+
* Vendor allocation and failover remain owned by the SDK.
|
|
171
|
+
*/
|
|
172
|
+
export declare function resolveProxy(options?: ProxyResolutionOptions): Promise<ResolvedProxyConfig>;
|
|
173
|
+
/**
|
|
174
|
+
* Each vendor's default egress protocol, chosen from live KR benchmarks. HTTP
|
|
175
|
+
* CONNECT wins for nodemaven (socks5 adds ~500ms through the gateway) and ties
|
|
176
|
+
* for smartproxy, and is the only protocol ctx.http (Bun native fetch) supports.
|
|
177
|
+
* Override per call via ProxyResolutionOptions.protocol (harness/tests).
|
|
178
|
+
*/
|
|
179
|
+
export declare const VENDOR_DEFAULT_PROTOCOL: Readonly<Record<ProxyVendorName, ProxyProtocol>>;
|
|
180
|
+
/**
|
|
181
|
+
* Guard the No-MITM invariant: a resolved proxy URL must use a tunnelling scheme
|
|
182
|
+
* (http CONNECT or socks5) so the client TLS handshake reaches the origin
|
|
183
|
+
* end-to-end. Anything else would intercept TLS and break fingerprinting.
|
|
184
|
+
*/
|
|
185
|
+
export declare function assertTunnelingScheme(url: string): void;
|
|
186
|
+
export type ProxyVendorResolutionContext = {
|
|
187
|
+
readonly protocol: ProxyProtocol;
|
|
188
|
+
readonly poolIndex: number;
|
|
189
|
+
readonly refreshEpoch: number;
|
|
190
|
+
/** Explicit vendor credentials. Omit only on the legacy ambient-env path. */
|
|
191
|
+
readonly credentials?: Readonly<Record<string, string>>;
|
|
192
|
+
/** Disable non-policy env defaults for deterministic injected adapters. */
|
|
193
|
+
readonly ambientDefaults?: boolean;
|
|
194
|
+
/** Disable env-discovered Redis sharing for deterministic injected adapters. */
|
|
195
|
+
readonly sharedCache?: boolean;
|
|
196
|
+
};
|
|
197
|
+
export declare function resolveWithVendor(vendor: ProxyVendorName, policy: ProviderProxyPolicy, options: ProxyResolutionOptions, context: ProxyVendorResolutionContext): Promise<ResolvedProxyConfig>;
|
|
198
|
+
/**
|
|
199
|
+
* Ordered list of SDK-native proxy vendors declared by the policy. `providers`
|
|
200
|
+
* takes precedence over the legacy singular `provider`; the platform default
|
|
201
|
+
* env is the final fallback. Non-registry names (decodo/custom) are dropped so
|
|
202
|
+
* an all-deprecated chain has no managed adapter.
|
|
203
|
+
*/
|
|
204
|
+
export declare function resolveVendorChain(policy: ProviderProxyPolicy): ProxyVendorName[];
|
|
205
|
+
/**
|
|
206
|
+
* Total attempt span across a policy's vendor chain — the sum of each vendor's
|
|
207
|
+
* pool size. Transports use this so successive attempts rotate a vendor's pool
|
|
208
|
+
* and then fail over to the next vendor via the flat attempt index. With one
|
|
209
|
+
* vendor this equals that vendor's pool size (today's behaviour).
|
|
210
|
+
*/
|
|
211
|
+
export declare function resolvePolicyProxyPoolSpan(policy: ProviderProxyPolicy): number;
|
|
212
|
+
/**
|
|
213
|
+
* Absolute upper bound on a chain's attempt span — the sum of each vendor's
|
|
214
|
+
* *maximum* pool size. Unlike `resolvePolicyProxyPoolSpan` (the configured
|
|
215
|
+
* span), this backstop is independent of `session.poolSize`, so it never
|
|
216
|
+
* truncates a legitimately large pool below the point where the flat attempt
|
|
217
|
+
* index would cross into the next vendor (e.g. a 50-slot NodeMaven pool).
|
|
218
|
+
*/
|
|
219
|
+
export declare function maxPolicyProxyPoolSpan(policy: ProviderProxyPolicy): number;
|
|
220
|
+
/**
|
|
221
|
+
* Transport-retry attempt cap for a policy-managed request. A transport failure
|
|
222
|
+
* rotates the flat attempt index onto the *next* endpoint (and, once the index
|
|
223
|
+
* passes the primary vendor's pool span, the *next vendor*), so the cap must be
|
|
224
|
+
* the chain's full pool span for failover to reach the fallback vendor — the
|
|
225
|
+
* per-endpoint retry budget (default 3) never gets there.
|
|
226
|
+
*
|
|
227
|
+
* The span only widens beyond the caller's retry budget when ALL hold:
|
|
228
|
+
* - the request is policy-allocator managed (not a caller-supplied proxy URL);
|
|
229
|
+
* - the caller did NOT pin an explicit retry policy — `HttpRetryOptions.attempts`
|
|
230
|
+
* is the documented total-attempt ceiling and must be honoured verbatim;
|
|
231
|
+
* - the method is safe/idempotent — an unsafe request must never be duplicated
|
|
232
|
+
* across the pool even if some framework default would allow it;
|
|
233
|
+
* - the policy resolves a non-empty *registry* vendor chain (smartproxy /
|
|
234
|
+
* nodemaven). Deprecated vendors (custom / decodo) resolve no managed pool,
|
|
235
|
+
* so there is no possible endpoint crossover — they keep the retry budget.
|
|
236
|
+
*
|
|
237
|
+
* The widened cap is bounded by the chain's true maximum span (sum of each
|
|
238
|
+
* vendor's max pool size), so a large NodeMaven pool (≤50) stays reachable and
|
|
239
|
+
* a pathological chain can never spin unbounded.
|
|
240
|
+
*/
|
|
241
|
+
/**
|
|
242
|
+
* True when a policy request is in *implicit chain-rotation* mode: successive
|
|
243
|
+
* transport attempts rotate the flat index across the concatenated vendor pool
|
|
244
|
+
* spans (and, past the primary vendor's span, into the fallback vendor). This is
|
|
245
|
+
* the ONLY mode in which the transport loop widens its attempt cap AND
|
|
246
|
+
* de-duplicates repeated endpoints — the two behaviours must share one predicate
|
|
247
|
+
* so they never diverge. It holds when ALL of the widening conditions hold:
|
|
248
|
+
* - the request is policy-allocator managed (not a caller-supplied proxy URL);
|
|
249
|
+
* - the caller did NOT pin an explicit retry policy — its `attempts` ceiling is
|
|
250
|
+
* the documented contract and must be honoured verbatim against whatever
|
|
251
|
+
* endpoint each attempt resolves (even a repeated one), so no de-duplication;
|
|
252
|
+
* - the method is safe/idempotent — an unsafe request is never duplicated;
|
|
253
|
+
* - the policy resolves a non-empty registry vendor chain (smartproxy /
|
|
254
|
+
* nodemaven). Deprecated vendors (custom / decodo) resolve no managed
|
|
255
|
+
* endpoint, so there is nothing to rotate or de-duplicate.
|
|
256
|
+
*/
|
|
257
|
+
export declare function policyRotatesTransportVendorChain(input: {
|
|
258
|
+
policy: ProviderProxyPolicy | undefined;
|
|
259
|
+
usesPolicyAllocator: boolean;
|
|
260
|
+
explicitRetry: boolean;
|
|
261
|
+
method: string;
|
|
262
|
+
}): boolean;
|
|
263
|
+
export declare function resolvePolicyTransportAttemptCap(input: {
|
|
264
|
+
policy: ProviderProxyPolicy | undefined;
|
|
265
|
+
usesPolicyAllocator: boolean;
|
|
266
|
+
retryAttempts: number;
|
|
267
|
+
explicitRetry: boolean;
|
|
268
|
+
method: string;
|
|
269
|
+
}): number;
|
|
270
|
+
/**
|
|
271
|
+
* A registry vendor chain (smartproxy/nodemaven) resolves a potentially
|
|
272
|
+
* *different* endpoint per flat attempt index, so a transport retry should
|
|
273
|
+
* advance across endpoints and de-duplicate once the chain stops yielding new
|
|
274
|
+
* ones. Deprecated custom/decodo policies have an empty registry chain and no
|
|
275
|
+
* managed endpoint, so the transport loop has nothing to rotate or de-duplicate.
|
|
276
|
+
*/
|
|
277
|
+
export declare function policyResolvesRegistryVendorChain(policy: ProviderProxyPolicy | undefined): boolean;
|
|
278
|
+
/** Map a resolved proxy source label to the vendor that served it. */
|
|
279
|
+
export declare function vendorFromResolvedSource(source: ResolvedProxyConfig["source"]): ProxyVendorName | undefined;
|
|
280
|
+
/**
|
|
281
|
+
* Map a flat attempt index into (vendorIndex, poolIndex) by concatenating each
|
|
282
|
+
* vendor's pool space in chain order. With a single vendor this reduces to
|
|
283
|
+
* `attempt % poolSize`, preserving today's behaviour exactly.
|
|
284
|
+
*/
|
|
285
|
+
export declare function mapFlatAttempt(flat: number, sizes: readonly number[]): {
|
|
286
|
+
vendorIndex: number;
|
|
287
|
+
poolIndex: number;
|
|
288
|
+
};
|
|
102
289
|
export declare function clearProxyResolutionCache(): void;
|
|
103
290
|
export declare function invalidateProxyResolutionCache(options?: ProxyResolutionOptions): boolean;
|
|
104
291
|
export declare function invalidateProxyResolutionCacheAsync(options?: ProxyResolutionOptions): Promise<boolean>;
|
|
105
292
|
export declare function defineConfig(config: ApiFuseConfig): ApiFuseConfig;
|
|
106
293
|
export declare function loadApiFuseConfig(dir?: string): Promise<ApiFuseConfig>;
|
|
107
|
-
export {};
|