@apifuse/provider-sdk 2.2.0-beta.5 → 2.2.0-beta.50
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 +537 -33
- package/CHANGELOG.md +201 -1
- package/README.md +83 -22
- package/SUBMISSION.md +2 -2
- package/bin/apifuse-check.ts +165 -11
- package/bin/apifuse-dev.ts +57 -13
- package/bin/apifuse-migrate-operation-declaration.ts +55 -0
- package/bin/apifuse-migrate-shape.ts +202 -0
- package/bin/apifuse-pack-check.ts +22 -2
- package/bin/apifuse-pack-smoke.ts +57 -2
- package/bin/apifuse-pack-types.ts +357 -38
- package/bin/apifuse-perf.ts +14 -13
- package/bin/apifuse-record.ts +709 -72
- package/bin/apifuse-submit-check.ts +2344 -324
- package/bin/apifuse-sync-assets.ts +117 -0
- 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 +27 -0
- package/dist/cli/create.d.ts +4 -1
- package/dist/cli/create.js +42 -37
- package/dist/cli/migrate-operation-declaration.d.ts +59 -0
- package/dist/cli/migrate-operation-declaration.js +1178 -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 +52 -0
- package/dist/cli/migrate-provider-shape.js +578 -0
- package/dist/cli/prompt-assets.d.ts +80 -0
- package/dist/cli/prompt-assets.js +743 -0
- package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
- package/dist/cli/templates/provider/README.md.tpl +5 -5
- 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 +179 -16
- package/dist/config/loader.js +435 -127
- 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 +33 -0
- package/dist/declaration-validation.js +266 -0
- package/dist/define.d.ts +66 -29
- package/dist/define.js +778 -69
- package/dist/dev.d.ts +3 -0
- package/dist/dev.js +1 -1
- package/dist/engine.d.ts +78 -0
- package/dist/engine.js +133 -0
- package/dist/error-observability.d.ts +7 -0
- package/dist/error-observability.js +61 -0
- package/dist/error-resolution.d.ts +4 -0
- package/dist/error-resolution.js +122 -0
- package/dist/errors.d.ts +33 -0
- package/dist/errors.js +40 -0
- package/dist/fixture-sanitization.d.ts +28 -0
- package/dist/fixture-sanitization.js +227 -0
- package/dist/health-scenario.d.ts +1842 -0
- package/dist/health-scenario.js +624 -0
- package/dist/index.d.ts +21 -10
- package/dist/index.js +12 -7
- package/dist/lint.d.ts +23 -11
- package/dist/lint.js +572 -69
- 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 +10 -2
- package/dist/provider.js +4 -1
- package/dist/runtime/auth-flow.d.ts +5 -1
- package/dist/runtime/auth-flow.js +6 -0
- package/dist/runtime/browser.d.ts +1 -0
- package/dist/runtime/browser.js +492 -49
- package/dist/runtime/cache.d.ts +1 -0
- package/dist/runtime/cache.js +169 -15
- package/dist/runtime/choice-wordlist.d.ts +9 -0
- package/dist/runtime/choice-wordlist.js +138 -0
- package/dist/runtime/choice.d.ts +13 -1
- package/dist/runtime/choice.js +490 -102
- package/dist/runtime/chrome149-header-order.d.ts +58 -0
- package/dist/runtime/chrome149-header-order.js +289 -0
- package/dist/runtime/env.js +12 -0
- package/dist/runtime/executor.d.ts +3 -2
- package/dist/runtime/executor.js +26 -25
- package/dist/runtime/http.d.ts +1 -0
- package/dist/runtime/http.js +515 -53
- package/dist/runtime/insights.js +2 -2
- package/dist/runtime/instrumentation.d.ts +2 -2
- package/dist/runtime/instrumentation.js +366 -8
- 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 +96 -0
- package/dist/runtime/native-network.js +1232 -0
- package/dist/runtime/ocr.d.ts +29 -0
- package/dist/runtime/ocr.js +440 -0
- package/dist/runtime/otlp.d.ts +71 -2
- package/dist/runtime/otlp.js +397 -16
- package/dist/runtime/proxy-errors.js +6 -2
- package/dist/runtime/proxy-nodemaven.d.ts +56 -0
- package/dist/runtime/proxy-nodemaven.js +146 -0
- package/dist/runtime/proxy-telemetry.d.ts +80 -1
- package/dist/runtime/proxy-telemetry.js +154 -47
- package/dist/runtime/redirects.d.ts +29 -0
- package/dist/runtime/redirects.js +36 -0
- package/dist/runtime/redis.d.ts +1 -1
- package/dist/runtime/redis.js +4 -2
- package/dist/runtime/request-options.d.ts +68 -1
- package/dist/runtime/request-options.js +548 -0
- package/dist/runtime/resolver-config.d.ts +6 -0
- package/dist/runtime/resolver-config.js +6 -0
- package/dist/runtime/resolver-public.d.ts +1 -0
- package/dist/runtime/resolver-public.js +1 -0
- package/dist/runtime/resolver-shared.d.ts +14 -0
- package/dist/runtime/resolver-shared.js +12 -0
- package/dist/runtime/resolver-vendors/bindings.d.ts +48 -0
- package/dist/runtime/resolver-vendors/bindings.js +40 -0
- package/dist/runtime/resolver-vendors/browser.d.ts +22 -0
- package/dist/runtime/resolver-vendors/browser.js +377 -0
- package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
- package/dist/runtime/resolver-vendors/capsolver.js +531 -0
- package/dist/runtime/resolver-vendors/hosts.d.ts +2 -0
- package/dist/runtime/resolver-vendors/hosts.js +33 -0
- package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
- package/dist/runtime/resolver-vendors/twocaptcha.js +408 -0
- package/dist/runtime/resolver-vendors/types.d.ts +94 -0
- package/dist/runtime/resolver-vendors/types.js +96 -0
- package/dist/runtime/resolver.d.ts +72 -0
- package/dist/runtime/resolver.js +771 -0
- package/dist/runtime/secrets.d.ts +27 -0
- package/dist/runtime/secrets.js +51 -0
- package/dist/runtime/state.d.ts +3 -0
- package/dist/runtime/state.js +277 -71
- package/dist/runtime/stealth-cookies.d.ts +20 -0
- package/dist/runtime/stealth-cookies.js +111 -0
- package/dist/runtime/stealth.d.ts +41 -5
- package/dist/runtime/stealth.js +997 -291
- package/dist/runtime/stt.js +1 -12
- 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 +5 -0
- package/dist/runtime/trace.js +43 -10
- 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/index.d.ts +5 -2
- package/dist/server/index.js +2 -2
- 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.d.ts +14 -3
- package/dist/server/self-test.js +129 -58
- package/dist/server/serve-implementation.d.ts +230 -0
- package/dist/server/serve-implementation.js +2265 -0
- package/dist/server/serve.d.ts +1 -70
- package/dist/server/serve.js +1 -1131
- package/dist/server/trace-output.d.ts +6 -0
- package/dist/server/trace-output.js +79 -0
- package/dist/server/types.d.ts +30 -5
- package/dist/server/types.js +13 -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 +215 -0
- package/dist/stateful/stateful-provider-runtime-context.d.ts +32 -0
- package/dist/stateful/stateful-provider-runtime-context.js +60 -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 +9 -4
- package/dist/stealth/profiles.js +160 -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 +489 -21
- package/dist/trace-sanitization.d.ts +5 -0
- package/dist/trace-sanitization.js +45 -0
- package/dist/types.d.ts +673 -131
- package/dist/types.js +1 -0
- package/package.json +45 -5
- package/src/auth-turn/index.ts +1 -1
- package/src/auth.ts +118 -0
- package/src/ceremonies/index.ts +189 -46
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +3 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +10 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +8 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +5 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +16 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +3 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +31 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +21 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +14 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +15 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +4 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +12 -0
- package/src/cli/commands.ts +33 -0
- package/src/cli/create.ts +50 -37
- package/src/cli/migrate-operation-declaration.ts +1654 -0
- package/src/cli/migrate-operation-shape.ts +184 -0
- package/src/cli/migrate-provider-shape.ts +772 -0
- package/src/cli/prompt-assets.ts +865 -0
- package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/src/cli/templates/provider/Dockerfile.tpl +1 -1
- package/src/cli/templates/provider/README.md.tpl +5 -5
- 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 +690 -163
- 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 +330 -0
- package/src/define.ts +1048 -131
- package/src/dev.ts +4 -1
- package/src/engine.ts +279 -0
- package/src/error-observability.ts +64 -0
- package/src/error-resolution.ts +127 -0
- package/src/errors.ts +68 -0
- package/src/fixture-sanitization.ts +264 -0
- package/src/health-scenario.ts +875 -0
- package/src/index.ts +220 -13
- package/src/lint.ts +698 -90
- 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 +161 -3
- package/src/runtime/auth-flow.ts +12 -0
- package/src/runtime/browser.ts +661 -63
- package/src/runtime/cache.ts +189 -14
- package/src/runtime/choice-wordlist.ts +145 -0
- package/src/runtime/choice.ts +631 -120
- package/src/runtime/chrome149-header-order.ts +330 -0
- package/src/runtime/env.ts +13 -0
- package/src/runtime/executor.ts +43 -31
- package/src/runtime/http.ts +641 -61
- package/src/runtime/insights.ts +2 -2
- package/src/runtime/instrumentation.ts +520 -15
- package/src/runtime/native-network-errors.ts +99 -0
- package/src/runtime/native-network.ts +1605 -0
- package/src/runtime/ocr.ts +523 -0
- package/src/runtime/otlp.ts +467 -21
- package/src/runtime/proxy-errors.ts +12 -4
- package/src/runtime/proxy-nodemaven.ts +221 -0
- package/src/runtime/proxy-telemetry.ts +244 -75
- package/src/runtime/redirects.ts +66 -0
- package/src/runtime/redis.ts +7 -2
- package/src/runtime/request-options.ts +680 -1
- package/src/runtime/resolver-config.ts +6 -0
- package/src/runtime/resolver-public.ts +23 -0
- package/src/runtime/resolver-shared.ts +33 -0
- package/src/runtime/resolver-vendors/bindings.ts +56 -0
- package/src/runtime/resolver-vendors/browser.ts +533 -0
- package/src/runtime/resolver-vendors/capsolver.ts +707 -0
- package/src/runtime/resolver-vendors/hosts.ts +38 -0
- package/src/runtime/resolver-vendors/twocaptcha.ts +540 -0
- package/src/runtime/resolver-vendors/types.ts +212 -0
- package/src/runtime/resolver.ts +1157 -0
- package/src/runtime/secrets.ts +64 -0
- package/src/runtime/state.ts +394 -77
- package/src/runtime/stealth-cookies.ts +132 -0
- package/src/runtime/stealth.ts +1280 -336
- package/src/runtime/stt.ts +1 -19
- package/src/runtime/timeout.ts +18 -0
- package/src/runtime/trace-config.ts +78 -0
- package/src/runtime/trace.ts +57 -17
- package/src/serve.ts +6 -1
- package/src/server/error-observability.ts +1 -0
- package/src/server/index.ts +34 -2
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/server/self-test.ts +191 -68
- package/src/server/serve-implementation.ts +3378 -0
- package/src/server/serve.ts +1 -1632
- package/src/server/trace-output.ts +129 -0
- package/src/server/types.ts +13 -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 +287 -0
- package/src/stateful/stateful-provider-runtime-context.ts +92 -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 +202 -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 +658 -15
- package/src/trace-sanitization.ts +63 -0
- package/src/types.ts +788 -174
- package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
- package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
- /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
package/dist/types.js
CHANGED
|
@@ -32,6 +32,7 @@ export const HEALTH_CHECK_TIMEOUT_MS_MIN = 1;
|
|
|
32
32
|
export const HEALTH_CHECK_TIMEOUT_MS_MAX = 60_000;
|
|
33
33
|
export const HEALTH_CHECK_DEGRADED_THRESHOLD_MS_MIN = 1;
|
|
34
34
|
export const HEALTH_CHECK_DEGRADED_THRESHOLD_MS_MAX = 60_000;
|
|
35
|
+
export const VALID_OPERATION_ERROR_STATUSES = [400, 401, 404, 409, 410, 422, 429, 500, 502, 503, 504];
|
|
35
36
|
export const HttpRetryPreset = {
|
|
36
37
|
Off: "off",
|
|
37
38
|
TransportTransient: "transport_transient",
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.2.0-beta.
|
|
2
|
+
"version": "2.2.0-beta.50",
|
|
3
3
|
"name": "@apifuse/provider-sdk",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
@@ -61,6 +61,36 @@
|
|
|
61
61
|
"import": "./dist/server/index.js",
|
|
62
62
|
"default": "./dist/server/index.js"
|
|
63
63
|
},
|
|
64
|
+
"./runtime/browser": {
|
|
65
|
+
"types": "./dist/runtime/browser.d.ts",
|
|
66
|
+
"import": "./dist/runtime/browser.js",
|
|
67
|
+
"default": "./dist/runtime/browser.js"
|
|
68
|
+
},
|
|
69
|
+
"./runtime/native-network": {
|
|
70
|
+
"types": "./dist/runtime/native-network.d.ts",
|
|
71
|
+
"import": "./dist/runtime/native-network.js",
|
|
72
|
+
"default": "./dist/runtime/native-network.js"
|
|
73
|
+
},
|
|
74
|
+
"./runtime/prevalidate": {
|
|
75
|
+
"types": "./dist/runtime/prevalidate.d.ts",
|
|
76
|
+
"import": "./dist/runtime/prevalidate.js",
|
|
77
|
+
"default": "./dist/runtime/prevalidate.js"
|
|
78
|
+
},
|
|
79
|
+
"./runtime/resolver": {
|
|
80
|
+
"types": "./dist/runtime/resolver-public.d.ts",
|
|
81
|
+
"import": "./dist/runtime/resolver-public.js",
|
|
82
|
+
"default": "./dist/runtime/resolver-public.js"
|
|
83
|
+
},
|
|
84
|
+
"./runtime/stealth": {
|
|
85
|
+
"types": "./dist/runtime/stealth.d.ts",
|
|
86
|
+
"import": "./dist/runtime/stealth.js",
|
|
87
|
+
"default": "./dist/runtime/stealth.js"
|
|
88
|
+
},
|
|
89
|
+
"./stateful": {
|
|
90
|
+
"types": "./dist/stateful/index.d.ts",
|
|
91
|
+
"import": "./dist/stateful/index.js",
|
|
92
|
+
"default": "./dist/stateful/index.js"
|
|
93
|
+
},
|
|
64
94
|
"./testing": {
|
|
65
95
|
"types": "./dist/testing/index.d.ts",
|
|
66
96
|
"import": "./dist/testing/index.js",
|
|
@@ -75,10 +105,16 @@
|
|
|
75
105
|
"scripts": {
|
|
76
106
|
"lint": "biome lint .",
|
|
77
107
|
"lint:fix": "biome lint --write",
|
|
108
|
+
"lint:deprecated": "bun run scripts/lint-deprecated-usage.ts",
|
|
109
|
+
"lint:test-typesafety": "bun scripts/check-test-typesafety.ts",
|
|
78
110
|
"format": "biome format --write",
|
|
79
111
|
"type-check": "tsc --noEmit",
|
|
80
112
|
"test": "bun test",
|
|
81
|
-
"check": "bun run lint && bun run type-check && bun run build",
|
|
113
|
+
"check": "bun run lint && bun run type-check && bun run lint:deprecated && bun run lint:test-typesafety && bun run build",
|
|
114
|
+
"api:update": "bun run build && bun scripts/api-reports.ts update",
|
|
115
|
+
"api:check": "bun run build && bun scripts/api-reports.ts check",
|
|
116
|
+
"verify:chrome-headers": "bun scripts/verify-chrome-header-parity.ts",
|
|
117
|
+
"changeset:check": "bun scripts/check-changeset.ts",
|
|
82
118
|
"pack:check": "bun run build && bun bin/apifuse-pack-check.ts",
|
|
83
119
|
"pack:smoke": "bun run build && bun bin/apifuse-pack-smoke.ts",
|
|
84
120
|
"pack:types": "bun run build && bun bin/apifuse-pack-types.ts",
|
|
@@ -89,18 +125,19 @@
|
|
|
89
125
|
"devDependencies": {
|
|
90
126
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
91
127
|
"@biomejs/biome": "^2.5.0",
|
|
128
|
+
"@changesets/cli": "^3.0.1",
|
|
129
|
+
"@microsoft/api-extractor": "^7.58.13",
|
|
92
130
|
"@types/bun": "latest",
|
|
93
131
|
"@types/node": "^25.9.3",
|
|
94
|
-
"
|
|
132
|
+
"ajv": "^8.17",
|
|
133
|
+
"typescript": "6.0.3"
|
|
95
134
|
},
|
|
96
135
|
"dependencies": {
|
|
97
136
|
"@clack/prompts": "^1.5.1",
|
|
98
137
|
"@rgrove/parse-xml": "4.2.2",
|
|
99
138
|
"@types/ms": "^2.1.0",
|
|
100
139
|
"acorn": "^8.17.0",
|
|
101
|
-
"ajv": "^8.17",
|
|
102
140
|
"hono": "^4.12.25",
|
|
103
|
-
"impit": "0.14.1",
|
|
104
141
|
"ioredis": "^5.11.1",
|
|
105
142
|
"ms": "^2.1.3",
|
|
106
143
|
"playwright": "^1.55.1",
|
|
@@ -108,6 +145,9 @@
|
|
|
108
145
|
"puppeteer-extra-plugin-stealth": "^2.11.2",
|
|
109
146
|
"re2-wasm": "^1.0",
|
|
110
147
|
"safe-regex": "^2.1",
|
|
148
|
+
"socks": "^2.8.9",
|
|
149
|
+
"tough-cookie": "^6.0.2",
|
|
150
|
+
"wreq-js": "3.0.0",
|
|
111
151
|
"zod": "^4.4.3"
|
|
112
152
|
},
|
|
113
153
|
"repository": {
|
package/src/auth-turn/index.ts
CHANGED
|
@@ -24,7 +24,7 @@ export const AUTH_TURN_SCHEMA_ARTIFACT_PATH = "dist/auth-turn/auth-turn.v1.schem
|
|
|
24
24
|
*
|
|
25
25
|
* This is the exact codification of the runtime validation the SDK applies to
|
|
26
26
|
* ceremony outputs (see `validateCeremonyOutput` in `src/ceremonies`), which
|
|
27
|
-
*
|
|
27
|
+
* evaluates this same document. `kind` is an OPEN string on the wire: the known
|
|
28
28
|
* kinds in {@link TURN_KINDS} are tooling metadata, never a wire constraint.
|
|
29
29
|
*
|
|
30
30
|
* The committed artifact at `src/auth-turn/auth-turn.v1.schema.json` (shipped
|
package/src/auth.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { AuthError, ProviderError } from "./errors.js";
|
|
2
|
+
import {
|
|
3
|
+
declarationInvalidError,
|
|
4
|
+
DECLARATION_RULE_IDS,
|
|
5
|
+
type DeclarationViolation,
|
|
6
|
+
} from "./declaration-validation.js";
|
|
2
7
|
import type {
|
|
3
8
|
AuthAbortData,
|
|
4
9
|
AuthConfig,
|
|
@@ -291,6 +296,25 @@ export interface DefineCredentialsAuthOptions<
|
|
|
291
296
|
):
|
|
292
297
|
| CredentialsAuthLoginResult<TCredentialKeys, keyof TChallenges & string>
|
|
293
298
|
| Promise<CredentialsAuthLoginResult<TCredentialKeys, keyof TChallenges & string>>;
|
|
299
|
+
/**
|
|
300
|
+
* Optional re-mint of an expired session from the stored credential, wired
|
|
301
|
+
* to `auth.flow.refresh`.
|
|
302
|
+
*
|
|
303
|
+
* Credential-auth upstreams routinely invalidate a session well before the
|
|
304
|
+
* `expiresAt` the provider advertised, which leaves every operation failing
|
|
305
|
+
* with a reauth error until a human repeats the whole interactive login.
|
|
306
|
+
* Implement this to re-establish the session from what is already stored on
|
|
307
|
+
* the connection; the result is resolved exactly like `login`, so it may
|
|
308
|
+
* also raise a challenge when the upstream demands one. Omit it when the
|
|
309
|
+
* upstream has no non-interactive path and re-authentication genuinely
|
|
310
|
+
* requires the user.
|
|
311
|
+
*/
|
|
312
|
+
refresh?(
|
|
313
|
+
ctx: FlowContext,
|
|
314
|
+
input: Partial<CredentialsAuthInput<TFields>>,
|
|
315
|
+
):
|
|
316
|
+
| CredentialsAuthLoginResult<TCredentialKeys, keyof TChallenges & string>
|
|
317
|
+
| Promise<CredentialsAuthLoginResult<TCredentialKeys, keyof TChallenges & string>>;
|
|
294
318
|
}
|
|
295
319
|
|
|
296
320
|
export interface DefinedCredentialsAuth {
|
|
@@ -371,6 +395,27 @@ function normalizeInput<TFields extends CredentialsAuthFields>(
|
|
|
371
395
|
return result as CredentialsAuthInput<TFields>;
|
|
372
396
|
}
|
|
373
397
|
|
|
398
|
+
/**
|
|
399
|
+
* Refresh variant of {@link normalizeInput}. `login` coerces every declared
|
|
400
|
+
* field to a string because the interactive turn has already enforced that they
|
|
401
|
+
* are present; refresh runs with no user present, so an absent field is omitted
|
|
402
|
+
* rather than turned into an empty string. That keeps "the user did not supply
|
|
403
|
+
* this" distinguishable from "the user supplied an empty value".
|
|
404
|
+
*/
|
|
405
|
+
function normalizePartialInput<TFields extends CredentialsAuthFields>(
|
|
406
|
+
fields: TFields,
|
|
407
|
+
input: Record<string, unknown> | undefined,
|
|
408
|
+
): Partial<CredentialsAuthInput<TFields>> {
|
|
409
|
+
const result: Record<string, string> = {};
|
|
410
|
+
for (const name of Object.keys(fields)) {
|
|
411
|
+
const value = input?.[name];
|
|
412
|
+
if (typeof value === "string") {
|
|
413
|
+
result[name] = value;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return result as Partial<CredentialsAuthInput<TFields>>;
|
|
417
|
+
}
|
|
418
|
+
|
|
374
419
|
function assertCredentialKeys<TCredentialKeys extends readonly string[]>(
|
|
375
420
|
credentialKeys: TCredentialKeys,
|
|
376
421
|
credential: Record<string, unknown>,
|
|
@@ -656,6 +701,7 @@ export function defineCredentialsAuth<
|
|
|
656
701
|
string,
|
|
657
702
|
CredentialsAuthChallengeDefinition<CredentialsAuthFields, TCredentialKeys, string>
|
|
658
703
|
>;
|
|
704
|
+
validateCredentialsAuthChallenges(challenges);
|
|
659
705
|
|
|
660
706
|
return {
|
|
661
707
|
auth: {
|
|
@@ -710,6 +756,44 @@ export function defineCredentialsAuth<
|
|
|
710
756
|
completeTurnId,
|
|
711
757
|
);
|
|
712
758
|
},
|
|
759
|
+
// Only advertise refresh when the provider implements it: the
|
|
760
|
+
// protocol treats the hook's presence as "this connection can be
|
|
761
|
+
// re-established without the user", and exposing a stub that
|
|
762
|
+
// cannot actually re-mint would turn a recoverable expiry into a
|
|
763
|
+
// silent failure.
|
|
764
|
+
...(options.refresh
|
|
765
|
+
? {
|
|
766
|
+
refresh: async (ctx: FlowContext, rawInput?: Record<string, unknown>) => {
|
|
767
|
+
// A pending challenge belongs to the interactive flow that
|
|
768
|
+
// raised it; finish it there rather than restarting.
|
|
769
|
+
const pending = getPendingChallenge(ctx);
|
|
770
|
+
if (pending) {
|
|
771
|
+
return await continuePendingChallenge(
|
|
772
|
+
ctx,
|
|
773
|
+
options.credentialKeys,
|
|
774
|
+
challenges,
|
|
775
|
+
pending,
|
|
776
|
+
rawInput,
|
|
777
|
+
completeTurnId,
|
|
778
|
+
);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// Refresh runs without user input, so fields are optional
|
|
782
|
+
// here — unlike `continue`, missing ones are not a retry.
|
|
783
|
+
const result = await options.refresh!(
|
|
784
|
+
ctx,
|
|
785
|
+
normalizePartialInput(options.fields, rawInput),
|
|
786
|
+
);
|
|
787
|
+
return await resolveAuthResult(
|
|
788
|
+
ctx,
|
|
789
|
+
options.credentialKeys,
|
|
790
|
+
challenges,
|
|
791
|
+
result,
|
|
792
|
+
completeTurnId,
|
|
793
|
+
);
|
|
794
|
+
},
|
|
795
|
+
}
|
|
796
|
+
: {}),
|
|
713
797
|
},
|
|
714
798
|
},
|
|
715
799
|
credential: {
|
|
@@ -726,3 +810,37 @@ export function defineCredentialsAuth<
|
|
|
726
810
|
},
|
|
727
811
|
};
|
|
728
812
|
}
|
|
813
|
+
|
|
814
|
+
function validateCredentialsAuthChallenges(
|
|
815
|
+
challenges: Record<
|
|
816
|
+
string,
|
|
817
|
+
CredentialsAuthChallengeDefinition<CredentialsAuthFields, readonly string[], string>
|
|
818
|
+
>,
|
|
819
|
+
): void {
|
|
820
|
+
const violations: DeclarationViolation[] = [];
|
|
821
|
+
for (const [challengeId, challenge] of Object.entries(challenges)) {
|
|
822
|
+
const fieldCount =
|
|
823
|
+
challenge.fields && typeof challenge.fields === "object"
|
|
824
|
+
? Object.keys(challenge.fields).length
|
|
825
|
+
: 0;
|
|
826
|
+
const fieldsDeclared =
|
|
827
|
+
challenge.fields !== undefined && challenge.fields !== null;
|
|
828
|
+
const hasFields = fieldCount > 0;
|
|
829
|
+
const hasVerify = typeof challenge.verify === "function";
|
|
830
|
+
const hasPoll = typeof challenge.poll === "function";
|
|
831
|
+
const isInteractive = hasFields && hasVerify && !hasPoll;
|
|
832
|
+
const isPolling = !fieldsDeclared && !hasVerify && hasPoll;
|
|
833
|
+
const isHybrid = hasFields && hasVerify && hasPoll;
|
|
834
|
+
const emptyFieldsDeclared = fieldsDeclared && !hasFields;
|
|
835
|
+
if (!emptyFieldsDeclared && (isInteractive || isPolling || isHybrid)) continue;
|
|
836
|
+
|
|
837
|
+
const path = `challenges.${challengeId}`;
|
|
838
|
+
violations.push({
|
|
839
|
+
ruleId: DECLARATION_RULE_IDS.challengeShape,
|
|
840
|
+
path,
|
|
841
|
+
message: "challenge must be interactive, polling, or an explicit hybrid.",
|
|
842
|
+
fix: `Give ${path} non-empty fields plus verify, poll alone, or all three for a hybrid.`,
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
if (violations.length > 0) throw declarationInvalidError(violations);
|
|
846
|
+
}
|
package/src/ceremonies/index.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
2
2
|
|
|
3
|
-
import Ajv2020 from "ajv/dist/2020.js";
|
|
4
|
-
|
|
5
3
|
import { AUTH_TURN_SCHEMA, type KnownAuthTurnKind } from "../auth-turn/index.js";
|
|
6
4
|
import {
|
|
7
5
|
FlowExpiredError,
|
|
@@ -9,6 +7,7 @@ import {
|
|
|
9
7
|
TurnValidationError,
|
|
10
8
|
ValidationError,
|
|
11
9
|
} from "../errors.js";
|
|
10
|
+
import type { AuthStartNoInputGuard } from "../define.js";
|
|
12
11
|
import type { AuthFlowDefinition, AuthFlowInputHandler, AuthTurn, FlowContext } from "../types.js";
|
|
13
12
|
|
|
14
13
|
type TurnKind = KnownAuthTurnKind;
|
|
@@ -16,16 +15,26 @@ type TurnKind = KnownAuthTurnKind;
|
|
|
16
15
|
type CeremonyHandler = AuthFlowInputHandler;
|
|
17
16
|
|
|
18
17
|
type JsonObject = Record<string, unknown>;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
type JsonSchemaNode = {
|
|
19
|
+
readonly additionalProperties?: boolean;
|
|
20
|
+
readonly minimum?: number;
|
|
21
|
+
readonly minLength?: number;
|
|
22
|
+
readonly properties?: Readonly<Record<string, JsonSchemaNode>>;
|
|
23
|
+
readonly required?: readonly string[];
|
|
24
|
+
readonly type?: "number" | "object" | "string";
|
|
25
|
+
};
|
|
26
26
|
|
|
27
27
|
const OAUTH2_STATE_KEY = "__oauth2_state";
|
|
28
28
|
const OAUTH2_PKCE_VERIFIER_KEY = "__oauth2_pkce_verifier";
|
|
29
|
+
export const OAUTH2_PROXIED_AUTH_PROXY_ORIGIN_ENV_KEY = "APIFUSE__AUTH_PROXY__URL";
|
|
30
|
+
export const OAUTH2_PROXIED_PKCE_VERIFIER_KEY = "__oauth2_proxied_pkce_verifier";
|
|
31
|
+
const OAUTH2_PROXIED_RESERVED_AUTHORIZE_PARAMS = new Set([
|
|
32
|
+
"client_id",
|
|
33
|
+
"response_type",
|
|
34
|
+
"state",
|
|
35
|
+
"code_challenge",
|
|
36
|
+
"code_challenge_method",
|
|
37
|
+
]);
|
|
29
38
|
const DEVICE_FLOW_KEY = "__device_flow";
|
|
30
39
|
const MAGIC_LINK_KEY = "__magic_link";
|
|
31
40
|
const COMBINED_STAGE_KEY = "__combined_stage";
|
|
@@ -36,6 +45,56 @@ function isRecord(value: unknown): value is JsonObject {
|
|
|
36
45
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
37
46
|
}
|
|
38
47
|
|
|
48
|
+
function validateSchemaNode(
|
|
49
|
+
value: unknown,
|
|
50
|
+
schema: JsonSchemaNode,
|
|
51
|
+
path: string,
|
|
52
|
+
errors: string[],
|
|
53
|
+
): void {
|
|
54
|
+
if (schema.type === "object") {
|
|
55
|
+
if (!isRecord(value)) {
|
|
56
|
+
errors.push(`${path} must be object`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const properties = schema.properties ?? {};
|
|
60
|
+
for (const required of schema.required ?? []) {
|
|
61
|
+
if (!Object.hasOwn(value, required) || value[required] === undefined) {
|
|
62
|
+
errors.push(`${path} must have required property '${required}'`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (schema.additionalProperties === false) {
|
|
66
|
+
for (const key of Object.keys(value)) {
|
|
67
|
+
if (!Object.hasOwn(properties, key)) {
|
|
68
|
+
errors.push(`${path} must NOT have additional property '${key}'`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
for (const [key, childSchema] of Object.entries(properties)) {
|
|
73
|
+
if (Object.hasOwn(value, key) && value[key] !== undefined) {
|
|
74
|
+
validateSchemaNode(value[key], childSchema, `${path}/${key}`, errors);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (schema.type === "string") {
|
|
81
|
+
if (typeof value !== "string") {
|
|
82
|
+
errors.push(`${path} must be string`);
|
|
83
|
+
} else if (schema.minLength !== undefined && value.length < schema.minLength) {
|
|
84
|
+
errors.push(`${path} must NOT have fewer than ${schema.minLength} characters`);
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (schema.type === "number") {
|
|
90
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
91
|
+
errors.push(`${path} must be number`);
|
|
92
|
+
} else if (schema.minimum !== undefined && value < schema.minimum) {
|
|
93
|
+
errors.push(`${path} must be >= ${schema.minimum}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
39
98
|
function ensureRecord(value: unknown): JsonObject {
|
|
40
99
|
return isRecord(value) ? value : {};
|
|
41
100
|
}
|
|
@@ -153,14 +212,29 @@ function withDeclaredFormFieldOrder(expectedInput: JsonObject): JsonObject {
|
|
|
153
212
|
}
|
|
154
213
|
|
|
155
214
|
export function validateCeremonyOutput(turn: unknown): AuthTurn {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
215
|
+
// Evaluate the exact exported versioned schema without eagerly initializing
|
|
216
|
+
// a general-purpose JSON Schema compiler in every provider process. Contract
|
|
217
|
+
// parity tests compare this focused evaluator with AJV over all fixtures and
|
|
218
|
+
// edge probes, so the runtime and shipped document remain locked together.
|
|
219
|
+
const errors: string[] = [];
|
|
220
|
+
validateSchemaNode(turn, AUTH_TURN_SCHEMA, "", errors);
|
|
221
|
+
if (errors.length > 0) {
|
|
222
|
+
throw new TurnValidationError(errors.join("; "));
|
|
161
223
|
}
|
|
162
224
|
|
|
163
|
-
return turn;
|
|
225
|
+
return turn as AuthTurn;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Defines an auth flow while preserving its concrete type for downstream checks.
|
|
230
|
+
* The compile-time guard validates the inferred literal; annotating or widening
|
|
231
|
+
* a flow to `AuthFlowDefinition` before passing it defeats the check. Full
|
|
232
|
+
* enforcement requires branding, which is deferred to a future major.
|
|
233
|
+
*/
|
|
234
|
+
export function defineAuthFlow<const TFlow extends AuthFlowDefinition>(
|
|
235
|
+
flow: TFlow & AuthStartNoInputGuard<TFlow>,
|
|
236
|
+
): TFlow {
|
|
237
|
+
return flow;
|
|
164
238
|
}
|
|
165
239
|
|
|
166
240
|
export function createOAuth2Ceremony(options: {
|
|
@@ -171,7 +245,7 @@ export function createOAuth2Ceremony(options: {
|
|
|
171
245
|
scopes: string[];
|
|
172
246
|
usePKCE?: boolean;
|
|
173
247
|
}): AuthFlowDefinition {
|
|
174
|
-
return {
|
|
248
|
+
return defineAuthFlow({
|
|
175
249
|
start: (ctx) =>
|
|
176
250
|
runCeremonyHandler(
|
|
177
251
|
async () => {
|
|
@@ -245,7 +319,75 @@ export function createOAuth2Ceremony(options: {
|
|
|
245
319
|
input,
|
|
246
320
|
),
|
|
247
321
|
abort: async () => validateCeremonyOutput(createTurn("abort", { hint: "OAuth flow aborted." })),
|
|
248
|
-
};
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Builds the start handler for a custom-scheme OAuth provider. The shared
|
|
327
|
+
* auth-proxy owns state minting and callback capture, while the provider owns
|
|
328
|
+
* token exchange and any following authentication turns.
|
|
329
|
+
*/
|
|
330
|
+
export function createOAuth2ProxiedStart(
|
|
331
|
+
options: import("../types.js").ProxiedOAuthConfig,
|
|
332
|
+
): import("../types.js").AuthFlowStartHandler {
|
|
333
|
+
const pkce = options.pkce ?? "S256";
|
|
334
|
+
|
|
335
|
+
return (ctx) =>
|
|
336
|
+
runCeremonyHandler(
|
|
337
|
+
async () => {
|
|
338
|
+
for (const key of Object.keys(options.authorizeParams ?? {})) {
|
|
339
|
+
if (OAUTH2_PROXIED_RESERVED_AUTHORIZE_PARAMS.has(key.toLowerCase())) {
|
|
340
|
+
throw new ValidationError(
|
|
341
|
+
`OAuth2 proxied authorizeParams cannot override reserved parameter "${key}".`,
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
const proxyOrigin = ctx.env.get(OAUTH2_PROXIED_AUTH_PROXY_ORIGIN_ENV_KEY);
|
|
346
|
+
if (!proxyOrigin) {
|
|
347
|
+
throw new ProviderSecretError(
|
|
348
|
+
`Missing required platform environment: ${OAUTH2_PROXIED_AUTH_PROXY_ORIGIN_ENV_KEY}`,
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
const clientId = getRequiredEnv(ctx, options.clientIdEnvKey);
|
|
352
|
+
if (!ctx.flowId) {
|
|
353
|
+
throw new ValidationError("OAuth2 proxied start requires the gateway flow id.");
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const authorizePath = new URL(options.authorizeUrl).pathname;
|
|
357
|
+
const url = new URL(
|
|
358
|
+
`/p/${encodeURIComponent(ctx.providerId)}/f/${encodeURIComponent(ctx.flowId)}${authorizePath}`,
|
|
359
|
+
proxyOrigin,
|
|
360
|
+
);
|
|
361
|
+
url.searchParams.set("client_id", clientId);
|
|
362
|
+
url.searchParams.set("response_type", "code");
|
|
363
|
+
|
|
364
|
+
if (pkce === "S256") {
|
|
365
|
+
const verifier = createCodeVerifier();
|
|
366
|
+
ctx.context.set(OAUTH2_PROXIED_PKCE_VERIFIER_KEY, verifier);
|
|
367
|
+
url.searchParams.set("code_challenge", createCodeChallenge(verifier));
|
|
368
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
for (const [key, value] of Object.entries(options.authorizeParams ?? {})) {
|
|
372
|
+
url.searchParams.set(key, value);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return createTurn("redirect", {
|
|
376
|
+
data: { url: url.toString() },
|
|
377
|
+
hint: "Open the provider authorization page to continue.",
|
|
378
|
+
expectedInput: {
|
|
379
|
+
type: "object",
|
|
380
|
+
required: ["code", "state"],
|
|
381
|
+
properties: {
|
|
382
|
+
code: { type: "string" },
|
|
383
|
+
state: { type: "string" },
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
});
|
|
387
|
+
},
|
|
388
|
+
"OAuth2 proxied start failed",
|
|
389
|
+
ctx,
|
|
390
|
+
);
|
|
249
391
|
}
|
|
250
392
|
|
|
251
393
|
export function createDeviceFlowCeremony(options: {
|
|
@@ -255,7 +397,7 @@ export function createDeviceFlowCeremony(options: {
|
|
|
255
397
|
clientSecretEnvKey?: string;
|
|
256
398
|
scopes: string[];
|
|
257
399
|
}): AuthFlowDefinition {
|
|
258
|
-
return {
|
|
400
|
+
return defineAuthFlow({
|
|
259
401
|
start: (ctx) =>
|
|
260
402
|
runCeremonyHandler(
|
|
261
403
|
async () => {
|
|
@@ -332,7 +474,7 @@ export function createDeviceFlowCeremony(options: {
|
|
|
332
474
|
),
|
|
333
475
|
abort: async () =>
|
|
334
476
|
validateCeremonyOutput(createTurn("abort", { hint: "Device flow aborted." })),
|
|
335
|
-
};
|
|
477
|
+
});
|
|
336
478
|
}
|
|
337
479
|
|
|
338
480
|
export function createWebAuthnCeremony(options: {
|
|
@@ -341,7 +483,7 @@ export function createWebAuthnCeremony(options: {
|
|
|
341
483
|
verifyUrl?: string;
|
|
342
484
|
timeoutMs?: number;
|
|
343
485
|
}): AuthFlowDefinition {
|
|
344
|
-
return {
|
|
486
|
+
return defineAuthFlow({
|
|
345
487
|
start: (ctx) =>
|
|
346
488
|
runCeremonyHandler(
|
|
347
489
|
async () => {
|
|
@@ -400,7 +542,7 @@ export function createWebAuthnCeremony(options: {
|
|
|
400
542
|
),
|
|
401
543
|
abort: async () =>
|
|
402
544
|
validateCeremonyOutput(createTurn("abort", { hint: "WebAuthn ceremony aborted." })),
|
|
403
|
-
};
|
|
545
|
+
});
|
|
404
546
|
}
|
|
405
547
|
|
|
406
548
|
export function createMagicLinkCeremony(options: {
|
|
@@ -410,23 +552,31 @@ export function createMagicLinkCeremony(options: {
|
|
|
410
552
|
expiresInMs?: number;
|
|
411
553
|
}): AuthFlowDefinition {
|
|
412
554
|
const emailField = options.emailField ?? "email";
|
|
555
|
+
const buildEmailForm = () =>
|
|
556
|
+
buildJsonSchemaForm(
|
|
557
|
+
{
|
|
558
|
+
type: "object",
|
|
559
|
+
required: [emailField],
|
|
560
|
+
properties: {
|
|
561
|
+
[emailField]: { type: "string", format: "email" },
|
|
562
|
+
},
|
|
563
|
+
},
|
|
564
|
+
"Provide the email address to receive a magic link.",
|
|
565
|
+
);
|
|
413
566
|
|
|
414
|
-
return {
|
|
415
|
-
start: (ctx
|
|
567
|
+
return defineAuthFlow({
|
|
568
|
+
start: (ctx) =>
|
|
569
|
+
runCeremonyHandler(
|
|
570
|
+
async () => buildEmailForm(),
|
|
571
|
+
"Magic link start failed",
|
|
572
|
+
ctx,
|
|
573
|
+
),
|
|
574
|
+
continue: (ctx, input = {}) =>
|
|
416
575
|
runCeremonyHandler(
|
|
417
576
|
async () => {
|
|
418
577
|
const email = getString(input, emailField);
|
|
419
578
|
if (!email) {
|
|
420
|
-
return
|
|
421
|
-
{
|
|
422
|
-
type: "object",
|
|
423
|
-
required: [emailField],
|
|
424
|
-
properties: {
|
|
425
|
-
[emailField]: { type: "string", format: "email" },
|
|
426
|
-
},
|
|
427
|
-
},
|
|
428
|
-
"Provide the email address to receive a magic link.",
|
|
429
|
-
);
|
|
579
|
+
return buildEmailForm();
|
|
430
580
|
}
|
|
431
581
|
|
|
432
582
|
await ctx.http.post(options.sendUrl, { email });
|
|
@@ -441,17 +591,10 @@ export function createMagicLinkCeremony(options: {
|
|
|
441
591
|
timing: { suggestedPollIntervalMs: 5_000, maxWaitMs: 300_000 },
|
|
442
592
|
});
|
|
443
593
|
},
|
|
444
|
-
"Magic link
|
|
594
|
+
"Magic link continuation failed",
|
|
445
595
|
ctx,
|
|
446
596
|
input,
|
|
447
597
|
),
|
|
448
|
-
continue: async () =>
|
|
449
|
-
validateCeremonyOutput(
|
|
450
|
-
createTurn("poll", {
|
|
451
|
-
hint: "Continue polling for magic link completion.",
|
|
452
|
-
timing: { suggestedPollIntervalMs: 5_000, maxWaitMs: 300_000 },
|
|
453
|
-
}),
|
|
454
|
-
),
|
|
455
598
|
poll: (ctx) =>
|
|
456
599
|
runCeremonyHandler(
|
|
457
600
|
async () => {
|
|
@@ -487,7 +630,7 @@ export function createMagicLinkCeremony(options: {
|
|
|
487
630
|
),
|
|
488
631
|
abort: async () =>
|
|
489
632
|
validateCeremonyOutput(createTurn("abort", { hint: "Magic link flow aborted." })),
|
|
490
|
-
};
|
|
633
|
+
});
|
|
491
634
|
}
|
|
492
635
|
|
|
493
636
|
export function createFormCeremony(options: {
|
|
@@ -495,7 +638,7 @@ export function createFormCeremony(options: {
|
|
|
495
638
|
hint?: string;
|
|
496
639
|
mapCredential?: (input: Record<string, unknown>) => JsonObject;
|
|
497
640
|
}): AuthFlowDefinition {
|
|
498
|
-
return {
|
|
641
|
+
return defineAuthFlow({
|
|
499
642
|
start: async () =>
|
|
500
643
|
validateCeremonyOutput(
|
|
501
644
|
buildJsonSchemaForm(
|
|
@@ -527,7 +670,7 @@ export function createFormCeremony(options: {
|
|
|
527
670
|
),
|
|
528
671
|
abort: async () =>
|
|
529
672
|
validateCeremonyOutput(createTurn("abort", { hint: "Form ceremony aborted." })),
|
|
530
|
-
};
|
|
673
|
+
});
|
|
531
674
|
}
|
|
532
675
|
|
|
533
676
|
export function combineCeremonies(...ceremonies: AuthFlowDefinition[]): AuthFlowDefinition {
|
|
@@ -610,7 +753,7 @@ export function createSwitchCeremony(options: {
|
|
|
610
753
|
}): AuthFlowDefinition {
|
|
611
754
|
const choiceKeys = Object.keys(options.choices);
|
|
612
755
|
|
|
613
|
-
return {
|
|
756
|
+
return defineAuthFlow({
|
|
614
757
|
start: async () =>
|
|
615
758
|
validateCeremonyOutput(
|
|
616
759
|
createTurn("multi_choice", {
|
|
@@ -682,5 +825,5 @@ export function createSwitchCeremony(options: {
|
|
|
682
825
|
"Switch ceremony abort failed",
|
|
683
826
|
ctx,
|
|
684
827
|
),
|
|
685
|
-
};
|
|
828
|
+
});
|
|
686
829
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const searchOperation = defineOperation<ProviderContext>()({
|
|
2
|
+
annotations: { readOnly: true },
|
|
3
|
+
inputExamples: [
|
|
4
|
+
{
|
|
5
|
+
scenario: "Search by a precise phrase",
|
|
6
|
+
input: {
|
|
7
|
+
query: `京都
|
|
8
|
+
ホテル`,
|
|
9
|
+
},
|
|
10
|
+
rationale: "Shows whitespace preservation",
|
|
11
|
+
},
|
|
12
|
+
],
|
|
13
|
+
input: InputSchema,
|
|
14
|
+
output: OutputSchema,
|
|
15
|
+
handler,
|
|
16
|
+
});
|