@adcp/sdk 17.0.0-beta.2 → 17.0.0-beta.4

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.
Files changed (70) hide show
  1. package/dist/lib/adapters/version/index.d.mts +9 -0
  2. package/dist/lib/adapters/version/index.d.ts +9 -0
  3. package/dist/lib/adapters/version/index.js +20 -6
  4. package/dist/lib/adapters/version/index.mjs +15 -2
  5. package/dist/lib/identity-3.3/trust.js +9 -2
  6. package/dist/lib/identity-3.3/trust.mjs +9 -2
  7. package/dist/lib/server/a2a-adapter.js +2 -1
  8. package/dist/lib/server/a2a-adapter.mjs +2 -1
  9. package/dist/lib/server/account-response-identity.d.mts +4 -0
  10. package/dist/lib/server/account-response-identity.d.ts +4 -0
  11. package/dist/lib/server/account-response-identity.js +23 -0
  12. package/dist/lib/server/account-response-identity.mjs +22 -1
  13. package/dist/lib/server/auth-signature.d.mts +2 -2
  14. package/dist/lib/server/auth-signature.d.ts +2 -2
  15. package/dist/lib/server/auth-signature.js +3 -0
  16. package/dist/lib/server/auth-signature.mjs +3 -0
  17. package/dist/lib/server/create-adcp-server.d.mts +2 -2
  18. package/dist/lib/server/create-adcp-server.d.ts +2 -2
  19. package/dist/lib/server/create-adcp-server.js +25 -3
  20. package/dist/lib/server/create-adcp-server.mjs +25 -3
  21. package/dist/lib/server/decisioning/account.d.mts +2 -1
  22. package/dist/lib/server/decisioning/account.d.ts +2 -1
  23. package/dist/lib/server/decisioning/account.js +1 -0
  24. package/dist/lib/server/decisioning/account.mjs +5 -1
  25. package/dist/lib/server/responses.js +8 -4
  26. package/dist/lib/server/responses.mjs +13 -5
  27. package/dist/lib/server/serve.js +3 -1
  28. package/dist/lib/server/serve.mjs +3 -1
  29. package/dist/lib/server/signed-request-transport.d.mts +1 -0
  30. package/dist/lib/server/signed-request-transport.d.ts +1 -0
  31. package/dist/lib/server/signed-request-transport.js +46 -0
  32. package/dist/lib/server/signed-request-transport.mjs +20 -0
  33. package/dist/lib/server/test-controller.d.mts +1 -0
  34. package/dist/lib/server/test-controller.d.ts +1 -0
  35. package/dist/lib/server/test-controller.js +5 -1
  36. package/dist/lib/server/test-controller.mjs +5 -1
  37. package/dist/lib/testing/index.d.mts +1 -0
  38. package/dist/lib/testing/index.d.ts +1 -0
  39. package/dist/lib/testing/index.js +3 -0
  40. package/dist/lib/testing/index.mjs +2 -0
  41. package/dist/lib/testing/storyboard/canonical-format-satisfaction.js +1 -15
  42. package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +1 -15
  43. package/dist/lib/testing/storyboard/index.d.mts +1 -0
  44. package/dist/lib/testing/storyboard/index.d.ts +1 -0
  45. package/dist/lib/testing/storyboard/index.js +3 -0
  46. package/dist/lib/testing/storyboard/index.mjs +2 -0
  47. package/dist/lib/testing/storyboard/loader.js +7 -0
  48. package/dist/lib/testing/storyboard/loader.mjs +7 -0
  49. package/dist/lib/testing/storyboard/request-builder.js +9 -6
  50. package/dist/lib/testing/storyboard/request-builder.mjs +9 -6
  51. package/dist/lib/testing/storyboard/runner.js +59 -6
  52. package/dist/lib/testing/storyboard/runner.mjs +59 -6
  53. package/dist/lib/testing/storyboard/types.d.mts +18 -0
  54. package/dist/lib/testing/storyboard/types.d.ts +18 -0
  55. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  56. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  57. package/dist/lib/testing/storyboard/web-bot-auth.d.mts +10 -0
  58. package/dist/lib/testing/storyboard/web-bot-auth.d.ts +10 -0
  59. package/dist/lib/testing/storyboard/web-bot-auth.js +80 -0
  60. package/dist/lib/testing/storyboard/web-bot-auth.mjs +56 -0
  61. package/dist/lib/version.d.mts +3 -3
  62. package/dist/lib/version.d.ts +3 -3
  63. package/dist/lib/version.js +3 -3
  64. package/dist/lib/version.mjs +3 -3
  65. package/docs/TYPE-SUMMARY.md +2 -2
  66. package/docs/llms.txt +2 -2
  67. package/docs/migration-14.x-rc-worksheet.md +4 -4
  68. package/docs/migration-16-to-17.md +27 -0
  69. package/docs/migration-agent-identity-3.3.md +106 -4
  70. package/package.json +15 -2
@@ -88,3 +88,12 @@ export declare function downgradeResponse<T>(toolName: string, data: T, options:
88
88
  data: T;
89
89
  drifts: import('./types.mjs').VersionDrift[];
90
90
  };
91
+ /**
92
+ * Project a seller-owned webhook result with the same per-release conversion
93
+ * as framework responses. Pass the originating request's `ctx.servedAdcpVersion`;
94
+ * when the server uses another source release, pass it as `fromVersion`.
95
+ * Envelope construction, credential stripping and webhook signing remain the
96
+ * emitter's responsibility. The input is never mutated.
97
+ * Use `downgradeResponse` when translation diagnostics are also needed.
98
+ */
99
+ export declare function projectResponseForRelease<T>(toolName: string, payload: T, servedAdcpVersion: string, fromVersion?: string): T;
@@ -88,3 +88,12 @@ export declare function downgradeResponse<T>(toolName: string, data: T, options:
88
88
  data: T;
89
89
  drifts: import('./types').VersionDrift[];
90
90
  };
