@adcp/sdk 16.3.0 → 16.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/adapters/version/3.1/assignments.d.mts +12 -0
- package/dist/lib/adapters/version/3.1/assignments.d.ts +12 -0
- package/dist/lib/adapters/version/3.1/assignments.js +67 -0
- package/dist/lib/adapters/version/3.1/assignments.mjs +43 -0
- package/dist/lib/adapters/version/3.1/bidding.d.mts +3 -0
- package/dist/lib/adapters/version/3.1/bidding.d.ts +3 -0
- package/dist/lib/adapters/version/3.1/bidding.js +115 -0
- package/dist/lib/adapters/version/3.1/bidding.mjs +90 -0
- package/dist/lib/adapters/version/3.1/delivery.d.mts +7 -0
- package/dist/lib/adapters/version/3.1/delivery.d.ts +7 -0
- package/dist/lib/adapters/version/3.1/delivery.js +78 -0
- package/dist/lib/adapters/version/3.1/delivery.mjs +54 -0
- package/dist/lib/adapters/version/3.1/index.d.mts +3 -0
- package/dist/lib/adapters/version/3.1/index.d.ts +3 -0
- package/dist/lib/adapters/version/3.1/index.js +36 -0
- package/dist/lib/adapters/version/3.1/index.mjs +12 -0
- package/dist/lib/adapters/version/index.d.mts +59 -7
- package/dist/lib/adapters/version/index.d.ts +59 -7
- package/dist/lib/adapters/version/index.js +51 -2
- package/dist/lib/adapters/version/index.mjs +49 -1
- package/dist/lib/adapters/version/negotiate.d.mts +71 -0
- package/dist/lib/adapters/version/negotiate.d.ts +71 -0
- package/dist/lib/adapters/version/negotiate.js +101 -0
- package/dist/lib/adapters/version/negotiate.mjs +73 -0
- package/dist/lib/adapters/version/schema-projection.d.mts +33 -0
- package/dist/lib/adapters/version/schema-projection.d.ts +33 -0
- package/dist/lib/adapters/version/schema-projection.js +294 -0
- package/dist/lib/adapters/version/schema-projection.mjs +269 -0
- package/dist/lib/adapters/version/translate.d.mts +122 -0
- package/dist/lib/adapters/version/translate.d.ts +122 -0
- package/dist/lib/adapters/version/translate.js +169 -0
- package/dist/lib/adapters/version/translate.mjs +141 -0
- package/dist/lib/adapters/version/types.d.mts +51 -10
- package/dist/lib/adapters/version/types.d.ts +51 -10
- package/dist/lib/core/AgentClient.d.mts +1 -1
- package/dist/lib/core/AgentClient.d.ts +1 -1
- package/dist/lib/core/ConversationTypes.d.mts +7 -0
- package/dist/lib/core/ConversationTypes.d.ts +7 -0
- package/dist/lib/core/SingleAgentClient.d.mts +82 -0
- package/dist/lib/core/SingleAgentClient.d.ts +82 -0
- package/dist/lib/core/SingleAgentClient.js +323 -15
- package/dist/lib/core/SingleAgentClient.mjs +337 -17
- package/dist/lib/core/TaskExecutor.d.mts +1 -1
- package/dist/lib/core/TaskExecutor.d.ts +1 -1
- package/dist/lib/core/TaskExecutor.js +97 -21
- package/dist/lib/core/TaskExecutor.mjs +97 -21
- package/dist/lib/core/account-reduction.d.mts +36 -0
- package/dist/lib/core/account-reduction.d.ts +36 -0
- package/dist/lib/core/account-reduction.js +127 -0
- package/dist/lib/core/account-reduction.mjs +98 -0
- package/dist/lib/core/buyer-account-registry.d.mts +52 -0
- package/dist/lib/core/buyer-account-registry.d.ts +52 -0
- package/dist/lib/core/buyer-account-registry.js +142 -6
- package/dist/lib/core/buyer-account-registry.mjs +142 -6
- package/dist/lib/media-buy/action-contracts.js +4 -4
- package/dist/lib/media-buy/action-contracts.mjs +4 -4
- package/dist/lib/media-buy/action-types.d.mts +3 -2
- package/dist/lib/media-buy/action-types.d.ts +3 -2
- package/dist/lib/media-buy/update-fields.generated.d.mts +3 -2
- package/dist/lib/media-buy/update-fields.generated.d.ts +3 -2
- package/dist/lib/registry/types.generated.d.mts +1 -1
- package/dist/lib/registry/types.generated.d.ts +1 -1
- package/dist/lib/server/create-adcp-server.d.mts +21 -0
- package/dist/lib/server/create-adcp-server.d.ts +21 -0
- package/dist/lib/server/create-adcp-server.js +97 -15
- package/dist/lib/server/create-adcp-server.mjs +83 -1
- package/dist/lib/server/index.d.mts +1 -1
- package/dist/lib/server/index.d.ts +1 -1
- package/dist/lib/storage/interfaces.d.mts +2 -0
- package/dist/lib/storage/interfaces.d.ts +2 -0
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/llms.txt +3 -3
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/package.json +1 -1
|
@@ -22,6 +22,10 @@ function isDefinitiveRejection(result) {
|
|
|
22
22
|
result.adcpError && !result.adcpError.synthetic && !result.adcpError.code.startsWith("IDEMPOTENCY_") && ["terminal", "correctable"].includes(result.adcpError.recovery ?? "")
|
|
23
23
|
);
|
|
24
24
|
}
|
|
25
|
+
function rowMatchesReference(ref, row) {
|
|
26
|
+
if ("account_id" in ref) return row.account_id === ref.account_id;
|
|
27
|
+
return row.brand?.domain === ref.brand.domain && row.operator === ref.operator && (!ref.brand.brand_id || row.brand.brand_id === ref.brand.brand_id) && sameCountrySet(ref.brand.countries, row.brand.countries) && (!ref.operator_unit || row.operator_unit?.id === ref.operator_unit.id) && (!ref.currency || row.currency === ref.currency) && (!ref.timezone || row.timezone === ref.timezone) && (row.sandbox === void 0 || row.sandbox === true === (ref.sandbox === true));
|
|
28
|
+
}
|
|
25
29
|
class BuyerAccountRegistry {
|
|
26
30
|
constructor(scope, provision, storage, repair, registryOptions = {}) {
|
|
27
31
|
this.scope = scope;
|
|
@@ -40,6 +44,8 @@ class BuyerAccountRegistry {
|
|
|
40
44
|
repair;
|
|
41
45
|
registryOptions;
|
|
42
46
|
entries = /* @__PURE__ */ new Map();
|
|
47
|
+
/** Reduction bindings when no storage is configured (never evicted). */
|
|
48
|
+
reductions = /* @__PURE__ */ new Map();
|
|
43
49
|
pending = /* @__PURE__ */ new Map();
|
|
44
50
|
writes = Promise.resolve();
|
|
45
51
|
repairs = /* @__PURE__ */ new Map();
|
|
@@ -421,12 +427,13 @@ class BuyerAccountRegistry {
|
|
|
421
427
|
return this.enqueue(async () => {
|
|
422
428
|
if (scope !== this.scope()) return;
|
|
423
429
|
for (const ref of refs) {
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
+
const isRow = (value) => !!value && typeof value === "object";
|
|
431
|
+
let candidates = rows.filter((value) => isRow(value) && rowMatchesReference(ref, value));
|
|
432
|
+
if (candidates.length === 0 && !("account_id" in ref)) {
|
|
433
|
+
const reduction = (await this.reductionFor(ref))?.account;
|
|
434
|
+
if (scope !== this.scope()) return;
|
|
435
|
+
if (reduction) candidates = rows.filter((value) => isRow(value) && rowMatchesReference(reduction, value));
|
|
436
|
+
}
|
|
430
437
|
if (candidates.length !== 1) continue;
|
|
431
438
|
let row = candidates[0];
|
|
432
439
|
if (row.action === "failed" || typeof row.status !== "string") continue;
|
|
@@ -591,6 +598,135 @@ class BuyerAccountRegistry {
|
|
|
591
598
|
}
|
|
592
599
|
}
|
|
593
600
|
}
|
|
601
|
+
reductionKey(kind, account, scope = this.scope()) {
|
|
602
|
+
return `${scope}:${kind}:${accountReferenceKey(account)}`;
|
|
603
|
+
}
|
|
604
|
+
async readReduction(key) {
|
|
605
|
+
const entry = this.storage ? await this.storage.get(key) : this.reductions.get(key);
|
|
606
|
+
return entry && entry.status === "reduced" ? structuredClone(entry) : void 0;
|
|
607
|
+
}
|
|
608
|
+
/** Insert-if-absent; returns false when another writer already holds the key. */
|
|
609
|
+
async insertReduction(key, entry) {
|
|
610
|
+
const prior = this.storage ? await this.storage.get(key) : this.reductions.get(key);
|
|
611
|
+
if (prior && prior.status === "reduced") return false;
|
|
612
|
+
if (this.storage?.compareAndSet) {
|
|
613
|
+
return this.storage.compareAndSet(key, prior?.revision, { ...entry, revision: (prior?.revision ?? 0) + 1 });
|
|
614
|
+
}
|
|
615
|
+
if (this.storage) await this.storage.set(key, structuredClone(entry));
|
|
616
|
+
else this.reductions.set(key, structuredClone(entry));
|
|
617
|
+
return true;
|
|
618
|
+
}
|
|
619
|
+
async replaceReduction(key, entry) {
|
|
620
|
+
const prior = this.storage ? await this.storage.get(key) : this.reductions.get(key);
|
|
621
|
+
if (this.storage?.compareAndSet) {
|
|
622
|
+
const next = { ...entry, revision: (prior?.revision ?? 0) + 1 };
|
|
623
|
+
if (!await this.storage.compareAndSet(key, prior?.revision, next))
|
|
624
|
+
throw new AccountSetupRequiredError("Account storage revision changed. Reload and reconcile before retrying.");
|
|
625
|
+
} else if (this.storage) await this.storage.set(key, structuredClone(entry));
|
|
626
|
+
else this.reductions.set(key, structuredClone(entry));
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Bind reduced account keys to the buyer keys they came from, before a
|
|
630
|
+
* request carrying them is sent to a seller on an older release. Each
|
|
631
|
+
* reduced key serves one buyer key only. A key sent unreduced claims itself
|
|
632
|
+
* (`account` and `reduced` equal), so a plain key and a reduced one can never
|
|
633
|
+
* land on the same seller account in either order.
|
|
634
|
+
*
|
|
635
|
+
* All-or-nothing: every claim is checked, against storage and against the
|
|
636
|
+
* other claims in the same request, before any is written. On a conflict
|
|
637
|
+
* nothing is written and the index and owner of the first conflicting claim
|
|
638
|
+
* are returned. A claim lost to a concurrent writer rolls back the claims
|
|
639
|
+
* this call already wrote.
|
|
640
|
+
*/
|
|
641
|
+
async claimReductions(claims) {
|
|
642
|
+
const scope = this.scope();
|
|
643
|
+
let conflict;
|
|
644
|
+
await this.enqueue(async () => {
|
|
645
|
+
const pending = /* @__PURE__ */ new Map();
|
|
646
|
+
const toInsert = [];
|
|
647
|
+
for (const [index, claim] of claims.entries()) {
|
|
648
|
+
const reducedKey = accountReferenceKey(claim.reduced);
|
|
649
|
+
const inRequest = pending.get(reducedKey);
|
|
650
|
+
if (inRequest && accountReferenceKey(inRequest) !== accountReferenceKey(claim.account)) {
|
|
651
|
+
conflict = { index, owner: inRequest };
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
pending.set(reducedKey, claim.account);
|
|
655
|
+
const owner = (await this.readReduction(this.reductionKey("reduced", claim.reduced, scope)))?.reducedFrom;
|
|
656
|
+
if (owner && accountReferenceKey(owner) !== accountReferenceKey(claim.account)) {
|
|
657
|
+
conflict = { index, owner };
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
if (!owner && !inRequest) toInsert.push(index);
|
|
661
|
+
}
|
|
662
|
+
const inserted = [];
|
|
663
|
+
for (const index of toInsert) {
|
|
664
|
+
const claim = claims[index];
|
|
665
|
+
const reverseKey = this.reductionKey("reduced", claim.reduced, scope);
|
|
666
|
+
const ok = await this.insertReduction(reverseKey, {
|
|
667
|
+
account: structuredClone(claim.reduced),
|
|
668
|
+
status: "reduced",
|
|
669
|
+
reducedFrom: structuredClone(claim.account)
|
|
670
|
+
});
|
|
671
|
+
const winner = ok ? void 0 : (await this.readReduction(reverseKey))?.reducedFrom;
|
|
672
|
+
if (!ok && winner && accountReferenceKey(winner) !== accountReferenceKey(claim.account)) {
|
|
673
|
+
for (const done of inserted) {
|
|
674
|
+
const doneClaim = claims[done];
|
|
675
|
+
await this.replaceReduction(this.reductionKey("reduced", doneClaim.reduced, scope), {
|
|
676
|
+
account: structuredClone(doneClaim.reduced),
|
|
677
|
+
status: "released"
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
conflict = { index, owner: winner };
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
if (ok) inserted.push(index);
|
|
684
|
+
}
|
|
685
|
+
for (const claim of claims) {
|
|
686
|
+
if (accountReferenceKey(claim.account) === accountReferenceKey(claim.reduced)) continue;
|
|
687
|
+
const forwardKey = this.reductionKey("reduction", claim.account, scope);
|
|
688
|
+
const current = await this.readReduction(forwardKey);
|
|
689
|
+
const reduction = { account: claim.reduced, adcpVersion: claim.adcpVersion };
|
|
690
|
+
if (current?.reduction && isDeepStrictEqual(current.reduction, reduction)) continue;
|
|
691
|
+
await this.replaceReduction(forwardKey, {
|
|
692
|
+
account: structuredClone(claim.account),
|
|
693
|
+
status: "reduced",
|
|
694
|
+
reduction: structuredClone(reduction)
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
});
|
|
698
|
+
return conflict;
|
|
699
|
+
}
|
|
700
|
+
/** The buyer key a reduced seller key was claimed for, if any. */
|
|
701
|
+
async reductionOwner(reduced) {
|
|
702
|
+
return (await this.readReduction(this.reductionKey("reduced", reduced)))?.reducedFrom;
|
|
703
|
+
}
|
|
704
|
+
/** The reduced key a buyer key reached an older seller with, if any. */
|
|
705
|
+
async reductionFor(account) {
|
|
706
|
+
return (await this.readReduction(this.reductionKey("reduction", account)))?.reduction;
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Forget that `account` reached this seller under a reduced key. Call once
|
|
710
|
+
* the account has moved to its full key: after a `sync_accounts` settings
|
|
711
|
+
* update rekeys `operator_unit` in place, or after opening a new account
|
|
712
|
+
* under the full key when the reduced fields (`currency`, `timezone`,
|
|
713
|
+
* `brand.countries`) cannot change on an existing account. Until then the
|
|
714
|
+
* client keeps addressing the seller account by its reduced key.
|
|
715
|
+
*/
|
|
716
|
+
async clearReduction(account) {
|
|
717
|
+
const scope = this.scope();
|
|
718
|
+
await this.enqueue(async () => {
|
|
719
|
+
const forwardKey = this.reductionKey("reduction", account, scope);
|
|
720
|
+
const forward = await this.readReduction(forwardKey);
|
|
721
|
+
if (!forward?.reduction) return;
|
|
722
|
+
const reverseKey = this.reductionKey("reduced", forward.reduction.account, scope);
|
|
723
|
+
const reverse = await this.readReduction(reverseKey);
|
|
724
|
+
if (reverse?.reducedFrom && accountReferenceKey(reverse.reducedFrom) === accountReferenceKey(account)) {
|
|
725
|
+
await this.replaceReduction(reverseKey, { account: reverse.account, status: "released" });
|
|
726
|
+
}
|
|
727
|
+
await this.replaceReduction(forwardKey, { account: forward.account, status: "released" });
|
|
728
|
+
});
|
|
729
|
+
}
|
|
594
730
|
}
|
|
595
731
|
export {
|
|
596
732
|
BuyerAccountRegistry
|
|
@@ -45,6 +45,7 @@ var import_media_buy_helpers = require('../server/media-buy-helpers.js');
|
|
|
45
45
|
var import_available_actions = require('./available-actions.js');
|
|
46
46
|
const NON_TERMINAL_ACTION_STATUSES = ["pending_creatives", "pending_start", "active", "paused"];
|
|
47
47
|
const MODES = ["self_serve", "conditional_self_serve", "seller_managed", "requires_approval"];
|
|
48
|
+
const CANONICAL_TASKS = new Set(Object.values(import_action_metadata.CANONICAL_ACTION_TASKS).flat());
|
|
48
49
|
const record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
49
50
|
const finite = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
50
51
|
function mediaBuyActionTasks(action) {
|
|
@@ -137,7 +138,7 @@ function changeConstraintIssues(action, constraints, currency) {
|
|
|
137
138
|
}
|
|
138
139
|
function slaValid(sla) {
|
|
139
140
|
return sla === void 0 || record(sla) && Object.entries(sla).every(
|
|
140
|
-
([k, v]) => ["response_max", "completion_max"].includes(k) && typeof v === "string" && /^P(?!$)(\d+Y)?(\d+M)?(\d+D)?(T(\d+H)?(\d+M)?(\d+S)?)?$/.test(v)
|
|
141
|
+
([k, v]) => k === "clock" && v === "elapsed" || ["response_max", "completion_max"].includes(k) && typeof v === "string" && /^P(?!$)(\d+Y)?(\d+M)?(\d+D)?(T(\d+H)?(\d+M)?(\d+S)?)?$/.test(v)
|
|
141
142
|
);
|
|
142
143
|
}
|
|
143
144
|
function changeTermIssues(terms, currency) {
|
|
@@ -211,7 +212,7 @@ function productTemplateIssues(templates, currency) {
|
|
|
211
212
|
currency
|
|
212
213
|
).filter((issue) => issue !== "invalid or duplicate action identity")
|
|
213
214
|
);
|
|
214
|
-
if (!
|
|
215
|
+
if (!Object.hasOwn(import_action_metadata.CANONICAL_ACTION_TASKS, template.action) && !import_action_metadata.LEGACY_AVAILABLE_ACTIONS.includes(template.action))
|
|
215
216
|
issues.push("invalid product action");
|
|
216
217
|
if (template.allowed_statuses !== void 0 && (!Array.isArray(template.allowed_statuses) || !template.allowed_statuses.length || new Set(template.allowed_statuses).size !== template.allowed_statuses.length || template.allowed_statuses.some(
|
|
217
218
|
(status) => ![...NON_TERMINAL_ACTION_STATUSES, "completed", "rejected", "canceled"].includes(status)
|
|
@@ -233,8 +234,7 @@ function liveActionIssues(entries) {
|
|
|
233
234
|
if (!record(entry) || typeof entry.action !== "string" || !entry.action || typeof entry.mode !== "string" || !entry.mode || seen.has(entry.action))
|
|
234
235
|
return ["invalid or duplicate live action"];
|
|
235
236
|
seen.add(entry.action);
|
|
236
|
-
if (entry.task !== void 0 && !
|
|
237
|
-
return ["invalid live task"];
|
|
237
|
+
if (entry.task !== void 0 && !CANONICAL_TASKS.has(String(entry.task))) return ["invalid live task"];
|
|
238
238
|
if (!slaValid(entry.sla)) return ["invalid live SLA"];
|
|
239
239
|
if (entry.change_term_id !== void 0 && (typeof entry.change_term_id !== "string" || !/^[A-Za-z0-9_.:-]+$/.test(entry.change_term_id)))
|
|
240
240
|
return ["invalid live term identity"];
|
|
@@ -9,6 +9,7 @@ import { validActionsForStatus } from "../server/media-buy-helpers.mjs";
|
|
|
9
9
|
import { getRollupParent } from "./available-actions.mjs";
|
|
10
10
|
const NON_TERMINAL_ACTION_STATUSES = ["pending_creatives", "pending_start", "active", "paused"];
|
|
11
11
|
const MODES = ["self_serve", "conditional_self_serve", "seller_managed", "requires_approval"];
|
|
12
|
+
const CANONICAL_TASKS = new Set(Object.values(CANONICAL_ACTION_TASKS).flat());
|
|
12
13
|
const record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
13
14
|
const finite = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
14
15
|
function mediaBuyActionTasks(action) {
|
|
@@ -101,7 +102,7 @@ function changeConstraintIssues(action, constraints, currency) {
|
|
|
101
102
|
}
|
|
102
103
|
function slaValid(sla) {
|
|
103
104
|
return sla === void 0 || record(sla) && Object.entries(sla).every(
|
|
104
|
-
([k, v]) => ["response_max", "completion_max"].includes(k) && typeof v === "string" && /^P(?!$)(\d+Y)?(\d+M)?(\d+D)?(T(\d+H)?(\d+M)?(\d+S)?)?$/.test(v)
|
|
105
|
+
([k, v]) => k === "clock" && v === "elapsed" || ["response_max", "completion_max"].includes(k) && typeof v === "string" && /^P(?!$)(\d+Y)?(\d+M)?(\d+D)?(T(\d+H)?(\d+M)?(\d+S)?)?$/.test(v)
|
|
105
106
|
);
|
|
106
107
|
}
|
|
107
108
|
function changeTermIssues(terms, currency) {
|
|
@@ -175,7 +176,7 @@ function productTemplateIssues(templates, currency) {
|
|
|
175
176
|
currency
|
|
176
177
|
).filter((issue) => issue !== "invalid or duplicate action identity")
|
|
177
178
|
);
|
|
178
|
-
if (!
|
|
179
|
+
if (!Object.hasOwn(CANONICAL_ACTION_TASKS, template.action) && !LEGACY_AVAILABLE_ACTIONS.includes(template.action))
|
|
179
180
|
issues.push("invalid product action");
|
|
180
181
|
if (template.allowed_statuses !== void 0 && (!Array.isArray(template.allowed_statuses) || !template.allowed_statuses.length || new Set(template.allowed_statuses).size !== template.allowed_statuses.length || template.allowed_statuses.some(
|
|
181
182
|
(status) => ![...NON_TERMINAL_ACTION_STATUSES, "completed", "rejected", "canceled"].includes(status)
|
|
@@ -197,8 +198,7 @@ function liveActionIssues(entries) {
|
|
|
197
198
|
if (!record(entry) || typeof entry.action !== "string" || !entry.action || typeof entry.mode !== "string" || !entry.mode || seen.has(entry.action))
|
|
198
199
|
return ["invalid or duplicate live action"];
|
|
199
200
|
seen.add(entry.action);
|
|
200
|
-
if (entry.task !== void 0 && !
|
|
201
|
-
return ["invalid live task"];
|
|
201
|
+
if (entry.task !== void 0 && !CANONICAL_TASKS.has(String(entry.task))) return ["invalid live task"];
|
|
202
202
|
if (!slaValid(entry.sla)) return ["invalid live SLA"];
|
|
203
203
|
if (entry.change_term_id !== void 0 && (typeof entry.change_term_id !== "string" || !/^[A-Za-z0-9_.:-]+$/.test(entry.change_term_id)))
|
|
204
204
|
return ["invalid live term identity"];
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { CanonicalProductAction, MediaBuyChangeTerm, MediaBuyChangeTermConstraints, MediaBuyStatus } from '../types/core.generated.mjs';
|
|
2
2
|
import type { MediaBuyActionContext, MediaBuyActionId, MediaBuyActionMode, SLAWindow } from './types.mjs';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import type { CANONICAL_ACTION_TASKS } from './action-metadata.generated.mjs';
|
|
4
|
+
/** Canonical wire tasks plus the established 3.1 mutation facade. */
|
|
5
|
+
export type MediaBuyTask = 'update_media_buy' | (typeof CANONICAL_ACTION_TASKS)[keyof typeof CANONICAL_ACTION_TASKS][number];
|
|
5
6
|
/** Alias of the shared, schema-derived action vocabulary. */
|
|
6
7
|
export type MediaBuyAction = MediaBuyActionId;
|
|
7
8
|
export type ProductActionTemplate = Pick<CanonicalProductAction, 'modes' | 'allowed_statuses' | 'sla' | 'constraints' | 'terms_ref'> & {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { CanonicalProductAction, MediaBuyChangeTerm, MediaBuyChangeTermConstraints, MediaBuyStatus } from '../types/core.generated';
|
|
2
2
|
import type { MediaBuyActionContext, MediaBuyActionId, MediaBuyActionMode, SLAWindow } from './types';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import type { CANONICAL_ACTION_TASKS } from './action-metadata.generated';
|
|
4
|
+
/** Canonical wire tasks plus the established 3.1 mutation facade. */
|
|
5
|
+
export type MediaBuyTask = 'update_media_buy' | (typeof CANONICAL_ACTION_TASKS)[keyof typeof CANONICAL_ACTION_TASKS][number];
|
|
5
6
|
/** Alias of the shared, schema-derived action vocabulary. */
|
|
6
7
|
export type MediaBuyAction = MediaBuyActionId;
|
|
7
8
|
export type ProductActionTemplate = Pick<CanonicalProductAction, 'modes' | 'allowed_statuses' | 'sla' | 'constraints' | 'terms_ref'> & {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { MediaBuyValidAction } from './types.mjs';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Update-binding actions that exist only on `available_actions[].action`
|
|
4
|
+
* (absent from the deprecated flat `valid_actions[]` enum). Their
|
|
5
5
|
* field bindings come from `core/media-buy-available-action-id.json`.
|
|
6
|
+
* Actions routed exclusively to other tasks are excluded.
|
|
6
7
|
* Empty when the schema cache predates that file.
|
|
7
8
|
*/
|
|
8
9
|
export declare const STRUCTURED_ONLY_MEDIA_BUY_ACTIONS: readonly ["update_media_buy_frequency_cap"];
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { MediaBuyValidAction } from './types';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Update-binding actions that exist only on `available_actions[].action`
|
|
4
|
+
* (absent from the deprecated flat `valid_actions[]` enum). Their
|
|
5
5
|
* field bindings come from `core/media-buy-available-action-id.json`.
|
|
6
|
+
* Actions routed exclusively to other tasks are excluded.
|
|
6
7
|
* Empty when the schema cache predates that file.
|
|
7
8
|
*/
|
|
8
9
|
export declare const STRUCTURED_ONLY_MEDIA_BUY_ACTIONS: readonly ["update_media_buy_frequency_cap"];
|
|
@@ -3612,7 +3612,7 @@ export interface components {
|
|
|
3612
3612
|
} | {
|
|
3613
3613
|
/** @enum {string} */
|
|
3614
3614
|
kind: "targeting_restriction";
|
|
3615
|
-
restricted_attributes?: ("racial_ethnic_origin" | "political_opinions" | "religious_beliefs" | "trade_union_membership" | "health_data" | "sex_life_sexual_orientation" | "genetic_data" | "biometric_data" | "age" | "familial_status")[];
|
|
3615
|
+
restricted_attributes?: ("racial_ethnic_origin" | "political_opinions" | "religious_beliefs" | "trade_union_membership" | "health_data" | "sex_life_sexual_orientation" | "genetic_data" | "biometric_data" | "age" | "familial_status" | "sex_gender")[];
|
|
3616
3616
|
description?: string;
|
|
3617
3617
|
} | {
|
|
3618
3618
|
/** @enum {string} */
|
|
@@ -3612,7 +3612,7 @@ export interface components {
|
|
|
3612
3612
|
} | {
|
|
3613
3613
|
/** @enum {string} */
|
|
3614
3614
|
kind: "targeting_restriction";
|
|
3615
|
-
restricted_attributes?: ("racial_ethnic_origin" | "political_opinions" | "religious_beliefs" | "trade_union_membership" | "health_data" | "sex_life_sexual_orientation" | "genetic_data" | "biometric_data" | "age" | "familial_status")[];
|
|
3615
|
+
restricted_attributes?: ("racial_ethnic_origin" | "political_opinions" | "religious_beliefs" | "trade_union_membership" | "health_data" | "sex_life_sexual_orientation" | "genetic_data" | "biometric_data" | "age" | "familial_status" | "sex_gender")[];
|
|
3616
3616
|
description?: string;
|
|
3617
3617
|
} | {
|
|
3618
3618
|
/** @enum {string} */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type VersionDrift } from '../adapters/version/index.mjs';
|
|
1
2
|
/**
|
|
2
3
|
* Declarative AdCP server builder.
|
|
3
4
|
*
|
|
@@ -1198,6 +1199,17 @@ export type WebhooksConfig = Pick<WebhookEmitterOptions, 'signerKey' | 'signerPr
|
|
|
1198
1199
|
/** Observability: receives failures isolated from attempt observers. */
|
|
1199
1200
|
onAttemptObserverError?: WebhookEmitterOptions['onAttemptObserverError'];
|
|
1200
1201
|
};
|
|
1202
|
+
/** One request or response conversion between the server's release and a buyer's. */
|
|
1203
|
+
export interface AdcpVersionTranslationEvent {
|
|
1204
|
+
tool: string;
|
|
1205
|
+
direction: 'request' | 'response';
|
|
1206
|
+
/** Release the payload was converted from. */
|
|
1207
|
+
fromVersion: string;
|
|
1208
|
+
/** Release the payload was converted to. */
|
|
1209
|
+
toVersion: string;
|
|
1210
|
+
/** What each conversion step removed or moved. */
|
|
1211
|
+
drifts: VersionDrift[];
|
|
1212
|
+
}
|
|
1201
1213
|
export interface AdcpServerConfig<TAccount = unknown> {
|
|
1202
1214
|
/** Experimental 3.3 authorization, invoked before idempotency and handler side effects. */
|
|
1203
1215
|
identity33?: {
|
|
@@ -1258,6 +1270,15 @@ export interface AdcpServerConfig<TAccount = unknown> {
|
|
|
1258
1270
|
* releases, and no newer than `adcpVersion`.
|
|
1259
1271
|
*/
|
|
1260
1272
|
defaultAdcpVersion?: AdcpVersion | (string & {});
|
|
1273
|
+
/**
|
|
1274
|
+
* Called each time the framework converts a request up from, or a
|
|
1275
|
+
* handler's response down to, a buyer's older release. `drifts` lists every
|
|
1276
|
+
* field the conversion removed or moved, with JSON paths, so a seller can
|
|
1277
|
+
* record what an older buyer did not receive. The same events are logged
|
|
1278
|
+
* at `debug` (requests) and `info` (responses). A throwing callback is
|
|
1279
|
+
* logged and ignored.
|
|
1280
|
+
*/
|
|
1281
|
+
onVersionTranslation?: (event: AdcpVersionTranslationEvent) => void;
|
|
1261
1282
|
/**
|
|
1262
1283
|
* Per-tool inclusive protocol-release availability. This narrows, but does
|
|
1263
1284
|
* not replace, the server-wide releases declared through capabilities.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type VersionDrift } from '../adapters/version';
|
|
1
2
|
/**
|
|
2
3
|
* Declarative AdCP server builder.
|
|
3
4
|
*
|
|
@@ -1198,6 +1199,17 @@ export type WebhooksConfig = Pick<WebhookEmitterOptions, 'signerKey' | 'signerPr
|
|
|
1198
1199
|
/** Observability: receives failures isolated from attempt observers. */
|
|
1199
1200
|
onAttemptObserverError?: WebhookEmitterOptions['onAttemptObserverError'];
|
|
1200
1201
|
};
|
|
1202
|
+
/** One request or response conversion between the server's release and a buyer's. */
|
|
1203
|
+
export interface AdcpVersionTranslationEvent {
|
|
1204
|
+
tool: string;
|
|
1205
|
+
direction: 'request' | 'response';
|
|
1206
|
+
/** Release the payload was converted from. */
|
|
1207
|
+
fromVersion: string;
|
|
1208
|
+
/** Release the payload was converted to. */
|
|
1209
|
+
toVersion: string;
|
|
1210
|
+
/** What each conversion step removed or moved. */
|
|
1211
|
+
drifts: VersionDrift[];
|
|
1212
|
+
}
|
|
1201
1213
|
export interface AdcpServerConfig<TAccount = unknown> {
|
|
1202
1214
|
/** Experimental 3.3 authorization, invoked before idempotency and handler side effects. */
|
|
1203
1215
|
identity33?: {
|
|
@@ -1258,6 +1270,15 @@ export interface AdcpServerConfig<TAccount = unknown> {
|
|
|
1258
1270
|
* releases, and no newer than `adcpVersion`.
|
|
1259
1271
|
*/
|
|
1260
1272
|
defaultAdcpVersion?: AdcpVersion | (string & {});
|
|
1273
|
+
/**
|
|
1274
|
+
* Called each time the framework converts a request up from, or a
|
|
1275
|
+
* handler's response down to, a buyer's older release. `drifts` lists every
|
|
1276
|
+
* field the conversion removed or moved, with JSON paths, so a seller can
|
|
1277
|
+
* record what an older buyer did not receive. The same events are logged
|
|
1278
|
+
* at `debug` (requests) and `info` (responses). A throwing callback is
|
|
1279
|
+
* logged and ignored.
|
|
1280
|
+
*/
|
|
1281
|
+
onVersionTranslation?: (event: AdcpVersionTranslationEvent) => void;
|
|
1261
1282
|
/**
|
|
1262
1283
|
* Per-tool inclusive protocol-release availability. This narrows, but does
|
|
1263
1284
|
* not replace, the server-wide releases declared through capabilities.
|
|
@@ -31,6 +31,7 @@ __export(create_adcp_server_exports, {
|
|
|
31
31
|
});
|
|
32
32
|
module.exports = __toCommonJS(create_adcp_server_exports);
|
|
33
33
|
var import_web_bot_auth = require('../signing/web-bot-auth.js');
|
|
34
|
+
var import_version = require('../adapters/version/index.js');
|
|
34
35
|
var import_schema_loader = require('../validation/schema-loader.js');
|
|
35
36
|
var import_lifecycle = require('../identity-3.3/lifecycle.js');
|
|
36
37
|
var import_server = require('../identity-3.3/server.js');
|
|
@@ -38,7 +39,7 @@ var import_web_bot_auth2 = require('../signing/web-bot-auth.js');
|
|
|
38
39
|
var import_validation = require('../identity-3.3/validation.js');
|
|
39
40
|
var import_trust = require('../identity-3.3/trust.js');
|
|
40
41
|
var import_zod = require("zod");
|
|
41
|
-
var
|
|
42
|
+
var import_version2 = require('../version.js');
|
|
42
43
|
var import_adcp_version_config = require('../utils/adcp-version-config.js');
|
|
43
44
|
var import_errors = require('../errors/index.js');
|
|
44
45
|
var import_schema_loader2 = require('../validation/schema-loader.js');
|
|
@@ -79,7 +80,7 @@ var import_middleware = require('../signing/middleware.js');
|
|
|
79
80
|
var import_operation_resolution = require('../signing/operation-resolution.js');
|
|
80
81
|
var import_account_mode = require('./account-mode.js');
|
|
81
82
|
var import_test_controller_bridge = require('./test-controller-bridge.js');
|
|
82
|
-
var
|
|
83
|
+
var import_version3 = require('../version.js');
|
|
83
84
|
var import_schemas2 = require('../types/schemas.generated.js');
|
|
84
85
|
var import_error_codes = require('../types/error-codes.js');
|
|
85
86
|
function hasIdempotencyClearAll(store) {
|
|
@@ -1406,7 +1407,7 @@ function normalizeMediaBuyStatusCollision(response, toolName) {
|
|
|
1406
1407
|
}
|
|
1407
1408
|
function injectVersionIntoResponse(response, servedVersion) {
|
|
1408
1409
|
if (!servedVersion) return;
|
|
1409
|
-
const wireVersion = (0,
|
|
1410
|
+
const wireVersion = (0, import_version2.toReleasePrecisionVersion)(servedVersion);
|
|
1410
1411
|
const sc = response.structuredContent;
|
|
1411
1412
|
if (sc && typeof sc === "object" && !("adcp_version" in sc)) {
|
|
1412
1413
|
const mirrorsStructuredContent = contentTextMirrorsStructuredContent(response, sc);
|
|
@@ -1660,11 +1661,11 @@ function getAdvertisedSupportedMajors(capConfig, serverPin) {
|
|
|
1660
1661
|
if (Number.isFinite(m)) out.add(m);
|
|
1661
1662
|
}
|
|
1662
1663
|
for (const v of capConfig?.supported_versions ?? []) {
|
|
1663
|
-
const m = (0,
|
|
1664
|
+
const m = (0, import_version2.parseAdcpMajorVersion)(v);
|
|
1664
1665
|
if (Number.isFinite(m)) out.add(m);
|
|
1665
1666
|
}
|
|
1666
1667
|
if (out.size === 0) {
|
|
1667
|
-
const pinMajor = (0,
|
|
1668
|
+
const pinMajor = (0, import_version2.parseAdcpMajorVersion)(serverPin);
|
|
1668
1669
|
if (Number.isFinite(pinMajor)) out.add(pinMajor);
|
|
1669
1670
|
}
|
|
1670
1671
|
return out;
|
|
@@ -1676,7 +1677,7 @@ function buildSupportedVersionsList(capConfig, serverPin) {
|
|
|
1676
1677
|
if (capConfig?.major_versions?.length) {
|
|
1677
1678
|
return capConfig.major_versions.filter((m) => Number.isFinite(m)).map((m) => String(m));
|
|
1678
1679
|
}
|
|
1679
|
-
const pinMajor = (0,
|
|
1680
|
+
const pinMajor = (0, import_version2.parseAdcpMajorVersion)(serverPin);
|
|
1680
1681
|
return Number.isFinite(pinMajor) ? [String(pinMajor)] : [];
|
|
1681
1682
|
}
|
|
1682
1683
|
function withImmutableServedAdcpVersion(context, servedAdcpVersion) {
|
|
@@ -1695,7 +1696,7 @@ function parseAdcpRelease(value) {
|
|
|
1695
1696
|
if (typeof value !== "string") return void 0;
|
|
1696
1697
|
let wire;
|
|
1697
1698
|
try {
|
|
1698
|
-
wire = (0,
|
|
1699
|
+
wire = (0, import_version2.toReleasePrecisionVersion)(value);
|
|
1699
1700
|
} catch {
|
|
1700
1701
|
return void 0;
|
|
1701
1702
|
}
|
|
@@ -1842,7 +1843,7 @@ let bundledCompatibleReleases;
|
|
|
1842
1843
|
function bundledReleasesForMajors(majors, configured) {
|
|
1843
1844
|
const acceptedMajors = new Set(majors);
|
|
1844
1845
|
const releases = /* @__PURE__ */ new Map();
|
|
1845
|
-
bundledCompatibleReleases ??=
|
|
1846
|
+
bundledCompatibleReleases ??= import_version2.COMPATIBLE_ADCP_VERSIONS.flatMap((version) => {
|
|
1846
1847
|
if (!(0, import_schema_loader2.hasSchemaBundle)(version)) return [];
|
|
1847
1848
|
const parsed = parseAdcpRelease(version);
|
|
1848
1849
|
return parsed ? [parsed] : [];
|
|
@@ -1993,7 +1994,7 @@ function createAdcpServer(config) {
|
|
|
1993
1994
|
responseEnhancer,
|
|
1994
1995
|
structuredContentTextFallback = "always"
|
|
1995
1996
|
} = config;
|
|
1996
|
-
if (capConfig?.major_versions?.some((major) => major < 3) || capConfig?.supported_versions?.some((version2) => (0,
|
|
1997
|
+
if (capConfig?.major_versions?.some((major) => major < 3) || capConfig?.supported_versions?.some((version2) => (0, import_version2.parseAdcpMajorVersion)(version2) < 3)) {
|
|
1997
1998
|
throw new import_errors.ConfigurationError(
|
|
1998
1999
|
"AdCP 2 reached end of life on 2026-08-01. Server capabilities must advertise AdCP 3 only.",
|
|
1999
2000
|
"capabilities"
|
|
@@ -2058,14 +2059,14 @@ function createAdcpServer(config) {
|
|
|
2058
2059
|
}
|
|
2059
2060
|
const credentialPolicyPatterns = credentialPolicy === void 0 || typeof credentialPolicy === "string" ? void 0 : credentialPolicy.patterns;
|
|
2060
2061
|
const adcpVersion = (0, import_adcp_version_config.resolveAdcpVersion)(
|
|
2061
|
-
configuredAdcpVersion ?? (config.identity33 ? "3.3" : config.proposalNegotiation ?
|
|
2062
|
+
configuredAdcpVersion ?? (config.identity33 ? "3.3" : config.proposalNegotiation ? import_version3.ADCP_VERSION : void 0)
|
|
2062
2063
|
);
|
|
2063
2064
|
const toolVersionRanges = parseToolVersionRanges(config.toolVersions);
|
|
2064
2065
|
const toolAvailableForRelease = (toolName, release) => toolIsAvailableInRelease(toolVersionRanges, toolName, release);
|
|
2065
2066
|
const movingSupportedVersion = capConfig?.supported_versions?.find(import_adcp_version_config.isMovingAdcpPrereleaseFamilyAlias);
|
|
2066
2067
|
if (movingSupportedVersion) {
|
|
2067
2068
|
throw new Error(
|
|
2068
|
-
`createAdcpServer: capabilities.supported_versions contains moving prerelease-family alias ${JSON.stringify(movingSupportedVersion)}; pin ${JSON.stringify((0,
|
|
2069
|
+
`createAdcpServer: capabilities.supported_versions contains moving prerelease-family alias ${JSON.stringify(movingSupportedVersion)}; pin ${JSON.stringify((0, import_version2.toReleasePrecisionVersion)(import_version3.ADCP_VERSION))} instead`
|
|
2069
2070
|
);
|
|
2070
2071
|
}
|
|
2071
2072
|
const configuredDefaultVersion = configuredDefaultAdcpVersion === void 0 ? void 0 : (0, import_adcp_version_config.resolveAdcpVersion)(configuredDefaultAdcpVersion, "defaultAdcpVersion");
|
|
@@ -2351,6 +2352,43 @@ function createAdcpServer(config) {
|
|
|
2351
2352
|
const selected = selectServedAdcpRelease(params, capConfig, adcpVersion, defaultAdcpVersion);
|
|
2352
2353
|
return isMcpToolResponse(selected) ? void 0 : selected;
|
|
2353
2354
|
};
|
|
2355
|
+
const downgradeTaskStatusResult = (toolName, response, servedVersion) => {
|
|
2356
|
+
if (toolName !== "get_task_status" || config.identity33) return response;
|
|
2357
|
+
if ((0, import_version.translationSteps)(adcpVersion, servedVersion).length === 0) return response;
|
|
2358
|
+
const body = response.structuredContent;
|
|
2359
|
+
if (!body || typeof body.task_type !== "string" || !body.result || typeof body.result !== "object") return response;
|
|
2360
|
+
const downgraded = (0, import_version.downgradeResponse)(body.task_type, body.result, {
|
|
2361
|
+
fromVersion: adcpVersion,
|
|
2362
|
+
toVersion: servedVersion
|
|
2363
|
+
});
|
|
2364
|
+
if (downgraded.drifts.length > 0) {
|
|
2365
|
+
reportVersionTranslation({
|
|
2366
|
+
tool: body.task_type,
|
|
2367
|
+
direction: "response",
|
|
2368
|
+
fromVersion: adcpVersion,
|
|
2369
|
+
toVersion: servedVersion,
|
|
2370
|
+
drifts: downgraded.drifts
|
|
2371
|
+
});
|
|
2372
|
+
}
|
|
2373
|
+
if (downgraded.data === body.result) return response;
|
|
2374
|
+
const mirrors = contentTextMirrorsStructuredContent(response, body);
|
|
2375
|
+
const next = cloneFormattedResponse(response);
|
|
2376
|
+
const nextBody = { ...next.structuredContent, result: downgraded.data };
|
|
2377
|
+
next.structuredContent = nextBody;
|
|
2378
|
+
syncContentJsonText(next, nextBody, mirrors);
|
|
2379
|
+
return next;
|
|
2380
|
+
};
|
|
2381
|
+
const reportVersionTranslation = (event) => {
|
|
2382
|
+
if (!config.onVersionTranslation) return;
|
|
2383
|
+
try {
|
|
2384
|
+
config.onVersionTranslation(event);
|
|
2385
|
+
} catch (err) {
|
|
2386
|
+
logger.warn("onVersionTranslation callback threw", {
|
|
2387
|
+
tool: event.tool,
|
|
2388
|
+
error: err instanceof Error ? err.message : String(err)
|
|
2389
|
+
});
|
|
2390
|
+
}
|
|
2391
|
+
};
|
|
2354
2392
|
const releaseDefinesTool = (toolName, release) => {
|
|
2355
2393
|
if (toolName === "refine_proposals") return true;
|
|
2356
2394
|
try {
|
|
@@ -2367,6 +2405,7 @@ function createAdcpServer(config) {
|
|
|
2367
2405
|
sanitizeAdcpErrorEnvelope(response);
|
|
2368
2406
|
enrichErrorTwoLayer(response, toolName, (0, import_error_arm_tools.getToolsWithErrorArm)(release.validationVersion));
|
|
2369
2407
|
if (!isErrorResponse(response)) {
|
|
2408
|
+
response = downgradeTaskStatusResult(toolName, response, release.validationVersion);
|
|
2370
2409
|
normalizeMediaBuyStatusCollision(response, toolName);
|
|
2371
2410
|
injectEnvelopeStatusIntoResponse(response, toolName);
|
|
2372
2411
|
const validationError = protocolTaskResponseValidationError(toolName, response, params);
|
|
@@ -2726,6 +2765,7 @@ function createAdcpServer(config) {
|
|
|
2726
2765
|
requestRelease = releaseSelection;
|
|
2727
2766
|
}
|
|
2728
2767
|
const requestErrorArms = (0, import_error_arm_tools.getToolsWithErrorArm)(requestRelease.validationVersion);
|
|
2768
|
+
const translatesRelease = !config.identity33 && toolName !== "get_adcp_capabilities" && (0, import_version.translationSteps)(adcpVersion, requestRelease.validationVersion).length > 0;
|
|
2729
2769
|
const ctx = withImmutableServedAdcpVersion(
|
|
2730
2770
|
{
|
|
2731
2771
|
store: stateStore,
|
|
@@ -2868,7 +2908,7 @@ function createAdcpServer(config) {
|
|
|
2868
2908
|
const reqAdcpMajorRaw = params.adcp_major_version;
|
|
2869
2909
|
const reqAdcpMajor = typeof reqAdcpMajorRaw === "number" ? reqAdcpMajorRaw : typeof reqAdcpMajorRaw === "string" ? Number.parseInt(reqAdcpMajorRaw, 10) : void 0;
|
|
2870
2910
|
if (typeof reqAdcpVersion === "string" && reqAdcpMajor !== void 0 && Number.isFinite(reqAdcpMajor)) {
|
|
2871
|
-
const stringMajor = (0,
|
|
2911
|
+
const stringMajor = (0, import_version2.parseAdcpMajorVersion)(reqAdcpVersion);
|
|
2872
2912
|
if (Number.isFinite(stringMajor) && stringMajor !== reqAdcpMajor) {
|
|
2873
2913
|
return finalize(
|
|
2874
2914
|
(0, import_errors2.adcpError)("VERSION_UNSUPPORTED", {
|
|
@@ -2878,7 +2918,7 @@ function createAdcpServer(config) {
|
|
|
2878
2918
|
);
|
|
2879
2919
|
}
|
|
2880
2920
|
}
|
|
2881
|
-
const effectiveReqMajor = reqAdcpMajor !== void 0 && Number.isFinite(reqAdcpMajor) ? reqAdcpMajor : typeof reqAdcpVersion === "string" ? (0,
|
|
2921
|
+
const effectiveReqMajor = reqAdcpMajor !== void 0 && Number.isFinite(reqAdcpMajor) ? reqAdcpMajor : typeof reqAdcpVersion === "string" ? (0, import_version2.parseAdcpMajorVersion)(reqAdcpVersion) : void 0;
|
|
2882
2922
|
if (effectiveReqMajor !== void 0 && Number.isFinite(effectiveReqMajor)) {
|
|
2883
2923
|
const supportedMajors = getAdvertisedSupportedMajors(capConfig, adcpVersion);
|
|
2884
2924
|
if (!supportedMajors.has(effectiveReqMajor)) {
|
|
@@ -3447,7 +3487,24 @@ function createAdcpServer(config) {
|
|
|
3447
3487
|
(_entry, index) => !notificationFailureRows.has(index)
|
|
3448
3488
|
)
|
|
3449
3489
|
};
|
|
3450
|
-
const
|
|
3490
|
+
const upgraded = translatesRelease ? (0, import_version.upgradeRequest)(toolName, handlerParams, {
|
|
3491
|
+
fromVersion: requestRelease.validationVersion,
|
|
3492
|
+
toVersion: adcpVersion
|
|
3493
|
+
}) : void 0;
|
|
3494
|
+
if (upgraded && upgraded.drifts.length > 0) {
|
|
3495
|
+
logger.debug(`Converted ${toolName} request up to AdCP ${adcpVersion}`, {
|
|
3496
|
+
tool: toolName,
|
|
3497
|
+
drifts: upgraded.drifts
|
|
3498
|
+
});
|
|
3499
|
+
reportVersionTranslation({
|
|
3500
|
+
tool: toolName,
|
|
3501
|
+
direction: "request",
|
|
3502
|
+
fromVersion: requestRelease.validationVersion,
|
|
3503
|
+
toVersion: adcpVersion,
|
|
3504
|
+
drifts: upgraded.drifts
|
|
3505
|
+
});
|
|
3506
|
+
}
|
|
3507
|
+
const result = notificationFailureRows.size > 0 && handlerParams.accounts.length === 0 ? { accounts: [], ...params.dry_run === true && { dry_run: true } } : await handler(upgraded ? upgraded.params : handlerParams, ctx);
|
|
3451
3508
|
mutationHandlerCompleted = true;
|
|
3452
3509
|
let formatted;
|
|
3453
3510
|
if (isFormattedResponse(result)) {
|
|
@@ -3915,6 +3972,31 @@ function createAdcpServer(config) {
|
|
|
3915
3972
|
injectEnvelopeStatusIntoResponse(formatted, toolName);
|
|
3916
3973
|
}
|
|
3917
3974
|
}
|
|
3975
|
+
if (translatesRelease && !isErrorResponse(formatted) && formatted.structuredContent) {
|
|
3976
|
+
const downgraded = (0, import_version.downgradeResponse)(toolName, formatted.structuredContent, {
|
|
3977
|
+
fromVersion: adcpVersion,
|
|
3978
|
+
toVersion: requestRelease.validationVersion
|
|
3979
|
+
});
|
|
3980
|
+
if (downgraded.data !== formatted.structuredContent) {
|
|
3981
|
+
const mirrors = contentTextMirrorsStructuredContent(formatted, formatted.structuredContent);
|
|
3982
|
+
formatted = cloneFormattedResponse(formatted);
|
|
3983
|
+
formatted.structuredContent = downgraded.data;
|
|
3984
|
+
syncContentJsonText(formatted, downgraded.data, mirrors);
|
|
3985
|
+
}
|
|
3986
|
+
if (downgraded.drifts.length > 0) {
|
|
3987
|
+
logger.info(`Converted ${toolName} response down to AdCP ${requestRelease.validationVersion}`, {
|
|
3988
|
+
tool: toolName,
|
|
3989
|
+
drifts: downgraded.drifts
|
|
3990
|
+
});
|
|
3991
|
+
reportVersionTranslation({
|
|
3992
|
+
tool: toolName,
|
|
3993
|
+
direction: "response",
|
|
3994
|
+
fromVersion: adcpVersion,
|
|
3995
|
+
toVersion: requestRelease.validationVersion,
|
|
3996
|
+
drifts: downgraded.drifts
|
|
3997
|
+
});
|
|
3998
|
+
}
|
|
3999
|
+
}
|
|
3918
4000
|
if (responseValidationMode !== "off" && !isErrorResponse(formatted)) {
|
|
3919
4001
|
const payload = formatted.structuredContent;
|
|
3920
4002
|
const outcome = validateFrameworkPayload(
|
|
@@ -4630,7 +4712,7 @@ function createAdcpServer(config) {
|
|
|
4630
4712
|
"measurement"
|
|
4631
4713
|
];
|
|
4632
4714
|
}
|
|
4633
|
-
capabilitiesData.library_version = `@adcp/client@${
|
|
4715
|
+
capabilitiesData.library_version = `@adcp/client@${import_version3.LIBRARY_VERSION}`;
|
|
4634
4716
|
async function authorizeAuxiliaryIdentityTool(toolName, params, extra) {
|
|
4635
4717
|
const failure = (0, import_web_bot_auth2.getWebBotAuthAuthorizationFailure)(extra?.authInfo?.extra);
|
|
4636
4718
|
if (failure) return (0, import_web_bot_auth2.webBotAuthToolFailure)(failure, servedAdcpVersion);
|