@adcp/sdk 16.5.0 → 16.6.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.
Files changed (236) hide show
  1. package/dist/lib/adapters/version/3.0/brand-fields.d.mts +7 -1
  2. package/dist/lib/adapters/version/3.0/brand-fields.d.ts +7 -1
  3. package/dist/lib/adapters/version/3.0/brand-fields.js +139 -3
  4. package/dist/lib/adapters/version/3.0/brand-fields.mjs +136 -2
  5. package/dist/lib/adapters/version/3.0/index.js +6 -0
  6. package/dist/lib/adapters/version/3.0/index.mjs +7 -1
  7. package/dist/lib/adapters/version/3.1/bidding.js +1 -1
  8. package/dist/lib/adapters/version/3.1/bidding.mjs +1 -1
  9. package/dist/lib/adapters/version/types.d.mts +5 -0
  10. package/dist/lib/adapters/version/types.d.ts +5 -0
  11. package/dist/lib/canonical-references/index.js +2 -0
  12. package/dist/lib/canonical-references/index.mjs +2 -0
  13. package/dist/lib/client/account-changes.d.mts +3 -1
  14. package/dist/lib/client/account-changes.d.ts +3 -1
  15. package/dist/lib/client/account-changes.js +22 -2
  16. package/dist/lib/client/account-changes.mjs +22 -2
  17. package/dist/lib/conformance/oracle.js +3 -2
  18. package/dist/lib/conformance/oracle.mjs +3 -2
  19. package/dist/lib/core/AgentClient.d.mts +165 -1
  20. package/dist/lib/core/AgentClient.d.ts +165 -1
  21. package/dist/lib/core/AgentClient.js +446 -8
  22. package/dist/lib/core/AgentClient.mjs +446 -8
  23. package/dist/lib/core/ConversationTypes.d.mts +8 -0
  24. package/dist/lib/core/ConversationTypes.d.ts +8 -0
  25. package/dist/lib/core/ProtocolResponseParser.d.mts +1 -1
  26. package/dist/lib/core/ProtocolResponseParser.d.ts +1 -1
  27. package/dist/lib/core/ProtocolResponseParser.js +28 -18
  28. package/dist/lib/core/ProtocolResponseParser.mjs +11 -1
  29. package/dist/lib/core/ResponseValidator.js +1 -1
  30. package/dist/lib/core/ResponseValidator.mjs +1 -1
  31. package/dist/lib/core/SingleAgentClient.d.mts +116 -6
  32. package/dist/lib/core/SingleAgentClient.d.ts +116 -6
  33. package/dist/lib/core/SingleAgentClient.js +556 -84
  34. package/dist/lib/core/SingleAgentClient.mjs +545 -72
  35. package/dist/lib/core/TaskExecutor.d.mts +7 -0
  36. package/dist/lib/core/TaskExecutor.d.ts +7 -0
  37. package/dist/lib/core/TaskExecutor.js +23 -8
  38. package/dist/lib/core/TaskExecutor.mjs +23 -8
  39. package/dist/lib/core/task-status.d.mts +2 -0
  40. package/dist/lib/core/task-status.d.ts +2 -0
  41. package/dist/lib/core/task-status.js +11 -2
  42. package/dist/lib/core/task-status.mjs +9 -1
  43. package/dist/lib/errors/index.d.mts +22 -0
  44. package/dist/lib/errors/index.d.ts +22 -0
  45. package/dist/lib/errors/index.js +43 -0
  46. package/dist/lib/errors/index.mjs +42 -0
  47. package/dist/lib/identity-3.3/trust.d.mts +1 -4
  48. package/dist/lib/identity-3.3/trust.d.ts +1 -4
  49. package/dist/lib/identity-3.3/trust.js +34 -21
  50. package/dist/lib/identity-3.3/trust.mjs +34 -21
  51. package/dist/lib/identity-3.3/validation.js +5 -3
  52. package/dist/lib/identity-3.3/validation.mjs +6 -4
  53. package/dist/lib/index.d.mts +8 -54
  54. package/dist/lib/index.d.ts +8 -54
  55. package/dist/lib/index.js +15 -0
  56. package/dist/lib/index.mjs +11 -0
  57. package/dist/lib/media-buy/action-assessment.js +29 -3
  58. package/dist/lib/media-buy/action-assessment.mjs +32 -4
  59. package/dist/lib/media-buy/action-contracts.d.mts +3 -0
  60. package/dist/lib/media-buy/action-contracts.d.ts +3 -0
  61. package/dist/lib/media-buy/action-contracts.js +24 -1
  62. package/dist/lib/media-buy/action-contracts.mjs +22 -1
  63. package/dist/lib/media-buy/compatibility.js +6 -1
  64. package/dist/lib/media-buy/compatibility.mjs +6 -1
  65. package/dist/lib/media-buy/preflight.js +1 -1
  66. package/dist/lib/media-buy/preflight.mjs +3 -2
  67. package/dist/lib/media-buy/types.d.mts +6 -1
  68. package/dist/lib/media-buy/types.d.ts +6 -1
  69. package/dist/lib/protocols/mcp-modern.d.mts +2 -0
  70. package/dist/lib/protocols/mcp-modern.d.ts +2 -0
  71. package/dist/lib/protocols/mcp-modern.js +31 -5
  72. package/dist/lib/protocols/mcp-modern.mjs +31 -5
  73. package/dist/lib/protocols/mcp-scope.d.mts +6 -1
  74. package/dist/lib/protocols/mcp-scope.d.ts +6 -1
  75. package/dist/lib/protocols/mcp-scope.js +25 -3
  76. package/dist/lib/protocols/mcp-scope.mjs +24 -3
  77. package/dist/lib/protocols/mcp.js +12 -6
  78. package/dist/lib/protocols/mcp.mjs +13 -6
  79. package/dist/lib/reporting/inspection.js +1 -0
  80. package/dist/lib/reporting/inspection.mjs +1 -0
  81. package/dist/lib/schemas/browser.d.mts +2 -0
  82. package/dist/lib/schemas/browser.d.ts +2 -0
  83. package/dist/lib/schemas/browser.js +3 -0
  84. package/dist/lib/schemas/browser.mjs +2 -0
  85. package/dist/lib/schemas/index.d.mts +5 -2
  86. package/dist/lib/schemas/index.d.ts +5 -2
  87. package/dist/lib/schemas/index.js +5 -0
  88. package/dist/lib/schemas/index.mjs +4 -0
  89. package/dist/lib/server/account-response-identity.d.mts +17 -0
  90. package/dist/lib/server/account-response-identity.d.ts +17 -0
  91. package/dist/lib/server/account-response-identity.js +52 -0
  92. package/dist/lib/server/account-response-identity.mjs +28 -0
  93. package/dist/lib/server/account-sync-contract.js +1 -0
  94. package/dist/lib/server/account-sync-contract.mjs +1 -0
  95. package/dist/lib/server/create-adcp-server.js +32 -19
  96. package/dist/lib/server/create-adcp-server.mjs +36 -12
  97. package/dist/lib/server/decisioning/account.d.mts +13 -6
  98. package/dist/lib/server/decisioning/account.d.ts +13 -6
  99. package/dist/lib/server/decisioning/account.js +37 -15
  100. package/dist/lib/server/decisioning/account.mjs +37 -15
  101. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -5
  102. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -5
  103. package/dist/lib/server/decisioning/runtime/from-platform.js +6 -6
  104. package/dist/lib/server/decisioning/runtime/from-platform.mjs +6 -6
  105. package/dist/lib/server/index.d.mts +1 -1
  106. package/dist/lib/server/index.d.ts +1 -1
  107. package/dist/lib/server/index.js +2 -0
  108. package/dist/lib/server/index.mjs +2 -0
  109. package/dist/lib/server/media-buy-action-resolver.d.mts +3 -0
  110. package/dist/lib/server/media-buy-action-resolver.d.ts +3 -0
  111. package/dist/lib/server/media-buy-action-resolver.js +32 -0
  112. package/dist/lib/server/media-buy-action-resolver.mjs +32 -0
  113. package/dist/lib/server/media-buy-store.d.mts +26 -12
  114. package/dist/lib/server/media-buy-store.d.ts +26 -12
  115. package/dist/lib/server/media-buy-store.js +69 -21
  116. package/dist/lib/server/media-buy-store.mjs +69 -21
  117. package/dist/lib/server/responses.js +9 -1
  118. package/dist/lib/server/responses.mjs +9 -1
  119. package/dist/lib/server/state-machine.d.mts +10 -11
  120. package/dist/lib/server/state-machine.d.ts +10 -11
  121. package/dist/lib/server/state-machine.js +20 -5
  122. package/dist/lib/server/state-machine.mjs +19 -5
  123. package/dist/lib/signing/agent-fetch.d.mts +1 -1
  124. package/dist/lib/signing/agent-fetch.d.ts +1 -1
  125. package/dist/lib/signing/agent-fetch.js +3 -3
  126. package/dist/lib/signing/agent-fetch.mjs +3 -3
  127. package/dist/lib/testing/client.d.mts +1 -0
  128. package/dist/lib/testing/client.d.ts +1 -0
  129. package/dist/lib/testing/client.js +6 -5
  130. package/dist/lib/testing/client.mjs +6 -5
  131. package/dist/lib/testing/storyboard/canonical-format-satisfaction.js +60 -14
  132. package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +60 -14
  133. package/dist/lib/testing/storyboard/compliance.d.mts +2 -5
  134. package/dist/lib/testing/storyboard/compliance.d.ts +2 -5
  135. package/dist/lib/testing/storyboard/compliance.js +62 -13
  136. package/dist/lib/testing/storyboard/compliance.mjs +63 -14
  137. package/dist/lib/testing/storyboard/context.d.mts +13 -3
  138. package/dist/lib/testing/storyboard/context.d.ts +13 -3
  139. package/dist/lib/testing/storyboard/context.js +15 -10
  140. package/dist/lib/testing/storyboard/context.mjs +15 -10
  141. package/dist/lib/testing/storyboard/default-invariants.js +10 -8
  142. package/dist/lib/testing/storyboard/default-invariants.mjs +11 -9
  143. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
  144. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
  145. package/dist/lib/testing/storyboard/request-signing/vector-loader.js +11 -0
  146. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +10 -0
  147. package/dist/lib/testing/storyboard/runner.js +23 -10
  148. package/dist/lib/testing/storyboard/runner.mjs +23 -10
  149. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  150. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  151. package/dist/lib/testing/storyboard/validations.js +4 -1
  152. package/dist/lib/testing/storyboard/validations.mjs +4 -1
  153. package/dist/lib/testing/test-controller.js +3 -0
  154. package/dist/lib/testing/test-controller.mjs +3 -0
  155. package/dist/lib/types/asset-instances.d.mts +1 -1
  156. package/dist/lib/types/asset-instances.d.ts +1 -1
  157. package/dist/lib/types/index.d.mts +5 -0
  158. package/dist/lib/types/index.d.ts +5 -0
  159. package/dist/lib/types/index.js +6 -1
  160. package/dist/lib/types/index.mjs +4 -1
  161. package/dist/lib/types/inline-enums.generated.d.mts +30 -4
  162. package/dist/lib/types/inline-enums.generated.d.ts +30 -4
  163. package/dist/lib/types/inline-enums.generated.js +41 -2
  164. package/dist/lib/types/inline-enums.generated.mjs +28 -2
  165. package/dist/lib/types/media-buy-delivery-report.d.mts +4 -0
  166. package/dist/lib/types/media-buy-delivery-report.d.ts +4 -0
  167. package/dist/lib/types/media-buy-delivery-report.js +16 -0
  168. package/dist/lib/types/media-buy-delivery-report.mjs +0 -0
  169. package/dist/lib/types/schemas.generated.d.ts +20 -69
  170. package/dist/lib/types/schemas.generated.js +29 -46
  171. package/dist/lib/types/schemas.generated.mjs +29 -46
  172. package/dist/lib/types/targeting-keys.generated.d.mts +4 -0
  173. package/dist/lib/types/targeting-keys.generated.d.ts +4 -0
  174. package/dist/lib/types/targeting-keys.generated.js +105 -0
  175. package/dist/lib/types/targeting-keys.generated.mjs +80 -0
  176. package/dist/lib/utils/adcp-version-config.js +5 -2
  177. package/dist/lib/utils/adcp-version-config.mjs +5 -2
  178. package/dist/lib/utils/envelope-status-compat.d.mts +18 -1
  179. package/dist/lib/utils/envelope-status-compat.d.ts +18 -1
  180. package/dist/lib/utils/envelope-status-compat.js +11 -5
  181. package/dist/lib/utils/envelope-status-compat.mjs +11 -5
  182. package/dist/lib/utils/response-unwrapper.js +18 -10
  183. package/dist/lib/utils/response-unwrapper.mjs +18 -10
  184. package/dist/lib/v2/format-schema/resolver.js +1 -1
  185. package/dist/lib/v2/format-schema/resolver.mjs +1 -1
  186. package/dist/lib/v2/projection/creative-delivery.js +123 -30
  187. package/dist/lib/v2/projection/creative-delivery.mjs +127 -30
  188. package/dist/lib/v2/projection/index.d.mts +1 -0
  189. package/dist/lib/v2/projection/index.d.ts +1 -0
  190. package/dist/lib/v2/projection/index.js +3 -0
  191. package/dist/lib/v2/projection/index.mjs +2 -0
  192. package/dist/lib/v2/projection/legacy-metadata.d.mts +19 -0
  193. package/dist/lib/v2/projection/legacy-metadata.d.ts +19 -0
  194. package/dist/lib/v2/projection/legacy-metadata.js +91 -0
  195. package/dist/lib/v2/projection/legacy-metadata.mjs +86 -0
  196. package/dist/lib/validation/compact-schema.d.mts +27 -0
  197. package/dist/lib/validation/compact-schema.d.ts +27 -0
  198. package/dist/lib/validation/compact-schema.js +276 -0
  199. package/dist/lib/validation/compact-schema.mjs +250 -0
  200. package/dist/lib/validation/media-buy-delivery-report.d.mts +8 -0
  201. package/dist/lib/validation/media-buy-delivery-report.d.ts +8 -0
  202. package/dist/lib/validation/media-buy-delivery-report.js +31 -0
  203. package/dist/lib/validation/media-buy-delivery-report.mjs +7 -0
  204. package/dist/lib/validation/schema-diagnostic-origins.d.mts +21 -0
  205. package/dist/lib/validation/schema-diagnostic-origins.d.ts +21 -0
  206. package/dist/lib/validation/schema-diagnostic-origins.js +193 -0
  207. package/dist/lib/validation/schema-diagnostic-origins.mjs +169 -0
  208. package/dist/lib/validation/schema-loader.js +86 -16
  209. package/dist/lib/validation/schema-loader.mjs +82 -16
  210. package/dist/lib/validation/schema-validator.d.mts +10 -19
  211. package/dist/lib/validation/schema-validator.d.ts +10 -19
  212. package/dist/lib/validation/schema-validator.js +136 -43
  213. package/dist/lib/validation/schema-validator.mjs +140 -44
  214. package/dist/lib/version.d.mts +3 -3
  215. package/dist/lib/version.d.ts +3 -3
  216. package/dist/lib/version.js +3 -3
  217. package/dist/lib/version.mjs +3 -3
  218. package/dist/lib/webhooks/index.d.mts +3 -0
  219. package/dist/lib/webhooks/index.d.ts +3 -0
  220. package/dist/lib/webhooks/index.js +3 -0
  221. package/dist/lib/webhooks/index.mjs +2 -0
  222. package/dist/lib/webhooks/media-buy-delivery.d.mts +43 -0
  223. package/dist/lib/webhooks/media-buy-delivery.d.ts +43 -0
  224. package/dist/lib/webhooks/media-buy-delivery.js +119 -0
  225. package/dist/lib/webhooks/media-buy-delivery.mjs +94 -0
  226. package/docs/TYPE-SUMMARY.md +2 -2
  227. package/docs/guides/BUILD-AN-AGENT.md +9 -1
  228. package/docs/guides/DELIVERY-WEBHOOK-PARSING.md +135 -0
  229. package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +15 -0
  230. package/docs/guides/TYPED-CLIENT-TOOLS.md +49 -0
  231. package/docs/llms.txt +3 -3
  232. package/docs/migration-14.x-rc-worksheet.md +4 -4
  233. package/docs/migration-6.6-to-6.7.md +14 -0
  234. package/docs/migration-account-change-feed.md +19 -0
  235. package/docs/releases/sdk-16.6-adoption-fixes.md +33 -0
  236. package/package.json +2 -2
