@apifuse/provider-sdk 2.2.0-beta.7 → 2.2.0-beta.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUTHORING.md +943 -51
- package/CHANGELOG.md +273 -1
- package/LICENSE +21 -0
- package/README.md +117 -29
- package/SUBMISSION.md +3 -2
- package/bin/apifuse-check.ts +293 -13
- package/bin/apifuse-dev.ts +42 -19
- package/bin/apifuse-migrate-deployment.ts +200 -0
- package/bin/apifuse-migrate-operation-declaration.ts +55 -0
- package/bin/apifuse-migrate-shape.ts +202 -0
- package/bin/apifuse-pack-check.ts +19 -6
- package/bin/apifuse-pack-smoke.ts +57 -2
- package/bin/apifuse-pack-types.ts +736 -38
- package/bin/apifuse-perf.ts +59 -23
- package/bin/apifuse-record.ts +923 -94
- package/bin/apifuse-submit-check.ts +2313 -281
- package/bin/apifuse-test.ts +3 -1
- package/bin/submit-check-delimited-text.ts +50 -0
- package/dist/auth-turn/index.d.ts +3 -3
- package/dist/auth-turn/index.js +1 -1
- package/dist/auth.d.ts +14 -0
- package/dist/auth.js +67 -0
- package/dist/ceremonies/index.d.ts +16 -0
- package/dist/ceremonies/index.js +141 -36
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +30 -0
- package/dist/cli/create.d.ts +1 -1
- package/dist/cli/create.js +8 -2
- package/dist/cli/deployment-intent.d.ts +178 -0
- package/dist/cli/deployment-intent.js +277 -0
- package/dist/cli/local-connection.d.ts +111 -0
- package/dist/cli/local-connection.js +151 -0
- package/dist/cli/migrate-deployment-intent.d.ts +132 -0
- package/dist/cli/migrate-deployment-intent.js +1552 -0
- package/dist/cli/migrate-operation-declaration.d.ts +70 -0
- package/dist/cli/migrate-operation-declaration.js +2206 -0
- package/dist/cli/migrate-operation-shape.d.ts +44 -0
- package/dist/cli/migrate-operation-shape.js +113 -0
- package/dist/cli/migrate-provider-shape.d.ts +56 -0
- package/dist/cli/migrate-provider-shape.js +580 -0
- package/dist/cli/resolver-runtime.d.ts +21 -0
- package/dist/cli/resolver-runtime.js +31 -0
- package/dist/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
- package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
- package/dist/cli/templates/provider/README.md.tpl +41 -19
- package/dist/cli/templates/provider/index.ts.tpl +6 -3
- package/dist/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/dist/cli/templates/provider/provider.json.tpl +6 -0
- package/dist/config/loader.d.ts +202 -16
- package/dist/config/loader.js +491 -141
- package/dist/contract-serialization.js +4 -8
- package/dist/contract-types.d.ts +12 -5
- package/dist/contract.js +24 -10
- package/dist/declaration-validation.d.ts +34 -0
- package/dist/declaration-validation.js +305 -0
- package/dist/define.d.ts +71 -29
- package/dist/define.js +807 -69
- package/dist/dev.d.ts +5 -0
- package/dist/dev.js +8 -1
- package/dist/engine.d.ts +129 -0
- package/dist/engine.js +209 -0
- package/dist/error-observability.d.ts +7 -0
- package/dist/error-observability.js +61 -0
- package/dist/error-resolution.d.ts +18 -0
- package/dist/error-resolution.js +243 -0
- package/dist/errors.d.ts +74 -0
- package/dist/errors.js +99 -0
- package/dist/fixture-sanitization.d.ts +28 -0
- package/dist/fixture-sanitization.js +371 -0
- package/dist/handle-meta.d.ts +90 -0
- package/dist/handle-meta.js +73 -0
- package/dist/handle.d.ts +226 -0
- package/dist/handle.js +345 -0
- package/dist/health-scenario.d.ts +1901 -0
- package/dist/health-scenario.js +653 -0
- package/dist/i18n/catalog.js +21 -1
- package/dist/i18n/error-messages.d.ts +86 -0
- package/dist/i18n/error-messages.js +192 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/keys.d.ts +12 -0
- package/dist/i18n/keys.js +76 -5
- package/dist/i18n/operation-locale-namespace.d.ts +2 -0
- package/dist/i18n/operation-locale-namespace.js +7 -0
- package/dist/index.d.ts +40 -15
- package/dist/index.js +29 -11
- package/dist/lint.d.ts +43 -11
- package/dist/lint.js +2512 -177
- package/dist/native-address.d.ts +43 -0
- package/dist/native-address.js +281 -0
- package/dist/native-egress-policy.d.ts +31 -0
- package/dist/native-egress-policy.js +288 -0
- package/dist/observability.d.ts +5 -2
- package/dist/observability.js +48 -1
- package/dist/provider.d.ts +18 -8
- package/dist/provider.js +11 -6
- package/dist/runtime/auth-flow.d.ts +6 -1
- package/dist/runtime/auth-flow.js +8 -0
- package/dist/runtime/bounded-expiring-map.d.ts +21 -0
- package/dist/runtime/bounded-expiring-map.js +64 -0
- package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
- package/dist/runtime/browser-telemetry-binding.js +83 -0
- package/dist/runtime/browser-telemetry.d.ts +76 -0
- package/dist/runtime/browser-telemetry.js +165 -0
- package/dist/runtime/browser.d.ts +4 -0
- package/dist/runtime/browser.js +688 -83
- package/dist/runtime/cache-telemetry.d.ts +71 -0
- package/dist/runtime/cache-telemetry.js +177 -0
- package/dist/runtime/cache.d.ts +3 -0
- package/dist/runtime/cache.js +245 -23
- package/dist/runtime/capability-response.d.ts +3 -0
- package/dist/runtime/capability-response.js +56 -0
- package/dist/runtime/capability-telemetry.d.ts +46 -0
- package/dist/runtime/capability-telemetry.js +68 -0
- package/dist/runtime/chrome149-header-order.d.ts +58 -0
- package/dist/runtime/chrome149-header-order.js +289 -0
- package/dist/runtime/diagnostic-env-values.d.ts +5 -0
- package/dist/runtime/diagnostic-env-values.js +57 -0
- package/dist/runtime/diagnostic-env.d.ts +14 -0
- package/dist/runtime/diagnostic-env.js +44 -0
- package/dist/runtime/diagnostic-redactor.d.ts +54 -0
- package/dist/runtime/diagnostic-redactor.js +571 -0
- package/dist/runtime/egress-lease.d.ts +65 -0
- package/dist/runtime/egress-lease.js +236 -0
- package/dist/runtime/engine-mode.d.ts +74 -0
- package/dist/runtime/engine-mode.js +152 -0
- package/dist/runtime/env.js +14 -1
- package/dist/runtime/executor.d.ts +3 -2
- package/dist/runtime/executor.js +23 -26
- package/dist/runtime/handle-wordlist.d.ts +43 -0
- package/dist/runtime/handle-wordlist.js +256 -0
- package/dist/runtime/handle.d.ts +71 -0
- package/dist/runtime/handle.js +908 -0
- package/dist/runtime/http-telemetry-binding.d.ts +10 -0
- package/dist/runtime/http-telemetry-binding.js +152 -0
- package/dist/runtime/http-telemetry-guard.d.ts +16 -0
- package/dist/runtime/http-telemetry-guard.js +202 -0
- package/dist/runtime/http-telemetry.d.ts +104 -0
- package/dist/runtime/http-telemetry.js +190 -0
- package/dist/runtime/http.d.ts +34 -0
- package/dist/runtime/http.js +680 -121
- package/dist/runtime/insights.js +2 -2
- package/dist/runtime/instrumentation.d.ts +2 -2
- package/dist/runtime/instrumentation.js +462 -19
- package/dist/runtime/native-network-errors.d.ts +33 -0
- package/dist/runtime/native-network-errors.js +69 -0
- package/dist/runtime/native-network.d.ts +105 -0
- package/dist/runtime/native-network.js +1433 -0
- package/dist/runtime/native-telemetry.d.ts +142 -0
- package/dist/runtime/native-telemetry.js +231 -0
- package/dist/runtime/ocr-telemetry.d.ts +82 -0
- package/dist/runtime/ocr-telemetry.js +192 -0
- package/dist/runtime/ocr.d.ts +29 -0
- package/dist/runtime/ocr.js +468 -0
- package/dist/runtime/otlp.d.ts +71 -2
- package/dist/runtime/otlp.js +398 -16
- package/dist/runtime/provider.d.ts +7 -0
- package/dist/runtime/provider.js +14 -0
- package/dist/runtime/proxy-errors.js +6 -2
- package/dist/runtime/proxy-nodemaven.d.ts +56 -0
- package/dist/runtime/proxy-nodemaven.js +147 -0
- package/dist/runtime/proxy-retry-policy.d.ts +4 -1
- package/dist/runtime/proxy-retry-policy.js +11 -2
- package/dist/runtime/proxy-telemetry.d.ts +133 -3
- package/dist/runtime/proxy-telemetry.js +218 -70
- package/dist/runtime/redirect-hop-headers.d.ts +19 -0
- package/dist/runtime/redirect-hop-headers.js +58 -0
- package/dist/runtime/redirects.d.ts +61 -0
- package/dist/runtime/redirects.js +149 -0
- package/dist/runtime/redis.d.ts +1 -1
- package/dist/runtime/redis.js +4 -2
- package/dist/runtime/request-options.d.ts +75 -1
- package/dist/runtime/request-options.js +588 -0
- package/dist/runtime/request-telemetry.d.ts +70 -0
- package/dist/runtime/request-telemetry.js +229 -0
- package/dist/runtime/resolver-config.d.ts +13 -0
- package/dist/runtime/resolver-config.js +14 -0
- package/dist/runtime/resolver-public.d.ts +3 -0
- package/dist/runtime/resolver-public.js +1 -0
- package/dist/runtime/resolver-runtime-options.d.ts +14 -0
- package/dist/runtime/resolver-runtime-options.js +33 -0
- package/dist/runtime/resolver-shared.d.ts +24 -0
- package/dist/runtime/resolver-shared.js +69 -0
- package/dist/runtime/resolver-span-attributes.d.ts +34 -0
- package/dist/runtime/resolver-span-attributes.js +93 -0
- package/dist/runtime/resolver-telemetry.d.ts +135 -0
- package/dist/runtime/resolver-telemetry.js +204 -0
- package/dist/runtime/resolver-usage.d.ts +32 -0
- package/dist/runtime/resolver-usage.js +54 -0
- package/dist/runtime/resolver-vendors/bindings.d.ts +53 -0
- package/dist/runtime/resolver-vendors/bindings.js +45 -0
- package/dist/runtime/resolver-vendors/browser.d.ts +24 -0
- package/dist/runtime/resolver-vendors/browser.js +423 -0
- package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
- package/dist/runtime/resolver-vendors/capsolver.js +544 -0
- package/dist/runtime/resolver-vendors/hosts.d.ts +23 -0
- package/dist/runtime/resolver-vendors/hosts.js +68 -0
- package/dist/runtime/resolver-vendors/hypersolutions.d.ts +27 -0
- package/dist/runtime/resolver-vendors/hypersolutions.js +369 -0
- package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
- package/dist/runtime/resolver-vendors/twocaptcha.js +425 -0
- package/dist/runtime/resolver-vendors/types.d.ts +125 -0
- package/dist/runtime/resolver-vendors/types.js +106 -0
- package/dist/runtime/resolver.d.ts +79 -0
- package/dist/runtime/resolver.js +1094 -0
- package/dist/runtime/state-telemetry.d.ts +79 -0
- package/dist/runtime/state-telemetry.js +194 -0
- package/dist/runtime/state.d.ts +10 -1
- package/dist/runtime/state.js +322 -82
- package/dist/runtime/stealth-akamai-sbsd.d.ts +54 -0
- package/dist/runtime/stealth-akamai-sbsd.js +142 -0
- package/dist/runtime/stealth-cookies.d.ts +24 -0
- package/dist/runtime/stealth-cookies.js +131 -0
- package/dist/runtime/stealth-owned-headers.d.ts +39 -0
- package/dist/runtime/stealth-owned-headers.js +57 -0
- package/dist/runtime/stealth-telemetry.d.ts +92 -0
- package/dist/runtime/stealth-telemetry.js +179 -0
- package/dist/runtime/stealth.d.ts +45 -6
- package/dist/runtime/stealth.js +1775 -320
- package/dist/runtime/stt-telemetry.d.ts +77 -0
- package/dist/runtime/stt-telemetry.js +176 -0
- package/dist/runtime/stt.js +18 -19
- package/dist/runtime/timeout.d.ts +5 -0
- package/dist/runtime/timeout.js +12 -0
- package/dist/runtime/trace-config.d.ts +12 -0
- package/dist/runtime/trace-config.js +62 -0
- package/dist/runtime/trace.d.ts +17 -0
- package/dist/runtime/trace.js +176 -25
- package/dist/runtime-boundary-lint.d.ts +137 -0
- package/dist/runtime-boundary-lint.js +590 -0
- package/dist/schema.d.ts +20 -0
- package/dist/schema.js +72 -2
- package/dist/serve.d.ts +1 -1
- package/dist/serve.js +1 -1
- package/dist/server/error-observability.d.ts +1 -0
- package/dist/server/error-observability.js +1 -0
- package/dist/server/error-stack-frames.d.ts +35 -0
- package/dist/server/error-stack-frames.js +219 -0
- package/dist/server/index.d.ts +21 -2
- package/dist/server/index.js +11 -2
- package/dist/server/runtime-diagnostics.d.ts +165 -0
- package/dist/server/runtime-diagnostics.js +360 -0
- package/dist/server/sdk-version.d.ts +3 -0
- package/dist/server/sdk-version.js +19 -0
- package/dist/server/self-test-input-tokens.d.ts +2 -1
- package/dist/server/self-test-input-tokens.js +18 -14
- package/dist/server/self-test-redaction.js +8 -33
- package/dist/server/self-test.d.ts +18 -3
- package/dist/server/self-test.js +139 -76
- package/dist/server/sensitive-values.d.ts +26 -0
- package/dist/server/sensitive-values.js +137 -0
- package/dist/server/serve-implementation.d.ts +285 -0
- package/dist/server/serve-implementation.js +3172 -0
- package/dist/server/serve.d.ts +1 -75
- package/dist/server/serve.js +1 -1170
- package/dist/server/state-backend-report.d.ts +70 -0
- package/dist/server/state-backend-report.js +113 -0
- package/dist/server/trace-output.d.ts +7 -0
- package/dist/server/trace-output.js +111 -0
- package/dist/server/types.d.ts +37 -5
- package/dist/server/types.js +34 -1
- package/dist/stateful/errors.d.ts +19 -0
- package/dist/stateful/errors.js +24 -0
- package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
- package/dist/stateful/http-provider-event-emitter.js +237 -0
- package/dist/stateful/http-session-owner-registry.d.ts +44 -0
- package/dist/stateful/http-session-owner-registry.js +210 -0
- package/dist/stateful/index.d.ts +18 -0
- package/dist/stateful/index.js +18 -0
- package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
- package/dist/stateful/provider-event-delivery-failures.js +43 -0
- package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
- package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
- package/dist/stateful/provider-event-pipeline.d.ts +50 -0
- package/dist/stateful/provider-event-pipeline.js +1 -0
- package/dist/stateful/provider-events.d.ts +101 -0
- package/dist/stateful/provider-events.js +289 -0
- package/dist/stateful/session-key.d.ts +15 -0
- package/dist/stateful/session-key.js +86 -0
- package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
- package/dist/stateful/stateful-provider-adapter-context.js +42 -0
- package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
- package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
- package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
- package/dist/stateful/stateful-provider-adapter.js +287 -0
- package/dist/stateful/stateful-provider-observability.d.ts +62 -0
- package/dist/stateful/stateful-provider-observability.js +161 -0
- package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
- package/dist/stateful/stateful-provider-owner-forwarder.js +237 -0
- package/dist/stateful/stateful-provider-runtime-context.d.ts +35 -0
- package/dist/stateful/stateful-provider-runtime-context.js +61 -0
- package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
- package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
- package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
- package/dist/stateful/stateful-provider-session-routing.js +345 -0
- package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
- package/dist/stateful/stateful-provider-session-runtime.js +245 -0
- package/dist/stateful-signing.d.ts +18 -0
- package/dist/stateful-signing.js +27 -0
- package/dist/stealth/profiles.d.ts +15 -4
- package/dist/stealth/profiles.js +169 -211
- package/dist/stream-evidence.d.ts +74 -0
- package/dist/stream-evidence.js +785 -0
- package/dist/stream.js +7 -1
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.js +2 -1
- package/dist/testing/run.d.ts +32 -2
- package/dist/testing/run.js +509 -25
- package/dist/trace-sanitization.d.ts +6 -0
- package/dist/trace-sanitization.js +68 -0
- package/dist/types.d.ts +899 -210
- package/dist/types.js +1 -0
- package/dist/typescript-module.d.ts +39 -0
- package/dist/typescript-module.js +72 -0
- package/package.json +52 -6
- package/src/auth-turn/index.ts +1 -1
- package/src/auth.ts +118 -0
- package/src/ceremonies/index.ts +189 -46
- package/src/cli/commands.ts +37 -0
- package/src/cli/create.ts +8 -2
- package/src/cli/deployment-intent.ts +364 -0
- package/src/cli/local-connection.ts +221 -0
- package/src/cli/migrate-deployment-intent.ts +1908 -0
- package/src/cli/migrate-operation-declaration.ts +3026 -0
- package/src/cli/migrate-operation-shape.ts +184 -0
- package/src/cli/migrate-provider-shape.ts +778 -0
- package/src/cli/resolver-runtime.ts +72 -0
- package/src/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
- package/src/cli/templates/provider/Dockerfile.tpl +1 -1
- package/src/cli/templates/provider/README.md.tpl +41 -19
- package/src/cli/templates/provider/index.ts.tpl +6 -3
- package/src/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/src/cli/templates/provider/provider.json.tpl +6 -0
- package/src/config/loader.ts +774 -181
- package/src/contract-serialization.ts +5 -7
- package/src/contract-types.ts +12 -5
- package/src/contract.ts +24 -10
- package/src/declaration-validation.ts +376 -0
- package/src/define.ts +1105 -131
- package/src/dev.ts +13 -1
- package/src/engine.ts +390 -0
- package/src/error-observability.ts +64 -0
- package/src/error-resolution.ts +269 -0
- package/src/errors.ts +157 -0
- package/src/fixture-sanitization.ts +422 -0
- package/src/handle-meta.ts +143 -0
- package/src/handle.ts +694 -0
- package/src/health-scenario.ts +960 -0
- package/src/i18n/catalog.ts +23 -1
- package/src/i18n/error-messages.ts +255 -0
- package/src/i18n/index.ts +1 -0
- package/src/i18n/keys.ts +80 -6
- package/src/i18n/operation-locale-namespace.ts +10 -0
- package/src/index.ts +390 -23
- package/src/lint.ts +2975 -234
- package/src/native-address.ts +340 -0
- package/src/native-egress-policy.ts +358 -0
- package/src/observability.ts +51 -1
- package/src/provider.ts +207 -27
- package/src/runtime/auth-flow.ts +15 -0
- package/src/runtime/bounded-expiring-map.ts +67 -0
- package/src/runtime/browser-telemetry-binding.ts +92 -0
- package/src/runtime/browser-telemetry.ts +289 -0
- package/src/runtime/browser.ts +882 -99
- package/src/runtime/cache-telemetry.ts +247 -0
- package/src/runtime/cache.ts +258 -22
- package/src/runtime/capability-response.ts +53 -0
- package/src/runtime/capability-telemetry.ts +101 -0
- package/src/runtime/chrome149-header-order.ts +330 -0
- package/src/runtime/diagnostic-env-values.ts +56 -0
- package/src/runtime/diagnostic-env.ts +65 -0
- package/src/runtime/diagnostic-redactor.ts +668 -0
- package/src/runtime/egress-lease.ts +341 -0
- package/src/runtime/engine-mode.ts +233 -0
- package/src/runtime/env.ts +15 -1
- package/src/runtime/executor.ts +39 -32
- package/src/runtime/handle-wordlist.ts +266 -0
- package/src/runtime/handle.ts +1180 -0
- package/src/runtime/http-telemetry-binding.ts +162 -0
- package/src/runtime/http-telemetry-guard.ts +208 -0
- package/src/runtime/http-telemetry.ts +292 -0
- package/src/runtime/http.ts +896 -150
- package/src/runtime/insights.ts +2 -2
- package/src/runtime/instrumentation.ts +628 -28
- package/src/runtime/native-network-errors.ts +99 -0
- package/src/runtime/native-network.ts +1853 -0
- package/src/runtime/native-telemetry.ts +366 -0
- package/src/runtime/ocr-telemetry.ts +308 -0
- package/src/runtime/ocr.ts +564 -0
- package/src/runtime/otlp.ts +468 -21
- package/src/runtime/provider.ts +15 -0
- package/src/runtime/proxy-errors.ts +12 -4
- package/src/runtime/proxy-nodemaven.ts +222 -0
- package/src/runtime/proxy-retry-policy.ts +12 -1
- package/src/runtime/proxy-telemetry.ts +358 -103
- package/src/runtime/redirect-hop-headers.ts +71 -0
- package/src/runtime/redirects.ts +215 -0
- package/src/runtime/redis.ts +7 -2
- package/src/runtime/request-options.ts +728 -1
- package/src/runtime/request-telemetry.ts +375 -0
- package/src/runtime/resolver-config.ts +18 -0
- package/src/runtime/resolver-public.ts +44 -0
- package/src/runtime/resolver-runtime-options.ts +50 -0
- package/src/runtime/resolver-shared.ts +113 -0
- package/src/runtime/resolver-span-attributes.ts +139 -0
- package/src/runtime/resolver-telemetry.ts +362 -0
- package/src/runtime/resolver-usage.ts +99 -0
- package/src/runtime/resolver-vendors/bindings.ts +61 -0
- package/src/runtime/resolver-vendors/browser.ts +591 -0
- package/src/runtime/resolver-vendors/capsolver.ts +727 -0
- package/src/runtime/resolver-vendors/hosts.ts +81 -0
- package/src/runtime/resolver-vendors/hypersolutions.ts +480 -0
- package/src/runtime/resolver-vendors/twocaptcha.ts +555 -0
- package/src/runtime/resolver-vendors/types.ts +261 -0
- package/src/runtime/resolver.ts +1543 -0
- package/src/runtime/state-telemetry.ts +298 -0
- package/src/runtime/state.ts +435 -89
- package/src/runtime/stealth-akamai-sbsd.ts +207 -0
- package/src/runtime/stealth-cookies.ts +155 -0
- package/src/runtime/stealth-owned-headers.ts +67 -0
- package/src/runtime/stealth-telemetry.ts +309 -0
- package/src/runtime/stealth.ts +2275 -372
- package/src/runtime/stt-telemetry.ts +282 -0
- package/src/runtime/stt.ts +96 -91
- package/src/runtime/timeout.ts +18 -0
- package/src/runtime/trace-config.ts +78 -0
- package/src/runtime/trace.ts +257 -35
- package/src/runtime-boundary-lint.ts +707 -0
- package/src/schema.ts +80 -2
- package/src/serve.ts +6 -1
- package/src/server/error-observability.ts +1 -0
- package/src/server/error-stack-frames.ts +214 -0
- package/src/server/index.ts +184 -2
- package/src/server/runtime-diagnostics.ts +522 -0
- package/src/server/sdk-version.ts +22 -0
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/server/self-test-redaction.ts +10 -40
- package/src/server/self-test.ts +205 -89
- package/src/server/sensitive-values.ts +211 -0
- package/src/server/serve-implementation.ts +4596 -0
- package/src/server/serve.ts +1 -1685
- package/src/server/state-backend-report.ts +185 -0
- package/src/server/trace-output.ts +189 -0
- package/src/server/types.ts +34 -1
- package/src/stateful/README.md +146 -0
- package/src/stateful/errors.ts +35 -0
- package/src/stateful/http-provider-event-emitter.ts +314 -0
- package/src/stateful/http-session-owner-registry.ts +306 -0
- package/src/stateful/index.ts +18 -0
- package/src/stateful/provider-event-delivery-failures.ts +80 -0
- package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
- package/src/stateful/provider-event-pipeline.ts +61 -0
- package/src/stateful/provider-events.ts +462 -0
- package/src/stateful/session-key.ts +111 -0
- package/src/stateful/stateful-provider-adapter-context.ts +59 -0
- package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
- package/src/stateful/stateful-provider-adapter.ts +562 -0
- package/src/stateful/stateful-provider-observability.ts +261 -0
- package/src/stateful/stateful-provider-owner-forwarder.ts +310 -0
- package/src/stateful/stateful-provider-runtime-context.ts +96 -0
- package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
- package/src/stateful/stateful-provider-session-routing.ts +546 -0
- package/src/stateful/stateful-provider-session-runtime.ts +403 -0
- package/src/stateful-signing.ts +46 -0
- package/src/stealth/profiles.ts +212 -231
- package/src/stream-evidence.ts +988 -0
- package/src/stream.ts +8 -1
- package/src/testing/index.ts +10 -1
- package/src/testing/run.ts +685 -19
- package/src/trace-sanitization.ts +110 -0
- package/src/types.ts +1014 -273
- package/src/typescript-module.ts +100 -0
- package/dist/choice-token.d.ts +0 -24
- package/dist/choice-token.js +0 -74
- package/dist/runtime/choice.d.ts +0 -15
- package/dist/runtime/choice.js +0 -413
- package/src/choice-token.ts +0 -165
- package/src/runtime/choice.ts +0 -686
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ProviderDeploymentOverrides } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Deployment-intent helpers shared by `apifuse check` and
|
|
5
|
+
* `apifuse migrate-deployment`.
|
|
6
|
+
*
|
|
7
|
+
* Deployment intent has exactly one authored home: the optional `deployment`
|
|
8
|
+
* key on `defineProvider()`. The APIFuse registry builder is the only reader;
|
|
9
|
+
* it resolves omitted fields from a runtime profile and rejects anything it
|
|
10
|
+
* cannot resolve. This module mirrors that profile table so the CLI can
|
|
11
|
+
* (a) subtract profile defaults when hoisting a legacy `deploy.ts` into the
|
|
12
|
+
* key and (b) warn when a declared key restates a default. The registry
|
|
13
|
+
* stays canonical — keep the constants below identical to
|
|
14
|
+
* `resolveProviderDeploymentConfig` in `@apifuse/provider-registry`.
|
|
15
|
+
*/
|
|
16
|
+
export type DeploymentRuntime = "shared" | "dedicated" | "browser";
|
|
17
|
+
export type DeploymentLanguage = "typescript" | "python";
|
|
18
|
+
export interface DeploymentResources {
|
|
19
|
+
cpu: string;
|
|
20
|
+
memory: string;
|
|
21
|
+
}
|
|
22
|
+
export interface DeploymentHpa {
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
minReplicas?: number;
|
|
25
|
+
maxReplicas?: number;
|
|
26
|
+
targetCPUUtilizationPercentage?: number;
|
|
27
|
+
}
|
|
28
|
+
/** Fully resolved deployment view: what the platform materializes for a provider. */
|
|
29
|
+
export interface ResolvedDeploymentIntent {
|
|
30
|
+
runtime: DeploymentRuntime;
|
|
31
|
+
language: DeploymentLanguage;
|
|
32
|
+
replicas: number;
|
|
33
|
+
hpa: DeploymentHpa;
|
|
34
|
+
resources: DeploymentResources;
|
|
35
|
+
cache?: {
|
|
36
|
+
redis?: {
|
|
37
|
+
enabled: boolean;
|
|
38
|
+
url?: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
network?: {
|
|
42
|
+
additionalTcpPorts: number[];
|
|
43
|
+
};
|
|
44
|
+
buildContext: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Runtime-profile defaults. `dedicated` carries no resource profile and
|
|
48
|
+
* therefore always needs explicit `resources`.
|
|
49
|
+
*/
|
|
50
|
+
export declare const DEPLOYMENT_PROFILE_DEFAULTS: Readonly<{
|
|
51
|
+
runtime: DeploymentRuntime;
|
|
52
|
+
language: DeploymentLanguage;
|
|
53
|
+
replicas: 1;
|
|
54
|
+
hpa: Readonly<DeploymentHpa>;
|
|
55
|
+
buildContext: ".";
|
|
56
|
+
resources: Readonly<Record<DeploymentRuntime, Readonly<DeploymentResources> | undefined>>;
|
|
57
|
+
}>;
|
|
58
|
+
/**
|
|
59
|
+
* The standalone `deploy.ts` contract (legacy). Mirrors the registry's
|
|
60
|
+
* `ProviderDeploymentConfigSchema`, including its own defaults — note that a
|
|
61
|
+
* legacy file without `hpa` resolved to `{ enabled: false }`, not the
|
|
62
|
+
* profile HPA, so the two default tables are deliberately different.
|
|
63
|
+
*/
|
|
64
|
+
export declare const legacyDeploymentConfigSchema: z.ZodObject<{
|
|
65
|
+
runtime: z.ZodEnum<{
|
|
66
|
+
browser: "browser";
|
|
67
|
+
shared: "shared";
|
|
68
|
+
dedicated: "dedicated";
|
|
69
|
+
}>;
|
|
70
|
+
language: z.ZodEnum<{
|
|
71
|
+
typescript: "typescript";
|
|
72
|
+
python: "python";
|
|
73
|
+
}>;
|
|
74
|
+
replicas: z.ZodDefault<z.ZodNumber>;
|
|
75
|
+
hpa: z.ZodDefault<z.ZodObject<{
|
|
76
|
+
enabled: z.ZodBoolean;
|
|
77
|
+
minReplicas: z.ZodOptional<z.ZodNumber>;
|
|
78
|
+
maxReplicas: z.ZodOptional<z.ZodNumber>;
|
|
79
|
+
targetCPUUtilizationPercentage: z.ZodOptional<z.ZodNumber>;
|
|
80
|
+
}, z.core.$strict>>;
|
|
81
|
+
resources: z.ZodObject<{
|
|
82
|
+
cpu: z.ZodString;
|
|
83
|
+
memory: z.ZodString;
|
|
84
|
+
}, z.core.$strict>;
|
|
85
|
+
cache: z.ZodOptional<z.ZodObject<{
|
|
86
|
+
redis: z.ZodOptional<z.ZodObject<{
|
|
87
|
+
enabled: z.ZodBoolean;
|
|
88
|
+
url: z.ZodOptional<z.ZodString>;
|
|
89
|
+
}, z.core.$strict>>;
|
|
90
|
+
}, z.core.$strict>>;
|
|
91
|
+
network: z.ZodOptional<z.ZodObject<{
|
|
92
|
+
additionalTcpPorts: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
|
|
93
|
+
}, z.core.$strict>>;
|
|
94
|
+
buildContext: z.ZodOptional<z.ZodString & z.ZodType<".", string, z.core.$ZodTypeInternals<".", string>>>;
|
|
95
|
+
}, z.core.$strict>;
|
|
96
|
+
/** The authored `deployment` key: every field optional (registry `ProviderDeploymentOverridesSchema`). */
|
|
97
|
+
export declare const deploymentOverridesSchema: z.ZodObject<{
|
|
98
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
99
|
+
browser: "browser";
|
|
100
|
+
shared: "shared";
|
|
101
|
+
dedicated: "dedicated";
|
|
102
|
+
}>>;
|
|
103
|
+
language: z.ZodOptional<z.ZodEnum<{
|
|
104
|
+
typescript: "typescript";
|
|
105
|
+
python: "python";
|
|
106
|
+
}>>;
|
|
107
|
+
replicas: z.ZodOptional<z.ZodNumber>;
|
|
108
|
+
hpa: z.ZodOptional<z.ZodObject<{
|
|
109
|
+
enabled: z.ZodBoolean;
|
|
110
|
+
minReplicas: z.ZodOptional<z.ZodNumber>;
|
|
111
|
+
maxReplicas: z.ZodOptional<z.ZodNumber>;
|
|
112
|
+
targetCPUUtilizationPercentage: z.ZodOptional<z.ZodNumber>;
|
|
113
|
+
}, z.core.$strict>>;
|
|
114
|
+
resources: z.ZodOptional<z.ZodObject<{
|
|
115
|
+
cpu: z.ZodString;
|
|
116
|
+
memory: z.ZodString;
|
|
117
|
+
}, z.core.$strict>>;
|
|
118
|
+
cache: z.ZodOptional<z.ZodObject<{
|
|
119
|
+
redis: z.ZodOptional<z.ZodObject<{
|
|
120
|
+
enabled: z.ZodBoolean;
|
|
121
|
+
url: z.ZodOptional<z.ZodString>;
|
|
122
|
+
}, z.core.$strict>>;
|
|
123
|
+
}, z.core.$strict>>;
|
|
124
|
+
network: z.ZodOptional<z.ZodObject<{
|
|
125
|
+
additionalTcpPorts: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
|
|
126
|
+
}, z.core.$strict>>;
|
|
127
|
+
buildContext: z.ZodOptional<z.ZodString & z.ZodType<".", string, z.core.$ZodTypeInternals<".", string>>>;
|
|
128
|
+
}, z.core.$strict>;
|
|
129
|
+
export type DeploymentParse<T> = {
|
|
130
|
+
readonly ok: true;
|
|
131
|
+
readonly value: T;
|
|
132
|
+
} | {
|
|
133
|
+
readonly ok: false;
|
|
134
|
+
readonly reason: string;
|
|
135
|
+
};
|
|
136
|
+
/** Parse a legacy `deploy.ts` default export into the resolved view. */
|
|
137
|
+
export declare function normalizeLegacyDeployment(value: unknown): DeploymentParse<ResolvedDeploymentIntent>;
|
|
138
|
+
/** Parse an authored `deployment` key against the strict overrides contract. */
|
|
139
|
+
export declare function parseDeploymentIntent(value: unknown): DeploymentParse<ProviderDeploymentOverrides>;
|
|
140
|
+
/**
|
|
141
|
+
* Resolve an authored key against the runtime profiles, per field;
|
|
142
|
+
* `resources` and `hpa` resolve as whole objects (never deep-merged).
|
|
143
|
+
* Throws when the intent cannot resolve (dedicated runtime without
|
|
144
|
+
* resources, non-default buildContext) — the registry rejects the same.
|
|
145
|
+
*/
|
|
146
|
+
export declare function resolveDeploymentIntent(intent?: ProviderDeploymentOverrides): ResolvedDeploymentIntent;
|
|
147
|
+
/**
|
|
148
|
+
* Two resolved views describe the same deployment when they are deep-equal
|
|
149
|
+
* after dropping empty shells (`network: { additionalTcpPorts: [] }`,
|
|
150
|
+
* `cache: {}`) that carry no intent — the manifests they render are
|
|
151
|
+
* byte-identical.
|
|
152
|
+
*/
|
|
153
|
+
export declare function deploymentIntentsEquivalent(left: ResolvedDeploymentIntent, right: ResolvedDeploymentIntent): boolean;
|
|
154
|
+
export declare function canonicalResolvedDeployment(resolved: ResolvedDeploymentIntent): ResolvedDeploymentIntent;
|
|
155
|
+
/**
|
|
156
|
+
* The smallest `deployment` key that resolves to `resolved`: profile
|
|
157
|
+
* defaults are omitted, `hpa`/`resources` are kept whole when they differ
|
|
158
|
+
* (the resolver never deep-merges them), and empty shells are dropped.
|
|
159
|
+
* Callers prove the result with
|
|
160
|
+
* `deploymentIntentsEquivalent(resolveDeploymentIntent(key), resolved)`.
|
|
161
|
+
*/
|
|
162
|
+
export declare function subtractDeploymentDefaults(resolved: ResolvedDeploymentIntent): ProviderDeploymentOverrides;
|
|
163
|
+
/** Authored order for emitted keys: the registry contract's field order. */
|
|
164
|
+
export declare const DEPLOYMENT_INTENT_FIELD_ORDER: readonly (keyof ProviderDeploymentOverrides)[];
|
|
165
|
+
export interface RedundantDeploymentField {
|
|
166
|
+
/** Dotted path under `deployment`, e.g. `hpa` or `network.additionalTcpPorts`. */
|
|
167
|
+
readonly path: string;
|
|
168
|
+
readonly message: string;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Fields of an authored `deployment` key that restate what the runtime
|
|
172
|
+
* profile already resolves (ADR-0009 "derived values are not re-stated").
|
|
173
|
+
* Accepts an unvalidated value because `apifuse check` inspects the loaded
|
|
174
|
+
* definition, whose key the SDK passes through verbatim.
|
|
175
|
+
*/
|
|
176
|
+
export declare function redundantDeploymentDefaults(intent: unknown): RedundantDeploymentField[];
|
|
177
|
+
/** Structural equality for JSON-shaped values, key order insensitive. */
|
|
178
|
+
export declare function deepEqual(left: unknown, right: unknown): boolean;
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Runtime-profile defaults. `dedicated` carries no resource profile and
|
|
4
|
+
* therefore always needs explicit `resources`.
|
|
5
|
+
*/
|
|
6
|
+
export const DEPLOYMENT_PROFILE_DEFAULTS = Object.freeze({
|
|
7
|
+
runtime: "shared",
|
|
8
|
+
language: "typescript",
|
|
9
|
+
replicas: 1,
|
|
10
|
+
hpa: Object.freeze({
|
|
11
|
+
enabled: true,
|
|
12
|
+
minReplicas: 1,
|
|
13
|
+
maxReplicas: 1,
|
|
14
|
+
targetCPUUtilizationPercentage: 70,
|
|
15
|
+
}),
|
|
16
|
+
buildContext: ".",
|
|
17
|
+
resources: Object.freeze({
|
|
18
|
+
shared: Object.freeze({ cpu: "25m", memory: "128Mi" }),
|
|
19
|
+
browser: Object.freeze({ cpu: "200m", memory: "256Mi" }),
|
|
20
|
+
dedicated: undefined,
|
|
21
|
+
}),
|
|
22
|
+
});
|
|
23
|
+
const BUILD_CONTEXT_CONSTRAINT = 'only "." is accepted; external provider images always build from the materialized checkout root';
|
|
24
|
+
const hpaSchema = z
|
|
25
|
+
.object({
|
|
26
|
+
enabled: z.boolean(),
|
|
27
|
+
minReplicas: z.number().int().positive().optional(),
|
|
28
|
+
maxReplicas: z.number().int().positive().optional(),
|
|
29
|
+
targetCPUUtilizationPercentage: z.number().int().positive().optional(),
|
|
30
|
+
})
|
|
31
|
+
.strict();
|
|
32
|
+
const resourcesSchema = z.object({ cpu: z.string().min(1), memory: z.string().min(1) }).strict();
|
|
33
|
+
const cacheSchema = z
|
|
34
|
+
.object({
|
|
35
|
+
redis: z
|
|
36
|
+
.object({ enabled: z.boolean(), url: z.string().min(1).optional() })
|
|
37
|
+
.strict()
|
|
38
|
+
.optional(),
|
|
39
|
+
})
|
|
40
|
+
.strict();
|
|
41
|
+
const networkSchema = z
|
|
42
|
+
.object({
|
|
43
|
+
additionalTcpPorts: z.array(z.number().int().min(1).max(65535)).default([]),
|
|
44
|
+
})
|
|
45
|
+
.strict();
|
|
46
|
+
const buildContextSchema = z
|
|
47
|
+
.string()
|
|
48
|
+
.min(1)
|
|
49
|
+
.refine((value) => value === ".", { message: BUILD_CONTEXT_CONSTRAINT });
|
|
50
|
+
/**
|
|
51
|
+
* The standalone `deploy.ts` contract (legacy). Mirrors the registry's
|
|
52
|
+
* `ProviderDeploymentConfigSchema`, including its own defaults — note that a
|
|
53
|
+
* legacy file without `hpa` resolved to `{ enabled: false }`, not the
|
|
54
|
+
* profile HPA, so the two default tables are deliberately different.
|
|
55
|
+
*/
|
|
56
|
+
export const legacyDeploymentConfigSchema = z
|
|
57
|
+
.object({
|
|
58
|
+
runtime: z.enum(["shared", "dedicated", "browser"]),
|
|
59
|
+
language: z.enum(["typescript", "python"]),
|
|
60
|
+
replicas: z.number().int().positive().default(1),
|
|
61
|
+
hpa: hpaSchema.default({ enabled: false }),
|
|
62
|
+
resources: resourcesSchema,
|
|
63
|
+
cache: cacheSchema.optional(),
|
|
64
|
+
network: networkSchema.optional(),
|
|
65
|
+
buildContext: buildContextSchema.optional(),
|
|
66
|
+
})
|
|
67
|
+
.strict();
|
|
68
|
+
/** The authored `deployment` key: every field optional (registry `ProviderDeploymentOverridesSchema`). */
|
|
69
|
+
export const deploymentOverridesSchema = z
|
|
70
|
+
.object({
|
|
71
|
+
runtime: z.enum(["shared", "dedicated", "browser"]).optional(),
|
|
72
|
+
language: z.enum(["typescript", "python"]).optional(),
|
|
73
|
+
replicas: z.number().int().positive().optional(),
|
|
74
|
+
hpa: hpaSchema.optional(),
|
|
75
|
+
resources: resourcesSchema.optional(),
|
|
76
|
+
cache: cacheSchema.optional(),
|
|
77
|
+
network: networkSchema.optional(),
|
|
78
|
+
buildContext: buildContextSchema.optional(),
|
|
79
|
+
})
|
|
80
|
+
.strict();
|
|
81
|
+
function formatZodIssues(error) {
|
|
82
|
+
return error.issues
|
|
83
|
+
.map((issue) => {
|
|
84
|
+
const path = issue.path.map(String).join(".");
|
|
85
|
+
return path ? `${path}: ${issue.message}` : issue.message;
|
|
86
|
+
})
|
|
87
|
+
.join("; ");
|
|
88
|
+
}
|
|
89
|
+
/** Parse a legacy `deploy.ts` default export into the resolved view. */
|
|
90
|
+
export function normalizeLegacyDeployment(value) {
|
|
91
|
+
const parsed = legacyDeploymentConfigSchema.safeParse(value);
|
|
92
|
+
if (!parsed.success) {
|
|
93
|
+
return {
|
|
94
|
+
ok: false,
|
|
95
|
+
reason: `deploy.ts is not a valid deployment config: ${formatZodIssues(parsed.error)}`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const legacy = parsed.data;
|
|
99
|
+
return {
|
|
100
|
+
ok: true,
|
|
101
|
+
value: {
|
|
102
|
+
runtime: legacy.runtime,
|
|
103
|
+
language: legacy.language,
|
|
104
|
+
replicas: legacy.replicas,
|
|
105
|
+
hpa: legacy.hpa,
|
|
106
|
+
resources: legacy.resources,
|
|
107
|
+
...(legacy.cache ? { cache: legacy.cache } : {}),
|
|
108
|
+
...(legacy.network ? { network: legacy.network } : {}),
|
|
109
|
+
buildContext: legacy.buildContext ?? DEPLOYMENT_PROFILE_DEFAULTS.buildContext,
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/** Parse an authored `deployment` key against the strict overrides contract. */
|
|
114
|
+
export function parseDeploymentIntent(value) {
|
|
115
|
+
const parsed = deploymentOverridesSchema.safeParse(value);
|
|
116
|
+
if (!parsed.success) {
|
|
117
|
+
return { ok: false, reason: `deployment key is invalid: ${formatZodIssues(parsed.error)}` };
|
|
118
|
+
}
|
|
119
|
+
return { ok: true, value: parsed.data };
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Resolve an authored key against the runtime profiles, per field;
|
|
123
|
+
* `resources` and `hpa` resolve as whole objects (never deep-merged).
|
|
124
|
+
* Throws when the intent cannot resolve (dedicated runtime without
|
|
125
|
+
* resources, non-default buildContext) — the registry rejects the same.
|
|
126
|
+
*/
|
|
127
|
+
export function resolveDeploymentIntent(intent = {}) {
|
|
128
|
+
const runtime = intent.runtime ?? DEPLOYMENT_PROFILE_DEFAULTS.runtime;
|
|
129
|
+
const resources = intent.resources ?? DEPLOYMENT_PROFILE_DEFAULTS.resources[runtime];
|
|
130
|
+
if (!resources) {
|
|
131
|
+
throw new Error(`resources: runtime "${runtime}" has no profile default; declare explicit resources { cpu, memory }`);
|
|
132
|
+
}
|
|
133
|
+
if (intent.buildContext !== undefined &&
|
|
134
|
+
intent.buildContext !== DEPLOYMENT_PROFILE_DEFAULTS.buildContext) {
|
|
135
|
+
throw new Error(`buildContext: ${BUILD_CONTEXT_CONSTRAINT}`);
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
runtime,
|
|
139
|
+
language: intent.language ?? DEPLOYMENT_PROFILE_DEFAULTS.language,
|
|
140
|
+
replicas: intent.replicas ?? DEPLOYMENT_PROFILE_DEFAULTS.replicas,
|
|
141
|
+
hpa: intent.hpa ? { ...intent.hpa } : { ...DEPLOYMENT_PROFILE_DEFAULTS.hpa },
|
|
142
|
+
resources: { ...resources },
|
|
143
|
+
...(intent.cache ? { cache: cloneJson(intent.cache) } : {}),
|
|
144
|
+
...(intent.network
|
|
145
|
+
? { network: { additionalTcpPorts: [...(intent.network.additionalTcpPorts ?? [])] } }
|
|
146
|
+
: {}),
|
|
147
|
+
buildContext: intent.buildContext ?? DEPLOYMENT_PROFILE_DEFAULTS.buildContext,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Two resolved views describe the same deployment when they are deep-equal
|
|
152
|
+
* after dropping empty shells (`network: { additionalTcpPorts: [] }`,
|
|
153
|
+
* `cache: {}`) that carry no intent — the manifests they render are
|
|
154
|
+
* byte-identical.
|
|
155
|
+
*/
|
|
156
|
+
export function deploymentIntentsEquivalent(left, right) {
|
|
157
|
+
return deepEqual(canonicalResolvedDeployment(left), canonicalResolvedDeployment(right));
|
|
158
|
+
}
|
|
159
|
+
export function canonicalResolvedDeployment(resolved) {
|
|
160
|
+
const { cache, network, ...rest } = resolved;
|
|
161
|
+
const canonical = { ...rest };
|
|
162
|
+
if (cache?.redis !== undefined)
|
|
163
|
+
canonical.cache = { redis: { ...cache.redis } };
|
|
164
|
+
if (network !== undefined && network.additionalTcpPorts.length > 0) {
|
|
165
|
+
canonical.network = { additionalTcpPorts: [...network.additionalTcpPorts] };
|
|
166
|
+
}
|
|
167
|
+
return canonical;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The smallest `deployment` key that resolves to `resolved`: profile
|
|
171
|
+
* defaults are omitted, `hpa`/`resources` are kept whole when they differ
|
|
172
|
+
* (the resolver never deep-merges them), and empty shells are dropped.
|
|
173
|
+
* Callers prove the result with
|
|
174
|
+
* `deploymentIntentsEquivalent(resolveDeploymentIntent(key), resolved)`.
|
|
175
|
+
*/
|
|
176
|
+
export function subtractDeploymentDefaults(resolved) {
|
|
177
|
+
const intent = {};
|
|
178
|
+
if (resolved.runtime !== DEPLOYMENT_PROFILE_DEFAULTS.runtime)
|
|
179
|
+
intent.runtime = resolved.runtime;
|
|
180
|
+
if (resolved.language !== DEPLOYMENT_PROFILE_DEFAULTS.language)
|
|
181
|
+
intent.language = resolved.language;
|
|
182
|
+
if (resolved.replicas !== DEPLOYMENT_PROFILE_DEFAULTS.replicas)
|
|
183
|
+
intent.replicas = resolved.replicas;
|
|
184
|
+
if (!deepEqual(resolved.hpa, DEPLOYMENT_PROFILE_DEFAULTS.hpa))
|
|
185
|
+
intent.hpa = { ...resolved.hpa };
|
|
186
|
+
const profileResources = DEPLOYMENT_PROFILE_DEFAULTS.resources[resolved.runtime];
|
|
187
|
+
if (profileResources === undefined || !deepEqual(resolved.resources, profileResources)) {
|
|
188
|
+
intent.resources = { ...resolved.resources };
|
|
189
|
+
}
|
|
190
|
+
if (resolved.cache?.redis !== undefined)
|
|
191
|
+
intent.cache = { redis: { ...resolved.cache.redis } };
|
|
192
|
+
if (resolved.network !== undefined && resolved.network.additionalTcpPorts.length > 0) {
|
|
193
|
+
intent.network = { additionalTcpPorts: [...resolved.network.additionalTcpPorts] };
|
|
194
|
+
}
|
|
195
|
+
// buildContext: "." is the only accepted value, so it is never authored.
|
|
196
|
+
return intent;
|
|
197
|
+
}
|
|
198
|
+
/** Authored order for emitted keys: the registry contract's field order. */
|
|
199
|
+
export const DEPLOYMENT_INTENT_FIELD_ORDER = [
|
|
200
|
+
"runtime",
|
|
201
|
+
"language",
|
|
202
|
+
"replicas",
|
|
203
|
+
"hpa",
|
|
204
|
+
"resources",
|
|
205
|
+
"cache",
|
|
206
|
+
"network",
|
|
207
|
+
"buildContext",
|
|
208
|
+
];
|
|
209
|
+
/**
|
|
210
|
+
* Fields of an authored `deployment` key that restate what the runtime
|
|
211
|
+
* profile already resolves (ADR-0009 "derived values are not re-stated").
|
|
212
|
+
* Accepts an unvalidated value because `apifuse check` inspects the loaded
|
|
213
|
+
* definition, whose key the SDK passes through verbatim.
|
|
214
|
+
*/
|
|
215
|
+
export function redundantDeploymentDefaults(intent) {
|
|
216
|
+
if (!isRecord(intent))
|
|
217
|
+
return [];
|
|
218
|
+
const redundant = [];
|
|
219
|
+
const flag = (path, detail) => {
|
|
220
|
+
redundant.push({ path, message: `deployment.${path} ${detail}; omit it` });
|
|
221
|
+
};
|
|
222
|
+
if (intent.runtime === DEPLOYMENT_PROFILE_DEFAULTS.runtime) {
|
|
223
|
+
flag("runtime", `restates the profile default ("${DEPLOYMENT_PROFILE_DEFAULTS.runtime}")`);
|
|
224
|
+
}
|
|
225
|
+
if (intent.language === DEPLOYMENT_PROFILE_DEFAULTS.language) {
|
|
226
|
+
flag("language", `restates the profile default ("${DEPLOYMENT_PROFILE_DEFAULTS.language}")`);
|
|
227
|
+
}
|
|
228
|
+
if (intent.replicas === DEPLOYMENT_PROFILE_DEFAULTS.replicas) {
|
|
229
|
+
flag("replicas", `restates the profile default (${DEPLOYMENT_PROFILE_DEFAULTS.replicas})`);
|
|
230
|
+
}
|
|
231
|
+
if (deepEqual(intent.hpa, DEPLOYMENT_PROFILE_DEFAULTS.hpa)) {
|
|
232
|
+
flag("hpa", "restates the profile default (enabled, 1-1 replicas, 70% CPU target)");
|
|
233
|
+
}
|
|
234
|
+
const runtime = typeof intent.runtime === "string" && intent.runtime in DEPLOYMENT_PROFILE_DEFAULTS.resources
|
|
235
|
+
? intent.runtime
|
|
236
|
+
: DEPLOYMENT_PROFILE_DEFAULTS.runtime;
|
|
237
|
+
const profileResources = DEPLOYMENT_PROFILE_DEFAULTS.resources[runtime];
|
|
238
|
+
if (profileResources !== undefined && deepEqual(intent.resources, profileResources)) {
|
|
239
|
+
flag("resources", `restates the "${runtime}" profile default (${profileResources.cpu}/${profileResources.memory})`);
|
|
240
|
+
}
|
|
241
|
+
if (intent.buildContext === DEPLOYMENT_PROFILE_DEFAULTS.buildContext) {
|
|
242
|
+
flag("buildContext", 'restates the only accepted value (".")');
|
|
243
|
+
}
|
|
244
|
+
if (isRecord(intent.network)) {
|
|
245
|
+
const ports = intent.network.additionalTcpPorts;
|
|
246
|
+
if (ports === undefined || (Array.isArray(ports) && ports.length === 0)) {
|
|
247
|
+
flag("network", "declares no additional TCP ports (empty shell)");
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (isRecord(intent.cache) && intent.cache.redis === undefined) {
|
|
251
|
+
flag("cache", "declares no redis intent (empty shell)");
|
|
252
|
+
}
|
|
253
|
+
return redundant;
|
|
254
|
+
}
|
|
255
|
+
/** Structural equality for JSON-shaped values, key order insensitive. */
|
|
256
|
+
export function deepEqual(left, right) {
|
|
257
|
+
if (left === right)
|
|
258
|
+
return true;
|
|
259
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
260
|
+
if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length)
|
|
261
|
+
return false;
|
|
262
|
+
return left.every((item, index) => deepEqual(item, right[index]));
|
|
263
|
+
}
|
|
264
|
+
if (!isRecord(left) || !isRecord(right))
|
|
265
|
+
return false;
|
|
266
|
+
const leftKeys = Object.keys(left).filter((key) => left[key] !== undefined);
|
|
267
|
+
const rightKeys = Object.keys(right).filter((key) => right[key] !== undefined);
|
|
268
|
+
if (leftKeys.length !== rightKeys.length)
|
|
269
|
+
return false;
|
|
270
|
+
return leftKeys.every((key) => Object.hasOwn(right, key) && deepEqual(left[key], right[key]));
|
|
271
|
+
}
|
|
272
|
+
function isRecord(value) {
|
|
273
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
274
|
+
}
|
|
275
|
+
function cloneJson(value) {
|
|
276
|
+
return JSON.parse(JSON.stringify(value));
|
|
277
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { AuthMode, ProviderDefinition } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The connection the local CLIs stand in for the gateway with.
|
|
4
|
+
*
|
|
5
|
+
* At invocation time the gateway resolves the credential a provider needs and
|
|
6
|
+
* attaches it to the request envelope as
|
|
7
|
+
* `connection: { id, mode, secrets, metadata }`; `serve` then builds
|
|
8
|
+
* `ctx.credential` from `connection.secrets` and nothing else. For
|
|
9
|
+
* `auth.mode: "platform-managed"` the secrets are the platform-owned key the
|
|
10
|
+
* caller never sees — which is why a probe reaches one only by going back
|
|
11
|
+
* through the gateway (`ctx.gateway.execute(...)` in a health case's
|
|
12
|
+
* `prepareInput`), and why nothing that runs outside the gateway had any way
|
|
13
|
+
* to supply it.
|
|
14
|
+
*
|
|
15
|
+
* `apifuse record` hard-coded `credential: { mode: "none" }`, so
|
|
16
|
+
* `ctx.credential.get(...)` returned `undefined` for every platform-managed
|
|
17
|
+
* provider and the run died on that provider's own `MISSING_SECRET`. The same
|
|
18
|
+
* hole made `submit-check --smoke` POST an envelope with no `connection` at
|
|
19
|
+
* all. A large share of the fleet was unrecordable and unsmokeable, and it
|
|
20
|
+
* read as "no live upstream success" rather than as a missing capability.
|
|
21
|
+
*
|
|
22
|
+
* This module is the local resolver for that connection. It does not invent a
|
|
23
|
+
* second credential path: it produces the exact shape the gateway injects, so
|
|
24
|
+
* the provider code under test takes the production branch.
|
|
25
|
+
*/
|
|
26
|
+
export interface LocalConnection {
|
|
27
|
+
readonly id: string;
|
|
28
|
+
readonly mode: AuthMode;
|
|
29
|
+
readonly secrets: Record<string, string>;
|
|
30
|
+
readonly metadata: Record<string, never>;
|
|
31
|
+
/**
|
|
32
|
+
* Empty, exactly as the gateway leaves it when it injects a platform
|
|
33
|
+
* credential. `OperationConnectionSchema` requires the field, so omitting
|
|
34
|
+
* it would make every smoke envelope fail request validation before the
|
|
35
|
+
* provider ran.
|
|
36
|
+
*/
|
|
37
|
+
readonly externalRef: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* JSON object of `connection.secrets`, keyed exactly as the provider reads
|
|
41
|
+
* them through `ctx.credential.get(...)`.
|
|
42
|
+
*
|
|
43
|
+
* A single JSON value rather than one variable per key on purpose:
|
|
44
|
+
* platform-managed providers must not declare `credential.keys` (the SDK lint
|
|
45
|
+
* rejects it), so the key names are known only to the provider's own source.
|
|
46
|
+
* There is no derivation from an env name that would be right for every
|
|
47
|
+
* provider, and guessing one would be a second, lossy contract next to the
|
|
48
|
+
* gateway's.
|
|
49
|
+
*/
|
|
50
|
+
export declare const LOCAL_CONNECTION_SECRETS_ENV = "APIFUSE__LOCAL_CONNECTION__SECRETS";
|
|
51
|
+
/** Stable local connection id, mirroring the CLIs' other `local-*` scopes. */
|
|
52
|
+
export declare const LOCAL_CONNECTION_ID = "local-connection";
|
|
53
|
+
/** Auth modes whose providers read a credential the gateway supplies. */
|
|
54
|
+
export declare function providerRequiresConnection(provider: {
|
|
55
|
+
readonly auth?: {
|
|
56
|
+
readonly mode?: AuthMode;
|
|
57
|
+
} | undefined;
|
|
58
|
+
}): boolean;
|
|
59
|
+
export type CredentialOverrideParse = {
|
|
60
|
+
readonly ok: true;
|
|
61
|
+
readonly secrets: Record<string, string>;
|
|
62
|
+
} | {
|
|
63
|
+
readonly ok: false;
|
|
64
|
+
readonly reason: string;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Parses repeated `--credential key=value` arguments.
|
|
68
|
+
*
|
|
69
|
+
* Splits on the first `=` only: a base64 or URL-shaped secret routinely
|
|
70
|
+
* contains more.
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseCredentialOverrides(values: readonly string[]): CredentialOverrideParse;
|
|
73
|
+
/** Reads {@link LOCAL_CONNECTION_SECRETS_ENV} into a secrets map. */
|
|
74
|
+
export declare function parseEnvironmentSecrets(raw: string | undefined): CredentialOverrideParse;
|
|
75
|
+
export interface ResolveLocalConnectionOptions {
|
|
76
|
+
/** Repeated `--credential key=value` arguments, in order. */
|
|
77
|
+
readonly overrides?: readonly string[];
|
|
78
|
+
/** Environment to read {@link LOCAL_CONNECTION_SECRETS_ENV} from. */
|
|
79
|
+
readonly env?: Readonly<Record<string, string | undefined>>;
|
|
80
|
+
}
|
|
81
|
+
export type LocalConnectionResolution = {
|
|
82
|
+
readonly ok: true;
|
|
83
|
+
readonly connection: LocalConnection | undefined;
|
|
84
|
+
} | {
|
|
85
|
+
readonly ok: false;
|
|
86
|
+
readonly reason: string;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Resolves the connection to attach for one local invocation.
|
|
90
|
+
*
|
|
91
|
+
* Three outcomes, and the middle one is the point of the change:
|
|
92
|
+
*
|
|
93
|
+
* - the provider needs no credential (`auth.mode` absent or `"none"`) →
|
|
94
|
+
* no connection, exactly as before;
|
|
95
|
+
* - the provider needs one and none is configured → `ok: false` with a
|
|
96
|
+
* message naming both ways to supply it. The caller surfaces that instead
|
|
97
|
+
* of letting the provider fail deep inside a handler on a `MISSING_SECRET`
|
|
98
|
+
* that reads like an upstream problem;
|
|
99
|
+
* - the provider needs one and it is configured → the gateway's envelope
|
|
100
|
+
* shape.
|
|
101
|
+
*
|
|
102
|
+
* CLI overrides win over the environment so a one-off run does not need the
|
|
103
|
+
* shell variable unset.
|
|
104
|
+
*/
|
|
105
|
+
export declare function resolveLocalConnection(provider: Pick<ProviderDefinition, "id"> & {
|
|
106
|
+
auth?: {
|
|
107
|
+
mode?: AuthMode;
|
|
108
|
+
};
|
|
109
|
+
}, options?: ResolveLocalConnectionOptions): LocalConnectionResolution;
|
|
110
|
+
/** The message a caller prints when a needed credential is not configured. */
|
|
111
|
+
export declare function missingLocalConnectionMessage(providerId: string, mode: AuthMode): string;
|