@adcp/sdk 16.0.0-beta.1 → 16.0.0-beta.3

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 (155) hide show
  1. package/README.md +54 -0
  2. package/dist/lib/core/ConversationTypes.d.mts +8 -3
  3. package/dist/lib/core/ConversationTypes.d.ts +8 -3
  4. package/dist/lib/core/SingleAgentClient.d.mts +15 -4
  5. package/dist/lib/core/SingleAgentClient.d.ts +15 -4
  6. package/dist/lib/core/SingleAgentClient.js +29 -8
  7. package/dist/lib/core/SingleAgentClient.mjs +29 -8
  8. package/dist/lib/core/TaskExecutor.js +5 -1
  9. package/dist/lib/core/TaskExecutor.mjs +5 -1
  10. package/dist/lib/errors/index.d.mts +9 -4
  11. package/dist/lib/errors/index.d.ts +9 -4
  12. package/dist/lib/identity-3.3/generated-compat.d.mts +34 -0
  13. package/dist/lib/identity-3.3/generated-compat.d.ts +34 -0
  14. package/dist/lib/identity-3.3/generated-compat.js +16 -0
  15. package/dist/lib/identity-3.3/generated-compat.mjs +0 -0
  16. package/dist/lib/identity-3.3/index.d.mts +2 -2
  17. package/dist/lib/identity-3.3/index.d.ts +2 -2
  18. package/dist/lib/identity-3.3/index.js +4 -0
  19. package/dist/lib/identity-3.3/index.mjs +5 -1
  20. package/dist/lib/identity-3.3/lifecycle.d.mts +17 -5
  21. package/dist/lib/identity-3.3/lifecycle.d.ts +17 -5
  22. package/dist/lib/identity-3.3/lifecycle.js +32 -5
  23. package/dist/lib/identity-3.3/lifecycle.mjs +38 -6
  24. package/dist/lib/identity-3.3/revocation.d.mts +39 -3
  25. package/dist/lib/identity-3.3/revocation.d.ts +39 -3
  26. package/dist/lib/identity-3.3/revocation.js +88 -18
  27. package/dist/lib/identity-3.3/revocation.mjs +89 -19
  28. package/dist/lib/identity-3.3/server.d.mts +12 -0
  29. package/dist/lib/identity-3.3/server.d.ts +12 -0
  30. package/dist/lib/identity-3.3/server.js +103 -43
  31. package/dist/lib/identity-3.3/server.mjs +111 -45
  32. package/dist/lib/identity-3.3/trust.d.mts +62 -1
  33. package/dist/lib/identity-3.3/trust.d.ts +62 -1
  34. package/dist/lib/identity-3.3/trust.js +126 -21
  35. package/dist/lib/identity-3.3/trust.mjs +124 -21
  36. package/dist/lib/identity-3.3/types.d.mts +39 -11
  37. package/dist/lib/identity-3.3/types.d.ts +39 -11
  38. package/dist/lib/index.d.mts +3 -3
  39. package/dist/lib/index.d.ts +3 -3
  40. package/dist/lib/index.js +8 -0
  41. package/dist/lib/index.mjs +9 -1
  42. package/dist/lib/negotiation/types.d.mts +20 -39
  43. package/dist/lib/negotiation/types.d.ts +20 -39
  44. package/dist/lib/protocols/index.d.mts +61 -25
  45. package/dist/lib/protocols/index.d.ts +61 -25
  46. package/dist/lib/protocols/index.js +11 -6
  47. package/dist/lib/protocols/index.mjs +5 -2
  48. package/dist/lib/protocols/mcp-modern.js +1 -0
  49. package/dist/lib/protocols/mcp-modern.mjs +2 -1
  50. package/dist/lib/protocols/mcp.js +1 -0
  51. package/dist/lib/protocols/mcp.mjs +2 -1
  52. package/dist/lib/protocols/responseSizeLimit.d.mts +91 -5
  53. package/dist/lib/protocols/responseSizeLimit.d.ts +91 -5
  54. package/dist/lib/protocols/responseSizeLimit.js +195 -31
  55. package/dist/lib/protocols/responseSizeLimit.mjs +192 -31
  56. package/dist/lib/reporting/bigquery/index.js +8 -0
  57. package/dist/lib/reporting/bigquery/index.mjs +8 -0
  58. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  59. package/dist/lib/server/auth-signature.d.mts +6 -1
  60. package/dist/lib/server/auth-signature.d.ts +6 -1
  61. package/dist/lib/server/auth-signature.js +24 -13
  62. package/dist/lib/server/auth-signature.mjs +29 -13
  63. package/dist/lib/server/auth.d.mts +2 -2
  64. package/dist/lib/server/auth.d.ts +2 -2
  65. package/dist/lib/server/create-adcp-server.js +31 -10
  66. package/dist/lib/server/create-adcp-server.mjs +37 -11
  67. package/dist/lib/signing/crypto.d.mts +15 -0
  68. package/dist/lib/signing/crypto.d.ts +15 -0
  69. package/dist/lib/signing/crypto.js +83 -3
  70. package/dist/lib/signing/crypto.mjs +86 -3
  71. package/dist/lib/signing/fetch-async.js +1 -1
  72. package/dist/lib/signing/fetch-async.mjs +1 -1
  73. package/dist/lib/signing/fetch.js +1 -1
  74. package/dist/lib/signing/fetch.mjs +1 -1
  75. package/dist/lib/signing/middleware.js +9 -0
  76. package/dist/lib/signing/middleware.mjs +14 -0
  77. package/dist/lib/signing/parser.d.mts +8 -5
  78. package/dist/lib/signing/parser.d.ts +8 -5
  79. package/dist/lib/signing/parser.js +77 -61
  80. package/dist/lib/signing/parser.mjs +77 -61
  81. package/dist/lib/signing/revocation.js +3 -0
  82. package/dist/lib/signing/revocation.mjs +3 -0
  83. package/dist/lib/signing/server.d.mts +1 -1
  84. package/dist/lib/signing/server.d.ts +1 -1
  85. package/dist/lib/signing/server.js +2 -0
  86. package/dist/lib/signing/server.mjs +2 -1
  87. package/dist/lib/signing/signer.js +2 -8
  88. package/dist/lib/signing/signer.mjs +3 -9
  89. package/dist/lib/signing/testing.js +2 -6
  90. package/dist/lib/signing/testing.mjs +3 -7
  91. package/dist/lib/signing/verifier.js +3 -3
  92. package/dist/lib/signing/verifier.mjs +4 -4
  93. package/dist/lib/signing/web-bot-auth.d.mts +84 -10
  94. package/dist/lib/signing/web-bot-auth.d.ts +84 -10
  95. package/dist/lib/signing/web-bot-auth.js +278 -88
  96. package/dist/lib/signing/web-bot-auth.mjs +279 -94
  97. package/dist/lib/signing/webhook-verifier.js +3 -3
  98. package/dist/lib/signing/webhook-verifier.mjs +4 -4
  99. package/dist/lib/substitution/compile.js +2 -1
  100. package/dist/lib/substitution/compile.mjs +2 -1
  101. package/dist/lib/substitution/consent-macros.d.mts +4 -0
  102. package/dist/lib/substitution/consent-macros.d.ts +4 -0
  103. package/dist/lib/substitution/consent-macros.js +45 -0
  104. package/dist/lib/substitution/consent-macros.mjs +20 -0
  105. package/dist/lib/substitution/index.d.mts +1 -1
  106. package/dist/lib/substitution/index.d.ts +1 -1
  107. package/dist/lib/substitution/index.js +2 -0
  108. package/dist/lib/substitution/index.mjs +2 -1
  109. package/dist/lib/substitution/translate.d.mts +15 -2
  110. package/dist/lib/substitution/translate.d.ts +15 -2
  111. package/dist/lib/substitution/translate.js +148 -26
  112. package/dist/lib/substitution/translate.mjs +147 -26
  113. package/dist/lib/testing/client.js +2 -1
  114. package/dist/lib/testing/client.mjs +2 -1
  115. package/dist/lib/testing/scenarios/capabilities.js +1 -1
  116. package/dist/lib/testing/scenarios/capabilities.mjs +1 -1
  117. package/dist/lib/testing/storyboard/request-signing/builder.js +2 -5
  118. package/dist/lib/testing/storyboard/request-signing/builder.mjs +3 -6
  119. package/dist/lib/testing/storyboard/signer-grader/grader.js +2 -7
  120. package/dist/lib/testing/storyboard/signer-grader/grader.mjs +2 -7
  121. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  122. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  123. package/dist/lib/types/enums.generated.d.mts +3 -0
  124. package/dist/lib/types/enums.generated.d.ts +3 -0
  125. package/dist/lib/types/enums.generated.js +9 -0
  126. package/dist/lib/types/enums.generated.mjs +6 -0
  127. package/dist/lib/v2/projection/catalog-snapshot.js +3 -1
  128. package/dist/lib/v2/projection/catalog-snapshot.mjs +3 -1
  129. package/dist/lib/v2/projection/creative-delivery.d.mts +31 -9
  130. package/dist/lib/v2/projection/creative-delivery.d.ts +31 -9
  131. package/dist/lib/v2/projection/index.d.mts +1 -1
  132. package/dist/lib/v2/projection/index.d.ts +1 -1
  133. package/dist/lib/v2/projection/index.js +2 -0
  134. package/dist/lib/v2/projection/index.mjs +2 -0
  135. package/dist/lib/v2/projection/legacy-routes.d.mts +10 -0
  136. package/dist/lib/v2/projection/legacy-routes.d.ts +10 -0
  137. package/dist/lib/v2/projection/legacy-routes.js +7 -0
  138. package/dist/lib/v2/projection/legacy-routes.mjs +6 -0
  139. package/dist/lib/validation/schema-loader.js +25 -0
  140. package/dist/lib/validation/schema-loader.mjs +24 -0
  141. package/dist/lib/version.d.mts +3 -3
  142. package/dist/lib/version.d.ts +3 -3
  143. package/dist/lib/version.js +3 -3
  144. package/dist/lib/version.mjs +3 -3
  145. package/docs/TYPE-SUMMARY.md +7 -2
  146. package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +3 -2
  147. package/docs/guides/REPORTING-LEDGER.md +15 -5
  148. package/docs/guides/REPORTING-OPERATIONS.md +17 -11
  149. package/docs/guides/UNIVERSAL-MACRO-COMPILATION.md +38 -0
  150. package/docs/guides/VALIDATE-YOUR-AGENT.md +12 -0
  151. package/docs/llms.txt +2 -2
  152. package/docs/migration-12-to-13.md +8 -0
  153. package/docs/migration-14.x-rc-worksheet.md +4 -4
  154. package/docs/migration-agent-identity-3.3.md +150 -11
  155. package/package.json +4 -1