@@ -1,3 +1,9 @@
1
- import type { VersionAdapter } from '../types.mjs';
1
+ import type { VersionAdapter, VersionDrift } from '../types.mjs';
2
2
  export declare const createMediaBuyAdapter: VersionAdapter;
3
3
  export declare const getProductsAdapter: VersionAdapter;
4
+ export declare const updateMediaBuyAdapter: VersionAdapter;
5
+ /** Convert only creative asset positions, never opaque ext/provenance objects. */
6
+ export declare function downgradeCreativeTrackers(params: unknown): {
7
+ params: unknown;
8
+ drift?: VersionDrift;
9
+ };
@@ -1,3 +1,9 @@
1
- import type { VersionAdapter } from '../types';
1
+ import type { VersionAdapter, VersionDrift } from '../types';
2
2
  export declare const createMediaBuyAdapter: VersionAdapter;
3
3
  export declare const getProductsAdapter: VersionAdapter;
4
+ export declare const updateMediaBuyAdapter: VersionAdapter;
5
+ /** Convert only creative asset positions, never opaque ext/provenance objects. */
6
+ export declare function downgradeCreativeTrackers(params: unknown): {
7
+ params: unknown;
8
+ drift?: VersionDrift;
9
+ };
@@ -19,9 +19,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var brand_fields_exports = {};
20
20
  __export(brand_fields_exports, {
21
21
  createMediaBuyAdapter: () => createMediaBuyAdapter,
22
- getProductsAdapter: () => getProductsAdapter
22
+ downgradeCreativeTrackers: () => downgradeCreativeTrackers,
23
+ getProductsAdapter: () => getProductsAdapter,
24
+ updateMediaBuyAdapter: () => updateMediaBuyAdapter
23
25
  });
