@adcp/sdk 14.0.0 → 14.1.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 +31 -1
- package/dist/lib/core/SingleAgentClient.d.ts +31 -1
- package/dist/lib/core/SingleAgentClient.js +355 -35
- package/dist/lib/core/SingleAgentClient.mjs +365 -37
- package/dist/lib/core/TaskExecutor.js +2 -1
- package/dist/lib/core/TaskExecutor.mjs +2 -1
- 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 +65 -0
- package/dist/lib/core/buyer-account-registry.d.ts +65 -0
- package/dist/lib/core/buyer-account-registry.js +518 -0
- package/dist/lib/core/buyer-account-registry.mjs +494 -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 +5 -3
- package/dist/lib/index.d.ts +5 -3
- package/dist/lib/index.js +20 -0
- package/dist/lib/index.mjs +19 -0
- 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 +1 -1
- package/dist/lib/signing/agent-resolver/errors.d.ts +1 -1
- package/dist/lib/signing/agent-resolver/fetch-helpers.d.mts +2 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.d.ts +2 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.js +2 -1
- package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +2 -1
- 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 +101 -132
- package/dist/lib/signing/agent-resolver/resolve-agent.mjs +102 -133
- 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 +27 -75
- package/dist/lib/signing/brand-jwks.d.ts +27 -75
- package/dist/lib/signing/brand-jwks.js +112 -182
- package/dist/lib/signing/brand-jwks.mjs +112 -182
- package/dist/lib/signing/errors.d.mts +3 -1
- package/dist/lib/signing/errors.d.ts +3 -1
- package/dist/lib/signing/errors.js +4 -1
- package/dist/lib/signing/errors.mjs +4 -1
- 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 +49 -4
- package/dist/lib/signing/verifier.mjs +49 -4
- 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 +43 -3
- 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/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/wholesale-feed-sync/sync.d.mts +1 -0
- package/dist/lib/wholesale-feed-sync/sync.d.ts +1 -0
- package/dist/lib/wholesale-feed-sync/sync.js +92 -21
- package/dist/lib/wholesale-feed-sync/sync.mjs +92 -21
- package/dist/lib/wholesale-feed-sync/types.d.mts +4 -3
- package/dist/lib/wholesale-feed-sync/types.d.ts +4 -3
- 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/FIRST-CALL-TO-A-SELLER.md +104 -0
- package/docs/guides/SIGNING-GUIDE.md +16 -7
- package/docs/guides/account-resolution.md +86 -0
- package/docs/llms.txt +3 -2
- 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 +123 -0
- package/docs/recipes/verifying-inbound-webhooks.md +56 -15
- package/package.json +2 -2
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var account_reference_warnings_exports = {};
|
|
20
|
+
__export(account_reference_warnings_exports, {
|
|
21
|
+
_resetAccountReferenceWarnings: () => _resetAccountReferenceWarnings,
|
|
22
|
+
warnAccountReferenceDeprecation: () => warnAccountReferenceDeprecation
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(account_reference_warnings_exports);
|
|
25
|
+
const warnedCodes = /* @__PURE__ */ new Set();
|
|
26
|
+
function warnAccountReferenceDeprecation(logger, code, message, meta = {}) {
|
|
27
|
+
const fields = { ...meta, code };
|
|
28
|
+
if (warnedCodes.has(code)) {
|
|
29
|
+
logger.debug(message, fields);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
warnedCodes.add(code);
|
|
33
|
+
logger.warn(message, fields);
|
|
34
|
+
if (process.env.NODE_ENV !== "production") {
|
|
35
|
+
try {
|
|
36
|
+
process.emitWarning(message, { type: "DeprecationWarning", code });
|
|
37
|
+
} catch {
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function _resetAccountReferenceWarnings() {
|
|
42
|
+
warnedCodes.clear();
|
|
43
|
+
}
|
|
44
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
45
|
+
0 && (module.exports = {
|
|
46
|
+
_resetAccountReferenceWarnings,
|
|
47
|
+
warnAccountReferenceDeprecation
|
|
48
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const warnedCodes = /* @__PURE__ */ new Set();
|
|
2
|
+
function warnAccountReferenceDeprecation(logger, code, message, meta = {}) {
|
|
3
|
+
const fields = { ...meta, code };
|
|
4
|
+
if (warnedCodes.has(code)) {
|
|
5
|
+
logger.debug(message, fields);
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
warnedCodes.add(code);
|
|
9
|
+
logger.warn(message, fields);
|
|
10
|
+
if (process.env.NODE_ENV !== "production") {
|
|
11
|
+
try {
|
|
12
|
+
process.emitWarning(message, { type: "DeprecationWarning", code });
|
|
13
|
+
} catch {
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function _resetAccountReferenceWarnings() {
|
|
18
|
+
warnedCodes.clear();
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
_resetAccountReferenceWarnings,
|
|
22
|
+
warnAccountReferenceDeprecation
|
|
23
|
+
};
|
|
@@ -70,6 +70,7 @@ function verifySignatureAsAuthenticator(options) {
|
|
|
70
70
|
const signer = {
|
|
71
71
|
keyid: result.keyid,
|
|
72
72
|
verified_at: result.verified_at,
|
|
73
|
+
...result.operatorRecord !== void 0 && { operatorRecord: result.operatorRecord },
|
|
73
74
|
...result.agent_url !== void 0 ? { agent_url: result.agent_url } : {}
|
|
74
75
|
};
|
|
75
76
|
const principal = principalForVerifiedSigner(signer, options.makePrincipal);
|
|
@@ -49,6 +49,7 @@ function verifySignatureAsAuthenticator(options) {
|
|
|
49
49
|
const signer = {
|
|
50
50
|
keyid: result.keyid,
|
|
51
51
|
verified_at: result.verified_at,
|
|
52
|
+
...result.operatorRecord !== void 0 && { operatorRecord: result.operatorRecord },
|
|
52
53
|
...result.agent_url !== void 0 ? { agent_url: result.agent_url } : {}
|
|
53
54
|
};
|
|
54
55
|
const principal = principalForVerifiedSigner(signer, options.makePrincipal);
|
|
@@ -188,6 +188,8 @@ export interface SessionKeyContext<TAccount = unknown> {
|
|
|
188
188
|
* resolved `TAccount` rather than re-resolving inside every handler.
|
|
189
189
|
*/
|
|
190
190
|
export interface ResolveAccountContext {
|
|
191
|
+
/** Whether this task may create/activate accounts or accept default terms. */
|
|
192
|
+
readonly provisioning?: boolean;
|
|
191
193
|
/** The AdCP tool being called. */
|
|
192
194
|
toolName: AdcpServerToolName;
|
|
193
195
|
/** Immutable SDK-selected AdCP release for this request. */
|
|
@@ -739,6 +741,11 @@ export interface ProtocolHandlers<TAccount = unknown> {
|
|
|
739
741
|
export interface AccountHandlers<TAccount = unknown> {
|
|
740
742
|
listAccountChanges?: DomainHandler<'list_account_changes', TAccount>;
|
|
741
743
|
listAccounts?: DomainHandler<'list_accounts', TAccount>;
|
|
744
|
+
/**
|
|
745
|
+
* Synchronous results must contain one row per dispatched entry in input
|
|
746
|
+
* order. With schema validation enabled, the framework may withhold invalid
|
|
747
|
+
* notification entries and merge their failures back into the response.
|
|
748
|
+
*/
|
|
742
749
|
syncAccounts?: DomainHandler<'sync_accounts', TAccount>;
|
|
743
750
|
syncGovernance?: DomainHandler<'sync_governance', TAccount>;
|
|
744
751
|
getAccountFinancials?: DomainHandler<'get_account_financials', TAccount>;
|
|
@@ -1264,6 +1271,33 @@ export interface AdcpServerConfig<TAccount = unknown> {
|
|
|
1264
1271
|
* principal across requests.
|
|
1265
1272
|
*/
|
|
1266
1273
|
resolveAccount?: (ref: AccountReference, ctx: ResolveAccountContext) => Promise<TAccount | null>;
|
|
1274
|
+
/**
|
|
1275
|
+
* Opt in to strict buyer-supplied account references. Default `false` in
|
|
1276
|
+
* SDK 14; becomes the default in the next major release.
|
|
1277
|
+
*
|
|
1278
|
+
* When `true`:
|
|
1279
|
+
* - A request that carries `account` on a server without `resolveAccount`
|
|
1280
|
+
* fails with `ACCOUNT_NOT_FOUND` instead of reaching the handler
|
|
1281
|
+
* unverified. An auth-only `resolveAccountFromAuth` does not authorize an
|
|
1282
|
+
* arbitrary reference.
|
|
1283
|
+
* - A seller that declares `capabilities.account.requiredForProducts`
|
|
1284
|
+
* refuses `get_products` with `ACCOUNT_REQUIRED` when the request carries
|
|
1285
|
+
* no account and authentication resolves none.
|
|
1286
|
+
* - `list_accounts.account` is treated as a filter: `resolveAccount` is not
|
|
1287
|
+
* called for it, and `ctx.account` comes from `resolveAccountFromAuth`.
|
|
1288
|
+
* - On `createAdcpServerFromPlatform` with `accounts.resolution: 'implicit'`,
|
|
1289
|
+
* an account whose returned identity metadata (`brand`, `operator`,
|
|
1290
|
+
* `operator_unit`, `currency`, `timezone`, `sandbox`) disagrees with the
|
|
1291
|
+
* supplied natural key is refused with `ACCOUNT_NOT_FOUND`.
|
|
1292
|
+
*
|
|
1293
|
+
* When `false` (default), each case keeps the SDK 14.0 behavior and logs a
|
|
1294
|
+
* deprecation warning once per process per warning code (`logger.warn`, plus
|
|
1295
|
+
* `process.emitWarning` outside `NODE_ENV=production`); later occurrences
|
|
1296
|
+
* log at debug level. Configure a reference-aware `resolveAccount` that
|
|
1297
|
+
* returns `null` for unknown or unauthorized references, then set this
|
|
1298
|
+
* flag. See `docs/guides/account-resolution.md`.
|
|
1299
|
+
*/
|
|
1300
|
+
strictAccountReferences?: boolean;
|
|
1267
1301
|
/**
|
|
1268
1302
|
* Resolve an account when the wire request doesn't carry one.
|
|
1269
1303
|
*
|
|
@@ -188,6 +188,8 @@ export interface SessionKeyContext<TAccount = unknown> {
|
|
|
188
188
|
* resolved `TAccount` rather than re-resolving inside every handler.
|
|
189
189
|
*/
|
|
190
190
|
export interface ResolveAccountContext {
|
|
191
|
+
/** Whether this task may create/activate accounts or accept default terms. */
|
|
192
|
+
readonly provisioning?: boolean;
|
|
191
193
|
/** The AdCP tool being called. */
|
|
192
194
|
toolName: AdcpServerToolName;
|
|
193
195
|
/** Immutable SDK-selected AdCP release for this request. */
|
|
@@ -739,6 +741,11 @@ export interface ProtocolHandlers<TAccount = unknown> {
|
|
|
739
741
|
export interface AccountHandlers<TAccount = unknown> {
|
|
740
742
|
listAccountChanges?: DomainHandler<'list_account_changes', TAccount>;
|
|
741
743
|
listAccounts?: DomainHandler<'list_accounts', TAccount>;
|
|
744
|
+
/**
|
|
745
|
+
* Synchronous results must contain one row per dispatched entry in input
|
|
746
|
+
* order. With schema validation enabled, the framework may withhold invalid
|
|
747
|
+
* notification entries and merge their failures back into the response.
|
|
748
|
+
*/
|
|
742
749
|
syncAccounts?: DomainHandler<'sync_accounts', TAccount>;
|
|
743
750
|
syncGovernance?: DomainHandler<'sync_governance', TAccount>;
|
|
744
751
|
getAccountFinancials?: DomainHandler<'get_account_financials', TAccount>;
|
|
@@ -1264,6 +1271,33 @@ export interface AdcpServerConfig<TAccount = unknown> {
|
|
|
1264
1271
|
* principal across requests.
|
|
1265
1272
|
*/
|
|
1266
1273
|
resolveAccount?: (ref: AccountReference, ctx: ResolveAccountContext) => Promise<TAccount | null>;
|
|
1274
|
+
/**
|
|
1275
|
+
* Opt in to strict buyer-supplied account references. Default `false` in
|
|
1276
|
+
* SDK 14; becomes the default in the next major release.
|
|
1277
|
+
*
|
|
1278
|
+
* When `true`:
|
|
1279
|
+
* - A request that carries `account` on a server without `resolveAccount`
|
|
1280
|
+
* fails with `ACCOUNT_NOT_FOUND` instead of reaching the handler
|
|
1281
|
+
* unverified. An auth-only `resolveAccountFromAuth` does not authorize an
|
|
1282
|
+
* arbitrary reference.
|
|
1283
|
+
* - A seller that declares `capabilities.account.requiredForProducts`
|
|
1284
|
+
* refuses `get_products` with `ACCOUNT_REQUIRED` when the request carries
|
|
1285
|
+
* no account and authentication resolves none.
|
|
1286
|
+
* - `list_accounts.account` is treated as a filter: `resolveAccount` is not
|
|
1287
|
+
* called for it, and `ctx.account` comes from `resolveAccountFromAuth`.
|
|
1288
|
+
* - On `createAdcpServerFromPlatform` with `accounts.resolution: 'implicit'`,
|
|
1289
|
+
* an account whose returned identity metadata (`brand`, `operator`,
|
|
1290
|
+
* `operator_unit`, `currency`, `timezone`, `sandbox`) disagrees with the
|
|
1291
|
+
* supplied natural key is refused with `ACCOUNT_NOT_FOUND`.
|
|
1292
|
+
*
|
|
1293
|
+
* When `false` (default), each case keeps the SDK 14.0 behavior and logs a
|
|
1294
|
+
* deprecation warning once per process per warning code (`logger.warn`, plus
|
|
1295
|
+
* `process.emitWarning` outside `NODE_ENV=production`); later occurrences
|
|
1296
|
+
* log at debug level. Configure a reference-aware `resolveAccount` that
|
|
1297
|
+
* returns `null` for unknown or unauthorized references, then set this
|
|
1298
|
+
* flag. See `docs/guides/account-resolution.md`.
|
|
1299
|
+
*/
|
|
1300
|
+
strictAccountReferences?: boolean;
|
|
1267
1301
|
/**
|
|
1268
1302
|
* Resolve an account when the wire request doesn't carry one.
|
|
1269
1303
|
*
|
|
@@ -58,6 +58,8 @@ var import_tool_request_schemas = require('../utils/tool-request-schemas.js');
|
|
|
58
58
|
var import_seller = require('../negotiation/seller.js');
|
|
59
59
|
var import_buyer = require('../negotiation/buyer.js');
|
|
60
60
|
var import_verification = require('../negotiation/verification.js');
|
|
61
|
+
var import_account_provisioning = require('./account-provisioning.js');
|
|
62
|
+
var import_account_reference_warnings = require('./account-reference-warnings.js');
|
|
61
63
|
var import_idempotency = require('../utils/idempotency.js');
|
|
62
64
|
var import_envelope_status_compat = require('../utils/envelope-status-compat.js');
|
|
63
65
|
var import_schema_validator = require('../validation/schema-validator.js');
|
|
@@ -584,6 +586,98 @@ function shallowToolInputHintSchema(toolName) {
|
|
|
584
586
|
SHALLOW_HINT_SCHEMAS.set(toolName, schema);
|
|
585
587
|
return schema;
|
|
586
588
|
}
|
|
589
|
+
function isAccountNotificationEventIssue(issue) {
|
|
590
|
+
return issue.keyword === "enum" && /^\/accounts\/\d+\/notification_configs\/\d+\/event_types\/\d+$/.test(issue.pointer);
|
|
591
|
+
}
|
|
592
|
+
function rejectedSyncAccountRow(entry) {
|
|
593
|
+
const identity = entry.account !== void 0 ? { account: entry.account } : Object.fromEntries(
|
|
594
|
+
["brand", "operator", "operator_unit", "currency", "timezone", "sandbox"].filter((key) => entry[key] !== void 0).map((key) => [key, entry[key]])
|
|
595
|
+
);
|
|
596
|
+
return {
|
|
597
|
+
...identity,
|
|
598
|
+
action: "failed",
|
|
599
|
+
// Provisioning was declined. A failed settings update does not establish
|
|
600
|
+
// the existing account's lifecycle state, so leave that status unknown.
|
|
601
|
+
...entry.account === void 0 && { status: "rejected" },
|
|
602
|
+
errors: []
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
function accountNotificationFailureRows(accounts, issues, deleteMissing) {
|
|
606
|
+
const rows = /* @__PURE__ */ new Map();
|
|
607
|
+
for (const issue of issues) {
|
|
608
|
+
const [, accountIndex, configIndex, eventIndex] = issue.pointer.match(
|
|
609
|
+
/^\/accounts\/(\d+)\/notification_configs\/(\d+)\/event_types\/(\d+)$/
|
|
610
|
+
);
|
|
611
|
+
const index = Number(accountIndex);
|
|
612
|
+
const entry = accounts[index];
|
|
613
|
+
let row = rows.get(index);
|
|
614
|
+
if (row === void 0) {
|
|
615
|
+
row = rejectedSyncAccountRow(entry);
|
|
616
|
+
rows.set(index, row);
|
|
617
|
+
}
|
|
618
|
+
row.errors.push({
|
|
619
|
+
code: "VALIDATION_ERROR",
|
|
620
|
+
recovery: "correctable",
|
|
621
|
+
message: issue.message,
|
|
622
|
+
field: `notification_configs[${configIndex}].event_types[${eventIndex}]`
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
if (deleteMissing) {
|
|
626
|
+
for (const [index, entry] of accounts.entries()) {
|
|
627
|
+
if (rows.has(index)) continue;
|
|
628
|
+
rows.set(index, {
|
|
629
|
+
...rejectedSyncAccountRow(entry),
|
|
630
|
+
errors: [
|
|
631
|
+
{
|
|
632
|
+
code: "VALIDATION_ERROR",
|
|
633
|
+
recovery: "correctable",
|
|
634
|
+
message: "delete_missing cannot be applied while account notification event types are invalid. Correct the rejected entries and retry.",
|
|
635
|
+
field: "delete_missing"
|
|
636
|
+
}
|
|
637
|
+
]
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return rows;
|
|
642
|
+
}
|
|
643
|
+
function restoreSyncAccountErrorIndices(row, acceptedIndices) {
|
|
644
|
+
if (!isPlainObject(row)) return row;
|
|
645
|
+
const restorePath = (path, pointer = false) => {
|
|
646
|
+
const match = pointer ? /^\/accounts\/(\d+)(?=\/|$)/.exec(path) : /^accounts\[(\d+)\](?=\.|\[|$)/.exec(path);
|
|
647
|
+
if (match === null) return path;
|
|
648
|
+
const originalIndex = acceptedIndices[Number(match[1])];
|
|
649
|
+
if (originalIndex === void 0) return path;
|
|
650
|
+
return `${pointer ? `/accounts/${originalIndex}` : `accounts[${originalIndex}]`}${path.slice(match[0].length)}`;
|
|
651
|
+
};
|
|
652
|
+
const restoreIssues = (issues) => issues.map(
|
|
653
|
+
(issue) => isPlainObject(issue) && typeof issue.pointer === "string" ? { ...issue, pointer: restorePath(issue.pointer, true) } : issue
|
|
654
|
+
);
|
|
655
|
+
const restoreField = (error) => {
|
|
656
|
+
if (!isPlainObject(error)) return error;
|
|
657
|
+
return {
|
|
658
|
+
...error,
|
|
659
|
+
...typeof error.field === "string" && { field: restorePath(error.field) },
|
|
660
|
+
...Array.isArray(error.issues) && { issues: restoreIssues(error.issues) },
|
|
661
|
+
...isPlainObject(error.details) && Array.isArray(error.details.issues) && {
|
|
662
|
+
details: { ...error.details, issues: restoreIssues(error.details.issues) }
|
|
663
|
+
}
|
|
664
|
+
};
|
|
665
|
+
};
|
|
666
|
+
return {
|
|
667
|
+
...row,
|
|
668
|
+
...Array.isArray(row.errors) && { errors: row.errors.map(restoreField) },
|
|
669
|
+
...isPlainObject(row.adcp_error) && { adcp_error: restoreField(row.adcp_error) }
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
function restoreSyncAccountEnvelopeErrorIndices(response, acceptedIndices) {
|
|
673
|
+
const body = response.structuredContent;
|
|
674
|
+
if (body === void 0 || !(Array.isArray(body.errors) || isPlainObject(body.adcp_error))) return response;
|
|
675
|
+
const restored = cloneFormattedResponse(response);
|
|
676
|
+
const mirrorsStructuredContent = contentTextMirrorsStructuredContent(restored, body);
|
|
677
|
+
restored.structuredContent = restoreSyncAccountErrorIndices(body, acceptedIndices);
|
|
678
|
+
syncContentJsonText(restored, restored.structuredContent, mirrorsStructuredContent);
|
|
679
|
+
return restored;
|
|
680
|
+
}
|
|
587
681
|
function validateFrameworkPayload(toolName, direction, payload, version, proposalCapabilities) {
|
|
588
682
|
if (toolName === "sync_reporting_status" && direction === "request") {
|
|
589
683
|
return (0, import_sync_reporting_status_envelope.validateSyncReportingStatusEnvelope)(payload, version);
|
|
@@ -1780,6 +1874,7 @@ function createAdcpServer(config) {
|
|
|
1780
1874
|
defaultAdcpVersion: configuredDefaultAdcpVersion,
|
|
1781
1875
|
mcpToolProfile = "auto",
|
|
1782
1876
|
requireCompactMutationAccountScope = false,
|
|
1877
|
+
strictAccountReferences = false,
|
|
1783
1878
|
resolveAccount,
|
|
1784
1879
|
resolveAccountFromAuth,
|
|
1785
1880
|
resolveSessionKey,
|
|
@@ -2495,6 +2590,7 @@ function createAdcpServer(config) {
|
|
|
2495
2590
|
const wrap = meta?.wrap ?? ((data, summary) => genericResponse(toolName, data, summary));
|
|
2496
2591
|
const toolHandler = async (params, extra) => {
|
|
2497
2592
|
const callRequestValidationMode = effectiveRequestValidationMode(extra);
|
|
2593
|
+
let notificationFailureRows = /* @__PURE__ */ new Map();
|
|
2498
2594
|
const releaseSelection = selectServedAdcpRelease(params, capConfig, adcpVersion, defaultAdcpVersion);
|
|
2499
2595
|
let releaseError;
|
|
2500
2596
|
let requestRelease;
|
|
@@ -2742,7 +2838,25 @@ function createAdcpServer(config) {
|
|
|
2742
2838
|
})
|
|
2743
2839
|
);
|
|
2744
2840
|
}
|
|
2745
|
-
|
|
2841
|
+
let issues = idempotencyDisabled && requestIsStateChanging ? outcome.issues.filter((i) => !(i.keyword === "required" && i.pointer === "/idempotency_key")) : outcome.issues;
|
|
2842
|
+
if (toolName === "sync_accounts" && effectiveFrameworkRequestValidationMode === "strict") {
|
|
2843
|
+
const eventIssues = issues.filter(isAccountNotificationEventIssue);
|
|
2844
|
+
if (eventIssues.length > 0 && eventIssues.length === issues.length) {
|
|
2845
|
+
const failedRows = accountNotificationFailureRows(
|
|
2846
|
+
params.accounts,
|
|
2847
|
+
eventIssues,
|
|
2848
|
+
params.delete_missing === true
|
|
2849
|
+
);
|
|
2850
|
+
if ((0, import_schema_validator.validateResponse)(
|
|
2851
|
+
"sync_accounts",
|
|
2852
|
+
{ accounts: [...failedRows.values()] },
|
|
2853
|
+
requestRelease.validationVersion
|
|
2854
|
+
).valid) {
|
|
2855
|
+
notificationFailureRows = failedRows;
|
|
2856
|
+
issues = [];
|
|
2857
|
+
}
|
|
2858
|
+
}
|
|
2859
|
+
}
|
|
2746
2860
|
if (issues.length > 0) {
|
|
2747
2861
|
if (effectiveFrameworkRequestValidationMode === "strict") {
|
|
2748
2862
|
const payload = (0, import_schema_errors.buildAdcpValidationErrorPayload)(toolName, "request", issues, {
|
|
@@ -2761,13 +2875,24 @@ function createAdcpServer(config) {
|
|
|
2761
2875
|
}
|
|
2762
2876
|
}
|
|
2763
2877
|
}
|
|
2764
|
-
|
|
2878
|
+
let unresolvedAccountPassThrough = false;
|
|
2879
|
+
const suppliedAccountRef = hasAccount && params.account != null && !(strictAccountReferences && toolName === "list_accounts");
|
|
2880
|
+
if (suppliedAccountRef && toolName === "list_accounts") {
|
|
2881
|
+
(0, import_account_reference_warnings.warnAccountReferenceDeprecation)(
|
|
2882
|
+
logger,
|
|
2883
|
+
"ADCP_LIST_ACCOUNTS_FILTER_RESOLVED",
|
|
2884
|
+
"[adcp/createAdcpServer] DEPRECATED: list_accounts.account is resolved as the request account (SDK 14.0 behavior). The next major release, or strictAccountReferences: true, treats it as a filter: resolveAccount is not called for it and ctx.account comes from resolveAccountFromAuth.",
|
|
2885
|
+
{ tool: toolName }
|
|
2886
|
+
);
|
|
2887
|
+
}
|
|
2888
|
+
if (suppliedAccountRef && resolveAccount) {
|
|
2765
2889
|
try {
|
|
2766
2890
|
const account = await resolveAccount(
|
|
2767
2891
|
params.account,
|
|
2768
2892
|
withImmutableServedAdcpVersion(
|
|
2769
2893
|
{
|
|
2770
2894
|
toolName,
|
|
2895
|
+
provisioning: (0, import_account_provisioning.isAccountProvisioningTask)(toolName),
|
|
2771
2896
|
authInfo: ctx.authInfo,
|
|
2772
2897
|
...ctx.agent != null && { agent: ctx.agent },
|
|
2773
2898
|
input: params
|
|
@@ -2800,20 +2925,32 @@ function createAdcpServer(config) {
|
|
|
2800
2925
|
})
|
|
2801
2926
|
);
|
|
2802
2927
|
}
|
|
2803
|
-
} else if (
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2928
|
+
} else if (suppliedAccountRef) {
|
|
2929
|
+
if (strictAccountReferences || toolName === "list_creative_formats") {
|
|
2930
|
+
return finalize(
|
|
2931
|
+
(0, import_errors2.adcpError)("ACCOUNT_NOT_FOUND", {
|
|
2932
|
+
message: "The specified account cannot be resolved",
|
|
2933
|
+
field: "account",
|
|
2934
|
+
suggestion: "The seller must configure resolveAccount to authorize supplied references; use list_accounts to discover an authorized account"
|
|
2935
|
+
})
|
|
2936
|
+
);
|
|
2937
|
+
}
|
|
2938
|
+
if (toolName !== "list_accounts") {
|
|
2939
|
+
(0, import_account_reference_warnings.warnAccountReferenceDeprecation)(
|
|
2940
|
+
logger,
|
|
2941
|
+
"ADCP_UNRESOLVED_ACCOUNT_REFERENCE",
|
|
2942
|
+
"[adcp/createAdcpServer] DEPRECATED: a request carried a buyer-supplied account reference, but no resolveAccount is configured. The reference reached the handler unverified (ctx.account is undefined). The next major release refuses it with ACCOUNT_NOT_FOUND. Configure a reference-aware resolveAccount that returns null for unknown or unauthorized references, then set strictAccountReferences: true. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/account-resolution.md",
|
|
2943
|
+
{ tool: toolName }
|
|
2944
|
+
);
|
|
2945
|
+
}
|
|
2946
|
+
unresolvedAccountPassThrough = true;
|
|
2947
|
+
} else if (!suppliedAccountRef && resolveAccountFromAuth) {
|
|
2812
2948
|
try {
|
|
2813
2949
|
const account = await resolveAccountFromAuth(
|
|
2814
2950
|
withImmutableServedAdcpVersion(
|
|
2815
2951
|
{
|
|
2816
2952
|
toolName,
|
|
2953
|
+
provisioning: (0, import_account_provisioning.isAccountProvisioningTask)(toolName),
|
|
2817
2954
|
authInfo: ctx.authInfo,
|
|
2818
2955
|
...ctx.agent != null && { agent: ctx.agent },
|
|
2819
2956
|
input: params
|
|
@@ -2844,6 +2981,26 @@ function createAdcpServer(config) {
|
|
|
2844
2981
|
}
|
|
2845
2982
|
}
|
|
2846
2983
|
}
|
|
2984
|
+
if ((toolName === "get_products" || toolName === "list_products") && capConfig?.account?.requiredForProducts && ctx.account == null && // A supplied reference the compatibility pass-through handed to the
|
|
2985
|
+
// handler satisfies the seller's declared requirement.
|
|
2986
|
+
!unresolvedAccountPassThrough) {
|
|
2987
|
+
if (!strictAccountReferences) {
|
|
2988
|
+
(0, import_account_reference_warnings.warnAccountReferenceDeprecation)(
|
|
2989
|
+
logger,
|
|
2990
|
+
"ADCP_REQUIRED_FOR_PRODUCTS_NOT_ENFORCED",
|
|
2991
|
+
`[adcp/createAdcpServer] DEPRECATED: this seller declares account.required_for_products, but ${toolName} ran without an account (SDK 14.0 behavior). The next major release, or strictAccountReferences: true, refuses it with ACCOUNT_REQUIRED.`,
|
|
2992
|
+
{ tool: toolName }
|
|
2993
|
+
);
|
|
2994
|
+
} else {
|
|
2995
|
+
return finalize(
|
|
2996
|
+
(0, import_errors2.adcpError)("ACCOUNT_REQUIRED", {
|
|
2997
|
+
message: "This seller requires an account for product discovery",
|
|
2998
|
+
field: "account",
|
|
2999
|
+
suggestion: "Provision an account with sync_accounts or discover one with list_accounts"
|
|
3000
|
+
})
|
|
3001
|
+
);
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
2847
3004
|
if (ctx.agent?.sandbox_only === true && ctx.account !== void 0 && ctx.account.sandbox !== true) {
|
|
2848
3005
|
return finalize(
|
|
2849
3006
|
(0, import_errors2.adcpError)("PERMISSION_DENIED", {
|
|
@@ -3105,13 +3262,23 @@ function createAdcpServer(config) {
|
|
|
3105
3262
|
if (typeof claimRenewalTimer === "object" && "unref" in claimRenewalTimer) claimRenewalTimer.unref();
|
|
3106
3263
|
}
|
|
3107
3264
|
let mutationHandlerCompleted = false;
|
|
3265
|
+
const acceptedAccountIndices = notificationFailureRows.size > 0 ? params.accounts.flatMap(
|
|
3266
|
+
(_entry, index) => notificationFailureRows.has(index) ? [] : [index]
|
|
3267
|
+
) : void 0;
|
|
3268
|
+
const restoreHandlerErrorIndices = (response) => acceptedAccountIndices === void 0 ? response : restoreSyncAccountEnvelopeErrorIndices(response, acceptedAccountIndices);
|
|
3108
3269
|
try {
|
|
3109
3270
|
if (webhookEmitter) {
|
|
3110
3271
|
const tenantScope = webhookTenantScopeForContext(ctx);
|
|
3111
3272
|
const scopedEmitter = tenantScope === void 0 ? configuredWebhookEmitter : webhookEmitter.forTenantScope(tenantScope);
|
|
3112
3273
|
ctx.emitWebhook = scopedEmitter.emit.bind(scopedEmitter);
|
|
3113
3274
|
}
|
|
3114
|
-
const
|
|
3275
|
+
const handlerParams = notificationFailureRows.size === 0 ? params : {
|
|
3276
|
+
...params,
|
|
3277
|
+
accounts: params.accounts.filter(
|
|
3278
|
+
(_entry, index) => !notificationFailureRows.has(index)
|
|
3279
|
+
)
|
|
3280
|
+
};
|
|
3281
|
+
const result = notificationFailureRows.size > 0 && handlerParams.accounts.length === 0 ? { accounts: [], ...params.dry_run === true && { dry_run: true } } : await handler(handlerParams, ctx);
|
|
3115
3282
|
mutationHandlerCompleted = true;
|
|
3116
3283
|
let formatted;
|
|
3117
3284
|
if (isFormattedResponse(result)) {
|
|
@@ -3148,6 +3315,42 @@ function createAdcpServer(config) {
|
|
|
3148
3315
|
} else {
|
|
3149
3316
|
formatted = wrap(result);
|
|
3150
3317
|
}
|
|
3318
|
+
formatted = restoreHandlerErrorIndices(formatted);
|
|
3319
|
+
if (notificationFailureRows.size > 0 && !isErrorResponse(formatted) && !(Array.isArray(formatted.structuredContent?.errors) && formatted.structuredContent?.accounts === void 0)) {
|
|
3320
|
+
formatted = cloneFormattedResponse(formatted);
|
|
3321
|
+
const body = formatted.structuredContent;
|
|
3322
|
+
const acceptedRows = Array.isArray(body.accounts) ? body.accounts.map((row) => restoreSyncAccountErrorIndices(row, acceptedAccountIndices)) : body.accounts;
|
|
3323
|
+
const submitted = isSubmittedEnvelope(body);
|
|
3324
|
+
let accounts;
|
|
3325
|
+
if (submitted) {
|
|
3326
|
+
if (acceptedRows !== void 0 && !Array.isArray(acceptedRows)) {
|
|
3327
|
+
throw new Error("sync_accounts submitted accounts must be an array when present");
|
|
3328
|
+
}
|
|
3329
|
+
accounts = [
|
|
3330
|
+
...Array.isArray(acceptedRows) ? acceptedRows : [],
|
|
3331
|
+
...[...notificationFailureRows.entries()].sort(([a], [b]) => a - b).map(([, row]) => row)
|
|
3332
|
+
];
|
|
3333
|
+
} else {
|
|
3334
|
+
if (!Array.isArray(acceptedRows) || acceptedRows.length !== handlerParams.accounts.length) {
|
|
3335
|
+
throw new Error("sync_accounts handler must return one result row for each accepted account entry");
|
|
3336
|
+
}
|
|
3337
|
+
let acceptedIndex = 0;
|
|
3338
|
+
accounts = params.accounts.map(
|
|
3339
|
+
(_entry, index) => notificationFailureRows.get(index) ?? acceptedRows[acceptedIndex++]
|
|
3340
|
+
);
|
|
3341
|
+
}
|
|
3342
|
+
const merged = { ...body, accounts };
|
|
3343
|
+
if (isFormattedResponse(result)) {
|
|
3344
|
+
const mirrorsStructuredContent = contentTextMirrorsStructuredContent(formatted, body);
|
|
3345
|
+
formatted = { ...formatted, structuredContent: wrap(merged).structuredContent };
|
|
3346
|
+
syncContentJsonText(formatted, formatted.structuredContent, mirrorsStructuredContent);
|
|
3347
|
+
} else {
|
|
3348
|
+
const rejected = accounts.filter((row) => row.action === "failed").length;
|
|
3349
|
+
const synced = accounts.length - rejected;
|
|
3350
|
+
const summary = submitted ? typeof body.message === "string" ? body.message : `Task ${body.task_id} submitted` : `Synced ${synced} account${synced === 1 ? "" : "s"}`;
|
|
3351
|
+
formatted = wrap(merged, `${summary}; ${rejected} account${rejected === 1 ? "" : "s"} rejected`);
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3151
3354
|
if (testControllerBridge && !isErrorResponse(formatted) && (0, import_test_controller_bridge.isSandboxRequest)(params) && ctx.account !== void 0 && !(0, import_account_mode.isSandboxOrMockAccount)(ctx.account)) {
|
|
3152
3355
|
const resolvedAccountId = typeof ctx.account === "object" && ctx.account !== null && typeof ctx.account.account_id === "string" ? ctx.account.account_id : void 0;
|
|
3153
3356
|
logger.debug(
|
|
@@ -3675,6 +3878,9 @@ function createAdcpServer(config) {
|
|
|
3675
3878
|
});
|
|
3676
3879
|
thrownTypedEnvelope = projectThrownAdcpError(err);
|
|
3677
3880
|
}
|
|
3881
|
+
if (thrownTypedEnvelope !== void 0) {
|
|
3882
|
+
thrownTypedEnvelope = restoreHandlerErrorIndices(thrownTypedEnvelope);
|
|
3883
|
+
}
|
|
3678
3884
|
const thrownRecovery = thrownTypedEnvelope ? thrownAdcpErrorRecovery(thrownTypedEnvelope) : void 0;
|
|
3679
3885
|
let stableTypedOutcome = !mutationHandlerCompleted && !!thrownTypedEnvelope && thrownRecovery !== "transient";
|
|
3680
3886
|
let replayEnvelope;
|
|
@@ -3769,7 +3975,7 @@ function createAdcpServer(config) {
|
|
|
3769
3975
|
message: env.message,
|
|
3770
3976
|
stack: err instanceof Error ? err.stack : void 0
|
|
3771
3977
|
});
|
|
3772
|
-
return finalize(err);
|
|
3978
|
+
return finalize(restoreHandlerErrorIndices(err));
|
|
3773
3979
|
}
|
|
3774
3980
|
if (err instanceof import_async_outcome.AdcpError) {
|
|
3775
3981
|
logger.warn("Handler threw an AdcpError", {
|
|
@@ -3779,7 +3985,7 @@ function createAdcpServer(config) {
|
|
|
3779
3985
|
message: err.message,
|
|
3780
3986
|
stack: err.stack
|
|
3781
3987
|
});
|
|
3782
|
-
return finalize(projectThrownAdcpError(err));
|
|
3988
|
+
return finalize(restoreHandlerErrorIndices(projectThrownAdcpError(err)));
|
|
3783
3989
|
}
|
|
3784
3990
|
const reason = err instanceof Error ? err.message : String(err);
|
|
3785
3991
|
logger.error("Handler failed", {
|
|
@@ -4082,6 +4288,11 @@ function createAdcpServer(config) {
|
|
|
4082
4288
|
}
|
|
4083
4289
|
}
|
|
4084
4290
|
checkCoherence(registeredToolNames, logger);
|
|
4291
|
+
if (!resolveAccount && process.env.NODE_ENV !== "production" && ["get_products", "get_signals", "request_proposals", "create_media_buy"].some((tool) => registeredToolNames.has(tool))) {
|
|
4292
|
+
logger.warn(
|
|
4293
|
+
strictAccountReferences ? "Account-carrying tools are registered without resolveAccount. Supplied references will fail with ACCOUNT_NOT_FOUND." : "Account-carrying tools are registered without resolveAccount. Supplied references reach handlers unverified; this is deprecated and they will fail with ACCOUNT_NOT_FOUND in the next major release. Configure a reference-aware resolveAccount and set strictAccountReferences: true."
|
|
4294
|
+
);
|
|
4295
|
+
}
|
|
4085
4296
|
const registeredMutatingTools = [...registeredToolNames].filter((t) => import_idempotency.MUTATING_TASKS.has(t));
|
|
4086
4297
|
if (registeredToolNames.has("get_creative_features") && idempotency && idempotency.ttlSeconds < 86400) {
|
|
4087
4298
|
throw new TypeError(
|