@adcp/sdk 7.6.0 → 7.8.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 (126) hide show
  1. package/bin/adcp.js +3 -1
  2. package/dist/lib/errors/index.d.ts +54 -0
  3. package/dist/lib/errors/index.d.ts.map +1 -1
  4. package/dist/lib/errors/index.js +132 -1
  5. package/dist/lib/errors/index.js.map +1 -1
  6. package/dist/lib/index.d.ts +4 -2
  7. package/dist/lib/index.d.ts.map +1 -1
  8. package/dist/lib/index.js +38 -9
  9. package/dist/lib/index.js.map +1 -1
  10. package/dist/lib/media-buy/available-actions.d.ts +60 -0
  11. package/dist/lib/media-buy/available-actions.d.ts.map +1 -0
  12. package/dist/lib/media-buy/available-actions.js +112 -0
  13. package/dist/lib/media-buy/available-actions.js.map +1 -0
  14. package/dist/lib/media-buy/index.d.ts +9 -0
  15. package/dist/lib/media-buy/index.d.ts.map +1 -0
  16. package/dist/lib/media-buy/index.js +36 -0
  17. package/dist/lib/media-buy/index.js.map +1 -0
  18. package/dist/lib/media-buy/preflight.d.ts +118 -0
  19. package/dist/lib/media-buy/preflight.d.ts.map +1 -0
  20. package/dist/lib/media-buy/preflight.js +376 -0
  21. package/dist/lib/media-buy/preflight.js.map +1 -0
  22. package/dist/lib/media-buy/types.d.ts +113 -0
  23. package/dist/lib/media-buy/types.d.ts.map +1 -0
  24. package/dist/lib/media-buy/types.js +25 -0
  25. package/dist/lib/media-buy/types.js.map +1 -0
  26. package/dist/lib/media-buy/update-fields.generated.d.ts +14 -0
  27. package/dist/lib/media-buy/update-fields.generated.d.ts.map +1 -0
  28. package/dist/lib/media-buy/update-fields.generated.js +137 -0
  29. package/dist/lib/media-buy/update-fields.generated.js.map +1 -0
  30. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  31. package/dist/lib/server/decisioning/account.d.ts +27 -0
  32. package/dist/lib/server/decisioning/account.d.ts.map +1 -1
  33. package/dist/lib/server/decisioning/account.js.map +1 -1
  34. package/dist/lib/server/decisioning/context.d.ts +65 -0
  35. package/dist/lib/server/decisioning/context.d.ts.map +1 -1
  36. package/dist/lib/server/decisioning/runtime/from-platform.js +59 -58
  37. package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
  38. package/dist/lib/server/decisioning/runtime/to-context.d.ts +1 -1
  39. package/dist/lib/server/decisioning/runtime/to-context.d.ts.map +1 -1
  40. package/dist/lib/server/decisioning/runtime/to-context.js +2 -1
  41. package/dist/lib/server/decisioning/runtime/to-context.js.map +1 -1
  42. package/dist/lib/server/test-controller.d.ts +46 -1
  43. package/dist/lib/server/test-controller.d.ts.map +1 -1
  44. package/dist/lib/server/test-controller.js +49 -2
  45. package/dist/lib/server/test-controller.js.map +1 -1
  46. package/dist/lib/signing/canonicalize.d.ts +53 -0
  47. package/dist/lib/signing/canonicalize.d.ts.map +1 -1
  48. package/dist/lib/signing/canonicalize.js +33 -1
  49. package/dist/lib/signing/canonicalize.js.map +1 -1
  50. package/dist/lib/signing/client.d.ts +6 -5
  51. package/dist/lib/signing/client.d.ts.map +1 -1
  52. package/dist/lib/signing/client.js +16 -1
  53. package/dist/lib/signing/client.js.map +1 -1
  54. package/dist/lib/signing/errors.d.ts +11 -0
  55. package/dist/lib/signing/errors.d.ts.map +1 -1
  56. package/dist/lib/signing/errors.js +11 -1
  57. package/dist/lib/signing/errors.js.map +1 -1
  58. package/dist/lib/signing/jwks-helpers.d.ts +11 -1
  59. package/dist/lib/signing/jwks-helpers.d.ts.map +1 -1
  60. package/dist/lib/signing/jwks-helpers.js.map +1 -1
  61. package/dist/lib/signing/provider.d.ts +17 -0
  62. package/dist/lib/signing/provider.d.ts.map +1 -1
  63. package/dist/lib/signing/replay.d.ts +16 -0
  64. package/dist/lib/signing/replay.d.ts.map +1 -1
  65. package/dist/lib/signing/replay.js.map +1 -1
  66. package/dist/lib/signing/request-context.d.ts +140 -0
  67. package/dist/lib/signing/request-context.d.ts.map +1 -0
  68. package/dist/lib/signing/request-context.js +160 -0
  69. package/dist/lib/signing/request-context.js.map +1 -0
  70. package/dist/lib/signing/response-verifier.d.ts +105 -0
  71. package/dist/lib/signing/response-verifier.d.ts.map +1 -0
  72. package/dist/lib/signing/response-verifier.js +271 -0
  73. package/dist/lib/signing/response-verifier.js.map +1 -0
  74. package/dist/lib/signing/server.d.ts +5 -3
  75. package/dist/lib/signing/server.d.ts.map +1 -1
  76. package/dist/lib/signing/server.js +13 -1
  77. package/dist/lib/signing/server.js.map +1 -1
  78. package/dist/lib/signing/signer-async.d.ts +8 -2
  79. package/dist/lib/signing/signer-async.d.ts.map +1 -1
  80. package/dist/lib/signing/signer-async.js +14 -0
  81. package/dist/lib/signing/signer-async.js.map +1 -1
  82. package/dist/lib/signing/signer.d.ts +170 -1
  83. package/dist/lib/signing/signer.d.ts.map +1 -1
  84. package/dist/lib/signing/signer.js +153 -0
  85. package/dist/lib/signing/signer.js.map +1 -1
  86. package/dist/lib/signing/testing.d.ts +14 -3
  87. package/dist/lib/signing/testing.d.ts.map +1 -1
  88. package/dist/lib/signing/testing.js +14 -0
  89. package/dist/lib/signing/testing.js.map +1 -1
  90. package/dist/lib/signing/types.d.ts +36 -0
  91. package/dist/lib/signing/types.d.ts.map +1 -1
  92. package/dist/lib/signing/types.js +37 -1
  93. package/dist/lib/signing/types.js.map +1 -1
  94. package/dist/lib/testing/comply-controller.d.ts +26 -1
  95. package/dist/lib/testing/comply-controller.d.ts.map +1 -1
  96. package/dist/lib/testing/comply-controller.js +17 -7
  97. package/dist/lib/testing/comply-controller.js.map +1 -1
  98. package/dist/lib/testing/index.d.ts +1 -1
  99. package/dist/lib/testing/index.d.ts.map +1 -1
  100. package/dist/lib/testing/index.js.map +1 -1
  101. package/dist/lib/testing/storyboard/agent-routing.d.ts +20 -3
  102. package/dist/lib/testing/storyboard/agent-routing.d.ts.map +1 -1
  103. package/dist/lib/testing/storyboard/agent-routing.js +60 -10
  104. package/dist/lib/testing/storyboard/agent-routing.js.map +1 -1
  105. package/dist/lib/testing/storyboard/default-invariants.js +111 -59
  106. package/dist/lib/testing/storyboard/default-invariants.js.map +1 -1
  107. package/dist/lib/testing/storyboard/request-signing/builder.d.ts.map +1 -1
  108. package/dist/lib/testing/storyboard/request-signing/builder.js +10 -1
  109. package/dist/lib/testing/storyboard/request-signing/builder.js.map +1 -1
  110. package/dist/lib/testing/storyboard/request-signing/grader.d.ts +24 -10
  111. package/dist/lib/testing/storyboard/request-signing/grader.d.ts.map +1 -1
  112. package/dist/lib/testing/storyboard/request-signing/grader.js +123 -29
  113. package/dist/lib/testing/storyboard/request-signing/grader.js.map +1 -1
  114. package/dist/lib/testing/storyboard/runner.d.ts +9 -1
  115. package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
  116. package/dist/lib/testing/storyboard/runner.js +30 -1
  117. package/dist/lib/testing/storyboard/runner.js.map +1 -1
  118. package/dist/lib/testing/storyboard/types.d.ts +128 -3
  119. package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
  120. package/dist/lib/testing/storyboard/types.js.map +1 -1
  121. package/dist/lib/testing/storyboard/validations.d.ts.map +1 -1
  122. package/dist/lib/testing/storyboard/validations.js +223 -22
  123. package/dist/lib/testing/storyboard/validations.js.map +1 -1
  124. package/dist/lib/version.d.ts +3 -3
  125. package/dist/lib/version.js +3 -3
  126. package/package.json +1 -1
