@adcp/sdk 14.0.0 → 14.2.0
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/dist/lib/adapters/implicit-account-store.d.mts +12 -7
- package/dist/lib/adapters/implicit-account-store.d.ts +12 -7
- package/dist/lib/adapters/implicit-account-store.js +69 -15
- package/dist/lib/adapters/implicit-account-store.mjs +69 -15
- package/dist/lib/core/AgentClient.d.mts +1 -0
- package/dist/lib/core/AgentClient.d.ts +1 -0
- package/dist/lib/core/AgentClient.js +3 -0
- package/dist/lib/core/AgentClient.mjs +3 -0
- package/dist/lib/core/SingleAgentClient.d.mts +35 -2
- package/dist/lib/core/SingleAgentClient.d.ts +35 -2
- package/dist/lib/core/SingleAgentClient.js +377 -36
- package/dist/lib/core/SingleAgentClient.mjs +387 -38
- package/dist/lib/core/TaskExecutor.d.mts +3 -1
- package/dist/lib/core/TaskExecutor.d.ts +3 -1
- package/dist/lib/core/TaskExecutor.js +17 -12
- package/dist/lib/core/TaskExecutor.mjs +17 -12
- package/dist/lib/core/account-key.d.mts +3 -0
- package/dist/lib/core/account-key.d.ts +3 -0
- package/dist/lib/core/account-key.js +41 -0
- package/dist/lib/core/account-key.mjs +17 -0
- package/dist/lib/core/account-resolution.d.mts +2 -0
- package/dist/lib/core/account-resolution.d.ts +2 -0
- package/dist/lib/core/buyer-account-registry.d.mts +93 -0
- package/dist/lib/core/buyer-account-registry.d.ts +93 -0
- package/dist/lib/core/buyer-account-registry.js +602 -0
- package/dist/lib/core/buyer-account-registry.mjs +578 -0
- package/dist/lib/core/product-cache.d.mts +18 -0
- package/dist/lib/core/product-cache.d.ts +18 -0
- package/dist/lib/core/product-cache.js +137 -0
- package/dist/lib/core/product-cache.mjs +112 -0
- package/dist/lib/errors/index.d.mts +40 -1
- package/dist/lib/errors/index.d.ts +40 -1
- package/dist/lib/errors/index.js +69 -3
- package/dist/lib/errors/index.mjs +64 -3
- package/dist/lib/governance/authorization.d.mts +17 -1
- package/dist/lib/governance/authorization.d.ts +17 -1
- package/dist/lib/governance/authorization.js +55 -7
- package/dist/lib/governance/authorization.mjs +59 -7
- package/dist/lib/governance/index.d.mts +2 -2
- package/dist/lib/governance/index.d.ts +2 -2
- package/dist/lib/governance/index.js +2 -0
- package/dist/lib/governance/index.mjs +3 -1
- package/dist/lib/index.d.mts +7 -4
- package/dist/lib/index.d.ts +7 -4
- package/dist/lib/index.js +29 -0
- package/dist/lib/index.mjs +31 -1
- package/dist/lib/net/agent-transport-fetch.d.mts +4 -0
- package/dist/lib/net/agent-transport-fetch.d.ts +4 -0
- package/dist/lib/net/agent-transport-fetch.js +18 -5
- package/dist/lib/net/agent-transport-fetch.mjs +17 -5
- package/dist/lib/protocols/a2a.js +9 -1
- package/dist/lib/protocols/a2a.mjs +9 -1
- package/dist/lib/protocols/index.js +9 -2
- package/dist/lib/protocols/index.mjs +9 -2
- package/dist/lib/protocols/mcp-modern.js +2 -1
- package/dist/lib/protocols/mcp-modern.mjs +2 -1
- package/dist/lib/protocols/mcp.js +5 -2
- package/dist/lib/protocols/mcp.mjs +5 -2
- package/dist/lib/protocols/rawResponseCapture.d.mts +6 -0
- package/dist/lib/protocols/rawResponseCapture.d.ts +6 -0
- package/dist/lib/protocols/rawResponseCapture.js +41 -29
- package/dist/lib/protocols/rawResponseCapture.mjs +40 -29
- package/dist/lib/protocols/signedRequestRejection.d.mts +9 -0
- package/dist/lib/protocols/signedRequestRejection.d.ts +9 -0
- package/dist/lib/protocols/signedRequestRejection.js +209 -0
- package/dist/lib/protocols/signedRequestRejection.mjs +189 -0
- package/dist/lib/protocols/transportDiagnostics.d.mts +1 -0
- package/dist/lib/protocols/transportDiagnostics.d.ts +1 -0
- package/dist/lib/protocols/transportDiagnostics.js +2 -0
- package/dist/lib/protocols/transportDiagnostics.mjs +1 -0
- package/dist/lib/registry/types.generated.d.mts +112 -45
- package/dist/lib/registry/types.generated.d.ts +112 -45
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/account-provisioning.d.mts +2 -0
- package/dist/lib/server/account-provisioning.d.ts +2 -0
- package/dist/lib/server/account-provisioning.js +30 -0
- package/dist/lib/server/account-provisioning.mjs +6 -0
- package/dist/lib/server/account-reference-warnings.d.mts +12 -0
- package/dist/lib/server/account-reference-warnings.d.ts +12 -0
- package/dist/lib/server/account-reference-warnings.js +48 -0
- package/dist/lib/server/account-reference-warnings.mjs +23 -0
- package/dist/lib/server/auth-signature.js +1 -0
- package/dist/lib/server/auth-signature.mjs +1 -0
- package/dist/lib/server/create-adcp-server.d.mts +34 -0
- package/dist/lib/server/create-adcp-server.d.ts +34 -0
- package/dist/lib/server/create-adcp-server.js +225 -14
- package/dist/lib/server/create-adcp-server.mjs +225 -14
- package/dist/lib/server/decisioning/account.d.mts +2 -0
- package/dist/lib/server/decisioning/account.d.ts +2 -0
- package/dist/lib/server/decisioning/runtime/from-platform.js +49 -10
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +49 -10
- package/dist/lib/server/index.d.mts +2 -2
- package/dist/lib/server/index.d.ts +2 -2
- package/dist/lib/server/index.js +2 -0
- package/dist/lib/server/index.mjs +3 -1
- package/dist/lib/signing/agent-resolver/consistency.d.mts +6 -13
- package/dist/lib/signing/agent-resolver/consistency.d.ts +6 -13
- package/dist/lib/signing/agent-resolver/consistency.js +0 -1
- package/dist/lib/signing/agent-resolver/consistency.mjs +0 -1
- package/dist/lib/signing/agent-resolver/errors.d.mts +3 -1
- package/dist/lib/signing/agent-resolver/errors.d.ts +3 -1
- package/dist/lib/signing/agent-resolver/errors.js +6 -0
- package/dist/lib/signing/agent-resolver/errors.mjs +6 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.d.mts +11 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.d.ts +11 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.js +37 -2
- package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +40 -3
- package/dist/lib/signing/agent-resolver/jwks-set.js +24 -3
- package/dist/lib/signing/agent-resolver/jwks-set.mjs +24 -3
- package/dist/lib/signing/agent-resolver/legacy-brand.d.mts +15 -0
- package/dist/lib/signing/agent-resolver/legacy-brand.d.ts +15 -0
- package/dist/lib/signing/agent-resolver/legacy-brand.js +60 -0
- package/dist/lib/signing/agent-resolver/legacy-brand.mjs +36 -0
- package/dist/lib/signing/agent-resolver/operator-authorization.d.mts +13 -0
- package/dist/lib/signing/agent-resolver/operator-authorization.d.ts +13 -0
- package/dist/lib/signing/agent-resolver/operator-authorization.js +108 -0
- package/dist/lib/signing/agent-resolver/operator-authorization.mjs +84 -0
- package/dist/lib/signing/agent-resolver/resolve-agent.d.mts +14 -4
- package/dist/lib/signing/agent-resolver/resolve-agent.d.ts +14 -4
- package/dist/lib/signing/agent-resolver/resolve-agent.js +148 -137
- package/dist/lib/signing/agent-resolver/resolve-agent.mjs +157 -139
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +7 -1
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +7 -1
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +50 -17
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +50 -17
- package/dist/lib/signing/agent-resolver/select-agent.d.mts +14 -15
- package/dist/lib/signing/agent-resolver/select-agent.d.ts +14 -15
- package/dist/lib/signing/agent-resolver/select-agent.js +98 -13
- package/dist/lib/signing/agent-resolver/select-agent.mjs +95 -13
- package/dist/lib/signing/brand-jwks.d.mts +29 -75
- package/dist/lib/signing/brand-jwks.d.ts +29 -75
- package/dist/lib/signing/brand-jwks.js +120 -182
- package/dist/lib/signing/brand-jwks.mjs +120 -182
- package/dist/lib/signing/errors.d.mts +7 -3
- package/dist/lib/signing/errors.d.ts +7 -3
- package/dist/lib/signing/errors.js +7 -2
- package/dist/lib/signing/errors.mjs +7 -2
- package/dist/lib/signing/jwks-https.d.mts +7 -0
- package/dist/lib/signing/jwks-https.d.ts +7 -0
- package/dist/lib/signing/jwks-https.js +31 -8
- package/dist/lib/signing/jwks-https.mjs +31 -8
- package/dist/lib/signing/jwks.d.mts +8 -0
- package/dist/lib/signing/jwks.d.ts +8 -0
- package/dist/lib/signing/middleware.js +2 -1
- package/dist/lib/signing/middleware.mjs +2 -1
- package/dist/lib/signing/publisher-pins.d.mts +11 -0
- package/dist/lib/signing/publisher-pins.d.ts +11 -0
- package/dist/lib/signing/publisher-pins.js +125 -0
- package/dist/lib/signing/publisher-pins.mjs +101 -0
- package/dist/lib/signing/server.d.mts +1 -0
- package/dist/lib/signing/server.d.ts +1 -0
- package/dist/lib/signing/types.d.mts +5 -0
- package/dist/lib/signing/types.d.ts +5 -0
- package/dist/lib/signing/verifier.js +50 -5
- package/dist/lib/signing/verifier.mjs +50 -5
- package/dist/lib/signing/webhook-verifier.d.mts +7 -2
- package/dist/lib/signing/webhook-verifier.d.ts +7 -2
- package/dist/lib/signing/webhook-verifier.js +42 -2
- package/dist/lib/signing/webhook-verifier.mjs +42 -2
- package/dist/lib/testing/storyboard/account-policy.d.mts +2 -0
- package/dist/lib/testing/storyboard/account-policy.d.ts +2 -0
- package/dist/lib/testing/storyboard/account-policy.js +35 -0
- package/dist/lib/testing/storyboard/account-policy.mjs +11 -0
- package/dist/lib/testing/storyboard/context.js +6 -0
- package/dist/lib/testing/storyboard/context.mjs +6 -0
- package/dist/lib/testing/storyboard/request-builder.js +12 -2
- package/dist/lib/testing/storyboard/request-builder.mjs +12 -2
- package/dist/lib/testing/storyboard/runner.js +3 -2
- package/dist/lib/testing/storyboard/runner.mjs +3 -2
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/types/accept-proposal.d.ts +19 -1
- package/dist/lib/types/buy-products.d.ts +19 -1
- package/dist/lib/types/check-governance.d.ts +19 -1
- package/dist/lib/types/comply-test-controller.d.ts +19 -1
- package/dist/lib/types/control-media-buy.d.ts +19 -1
- package/dist/lib/types/core.generated.d.mts +14 -1
- package/dist/lib/types/core.generated.d.ts +14 -1
- package/dist/lib/types/create-media-buy.d.ts +14 -1
- package/dist/lib/types/get-media-buys.d.ts +14 -1
- package/dist/lib/types/get-products.d.ts +19 -1
- package/dist/lib/types/list-products.d.ts +19 -1
- package/dist/lib/types/refine-proposals.d.ts +19 -1
- package/dist/lib/types/request-proposals.d.ts +19 -1
- package/dist/lib/types/schemas.generated.d.ts +12 -3
- package/dist/lib/types/schemas.generated.js +4 -1
- package/dist/lib/types/schemas.generated.mjs +4 -1
- package/dist/lib/types/tools.generated.d.mts +14 -1
- package/dist/lib/types/tools.generated.d.ts +14 -1
- package/dist/lib/types/update-media-buy.d.ts +14 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/dist/lib/webhooks/index.d.mts +24 -0
- package/dist/lib/webhooks/index.d.ts +24 -0
- package/dist/lib/webhooks/index.js +50 -24
- package/dist/lib/webhooks/index.mjs +49 -24
- package/dist/lib/wholesale-feed-sync/index.d.mts +2 -0
- package/dist/lib/wholesale-feed-sync/index.d.ts +2 -0
- package/dist/lib/wholesale-feed-sync/index.js +7 -0
- package/dist/lib/wholesale-feed-sync/index.mjs +4 -0
- package/dist/lib/wholesale-feed-sync/mirror.d.mts +97 -0
- package/dist/lib/wholesale-feed-sync/mirror.d.ts +97 -0
- package/dist/lib/wholesale-feed-sync/mirror.js +350 -0
- package/dist/lib/wholesale-feed-sync/mirror.mjs +322 -0
- package/dist/lib/wholesale-feed-sync/sync.d.mts +13 -29
- package/dist/lib/wholesale-feed-sync/sync.d.ts +13 -29
- package/dist/lib/wholesale-feed-sync/sync.js +208 -281
- package/dist/lib/wholesale-feed-sync/sync.mjs +213 -281
- package/dist/lib/wholesale-feed-sync/types.d.mts +4 -3
- package/dist/lib/wholesale-feed-sync/types.d.ts +4 -3
- package/docs/README.md +6 -0
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/BUILD-AN-AGENT.md +2 -2
- package/docs/guides/BUYER-QUICKSTART-3.2.md +2 -0
- package/docs/guides/BUYER-STORAGE.md +3 -0
- package/docs/guides/FIRST-CALL-TO-A-SELLER.md +106 -0
- package/docs/guides/SIGNING-GUIDE.md +16 -7
- package/docs/guides/account-resolution.md +132 -10
- package/docs/llms.txt +3 -2
- package/docs/migration-14.0-to-14.1.md +85 -0
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-4.x-to-5.x.md +1 -0
- package/docs/migration-agent-resolution-3.3.md +125 -0
- package/docs/recipes/verifying-inbound-webhooks.md +60 -15
- package/package.json +3 -2
- package/skills/adcp-brand.previous/SKILL.md +0 -200
- package/skills/adcp-creative.previous/SKILL.md +0 -305
- package/skills/adcp-governance.previous/SKILL.md +0 -566
- package/skills/adcp-measurement.previous/SKILL.md +0 -136
- package/skills/adcp-media-buy.previous/SKILL.md +0 -556
- package/skills/adcp-si.previous/SKILL.md +0 -206
- package/skills/adcp-signals.previous/SKILL.md +0 -204
|
@@ -23,10 +23,14 @@ __export(brand_jwks_exports, {
|
|
|
23
23
|
fetchBrandJson: () => fetchBrandJson
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(brand_jwks_exports);
|
|
26
|
+
var import_fetch_helpers = require('./agent-resolver/fetch-helpers.js');
|
|
26
27
|
var import_net = require('../net/index.js');
|
|
27
|
-
var
|
|
28
|
+
var import_resolved_agent_jwks = require('./agent-resolver/resolved-agent-jwks.js');
|
|
29
|
+
var import_strict_json = require('./agent-resolver/strict-json.js');
|
|
30
|
+
var import_select_agent = require('./agent-resolver/select-agent.js');
|
|
28
31
|
class BrandJsonResolverError extends Error {
|
|
29
32
|
code;
|
|
33
|
+
recovery;
|
|
30
34
|
cause;
|
|
31
35
|
/** HTTP status for `fetch_failed` responses, when a response was received. */
|
|
32
36
|
httpStatus;
|
|
@@ -36,6 +40,7 @@ class BrandJsonResolverError extends Error {
|
|
|
36
40
|
this.code = code;
|
|
37
41
|
this.httpStatus = details.httpStatus;
|
|
38
42
|
this.cause = details.cause;
|
|
43
|
+
this.recovery = code !== "fetch_failed" || (0, import_fetch_helpers.isPermanentDiscoveryFailure)((0, import_fetch_helpers.classifyDiscoveryFailure)(this)) ? "terminal" : "transient";
|
|
39
44
|
}
|
|
40
45
|
}
|
|
41
46
|
const DEFAULT_MIN_COOLDOWN_SECONDS = 30;
|
|
@@ -43,115 +48,115 @@ const DEFAULT_MAX_AGE_SECONDS = 3600;
|
|
|
43
48
|
const DEFAULT_MAX_REDIRECTS = 3;
|
|
44
49
|
const BARE_HOSTNAME = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/;
|
|
45
50
|
class BrandJsonJwksResolver {
|
|
46
|
-
url;
|
|
47
|
-
selector;
|
|
48
|
-
minCooldown;
|
|
49
|
-
maxAge;
|
|
50
|
-
maxRedirects;
|
|
51
|
-
allowPrivateIp;
|
|
52
|
-
lookup;
|
|
53
|
-
jwksOptions;
|
|
54
|
-
now;
|
|
55
|
-
snapshot;
|
|
56
|
-
inner;
|
|
57
|
-
inFlight;
|
|
58
51
|
constructor(brandJsonUrl, options) {
|
|
59
|
-
this.
|
|
60
|
-
this.
|
|
52
|
+
this.brandJsonUrl = brandJsonUrl;
|
|
53
|
+
this.options = options;
|
|
54
|
+
for (const lifetime of [options.maxAgeSeconds, options.jwksOptions?.maxAgeSeconds]) {
|
|
55
|
+
if (lifetime !== void 0 && (!Number.isFinite(lifetime) || lifetime <= 0))
|
|
56
|
+
throw new TypeError("maxAgeSeconds must be a finite positive number.");
|
|
57
|
+
}
|
|
58
|
+
for (const cooldown of [options.minCooldownSeconds, options.jwksOptions?.minCooldownSeconds]) {
|
|
59
|
+
if (cooldown !== void 0 && (!Number.isFinite(cooldown) || cooldown < 0))
|
|
60
|
+
throw new TypeError("minCooldownSeconds must be a finite non-negative number.");
|
|
61
|
+
}
|
|
62
|
+
if (options.agentUrl !== void 0) this.resolver = this.createResolver(options.agentUrl, brandJsonUrl);
|
|
63
|
+
}
|
|
64
|
+
brandJsonUrl;
|
|
65
|
+
options;
|
|
66
|
+
resolver;
|
|
67
|
+
onboarding;
|
|
68
|
+
lastOnboardingAttempt = Number.NEGATIVE_INFINITY;
|
|
69
|
+
lastOnboardingError;
|
|
70
|
+
createResolver(agentUrl, operatorUrl) {
|
|
71
|
+
const options = this.options;
|
|
72
|
+
return new import_resolved_agent_jwks.ResolvedAgentJwksResolver(agentUrl, options.protocol ?? "mcp", {
|
|
61
73
|
agentType: options.agentType,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
74
|
+
agentId: options.agentId,
|
|
75
|
+
expectedBrandJsonUrl: operatorUrl,
|
|
76
|
+
fetchCapabilities: options.fetchCapabilities,
|
|
77
|
+
legacyWebhookFallback: options.legacyWebhookFallback ?? true,
|
|
78
|
+
allowPrivateIp: options.allowPrivateIp,
|
|
79
|
+
lookup: options.lookup,
|
|
80
|
+
now: options.now,
|
|
81
|
+
cacheTtlSeconds: Math.min(
|
|
82
|
+
options.maxAgeSeconds ?? DEFAULT_MAX_AGE_SECONDS,
|
|
83
|
+
options.jwksOptions?.maxAgeSeconds ?? 1800
|
|
84
|
+
),
|
|
85
|
+
unknownKidCooldownSeconds: options.minCooldownSeconds ?? options.jwksOptions?.minCooldownSeconds ?? DEFAULT_MIN_COOLDOWN_SECONDS
|
|
86
|
+
});
|
|
72
87
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
if (!this.inner) return null;
|
|
88
|
-
const hit = await this.inner.resolve(keyid);
|
|
89
|
-
if (hit) return hit;
|
|
90
|
-
if (this.snapshot && this.now() - this.snapshot.fetchedAt >= this.minCooldown) {
|
|
91
|
-
await this.refresh().catch(() => {
|
|
88
|
+
async confirmedResolver() {
|
|
89
|
+
if (this.resolver) return this.resolver;
|
|
90
|
+
if (this.onboarding) return this.onboarding;
|
|
91
|
+
const now = this.options.now?.() ?? Date.now() / 1e3;
|
|
92
|
+
if (now - this.lastOnboardingAttempt < 30)
|
|
93
|
+
throw this.lastOnboardingError ?? new BrandJsonResolverError("fetch_failed", "Operator onboarding discovery is in its retry cooldown.");
|
|
94
|
+
this.lastOnboardingAttempt = now;
|
|
95
|
+
this.onboarding = (async () => {
|
|
96
|
+
const record = await fetchBrandJson({
|
|
97
|
+
startUrl: this.brandJsonUrl,
|
|
98
|
+
maxRedirects: this.options.maxRedirects,
|
|
99
|
+
allowPrivateIp: this.options.allowPrivateIp,
|
|
100
|
+
lookup: this.options.lookup
|
|
92
101
|
});
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
102
|
+
const agentUrl = inferOnboardingAgentUrl(record.data, this.options);
|
|
103
|
+
const resolver = this.createResolver(agentUrl, record.finalUrl);
|
|
104
|
+
await resolver.forceRefresh();
|
|
105
|
+
this.resolver = resolver;
|
|
106
|
+
this.lastOnboardingError = void 0;
|
|
107
|
+
return resolver;
|
|
108
|
+
})().catch((error) => {
|
|
109
|
+
this.lastOnboardingError = error;
|
|
110
|
+
throw error;
|
|
111
|
+
}).finally(() => {
|
|
112
|
+
this.onboarding = void 0;
|
|
113
|
+
});
|
|
114
|
+
return this.onboarding;
|
|
115
|
+
}
|
|
116
|
+
async resolve(keyid) {
|
|
117
|
+
return (await this.confirmedResolver()).resolve(keyid);
|
|
118
|
+
}
|
|
119
|
+
async resolveWithMetadata(keyid) {
|
|
120
|
+
return (await this.confirmedResolver()).resolveWithMetadata(keyid);
|
|
96
121
|
}
|
|
97
|
-
/**
|
|
98
|
-
* The agent URL we resolved `jwks_uri` from. Populated after the first
|
|
99
|
-
* successful refresh; useful for verifier result attribution
|
|
100
|
-
* (`VerifyWebhookOptions.agentUrlForKeyid`).
|
|
101
|
-
*/
|
|
102
122
|
get agentUrl() {
|
|
103
|
-
return this.
|
|
123
|
+
return this.resolver?.resolvedAgentUrl;
|
|
104
124
|
}
|
|
105
|
-
/** Force a refetch of both brand.json and the inner JWKS, bypassing the cooldown. */
|
|
106
125
|
async forceRefresh() {
|
|
107
|
-
this.
|
|
108
|
-
this.
|
|
109
|
-
await this.refresh();
|
|
110
|
-
}
|
|
111
|
-
async refresh() {
|
|
112
|
-
if (this.inFlight) {
|
|
113
|
-
await this.inFlight;
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
this.inFlight = this.doRefresh().finally(() => {
|
|
117
|
-
this.inFlight = void 0;
|
|
118
|
-
});
|
|
119
|
-
await this.inFlight;
|
|
126
|
+
if (this.resolver) await this.resolver.forceRefresh();
|
|
127
|
+
else await this.confirmedResolver();
|
|
120
128
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
...this.snapshot,
|
|
132
|
-
...fetched.etag && { etag: fetched.etag },
|
|
133
|
-
fetchedAt: this.now(),
|
|
134
|
-
expiresAt: this.now() + computeLifetime(fetched.cacheControl, this.maxAge)
|
|
135
|
-
};
|
|
136
|
-
return;
|
|
129
|
+
}
|
|
130
|
+
function inferOnboardingAgentUrl(document, selector) {
|
|
131
|
+
const record = document;
|
|
132
|
+
const candidates = (agents) => !Array.isArray(agents) ? [] : agents.filter(
|
|
133
|
+
(entry) => entry?.type === selector.agentType && (selector.agentId === void 0 || entry.id === selector.agentId) && typeof entry.url === "string"
|
|
134
|
+
).flatMap((entry) => {
|
|
135
|
+
try {
|
|
136
|
+
return [(0, import_select_agent.canonicalAgentUrl)(entry.url)];
|
|
137
|
+
} catch {
|
|
138
|
+
return [];
|
|
137
139
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
140
|
+
});
|
|
141
|
+
let urls;
|
|
142
|
+
if (isPortfolioHouse(record.house)) {
|
|
143
|
+
const house = record.house;
|
|
144
|
+
urls = [];
|
|
145
|
+
if (selector.brandId !== void 0 && Array.isArray(record.brands)) {
|
|
146
|
+
const brands = record.brands.filter((brand) => brand?.id === selector.brandId);
|
|
147
|
+
if (brands.length > 1)
|
|
148
|
+
throw new BrandJsonResolverError("agent_ambiguous", "Onboarding brand selector is ambiguous.");
|
|
149
|
+
urls = candidates(brands[0]?.agents);
|
|
146
150
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
151
|
+
if (urls.length === 0) urls = candidates(house.agents);
|
|
152
|
+
} else urls = candidates(record.agents);
|
|
153
|
+
const unique = [...new Set(urls)];
|
|
154
|
+
if (unique.length !== 1)
|
|
155
|
+
throw new BrandJsonResolverError(
|
|
156
|
+
unique.length === 0 ? "agent_not_found" : "agent_ambiguous",
|
|
157
|
+
"Onboarding must identify exactly one agent URL; supply agentUrl explicitly."
|
|
158
|
+
);
|
|
159
|
+
return unique[0];
|
|
155
160
|
}
|
|
156
161
|
const MAX_BRAND_JSON_TIMEOUT_MS = 1e4;
|
|
157
162
|
const MAX_BRAND_JSON_BODY_BYTES = 262144;
|
|
@@ -172,6 +177,8 @@ async function fetchBrandJson(args) {
|
|
|
172
177
|
const allowPrivateIp = args.allowPrivateIp === true;
|
|
173
178
|
const seen = /* @__PURE__ */ new Set();
|
|
174
179
|
let url = canonicalizeUrl(args.startUrl, allowPrivateIp);
|
|
180
|
+
const initial = new URL(url);
|
|
181
|
+
let httpRedirects = 0;
|
|
175
182
|
for (let hop = 0; hop <= maxRedirects; hop++) {
|
|
176
183
|
if (seen.has(url)) {
|
|
177
184
|
throw new BrandJsonResolverError("redirect_loop", `brand.json redirect loop detected`);
|
|
@@ -194,6 +201,19 @@ async function fetchBrandJson(args) {
|
|
|
194
201
|
} catch (cause) {
|
|
195
202
|
throw new BrandJsonResolverError("fetch_failed", "Unable to fetch brand.json", { cause });
|
|
196
203
|
}
|
|
204
|
+
if (args.domainDerived && hop === 0 && [301, 302, 303, 307, 308].includes(res.status)) {
|
|
205
|
+
const location = res.headers.location;
|
|
206
|
+
if (!location || httpRedirects++ >= 3)
|
|
207
|
+
throw new BrandJsonResolverError("fetch_failed", "Invalid domain-derived redirect");
|
|
208
|
+
const target = new URL(location, url);
|
|
209
|
+
const baseHost = initial.hostname.startsWith("www.") ? initial.hostname.slice(4) : initial.hostname;
|
|
210
|
+
if (target.hostname !== baseHost && target.hostname !== `www.${baseHost}` || target.port !== initial.port || target.protocol !== initial.protocol || target.username || target.password) {
|
|
211
|
+
throw new BrandJsonResolverError("invalid_url", "brand.json redirect leaves its original host/www boundary");
|
|
212
|
+
}
|
|
213
|
+
url = canonicalizeUrl(target.href, allowPrivateIp);
|
|
214
|
+
hop--;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
197
217
|
if (hop === 0 && res.status === 304) {
|
|
198
218
|
return {
|
|
199
219
|
status: "not_modified",
|
|
@@ -211,7 +231,7 @@ async function fetchBrandJson(args) {
|
|
|
211
231
|
const text = Buffer.from(res.body).toString("utf8");
|
|
212
232
|
let parsed;
|
|
213
233
|
try {
|
|
214
|
-
parsed =
|
|
234
|
+
parsed = (0, import_strict_json.parseStrictJson)(text);
|
|
215
235
|
} catch {
|
|
216
236
|
throw new BrandJsonResolverError("invalid_body", `brand.json response is not valid JSON`);
|
|
217
237
|
}
|
|
@@ -303,88 +323,6 @@ function assertBrandJsonShape(obj) {
|
|
|
303
323
|
}
|
|
304
324
|
}
|
|
305
325
|
}
|
|
306
|
-
function selectAgent(data, finalBrandUrl, selector) {
|
|
307
|
-
if (!data || typeof data !== "object") {
|
|
308
|
-
throw new BrandJsonResolverError(
|
|
309
|
-
"agent_not_found",
|
|
310
|
-
`brand.json has no agent matching ${describeSelector(selector)}`
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
const obj = data;
|
|
314
|
-
let picked;
|
|
315
|
-
if (isPortfolioHouse(obj.house)) {
|
|
316
|
-
const house = obj.house;
|
|
317
|
-
if (selector.brandId !== void 0) {
|
|
318
|
-
const brands = Array.isArray(obj.brands) ? obj.brands : [];
|
|
319
|
-
const brand = brands.find((b) => b && b.id === selector.brandId);
|
|
320
|
-
if (brand) picked = pickAgent(brand.agents, finalBrandUrl, selector);
|
|
321
|
-
}
|
|
322
|
-
picked ??= pickAgent(house.agents, finalBrandUrl, selector);
|
|
323
|
-
} else {
|
|
324
|
-
picked = pickAgent(obj.agents, finalBrandUrl, selector);
|
|
325
|
-
}
|
|
326
|
-
if (!picked) {
|
|
327
|
-
throw new BrandJsonResolverError(
|
|
328
|
-
"agent_not_found",
|
|
329
|
-
`brand.json has no agent matching ${describeSelector(selector)}`
|
|
330
|
-
);
|
|
331
|
-
}
|
|
332
|
-
return picked;
|
|
333
|
-
}
|
|
334
|
-
function pickAgent(agents, finalBrandUrl, selector) {
|
|
335
|
-
if (!Array.isArray(agents)) return void 0;
|
|
336
|
-
const matches = agents.filter((a) => {
|
|
337
|
-
if (!a || typeof a !== "object") return false;
|
|
338
|
-
const e = a;
|
|
339
|
-
if (e.type !== selector.agentType) return false;
|
|
340
|
-
if (selector.agentId !== void 0 && e.id !== selector.agentId) return false;
|
|
341
|
-
return typeof e.url === "string";
|
|
342
|
-
});
|
|
343
|
-
if (matches.length === 0) return void 0;
|
|
344
|
-
if (matches.length > 1 && selector.agentId === void 0) {
|
|
345
|
-
throw new BrandJsonResolverError(
|
|
346
|
-
"agent_ambiguous",
|
|
347
|
-
`brand.json declares ${matches.length} agents of type "${selector.agentType}"; pass \`agentId\` to disambiguate (choices: ${matches.map((m) => m.id ?? "<no-id>").join(", ")})`
|
|
348
|
-
);
|
|
349
|
-
}
|
|
350
|
-
const agent = matches[0];
|
|
351
|
-
const url = agent.url;
|
|
352
|
-
const jwksUri = agent.jwks_uri ?? defaultJwksUri(url, finalBrandUrl);
|
|
353
|
-
return { url, jwksUri };
|
|
354
|
-
}
|
|
355
|
-
function defaultJwksUri(agentUrl, finalBrandUrl) {
|
|
356
|
-
let agent;
|
|
357
|
-
try {
|
|
358
|
-
agent = new URL(agentUrl);
|
|
359
|
-
} catch {
|
|
360
|
-
throw new BrandJsonResolverError("invalid_url", `agent.url is not a valid URL`);
|
|
361
|
-
}
|
|
362
|
-
const brand = new URL(finalBrandUrl);
|
|
363
|
-
if (agent.origin !== brand.origin) {
|
|
364
|
-
throw new BrandJsonResolverError(
|
|
365
|
-
"jwks_origin_mismatch",
|
|
366
|
-
`agent.url origin (${agent.origin}) does not match brand.json origin (${brand.origin}); publisher must declare an explicit jwks_uri for cross-origin agents`
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
return `${agent.origin}/.well-known/jwks.json`;
|
|
370
|
-
}
|
|
371
|
-
function describeSelector(selector) {
|
|
372
|
-
const parts = [`type=${selector.agentType}`];
|
|
373
|
-
if (selector.agentId !== void 0) parts.push(`id=${selector.agentId}`);
|
|
374
|
-
if (selector.brandId !== void 0) parts.push(`brand=${selector.brandId}`);
|
|
375
|
-
return parts.join(" ");
|
|
376
|
-
}
|
|
377
|
-
function computeLifetime(cacheControl, maxAge) {
|
|
378
|
-
if (!cacheControl) return maxAge;
|
|
379
|
-
const lower = cacheControl.toLowerCase();
|
|
380
|
-
if (/\bno-store\b|\bno-cache\b/.test(lower)) return 0;
|
|
381
|
-
const match = /max-age\s*=\s*(\d+)/.exec(lower);
|
|
382
|
-
if (match) {
|
|
383
|
-
const serverMax = Number(match[1]);
|
|
384
|
-
if (Number.isFinite(serverMax)) return Math.min(serverMax, maxAge);
|
|
385
|
-
}
|
|
386
|
-
return maxAge;
|
|
387
|
-
}
|
|
388
326
|
// Annotate the CommonJS export names for ESM import in node:
|
|
389
327
|
0 && (module.exports = {
|
|
390
328
|
BrandJsonJwksResolver,
|