91
+ /**
92
+ * Project a seller-owned webhook result with the same per-release conversion
93
+ * as framework responses. Pass the originating request's `ctx.servedAdcpVersion`;
94
+ * when the server uses another source release, pass it as `fromVersion`.
95
+ * Envelope construction, credential stripping and webhook signing remain the
96
+ * emitter's responsibility. The input is never mutated.
97
+ * Use `downgradeResponse` when translation diagnostics are also needed.
98
+ */
99
+ export declare function projectResponseForRelease<T>(toolName: string, payload: T, servedAdcpVersion: string, fromVersion?: string): T;
@@ -18,16 +18,17 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var version_exports = {};
20
20
  __export(version_exports, {
21
- adcpMinorLine: () => import_negotiate.adcpMinorLine,
22
- compareAdcpMinorLines: () => import_negotiate.compareAdcpMinorLines,
21
+ adcpMinorLine: () => import_negotiate2.adcpMinorLine,
22
+ compareAdcpMinorLines: () => import_negotiate2.compareAdcpMinorLines,
23
23
  convertRequest: () => convertRequest,
24
24
  convertResponse: () => convertResponse,
25
25
  downgradeResponse: () => downgradeResponse,
26
26
  getVersionAdapter: () => getVersionAdapter,
27
- isNegotiationFailure: () => import_negotiate.isNegotiationFailure,
27
+ isNegotiationFailure: () => import_negotiate2.isNegotiationFailure,
28
28
  listVersionAdapterTools: () => listVersionAdapterTools,
29
- negotiateAdcpRelease: () => import_negotiate.negotiateAdcpRelease,
30
- parseAdcpRelease: () => import_negotiate.parseAdcpRelease,
29
+ negotiateAdcpRelease: () => import_negotiate2.negotiateAdcpRelease,
30
+ parseAdcpRelease: () => import_negotiate2.parseAdcpRelease,
31
+ projectResponseForRelease: () => projectResponseForRelease,
31
32
  projectToolPayload: () => import_schema_projection.projectToolPayload,
32
33
  releaseDefinesTool: () => import_schema_projection.releaseDefinesTool,
33
34
  resolveAdapterKey: () => resolveAdapterKey,
@@ -36,12 +37,15 @@ __export(version_exports, {
36
37
  });
37
38
  module.exports = __toCommonJS(version_exports);
38
39
  var import_adcp_version_config = require('../../utils/adcp-version-config.js');
40
+ var import_version = require('../../version.js');
41
+ var import_negotiate = require('./negotiate.js');
42
+ var import_schema_loader = require('../../validation/schema-loader.js');
39
43
  var import_idempotency = require('../../utils/idempotency.js');
40
44
  var import__ = require('./3.0/index.js');
41
45
  var import__2 = require('./3.1/index.js');
42
46
  var import_translate = require('./translate.js');
43
47
  var import_translate2 = require('./translate.js');
44
- var import_negotiate = require('./negotiate.js');
48
+ var import_negotiate2 = require('./negotiate.js');
45
49
  var import_schema_projection = require('./schema-projection.js');
46
50
  const REGISTRY = /* @__PURE__ */ new Map();
47
51
  function register(version, adapters) {
@@ -77,6 +81,15 @@ function upgradeRequest(toolName, params, options) {
77
81
  function downgradeResponse(toolName, data, options) {
78
82
  return (0, import_translate.convertResponseToRelease)(toolName, data, { ...options, adapters: getVersionAdapter });
79
83
  }
84
+ function projectResponseForRelease(toolName, payload, servedAdcpVersion, fromVersion = import_version.ADCP_VERSION) {
85
+ const source = typeof fromVersion === "string" ? (0, import_negotiate.parseAdcpRelease)(fromVersion) : void 0;
86
+ const target = typeof servedAdcpVersion === "string" ? (0, import_negotiate.parseAdcpRelease)(servedAdcpVersion) : void 0;
87
+ if (!source || !target || source.major !== 3 || target.major !== 3 || target.minor > source.minor || source.minor === target.minor && source.prerelease !== target.prerelease || !(0, import_schema_loader.hasSchemaBundle)(fromVersion) || !(0, import_schema_loader.hasSchemaBundle)(servedAdcpVersion))
88
+ throw new TypeError(
89
+ "projectResponseForRelease requires valid AdCP 3 schema bundles, with the served minor line on or below the source and matching same-line previews"
90
+ );
91
+ return downgradeResponse(toolName, payload, { fromVersion, toVersion: servedAdcpVersion }).data;
92
+ }
80
93
  // Annotate the CommonJS export names for ESM import in node:
81
94
  0 && (module.exports = {
82
95
  adcpMinorLine,
@@ -89,6 +102,7 @@ function downgradeResponse(toolName, data, options) {
89
102
  listVersionAdapterTools,
90
103
  negotiateAdcpRelease,
91
104
  parseAdcpRelease,
105
+ projectResponseForRelease,
92
106
  projectToolPayload,
93
107
  releaseDefinesTool,
94
108
  resolveAdapterKey,
@@ -1,4 +1,7 @@
1
1
  import { shouldOmit31Fields } from "../../utils/adcp-version-config.mjs";
2
+ import { ADCP_VERSION } from "../../version.mjs";
3
+ import { parseAdcpRelease } from "./negotiate.mjs";
4
+ import { hasSchemaBundle } from "../../validation/schema-loader.mjs";
2
5
  import { isMutatingTask } from "../../utils/idempotency.mjs";
3
6
  import { v30Adapters } from "./3.0/index.mjs";
4
7
  import { v31Adapters } from "./3.1/index.mjs";
@@ -12,7 +15,7 @@ import { translationSteps } from "./translate.mjs";
12
15
  import {
13
16
  negotiateAdcpRelease,
14
17
  isNegotiationFailure,
15
- parseAdcpRelease,
18
+ parseAdcpRelease as parseAdcpRelease2,
16
19
  adcpMinorLine,
17
20
  compareAdcpMinorLines
18
21
  } from "./negotiate.mjs";
@@ -51,6 +54,15 @@ function upgradeRequest(toolName, params, options) {
51
54
  function downgradeResponse(toolName, data, options) {
52
55
  return convertResponseToRelease(toolName, data, { ...options, adapters: getVersionAdapter });
53
56
  }
57
+ function projectResponseForRelease(toolName, payload, servedAdcpVersion, fromVersion = ADCP_VERSION) {
58
+ const source = typeof fromVersion === "string" ? parseAdcpRelease(fromVersion) : void 0;
59
+ const target = typeof servedAdcpVersion === "string" ? parseAdcpRelease(servedAdcpVersion) : void 0;
60
+ if (!source || !target || source.major !== 3 || target.major !== 3 || target.minor > source.minor || source.minor === target.minor && source.prerelease !== target.prerelease || !hasSchemaBundle(fromVersion) || !hasSchemaBundle(servedAdcpVersion))
61
+ throw new TypeError(
62
+ "projectResponseForRelease requires valid AdCP 3 schema bundles, with the served minor line on or below the source and matching same-line previews"
63
+ );
64
+ return downgradeResponse(toolName, payload, { fromVersion, toVersion: servedAdcpVersion }).data;
65
+ }
54
66
  export {
55
67
  adcpMinorLine,
56
68
  compareAdcpMinorLines,
@@ -61,7 +73,8 @@ export {
61
73
  isNegotiationFailure,
62
74
  listVersionAdapterTools,
63
75
  negotiateAdcpRelease,
64
- parseAdcpRelease,
76
+ parseAdcpRelease2 as parseAdcpRelease,
77
+ projectResponseForRelease,
65
78
  projectToolPayload,
66
79
  releaseDefinesTool,
67
80
  resolveAdapterKey,
@@ -100,6 +100,13 @@ function failure(cause) {
100
100
  if (cause !== void 0) Object.defineProperty(error, "cause", { value: cause });
101
101
  throw error;
102
102
  }
103
+ function claimRegistrableDomain(domain) {
104
+ try {
105
+ return (0, import_etld.eTldPlusOne)(domain);
106
+ } catch (cause) {
107
+ return failure(cause);
108
+ }
109
+ }
103
110
  function validateTrustRecord(value) {
104
111
  if (!validateIdentity33Schema("trust/v1/trust", value)) failure();
105
112
  const record = value;
@@ -361,7 +368,7 @@ async function authorizeDemandGrant(claim, options) {
361
368
  const now = (options.now ?? (() => Date.now() / 1e3))();
362
369
  const signer = await options.evaluator.match(claim.signerOrigin, "adcp:buying", claim.brand.countries);
363
370
  if (signer.agent.countries && !claim.brand.countries?.length) failure();
364
- const brand = (0, import_etld.eTldPlusOne)(claim.brand.domain), account = (0, import_etld.eTldPlusOne)(claim.accountOperator), operator = signer.operator;
371
+ const brand = claimRegistrableDomain(claim.brand.domain), account = claimRegistrableDomain(claim.accountOperator), operator = signer.operator;
365
372
  const result = (source, chain, grants = []) => ({
366
373
  source,
367
374
  chain,
@@ -378,7 +385,7 @@ async function authorizeDemandGrant(claim, options) {
378
385
  throw cause;
379
386
  unavailable(cause);
380
387
  }
381
- const authoritativeBrand = house ? (0, import_etld.eTldPlusOne)(house.domain) : brand;
388
+ const authoritativeBrand = house ? claimRegistrableDomain(house.domain) : brand;
382
389
  const self = /* @__PURE__ */ new Set([brand, authoritativeBrand]);
383
390
  if (self.has(account) && self.has(operator)) return result("implicit", [.../* @__PURE__ */ new Set([brand, account, operator])]);
384
391
  const grantClaim = house ? { ...claim, brand: { ...claim.brand, brand_id: house.brand_id } } : claim;
@@ -59,6 +59,13 @@ function failure(cause) {
59
59
  if (cause !== void 0) Object.defineProperty(error, "cause", { value: cause });
60
60
  throw error;
61
61
  }
62
+ function claimRegistrableDomain(domain) {
63
+ try {
64
+ return eTldPlusOne(domain);
65
+ } catch (cause) {
66
+ return failure(cause);
67
+ }
68
+ }
62
69
  function validateTrustRecord(value) {
63
70
  if (!validateIdentity33Schema("trust/v1/trust", value)) failure();
64
71
  const record = value;
@@ -320,7 +327,7 @@ async function authorizeDemandGrant(claim, options) {
320
327
  const now = (options.now ?? (() => Date.now() / 1e3))();
321
328
  const signer = await options.evaluator.match(claim.signerOrigin, "adcp:buying", claim.brand.countries);
322
329
  if (signer.agent.countries && !claim.brand.countries?.length) failure();
323
- const brand = eTldPlusOne(claim.brand.domain), account = eTldPlusOne(claim.accountOperator), operator = signer.operator;
330
+ const brand = claimRegistrableDomain(claim.brand.domain), account = claimRegistrableDomain(claim.accountOperator), operator = signer.operator;
324
331
  const result = (source, chain, grants = []) => ({
325
332
  source,
326
333
  chain,
@@ -337,7 +344,7 @@ async function authorizeDemandGrant(claim, options) {
337
344
  throw cause;
338
345
  unavailable(cause);
339
346
  }
340
- const authoritativeBrand = house ? eTldPlusOne(house.domain) : brand;
347
+ const authoritativeBrand = house ? claimRegistrableDomain(house.domain) : brand;
341
348
  const self = /* @__PURE__ */ new Set([brand, authoritativeBrand]);
342
349
  if (self.has(account) && self.has(operator)) return result("implicit", [.../* @__PURE__ */ new Set([brand, account, operator])]);
343
350
  const grantClaim = house ? { ...claim, brand: { ...claim.brand, brand_id: house.brand_id } } : claim;
@@ -32,6 +32,7 @@ var import_operation_resolution = require('../signing/operation-resolution.js');
32
32
  var import_adcp_server = require('./adcp-server.js');
33
33
  var import_create_adcp_server = require('./create-adcp-server.js');
34
34
  var import_auth = require('./auth.js');
35
+ var import_signed_request_transport = require('./signed-request-transport.js');
35
36
  class RedactingA2ATaskStore {
36
37
  constructor(delegate) {
37
38
  this.delegate = delegate;
@@ -625,7 +626,7 @@ function captureRawBody(req, _res, buf) {
625
626
  }
626
627
  function resolveSignatureGate(options) {
627
628
  const symbols = options.server;
628
- const attached = symbols[import_create_adcp_server.ADCP_PRE_TRANSPORT];
629
+ const attached = (0, import_signed_request_transport.getSignedRequestPreTransport)(options.server) ?? symbols[import_create_adcp_server.ADCP_PRE_TRANSPORT];
629
630
  const gate = options.preTransport ?? (typeof attached === "function" ? attached : void 0);
630
631
  if (gate) return gate;
631
632
  const state = symbols[import_create_adcp_server.ADCP_SIGNED_REQUESTS_STATE];
@@ -25,6 +25,7 @@ import {
25
25
  ADCP_SIGNED_REQUESTS_STATE
26
26
  } from "./create-adcp-server.mjs";
27
27
  import { ADCP_SERVE_REQUEST_CONTEXT } from "./auth.mjs";
28
+ import { getSignedRequestPreTransport } from "./signed-request-transport.mjs";
28
29
  class RedactingA2ATaskStore {
29
30
  constructor(delegate) {
30
31
  this.delegate = delegate;
@@ -618,7 +619,7 @@ function captureRawBody(req, _res, buf) {
618
619
  }
619
620
  function resolveSignatureGate(options) {
620
621
  const symbols = options.server;
621
- const attached = symbols[ADCP_PRE_TRANSPORT];
622
+ const attached = getSignedRequestPreTransport(options.server) ?? symbols[ADCP_PRE_TRANSPORT];
622
623
  const gate = options.preTransport ?? (typeof attached === "function" ? attached : void 0);
623
624
  if (gate) return gate;
624
625
  const state = symbols[ADCP_SIGNED_REQUESTS_STATE];
@@ -1,4 +1,8 @@
1
1
  import type { SyncAccountsSuccess } from '../types/tools.generated.mjs';
2
+ export declare const ACCOUNT_REQUEST_RESULT_KEYS: readonly ["request_id", "resolution"];
3
+ export type AccountRequestResultFields = Pick<SyncAccountsSuccess['accounts'][number], Extract<keyof SyncAccountsSuccess['accounts'][number], (typeof ACCOUNT_REQUEST_RESULT_KEYS)[number]>>;
4
+ /** Preserve request results only after the source protocol bundle declares them. */
5
+ export declare function projectAccountRequestResultFields(account: object): AccountRequestResultFields;
2
6
  declare const IDENTITY_RESPONSE_SCHEMAS: {
3
7
  readonly account: "core/account-ref.json";
4
8
  readonly operator_unit: "core/operator-unit.json";
@@ -1,4 +1,8 @@
1
1
  import type { SyncAccountsSuccess } from '../types/tools.generated';
2
+ export declare const ACCOUNT_REQUEST_RESULT_KEYS: readonly ["request_id", "resolution"];
3
+ export type AccountRequestResultFields = Pick<SyncAccountsSuccess['accounts'][number], Extract<keyof SyncAccountsSuccess['accounts'][number], (typeof ACCOUNT_REQUEST_RESULT_KEYS)[number]>>;
4
+ /** Preserve request results only after the source protocol bundle declares them. */
5
+ export declare function projectAccountRequestResultFields(account: object): AccountRequestResultFields;
2
6
  declare const IDENTITY_RESPONSE_SCHEMAS: {
3
7
  readonly account: "core/account-ref.json";
4
8
  readonly operator_unit: "core/operator-unit.json";
@@ -18,10 +18,31 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var account_response_identity_exports = {};
20
20
  __export(account_response_identity_exports, {
21
+ ACCOUNT_REQUEST_RESULT_KEYS: () => ACCOUNT_REQUEST_RESULT_KEYS,
22
+ projectAccountRequestResultFields: () => projectAccountRequestResultFields,
21
23
  projectAccountResponseIdentityFields: () => projectAccountResponseIdentityFields
22
24
  });
23
25
  module.exports = __toCommonJS(account_response_identity_exports);
24
26
  var import_schema_loader = require('../validation/schema-loader.js');
27
+ const ACCOUNT_REQUEST_RESULT_KEYS = ["request_id", "resolution"];
28
+ function projectAccountRequestResultFields(account) {
29
+ const source = account;
30
+ const projected = {};
31
+ if (ACCOUNT_REQUEST_RESULT_KEYS.every((key) => source[key] === void 0)) return projected;
32
+ const schema = (0, import_schema_loader.getSchemaDocumentByRef)("account/sync-accounts-response.json")?.schema;
33
+ const branches = schema?.oneOf;
34
+ const success = Array.isArray(branches) ? branches.find((branch) => branch && typeof branch === "object" && branch.title === "SyncAccountsSuccess") : void 0;
35
+ const fields = success?.properties?.accounts?.items?.properties;
36
+ for (const key of ACCOUNT_REQUEST_RESULT_KEYS) {
37
+ const value = source[key];
38
+ if (value === void 0 || !fields || !Object.hasOwn(fields, key)) continue;
39
+ if (typeof value !== "string") {
40
+ throw new Error(`Account request result ${key} must be a string.`);
41
+ }
42
+ Object.assign(projected, { [key]: value });
43
+ }
44
+ return projected;
45
+ }
25
46
  const IDENTITY_RESPONSE_SCHEMAS = {
26
47
  account: "core/account-ref.json",
27
48
  operator_unit: "core/operator-unit.json",
@@ -48,5 +69,7 @@ function projectAccountResponseIdentityFields(account) {
48
69
  }
49
70
  // Annotate the CommonJS export names for ESM import in node:
50
71
  0 && (module.exports = {
72
+ ACCOUNT_REQUEST_RESULT_KEYS,
73
+ projectAccountRequestResultFields,
51
74
  projectAccountResponseIdentityFields
52
75
  });
@@ -1,4 +1,23 @@
1
- import { getSchemaValidatorByRef } from "../validation/schema-loader.mjs";
1
+ import { getSchemaDocumentByRef, getSchemaValidatorByRef } from "../validation/schema-loader.mjs";
2
+ const ACCOUNT_REQUEST_RESULT_KEYS = ["request_id", "resolution"];
3
+ function projectAccountRequestResultFields(account) {
4
+ const source = account;
5
+ const projected = {};
6
+ if (ACCOUNT_REQUEST_RESULT_KEYS.every((key) => source[key] === void 0)) return projected;
7
+ const schema = getSchemaDocumentByRef("account/sync-accounts-response.json")?.schema;
8
+ const branches = schema?.oneOf;
9
+ const success = Array.isArray(branches) ? branches.find((branch) => branch && typeof branch === "object" && branch.title === "SyncAccountsSuccess") : void 0;
10
+ const fields = success?.properties?.accounts?.items?.properties;
11
+ for (const key of ACCOUNT_REQUEST_RESULT_KEYS) {
12
+ const value = source[key];
13
+ if (value === void 0 || !fields || !Object.hasOwn(fields, key)) continue;
14
+ if (typeof value !== "string") {
15
+ throw new Error(`Account request result ${key} must be a string.`);
16
+ }
17
+ Object.assign(projected, { [key]: value });
18
+ }
19
+ return projected;
20
+ }
2
21
  const IDENTITY_RESPONSE_SCHEMAS = {
3
22
  account: "core/account-ref.json",
4
23
  operator_unit: "core/operator-unit.json",
@@ -24,5 +43,7 @@ function projectAccountResponseIdentityFields(account) {
24
43
  return projected;
25
44
  }
26
45
  export {
46
+ ACCOUNT_REQUEST_RESULT_KEYS,
47
+ projectAccountRequestResultFields,
27
48
  projectAccountResponseIdentityFields
28
49
  };
@@ -64,8 +64,8 @@ export interface VerifySignatureAsAuthenticatorOptions {
64
64
  * requests fall through to the next authenticator — so set it to whatever
65
65
  * your `request_signing` capability claim advertises. */
66
66
  capability: VerifierCapability;
67
- /** Resolves verification keys by `keyid`. */
68
- jwks: JwksResolver;
67
+ /** Resolves legacy RFC 9421 keys. May be omitted for a Web Bot Auth-only endpoint. */
68
+ jwks?: JwksResolver;
69
69
  /**
70
70
  * Stores `(keyid, signature-bytes, expires)` tuples for replay detection.
71
71
  * Defaults to a fresh {@link InMemoryReplayStore} — fine for single-process
@@ -64,8 +64,8 @@ export interface VerifySignatureAsAuthenticatorOptions {
64
64
  * requests fall through to the next authenticator — so set it to whatever
65
65
  * your `request_signing` capability claim advertises. */
66
66
  capability: VerifierCapability;
67
- /** Resolves verification keys by `keyid`. */
68
- jwks: JwksResolver;
67
+ /** Resolves legacy RFC 9421 keys. May be omitted for a Web Bot Auth-only endpoint. */
68
+ jwks?: JwksResolver;
69
69
  /**
70
70
  * Stores `(keyid, signature-bytes, expires)` tuples for replay detection.
71
71
  * Defaults to a fresh {@link InMemoryReplayStore} — fine for single-process
@@ -36,6 +36,8 @@ var import_verifier = require('../signing/verifier.js');
36
36
  var import_buyer_agent = require('./decisioning/buyer-agent.js');
37
37
  var import_auth = require('./auth.js');
38
38
  function verifySignatureAsAuthenticator(options) {
39
+ if (!options.jwks && !options.webBotAuth)
40
+ throw new TypeError("verifySignatureAsAuthenticator requires jwks or webBotAuth");
39
41
  const replayStore = options.replayStore ?? new import_replay.InMemoryReplayStore();
40
42
  const legacyOriginGate = options.assertLegacyOriginAllowed ?? (0, import_web_bot_auth.getWebBotAuthLegacyOriginGate)(options.webBotAuth?.resolvePrincipal);
41
43
  if (options.webBotAuth && !legacyOriginGate)
@@ -102,6 +104,7 @@ function verifySignatureAsAuthenticator(options) {
102
104
  }
103
105
  };
104
106
  }
107
+ if (!options.jwks) throw new import_web_bot_auth2.WebBotAuthError(403, "profile_disabled");
105
108
  result = await (0, import_verifier.verifyRequestSignature)(requestLike, {
106
109
  capability: options.capability,
107
110
  jwks: options.jwks,
@@ -36,6 +36,8 @@ import {
36
36
  tagAuthenticatorPresenceGated
37
37
  } from "./auth.mjs";
38
38
  function verifySignatureAsAuthenticator(options) {
39
+ if (!options.jwks && !options.webBotAuth)
40
+ throw new TypeError("verifySignatureAsAuthenticator requires jwks or webBotAuth");
39
41
  const replayStore = options.replayStore ?? new InMemoryReplayStore();
40
42
  const legacyOriginGate = options.assertLegacyOriginAllowed ?? getWebBotAuthLegacyOriginGate(options.webBotAuth?.resolvePrincipal);
41
43
  if (options.webBotAuth && !legacyOriginGate)
@@ -102,6 +104,7 @@ function verifySignatureAsAuthenticator(options) {
102
104
  }
103
105
  };
104
106
  }
107
+ if (!options.jwks) throw new WebBotAuthError(403, "profile_disabled");
105
108
  result = await verifyRequestSignature(requestLike, {
106
109
  capability: options.capability,
107
110
  jwks: options.jwks,
@@ -946,8 +946,8 @@ export interface AdcpCapabilitiesOverrides {
946
946
  export interface SignedRequestsConfig {
947
947
  webBotAuth?: import('./auth-signature.mjs').VerifySignatureAsAuthenticatorOptions['webBotAuth'];
948
948
  assertLegacyOriginAllowed?: (agentUrl: string) => Promise<void>;
949
- /** Resolves verification keys by `keyid`. */
950
- jwks: JwksResolver;
949
+ /** Resolves legacy RFC 9421 keys. May be omitted for a Web Bot Auth-only endpoint. */
950
+ jwks?: JwksResolver;
951
951
  /** Stores `(keyid, signature-bytes, expires)` tuples for replay detection. */
952
952
  replayStore: ReplayStore;
953
953
  /** Consulted for revoked `kid` / `jti` before accepting a signature. */
@@ -946,8 +946,8 @@ export interface AdcpCapabilitiesOverrides {
946
946
  export interface SignedRequestsConfig {
947
947
  webBotAuth?: import('./auth-signature').VerifySignatureAsAuthenticatorOptions['webBotAuth'];
948
948
  assertLegacyOriginAllowed?: (agentUrl: string) => Promise<void>;
949
- /** Resolves verification keys by `keyid`. */
950
- jwks: JwksResolver;
949
+ /** Resolves legacy RFC 9421 keys. May be omitted for a Web Bot Auth-only endpoint. */
950
+ jwks?: JwksResolver;
951
951
  /** Stores `(keyid, signature-bytes, expires)` tuples for replay detection. */
952
952
  replayStore: ReplayStore;
953
953
  /** Consulted for revoked `kid` / `jti` before accepting a signature. */
@@ -81,6 +81,7 @@ var import_middleware = require('../signing/middleware.js');
81
81
  var import_operation_resolution = require('../signing/operation-resolution.js');
82
82
  var import_account_mode = require('./account-mode.js');
83
83
  var import_test_controller_bridge = require('./test-controller-bridge.js');
84
+ var import_signed_request_transport = require('./signed-request-transport.js');
84
85
  var import_version3 = require('../version.js');
85
86
  var import_schemas2 = require('../types/schemas.generated.js');
86
87
  var import_error_codes = require('../types/error-codes.js');
@@ -1466,6 +1467,8 @@ function resolveEffectiveSignedRequestPolicy(signedRequests, capabilityRequestSi
1466
1467
  };
1467
1468
  }
1468
1469
  function buildSignedRequestsPreTransport(signedRequests, effectiveRequestSigning, adcpVersion) {
1470
+ if (!signedRequests.jwks && !signedRequests.webBotAuth)
1471
+ throw new TypeError("signedRequests requires jwks or webBotAuth");
1469
1472
  const legacyOriginGate = signedRequests.assertLegacyOriginAllowed ?? (0, import_web_bot_auth.getWebBotAuthLegacyOriginGate)(signedRequests.webBotAuth?.resolvePrincipal);
1470
1473
  if (signedRequests.webBotAuth && !legacyOriginGate)
1471
1474
  throw new Error(
@@ -1485,7 +1488,7 @@ function buildSignedRequestsPreTransport(signedRequests, effectiveRequestSigning
1485
1488
  required_for: requiredFor,
1486
1489
  ...effectiveRequestSigning.protocol_methods_required_for ? { protocol_methods_required_for: effectiveRequestSigning.protocol_methods_required_for } : {}
1487
1490
  },
1488
- jwks: signedRequests.jwks,
1491
+ jwks: signedRequests.jwks ?? { resolve: async () => null },
1489
1492
  replayStore: signedRequests.replayStore,
1490
1493
  revocationStore: signedRequests.revocationStore,
1491
1494
  adcpVersion,
@@ -1558,6 +1561,12 @@ function buildSignedRequestsPreTransport(signedRequests, effectiveRequestSigning
1558
1561
  return true;
1559
1562
  }
1560
1563
  }
1564
+ if (!signedRequests.jwks && (req.headers["signature"] !== void 0 || req.headers["signature-input"] !== void 0)) {
1565
+ const refused = new import_web_bot_auth2.WebBotAuthError(403, "profile_disabled");
1566
+ res.writeHead(refused.status, { ...refused.headers, "Content-Type": "application/json" });
1567
+ res.end(JSON.stringify(refused.body));
1568
+ return true;
1569
+ }
1561
1570
  const reqShim = {
1562
1571
  method: req.method ?? "POST",
1563
1572
  url: req.url ?? "/mcp",
@@ -5121,12 +5130,25 @@ function createAdcpServer(config) {
5121
5130
  (0, import_adcp_server.setMcpAppResources)(wrapped, mcpAppResources);
5122
5131
  if (signedRequests) {
5123
5132
  const preTransport = buildSignedRequestsPreTransport(signedRequests, enforcedRequestSigningPolicy, adcpVersion);
5133
+ const transportPermitted = (0, import_signed_request_transport.registerSignedRequestTransportGuard)(wrapped, preTransport);
5134
+ let preTransportConsumed = false;
5124
5135
  Object.defineProperty(wrapped, ADCP_PRE_TRANSPORT, {
5125
- value: preTransport,
5136
+ get() {
5137
+ preTransportConsumed = true;
5138
+ return preTransport;
5139
+ },
5126
5140
  enumerable: false,
5127
- writable: false,
5128
5141
  configurable: true
5129
5142
  });
5143
+ const connect = wrapped.connect.bind(wrapped);
5144
+ wrapped.connect = async (transport) => {
5145
+ if (!preTransportConsumed && !transportPermitted(transport)) {
5146
+ throw new Error(
5147
+ "signedRequests verifier is not mounted: direct server.connect(transport) does not run HTTP middleware. Use serve(), createA2AAdapter(), or mount server[ADCP_PRE_TRANSPORT] before handling requests. For custom authentication, compose verifySignatureAsAuthenticator({ webBotAuth }) and capture rawBody."
5148
+ );
5149
+ }
5150
+ return connect(transport);
5151
+ };
5130
5152
  }
5131
5153
  const signedRequestsState = {
5132
5154
  autoWired: Boolean(signedRequests),
@@ -183,6 +183,7 @@ import {
183
183
  filterValidSeededRights,
184
184
  filterValidSeededSiOffering
185
185
  } from "./test-controller-bridge.mjs";
186
+ import { registerSignedRequestTransportGuard } from "./signed-request-transport.mjs";
186
187
  import { ADCP_VERSION, LIBRARY_VERSION } from "../version.mjs";
187
188
  import { AccountReferenceSchema } from "../types/schemas.generated.mjs";
188
189
  import {
@@ -1568,6 +1569,8 @@ function resolveEffectiveSignedRequestPolicy(signedRequests, capabilityRequestSi
1568
1569
  };
1569
1570
  }
1570
1571
  function buildSignedRequestsPreTransport(signedRequests, effectiveRequestSigning, adcpVersion) {
1572
+ if (!signedRequests.jwks && !signedRequests.webBotAuth)
1573
+ throw new TypeError("signedRequests requires jwks or webBotAuth");
1571
1574
  const legacyOriginGate = signedRequests.assertLegacyOriginAllowed ?? getWebBotAuthLegacyOriginGate(signedRequests.webBotAuth?.resolvePrincipal);
1572
1575
  if (signedRequests.webBotAuth && !legacyOriginGate)
1573
1576
  throw new Error(
@@ -1587,7 +1590,7 @@ function buildSignedRequestsPreTransport(signedRequests, effectiveRequestSigning
1587
1590
  required_for: requiredFor,
1588
1591
  ...effectiveRequestSigning.protocol_methods_required_for ? { protocol_methods_required_for: effectiveRequestSigning.protocol_methods_required_for } : {}
1589
1592
  },
1590
- jwks: signedRequests.jwks,
1593
+ jwks: signedRequests.jwks ?? { resolve: async () => null },
1591
1594
  replayStore: signedRequests.replayStore,
1592
1595
  revocationStore: signedRequests.revocationStore,
1593
1596
  adcpVersion,
@@ -1660,6 +1663,12 @@ function buildSignedRequestsPreTransport(signedRequests, effectiveRequestSigning
1660
1663
  return true;
1661
1664
  }
1662
1665
  }
1666
+ if (!signedRequests.jwks && (req.headers["signature"] !== void 0 || req.headers["signature-input"] !== void 0)) {
1667
+ const refused = new WebBotAuthError(403, "profile_disabled");
1668
+ res.writeHead(refused.status, { ...refused.headers, "Content-Type": "application/json" });
1669
+ res.end(JSON.stringify(refused.body));
1670
+ return true;
1671
+ }
1663
1672
  const reqShim = {
1664
1673
  method: req.method ?? "POST",
1665
1674
  url: req.url ?? "/mcp",
@@ -5223,12 +5232,25 @@ function createAdcpServer(config) {
5223
5232
  setMcpAppResources(wrapped, mcpAppResources);
5224
5233
  if (signedRequests) {
5225
5234
  const preTransport = buildSignedRequestsPreTransport(signedRequests, enforcedRequestSigningPolicy, adcpVersion);
5235
+ const transportPermitted = registerSignedRequestTransportGuard(wrapped, preTransport);
5236
+ let preTransportConsumed = false;
5226
5237
  Object.defineProperty(wrapped, ADCP_PRE_TRANSPORT, {
5227
- value: preTransport,
5238
+ get() {
5239
+ preTransportConsumed = true;
5240
+ return preTransport;
5241
+ },
5228
5242
  enumerable: false,
5229
- writable: false,
5230
5243
  configurable: true
5231
5244
  });
5245
+ const connect = wrapped.connect.bind(wrapped);
5246
+ wrapped.connect = async (transport) => {
5247
+ if (!preTransportConsumed && !transportPermitted(transport)) {
5248
+ throw new Error(
5249
+ "signedRequests verifier is not mounted: direct server.connect(transport) does not run HTTP middleware. Use serve(), createA2AAdapter(), or mount server[ADCP_PRE_TRANSPORT] before handling requests. For custom authentication, compose verifySignatureAsAuthenticator({ webBotAuth }) and capture rawBody."
5250
+ );
5251
+ }
5252
+ return connect(transport);
5253
+ };
5232
5254
  }
5233
5255
  const signedRequestsState = {
5234
5256
  autoWired: Boolean(signedRequests),
@@ -18,6 +18,7 @@
18
18
  */
19
19
  import type { Account as WireAccount, AccountAuthorization, AccountScope, BillingParty, BrandReference, AccountReference, BusinessEntity, ExtensionObject, ListAccountChangesRequest, ListAccountChangesResponse, ListAccountsRequest, NotificationConfig, PaymentTerms, ReportingDeliveryConfigurationState, ListAccountsResponse, ReportUsageRequest, ReportUsageResponse, SyncAccountsResponse, SyncAccountsSuccess, SyncGovernanceRequest, SyncGovernanceResponse, SyncGovernanceSuccess, GetAccountFinancialsRequest, GetAccountFinancialsResponse, GetAccountFinancialsSuccess } from '../../types/tools.generated.mjs';
20
20
  import type { ServerPayload } from '../../types/server-payload.mjs';
21
+ import { type AccountRequestResultFields } from '../account-response-identity.mjs';
21
22
  import type { CursorPage } from './pagination.mjs';
22
23
  import type { AccountMode } from '../account-mode.mjs';
23
24
  import type { AdcpStructuredError } from './async-outcome.mjs';
@@ -889,7 +890,7 @@ export type AccountFilter = ListAccountsRequest;
889
890
  * returned rows — same MUST-NOT-LEAK rule the framework enforces on
890
891
  * `Account.authInfo`.
891
892
  */
892
- interface SyncAccountsResultFields {
893
+ interface SyncAccountsResultFields extends AccountRequestResultFields {
893
894
  account_id?: string;
894
895
  /** Current canonical operator unit, distinct from the seller account ID. */
895
896
  operator_unit?: SyncAccountsRow['operator_unit'];
@@ -18,6 +18,7 @@
18
18
  */
19
19
  import type { Account as WireAccount, AccountAuthorization, AccountScope, BillingParty, BrandReference, AccountReference, BusinessEntity, ExtensionObject, ListAccountChangesRequest, ListAccountChangesResponse, ListAccountsRequest, NotificationConfig, PaymentTerms, ReportingDeliveryConfigurationState, ListAccountsResponse, ReportUsageRequest, ReportUsageResponse, SyncAccountsResponse, SyncAccountsSuccess, SyncGovernanceRequest, SyncGovernanceResponse, SyncGovernanceSuccess, GetAccountFinancialsRequest, GetAccountFinancialsResponse, GetAccountFinancialsSuccess } from '../../types/tools.generated';
20
20
  import type { ServerPayload } from '../../types/server-payload';
21
+ import { type AccountRequestResultFields } from '../account-response-identity';
21
22
  import type { CursorPage } from './pagination';
22
23
  import type { AccountMode } from '../account-mode';
23
24
  import type { AdcpStructuredError } from './async-outcome';
@@ -889,7 +890,7 @@ export type AccountFilter = ListAccountsRequest;
889
890
  * returned rows — same MUST-NOT-LEAK rule the framework enforces on
890
891
  * `Account.authInfo`.
891
892
  */
892
- interface SyncAccountsResultFields {
893
+ interface SyncAccountsResultFields extends AccountRequestResultFields {
893
894
  account_id?: string;
894
895
  /** Current canonical operator unit, distinct from the seller account ID. */
895
896
  operator_unit?: SyncAccountsRow['operator_unit'];
@@ -156,6 +156,7 @@ function toWireSyncAccountRow(row) {
156
156
  row.authorization
157
157
  );
158
158
  }
159
+ Object.assign(wire, (0, import_account_response_identity.projectAccountRequestResultFields)(row));
159
160
  return wire;
160
161
  }
161
162
  function projectNotificationConfig(config) {
@@ -1,5 +1,8 @@
1
1
  import { projectReportingDeliveryConfigStates } from "../reporting-delivery-config.mjs";
2
- import { projectAccountResponseIdentityFields } from "../account-response-identity.mjs";
2
+ import {
3
+ projectAccountRequestResultFields,
4
+ projectAccountResponseIdentityFields
5
+ } from "../account-response-identity.mjs";
3
6
  const ACCOUNT_AUTHORIZATION_WIRE_KEYS = [
4
7
  "allowed_tasks",
5
8
  "field_scopes",
@@ -125,6 +128,7 @@ function toWireSyncAccountRow(row) {
125
128
  row.authorization
126
129
  );
127
130
  }
131
+ Object.assign(wire, projectAccountRequestResultFields(row));
128
132
  return wire;
129
133
  }
130
134
  function projectNotificationConfig(config) {