@@ -1,14 +1,43 @@
1
1
  import { encodeUnreserved } from "./rfc3986.mjs";
2
- const UNIVERSAL_MACRO = /\{[A-Z][A-Z0-9_]*\}/g;
3
- const NATIVE_TOKEN_SHAPE = /^(?:%%.+%%|\{\{.+\}\}|\$\{.+\}|\[[A-Z][A-Z0-9_]*\])$/;
4
- const CONSENT_MACROS = /* @__PURE__ */ new Set([
5
- "{GDPR}",
6
- "{GDPR_CONSENT}",
7
- "{US_PRIVACY}",
8
- "{GPP_STRING}",
9
- "{GPP_SID}",
10
- "{LIMIT_AD_TRACKING}"
11
- ]);
2
+ import { isConsentMacro, isVendorScopedConsentMacro } from "./consent-macros.mjs";
3
+ function* macroTokens(text) {
4
+ const missingClosers = /* @__PURE__ */ new Set();
5
+ let cursor = 0;
6
+ while (cursor < text.length) {
7
+ let end = -1;
8
+ let native = true;
9
+ const close = text.startsWith("%%", cursor) ? "%%" : text.startsWith("{{", cursor) ? "}}" : text.startsWith("${", cursor) ? "}" : null;
10
+ if (close && !missingClosers.has(close)) {
11
+ const closer = text.indexOf(close, cursor + 2);
12
+ if (closer === -1) missingClosers.add(close);
13
+ else end = closer + close.length;
14
+ }
15
+ if (end === -1 && (text[cursor] === "{" || text[cursor] === "[")) {
16
+ let nameEnd = cursor + 1;
17
+ if (/[A-Z]/.test(text[nameEnd] ?? "")) {
18
+ nameEnd += 1;
19
+ while (/[A-Z0-9_]/.test(text[nameEnd] ?? "")) nameEnd += 1;
20
+ if (text[nameEnd] === (text[cursor] === "{" ? "}" : "]")) {
21
+ end = nameEnd + 1;
22
+ native = text[cursor] === "[";
23
+ }
24
+ }
25
+ }
26
+ if (end === -1) {
27
+ cursor += 1;
28
+ continue;
29
+ }
30
+ yield { text: text.slice(cursor, end), start: cursor, end, native };
31
+ cursor = end;
32
+ }
33
+ }
34
+ function hasNativeTokenSyntax(value) {
35
+ for (const token of macroTokens(value)) {
36
+ const minimumLength = token.text.startsWith("${") ? 3 : token.text.startsWith("[") ? 2 : 4;
37
+ if (token.native && token.text.length > minimumLength) return true;
38
+ }
39
+ return false;
40
+ }
12
41
  const UNSAFE_NATIVE_CHARACTER = /[\u0000-\u001F\u007F]/;