@@ -0,0 +1,376 @@
1
+ "use strict";
2
+ // Buyer-side preflight helpers for `update_media_buy`. See RFC #4480.
3
+ //
4
+ // Three layers, each usable on its own:
5
+ // 1. Boolean gates: `canPause(buy)`, `canExtendFlight(buy)`, ... - single
6
+ // question, single answer. Drives UI affordances.
7
+ // 2. Resolver: `getActionForMutation(buy, request)` - turns a request diff
8
+ // into the set of fine-grained actions it covers. Drives dispatch.
9
+ // 3. Preflight: `preflightUpdateMediaBuy(buy, request)` - composes
10
+ // resolver + gate checks into a single ok/not-ok decision.
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.canRemoveCreative = exports.canRemovePackages = exports.canAddPackages = exports.canUpdateCreativeAssignments = exports.canReplaceCreative = exports.canUpdateFrequencyCaps = exports.canUpdatePacing = exports.canUpdateTargeting = exports.canReallocateBudget = exports.canDecreaseBudget = exports.canIncreaseBudget = exports.canUpdateFlightDates = exports.canShortenFlight = exports.canExtendFlight = exports.canCancel = exports.canResume = exports.canPause = void 0;
13
+ exports.getActionForMutation = getActionForMutation;
14
+ exports.preflightUpdateMediaBuy = preflightUpdateMediaBuy;
15
+ exports.recoveryForModeMismatch = recoveryForModeMismatch;
16
+ const errors_1 = require("../errors");
17
+ const available_actions_1 = require("./available-actions");
18
+ const update_fields_generated_1 = require("./update-fields.generated");
19
+ // ---------------------------------------------------------------------------
20
+ // Boolean gates
21
+ // ---------------------------------------------------------------------------
22
+ function isAvailable(buy, action) {
23
+ return (0, available_actions_1.findAvailableAction)(buy, action, { silent: true }) !== undefined;
24
+ }
25
+ const canPause = (buy) => isAvailable(buy, 'pause');
26
+ exports.canPause = canPause;
27
+ const canResume = (buy) => isAvailable(buy, 'resume');
28
+ exports.canResume = canResume;
29
+ const canCancel = (buy) => isAvailable(buy, 'cancel');
30
+ exports.canCancel = canCancel;
31
+ const canExtendFlight = (buy) => isAvailable(buy, 'extend_flight');
32
+ exports.canExtendFlight = canExtendFlight;
33
+ const canShortenFlight = (buy) => isAvailable(buy, 'shorten_flight');
34
+ exports.canShortenFlight = canShortenFlight;
35
+ const canUpdateFlightDates = (buy) => isAvailable(buy, 'update_flight_dates');
36
+ exports.canUpdateFlightDates = canUpdateFlightDates;
37
+ const canIncreaseBudget = (buy) => isAvailable(buy, 'increase_budget');
38
+ exports.canIncreaseBudget = canIncreaseBudget;
39
+ const canDecreaseBudget = (buy) => isAvailable(buy, 'decrease_budget');
40
+ exports.canDecreaseBudget = canDecreaseBudget;
41
+ const canReallocateBudget = (buy) => isAvailable(buy, 'reallocate_budget');
42
+ exports.canReallocateBudget = canReallocateBudget;
43
+ const canUpdateTargeting = (buy) => isAvailable(buy, 'update_targeting');
44
+ exports.canUpdateTargeting = canUpdateTargeting;
45
+ const canUpdatePacing = (buy) => isAvailable(buy, 'update_pacing');
46
+ exports.canUpdatePacing = canUpdatePacing;
47
+ const canUpdateFrequencyCaps = (buy) => isAvailable(buy, 'update_frequency_caps');
48
+ exports.canUpdateFrequencyCaps = canUpdateFrequencyCaps;
49
+ const canReplaceCreative = (buy) => isAvailable(buy, 'replace_creative');
50
+ exports.canReplaceCreative = canReplaceCreative;
51
+ const canUpdateCreativeAssignments = (buy) => isAvailable(buy, 'update_creative_assignments');
52
+ exports.canUpdateCreativeAssignments = canUpdateCreativeAssignments;
53
+ const canAddPackages = (buy) => isAvailable(buy, 'add_packages');
54
+ exports.canAddPackages = canAddPackages;
55
+ const canRemovePackages = (buy) => isAvailable(buy, 'remove_packages');
56
+ exports.canRemovePackages = canRemovePackages;
57
+ const canRemoveCreative = (buy) => isAvailable(buy, 'remove_creative');
58
+ exports.canRemoveCreative = canRemoveCreative;
59
+ // Float tolerance for comparing summed budgets across packages. Below this
60
+ // difference, two totals are treated as equal (absorbs cent-rounding from
61
+ // per-package decimal math). Half a cent is the smallest representable
62
+ // difference any current AdCP currency cares about. If a future spec
63
+ // extension allows sub-cent / micro-amount pricing (e.g. programmatic
64
+ // auction-side bidding) this tolerance would mask real reallocations and
65
+ // should be tightened or made currency-aware.
66
+ const BUDGET_EQUAL_TOLERANCE = 0.005;
67
+ /**
68
+ * Walk the request body and return the set of fine-grained actions it
69
+ * covers. Uses `ACTIONS_BY_FIELD` from the generated table to map dotted
70
+ * paths back to actions, then compares against `currentBuy` to pick
71
+ * direction-specific siblings.
72
+ *
73
+ * Returns an empty array when the request touches no recognized field
74
+ * (e.g. only `idempotency_key` / `revision` / `account` were set).
75
+ */
76
+ function getActionForMutation(currentBuy, request) {
77
+ const touched = collectTouchedFields(request);
78
+ if (touched.size === 0)
79
+ return [];
80
+ // Map each touched path to candidate actions, then resolve direction
81
+ // for budget/flight clusters.
82
+ const resolved = new Map();
83
+ for (const field of touched) {
84
+ const candidates = update_fields_generated_1.ACTIONS_BY_FIELD[field];
85
+ if (!candidates)
86
+ continue;
87
+ let pick;
88
+ if (field === 'paused') {
89
+ pick = { action: request.paused === false ? 'resume' : 'pause' };
90
+ }
91
+ else if (field === 'packages[].budget') {
92
+ pick = resolveBudgetDirection(currentBuy, request);
93
+ }
94
+ else if (field === 'end_time' || field === 'packages[].end_time') {
95
+ pick = resolveFlightEndDirection(currentBuy, request, field);
96
+ }
97
+ else if (field === 'start_time' || field === 'packages[].start_time') {
98
+ pick = { action: 'update_flight_dates', direction: 'shift' };
99
+ }
100
+ else {
101
+ // Unambiguous: every other field has exactly one fine-grained
102
+ // action in ACTIONS_BY_FIELD.
103
+ pick = { action: candidates[0] };
104
+ }
105
+ const existing = resolved.get(pick.action);
106
+ if (existing) {
107
+ existing.touched_fields.push(field);
108
+ }
109
+ else {
110
+ resolved.set(pick.action, {
111
+ action: pick.action,
112
+ direction: pick.direction,
113
+ touched_fields: [field],
114
+ });
115
+ }
116
+ }
117
+ return [...resolved.values()];
118
+ }
119
+ function collectTouchedFields(request) {
120
+ const touched = new Set();
121
+ if (request.paused !== undefined)
122
+ touched.add('paused');
123
+ if (request.canceled !== undefined)
124
+ touched.add('canceled');
125
+ if (request.cancellation_reason !== undefined)
126
+ touched.add('cancellation_reason');
127
+ if (request.start_time !== undefined)
128
+ touched.add('start_time');
129
+ if (request.end_time !== undefined)
130
+ touched.add('end_time');
131
+ if (request.new_packages !== undefined && request.new_packages.length > 0) {
132
+ touched.add('new_packages');
133
+ }
134
+ if (request.packages) {
135
+ for (const pkg of request.packages) {
136
+ if (pkg.canceled !== undefined)
137
+ touched.add('packages[].canceled');
138
+ // `pkg.paused` has no entry in the generated action mapping - the
139
+ // spec keys pause/resume at the buy level only. Drop silently so the
140
+ // resolver doesn't conflate it with the top-level `paused` action.
141
+ if (pkg.budget !== undefined)
142
+ touched.add('packages[].budget');
143
+ if (pkg.pacing !== undefined)
144
+ touched.add('packages[].pacing');
145
+ if (pkg.start_time !== undefined)
146
+ touched.add('packages[].start_time');
147
+ if (pkg.end_time !== undefined)
148
+ touched.add('packages[].end_time');
149
+ if (pkg.creative_assignments !== undefined) {
150
+ touched.add('packages[].creative_assignments');
151
+ }
152
+ if (pkg.creatives !== undefined)
153
+ touched.add('packages[].creatives');
154
+ if (pkg.keyword_targets_add !== undefined)
155
+ touched.add('packages[].keyword_targets_add');
156
+ if (pkg.keyword_targets_remove !== undefined) {
157
+ touched.add('packages[].keyword_targets_remove');
158
+ }
159
+ if (pkg.negative_keywords_add !== undefined)
160
+ touched.add('packages[].negative_keywords_add');
161
+ if (pkg.negative_keywords_remove !== undefined) {
162
+ touched.add('packages[].negative_keywords_remove');
163
+ }
164
+ if (pkg.targeting_overlay !== undefined) {
165
+ // `frequency_cap` is the only nested field with its own action.
166
+ // Touching the whole overlay falls through to update_targeting.
167
+ const overlayKeys = Object.keys(pkg.targeting_overlay);
168
+ if (overlayKeys.length === 1 && overlayKeys[0] === 'frequency_cap') {
169
+ touched.add('packages[].targeting_overlay.frequency_cap');
170
+ }
171
+ else {
172
+ touched.add('packages[].targeting_overlay');
173
+ }
174
+ }
175
+ }
176
+ }
177
+ return touched;
178
+ }
179
+ function resolveBudgetDirection(currentBuy, request) {
180
+ const currentByPkg = new Map();
181
+ for (const pkg of currentBuy.packages ?? []) {
182
+ if (pkg.package_id && typeof pkg.budget === 'number') {
183
+ currentByPkg.set(pkg.package_id, pkg.budget);
184
+ }
185
+ }
186
+ let currentTotal = 0;
187
+ let proposedTotal = 0;
188
+ let sawIncrease = false;
189
+ let sawDecrease = false;
190
+ for (const pkg of request.packages ?? []) {
191
+ if (typeof pkg.budget !== 'number')
192
+ continue;
193
+ const prev = currentByPkg.get(pkg.package_id);
194
+ if (prev === undefined) {
195
+ // No baseline - treat as increase (mirrors how sellers see a new
196
+ // budget on a previously-zero line).
197
+ sawIncrease = true;
198
+ proposedTotal += pkg.budget;
199
+ continue;
200
+ }
201
+ currentTotal += prev;
202
+ proposedTotal += pkg.budget;
203
+ if (pkg.budget > prev)
204
+ sawIncrease = true;
205
+ if (pkg.budget < prev)
206
+ sawDecrease = true;
207
+ }
208
+ // Reallocate: per-package movement in both directions but total
209
+ // unchanged (within float tolerance to absorb cent rounding).
210
+ if (sawIncrease && sawDecrease && Math.abs(proposedTotal - currentTotal) < BUDGET_EQUAL_TOLERANCE) {
211
+ return { action: 'reallocate_budget', direction: 'reallocate' };
212
+ }
213
+ if (proposedTotal > currentTotal)
214
+ return { action: 'increase_budget', direction: 'increase' };
215
+ if (proposedTotal < currentTotal)
216
+ return { action: 'decrease_budget', direction: 'decrease' };
217
+ // Equal totals with no per-package movement (e.g. budget set to same
218
+ // value) - defaults to reallocate so the request still has *some*
219
+ // action attached for the preflight to check against.
220
+ return { action: 'reallocate_budget', direction: 'reallocate' };
221
+ }
222
+ function resolveFlightEndDirection(currentBuy, request, field) {
223
+ // If start_time is being touched at the same time, the action is
224
+ // update_flight_dates regardless of end direction (shift semantics).
225
+ if (request.start_time !== undefined) {
226
+ return { action: 'update_flight_dates', direction: 'shift' };
227
+ }
228
+ const packageStartTouched = (request.packages ?? []).some(pkg => pkg.start_time !== undefined);
229
+ if (packageStartTouched) {
230
+ return { action: 'update_flight_dates', direction: 'shift' };
231
+ }
232
+ if (field === 'end_time') {
233
+ const currentEnd = currentBuy.end_time;
234
+ const proposedEnd = request.end_time;
235
+ if (currentEnd && proposedEnd) {
236
+ const cur = Date.parse(currentEnd);
237
+ const next = Date.parse(proposedEnd);
238
+ if (!Number.isNaN(cur) && !Number.isNaN(next)) {
239
+ if (next > cur)
240
+ return { action: 'extend_flight', direction: 'extend' };
241
+ if (next < cur)
242
+ return { action: 'shorten_flight', direction: 'shorten' };
243
+ }
244
+ }
245
+ // Indeterminate (missing baseline or unparseable dates). Fall through
246
+ // to the generic vocabulary; sellers that advertise either of the
247
+ // direction-specific actions usually also advertise update_flight_dates.
248
+ return { action: 'update_flight_dates', direction: 'shift' };
249
+ }
250
+ // packages[].end_time
251
+ let extending = false;
252
+ let shortening = false;
253
+ const currentByPkg = new Map();
254
+ for (const pkg of currentBuy.packages ?? []) {
255
+ if (pkg.package_id)
256
+ currentByPkg.set(pkg.package_id, pkg.end_time);
257
+ }
258
+ for (const pkg of request.packages ?? []) {
259
+ if (!pkg.end_time)
260
+ continue;
261
+ const prev = currentByPkg.get(pkg.package_id);
262
+ if (!prev) {
263
+ extending = true;
264
+ continue;
265
+ }
266
+ const cur = Date.parse(prev);
267
+ const next = Date.parse(pkg.end_time);
268
+ if (Number.isNaN(cur) || Number.isNaN(next))
269
+ continue;
270
+ if (next > cur)
271
+ extending = true;
272
+ if (next < cur)
273
+ shortening = true;
274
+ }
275
+ if (extending && !shortening)
276
+ return { action: 'extend_flight', direction: 'extend' };
277
+ if (shortening && !extending)
278
+ return { action: 'shorten_flight', direction: 'shorten' };
279
+ // Mixed or indeterminate - fall through to update_flight_dates.
280
+ return { action: 'update_flight_dates', direction: 'shift' };
281
+ }
282
+ /**
283
+ * Decide whether an `update_media_buy` request is reachable against the
284
+ * current buy state. When the buy carries only legacy `valid_actions[]`,
285
+ * the preflight passes (with `compat.source: 'valid_actions'`) for any
286
+ * matching action - mode is not knowable, so it's reported as `self_serve`
287
+ * but flagged as a compat fallback.
288
+ *
289
+ * Multi-action requests: every resolved action must be present in
290
+ * `available_actions[]`. All missing actions are reported in `denials[]`
291
+ * so callers can render every blocker in a single pass.
292
+ *
293
+ * Throws `ValidationError` when the request touches no recognized
294
+ * `update_media_buy` field. This is a buyer-side bug (the SDK was asked to
295
+ * dispatch a no-op), not a seller-side denial.
296
+ */
297
+ function preflightUpdateMediaBuy(currentBuy, request) {
298
+ const resolved = getActionForMutation(currentBuy, request);
299
+ if (resolved.length === 0) {
300
+ throw new errors_1.ValidationError('request', request, 'update_media_buy request must touch at least one mutating field (paused, canceled, start_time, end_time, packages[*], or new_packages)');
301
+ }
302
+ const result = (0, available_actions_1.getAvailableActions)(currentBuy, { silent: true });
303
+ const compat = result.source === 'valid_actions' ? { source: result.source, message: result.deprecationHint ?? '' } : undefined;
304
+ const matched = [];
305
+ const modes = [];
306
+ const denials = [];
307
+ for (const resolvedAction of resolved) {
308
+ const lookup = (0, available_actions_1.findAvailableAction)(currentBuy, resolvedAction.action, { silent: true });
309
+ if (!lookup) {
310
+ // Without product allowed_actions on the buy we can't distinguish
311
+ // not_supported_on_product vs not_supported_on_buy. wrong_status
312
+ // is server-side. Default to not_supported_on_buy: the most common
313
+ // preflight failure when a seller doesn't advertise the action on
314
+ // this specific buy.
315
+ denials.push({ action: resolvedAction.action, reason: 'not_supported_on_buy' });
316
+ continue;
317
+ }
318
+ matched.push(lookup.entry);
319
+ modes.push(lookup.entry.mode);
320
+ }
321
+ if (denials.length > 0) {
322
+ return {
323
+ ok: false,
324
+ denials,
325
+ currently_available_actions: result.actions,
326
+ compat,
327
+ };
328
+ }
329
+ return {
330
+ ok: true,
331
+ actions: resolved,
332
+ modes,
333
+ matched,
334
+ requiresAsyncFlow: modes.some(m => m !== 'self_serve'),
335
+ compat,
336
+ };
337
+ }
338
+ /**
339
+ * Build a typed recovery hint from a `mode_mismatch` rejection. Exported
340
+ * so callers handling `ActionNotAllowedError` outside of the preflight
341
+ * surface (e.g. when an in-flight mutation races a buy state change) get
342
+ * the same structured recovery path.
343
+ */
344
+ function recoveryForModeMismatch(attemptedAction, currentlyAvailable) {
345
+ const entry = currentlyAvailable.find(a => a.action === attemptedAction);
346
+ if (!entry)
347
+ return undefined;
348
+ switch (entry.mode) {
349
+ case 'requires_proposal':
350
+ return {
351
+ kind: 'createProposal',
352
+ message: `seller now resolves \`${attemptedAction}\` as requires_proposal. ` +
353
+ 'reissue via the proposal lifecycle (`create_proposal` / `finalize_proposal`).',
354
+ };
355
+ case 'requires_approval':
356
+ return {
357
+ kind: 'waitForApproval',
358
+ message: `seller now resolves \`${attemptedAction}\` as requires_approval. ` +
359
+ 'expect an async approval callback rather than a direct response.',
360
+ };
361
+ case 'conditional_self_serve':
362
+ return {
363
+ kind: 'reissueAsDirect',
364
+ message: `seller resolves \`${attemptedAction}\` as conditional_self_serve: ` +
365
+ 'small mutations clear automatically, larger ones queue. retry; expect a possible async escalation.',
366
+ };
367
+ case 'self_serve':
368
+ return {
369
+ kind: 'reissueAsDirect',
370
+ message: `seller resolves \`${attemptedAction}\` as self_serve. retry the same request.`,
371
+ };
372
+ default:
373
+ return undefined;
374
+ }
375
+ }
376
+ //# sourceMappingURL=preflight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../../src/lib/media-buy/preflight.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Fine-grained action identifier introduced in AdCP 3.1. Includes the legacy
3
+ * coarse values (`update_budget`, `update_dates`, `update_packages`,
4
+ * `sync_creatives`) so sellers staying on 3.x continue to round-trip.
5
+ */
6
+ export type MediaBuyValidAction = 'pause' | 'resume' | 'cancel' | 'extend_flight' | 'shorten_flight' | 'update_flight_dates' | 'increase_budget' | 'decrease_budget' | 'reallocate_budget' | 'update_targeting' | 'update_pacing' | 'update_frequency_caps' | 'replace_creative' | 'update_creative_assignments' | 'remove_creative' | 'add_packages' | 'remove_packages' | 'update_budget' | 'update_dates' | 'update_packages' | 'sync_creatives';
7
+ export declare const LEGACY_COARSE_ACTIONS: readonly ["update_budget", "update_dates", "update_packages", "sync_creatives"];
8
+ export type LegacyCoarseAction = (typeof LEGACY_COARSE_ACTIONS)[number];
9
+ /**
10
+ * How a seller honors a given action on a media buy. Buyers branch on this to
11
+ * pick a synchronous, conditional, proposal, or async-approval flow.
12
+ */
13
+ export type MediaBuyActionMode = 'self_serve' | 'conditional_self_serve' | 'requires_proposal' | 'requires_approval';
14
+ /**
15
+ * SLA window expressed as a structured duration. Mirrors `sla-window.json`
16
+ * as a `{ unit, value }` pair (e.g. `{ unit: 'hours', value: 24 }`). The schema
17
+ * landed alongside #4514 but is intentionally minimal; the spec calls out
18
+ * that absence means "no commitment", not "zero commitment".
19
+ */
20
+ export interface SlaWindow {
21
+ unit: 'minutes' | 'hours' | 'days' | 'business_days';
22
+ value: number;
23
+ response_max?: number;
24
+ }
25
+ /**
26
+ * One entry of the per-buy `available_actions[]` array. Authoritative for
27
+ * the buy at the moment of emission - sellers MAY resolve to a different
28
+ * mode by the time the mutation arrives, in which case the call is rejected
29
+ * with `ACTION_NOT_ALLOWED` (`reason: mode_mismatch`).
30
+ *
31
+ * The containing array is uniquely keyed by `action` (contract invariant,
32
+ * not enforced by JSON Schema `uniqueItems`).
33
+ */
34
+ export interface MediaBuyAvailableAction {
35
+ action: MediaBuyValidAction;
36
+ mode: MediaBuyActionMode;
37
+ sla?: SlaWindow;
38
+ /**
39
+ * Opaque pointer into a buy-terms negotiation. The buy-terms RFC is
40
+ * separate; until it lands the field is any string.
41
+ */
42
+ terms_ref?: string;
43
+ }
44
+ /**
45
+ * Reason an `update_media_buy` request was rejected with
46
+ * `ACTION_NOT_ALLOWED`. Buyer SDKs branch on this to choose a recovery path.
47
+ */
48
+ export type ActionNotAllowedReason = 'wrong_status' | 'not_supported_on_product' | 'not_supported_on_buy' | 'mode_mismatch';
49
+ /**
50
+ * Structured details payload for `ACTION_NOT_ALLOWED` errors.
51
+ */
52
+ export interface ActionNotAllowedDetails {
53
+ attempted_action: MediaBuyValidAction;
54
+ reason: ActionNotAllowedReason;
55
+ currently_available_actions?: MediaBuyAvailableAction[];
56
+ }
57
+ /**
58
+ * Minimum surface a media buy needs to expose for the preflight helpers to
59
+ * operate. Picks the fields the helpers actually read so callers can pass
60
+ * either a `MediaBuy`, a `CreateMediaBuySuccess`, an `UpdateMediaBuySuccess`,
61
+ * or a `get_media_buys` entry. Optional fields match the schema; required
62
+ * fields are required by the helpers themselves.
63
+ */
64
+ export interface MediaBuyActionContext {
65
+ media_buy_id?: string;
66
+ status?: string;
67
+ start_time?: string;
68
+ end_time?: string;
69
+ packages?: ReadonlyArray<{
70
+ package_id?: string;
71
+ budget?: number;
72
+ start_time?: string;
73
+ end_time?: string;
74
+ }>;
75
+ available_actions?: MediaBuyAvailableAction[];
76
+ valid_actions?: MediaBuyValidAction[];
77
+ }
78
+ /**
79
+ * Subset of `UpdateMediaBuyRequest` the resolver introspects. Reusing a
80
+ * minimal interface keeps the preflight independent of the generated
81
+ * request type so a schema bump that adds optional fields doesn't churn the
82
+ * resolver signature.
83
+ */
84
+ export interface UpdateMediaBuyRequestLike {
85
+ paused?: boolean;
86
+ canceled?: true;
87
+ cancellation_reason?: string;
88
+ start_time?: {
89
+ datetime?: string;
90
+ } | string;
91
+ end_time?: string;
92
+ new_packages?: ReadonlyArray<unknown>;
93
+ packages?: ReadonlyArray<{
94
+ package_id: string;
95
+ budget?: number;
96
+ pacing?: unknown;
97
+ start_time?: string;
98
+ end_time?: string;
99
+ paused?: boolean;
100
+ canceled?: true;
101
+ targeting_overlay?: {
102
+ frequency_cap?: unknown;
103
+ [k: string]: unknown;
104
+ };
105
+ keyword_targets_add?: unknown;
106
+ keyword_targets_remove?: unknown;
107
+ negative_keywords_add?: unknown;
108
+ negative_keywords_remove?: unknown;
109
+ creative_assignments?: unknown;
110
+ creatives?: unknown;
111
+ }>;
112
+ }
113
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/media-buy/types.ts"],"names":[],"mappings":"AAgBA;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC3B,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,eAAe,GACf,gBAAgB,GAChB,qBAAqB,GACrB,iBAAiB,GACjB,iBAAiB,GACjB,mBAAmB,GACnB,kBAAkB,GAClB,eAAe,GACf,uBAAuB,GACvB,kBAAkB,GAClB,6BAA6B,GAC7B,iBAAiB,GACjB,cAAc,GACd,iBAAiB,GACjB,eAAe,GACf,cAAc,GACd,iBAAiB,GACjB,gBAAgB,CAAC;AAErB,eAAO,MAAM,qBAAqB,iFAKiB,CAAC;AAEpD,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,wBAAwB,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAErH;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,eAAe,CAAC;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,IAAI,EAAE,kBAAkB,CAAC;IACzB,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAC9B,cAAc,GACd,0BAA0B,GAC1B,sBAAsB,GACtB,eAAe,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,EAAE,mBAAmB,CAAC;IACtC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,2BAA2B,CAAC,EAAE,uBAAuB,EAAE,CAAC;CACzD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,aAAa,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,iBAAiB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IAC9C,aAAa,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACvC;AAED;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,aAAa,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,IAAI,CAAC;QAChB,iBAAiB,CAAC,EAAE;YAAE,aAAa,CAAC,EAAE,OAAO,CAAC;YAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,CAAC;QACtE,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,sBAAsB,CAAC,EAAE,OAAO,CAAC;QACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;QAChC,wBAAwB,CAAC,EAAE,OAAO,CAAC;QACnC,oBAAoB,CAAC,EAAE,OAAO,CAAC;QAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC,CAAC;CACJ"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ // Buyer-side types for the available_actions surface (AdCP 3.1, RFC #4480).
3
+ //
4
+ // Hand-written until schemas/cache/ catches up to the 3.1 release and the
5
+ // codegen regenerates `*.generated.ts`. Mirrors:
6
+ // - schemas/source/core/media-buy-available-action.json
7
+ // - schemas/source/core/sla-window.json
8
+ // - schemas/source/enums/media-buy-action-mode.json
9
+ // - schemas/source/enums/media-buy-valid-action.json
10
+ // - schemas/source/enums/action-not-allowed-reason.json
11
+ // - schemas/source/error-details/action-not-allowed.json
12
+ //
13
+ // When `sync-schemas` next runs and produces the equivalent types under
14
+ // `src/lib/types/*.generated.ts`, this file should be deleted and the public
15
+ // re-exports in `src/lib/media-buy/index.ts` should point at the generated
16
+ // names.
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.LEGACY_COARSE_ACTIONS = void 0;
19
+ exports.LEGACY_COARSE_ACTIONS = [
20
+ 'update_budget',
21
+ 'update_dates',
22
+ 'update_packages',
23
+ 'sync_creatives',
24
+ ];
25
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/media-buy/types.ts"],"names":[],"mappings":";AAAA,4EAA4E;AAC5E,EAAE;AACF,0EAA0E;AAC1E,iDAAiD;AACjD,0DAA0D;AAC1D,0CAA0C;AAC1C,sDAAsD;AACtD,uDAAuD;AACvD,0DAA0D;AAC1D,2DAA2D;AAC3D,EAAE;AACF,wEAAwE;AACxE,6EAA6E;AAC7E,2EAA2E;AAC3E,SAAS;;;AA8BI,QAAA,qBAAqB,GAAG;IACnC,eAAe;IACf,cAAc;IACd,iBAAiB;IACjB,gBAAgB;CACiC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { MediaBuyValidAction } from './types';
2
+ export interface UpdateFieldEntry {
3
+ /** Dotted paths into the update_media_buy request body this action covers. */
4
+ readonly update_fields: readonly string[];
5
+ /** Fine-grained values this action rolls up to (legacy coarse actions only). */
6
+ readonly rollup: readonly MediaBuyValidAction[] | null;
7
+ /** True for `x-deprecated-enum-values` (legacy coarse vocabulary). */
8
+ readonly deprecated: boolean;
9
+ }
10
+ export declare const UPDATE_FIELDS_BY_ACTION: Readonly<Record<MediaBuyValidAction, UpdateFieldEntry>>;
11
+ export declare const ACTIONS_BY_FIELD: Readonly<Record<string, readonly MediaBuyValidAction[]>>;
12
+ export { LEGACY_COARSE_ACTIONS } from './types';
13
+ export type { LegacyCoarseAction } from './types';
14
+ //# sourceMappingURL=update-fields.generated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-fields.generated.d.ts","sourceRoot":"","sources":["../../../src/lib/media-buy/update-fields.generated.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,gFAAgF;IAChF,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,GAAG,IAAI,CAAC;IACvD,sEAAsE;IACtE,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAC5C,MAAM,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CA2GrC,CAAC;AAEX,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CACrC,MAAM,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC,CAqBtC,CAAC;AAEX,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC"}