24
26
  module.exports = __toCommonJS(brand_fields_exports);
27
+ var import_creative_delivery = require('../../../v2/projection/creative-delivery.js');
28
+ var import_legacy_metadata = require('../../../v2/projection/legacy-metadata.js');
25
29
  var import_adcp_version_config = require('../../../utils/adcp-version-config.js');
26
30
  const BRAND_DRIFT = {
27
31
  type: "pre31_brand_fields_stripped",
@@ -36,16 +40,148 @@ function stripTopLevelBrand(params) {
36
40
  if (stripped === req.brand) return { params };
37
41
  return { params: { ...req, brand: stripped }, drift: BRAND_DRIFT };
38
42
  }
43
+ function downgradeMediaBuyStatus(data) {
44
+ if (!data || typeof data !== "object" || Array.isArray(data)) return { data };
45
+ const response = data;
46
+ if (typeof response.media_buy_status !== "string") {
47
+ if (response.status !== "completed") return { data };
48
+ const { status: _taskStatus, ...rest2 } = response;
49
+ return {
50
+ data: rest2,
51
+ drift: {
52
+ type: "pre31_task_status_stripped",
53
+ message: "Task completion omitted: AdCP 3.0 status describes the media-buy lifecycle.",
54
+ strippedFields: ["status"]
55
+ }
56
+ };
57
+ }
58
+ if (response.status !== void 0 && response.status !== "completed") return { data };
59
+ const { media_buy_status, ...rest } = response;
60
+ return {
61
+ data: { ...rest, status: media_buy_status },
62
+ drift: {
63
+ type: "pre31_media_buy_status_moved",
64
+ message: "Media-buy lifecycle moved from media_buy_status to the AdCP 3.0 status field.",
65
+ movedFields: [{ from: "media_buy_status", to: "status" }]
66
+ }
67
+ };
68
+ }
39
69
  const createMediaBuyAdapter = {
40
70
  toolName: "create_media_buy",
41
- adaptRequest: stripTopLevelBrand
71
+ adaptUnnegotiatedRequest: stripTopLevelBrand,
72
+ adaptRequest(params) {
73
+ const brand = stripTopLevelBrand(params);
74
+ const trackers = downgradeCreativeTrackers(brand.params);
75
+ if (!brand.drift) return trackers;
76
+ if (!trackers.drift) return { params: trackers.params, drift: brand.drift };
77
+ return {
78
+ params: trackers.params,
79
+ drift: {
80
+ type: brand.drift.type,
81
+ message: `${brand.drift.message} ${trackers.drift.message}`,
82
+ strippedFields: [...brand.drift.strippedFields ?? [], ...trackers.drift.strippedFields ?? []],
83
+ constituentTypes: [brand.drift.type, trackers.drift.type]
84
+ }
85
+ };
86
+ },
87
+ downgradeResponse: downgradeMediaBuyStatus
42
88
  };
43
89
  const getProductsAdapter = {
44
90
  toolName: "get_products",
45
91
  adaptRequest: stripTopLevelBrand
46
92
  };
93
+ const updateMediaBuyAdapter = {
94
+ toolName: "update_media_buy",
95
+ adaptRequest: downgradeCreativeTrackers,
96
+ adaptUnnegotiatedRequest: (params) => ({ params }),
97
+ downgradeResponse: downgradeMediaBuyStatus
98
+ };
99
+ function record(value) {
100
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
101
+ }
102
+ function downgradeCreativeTrackers(params) {
103
+ const request = record(params);
104
+ if (!request) return { params };
105
+ const losses = [];
106
+ const convertCreatives = (items, path) => {
107
+ if (!Array.isArray(items)) return items;
108
+ let changed = false;
109
+ const converted = items.map((item, index) => {
110
+ const creative = record(item);
111
+ const assets = record(creative?.assets);
112
+ if (!creative || !assets) return item;
113
+ const replacements = /* @__PURE__ */ new Map();
114
+ for (const [key, value] of Object.entries(assets)) {
115
+ const pixels = Array.isArray(value) ? value : [value];
116
+ if (pixels.length === 0) continue;
117
+ const trackers = pixels.map(import_legacy_metadata.downgradePixelTracker);
118
+ if (trackers.some((tracker) => tracker === void 0)) continue;
119
+ const groups = /* @__PURE__ */ new Map();
120
+ for (const tracker of trackers) {
121
+ const group = groups.get(tracker.assetId) ?? [];
122
+ group.push(tracker.asset);
123
+ groups.set(tracker.assetId, group);
124
+ }
125
+ for (const [target, group] of groups) {
126
+ if (Object.hasOwn(assets, target) && target !== key || replacements.has(target)) {
127
+ throw new import_creative_delivery.CreativeFormatProjectionError(
128
+ "creative_delivery",
129
+ typeof creative.creative_id === "string" ? creative.creative_id : "(unknown)",
130
+ `multiple assets would occupy the legacy tracker slot ${target}`
131
+ );
132
+ }
133
+ replacements.set(target, { source: key, asset: Array.isArray(value) ? group : group[0] });
134
+ }
135
+ trackers.forEach((tracker, trackerIndex) => {
136
+ const field = `${path}[${index}].assets.${key}${Array.isArray(value) ? `[${trackerIndex}]` : ""}`;
137
+ const drift = (0, import_legacy_metadata.pixelTrackerDrift)(field, tracker);
138
+ if (drift) losses.push(drift);
139
+ });
140
+ }
141
+ if (replacements.size === 0) return item;
142
+ changed = true;
143
+ const sources = new Set([...replacements.values()].map((entry) => entry.source));
144
+ return {
145
+ ...creative,
146
+ assets: {
147
+ ...Object.fromEntries(Object.entries(assets).filter(([key]) => !sources.has(key))),
148
+ ...Object.fromEntries([...replacements].map(([target, entry]) => [target, entry.asset]))
149
+ }
150
+ };
151
+ });
152
+ return changed ? converted : items;
153
+ };
154
+ let adapted = request;
155
+ const creatives = convertCreatives(request.creatives, "creatives");
156
+ if (creatives !== request.creatives) adapted = { ...adapted, creatives };
157
+ for (const field of ["packages", "new_packages"]) {
158
+ const packages = request[field];
159
+ if (!Array.isArray(packages)) continue;
160
+ let changed = false;
161
+ const converted = packages.map((pkg, index) => {
162
+ const item = record(pkg);
163
+ if (!item) return pkg;
164
+ const creatives2 = convertCreatives(item.creatives, `${field}[${index}].creatives`);
165
+ if (creatives2 === item.creatives) return pkg;
166
+ changed = true;
167
+ return { ...item, creatives: creatives2 };
168
+ });
169
+ if (changed) adapted = { ...adapted, [field]: converted };
170
+ }
171
+ if (losses.length === 0) return { params: adapted };
172
+ return {
173
+ params: adapted,
174
+ drift: {
175
+ type: "PIXEL_TRACKER_LOSSY_DOWNGRADE",
176
+ message: losses.map((loss) => loss.message).join(" "),
177
+ strippedFields: losses.flatMap((loss) => loss.strippedFields ?? [])
178
+ }
179
+ };
180
+ }
47
181
  // Annotate the CommonJS export names for ESM import in node:
48
182
  0 && (module.exports = {
49
183
  createMediaBuyAdapter,
50
- getProductsAdapter
184
+ downgradeCreativeTrackers,
185
+ getProductsAdapter,
186
+ updateMediaBuyAdapter
51
187
  });
@@ -1,3 +1,5 @@
1
+ import { CreativeFormatProjectionError } from "../../../v2/projection/creative-delivery.mjs";
2
+ import { downgradePixelTracker, pixelTrackerDrift } from "../../../v2/projection/legacy-metadata.mjs";
1
3
  import { omit31BrandFields } from "../../../utils/adcp-version-config.mjs";
2
4
  const BRAND_DRIFT = {
3
5
  type: "pre31_brand_fields_stripped",
@@ -12,15 +14,147 @@ function stripTopLevelBrand(params) {
12
14
  if (stripped === req.brand) return { params };
13
15
  return { params: { ...req, brand: stripped }, drift: BRAND_DRIFT };
14
16
  }
17
+ function downgradeMediaBuyStatus(data) {
18
+ if (!data || typeof data !== "object" || Array.isArray(data)) return { data };
19
+ const response = data;
20
+ if (typeof response.media_buy_status !== "string") {
21
+ if (response.status !== "completed") return { data };
22
+ const { status: _taskStatus, ...rest2 } = response;
23
+ return {
24
+ data: rest2,
25
+ drift: {
26
+ type: "pre31_task_status_stripped",
27
+ message: "Task completion omitted: AdCP 3.0 status describes the media-buy lifecycle.",
28
+ strippedFields: ["status"]
29
+ }
30
+ };
31
+ }
32
+ if (response.status !== void 0 && response.status !== "completed") return { data };
33
+ const { media_buy_status, ...rest } = response;
34
+ return {
35
+ data: { ...rest, status: media_buy_status },
36
+ drift: {
37
+ type: "pre31_media_buy_status_moved",
38
+ message: "Media-buy lifecycle moved from media_buy_status to the AdCP 3.0 status field.",
39
+ movedFields: [{ from: "media_buy_status", to: "status" }]
40
+ }
41
+ };
42
+ }
15
43
  const createMediaBuyAdapter = {
16
44
  toolName: "create_media_buy",
17
- adaptRequest: stripTopLevelBrand
45
+ adaptUnnegotiatedRequest: stripTopLevelBrand,
46
+ adaptRequest(params) {
47
+ const brand = stripTopLevelBrand(params);
48
+ const trackers = downgradeCreativeTrackers(brand.params);
49
+ if (!brand.drift) return trackers;
50
+ if (!trackers.drift) return { params: trackers.params, drift: brand.drift };
51
+ return {
52
+ params: trackers.params,
53
+ drift: {
54
+ type: brand.drift.type,
55
+ message: `${brand.drift.message} ${trackers.drift.message}`,
56
+ strippedFields: [...brand.drift.strippedFields ?? [], ...trackers.drift.strippedFields ?? []],
57
+ constituentTypes: [brand.drift.type, trackers.drift.type]
58
+ }
59
+ };
60
+ },
61
+ downgradeResponse: downgradeMediaBuyStatus
18
62
  };
19
63
  const getProductsAdapter = {
20
64
  toolName: "get_products",
21
65
  adaptRequest: stripTopLevelBrand
22
66
  };
67
+ const updateMediaBuyAdapter = {
68
+ toolName: "update_media_buy",
69
+ adaptRequest: downgradeCreativeTrackers,
70
+ adaptUnnegotiatedRequest: (params) => ({ params }),
71
+ downgradeResponse: downgradeMediaBuyStatus
72
+ };
73
+ function record(value) {
74
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
75
+ }
76
+ function downgradeCreativeTrackers(params) {
77
+ const request = record(params);
78
+ if (!request) return { params };
79
+ const losses = [];
80
+ const convertCreatives = (items, path) => {
81
+ if (!Array.isArray(items)) return items;
82
+ let changed = false;
83
+ const converted = items.map((item, index) => {
84
+ const creative = record(item);
85
+ const assets = record(creative?.assets);
86
+ if (!creative || !assets) return item;
87
+ const replacements = /* @__PURE__ */ new Map();
88
+ for (const [key, value] of Object.entries(assets)) {
89
+ const pixels = Array.isArray(value) ? value : [value];
90
+ if (pixels.length === 0) continue;
91
+ const trackers = pixels.map(downgradePixelTracker);
92
+ if (trackers.some((tracker) => tracker === void 0)) continue;
93
+ const groups = /* @__PURE__ */ new Map();
94
+ for (const tracker of trackers) {
95
+ const group = groups.get(tracker.assetId) ?? [];
96
+ group.push(tracker.asset);
97
+ groups.set(tracker.assetId, group);
98
+ }
99
+ for (const [target, group] of groups) {
100
+ if (Object.hasOwn(assets, target) && target !== key || replacements.has(target)) {
101
+ throw new CreativeFormatProjectionError(
102
+ "creative_delivery",
103
+ typeof creative.creative_id === "string" ? creative.creative_id : "(unknown)",
104
+ `multiple assets would occupy the legacy tracker slot ${target}`
105
+ );
106
+ }
107
+ replacements.set(target, { source: key, asset: Array.isArray(value) ? group : group[0] });
108
+ }
109
+ trackers.forEach((tracker, trackerIndex) => {
110
+ const field = `${path}[${index}].assets.${key}${Array.isArray(value) ? `[${trackerIndex}]` : ""}`;
111
+ const drift = pixelTrackerDrift(field, tracker);
112
+ if (drift) losses.push(drift);
113
+ });
114
+ }
115
+ if (replacements.size === 0) return item;
116
+ changed = true;
117
+ const sources = new Set([...replacements.values()].map((entry) => entry.source));
118
+ return {
119
+ ...creative,
120
+ assets: {
121
+ ...Object.fromEntries(Object.entries(assets).filter(([key]) => !sources.has(key))),
122
+ ...Object.fromEntries([...replacements].map(([target, entry]) => [target, entry.asset]))
123
+ }
124
+ };
125
+ });
126
+ return changed ? converted : items;
127
+ };
128
+ let adapted = request;
129
+ const creatives = convertCreatives(request.creatives, "creatives");
130
+ if (creatives !== request.creatives) adapted = { ...adapted, creatives };
131
+ for (const field of ["packages", "new_packages"]) {
132
+ const packages = request[field];
133
+ if (!Array.isArray(packages)) continue;
134
+ let changed = false;
135
+ const converted = packages.map((pkg, index) => {
136
+ const item = record(pkg);
137
+ if (!item) return pkg;
138
+ const creatives2 = convertCreatives(item.creatives, `${field}[${index}].creatives`);
139
+ if (creatives2 === item.creatives) return pkg;
140
+ changed = true;
141
+ return { ...item, creatives: creatives2 };
142
+ });
143
+ if (changed) adapted = { ...adapted, [field]: converted };
144
+ }
145
+ if (losses.length === 0) return { params: adapted };
146
+ return {
147
+ params: adapted,
148
+ drift: {
149
+ type: "PIXEL_TRACKER_LOSSY_DOWNGRADE",
150
+ message: losses.map((loss) => loss.message).join(" "),
151
+ strippedFields: losses.flatMap((loss) => loss.strippedFields ?? [])
152
+ }
153
+ };
154
+ }
23
155
  export {
24
156
  createMediaBuyAdapter,
25
- getProductsAdapter
157
+ downgradeCreativeTrackers,
158
+ getProductsAdapter,
159
+ updateMediaBuyAdapter
26
160
  };
@@ -27,6 +27,12 @@ var import_get_signals = require('./get-signals.js');
27
27
  var import_sync_accounts = require('./sync-accounts.js');
28
28
  const v30Adapters = [
29
29
  import_brand_fields.createMediaBuyAdapter,
30
+ import_brand_fields.updateMediaBuyAdapter,
31
+ {
32
+ toolName: "sync_creatives",
33
+ adaptRequest: import_brand_fields.downgradeCreativeTrackers,
34
+ adaptUnnegotiatedRequest: (params) => ({ params })
35
+ },
30
36
  import_get_products.getProductsAdapter,
31
37
  import_get_signals.getSignalsAdapter,
32
38
  import_sync_accounts.syncAccountsAdapter
@@ -1,9 +1,15 @@
1
- import { createMediaBuyAdapter } from "./brand-fields.mjs";
1
+ import { createMediaBuyAdapter, updateMediaBuyAdapter, downgradeCreativeTrackers } from "./brand-fields.mjs";
2
2
  import { getProductsAdapter } from "./get-products.mjs";
3
3
  import { getSignalsAdapter } from "./get-signals.mjs";
4
4
  import { syncAccountsAdapter } from "./sync-accounts.mjs";
5
5
  const v30Adapters = [
6
6
  createMediaBuyAdapter,
7
+ updateMediaBuyAdapter,
8
+ {
9
+ toolName: "sync_creatives",
10
+ adaptRequest: downgradeCreativeTrackers,
11
+ adaptUnnegotiatedRequest: (params) => ({ params })
12
+ },
7
13
  getProductsAdapter,
8
14
  getSignalsAdapter,
9
15
  syncAccountsAdapter
@@ -96,7 +96,7 @@ const updateMediaBuyAdapter = {
96
96
  function adaptMediaBuyStatus(toolName) {
97
97
  return (data) => {
98
98
  if (!isObject(data)) return { data };
99
- const adapted = (0, import_envelope_status_compat.injectLegacyEnvelopeStatus)(data, { toolName });
99
+ const adapted = (0, import_envelope_status_compat.injectLegacyEnvelopeStatus)(data, { toolName, adcpVersion: "3.1" });
100
100
  if (adapted === data || adapted.media_buy_status === data.media_buy_status) return { data };
101
101
  return {
102
102
  data: adapted,
@@ -72,7 +72,7 @@ const updateMediaBuyAdapter = {
72
72
  function adaptMediaBuyStatus(toolName) {
73
73
  return (data) => {
74
74
  if (!isObject(data)) return { data };
75
- const adapted = injectLegacyEnvelopeStatus(data, { toolName });
75
+ const adapted = injectLegacyEnvelopeStatus(data, { toolName, adcpVersion: "3.1" });
76
76
  if (adapted === data || adapted.media_buy_status === data.media_buy_status) return { data };
77
77
  return {
78
78
  data: adapted,
@@ -48,6 +48,11 @@ export interface VersionAdapter {
48
48
  params: unknown;
49
49
  drift?: VersionDrift;
50
50
  };
51
+ /** Compatibility fallback when no authoritative wire release was negotiated. */
52
+ adaptUnnegotiatedRequest?(params: unknown): {
53
+ params: unknown;
54
+ drift?: VersionDrift;
55
+ };
51
56
  /**
52
57
  * Adapt a response from this adapter's release up to the next minor
53
58
  * release. Returns the original reference when nothing changes.
@@ -48,6 +48,11 @@ export interface VersionAdapter {
48
48
  params: unknown;
49
49
  drift?: VersionDrift;
50
50
  };
51
+ /** Compatibility fallback when no authoritative wire release was negotiated. */
52
+ adaptUnnegotiatedRequest?(params: unknown): {
53
+ params: unknown;
54
+ drift?: VersionDrift;
55
+ };
51
56
  /**
52
57
  * Adapt a response from this adapter's release up to the next minor
53
58
  * release. Returns the original reference when nothing changes.
@@ -696,6 +696,7 @@ function detectDraft(schema) {
696
696
  }
697
697
  function getDraft07Ajv() {
698
698
  const ajv = new import_ajv.default({
699
+ inlineRefs: false,
699
700
  strict: false,
700
701
  allErrors: true,
701
702
  validateSchema: true,
@@ -707,6 +708,7 @@ function getDraft07Ajv() {
707
708
  }
708
709
  function getDraft2020Ajv() {
709
710
  const ajv = new Ajv2020({
711
+ inlineRefs: false,
710
712
  strict: false,
711
713
  allErrors: true,
712
714
  validateSchema: true,
@@ -669,6 +669,7 @@ function detectDraft(schema) {
669
669
  }
670
670
  function getDraft07Ajv() {
671
671
  const ajv = new Ajv({
672
+ inlineRefs: false,
672
673
  strict: false,
673
674
  allErrors: true,
674
675
  validateSchema: true,
@@ -680,6 +681,7 @@ function getDraft07Ajv() {
680
681
  }
681
682
  function getDraft2020Ajv() {
682
683
  const ajv = new Ajv2020({
684
+ inlineRefs: false,
683
685
  strict: false,
684
686
  allErrors: true,
685
687
  validateSchema: true,
@@ -39,6 +39,8 @@ export interface StreamAccountChangesOptions {
39
39
  resourceTypes?: readonly string[];
40
40
  maxResults?: number;
41
41
  taskOptions?: TaskOptions;
42
+ /** Fallback served schema release for custom readers without SDK version metadata. */
43
+ adcpVersion?: string;
42
44
  /**
43
45
  * Rebuild every authoritative snapshot in scope, including all statuses and
44
46
  * pages. A fresh latest cursor is acquired BEFORE this hook. No checkpoint
@@ -61,4 +63,4 @@ export interface AccountChangeDrainPage extends Omit<AccountChangePage, 'cursor'
61
63
  * webhook targets never enter continuation requests. Poll again periodically.
62
64
  * The adopter owns storage, transaction atomicity and concurrency fencing.
63
65
  */
64
- export declare function streamAccountChanges(client: Pick<AgentClient, 'listAccountChanges'>, options: StreamAccountChangesOptions): AsyncGenerator<AccountChangeDrainPage, void, void>;
66
+ export declare function streamAccountChanges(client: Pick<AgentClient, 'listAccountChanges'> & Partial<Pick<AgentClient, 'getAdcpVersion'>>, options: StreamAccountChangesOptions): AsyncGenerator<AccountChangeDrainPage, void, void>;
@@ -39,6 +39,8 @@ export interface StreamAccountChangesOptions {
39
39
  resourceTypes?: readonly string[];
40
40
  maxResults?: number;
41
41
  taskOptions?: TaskOptions;
42
+ /** Fallback served schema release for custom readers without SDK version metadata. */
43
+ adcpVersion?: string;
42
44
  /**
43
45
  * Rebuild every authoritative snapshot in scope, including all statuses and
44
46
  * pages. A fresh latest cursor is acquired BEFORE this hook. No checkpoint
@@ -61,4 +63,4 @@ export interface AccountChangeDrainPage extends Omit<AccountChangePage, 'cursor'
61
63
  * webhook targets never enter continuation requests. Poll again periodically.
62
64
  * The adopter owns storage, transaction atomicity and concurrency fencing.
63
65
  */
64
- export declare function streamAccountChanges(client: Pick<AgentClient, 'listAccountChanges'>, options: StreamAccountChangesOptions): AsyncGenerator<AccountChangeDrainPage, void, void>;
66
+ export declare function streamAccountChanges(client: Pick<AgentClient, 'listAccountChanges'> & Partial<Pick<AgentClient, 'getAdcpVersion'>>, options: StreamAccountChangesOptions): AsyncGenerator<AccountChangeDrainPage, void, void>;
@@ -24,6 +24,7 @@ __export(account_changes_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(account_changes_exports);
26
26
  var import_errors = require('../errors/index.js');
27
+ var import_adcp_version_config = require('../utils/adcp-version-config.js');
27
28
  var import_schema_loader = require('../validation/schema-loader.js');
28
29
  var import_account_change_cursor = require('./account-change-cursor.js');
29
30
  var import_account_change_json = require('./account-change-json.js');
@@ -55,6 +56,7 @@ async function* streamAccountChanges(client, options) {
55
56
  if (options.maxResults !== void 0 && (!Number.isInteger(options.maxResults) || options.maxResults < 1 || options.maxResults > 100)) {
56
57
  throw new import_errors.ConfigurationError("maxResults must be an integer between 1 and 100.", "maxResults");
57
58
  }
59
+ const configuredVersion = (0, import_adcp_version_config.resolveAdcpVersion)(options.adcpVersion ?? client.getAdcpVersion?.());
58
60
  const account = structuredClone(options.account);
59
61
  const resourceTypes = options.resourceTypes ? [...new Set(options.resourceTypes)].sort() : void 0;
60
62
  const request = {
@@ -104,8 +106,26 @@ async function* streamAccountChanges(client, options) {
104
106
  result
105
107
  );
106
108
  }
107
- const validator = (0, import_schema_loader.getSchemaValidatorByRef)("account/list-account-changes-response.json");
108
- if (!validator) throw new import_errors.ConfigurationError("Bundled account change response schema is unavailable.", "schemas");
109
+ let validator;
110
+ try {
111
+ const pageVersion = (0, import_adcp_version_config.resolveAdcpVersion)(
112
+ result.metadata?.negotiatedAdcpVersion ?? result.metadata?.wireAdcpVersion ?? options.adcpVersion ?? result.metadata?.adcpVersion ?? configuredVersion
113
+ );
114
+ validator = (0, import_schema_loader.getSchemaValidatorByRef)("account/list-account-changes-response.json", pageVersion);
115
+ } catch {
116
+ throw new AccountChangeDrainError(
117
+ "account_change_page_invalid",
118
+ "Account change response names an unavailable schema release.",
119
+ result
120
+ );
121
+ }
122
+ if (!validator) {
123
+ throw new AccountChangeDrainError(
124
+ "account_change_page_invalid",
125
+ "Account change response schema is unavailable for the served release.",
126
+ result
127
+ );
128
+ }
109
129
  if (!validator(page)) {
110
130
  throw new AccountChangeDrainError("account_change_page_invalid", "Invalid account change feed response.", result);
111
131
  }
@@ -1,4 +1,5 @@
1
1
  import { ADCPError, ConfigurationError } from "../errors/index.mjs";
2
+ import { resolveAdcpVersion } from "../utils/adcp-version-config.mjs";
2
3
  import { getSchemaValidatorByRef } from "../validation/schema-loader.mjs";
3
4
  import {
4
5
  restoreAccountChangeCursor,
@@ -33,6 +34,7 @@ async function* streamAccountChanges(client, options) {
33
34
  if (options.maxResults !== void 0 && (!Number.isInteger(options.maxResults) || options.maxResults < 1 || options.maxResults > 100)) {
34
35
  throw new ConfigurationError("maxResults must be an integer between 1 and 100.", "maxResults");
35
36
  }
37
+ const configuredVersion = resolveAdcpVersion(options.adcpVersion ?? client.getAdcpVersion?.());
36
38
  const account = structuredClone(options.account);
37
39
  const resourceTypes = options.resourceTypes ? [...new Set(options.resourceTypes)].sort() : void 0;
38
40
  const request = {
@@ -82,8 +84,26 @@ async function* streamAccountChanges(client, options) {
82
84
  result
83
85
  );
84
86
  }
85
- const validator = getSchemaValidatorByRef("account/list-account-changes-response.json");
86
- if (!validator) throw new ConfigurationError("Bundled account change response schema is unavailable.", "schemas");
87
+ let validator;
88
+ try {
89
+ const pageVersion = resolveAdcpVersion(
90
+ result.metadata?.negotiatedAdcpVersion ?? result.metadata?.wireAdcpVersion ?? options.adcpVersion ?? result.metadata?.adcpVersion ?? configuredVersion
91
+ );
92
+ validator = getSchemaValidatorByRef("account/list-account-changes-response.json", pageVersion);
93
+ } catch {
94
+ throw new AccountChangeDrainError(
95
+ "account_change_page_invalid",
96
+ "Account change response names an unavailable schema release.",
97
+ result
98
+ );
99
+ }
100
+ if (!validator) {
101
+ throw new AccountChangeDrainError(
102
+ "account_change_page_invalid",
103
+ "Account change response schema is unavailable for the served release.",
104
+ result
105
+ );
106
+ }
87
107
  if (!validator(page)) {
88
108
  throw new AccountChangeDrainError("account_change_page_invalid", "Invalid account change feed response.", result);
89
109
  }
@@ -34,6 +34,7 @@ __export(oracle_exports, {
34
34
  module.exports = __toCommonJS(oracle_exports);
35
35
  var import_ajv = __toESM(require("ajv"));
36
36
  var import_ajv_formats = __toESM(require("ajv-formats"));
37
+ var import_compact_schema = require('../validation/compact-schema.js');
37
38
  var import_schemaLoader = require('./schemaLoader.js');
38
39
  var import_envelope_status_compat = require('../utils/envelope-status-compat.js');
39
40
  const STACK_TRACE_SIGNATURES = [
@@ -88,7 +89,7 @@ const FS_PATH_SIGNATURES = [/\/Users\/[^ "']+/, /\/home\/[^ "']+/, /[A-Z]:\\\\Us
88
89
  let cachedAjv = null;
89
90
  function getAjv() {
90
91
  if (cachedAjv) return cachedAjv;
91
- const ajv = new import_ajv.default({ allErrors: true, strict: false, validateFormats: true });
92
+ const ajv = new import_ajv.default({ inlineRefs: false, allErrors: true, strict: false, validateFormats: true });
92
93
  (0, import_ajv_formats.default)(ajv);
93
94
  cachedAjv = ajv;
94
95
  return ajv;
@@ -102,7 +103,7 @@ function responseValidator(tool, options) {
102
103
  const cached = compiledValidators.get(cacheKey);
103
104
  if (cached) return cached;
104
105
  const schema = (0, import_schemaLoader.loadResponseSchema)(tool, options);
105
- const validator = getAjv().compile(schema);
106
+ const validator = getAjv().compile((0, import_compact_schema.compactSchemaForValidation)(schema));
106
107
  compiledValidators.set(cacheKey, validator);
107
108
  return validator;
108
109
  }
@@ -1,5 +1,6 @@
1
1
  import Ajv from "ajv";
2
2
  import addFormats from "ajv-formats";
3
+ import { compactSchemaForValidation } from "../validation/compact-schema.mjs";
3
4
  import { loadResponseSchema } from "./schemaLoader.mjs";
4
5
  import { injectLegacyEnvelopeStatus, isLegacy30xPayload } from "../utils/envelope-status-compat.mjs";
5
6
  const STACK_TRACE_SIGNATURES = [
@@ -54,7 +55,7 @@ const FS_PATH_SIGNATURES = [/\/Users\/[^ "']+/, /\/home\/[^ "']+/, /[A-Z]:\\\\Us
54
55
  let cachedAjv = null;
55
56
  function getAjv() {
56
57
  if (cachedAjv) return cachedAjv;
57
- const ajv = new Ajv({ allErrors: true, strict: false, validateFormats: true });
58
+ const ajv = new Ajv({ inlineRefs: false, allErrors: true, strict: false, validateFormats: true });
58
59
  addFormats(ajv);
59
60
  cachedAjv = ajv;
60
61
  return ajv;
@@ -68,7 +69,7 @@ function responseValidator(tool, options) {
68
69
  const cached = compiledValidators.get(cacheKey);
69
70
  if (cached) return cached;
70
71
  const schema = loadResponseSchema(tool, options);
71
- const validator = getAjv().compile(schema);
72
+ const validator = getAjv().compile(compactSchemaForValidation(schema));
72
73
  compiledValidators.set(cacheKey, validator);
73
74
  return validator;
74
75
  }