@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,17 @@ class ResolvedAgentJwksResolver {
|
|
|
23
23
|
cacheTtlSeconds;
|
|
24
24
|
unknownKidCooldownSeconds;
|
|
25
25
|
resolveAgentFn;
|
|
26
|
+
canonicalAgentUrl;
|
|
27
|
+
legacyWebhookFallback;
|
|
28
|
+
operatorRecord;
|
|
29
|
+
get resolvedAgentUrl() {
|
|
30
|
+
return this.canonicalAgentUrl;
|
|
31
|
+
}
|
|
26
32
|
keys = /* @__PURE__ */ new Map();
|
|
27
33
|
expiresAt = 0;
|
|
28
34
|
operatorAuthorizationValidUntil;
|
|
29
35
|
lastUnknownKidRefresh = Number.NEGATIVE_INFINITY;
|
|
36
|
+
lastDiscoveryAttemptAt = Number.NEGATIVE_INFINITY;
|
|
30
37
|
inFlight;
|
|
31
38
|
async resolve(keyid) {
|
|
32
39
|
return (await this.resolveWithMetadata(keyid)).jwk;
|
|
@@ -35,6 +42,15 @@ class ResolvedAgentJwksResolver {
|
|
|
35
42
|
const now = this.now();
|
|
36
43
|
let refreshed = false;
|
|
37
44
|
if (now >= this.expiresAt) {
|
|
45
|
+
if (!this.inFlight && now - this.lastDiscoveryAttemptAt < 30) {
|
|
46
|
+
const expiredAuthorization = this.operatorAuthorizationValidUntil !== void 0 && now >= this.operatorAuthorizationValidUntil;
|
|
47
|
+
throw new AgentResolverError(
|
|
48
|
+
expiredAuthorization ? "request_signature_brand_origin_mismatch" : "request_signature_brand_json_unreachable",
|
|
49
|
+
"Expired operator mapping cannot be used during the discovery cooldown",
|
|
50
|
+
{ agent_url: this.agentUrl },
|
|
51
|
+
["agent_url"]
|
|
52
|
+
);
|
|
53
|
+
}
|
|
38
54
|
await this.refresh();
|
|
39
55
|
refreshed = true;
|
|
40
56
|
}
|
|
@@ -44,14 +60,22 @@ class ResolvedAgentJwksResolver {
|
|
|
44
60
|
this.lastUnknownKidRefresh = now;
|
|
45
61
|
return this.resolution(null);
|
|
46
62
|
}
|
|
47
|
-
if (now - this.lastUnknownKidRefresh
|
|
63
|
+
if (now - Math.max(this.lastUnknownKidRefresh, this.lastDiscoveryAttemptAt) < Math.max(30, this.unknownKidCooldownSeconds))
|
|
64
|
+
return this.resolution(null);
|
|
48
65
|
await this.refresh();
|
|
49
66
|
this.lastUnknownKidRefresh = now;
|
|
50
67
|
return this.resolution(this.keys.get(keyid) ?? null);
|
|
51
68
|
}
|
|
69
|
+
async forceRefresh() {
|
|
70
|
+
this.expiresAt = 0;
|
|
71
|
+
await this.refresh();
|
|
72
|
+
}
|
|
52
73
|
resolution(jwk) {
|
|
53
74
|
return {
|
|
54
75
|
jwk,
|
|
76
|
+
...this.operatorRecord !== void 0 && { operatorRecord: this.operatorRecord },
|
|
77
|
+
...this.legacyWebhookFallback && { legacyWebhookFallback: true },
|
|
78
|
+
...this.resolvedAgentUrl !== void 0 && { agentUrl: this.resolvedAgentUrl },
|
|
55
79
|
...this.operatorAuthorizationValidUntil !== void 0 && {
|
|
56
80
|
operatorAuthorizationValidUntil: this.operatorAuthorizationValidUntil
|
|
57
81
|
}
|
|
@@ -59,23 +83,11 @@ class ResolvedAgentJwksResolver {
|
|
|
59
83
|
}
|
|
60
84
|
async refresh() {
|
|
61
85
|
if (this.inFlight) return this.inFlight;
|
|
86
|
+
this.lastDiscoveryAttemptAt = this.now();
|
|
62
87
|
this.inFlight = (async () => {
|
|
63
88
|
const resolution = await this.resolveAgentFn(this.agentUrl, {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
...this.options.allowPrivateIp !== void 0 && { allowPrivateIp: this.options.allowPrivateIp },
|
|
67
|
-
...this.options.bodyCaps && { bodyCaps: this.options.bodyCaps },
|
|
68
|
-
...this.options.timeoutMs !== void 0 && { timeoutMs: this.options.timeoutMs },
|
|
69
|
-
...this.options.now && { now: this.options.now },
|
|
70
|
-
...this.options.requiredOperatorBrand !== void 0 && {
|
|
71
|
-
requiredOperatorBrand: this.options.requiredOperatorBrand
|
|
72
|
-
},
|
|
73
|
-
...this.options.requiredOperatorScope !== void 0 && {
|
|
74
|
-
requiredOperatorScope: this.options.requiredOperatorScope
|
|
75
|
-
},
|
|
76
|
-
...this.options.requiredOperatorCountry !== void 0 && {
|
|
77
|
-
requiredOperatorCountry: this.options.requiredOperatorCountry
|
|
78
|
-
}
|
|
89
|
+
...this.options,
|
|
90
|
+
protocol: this.protocol
|
|
79
91
|
});
|
|
80
92
|
const refreshedAt = this.now();
|
|
81
93
|
if (resolution.operatorAuthorizationValidUntil !== void 0 && refreshedAt >= resolution.operatorAuthorizationValidUntil) {
|
|
@@ -89,13 +101,28 @@ class ResolvedAgentJwksResolver {
|
|
|
89
101
|
const next = /* @__PURE__ */ new Map();
|
|
90
102
|
for (const candidate of resolution.jwks.keys) {
|
|
91
103
|
if (candidate && typeof candidate === "object" && typeof candidate.kid === "string") {
|
|
104
|
+
if (next.has(candidate.kid))
|
|
105
|
+
throw new AgentResolverError(
|
|
106
|
+
"request_signature_key_unknown",
|
|
107
|
+
"JWKS has duplicate key identifiers",
|
|
108
|
+
{ agent_url: this.agentUrl },
|
|
109
|
+
["agent_url"]
|
|
110
|
+
);
|
|
92
111
|
next.set(candidate.kid, candidate);
|
|
93
112
|
}
|
|
94
113
|
}
|
|
95
114
|
this.keys = next;
|
|
115
|
+
this.canonicalAgentUrl = resolution.agentUrl;
|
|
116
|
+
this.operatorRecord = resolution.brandJson === void 0 ? void 0 : { url: resolution.brandJsonUrl, document: resolution.brandJson };
|
|
117
|
+
this.legacyWebhookFallback = resolution.legacyWebhookFallback;
|
|
96
118
|
this.operatorAuthorizationValidUntil = resolution.operatorAuthorizationValidUntil;
|
|
97
119
|
this.expiresAt = Math.min(
|
|
98
|
-
refreshedAt +
|
|
120
|
+
refreshedAt + Math.min(
|
|
121
|
+
this.cacheTtlSeconds,
|
|
122
|
+
1800,
|
|
123
|
+
Math.max(30, cacheLifetime(resolution.brandJsonCacheControl)),
|
|
124
|
+
Math.max(60, cacheLifetime(resolution.jwksCacheControl))
|
|
125
|
+
),
|
|
99
126
|
resolution.operatorAuthorizationValidUntil ?? Number.POSITIVE_INFINITY
|
|
100
127
|
);
|
|
101
128
|
})().finally(() => {
|
|
@@ -104,6 +131,12 @@ class ResolvedAgentJwksResolver {
|
|
|
104
131
|
return this.inFlight;
|
|
105
132
|
}
|
|
106
133
|
}
|
|
134
|
+
function cacheLifetime(cacheControl) {
|
|
135
|
+
if (!cacheControl) return Infinity;
|
|
136
|
+
if (/\bno-cache\b|\bno-store\b/i.test(cacheControl)) return 0;
|
|
137
|
+
const match = /(?:^|,)\s*max-age\s*=\s*"?(\d+)/i.exec(cacheControl);
|
|
138
|
+
return match ? Number(match[1]) : Infinity;
|
|
139
|
+
}
|
|
107
140
|
export {
|
|
108
141
|
ResolvedAgentJwksResolver
|
|
109
142
|
};
|
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
* `agents[]` entry whose `url` byte-equals the agent URL the verifier is
|
|
4
|
-
* resolving. The byte-equal rule is deliberate (security.mdx §"Discovering
|
|
5
|
-
* an agent's signing keys via `brand_json_url`" step 5) — no canonicalization,
|
|
6
|
-
* because the most common operator misconfiguration is a trailing-slash or
|
|
7
|
-
* scheme mismatch (`https://x.com/mcp` vs `https://x.com/mcp/`), and silently
|
|
8
|
-
* canonicalizing past that hides the bug. The match must be exact.
|
|
9
|
-
*
|
|
10
|
-
* Both flat (`agents[]` at top level) and house-portfolio
|
|
11
|
-
* (`house.agents[]` + `brands[].agents[]`) brand.json shapes are supported,
|
|
12
|
-
* because either may carry the entry that matches the agent URL.
|
|
13
|
-
*/
|
|
1
|
+
/** Shared identifier rules, including query escapes (unlike the signing profile's raw query). */
|
|
2
|
+
export declare function canonicalAgentUrl(raw: string): string;
|
|
14
3
|
export type AgentSelectorErrorCode = 'agent_not_in_brand_json' | 'brand_json_ambiguous';
|
|
15
4
|
export interface AgentEntry {
|
|
16
5
|
url: string;
|
|
@@ -18,6 +7,12 @@ export interface AgentEntry {
|
|
|
18
7
|
/** Other fields preserved verbatim — the resolver passes the entry to the caller. */
|
|
19
8
|
[key: string]: unknown;
|
|
20
9
|
}
|
|
10
|
+
export interface AgentSelector {
|
|
11
|
+
agentType?: string;
|
|
12
|
+
agentId?: string;
|
|
13
|
+
}
|
|
14
|
+
/** The key source always belongs to the matched entry, never to the artifact. */
|
|
15
|
+
export declare function agentJwksUri(entry: AgentEntry): string;
|
|
21
16
|
export declare class AgentSelectorError extends Error {
|
|
22
17
|
readonly code: AgentSelectorErrorCode;
|
|
23
18
|
readonly detail: {
|
|
@@ -40,7 +35,9 @@ export declare class AgentSelectorError extends Error {
|
|
|
40
35
|
*/
|
|
41
36
|
export declare function collectAgentEntries(brandJson: unknown): AgentEntry[];
|
|
42
37
|
/**
|
|
43
|
-
* Find the unique
|
|
38
|
+
* Find the unique canonical match. Portfolio repetitions across collections
|
|
39
|
+
* count once when their type and canonical JWKS source agree. Duplicates
|
|
40
|
+
* within one collection remain ambiguous. Type/id only narrow URL matches.
|
|
44
41
|
*
|
|
45
42
|
* - Returns the matched entry on a unique hit.
|
|
46
43
|
* - Throws `AgentSelectorError('agent_not_in_brand_json')` on zero matches.
|
|
@@ -50,4 +47,6 @@ export declare function collectAgentEntries(brandJson: unknown): AgentEntry[];
|
|
|
50
47
|
* fields. `matched_entries` reflects counterparty-controlled state and is
|
|
51
48
|
* marked attacker-influenceable in the resolver's error mapping.
|
|
52
49
|
*/
|
|
53
|
-
export declare function selectAgentByUrl(brandJson: unknown, agentUrl: string): AgentEntry;
|
|
50
|
+
export declare function selectAgentByUrl(brandJson: unknown, agentUrl: string, selector?: AgentSelector): AgentEntry;
|
|
51
|
+
/** Select a relying party's collection without incorporating sibling brands. */
|
|
52
|
+
export declare function relyingPartyAgentRecord(brandJson: unknown, brandDomain: string): unknown;
|
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
* `agents[]` entry whose `url` byte-equals the agent URL the verifier is
|
|
4
|
-
* resolving. The byte-equal rule is deliberate (security.mdx §"Discovering
|
|
5
|
-
* an agent's signing keys via `brand_json_url`" step 5) — no canonicalization,
|
|
6
|
-
* because the most common operator misconfiguration is a trailing-slash or
|
|
7
|
-
* scheme mismatch (`https://x.com/mcp` vs `https://x.com/mcp/`), and silently
|
|
8
|
-
* canonicalizing past that hides the bug. The match must be exact.
|
|
9
|
-
*
|
|
10
|
-
* Both flat (`agents[]` at top level) and house-portfolio
|
|
11
|
-
* (`house.agents[]` + `brands[].agents[]`) brand.json shapes are supported,
|
|
12
|
-
* because either may carry the entry that matches the agent URL.
|
|
13
|
-
*/
|
|
1
|
+
/** Shared identifier rules, including query escapes (unlike the signing profile's raw query). */
|
|
2
|
+
export declare function canonicalAgentUrl(raw: string): string;
|
|
14
3
|
export type AgentSelectorErrorCode = 'agent_not_in_brand_json' | 'brand_json_ambiguous';
|
|
15
4
|
export interface AgentEntry {
|
|
16
5
|
url: string;
|
|
@@ -18,6 +7,12 @@ export interface AgentEntry {
|
|
|
18
7
|
/** Other fields preserved verbatim — the resolver passes the entry to the caller. */
|
|
19
8
|
[key: string]: unknown;
|
|
20
9
|
}
|
|
10
|
+
export interface AgentSelector {
|
|
11
|
+
agentType?: string;
|
|
12
|
+
agentId?: string;
|
|
13
|
+
}
|
|
14
|
+
/** The key source always belongs to the matched entry, never to the artifact. */
|
|
15
|
+
export declare function agentJwksUri(entry: AgentEntry): string;
|
|
21
16
|
export declare class AgentSelectorError extends Error {
|
|
22
17
|
readonly code: AgentSelectorErrorCode;
|
|
23
18
|
readonly detail: {
|
|
@@ -40,7 +35,9 @@ export declare class AgentSelectorError extends Error {
|
|
|
40
35
|
*/
|
|
41
36
|
export declare function collectAgentEntries(brandJson: unknown): AgentEntry[];
|
|
42
37
|
/**
|
|
43
|
-
* Find the unique
|
|
38
|
+
* Find the unique canonical match. Portfolio repetitions across collections
|
|
39
|
+
* count once when their type and canonical JWKS source agree. Duplicates
|
|
40
|
+
* within one collection remain ambiguous. Type/id only narrow URL matches.
|
|
44
41
|
*
|
|
45
42
|
* - Returns the matched entry on a unique hit.
|
|
46
43
|
* - Throws `AgentSelectorError('agent_not_in_brand_json')` on zero matches.
|
|
@@ -50,4 +47,6 @@ export declare function collectAgentEntries(brandJson: unknown): AgentEntry[];
|
|
|
50
47
|
* fields. `matched_entries` reflects counterparty-controlled state and is
|
|
51
48
|
* marked attacker-influenceable in the resolver's error mapping.
|
|
52
49
|
*/
|
|
53
|
-
export declare function selectAgentByUrl(brandJson: unknown, agentUrl: string): AgentEntry;
|
|
50
|
+
export declare function selectAgentByUrl(brandJson: unknown, agentUrl: string, selector?: AgentSelector): AgentEntry;
|
|
51
|
+
/** Select a relying party's collection without incorporating sibling brands. */
|
|
52
|
+
export declare function relyingPartyAgentRecord(brandJson: unknown, brandDomain: string): unknown;
|
|
@@ -19,10 +19,34 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var select_agent_exports = {};
|
|
20
20
|
__export(select_agent_exports, {
|
|
21
21
|
AgentSelectorError: () => AgentSelectorError,
|
|
22
|
+
agentJwksUri: () => agentJwksUri,
|
|
23
|
+
canonicalAgentUrl: () => canonicalAgentUrl,
|
|
22
24
|
collectAgentEntries: () => collectAgentEntries,
|
|
25
|
+
relyingPartyAgentRecord: () => relyingPartyAgentRecord,
|
|
23
26
|
selectAgentByUrl: () => selectAgentByUrl
|
|
24
27
|
});
|
|
25
28
|
module.exports = __toCommonJS(select_agent_exports);
|
|
29
|
+
var import_canonicalize = require('../canonicalize.js');
|
|
30
|
+
function canonicalAgentUrl(raw) {
|
|
31
|
+
const authority = /^[a-z][a-z0-9+.\-]*:\/\/([^/?#]*)/i.exec(raw)?.[1];
|
|
32
|
+
if (authority) (0, import_canonicalize.rejectNonAsciiHost)(`https://${authority.slice(authority.lastIndexOf("@") + 1)}`);
|
|
33
|
+
const canonical = (0, import_canonicalize.canonicalTargetUri)(raw, "3.2");
|
|
34
|
+
if (!/^https?:\/\//.test(canonical)) throw new TypeError("Agent identifier must be an HTTP(S) URL");
|
|
35
|
+
return canonical.replace(/%([0-9a-f]{2})/gi, (_escape, hex) => {
|
|
36
|
+
const character = String.fromCharCode(parseInt(hex, 16));
|
|
37
|
+
return /^[a-z0-9._~-]$/i.test(character) ? character : `%${hex.toUpperCase()}`;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function agentJwksUri(entry) {
|
|
41
|
+
if (entry.jwks_uri !== void 0) {
|
|
42
|
+
if (typeof entry.jwks_uri !== "string" || !entry.jwks_uri) throw new TypeError("Invalid jwks_uri");
|
|
43
|
+
const source = new URL(entry.jwks_uri);
|
|
44
|
+
if (source.username || source.password) throw new TypeError("JWKS URI must not contain userinfo");
|
|
45
|
+
canonicalAgentUrl(entry.jwks_uri);
|
|
46
|
+
return entry.jwks_uri;
|
|
47
|
+
}
|
|
48
|
+
return `${new URL(canonicalAgentUrl(entry.url)).origin}/.well-known/jwks.json`;
|
|
49
|
+
}
|
|
26
50
|
class AgentSelectorError extends Error {
|
|
27
51
|
code;
|
|
28
52
|
detail;
|
|
@@ -34,22 +58,31 @@ class AgentSelectorError extends Error {
|
|
|
34
58
|
}
|
|
35
59
|
}
|
|
36
60
|
function collectAgentEntries(brandJson) {
|
|
61
|
+
return agentCollections(brandJson).flat();
|
|
62
|
+
}
|
|
63
|
+
function agentCollections(brandJson) {
|
|
37
64
|
if (!brandJson || typeof brandJson !== "object") return [];
|
|
38
|
-
const
|
|
65
|
+
const collections = [];
|
|
39
66
|
const obj = brandJson;
|
|
40
|
-
|
|
67
|
+
const add = (value) => {
|
|
68
|
+
const entries = [];
|
|
69
|
+
pushAgentArray(value, entries);
|
|
70
|
+
collections.push(entries);
|
|
71
|
+
};
|
|
72
|
+
if (obj.agents !== void 0) {
|
|
73
|
+
add(obj.agents);
|
|
74
|
+
return collections;
|
|
75
|
+
}
|
|
41
76
|
const house = obj.house;
|
|
42
77
|
if (house && typeof house === "object") {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (brand && typeof brand === "object") {
|
|
48
|
-
pushAgentArray(brand.agents, entries);
|
|
78
|
+
add(house.agents);
|
|
79
|
+
if (Array.isArray(obj.brands)) {
|
|
80
|
+
for (const brand of obj.brands) {
|
|
81
|
+
if (brand && typeof brand === "object") add(brand.agents);
|
|
49
82
|
}
|
|
50
83
|
}
|
|
51
84
|
}
|
|
52
|
-
return
|
|
85
|
+
return collections;
|
|
53
86
|
}
|
|
54
87
|
function pushAgentArray(value, out) {
|
|
55
88
|
if (!Array.isArray(value)) return;
|
|
@@ -62,13 +95,37 @@ function pushAgentArray(value, out) {
|
|
|
62
95
|
}
|
|
63
96
|
}
|
|
64
97
|
}
|
|
65
|
-
function selectAgentByUrl(brandJson, agentUrl) {
|
|
66
|
-
const
|
|
67
|
-
const matches =
|
|
98
|
+
function selectAgentByUrl(brandJson, agentUrl, selector = {}) {
|
|
99
|
+
const canonicalUrl = canonicalAgentUrl(agentUrl);
|
|
100
|
+
const matches = [];
|
|
101
|
+
const seen = /* @__PURE__ */ new Set();
|
|
102
|
+
for (const collection of agentCollections(brandJson)) {
|
|
103
|
+
const local = collection.filter((e) => {
|
|
104
|
+
try {
|
|
105
|
+
return canonicalAgentUrl(e.url) === canonicalUrl && (selector.agentType === void 0 || e.type === selector.agentType) && (selector.agentId === void 0 || e.id === selector.agentId);
|
|
106
|
+
} catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
if (local.length > 1) {
|
|
111
|
+
throw new AgentSelectorError("brand_json_ambiguous", `Multiple brand.json agent entries match ${agentUrl}`, {
|
|
112
|
+
agent_url: agentUrl,
|
|
113
|
+
matched_count: local.length,
|
|
114
|
+
matched_entries: local
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
for (const entry of local) {
|
|
118
|
+
const source = JSON.stringify([entry.type, canonicalAgentUrl(agentJwksUri(entry))]);
|
|
119
|
+
if (!seen.has(source)) {
|
|
120
|
+
seen.add(source);
|
|
121
|
+
matches.push(entry);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
68
125
|
if (matches.length === 0) {
|
|
69
126
|
throw new AgentSelectorError(
|
|
70
127
|
"agent_not_in_brand_json",
|
|
71
|
-
`No brand.json agent entry has
|
|
128
|
+
`No brand.json agent entry has canonical URL ${canonicalUrl}`,
|
|
72
129
|
{ agent_url: agentUrl }
|
|
73
130
|
);
|
|
74
131
|
}
|
|
@@ -81,9 +138,37 @@ function selectAgentByUrl(brandJson, agentUrl) {
|
|
|
81
138
|
}
|
|
82
139
|
return matches[0];
|
|
83
140
|
}
|
|
141
|
+
function relyingPartyAgentRecord(brandJson, brandDomain) {
|
|
142
|
+
if (!brandJson || typeof brandJson !== "object") throw new TypeError("Invalid brand.json");
|
|
143
|
+
const obj = brandJson;
|
|
144
|
+
if (!obj.house || typeof obj.house !== "object") return obj;
|
|
145
|
+
const domainHost = (domain) => {
|
|
146
|
+
if (typeof domain !== "string" || !/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*\.?$/i.test(domain))
|
|
147
|
+
throw new TypeError("Invalid brand domain");
|
|
148
|
+
return new URL(canonicalAgentUrl(`https://${domain}`)).hostname;
|
|
149
|
+
};
|
|
150
|
+
const host = domainHost(brandDomain);
|
|
151
|
+
const house = obj.house;
|
|
152
|
+
if (house.domain !== void 0 && domainHost(house.domain) === host) {
|
|
153
|
+
return { agents: house.agents };
|
|
154
|
+
}
|
|
155
|
+
const brands = Array.isArray(obj.brands) ? obj.brands : [];
|
|
156
|
+
const matches = brands.filter((b) => {
|
|
157
|
+
try {
|
|
158
|
+
return b && typeof b === "object" && typeof b.url === "string" && new URL(canonicalAgentUrl(b.url)).hostname === host;
|
|
159
|
+
} catch {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
if (matches.length !== 1) throw new TypeError("Brand domain is absent or ambiguous in portfolio");
|
|
164
|
+
return { agents: matches[0].agents === void 0 ? house.agents : matches[0].agents };
|
|
165
|
+
}
|
|
84
166
|
// Annotate the CommonJS export names for ESM import in node:
|
|
85
167
|
0 && (module.exports = {
|
|
86
168
|
AgentSelectorError,
|
|
169
|
+
agentJwksUri,
|
|
170
|
+
canonicalAgentUrl,
|
|
87
171
|
collectAgentEntries,
|
|
172
|
+
relyingPartyAgentRecord,
|
|
88
173
|
selectAgentByUrl
|
|
89
174
|
});
|
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
import { canonicalTargetUri, rejectNonAsciiHost } from "../canonicalize.mjs";
|
|
2
|
+
function canonicalAgentUrl(raw) {
|
|
3
|
+
const authority = /^[a-z][a-z0-9+.\-]*:\/\/([^/?#]*)/i.exec(raw)?.[1];
|
|
4
|
+
if (authority) rejectNonAsciiHost(`https://${authority.slice(authority.lastIndexOf("@") + 1)}`);
|
|
5
|
+
const canonical = canonicalTargetUri(raw, "3.2");
|
|
6
|
+
if (!/^https?:\/\//.test(canonical)) throw new TypeError("Agent identifier must be an HTTP(S) URL");
|
|
7
|
+
return canonical.replace(/%([0-9a-f]{2})/gi, (_escape, hex) => {
|
|
8
|
+
const character = String.fromCharCode(parseInt(hex, 16));
|
|
9
|
+
return /^[a-z0-9._~-]$/i.test(character) ? character : `%${hex.toUpperCase()}`;
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function agentJwksUri(entry) {
|
|
13
|
+
if (entry.jwks_uri !== void 0) {
|
|
14
|
+
if (typeof entry.jwks_uri !== "string" || !entry.jwks_uri) throw new TypeError("Invalid jwks_uri");
|
|
15
|
+
const source = new URL(entry.jwks_uri);
|
|
16
|
+
if (source.username || source.password) throw new TypeError("JWKS URI must not contain userinfo");
|
|
17
|
+
canonicalAgentUrl(entry.jwks_uri);
|
|
18
|
+
return entry.jwks_uri;
|
|
19
|
+
}
|
|
20
|
+
return `${new URL(canonicalAgentUrl(entry.url)).origin}/.well-known/jwks.json`;
|
|
21
|
+
}
|
|
1
22
|
class AgentSelectorError extends Error {
|
|
2
23
|
code;
|
|
3
24
|
detail;
|
|
@@ -9,22 +30,31 @@ class AgentSelectorError extends Error {
|
|
|
9
30
|
}
|
|
10
31
|
}
|
|
11
32
|
function collectAgentEntries(brandJson) {
|
|
33
|
+
return agentCollections(brandJson).flat();
|
|
34
|
+
}
|
|
35
|
+
function agentCollections(brandJson) {
|
|
12
36
|
if (!brandJson || typeof brandJson !== "object") return [];
|
|
13
|
-
const
|
|
37
|
+
const collections = [];
|
|
14
38
|
const obj = brandJson;
|
|
15
|
-
|
|
39
|
+
const add = (value) => {
|
|
40
|
+
const entries = [];
|
|
41
|
+
pushAgentArray(value, entries);
|
|
42
|
+
collections.push(entries);
|
|
43
|
+
};
|
|
44
|
+
if (obj.agents !== void 0) {
|
|
45
|
+
add(obj.agents);
|
|
46
|
+
return collections;
|
|
47
|
+
}
|
|
16
48
|
const house = obj.house;
|
|
17
49
|
if (house && typeof house === "object") {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (brand && typeof brand === "object") {
|
|
23
|
-
pushAgentArray(brand.agents, entries);
|
|
50
|
+
add(house.agents);
|
|
51
|
+
if (Array.isArray(obj.brands)) {
|
|
52
|
+
for (const brand of obj.brands) {
|
|
53
|
+
if (brand && typeof brand === "object") add(brand.agents);
|
|
24
54
|
}
|
|
25
55
|
}
|
|
26
56
|
}
|
|
27
|
-
return
|
|
57
|
+
return collections;
|
|
28
58
|
}
|
|
29
59
|
function pushAgentArray(value, out) {
|
|
30
60
|
if (!Array.isArray(value)) return;
|
|
@@ -37,13 +67,37 @@ function pushAgentArray(value, out) {
|
|
|
37
67
|
}
|
|
38
68
|
}
|
|
39
69
|
}
|
|
40
|
-
function selectAgentByUrl(brandJson, agentUrl) {
|
|
41
|
-
const
|
|
42
|
-
const matches =
|
|
70
|
+
function selectAgentByUrl(brandJson, agentUrl, selector = {}) {
|
|
71
|
+
const canonicalUrl = canonicalAgentUrl(agentUrl);
|
|
72
|
+
const matches = [];
|
|
73
|
+
const seen = /* @__PURE__ */ new Set();
|
|
74
|
+
for (const collection of agentCollections(brandJson)) {
|
|
75
|
+
const local = collection.filter((e) => {
|
|
76
|
+
try {
|
|
77
|
+
return canonicalAgentUrl(e.url) === canonicalUrl && (selector.agentType === void 0 || e.type === selector.agentType) && (selector.agentId === void 0 || e.id === selector.agentId);
|
|
78
|
+
} catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
if (local.length > 1) {
|
|
83
|
+
throw new AgentSelectorError("brand_json_ambiguous", `Multiple brand.json agent entries match ${agentUrl}`, {
|
|
84
|
+
agent_url: agentUrl,
|
|
85
|
+
matched_count: local.length,
|
|
86
|
+
matched_entries: local
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
for (const entry of local) {
|
|
90
|
+
const source = JSON.stringify([entry.type, canonicalAgentUrl(agentJwksUri(entry))]);
|
|
91
|
+
if (!seen.has(source)) {
|
|
92
|
+
seen.add(source);
|
|
93
|
+
matches.push(entry);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
43
97
|
if (matches.length === 0) {
|
|
44
98
|
throw new AgentSelectorError(
|
|
45
99
|
"agent_not_in_brand_json",
|
|
46
|
-
`No brand.json agent entry has
|
|
100
|
+
`No brand.json agent entry has canonical URL ${canonicalUrl}`,
|
|
47
101
|
{ agent_url: agentUrl }
|
|
48
102
|
);
|
|
49
103
|
}
|
|
@@ -56,8 +110,36 @@ function selectAgentByUrl(brandJson, agentUrl) {
|
|
|
56
110
|
}
|
|
57
111
|
return matches[0];
|
|
58
112
|
}
|
|
113
|
+
function relyingPartyAgentRecord(brandJson, brandDomain) {
|
|
114
|
+
if (!brandJson || typeof brandJson !== "object") throw new TypeError("Invalid brand.json");
|
|
115
|
+
const obj = brandJson;
|
|
116
|
+
if (!obj.house || typeof obj.house !== "object") return obj;
|
|
117
|
+
const domainHost = (domain) => {
|
|
118
|
+
if (typeof domain !== "string" || !/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*\.?$/i.test(domain))
|
|
119
|
+
throw new TypeError("Invalid brand domain");
|
|
120
|
+
return new URL(canonicalAgentUrl(`https://${domain}`)).hostname;
|
|
121
|
+
};
|
|
122
|
+
const host = domainHost(brandDomain);
|
|
123
|
+
const house = obj.house;
|
|
124
|
+
if (house.domain !== void 0 && domainHost(house.domain) === host) {
|
|
125
|
+
return { agents: house.agents };
|
|
126
|
+
}
|
|
127
|
+
const brands = Array.isArray(obj.brands) ? obj.brands : [];
|
|
128
|
+
const matches = brands.filter((b) => {
|
|
129
|
+
try {
|
|
130
|
+
return b && typeof b === "object" && typeof b.url === "string" && new URL(canonicalAgentUrl(b.url)).hostname === host;
|
|
131
|
+
} catch {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
if (matches.length !== 1) throw new TypeError("Brand domain is absent or ambiguous in portfolio");
|
|
136
|
+
return { agents: matches[0].agents === void 0 ? house.agents : matches[0].agents };
|
|
137
|
+
}
|
|
59
138
|
export {
|
|
60
139
|
AgentSelectorError,
|
|
140
|
+
agentJwksUri,
|
|
141
|
+
canonicalAgentUrl,
|
|
61
142
|
collectAgentEntries,
|
|
143
|
+
relyingPartyAgentRecord,
|
|
62
144
|
selectAgentByUrl
|
|
63
145
|
};
|