13
42
  class UnsafeNativeMappingError extends Error {
14
43
  code = "unsafe_native_mapping";
@@ -22,6 +51,83 @@ class UnsafeNativeMappingError extends Error {
22
51
  this.macro = macro;
23
52
  }
24
53
  }
54
+ class MultipleVendorConsentMacrosError extends Error {
55
+ code = "multiple_vendor_consent_macros";
56
+ macro;
57
+ constructor(macro) {
58
+ super(`Multiple vendor-scoped consent macros; second token is ${JSON.stringify(macro)}`);
59
+ this.name = "MultipleVendorConsentMacrosError";
60
+ this.macro = macro;
61
+ }
62
+ }
63
+ function overlappingRange(ranges, candidate) {
64
+ let low = 0;
65
+ let high = ranges.length;
66
+ while (low < high) {
67
+ const middle = Math.floor((low + high) / 2);
68
+ if (ranges[middle].end <= candidate.start) low = middle + 1;
69
+ else high = middle;
70
+ }
71
+ const range = ranges[low];
72
+ return range && range.start < candidate.end ? range : void 0;
73
+ }
74
+ function assertSingleScopedConsent(spans, mapping) {
75
+ const url = spans.map((span) => span.text).join("");
76
+ const concrete = [];
77
+ const sources = [];
78
+ let offset = 0;
79
+ for (const span of spans) {
80
+ const range = { start: offset, end: offset + span.text.length };
81
+ if (span.concrete && range.start < range.end) {
82
+ const previous = concrete[concrete.length - 1];
83
+ if (previous?.end === range.start) previous.end = range.end;
84
+ else concrete.push(range);
85
+ }
86
+ if (span.scopedSource && span.text.length > 0) sources.push({ ...range, macro: span.scopedSource });
87
+ offset = range.end;
88
+ }
89
+ const occurrences = [];
90
+ const shells = [];
91
+ for (const token of macroTokens(url)) {
92
+ const range = { start: token.start, end: token.end };
93
+ shells.push(range);
94
+ const canonical = token.text.startsWith("${") ? token.text.slice(1) : token.text;
95
+ if (isVendorScopedConsentMacro(canonical)) {
96
+ occurrences.push({ ...range, macro: canonical });
97
+ }
98
+ }
99
+ const aliases = [];
100
+ for (const [macro, entry] of Object.entries(mapping)) {
101
+ if (!isVendorScopedConsentMacro(macro) || !("native" in entry) || entry.native.length === 0) continue;
102
+ let start = url.indexOf(entry.native);
103
+ while (start !== -1) {
104
+ const range = { start, end: start + entry.native.length };
105
+ const shell = overlappingRange(shells, range);
106
+ const completeShell = shell?.start === range.start && shell.end === range.end;
107
+ const insideShell = shell && shell.start <= range.start && range.end <= shell.end && !completeShell;
108
+ const data = overlappingRange(concrete, range);
109
+ const entirelyConcrete = data && data.start <= range.start && range.end <= data.end;
110
+ if (!insideShell && (completeShell || !entirelyConcrete) && !overlappingRange(occurrences, range)) {
111
+ aliases.push({ ...range, macro });
112
+ }
113
+ start = url.indexOf(entry.native, range.end);
114
+ }
115
+ }
116
+ aliases.sort((a, b) => a.start - b.start || b.end - a.end);
117
+ const selectedAliases = [];
118
+ for (const alias of aliases) {
119
+ const previous = selectedAliases[selectedAliases.length - 1];
120
+ if (!previous || previous.end <= alias.start) selectedAliases.push(alias);
121
+ }
122
+ for (const alias of selectedAliases) occurrences.push(alias);
123
+ occurrences.sort((a, b) => a.start - b.start);
124
+ const unmatchedSources = sources.filter((source) => !overlappingRange(occurrences, source));
125
+ for (const source of unmatchedSources) occurrences.push(source);
126
+ occurrences.sort((a, b) => a.start - b.start);
127
+ const second = occurrences[1];
128
+ if (second) throw new MultipleVendorConsentMacrosError(second.macro);
129
+ return url;
130
+ }
25
131
  function translateUniversalMacros(input_pixel_url, mapping) {
26
132
  const suspect_native_values = [];
27
133
  const suspectSeen = /* @__PURE__ */ new Set();
@@ -34,11 +140,11 @@ function translateUniversalMacros(input_pixel_url, mapping) {
34
140
  }
35
141
  continue;
36
142
  }
