@apifuse/provider-sdk 2.2.0-beta.2 → 2.2.0-beta.21
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 +487 -0
- package/CHANGELOG.md +90 -0
- package/README.md +49 -3
- package/SUBMISSION.md +1 -1
- package/bin/apifuse-check.ts +44 -59
- package/bin/apifuse-create.ts +1 -1
- package/bin/apifuse-dev.ts +27 -52
- package/bin/apifuse-pack-check.ts +14 -0
- package/bin/apifuse-pack-smoke.ts +36 -81
- package/bin/apifuse-pack-types.ts +305 -0
- package/bin/apifuse-perf.ts +45 -127
- package/bin/apifuse-record.ts +659 -111
- package/bin/apifuse-submit-check.ts +546 -48
- package/bin/apifuse-sync-assets.ts +117 -0
- package/bin/apifuse.ts +1 -1
- package/bin/submit-check-delimited-text.ts +50 -0
- package/bin/submit-check-xml-semantics.ts +204 -0
- package/bin/submit-check-xml.ts +134 -0
- package/dist/auth-turn/index.d.ts +3 -3
- package/dist/auth.d.ts +2 -2
- package/dist/auth.js +9 -18
- package/dist/ceremonies/index.d.ts +9 -1
- package/dist/ceremonies/index.js +65 -18
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +8 -0
- package/dist/cli/create.d.ts +3 -0
- package/dist/cli/create.js +34 -35
- 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/config/loader.d.ts +176 -8
- package/dist/config/loader.js +424 -95
- package/dist/contract-serialization.d.ts +2 -2
- package/dist/contract-serialization.js +3 -6
- package/dist/contract-types.d.ts +2 -2
- package/dist/contract.d.ts +3 -3
- package/dist/contract.js +4 -6
- package/dist/define.d.ts +9 -1
- package/dist/define.js +304 -119
- package/dist/dev.d.ts +1 -1
- package/dist/dev.js +1 -1
- package/dist/error-resolution.d.ts +2 -0
- package/dist/error-resolution.js +90 -0
- package/dist/errors.d.ts +22 -1
- package/dist/errors.js +88 -0
- package/dist/fixture-sanitization.d.ts +26 -0
- package/dist/fixture-sanitization.js +216 -0
- package/dist/i18n/catalog.d.ts +2 -2
- package/dist/i18n/catalog.js +4 -10
- package/dist/i18n/index.d.ts +2 -2
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/keys.d.ts +2 -2
- package/dist/index.d.ts +46 -42
- package/dist/index.js +41 -37
- package/dist/lint.d.ts +1 -1
- package/dist/lint.js +8 -15
- 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 +12 -11
- package/dist/provider.js +10 -9
- package/dist/public-schema-field-lint.d.ts +1 -1
- package/dist/recipes/gov-api.js +1 -1
- package/dist/runtime/auth-flow.d.ts +2 -1
- package/dist/runtime/auth-flow.js +4 -3
- package/dist/runtime/browser.d.ts +1 -1
- package/dist/runtime/browser.js +15 -29
- package/dist/runtime/cache.d.ts +1 -1
- package/dist/runtime/cache.js +4 -8
- package/dist/runtime/choice.d.ts +1 -1
- package/dist/runtime/choice.js +31 -35
- package/dist/runtime/credential.d.ts +1 -1
- package/dist/runtime/credential.js +1 -1
- package/dist/runtime/env.d.ts +1 -1
- package/dist/runtime/executor.d.ts +1 -1
- package/dist/runtime/executor.js +31 -4
- package/dist/runtime/http.d.ts +2 -2
- package/dist/runtime/http.js +387 -47
- package/dist/runtime/insights.d.ts +1 -1
- package/dist/runtime/insights.js +6 -13
- package/dist/runtime/instrumentation.d.ts +2 -2
- package/dist/runtime/instrumentation.js +345 -22
- package/dist/runtime/keyring.js +1 -1
- package/dist/runtime/namespace.js +1 -1
- package/dist/runtime/native-network.d.ts +127 -0
- package/dist/runtime/native-network.js +1298 -0
- package/dist/runtime/otlp.d.ts +1 -1
- package/dist/runtime/perf.d.ts +1 -1
- package/dist/runtime/provider.d.ts +1 -1
- package/dist/runtime/provider.js +1 -2
- package/dist/runtime/proxy-errors.d.ts +1 -1
- package/dist/runtime/proxy-errors.js +9 -7
- package/dist/runtime/proxy-nodemaven.d.ts +56 -0
- package/dist/runtime/proxy-nodemaven.js +146 -0
- package/dist/runtime/proxy-retry-policy.d.ts +2 -2
- package/dist/runtime/proxy-retry-policy.js +2 -2
- package/dist/runtime/proxy-telemetry.d.ts +2 -1
- package/dist/runtime/proxy-telemetry.js +55 -52
- 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 +2 -4
- package/dist/runtime/request-options.d.ts +68 -1
- package/dist/runtime/request-options.js +548 -0
- package/dist/runtime/secrets.d.ts +27 -0
- package/dist/runtime/secrets.js +51 -0
- package/dist/runtime/state.d.ts +2 -2
- package/dist/runtime/state.js +238 -26
- package/dist/runtime/stealth.d.ts +5 -3
- package/dist/runtime/stealth.js +423 -143
- package/dist/runtime/stt.d.ts +1 -1
- package/dist/runtime/stt.js +11 -15
- package/dist/runtime/trace.d.ts +2 -2
- package/dist/runtime/trace.js +2 -4
- package/dist/runtime/waterfall.d.ts +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/schema.js +7 -15
- package/dist/serve.d.ts +1 -1
- package/dist/serve.js +1 -1
- package/dist/server/index.d.ts +7 -7
- package/dist/server/index.js +6 -6
- 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.d.ts +1 -1
- package/dist/server/self-test-redaction.js +1 -1
- package/dist/server/self-test.d.ts +104 -3
- package/dist/server/self-test.js +673 -115
- package/dist/server/serve.d.ts +116 -4
- package/dist/server/serve.js +799 -128
- package/dist/server/types.d.ts +34 -9
- package/dist/server/types.js +8 -1
- package/dist/stateful/errors.d.ts +14 -0
- package/dist/stateful/errors.js +14 -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 +71 -0
- package/dist/stateful/stateful-provider-session-routing.js +353 -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 +1 -1
- package/dist/stealth/profiles.js +5 -14
- package/dist/stream-evidence.d.ts +74 -0
- package/dist/stream-evidence.js +785 -0
- package/dist/stream.d.ts +1 -1
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js +2 -2
- package/dist/testing/run.d.ts +32 -2
- package/dist/testing/run.js +478 -28
- package/dist/types.d.ts +342 -14
- package/dist/types.js +1 -0
- package/dist/user-input.d.ts +30 -0
- package/dist/user-input.js +66 -0
- package/package.json +16 -5
- package/src/auth-turn/index.ts +1 -1
- package/src/auth.ts +28 -86
- package/src/ceremonies/index.ts +103 -78
- package/src/cli/commands.ts +10 -0
- package/src/cli/create.ts +42 -35
- package/src/cli/prompt-assets.ts +865 -0
- package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/src/config/loader.ts +652 -204
- package/src/contract-serialization.ts +5 -11
- package/src/contract-types.ts +2 -2
- package/src/contract.ts +12 -28
- package/src/define.ts +499 -498
- package/src/dev.ts +4 -9
- package/src/error-resolution.ts +91 -0
- package/src/errors.ts +110 -5
- package/src/fixture-sanitization.ts +247 -0
- package/src/i18n/catalog.ts +10 -32
- package/src/i18n/index.ts +2 -2
- package/src/i18n/keys.ts +5 -11
- package/src/index.ts +112 -42
- package/src/lint.ts +88 -152
- 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 +66 -11
- package/src/public-schema-field-lint.ts +7 -33
- package/src/recipes/gov-api.ts +2 -5
- package/src/runtime/auth-flow.ts +7 -7
- package/src/runtime/browser.ts +64 -187
- package/src/runtime/cache.ts +20 -67
- package/src/runtime/choice.ts +79 -132
- package/src/runtime/credential.ts +2 -2
- package/src/runtime/env.ts +1 -1
- package/src/runtime/executor.ts +43 -20
- package/src/runtime/http.ts +494 -57
- package/src/runtime/insights.ts +15 -53
- package/src/runtime/instrumentation.ts +495 -66
- package/src/runtime/keyring.ts +7 -19
- package/src/runtime/namespace.ts +2 -7
- package/src/runtime/native-network.ts +1686 -0
- package/src/runtime/otlp.ts +12 -23
- package/src/runtime/perf.ts +1 -1
- package/src/runtime/provider.ts +4 -9
- package/src/runtime/proxy-errors.ts +29 -42
- package/src/runtime/proxy-nodemaven.ts +221 -0
- package/src/runtime/proxy-retry-policy.ts +3 -3
- package/src/runtime/proxy-telemetry.ts +79 -77
- package/src/runtime/redirects.ts +66 -0
- package/src/runtime/redis.ts +4 -12
- package/src/runtime/request-options.ts +679 -9
- package/src/runtime/secrets.ts +64 -0
- package/src/runtime/state.ts +353 -133
- package/src/runtime/stealth.ts +505 -154
- package/src/runtime/stt.ts +38 -94
- package/src/runtime/trace.ts +14 -44
- package/src/runtime/waterfall.ts +5 -18
- package/src/schema.ts +23 -84
- package/src/serve.ts +1 -1
- package/src/server/index.ts +29 -7
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/server/self-test-redaction.ts +2 -2
- package/src/server/self-test.ts +857 -132
- package/src/server/serve.ts +1151 -328
- package/src/server/types.ts +12 -13
- package/src/stateful/README.md +146 -0
- package/src/stateful/errors.ts +23 -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 +555 -0
- package/src/stateful/stateful-provider-session-runtime.ts +403 -0
- package/src/stateful-signing.ts +46 -0
- package/src/stealth/profiles.ts +10 -26
- package/src/stream-evidence.ts +988 -0
- package/src/stream.ts +8 -19
- package/src/testing/index.ts +10 -2
- package/src/testing/run.ts +653 -74
- package/src/types.ts +408 -28
- package/src/user-input.ts +118 -0
- 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/runtime/choice.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes, timingSafeEqual, } from "node:crypto";
|
|
2
|
-
import { assertFreshProviderChoiceIssuedAt, ProviderChoiceTokenError, } from "../choice-token";
|
|
3
|
-
import { ProviderError } from "../errors";
|
|
2
|
+
import { assertFreshProviderChoiceIssuedAt, ProviderChoiceTokenError, } from "../choice-token.js";
|
|
3
|
+
import { isProviderError, ProviderError } from "../errors.js";
|
|
4
4
|
export const PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV = "APIFUSE__PROVIDER_RUNTIME__CHOICE_TOKEN_MASTER_SECRET";
|
|
5
5
|
const PRIMARY_CHOICE_TOKEN_KID = "v1";
|
|
6
6
|
const MANAGED_CHOICE_TOKEN_VERSION = 1;
|
|
@@ -53,7 +53,7 @@ export function createProviderChoiceContext(options) {
|
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
function parse(parseOptions) {
|
|
56
|
-
const [actualPrefix, tokenKid, encodedIv, encryptedPayload, authTag, signature
|
|
56
|
+
const [actualPrefix, tokenKid, encodedIv, encryptedPayload, authTag, signature] = parseManagedChoiceTokenParts(parseOptions.token);
|
|
57
57
|
if (actualPrefix !== parseOptions.prefix ||
|
|
58
58
|
tokenKid !== kid ||
|
|
59
59
|
!encodedIv ||
|
|
@@ -68,13 +68,7 @@ export function createProviderChoiceContext(options) {
|
|
|
68
68
|
purpose: parseOptions.purpose,
|
|
69
69
|
kid: tokenKid,
|
|
70
70
|
});
|
|
71
|
-
const signedBody = [
|
|
72
|
-
parseOptions.prefix,
|
|
73
|
-
tokenKid,
|
|
74
|
-
encodedIv,
|
|
75
|
-
encryptedPayload,
|
|
76
|
-
authTag,
|
|
77
|
-
].join(".");
|
|
71
|
+
const signedBody = [parseOptions.prefix, tokenKid, encodedIv, encryptedPayload, authTag].join(".");
|
|
78
72
|
assertManagedChoiceSignature({
|
|
79
73
|
signedBody,
|
|
80
74
|
signature,
|
|
@@ -117,13 +111,11 @@ export function createProviderChoiceContext(options) {
|
|
|
117
111
|
export function createTestProviderChoiceContext(options) {
|
|
118
112
|
return createProviderChoiceContext({
|
|
119
113
|
...options,
|
|
120
|
-
masterSecret: options.masterSecret ??
|
|
121
|
-
"apifuse-test-provider-runtime-choice-token-master-secret",
|
|
114
|
+
masterSecret: options.masterSecret ?? "apifuse-test-provider-runtime-choice-token-master-secret",
|
|
122
115
|
});
|
|
123
116
|
}
|
|
124
117
|
function resolveChoiceMasterSecret(options) {
|
|
125
|
-
const configured = options.masterSecret ??
|
|
126
|
-
options.env?.get(PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV);
|
|
118
|
+
const configured = options.masterSecret ?? options.env?.get(PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV);
|
|
127
119
|
const trimmed = configured?.trim();
|
|
128
120
|
if (trimmed)
|
|
129
121
|
return trimmed;
|
|
@@ -165,13 +157,7 @@ function encryptManagedChoiceToken(options) {
|
|
|
165
157
|
]).toString("base64url");
|
|
166
158
|
const authTag = cipher.getAuthTag().toString("base64url");
|
|
167
159
|
const encodedIv = iv.toString("base64url");
|
|
168
|
-
const signedBody = [
|
|
169
|
-
options.prefix,
|
|
170
|
-
options.kid,
|
|
171
|
-
encodedIv,
|
|
172
|
-
encryptedPayload,
|
|
173
|
-
authTag,
|
|
174
|
-
].join(".");
|
|
160
|
+
const signedBody = [options.prefix, options.kid, encodedIv, encryptedPayload, authTag].join(".");
|
|
175
161
|
const signature = createHmac("sha256", options.keys.signing)
|
|
176
162
|
.update(signedBody)
|
|
177
163
|
.digest("base64url");
|
|
@@ -223,7 +209,25 @@ async function parseServerStoredChoice(options) {
|
|
|
223
209
|
storage,
|
|
224
210
|
contextState: options.contextState,
|
|
225
211
|
});
|
|
226
|
-
|
|
212
|
+
// Reading a server-stored choice back deserializes a persisted value. A
|
|
213
|
+
// corrupt/undecodable value would otherwise surface as a raw JSON.parse
|
|
214
|
+
// SyntaxError (or another unexpected throwable) that escapes the choice error
|
|
215
|
+
// taxonomy, gets masked as internal_error 500, and is treated as retryable by
|
|
216
|
+
// the hub -> reservation restart loop (2026-07-22 catchtable RCA, candidate A).
|
|
217
|
+
// Convert any non-branded throwable into a branded invalid_payload so it maps
|
|
218
|
+
// to a clean, non-retryable 400. Branded ProviderChoiceTokenError and genuine
|
|
219
|
+
// ProviderError (e.g. Redis-unavailable / state-unavailable) pass through so
|
|
220
|
+
// their category/retryable semantics are preserved.
|
|
221
|
+
let record;
|
|
222
|
+
try {
|
|
223
|
+
record = await namespace.get(optionsStateKey(options.handle.state_id));
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
if (error instanceof ProviderChoiceTokenError || isProviderError(error)) {
|
|
227
|
+
throw error;
|
|
228
|
+
}
|
|
229
|
+
throw new ProviderChoiceTokenError("invalid_payload", "Provider choice token state payload could not be decoded.");
|
|
230
|
+
}
|
|
227
231
|
if (!record) {
|
|
228
232
|
throw new ProviderChoiceTokenError("invalid_payload", "Provider choice token state payload is missing.");
|
|
229
233
|
}
|
|
@@ -345,9 +349,7 @@ function isManagedChoiceEnvelope(value) {
|
|
|
345
349
|
typeof value.issued_at_ms === "number" &&
|
|
346
350
|
"ttl_ms" in value &&
|
|
347
351
|
typeof value.ttl_ms === "number" &&
|
|
348
|
-
(!("binding" in value) ||
|
|
349
|
-
value.binding === undefined ||
|
|
350
|
-
isChoiceBinding(value.binding)));
|
|
352
|
+
(!("binding" in value) || value.binding === undefined || isChoiceBinding(value.binding)));
|
|
351
353
|
}
|
|
352
354
|
function isChoicePayload(value) {
|
|
353
355
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
@@ -355,29 +357,23 @@ function isChoicePayload(value) {
|
|
|
355
357
|
function isChoiceBinding(value) {
|
|
356
358
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
357
359
|
return false;
|
|
358
|
-
return ((!("connection_hash" in value) ||
|
|
359
|
-
typeof value.connection_hash === "string") &&
|
|
360
|
+
return ((!("connection_hash" in value) || typeof value.connection_hash === "string") &&
|
|
360
361
|
(!("credential_hash" in value) || typeof value.credential_hash === "string"));
|
|
361
362
|
}
|
|
362
363
|
function assertManagedChoiceEnvelope(envelope, options) {
|
|
363
|
-
if (envelope.provider_id !== options.providerId ||
|
|
364
|
-
envelope.purpose !== options.purpose) {
|
|
364
|
+
if (envelope.provider_id !== options.providerId || envelope.purpose !== options.purpose) {
|
|
365
365
|
throw new ProviderChoiceTokenError("invalid_payload", "Provider choice token payload is invalid.");
|
|
366
366
|
}
|
|
367
367
|
assertFreshProviderChoiceIssuedAt(envelope.issued_at_ms, {
|
|
368
368
|
// Clamp to the issuer's embedded TTL so a caller-supplied value cannot
|
|
369
369
|
// silently extend token validity past the deadline the issuer intended.
|
|
370
|
-
ttlMs: options.ttlMs != null
|
|
371
|
-
? Math.min(options.ttlMs, envelope.ttl_ms)
|
|
372
|
-
: envelope.ttl_ms,
|
|
370
|
+
ttlMs: options.ttlMs != null ? Math.min(options.ttlMs, envelope.ttl_ms) : envelope.ttl_ms,
|
|
373
371
|
nowMs: options.nowMs,
|
|
374
372
|
futureToleranceMs: options.futureToleranceMs,
|
|
375
373
|
});
|
|
376
374
|
}
|
|
377
375
|
function createChoiceBinding(options) {
|
|
378
|
-
const connectionHash = options.options?.connection
|
|
379
|
-
? hashRequiredConnection(options)
|
|
380
|
-
: undefined;
|
|
376
|
+
const connectionHash = options.options?.connection ? hashRequiredConnection(options) : undefined;
|
|
381
377
|
const credentialHash = options.options?.credentialKeys?.length
|
|
382
378
|
? hashCredentialKeys(options)
|
|
383
379
|
: undefined;
|
package/dist/runtime/env.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { EnvContext } from "../types";
|
|
1
|
+
import type { EnvContext } from "../types.js";
|
|
2
2
|
export declare function createEnvContext(allowedKeys?: string[]): EnvContext;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ProviderContext, ProviderDefinition } from "../types";
|
|
1
|
+
import type { ProviderContext, ProviderDefinition } from "../types.js";
|
|
2
2
|
export declare function isStreamingOperation(provider: ProviderDefinition, operationId: string): boolean;
|
|
3
3
|
/**
|
|
4
4
|
* Execute a provider operation by calling its handler.
|
package/dist/runtime/executor.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { ProviderError, SessionExpiredError } from "../errors";
|
|
2
|
-
import {
|
|
1
|
+
import { isSessionExpiredError, isValidationError, ProviderError, SessionExpiredError, ValidationError, } from "../errors.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { parseSchema } from "../schema.js";
|
|
4
|
+
import { assertRequiredSecretsPresent } from "./secrets.js";
|
|
3
5
|
export function isStreamingOperation(provider, operationId) {
|
|
4
6
|
const kind = provider.operations[operationId]?.transport?.kind ?? "json";
|
|
5
7
|
return kind !== "json";
|
|
@@ -23,6 +25,12 @@ export async function executeOperation(provider, operationId, ctx, input, _optio
|
|
|
23
25
|
fix: `Valid operations: ${Object.keys(provider.operations).join(", ")}`,
|
|
24
26
|
});
|
|
25
27
|
}
|
|
28
|
+
// SDK-owned secret presence gate (single source of truth): declared
|
|
29
|
+
// `required: true` secrets are validated here, before input parsing and the
|
|
30
|
+
// handler, so every invocation path (serve /v1, self-test probes, perf,
|
|
31
|
+
// record) fails with the same structured MISSING_SECRET error instead of a
|
|
32
|
+
// handler-specific crash. Providers must not re-check presence locally.
|
|
33
|
+
assertRequiredSecretsPresent(provider, ctx.env);
|
|
26
34
|
const validatedInput = await parseSchema(operation.input, input, `operations.${operationId}.input`);
|
|
27
35
|
const execute = () => ctx.trace.span(`handler:${operationId}`, () => Promise.resolve(operation.handler(ctx, validatedInput)));
|
|
28
36
|
let result;
|
|
@@ -39,7 +47,12 @@ export async function executeOperation(provider, operationId, ctx, input, _optio
|
|
|
39
47
|
// operation is safe to re-drive after refresh, which we signal by marking
|
|
40
48
|
// the surfaced error retryable; non-idempotent operations (the default)
|
|
41
49
|
// stay non-retryable so they are not auto-re-driven. See design.md §4.3 D3.
|
|
42
|
-
|
|
50
|
+
// Use the branded guard, not `instanceof`: a handler loaded through a
|
|
51
|
+
// duplicate/published SDK module can throw a correctly branded
|
|
52
|
+
// SessionExpiredError whose constructor identity differs from this
|
|
53
|
+
// executor's, which `instanceof` would miss — dropping the retryable
|
|
54
|
+
// upgrade and stranding an operation that opted into auth refresh.
|
|
55
|
+
if (isSessionExpiredError(error) && operation.retryOnAuthRefresh) {
|
|
43
56
|
throw new SessionExpiredError(error.message, { retryable: true });
|
|
44
57
|
}
|
|
45
58
|
throw error;
|
|
@@ -47,5 +60,19 @@ export async function executeOperation(provider, operationId, ctx, input, _optio
|
|
|
47
60
|
if (isStreamingOperation(provider, operationId)) {
|
|
48
61
|
return result;
|
|
49
62
|
}
|
|
50
|
-
|
|
63
|
+
try {
|
|
64
|
+
return await parseSchema(operation.output, result, `operations.${operationId}.output`);
|
|
65
|
+
}
|
|
66
|
+
catch (cause) {
|
|
67
|
+
if (!(cause instanceof z.ZodError) && !isValidationError(cause)) {
|
|
68
|
+
throw cause;
|
|
69
|
+
}
|
|
70
|
+
throw new ValidationError(`Operation handler output failed schema validation.`, {
|
|
71
|
+
code: "OUTPUT_VALIDATION_FAILED",
|
|
72
|
+
category: "output_validation",
|
|
73
|
+
retryable: false,
|
|
74
|
+
zodError: isValidationError(cause) ? cause.zodError : cause,
|
|
75
|
+
...(cause instanceof Error ? { cause } : {}),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
51
78
|
}
|
package/dist/runtime/http.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ProxyResolutionOptions } from "../config/loader";
|
|
2
|
-
import type { HttpClient, HttpRetrySummary } from "../types";
|
|
1
|
+
import type { ProxyResolutionOptions } from "../config/loader.js";
|
|
2
|
+
import type { HttpClient, HttpRetrySummary } from "../types.js";
|
|
3
3
|
export type HttpClientOptions = ProxyResolutionOptions & {
|
|
4
4
|
warn?: (message: string) => void;
|
|
5
5
|
userAgent?: string;
|