37
- if (CONSENT_MACROS.has(macro) && !frozenConsentSeen.has(macro)) {
143
+ if (isConsentMacro(macro) && !frozenConsentSeen.has(macro)) {
38
144
  frozenConsentSeen.add(macro);
39
145
  frozen_consent_macros.push(macro);
40
146
  }
41
- if (NATIVE_TOKEN_SHAPE.test(entry.value) && !suspectSeen.has(macro)) {
147
+ if (hasNativeTokenSyntax(entry.value) && !suspectSeen.has(macro)) {
42
148
  suspectSeen.add(macro);
43
149
  suspect_native_values.push(macro);
44
150
  }
@@ -49,7 +155,7 @@ function translateUniversalMacros(input_pixel_url, mapping) {
49
155
  const queryIdx = withoutFragment.indexOf("?");
50
156
  if (queryIdx === -1) {
51
157
  return {
52
- url: input_pixel_url,
158
+ url: assertSingleScopedConsent([{ text: input_pixel_url }], mapping),
53
159
  dropped_params: [],
54
160
  unmapped_macros: [],
55
161
  dropped_consent_macros: [],
@@ -69,12 +175,12 @@ function translateUniversalMacros(input_pixel_url, mapping) {
69
175
  const eqIdx = rawParam.indexOf("=");
70
176
  const key = eqIdx === -1 ? rawParam : rawParam.slice(0, eqIdx);
71
177
  const value = eqIdx === -1 ? "" : rawParam.slice(eqIdx + 1);
72
- const tokens = value.match(UNIVERSAL_MACRO);
73
- if (!tokens) {
74
- outputParts.push(rawParam);
178
+ const tokens = [...macroTokens(value)].filter((token) => !token.native);
179
+ if (tokens.length === 0) {
180
+ outputParts.push([{ text: rawParam }]);
75
181
  continue;
76
182
  }
77
- const missing = tokens.filter((t) => !(t in mapping));
183
+ const missing = tokens.map((token) => token.text).filter((token) => !(token in mapping));
78
184
  if (missing.length > 0) {
79
185
  dropped_params.push(key);
80
186
  for (const m of missing) {
@@ -82,24 +188,38 @@ function translateUniversalMacros(input_pixel_url, mapping) {
82
188
  unmappedSeen.add(m);
83
189
  unmapped_macros.push(m);
84
190
  }
85
- if (CONSENT_MACROS.has(m) && !consentSeen.has(m)) {
191
+ if (isConsentMacro(m) && !consentSeen.has(m)) {
86
192
  consentSeen.add(m);
87
193
  dropped_consent_macros.push(m);
88
194
  }
89
195
  }
90
196
  continue;
91
197
  }
92
- const translated = value.replace(UNIVERSAL_MACRO, (token) => {
198
+ const translated = [{ text: `${key}=` }];
199
+ let cursor = 0;
200
+ for (const match of tokens) {
201
+ const token = match.text;
202
+ translated.push({ text: value.slice(cursor, match.start) });
93
203
  const entry = mapping[token];
94
- if (!entry) {
95
- return token;
204
+ if ("native" in entry) {
205
+ translated.push({
206
+ text: entry.native,
207
+ ...isVendorScopedConsentMacro(token) ? { scopedSource: token } : {}
208
+ });
209
+ } else {
210
+ translated.push({ text: encodeUnreserved(entry.value), concrete: true });
96
211
  }
97
- return "native" in entry ? entry.native : encodeUnreserved(entry.value);
98
- });
99
- outputParts.push(`${key}=${translated}`);
212
+ cursor = match.end;
213
+ }
214
+ translated.push({ text: value.slice(cursor) });
215
+ outputParts.push(translated);
100
216
  }
101
- const newQuery = outputParts.join("&");
102
- const url = newQuery ? `${base}?${newQuery}${fragment}` : `${base}${fragment}`;
217
+ const querySpans = outputParts.flatMap((part, index) => index === 0 ? part : [{ text: "&" }, ...part]);
218
+ const hasQuery = querySpans.some((span) => span.text.length > 0);
219
+ const url = assertSingleScopedConsent(
220
+ [{ text: base }, ...hasQuery ? [{ text: "?" }, ...querySpans] : [], { text: fragment }],
221
+ mapping
222
+ );
103
223
  return {
104
224
  url,
105
225
  dropped_params,
@@ -110,6 +230,7 @@ function translateUniversalMacros(input_pixel_url, mapping) {
110
230
  };
111
231
  }
112
232
  export {
233
+ MultipleVendorConsentMacrosError,
113
234
  UnsafeNativeMappingError,
114
235
  translateUniversalMacros
115
236
  };
@@ -55,6 +55,7 @@ var import_protocols = require('../protocols/index.js');
55
55
  var import_node_crypto = require("node:crypto");
56
56
  var import_node_async_hooks = require("node:async_hooks");
57
57
  var import_client_hooks = require('../validation/client-hooks.js');
58
+ var import_schema_loader = require('../validation/schema-loader.js');
58
59
  var import_error_extraction = require('../utils/error-extraction.js');
59
60
  var import_client = require('../signing/client.js');
60
61
  var import_storage_registry = require('../auth/oauth/storage-registry.js');
@@ -534,7 +535,7 @@ async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
534
535
  caps.data,
535
536
  "strict",
536
537
  void 0,
537
- schemaAdcpVersion ?? client.getAdcpVersion()
538
+ (0, import_schema_loader.resolveServedValidationVersion)(caps.data, schemaAdcpVersion ?? client.getAdcpVersion())
538
539
  );
539
540
  if (!validation.valid) {
540
541
  profile.capabilities_schema_issues = validation.issues.map((issue) => ({
@@ -12,6 +12,7 @@ import { normalizeTransportOptions } from "../protocols/index.mjs";
12
12
  import { createHmac, hkdfSync, randomBytes } from "node:crypto";
13
13
  import { AsyncLocalStorage } from "node:async_hooks";
14
14
  import { validateIncomingResponse } from "../validation/client-hooks.mjs";
15
+ import { resolveServedValidationVersion } from "../validation/schema-loader.mjs";
15
16
  import { extractVersionUnsupportedDetails } from "../utils/error-extraction.mjs";
16
17
  import { buildAgentSigningContext } from "../signing/client.mjs";
17
18
  import { bindAgentStorage } from "../auth/oauth/storage-registry.mjs";
@@ -491,7 +492,7 @@ async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
491
492
  caps.data,
492
493
  "strict",
493
494
  void 0,
494
- schemaAdcpVersion ?? client.getAdcpVersion()
495
+ resolveServedValidationVersion(caps.data, schemaAdcpVersion ?? client.getAdcpVersion())
495
496
  );
496
497
  if (!validation.valid) {
497
498
  profile.capabilities_schema_issues = validation.issues.map((issue) => ({
@@ -239,7 +239,7 @@ function crossValidateProtocolsAndTools(capabilities, tools) {
239
239
  creative: import_capabilities.CREATIVE_TOOLS,
240
240
  sponsored_intelligence: import_capabilities.SPONSORED_INTELLIGENCE_TOOLS,
241
241
  trusted_match: import_capabilities.TRUSTED_MATCH_TOOLS,
242
- compliance: import_capabilities.COMPLIANCE_TOOLS
242
+ compliance_testing: import_capabilities.COMPLIANCE_TOOLS
243
243
  };
244
244
  const perProtocolDiffs = {};
245
245
  for (const protocol of capabilities.protocols) {
@@ -225,7 +225,7 @@ function crossValidateProtocolsAndTools(capabilities, tools) {
225
225
  creative: CREATIVE_TOOLS,
226
226
  sponsored_intelligence: SPONSORED_INTELLIGENCE_TOOLS,
227
227
  trusted_match: TRUSTED_MATCH_TOOLS,
228
- compliance: COMPLIANCE_TOOLS
228
+ compliance_testing: COMPLIANCE_TOOLS
229
229
  };
230
230
  const perProtocolDiffs = {};
231
231
  for (const protocol of capabilities.protocols) {
@@ -24,6 +24,7 @@ __export(builder_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(builder_exports);
26
26
  var import_crypto = require("crypto");
27
+ var import_crypto2 = require('../../../signing/crypto.js');
27
28
  var import_signing = require('../../../signing/index.js');
28
29
  var import_vector_loader = require('./vector-loader.js');
29
30
  function buildPositiveRequest(vector, keys, options = {}) {
@@ -571,11 +572,7 @@ function formatParamsWithOmissions(components, params, override) {
571
572
  return `(${componentList});${pairs.join(";")}`;
572
573
  }
573
574
  function produceSignature(key, data) {
574
- const privateKey = (0, import_crypto.createPrivateKey)({ key: key.privateKey, format: "jwk" });
575
- if (key.alg === "ed25519") {
576
- return new Uint8Array((0, import_crypto.sign)(null, data, privateKey));
577
- }
578
- return new Uint8Array((0, import_crypto.sign)("sha256", data, { key: privateKey, dsaEncoding: "ieee-p1363" }));
575
+ return (0, import_crypto2.signWithPrivateJwk)(key.alg, key.privateKey, data);
579
576
  }
580
577
  function signerKeyFor(vector, keys) {
581
578
  const kid = vector.jwks_ref?.[0];
@@ -1,4 +1,5 @@
1
- import { createHash, createPrivateKey, randomBytes, randomUUID, sign as nodeSign } from "crypto";
1
+ import { createHash, randomBytes, randomUUID } from "crypto";
2
+ import { signWithPrivateJwk } from "../../../signing/crypto.mjs";
2
3
  import {
3
4
  buildSignatureBase,
4
5
  computeContentDigest,
@@ -554,11 +555,7 @@ function formatParamsWithOmissions(components, params, override) {
554
555
  return `(${componentList});${pairs.join(";")}`;
555
556
  }
556
557
  function produceSignature(key, data) {
557
- const privateKey = createPrivateKey({ key: key.privateKey, format: "jwk" });
558
- if (key.alg === "ed25519") {
559
- return new Uint8Array(nodeSign(null, data, privateKey));
560
- }
561
- return new Uint8Array(nodeSign("sha256", data, { key: privateKey, dsaEncoding: "ieee-p1363" }));
558
+ return signWithPrivateJwk(key.alg, key.privateKey, data);
562
559
  }
563
560
  function signerKeyFor(vector, keys) {
564
561
  const kid = vector.jwks_ref?.[0];
@@ -22,7 +22,7 @@ __export(grader_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(grader_exports);
24
24
  var import_promises = require("node:fs/promises");
25
- var import_node_crypto = require("node:crypto");
25
+ var import_crypto = require('../../../signing/crypto.js');
26
26
  var import_signing = require('../../../signing/index.js');
27
27
  var import_ssrf_fetch = require('../../../net/ssrf-fetch.js');
28
28
  var import_content_digest = require('../../../signing/content-digest.js');
@@ -175,12 +175,7 @@ async function keyFileProvider(filePath, kid, algorithm) {
175
175
  algorithm,
176
176
  fingerprint: `key-file:${kid}`,
177
177
  async sign(payload) {
178
- const privateKey = (0, import_node_crypto.createPrivateKey)({ key: jwk, format: "jwk" });
179
- const data = Buffer.from(payload);
180
- if (algorithm === "ed25519") {
181
- return new Uint8Array((0, import_node_crypto.sign)(null, data, privateKey));
182
- }
183
- return new Uint8Array((0, import_node_crypto.sign)("sha256", data, { key: privateKey, dsaEncoding: "ieee-p1363" }));
178
+ return (0, import_crypto.signWithPrivateJwkAsync)(algorithm, jwk, payload);
184
179
  }
185
180
  };
186
181
  }
@@ -1,5 +1,5 @@
1
1
  import { readFile } from "node:fs/promises";
2
- import { createPrivateKey, sign as nodeSign } from "node:crypto";
2
+ import { signWithPrivateJwkAsync } from "../../../signing/crypto.mjs";
3
3
  import {
4
4
  HttpsJwksResolver,
5
5
  InMemoryReplayStore,
@@ -159,12 +159,7 @@ async function keyFileProvider(filePath, kid, algorithm) {
159
159
  algorithm,
160
160
  fingerprint: `key-file:${kid}`,
161
161
  async sign(payload) {
162
- const privateKey = createPrivateKey({ key: jwk, format: "jwk" });
163
- const data = Buffer.from(payload);
164
- if (algorithm === "ed25519") {
165
- return new Uint8Array(nodeSign(null, data, privateKey));
166
- }
167
- return new Uint8Array(nodeSign("sha256", data, { key: privateKey, dsaEncoding: "ieee-p1363" }));
162
+ return signWithPrivateJwkAsync(algorithm, jwk, payload);
168
163
  }
169
164
  };
170
165
  }
@@ -197,7 +197,7 @@ export interface UpstreamTrafficQueryResult {
197
197
  */
198
198
  export declare function runValidations(validations: StoryboardValidation[], context: ValidationContext): ValidationResult[];
199
199
  /** Capability semver emitted in run summaries and used for advisory expiry. */
200
- export declare const RUNNER_CAPABILITY_VERSION = "16.0.0-beta.1";
200
+ export declare const RUNNER_CAPABILITY_VERSION = "16.0.0-beta.3";
201
201
  /** True when a failed validation contributes to the owning step's grade. */
202
202
  export declare function validationFailsStep(result: ValidationResult): boolean;
203
203
  /**
@@ -197,7 +197,7 @@ export interface UpstreamTrafficQueryResult {
197
197
  */
198
198
  export declare function runValidations(validations: StoryboardValidation[], context: ValidationContext): ValidationResult[];
199
199
  /** Capability semver emitted in run summaries and used for advisory expiry. */
200
- export declare const RUNNER_CAPABILITY_VERSION = "16.0.0-beta.1";
200
+ export declare const RUNNER_CAPABILITY_VERSION = "16.0.0-beta.3";
201
201
  /** True when a failed validation contributes to the owning step's grade. */
202
202
  export declare function validationFailsStep(result: ValidationResult): boolean;
203
203
  /**
@@ -98,6 +98,8 @@ export declare const FrequencyCapDurationUnitValues: readonly ["seconds", "minut
98
98
  export declare const FrequencyCapMutableFieldValues: readonly ["max_impressions", "per", "window", "suppress"];
99
99
  export declare const FrequencyCapScopeValues: readonly ["package"];
100
100
  export declare const GenreTaxonomyValues: readonly ["iab_content_3.0", "iab_content_2.2", "gracenote", "eidr", "apple_genres", "google_genres", "roku", "amazon_genres", "custom"];
101
+ export declare const GeographicPlaceIdentifierSystemValues: readonly ["geonames", "google_ads", "microsoft_ads"];
102
+ export declare const GeographicPlaceTypeValues: readonly ["airport", "borough", "city", "city_region", "commune", "county", "district", "municipality", "neighborhood", "post_town", "prefecture", "province", "quarter", "state", "territory", "ward"];
101
103
  export declare const GeographicTargetingLevelValues: readonly ["country", "region", "metro", "postal_area"];
102
104
  export declare const GOPTypeValues: readonly ["closed", "open"];
103
105
  export declare const GovernanceDecisionValues: readonly ["approved", "denied", "conditions"];
@@ -200,6 +202,7 @@ export declare const SortMetricValues: readonly ["impressions", "spend", "clicks
200
202
  export declare const SpecialCategoryValues: readonly ["awards", "championship", "concert", "conference", "election", "festival", "gala", "holiday", "premiere", "product_launch", "reunion", "tribute"];
201
203
  export declare const SponsoredPlacementTypeValues: readonly ["sponsored_search", "sponsored_display", "sponsored_native"];
202
204
  export declare const StandardScopeValues: readonly ["attestation_verifier"];
205
+ export declare const StartTimingValues: readonly ["asap"];
203
206
  export declare const StoryboardStatusValues: readonly ["passing", "failing", "partial", "untested", "skipped", "not_selected", "unknown"];
204
207
  export declare const TalentRoleValues: readonly ["host", "guest", "creator", "cast", "narrator", "producer", "correspondent", "commentator", "analyst"];
205
208
  export declare const TaskStatusValues: readonly ["submitted", "working", "input-required", "completed", "canceled", "failed", "rejected", "auth-required", "unknown"];
@@ -98,6 +98,8 @@ export declare const FrequencyCapDurationUnitValues: readonly ["seconds", "minut
98
98
  export declare const FrequencyCapMutableFieldValues: readonly ["max_impressions", "per", "window", "suppress"];
99
99
  export declare const FrequencyCapScopeValues: readonly ["package"];
100
100
  export declare const GenreTaxonomyValues: readonly ["iab_content_3.0", "iab_content_2.2", "gracenote", "eidr", "apple_genres", "google_genres", "roku", "amazon_genres", "custom"];
101
+ export declare const GeographicPlaceIdentifierSystemValues: readonly ["geonames", "google_ads", "microsoft_ads"];
102
+ export declare const GeographicPlaceTypeValues: readonly ["airport", "borough", "city", "city_region", "commune", "county", "district", "municipality", "neighborhood", "post_town", "prefecture", "province", "quarter", "state", "territory", "ward"];
101
103
  export declare const GeographicTargetingLevelValues: readonly ["country", "region", "metro", "postal_area"];
102
104
  export declare const GOPTypeValues: readonly ["closed", "open"];
103
105
  export declare const GovernanceDecisionValues: readonly ["approved", "denied", "conditions"];
@@ -200,6 +202,7 @@ export declare const SortMetricValues: readonly ["impressions", "spend", "clicks
200
202
  export declare const SpecialCategoryValues: readonly ["awards", "championship", "concert", "conference", "election", "festival", "gala", "holiday", "premiere", "product_launch", "reunion", "tribute"];
201
203
  export declare const SponsoredPlacementTypeValues: readonly ["sponsored_search", "sponsored_display", "sponsored_native"];
202
204
  export declare const StandardScopeValues: readonly ["attestation_verifier"];
205
+ export declare const StartTimingValues: readonly ["asap"];
203
206
  export declare const StoryboardStatusValues: readonly ["passing", "failing", "partial", "untested", "skipped", "not_selected", "unknown"];
204
207
  export declare const TalentRoleValues: readonly ["host", "guest", "creator", "cast", "narrator", "producer", "correspondent", "commentator", "analyst"];
205
208
  export declare const TaskStatusValues: readonly ["submitted", "working", "input-required", "completed", "canceled", "failed", "rejected", "auth-required", "unknown"];
@@ -121,6 +121,8 @@ __export(enums_generated_exports, {
121
121
  FrequencyCapScopeValues: () => FrequencyCapScopeValues,
122
122
  GOPTypeValues: () => GOPTypeValues,
123
123
  GenreTaxonomyValues: () => GenreTaxonomyValues,
124
+ GeographicPlaceIdentifierSystemValues: () => GeographicPlaceIdentifierSystemValues,
125
+ GeographicPlaceTypeValues: () => GeographicPlaceTypeValues,
124
126
  GeographicTargetingLevelValues: () => GeographicTargetingLevelValues,
125
127
  GovernanceDecisionValues: () => GovernanceDecisionValues,
126
128
  GovernanceDomainValues: () => GovernanceDomainValues,
@@ -223,6 +225,7 @@ __export(enums_generated_exports, {
223
225
  SpecialCategoryValues: () => SpecialCategoryValues,
224
226
  SponsoredPlacementTypeValues: () => SponsoredPlacementTypeValues,
225
227
  StandardScopeValues: () => StandardScopeValues,
228
+ StartTimingValues: () => StartTimingValues,
226
229
  StoryboardStatusValues: () => StoryboardStatusValues,
227
230
  TMPResponseTypeValues: () => TMPResponseTypeValues,
228
231
  TalentRoleValues: () => TalentRoleValues,
@@ -354,6 +357,8 @@ const FrequencyCapDurationUnitValues = ["seconds", "minutes", "hours", "days", "
354
357
  const FrequencyCapMutableFieldValues = ["max_impressions", "per", "window", "suppress"];
355
358
  const FrequencyCapScopeValues = ["package"];
356
359
  const GenreTaxonomyValues = ["iab_content_3.0", "iab_content_2.2", "gracenote", "eidr", "apple_genres", "google_genres", "roku", "amazon_genres", "custom"];
360
+ const GeographicPlaceIdentifierSystemValues = ["geonames", "google_ads", "microsoft_ads"];
361
+ const GeographicPlaceTypeValues = ["airport", "borough", "city", "city_region", "commune", "county", "district", "municipality", "neighborhood", "post_town", "prefecture", "province", "quarter", "state", "territory", "ward"];
357
362
  const GeographicTargetingLevelValues = ["country", "region", "metro", "postal_area"];
358
363
  const GOPTypeValues = ["closed", "open"];
359
364
  const GovernanceDecisionValues = ["approved", "denied", "conditions"];
@@ -455,6 +460,7 @@ const SortMetricValues = ["impressions", "spend", "clicks", "ctr", "views", "com
455
460
  const SpecialCategoryValues = ["awards", "championship", "concert", "conference", "election", "festival", "gala", "holiday", "premiere", "product_launch", "reunion", "tribute"];
456
461
  const SponsoredPlacementTypeValues = ["sponsored_search", "sponsored_display", "sponsored_native"];
457
462
  const StandardScopeValues = ["attestation_verifier"];
463
+ const StartTimingValues = ["asap"];
458
464
  const StoryboardStatusValues = ["passing", "failing", "partial", "untested", "skipped", "not_selected", "unknown"];
459
465
  const TalentRoleValues = ["host", "guest", "creator", "cast", "narrator", "producer", "correspondent", "commentator", "analyst"];
460
466
  const TaskStatusValues = ["submitted", "working", "input-required", "completed", "canceled", "failed", "rejected", "auth-required", "unknown"];
@@ -712,6 +718,8 @@ const RequestSigningErrorCodeMetadata = Object.freeze(requestSigningErrorCodeMet
712
718
  FrequencyCapScopeValues,
713
719
  GOPTypeValues,
714
720
  GenreTaxonomyValues,
721
+ GeographicPlaceIdentifierSystemValues,
722
+ GeographicPlaceTypeValues,
715
723
  GeographicTargetingLevelValues,
716
724
  GovernanceDecisionValues,
717
725
  GovernanceDomainValues,
@@ -814,6 +822,7 @@ const RequestSigningErrorCodeMetadata = Object.freeze(requestSigningErrorCodeMet
814
822
  SpecialCategoryValues,
815
823
  SponsoredPlacementTypeValues,
816
824
  StandardScopeValues,
825
+ StartTimingValues,
817
826
  StoryboardStatusValues,
818
827
  TMPResponseTypeValues,
819
828
  TalentRoleValues,
@@ -98,6 +98,8 @@ const FrequencyCapDurationUnitValues = ["seconds", "minutes", "hours", "days", "
98
98
  const FrequencyCapMutableFieldValues = ["max_impressions", "per", "window", "suppress"];
99
99
  const FrequencyCapScopeValues = ["package"];
100
100
  const GenreTaxonomyValues = ["iab_content_3.0", "iab_content_2.2", "gracenote", "eidr", "apple_genres", "google_genres", "roku", "amazon_genres", "custom"];
101
+ const GeographicPlaceIdentifierSystemValues = ["geonames", "google_ads", "microsoft_ads"];
102
+ const GeographicPlaceTypeValues = ["airport", "borough", "city", "city_region", "commune", "county", "district", "municipality", "neighborhood", "post_town", "prefecture", "province", "quarter", "state", "territory", "ward"];
101
103
  const GeographicTargetingLevelValues = ["country", "region", "metro", "postal_area"];
102
104
  const GOPTypeValues = ["closed", "open"];
103
105
  const GovernanceDecisionValues = ["approved", "denied", "conditions"];
@@ -199,6 +201,7 @@ const SortMetricValues = ["impressions", "spend", "clicks", "ctr", "views", "com
199
201
  const SpecialCategoryValues = ["awards", "championship", "concert", "conference", "election", "festival", "gala", "holiday", "premiere", "product_launch", "reunion", "tribute"];
200
202
  const SponsoredPlacementTypeValues = ["sponsored_search", "sponsored_display", "sponsored_native"];
201
203
  const StandardScopeValues = ["attestation_verifier"];
204
+ const StartTimingValues = ["asap"];
202
205
  const StoryboardStatusValues = ["passing", "failing", "partial", "untested", "skipped", "not_selected", "unknown"];
203
206
  const TalentRoleValues = ["host", "guest", "creator", "cast", "narrator", "producer", "correspondent", "commentator", "analyst"];
204
207
  const TaskStatusValues = ["submitted", "working", "input-required", "completed", "canceled", "failed", "rejected", "auth-required", "unknown"];
@@ -455,6 +458,8 @@ export {
455
458
  FrequencyCapScopeValues,
456
459
  GOPTypeValues,
457
460
  GenreTaxonomyValues,
461
+ GeographicPlaceIdentifierSystemValues,
462
+ GeographicPlaceTypeValues,
458
463
  GeographicTargetingLevelValues,
459
464
  GovernanceDecisionValues,
460
465
  GovernanceDomainValues,
@@ -557,6 +562,7 @@ export {
557
562
  SpecialCategoryValues,
558
563
  SponsoredPlacementTypeValues,
559
564
  StandardScopeValues,
565
+ StartTimingValues,
560
566
  StoryboardStatusValues,
561
567
  TMPResponseTypeValues,
562
568
  TalentRoleValues,
@@ -25,6 +25,7 @@ __export(catalog_snapshot_exports, {
25
25
  module.exports = __toCommonJS(catalog_snapshot_exports);
26
26
  var import_resolve_agent_properties = require('../../discovery/resolve-agent-properties.js');
27
27
  var import_canonical_properties = require('./canonical-properties.js');
28
+ var import_legacy_routes = require('./legacy-routes.js');
28
29
  const compiledSnapshotCache = /* @__PURE__ */ new WeakMap();
29
30
  function normalizedAgentUrl(value) {
30
31
  return (0, import_resolve_agent_properties.canonicalizeAgentUrl)(value) ?? value;
@@ -202,7 +203,7 @@ function legacyFormatConverterFromCatalogSnapshots(snapshots, fallback) {
202
203
  function canonicalFormatLegacyResolverFromCatalogSnapshots(snapshots, fallback) {
203
204
  if (!snapshots || snapshots.length === 0) return fallback;
204
205
  const compiled = compileProjectionCatalogSnapshots(snapshots);
205
- return (context) => {
206
+ const resolver = (context) => {
206
207
  const refs = resolutionContextFormatOptionRefs(context);
207
208
  if (refs.length === 0) return fallback?.(context);
208
209
  const resolved = [];
@@ -225,6 +226,7 @@ function canonicalFormatLegacyResolverFromCatalogSnapshots(snapshots, fallback)
225
226
  }
226
227
  return [...new Map(resolved.map((ref) => [legacyRefKey(ref), ref])).values()];
227
228
  };
229
+ return (0, import_legacy_routes.carryFormatOptionOrigins)(resolver, fallback);
228
230
  }
229
231
  function assertBidirectionalProjectionCatalogs(snapshots) {
230
232
  const routeByCanonicalOption = /* @__PURE__ */ new Map();
@@ -1,5 +1,6 @@
1
1
  import { canonicalizeAgentUrl } from "../../discovery/resolve-agent-properties.mjs";
2
2
  import { isCanonicalV1Translatable } from "./canonical-properties.mjs";
3
+ import { carryFormatOptionOrigins } from "./legacy-routes.mjs";
3
4
  const compiledSnapshotCache = /* @__PURE__ */ new WeakMap();
4
5
  function normalizedAgentUrl(value) {
5
6
  return canonicalizeAgentUrl(value) ?? value;
@@ -177,7 +178,7 @@ function legacyFormatConverterFromCatalogSnapshots(snapshots, fallback) {
177
178
  function canonicalFormatLegacyResolverFromCatalogSnapshots(snapshots, fallback) {
178
179
  if (!snapshots || snapshots.length === 0) return fallback;
179
180
  const compiled = compileProjectionCatalogSnapshots(snapshots);
180
- return (context) => {
181
+ const resolver = (context) => {
181
182
  const refs = resolutionContextFormatOptionRefs(context);
182
183
  if (refs.length === 0) return fallback?.(context);
183
184
  const resolved = [];
@@ -200,6 +201,7 @@ function canonicalFormatLegacyResolverFromCatalogSnapshots(snapshots, fallback)
200
201
  }
201
202
  return [...new Map(resolved.map((ref) => [legacyRefKey(ref), ref])).values()];
202
203
  };
204
+ return carryFormatOptionOrigins(resolver, fallback);
203
205
  }
204
206
  function assertBidirectionalProjectionCatalogs(snapshots) {
205
207
  const routeByCanonicalOption = /* @__PURE__ */ new Map();
@@ -78,16 +78,38 @@ export type CanonicalCreateMediaBuyRequest = Omit<CanonicalCreativeResponse<Crea
78
78
  packages?: CanonicalPackageRequest[];
79
79
  };
80
80
  type CanonicalReportingWebhook = NonNullable<CanonicalCreateMediaBuyRequest['reporting_webhook']>;
81
- type ReportingWebhookPreferences = Omit<CanonicalReportingWebhook, 'url' | 'authentication' | 'reporting_frequency'> & {
82
- reporting_frequency?: CanonicalReportingWebhook['reporting_frequency'];
81
+ /**
82
+ * Client-facing form of a wire reporting webhook `W`. Every field is optional:
83
+ * the SDK can supply the callback `url`, `reporting_frequency` and the
84
+ * `authentication` block from client configuration.
85
+ *
86
+ * `authentication` is optional even with a caller-supplied `url`. AdCP 3.3
87
+ * makes it optional on the wire when the seller signs webhooks under its
88
+ * profile (`webhook_signing.supported`), and the experimental 3.3 client sends
89
+ * the registration without it once it has negotiated that. Below 3.3 the wire
90
+ * still requires it: with `webhookUrlTemplate` configured the client throws
91
+ * rather than send a caller URL without credentials (it never pairs its own
92
+ * `webhookSecret` with a caller-controlled host), and request validation
93
+ * reports the missing field otherwise.
94
+ *
95
+ * Derived from `W` rather than restating its fields, so it accepts every
96
+ * reporting webhook the pinned schemas generate, whether they declare
97
+ * `authentication` required (3.2) or optional (3.3).
98
+ *
99
+ * Exported for the type tests only; not re-exported from the package root.
100
+ */
101
+ export type ClientReportingWebhookInputFor<W extends {
102
+ url: string;
103
+ reporting_frequency: unknown;
104
+ }> = Omit<W, 'url' | 'authentication' | 'reporting_frequency'> & {
105
+ url?: W['url'];
106
+ reporting_frequency?: W['reporting_frequency'];
107
+ /** Atomic: `schemes` and `credentials` always come from the same source. */
108
+ authentication?: W extends {
109
+ authentication?: infer A;
110
+ } ? (unknown extends A ? never : A) : never;
83
111
  };
84
- type ClientReportingWebhookInput = (ReportingWebhookPreferences & {
85
- url?: never;
86
- authentication?: CanonicalReportingWebhook['authentication'];
87
- }) | (ReportingWebhookPreferences & {
88
- url: CanonicalReportingWebhook['url'];
89
- authentication: CanonicalReportingWebhook['authentication'];
90
- });
112
+ type ClientReportingWebhookInput = ClientReportingWebhookInputFor<CanonicalReportingWebhook>;
91
113
  /**
92
114
  * Client-facing create request. The SDK may supply the reporting callback URL
93
115
  * and its complete authentication block from client configuration; the wire