@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.
- package/dist/lib/adapters/version/3.0/brand-fields.d.mts +7 -1
- package/dist/lib/adapters/version/3.0/brand-fields.d.ts +7 -1
- package/dist/lib/adapters/version/3.0/brand-fields.js +139 -3
- package/dist/lib/adapters/version/3.0/brand-fields.mjs +136 -2
- package/dist/lib/adapters/version/3.0/index.js +6 -0
- package/dist/lib/adapters/version/3.0/index.mjs +7 -1
- package/dist/lib/adapters/version/3.1/bidding.js +1 -1
- package/dist/lib/adapters/version/3.1/bidding.mjs +1 -1
- package/dist/lib/adapters/version/types.d.mts +5 -0
- package/dist/lib/adapters/version/types.d.ts +5 -0
- package/dist/lib/canonical-references/index.js +2 -0
- package/dist/lib/canonical-references/index.mjs +2 -0
- package/dist/lib/client/account-changes.d.mts +3 -1
- package/dist/lib/client/account-changes.d.ts +3 -1
- package/dist/lib/client/account-changes.js +22 -2
- package/dist/lib/client/account-changes.mjs +22 -2
- package/dist/lib/conformance/oracle.js +3 -2
- package/dist/lib/conformance/oracle.mjs +3 -2
- package/dist/lib/core/AgentClient.d.mts +165 -1
- package/dist/lib/core/AgentClient.d.ts +165 -1
- package/dist/lib/core/AgentClient.js +446 -8
- package/dist/lib/core/AgentClient.mjs +446 -8
- package/dist/lib/core/ConversationTypes.d.mts +8 -0
- package/dist/lib/core/ConversationTypes.d.ts +8 -0
- package/dist/lib/core/ProtocolResponseParser.d.mts +1 -1
- package/dist/lib/core/ProtocolResponseParser.d.ts +1 -1
- package/dist/lib/core/ProtocolResponseParser.js +28 -18
- package/dist/lib/core/ProtocolResponseParser.mjs +11 -1
- package/dist/lib/core/ResponseValidator.js +1 -1
- package/dist/lib/core/ResponseValidator.mjs +1 -1
- package/dist/lib/core/SingleAgentClient.d.mts +116 -6
- package/dist/lib/core/SingleAgentClient.d.ts +116 -6
- package/dist/lib/core/SingleAgentClient.js +556 -84
- package/dist/lib/core/SingleAgentClient.mjs +545 -72
- package/dist/lib/core/TaskExecutor.d.mts +7 -0
- package/dist/lib/core/TaskExecutor.d.ts +7 -0
- package/dist/lib/core/TaskExecutor.js +23 -8
- package/dist/lib/core/TaskExecutor.mjs +23 -8
- package/dist/lib/core/task-status.d.mts +2 -0
- package/dist/lib/core/task-status.d.ts +2 -0
- package/dist/lib/core/task-status.js +11 -2
- package/dist/lib/core/task-status.mjs +9 -1
- package/dist/lib/errors/index.d.mts +22 -0
- package/dist/lib/errors/index.d.ts +22 -0
- package/dist/lib/errors/index.js +43 -0
- package/dist/lib/errors/index.mjs +42 -0
- package/dist/lib/identity-3.3/trust.d.mts +1 -4
- package/dist/lib/identity-3.3/trust.d.ts +1 -4
- package/dist/lib/identity-3.3/trust.js +34 -21
- package/dist/lib/identity-3.3/trust.mjs +34 -21
- package/dist/lib/identity-3.3/validation.js +5 -3
- package/dist/lib/identity-3.3/validation.mjs +6 -4
- package/dist/lib/index.d.mts +8 -54
- package/dist/lib/index.d.ts +8 -54
- package/dist/lib/index.js +15 -0
- package/dist/lib/index.mjs +11 -0
- package/dist/lib/media-buy/action-assessment.js +29 -3
- package/dist/lib/media-buy/action-assessment.mjs +32 -4
- package/dist/lib/media-buy/action-contracts.d.mts +3 -0
- package/dist/lib/media-buy/action-contracts.d.ts +3 -0
- package/dist/lib/media-buy/action-contracts.js +24 -1
- package/dist/lib/media-buy/action-contracts.mjs +22 -1
- package/dist/lib/media-buy/compatibility.js +6 -1
- package/dist/lib/media-buy/compatibility.mjs +6 -1
- package/dist/lib/media-buy/preflight.js +1 -1
- package/dist/lib/media-buy/preflight.mjs +3 -2
- package/dist/lib/media-buy/types.d.mts +6 -1
- package/dist/lib/media-buy/types.d.ts +6 -1
- package/dist/lib/protocols/mcp-modern.d.mts +2 -0
- package/dist/lib/protocols/mcp-modern.d.ts +2 -0
- package/dist/lib/protocols/mcp-modern.js +31 -5
- package/dist/lib/protocols/mcp-modern.mjs +31 -5
- package/dist/lib/protocols/mcp-scope.d.mts +6 -1
- package/dist/lib/protocols/mcp-scope.d.ts +6 -1
- package/dist/lib/protocols/mcp-scope.js +25 -3
- package/dist/lib/protocols/mcp-scope.mjs +24 -3
- package/dist/lib/protocols/mcp.js +12 -6
- package/dist/lib/protocols/mcp.mjs +13 -6
- package/dist/lib/reporting/inspection.js +1 -0
- package/dist/lib/reporting/inspection.mjs +1 -0
- package/dist/lib/schemas/browser.d.mts +2 -0
- package/dist/lib/schemas/browser.d.ts +2 -0
- package/dist/lib/schemas/browser.js +3 -0
- package/dist/lib/schemas/browser.mjs +2 -0
- package/dist/lib/schemas/index.d.mts +5 -2
- package/dist/lib/schemas/index.d.ts +5 -2
- package/dist/lib/schemas/index.js +5 -0
- package/dist/lib/schemas/index.mjs +4 -0
- package/dist/lib/server/account-response-identity.d.mts +17 -0
- package/dist/lib/server/account-response-identity.d.ts +17 -0
- package/dist/lib/server/account-response-identity.js +52 -0
- package/dist/lib/server/account-response-identity.mjs +28 -0
- package/dist/lib/server/account-sync-contract.js +1 -0
- package/dist/lib/server/account-sync-contract.mjs +1 -0
- package/dist/lib/server/create-adcp-server.js +32 -19
- package/dist/lib/server/create-adcp-server.mjs +36 -12
- package/dist/lib/server/decisioning/account.d.mts +13 -6
- package/dist/lib/server/decisioning/account.d.ts +13 -6
- package/dist/lib/server/decisioning/account.js +37 -15
- package/dist/lib/server/decisioning/account.mjs +37 -15
- package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -5
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -5
- package/dist/lib/server/decisioning/runtime/from-platform.js +6 -6
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +6 -6
- package/dist/lib/server/index.d.mts +1 -1
- package/dist/lib/server/index.d.ts +1 -1
- package/dist/lib/server/index.js +2 -0
- package/dist/lib/server/index.mjs +2 -0
- package/dist/lib/server/media-buy-action-resolver.d.mts +3 -0
- package/dist/lib/server/media-buy-action-resolver.d.ts +3 -0
- package/dist/lib/server/media-buy-action-resolver.js +32 -0
- package/dist/lib/server/media-buy-action-resolver.mjs +32 -0
- package/dist/lib/server/media-buy-store.d.mts +26 -12
- package/dist/lib/server/media-buy-store.d.ts +26 -12
- package/dist/lib/server/media-buy-store.js +69 -21
- package/dist/lib/server/media-buy-store.mjs +69 -21
- package/dist/lib/server/responses.js +9 -1
- package/dist/lib/server/responses.mjs +9 -1
- package/dist/lib/server/state-machine.d.mts +10 -11
- package/dist/lib/server/state-machine.d.ts +10 -11
- package/dist/lib/server/state-machine.js +20 -5
- package/dist/lib/server/state-machine.mjs +19 -5
- package/dist/lib/signing/agent-fetch.d.mts +1 -1
- package/dist/lib/signing/agent-fetch.d.ts +1 -1
- package/dist/lib/signing/agent-fetch.js +3 -3
- package/dist/lib/signing/agent-fetch.mjs +3 -3
- package/dist/lib/testing/client.d.mts +1 -0
- package/dist/lib/testing/client.d.ts +1 -0
- package/dist/lib/testing/client.js +6 -5
- package/dist/lib/testing/client.mjs +6 -5
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.js +60 -14
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +60 -14
- package/dist/lib/testing/storyboard/compliance.d.mts +2 -5
- package/dist/lib/testing/storyboard/compliance.d.ts +2 -5
- package/dist/lib/testing/storyboard/compliance.js +62 -13
- package/dist/lib/testing/storyboard/compliance.mjs +63 -14
- package/dist/lib/testing/storyboard/context.d.mts +13 -3
- package/dist/lib/testing/storyboard/context.d.ts +13 -3
- package/dist/lib/testing/storyboard/context.js +15 -10
- package/dist/lib/testing/storyboard/context.mjs +15 -10
- package/dist/lib/testing/storyboard/default-invariants.js +10 -8
- package/dist/lib/testing/storyboard/default-invariants.mjs +11 -9
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.js +11 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +10 -0
- package/dist/lib/testing/storyboard/runner.js +23 -10
- package/dist/lib/testing/storyboard/runner.mjs +23 -10
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/testing/storyboard/validations.js +4 -1
- package/dist/lib/testing/storyboard/validations.mjs +4 -1
- package/dist/lib/testing/test-controller.js +3 -0
- package/dist/lib/testing/test-controller.mjs +3 -0
- package/dist/lib/types/asset-instances.d.mts +1 -1
- package/dist/lib/types/asset-instances.d.ts +1 -1
- package/dist/lib/types/index.d.mts +5 -0
- package/dist/lib/types/index.d.ts +5 -0
- package/dist/lib/types/index.js +6 -1
- package/dist/lib/types/index.mjs +4 -1
- package/dist/lib/types/inline-enums.generated.d.mts +30 -4
- package/dist/lib/types/inline-enums.generated.d.ts +30 -4
- package/dist/lib/types/inline-enums.generated.js +41 -2
- package/dist/lib/types/inline-enums.generated.mjs +28 -2
- package/dist/lib/types/media-buy-delivery-report.d.mts +4 -0
- package/dist/lib/types/media-buy-delivery-report.d.ts +4 -0
- package/dist/lib/types/media-buy-delivery-report.js +16 -0
- package/dist/lib/types/media-buy-delivery-report.mjs +0 -0
- package/dist/lib/types/schemas.generated.d.ts +20 -69
- package/dist/lib/types/schemas.generated.js +29 -46
- package/dist/lib/types/schemas.generated.mjs +29 -46
- package/dist/lib/types/targeting-keys.generated.d.mts +4 -0
- package/dist/lib/types/targeting-keys.generated.d.ts +4 -0
- package/dist/lib/types/targeting-keys.generated.js +105 -0
- package/dist/lib/types/targeting-keys.generated.mjs +80 -0
- package/dist/lib/utils/adcp-version-config.js +5 -2
- package/dist/lib/utils/adcp-version-config.mjs +5 -2
- package/dist/lib/utils/envelope-status-compat.d.mts +18 -1
- package/dist/lib/utils/envelope-status-compat.d.ts +18 -1
- package/dist/lib/utils/envelope-status-compat.js +11 -5
- package/dist/lib/utils/envelope-status-compat.mjs +11 -5
- package/dist/lib/utils/response-unwrapper.js +18 -10
- package/dist/lib/utils/response-unwrapper.mjs +18 -10
- package/dist/lib/v2/format-schema/resolver.js +1 -1
- package/dist/lib/v2/format-schema/resolver.mjs +1 -1
- package/dist/lib/v2/projection/creative-delivery.js +123 -30
- package/dist/lib/v2/projection/creative-delivery.mjs +127 -30
- package/dist/lib/v2/projection/index.d.mts +1 -0
- package/dist/lib/v2/projection/index.d.ts +1 -0
- package/dist/lib/v2/projection/index.js +3 -0
- package/dist/lib/v2/projection/index.mjs +2 -0
- package/dist/lib/v2/projection/legacy-metadata.d.mts +19 -0
- package/dist/lib/v2/projection/legacy-metadata.d.ts +19 -0
- package/dist/lib/v2/projection/legacy-metadata.js +91 -0
- package/dist/lib/v2/projection/legacy-metadata.mjs +86 -0
- package/dist/lib/validation/compact-schema.d.mts +27 -0
- package/dist/lib/validation/compact-schema.d.ts +27 -0
- package/dist/lib/validation/compact-schema.js +276 -0
- package/dist/lib/validation/compact-schema.mjs +250 -0
- package/dist/lib/validation/media-buy-delivery-report.d.mts +8 -0
- package/dist/lib/validation/media-buy-delivery-report.d.ts +8 -0
- package/dist/lib/validation/media-buy-delivery-report.js +31 -0
- package/dist/lib/validation/media-buy-delivery-report.mjs +7 -0
- package/dist/lib/validation/schema-diagnostic-origins.d.mts +21 -0
- package/dist/lib/validation/schema-diagnostic-origins.d.ts +21 -0
- package/dist/lib/validation/schema-diagnostic-origins.js +193 -0
- package/dist/lib/validation/schema-diagnostic-origins.mjs +169 -0
- package/dist/lib/validation/schema-loader.js +86 -16
- package/dist/lib/validation/schema-loader.mjs +82 -16
- package/dist/lib/validation/schema-validator.d.mts +10 -19
- package/dist/lib/validation/schema-validator.d.ts +10 -19
- package/dist/lib/validation/schema-validator.js +136 -43
- package/dist/lib/validation/schema-validator.mjs +140 -44
- 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/dist/lib/webhooks/index.d.mts +3 -0
- package/dist/lib/webhooks/index.d.ts +3 -0
- package/dist/lib/webhooks/index.js +3 -0
- package/dist/lib/webhooks/index.mjs +2 -0
- package/dist/lib/webhooks/media-buy-delivery.d.mts +43 -0
- package/dist/lib/webhooks/media-buy-delivery.d.ts +43 -0
- package/dist/lib/webhooks/media-buy-delivery.js +119 -0
- package/dist/lib/webhooks/media-buy-delivery.mjs +94 -0
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/BUILD-AN-AGENT.md +9 -1
- package/docs/guides/DELIVERY-WEBHOOK-PARSING.md +135 -0
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +15 -0
- package/docs/guides/TYPED-CLIENT-TOOLS.md +49 -0
- package/docs/llms.txt +3 -3
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-6.6-to-6.7.md +14 -0
- package/docs/migration-account-change-feed.md +19 -0
- package/docs/releases/sdk-16.6-adoption-fixes.md +33 -0
- package/package.json +2 -2
|
@@ -34,6 +34,7 @@ var import_v2_to_v1 = require('./v2-to-v1.js');
|
|
|
34
34
|
var import_legacy_metadata = require('./legacy-metadata.js');
|
|
35
35
|
var import_jcs = require('../../utils/jcs.js');
|
|
36
36
|
var import_catalog = require('./catalog.js');
|
|
37
|
+
var import_legacy_metadata2 = require('./legacy-metadata.js');
|
|
37
38
|
function stripLegacyCreativeIdentity(value) {
|
|
38
39
|
const legacyTokens = /* @__PURE__ */ new Set();
|
|
39
40
|
const legacyUrlTokens = /* @__PURE__ */ new Set();
|
|
@@ -501,16 +502,38 @@ function creativeFormatParameterConstraints(creative) {
|
|
|
501
502
|
if (width === void 0 && height === void 0 && durationMs === void 0) return void 0;
|
|
502
503
|
return { width, height, durationMs };
|
|
503
504
|
}
|
|
504
|
-
function
|
|
505
|
+
function primaryMediaConstraints(creative) {
|
|
506
|
+
const assetType = creative.format_kind === "image" ? "image" : creative.format_kind === "video_hosted" ? "video" : creative.format_kind === "audio_hosted" ? "audio" : void 0;
|
|
507
|
+
if (!assetType) return void 0;
|
|
508
|
+
const assets = Object.values(record(creative.assets) ?? {}).flatMap(
|
|
509
|
+
(value) => (Array.isArray(value) ? value : [value]).flatMap((item) => {
|
|
510
|
+
const asset2 = record(item);
|
|
511
|
+
return asset2?.asset_type === assetType ? [asset2] : [];
|
|
512
|
+
})
|
|
513
|
+
);
|
|
514
|
+
if (assets.length !== 1) return void 0;
|
|
515
|
+
const asset = assets[0];
|
|
516
|
+
const width = assetType === "audio" ? void 0 : positiveConstraint(asset.width);
|
|
517
|
+
const height = assetType === "audio" ? void 0 : positiveConstraint(asset.height);
|
|
518
|
+
const durationMs = assetType === "image" ? void 0 : positiveConstraint(asset.duration_ms);
|
|
519
|
+
return width === void 0 && height === void 0 && durationMs === void 0 ? void 0 : { width, height, durationMs };
|
|
520
|
+
}
|
|
521
|
+
function positiveConstraint(value) {
|
|
522
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
523
|
+
}
|
|
524
|
+
function legacyRefParameterConstraints(ref, selectorParams) {
|
|
505
525
|
const params = typeof ref.width !== "number" || typeof ref.height !== "number" ? record((0, import_v1_to_v2.canonicalDeclarationFromBareId)(ref.id, { agentUrl: ref.agent_url })?.params) : void 0;
|
|
526
|
+
const selector = record(selectorParams);
|
|
527
|
+
const sizes = Array.isArray(selector?.sizes) ? selector.sizes : [];
|
|
528
|
+
const size = sizes.length === 1 ? record(sizes[0]) : void 0;
|
|
506
529
|
return {
|
|
507
|
-
width: typeof ref.width === "number" ? ref.width : typeof params?.width === "number" ? params.width :
|
|
508
|
-
height: typeof ref.height === "number" ? ref.height : typeof params?.height === "number" ? params.height :
|
|
509
|
-
durationMs: ref.duration_ms
|
|
530
|
+
width: typeof ref.width === "number" ? ref.width : typeof params?.width === "number" ? params.width : positiveConstraint(selector?.width) ?? positiveConstraint(size?.width),
|
|
531
|
+
height: typeof ref.height === "number" ? ref.height : typeof params?.height === "number" ? params.height : positiveConstraint(selector?.height) ?? positiveConstraint(size?.height),
|
|
532
|
+
durationMs: ref.duration_ms ?? positiveConstraint(selector?.duration_ms_exact) ?? positiveConstraint(selector?.duration_ms)
|
|
510
533
|
};
|
|
511
534
|
}
|
|
512
|
-
function refContradictsConstraints(ref, constraints) {
|
|
513
|
-
const refConstraints = legacyRefParameterConstraints(ref);
|
|
535
|
+
function refContradictsConstraints(ref, constraints, selectorParams) {
|
|
536
|
+
const refConstraints = legacyRefParameterConstraints(ref, selectorParams);
|
|
514
537
|
if (constraints.width !== void 0 && refConstraints.width !== void 0 && refConstraints.width !== constraints.width) {
|
|
515
538
|
return true;
|
|
516
539
|
}
|
|
@@ -522,8 +545,8 @@ function refContradictsConstraints(ref, constraints) {
|
|
|
522
545
|
}
|
|
523
546
|
return false;
|
|
524
547
|
}
|
|
525
|
-
function refPinsConstraints(ref, constraints) {
|
|
526
|
-
const refConstraints = legacyRefParameterConstraints(ref);
|
|
548
|
+
function refPinsConstraints(ref, constraints, selectorParams) {
|
|
549
|
+
const refConstraints = legacyRefParameterConstraints(ref, selectorParams);
|
|
527
550
|
if (constraints.width !== void 0 && refConstraints.width === void 0) return false;
|
|
528
551
|
if (constraints.height !== void 0 && refConstraints.height === void 0) return false;
|
|
529
552
|
if (constraints.durationMs !== void 0 && typeof refConstraints.durationMs !== "number") return false;
|
|
@@ -535,8 +558,8 @@ function legacyIdPinsDimensions(ref) {
|
|
|
535
558
|
const params = record(declaration.params) ?? {};
|
|
536
559
|
return typeof params.width === "number" || typeof params.height === "number" || typeof params.duration_ms_exact === "number" || Array.isArray(params.sizes);
|
|
537
560
|
}
|
|
538
|
-
function refConstraintKey(ref) {
|
|
539
|
-
const constraints = legacyRefParameterConstraints(ref);
|
|
561
|
+
function refConstraintKey(ref, selectorParams) {
|
|
562
|
+
const constraints = legacyRefParameterConstraints(ref, selectorParams);
|
|
540
563
|
return [
|
|
541
564
|
agentIdentity(ref.agent_url),
|
|
542
565
|
constraints.width ?? "",
|
|
@@ -546,14 +569,21 @@ function refConstraintKey(ref) {
|
|
|
546
569
|
}
|
|
547
570
|
function preferMostConstrainedLegacyCandidates(candidates, creative) {
|
|
548
571
|
let remaining = candidates;
|
|
549
|
-
const
|
|
572
|
+
const mediaKind = ["image", "video_hosted", "audio_hosted"].includes(String(creative.format_kind));
|
|
573
|
+
const constraints = creativeFormatParameterConstraints(creative) ?? (remaining.length > 1 ? primaryMediaConstraints(creative) : void 0);
|
|
550
574
|
if (constraints) {
|
|
551
|
-
remaining = remaining.filter(
|
|
552
|
-
|
|
575
|
+
remaining = remaining.filter(
|
|
576
|
+
(candidate) => !refContradictsConstraints(candidate.ref, constraints, mediaKind ? candidate.selectorParams : void 0)
|
|
577
|
+
);
|
|
578
|
+
const pinned = remaining.filter(
|
|
579
|
+
(candidate) => refPinsConstraints(candidate.ref, constraints, mediaKind ? candidate.selectorParams : void 0)
|
|
580
|
+
);
|
|
553
581
|
if (pinned.length > 0) remaining = pinned;
|
|
554
582
|
}
|
|
555
583
|
if (remaining.length <= 1) return remaining;
|
|
556
|
-
const constraintKeys = new Set(
|
|
584
|
+
const constraintKeys = new Set(
|
|
585
|
+
remaining.map((candidate) => refConstraintKey(candidate.ref, mediaKind ? candidate.selectorParams : void 0))
|
|
586
|
+
);
|
|
557
587
|
if (constraintKeys.size !== 1) return remaining;
|
|
558
588
|
const specific = remaining.filter((candidate) => legacyIdPinsDimensions(candidate.ref) === true);
|
|
559
589
|
return specific.length > 0 && specific.length < remaining.length ? specific : remaining;
|
|
@@ -592,43 +622,82 @@ function selectLegacyRef(creative, container, canonicalFormatLegacyResolver, ope
|
|
|
592
622
|
matching = preferMostConstrainedLegacyCandidates(matching, creative);
|
|
593
623
|
return matching.length === 1 ? matching[0].ref : void 0;
|
|
594
624
|
}
|
|
625
|
+
function legacyUrlTrackerSlotMatches(slot, tracker) {
|
|
626
|
+
return slot.asset_type === "url" && slot.requirements?.url_type === "tracker_pixel" && (slot.asset_id === tracker.assetId || slot.requirements.role === tracker.assetId);
|
|
627
|
+
}
|
|
595
628
|
function projectLegacyAssetKeys(assetsValue, definition) {
|
|
629
|
+
const unchanged = { assets: assetsValue, drifts: [] };
|
|
596
630
|
const assets = record(assetsValue);
|
|
597
|
-
if (!assets || !Array.isArray(definition?.assets)) return
|
|
631
|
+
if (!assets || !Array.isArray(definition?.assets)) return unchanged;
|
|
598
632
|
const slots = definition.assets.filter((slot) => record(slot) !== void 0);
|
|
599
|
-
if (slots.some((slot) => slot.item_type !== void 0 && slot.item_type !== "individual")) return
|
|
633
|
+
if (slots.some((slot) => slot.item_type !== void 0 && slot.item_type !== "individual")) return unchanged;
|
|
600
634
|
const declaredIds = new Set(slots.map((slot) => slot.asset_id));
|
|
601
635
|
const availableSlots = slots.filter(
|
|
602
|
-
(slot) =>
|
|
636
|
+
(slot) => typeof slot.asset_id === "string" && slot.asset_id.length > 0 && !Object.hasOwn(assets, slot.asset_id)
|
|
603
637
|
);
|
|
604
638
|
const targetBySource = /* @__PURE__ */ new Map();
|
|
605
639
|
const sourcesByTarget = /* @__PURE__ */ new Map();
|
|
640
|
+
const trackersBySource = /* @__PURE__ */ new Map();
|
|
606
641
|
for (const [key, value] of Object.entries(assets)) {
|
|
607
|
-
|
|
642
|
+
const candidates = (Array.isArray(value) ? value : [value]).map(import_legacy_metadata2.downgradePixelTracker);
|
|
643
|
+
const trackers = candidates.length > 0 && candidates.every((tracker) => tracker !== void 0) ? candidates : void 0;
|
|
644
|
+
const trackerSlotMatches = (slot2) => trackers !== void 0 && trackers.every((tracker) => legacyUrlTrackerSlotMatches(slot2, tracker));
|
|
645
|
+
if (declaredIds.has(key)) {
|
|
646
|
+
const slot2 = slots.find((slot3) => slot3.asset_id === key);
|
|
647
|
+
if (trackers && slot2 && trackerSlotMatches(slot2)) trackersBySource.set(key, trackers);
|
|
648
|
+
continue;
|
|
649
|
+
}
|
|
608
650
|
const asset = record(value);
|
|
609
|
-
if (!asset || typeof asset.asset_type !== "string") continue;
|
|
610
|
-
const matches = availableSlots.filter((
|
|
611
|
-
if (
|
|
651
|
+
if (!trackers && (!asset || typeof asset.asset_type !== "string")) continue;
|
|
652
|
+
const matches = availableSlots.filter((slot2) => {
|
|
653
|
+
if (trackerSlotMatches(slot2)) return true;
|
|
654
|
+
if (!asset || slot2.asset_type !== asset.asset_type) return false;
|
|
612
655
|
if (asset.asset_type === "url") {
|
|
613
|
-
return typeof asset.url_type === "string" && asset.url_type ===
|
|
656
|
+
return typeof asset.url_type === "string" && asset.url_type === slot2.requirements?.url_type;
|
|
614
657
|
}
|
|
615
658
|
if (asset.asset_type === "pixel_tracker") {
|
|
616
|
-
return typeof asset.event === "string" && asset.event ===
|
|
659
|
+
return typeof asset.event === "string" && asset.event === slot2.event && (asset.event !== "custom" || typeof asset.custom_event_name === "string" && asset.custom_event_name === slot2.custom_event_name);
|
|
617
660
|
}
|
|
618
661
|
return true;
|
|
619
662
|
});
|
|
620
663
|
if (matches.length !== 1) continue;
|
|
621
|
-
const
|
|
664
|
+
const slot = matches[0];
|
|
665
|
+
const target = slot.asset_id;
|
|
622
666
|
targetBySource.set(key, target);
|
|
667
|
+
if (trackers && trackerSlotMatches(slot)) trackersBySource.set(key, trackers);
|
|
623
668
|
const sources = sourcesByTarget.get(target) ?? [];
|
|
624
669
|
sources.push(key);
|
|
625
670
|
sourcesByTarget.set(target, sources);
|
|
626
671
|
}
|
|
627
672
|
for (const sources of sourcesByTarget.values()) {
|
|
628
|
-
if (sources.length > 1)
|
|
673
|
+
if (sources.length > 1) {
|
|
674
|
+
for (const source of sources) {
|
|
675
|
+
targetBySource.delete(source);
|
|
676
|
+
trackersBySource.delete(source);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
629
679
|
}
|
|
630
|
-
if (targetBySource.size === 0) return
|
|
631
|
-
|
|
680
|
+
if (targetBySource.size === 0 && trackersBySource.size === 0) return unchanged;
|
|
681
|
+
const drifts = [];
|
|
682
|
+
for (const [key, trackers] of trackersBySource) {
|
|
683
|
+
trackers.forEach((tracker, index) => {
|
|
684
|
+
const path = `assets.${key}${Array.isArray(assets[key]) ? `[${index}]` : ""}`;
|
|
685
|
+
const drift = (0, import_legacy_metadata2.pixelTrackerDrift)(path, tracker);
|
|
686
|
+
if (drift) drifts.push(drift);
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
return {
|
|
690
|
+
assets: Object.fromEntries(
|
|
691
|
+
Object.entries(assets).map(([key, value]) => {
|
|
692
|
+
const trackers = trackersBySource.get(key);
|
|
693
|
+
return [
|
|
694
|
+
targetBySource.get(key) ?? key,
|
|
695
|
+
trackers ? Array.isArray(value) ? trackers.map((tracker) => tracker.asset) : trackers[0].asset : value
|
|
696
|
+
];
|
|
697
|
+
})
|
|
698
|
+
),
|
|
699
|
+
drifts
|
|
700
|
+
};
|
|
632
701
|
}
|
|
633
702
|
function projectCreative(creative, formatId, legacyFormatDefinitions) {
|
|
634
703
|
const next = { ...creative };
|
|
@@ -640,7 +709,12 @@ function projectCreative(creative, formatId, legacyFormatDefinitions) {
|
|
|
640
709
|
return ref !== void 0 && sameLegacyIdentity(ref, formatId);
|
|
641
710
|
});
|
|
642
711
|
const definition = supplied?.length ? supplied.length === 1 ? supplied[0] : void 0 : (0, import_catalog.lookupV1Format)(formatId);
|
|
643
|
-
if (Object.hasOwn(creative, "assets"))
|
|
712
|
+
if (Object.hasOwn(creative, "assets")) {
|
|
713
|
+
const projected = projectLegacyAssetKeys(creative.assets, definition);
|
|
714
|
+
next.assets = projected.assets;
|
|
715
|
+
(0, import_legacy_metadata.transferLegacyCreativeMetadata)(creative, next);
|
|
716
|
+
(0, import_legacy_metadata2.rememberCreativeDeliveryDiagnostics)(next, projected.drifts);
|
|
717
|
+
}
|
|
644
718
|
return next;
|
|
645
719
|
}
|
|
646
720
|
function dedupeLegacyRefs(refs) {
|
|
@@ -878,6 +952,7 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
|
|
|
878
952
|
const inputRecord = creative;
|
|
879
953
|
const originalLegacyRef = legacyRef(inputRecord.format_id);
|
|
880
954
|
const creativeRecord = canonicalizeCreative(inputRecord, selectorContainer, operation, legacyFormatConverter);
|
|
955
|
+
(0, import_legacy_metadata.transferLegacyCreativeMetadata)(inputRecord, creativeRecord);
|
|
881
956
|
if (wireMode === "canonical") return creativeRecord;
|
|
882
957
|
if (originalLegacyRef) {
|
|
883
958
|
const selectedOriginal = selectLegacyRef(inputRecord, selectorContainer, canonicalFormatLegacyResolver, operation);
|
|
@@ -949,14 +1024,32 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
|
|
|
949
1024
|
throw new CreativeFormatProjectionError(
|
|
950
1025
|
operation,
|
|
951
1026
|
creativeId,
|
|
952
|
-
`the seller advertised ${candidates.length} legacy refs for canonical kind ${creativeRecord.format_kind}`
|
|
1027
|
+
`the seller advertised ${candidates.length} legacy refs for canonical kind ${creativeRecord.format_kind}` + (candidates.some((candidate) => legacyIdPinsDimensions(candidate.ref) === true) ? "; set format_parameters.width/height or give the asset one rendered width/height to select one" : "")
|
|
953
1028
|
);
|
|
954
1029
|
}
|
|
955
|
-
const reason = pinned ? "the creative is pinned to a format option that names none of the selected seller product legacy format references" :
|
|
1030
|
+
const reason = pinned ? "the creative is pinned to a format option that names none of the selected seller product legacy format references" : describeUnmatchedLegacyCandidates(creativeRecord, allCandidates);
|
|
956
1031
|
throw new CreativeFormatProjectionError(operation, creativeId, reason);
|
|
957
1032
|
}
|
|
958
1033
|
return creative;
|
|
959
1034
|
}
|
|
1035
|
+
function describeUnmatchedLegacyCandidates(creative, allCandidates) {
|
|
1036
|
+
const generic = "the selected seller product did not provide one unambiguous legacy format reference";
|
|
1037
|
+
const kind = String(creative.format_kind);
|
|
1038
|
+
if (allCandidates.length === 0) return generic;
|
|
1039
|
+
const sameKind = allCandidates.filter((candidate) => candidate.formatKind === kind);
|
|
1040
|
+
if (sameKind.length === 0) {
|
|
1041
|
+
const offered = [
|
|
1042
|
+
...new Set(allCandidates.flatMap((candidate) => candidate.formatKind ? [candidate.formatKind] : []))
|
|
1043
|
+
];
|
|
1044
|
+
if (offered.length === 0) return generic;
|
|
1045
|
+
return `the selected seller product offers legacy refs for canonical kind ${offered.join(", ")}, not ${kind}`;
|
|
1046
|
+
}
|
|
1047
|
+
const size = creativeFormatParameterConstraints(creative);
|
|
1048
|
+
if (size?.width !== void 0 && size.height !== void 0) {
|
|
1049
|
+
return `none of the seller's ${sameKind.length} ${kind} legacy refs matches the creative's ${size.width}x${size.height} size`;
|
|
1050
|
+
}
|
|
1051
|
+
return generic;
|
|
1052
|
+
}
|
|
960
1053
|
function projectMediaBuyCreativesForDelivery(request, wireMode = "canonical", operation = "create_media_buy", legacyFormatConverter, canonicalFormatLegacyResolver, legacyFormatDefinitions) {
|
|
961
1054
|
const requestRecord = record(request);
|
|
962
1055
|
if (!requestRecord) return request;
|
|
@@ -13,6 +13,11 @@ import {
|
|
|
13
13
|
} from "./legacy-metadata.mjs";
|
|
14
14
|
import { canonicalize as canonicalizeJson } from "../../utils/jcs.mjs";
|
|
15
15
|
import { lookupV1Format } from "./catalog.mjs";
|
|
16
|
+
import {
|
|
17
|
+
downgradePixelTracker,
|
|
18
|
+
pixelTrackerDrift,
|
|
19
|
+
rememberCreativeDeliveryDiagnostics
|
|
20
|
+
} from "./legacy-metadata.mjs";
|
|
16
21
|
function stripLegacyCreativeIdentity(value) {
|
|
17
22
|
const legacyTokens = /* @__PURE__ */ new Set();
|
|
18
23
|
const legacyUrlTokens = /* @__PURE__ */ new Set();
|
|
@@ -480,16 +485,38 @@ function creativeFormatParameterConstraints(creative) {
|
|
|
480
485
|
if (width === void 0 && height === void 0 && durationMs === void 0) return void 0;
|
|
481
486
|
return { width, height, durationMs };
|
|
482
487
|
}
|
|
483
|
-
function
|
|
488
|
+
function primaryMediaConstraints(creative) {
|
|
489
|
+
const assetType = creative.format_kind === "image" ? "image" : creative.format_kind === "video_hosted" ? "video" : creative.format_kind === "audio_hosted" ? "audio" : void 0;
|
|
490
|
+
if (!assetType) return void 0;
|
|
491
|
+
const assets = Object.values(record(creative.assets) ?? {}).flatMap(
|
|
492
|
+
(value) => (Array.isArray(value) ? value : [value]).flatMap((item) => {
|
|
493
|
+
const asset2 = record(item);
|
|
494
|
+
return asset2?.asset_type === assetType ? [asset2] : [];
|
|
495
|
+
})
|
|
496
|
+
);
|
|
497
|
+
if (assets.length !== 1) return void 0;
|
|
498
|
+
const asset = assets[0];
|
|
499
|
+
const width = assetType === "audio" ? void 0 : positiveConstraint(asset.width);
|
|
500
|
+
const height = assetType === "audio" ? void 0 : positiveConstraint(asset.height);
|
|
501
|
+
const durationMs = assetType === "image" ? void 0 : positiveConstraint(asset.duration_ms);
|
|
502
|
+
return width === void 0 && height === void 0 && durationMs === void 0 ? void 0 : { width, height, durationMs };
|
|
503
|
+
}
|
|
504
|
+
function positiveConstraint(value) {
|
|
505
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
506
|
+
}
|
|
507
|
+
function legacyRefParameterConstraints(ref, selectorParams) {
|
|
484
508
|
const params = typeof ref.width !== "number" || typeof ref.height !== "number" ? record(canonicalDeclarationFromBareId(ref.id, { agentUrl: ref.agent_url })?.params) : void 0;
|
|
509
|
+
const selector = record(selectorParams);
|
|
510
|
+
const sizes = Array.isArray(selector?.sizes) ? selector.sizes : [];
|
|
511
|
+
const size = sizes.length === 1 ? record(sizes[0]) : void 0;
|
|
485
512
|
return {
|
|
486
|
-
width: typeof ref.width === "number" ? ref.width : typeof params?.width === "number" ? params.width :
|
|
487
|
-
height: typeof ref.height === "number" ? ref.height : typeof params?.height === "number" ? params.height :
|
|
488
|
-
durationMs: ref.duration_ms
|
|
513
|
+
width: typeof ref.width === "number" ? ref.width : typeof params?.width === "number" ? params.width : positiveConstraint(selector?.width) ?? positiveConstraint(size?.width),
|
|
514
|
+
height: typeof ref.height === "number" ? ref.height : typeof params?.height === "number" ? params.height : positiveConstraint(selector?.height) ?? positiveConstraint(size?.height),
|
|
515
|
+
durationMs: ref.duration_ms ?? positiveConstraint(selector?.duration_ms_exact) ?? positiveConstraint(selector?.duration_ms)
|
|
489
516
|
};
|
|
490
517
|
}
|
|
491
|
-
function refContradictsConstraints(ref, constraints) {
|
|
492
|
-
const refConstraints = legacyRefParameterConstraints(ref);
|
|
518
|
+
function refContradictsConstraints(ref, constraints, selectorParams) {
|
|
519
|
+
const refConstraints = legacyRefParameterConstraints(ref, selectorParams);
|
|
493
520
|
if (constraints.width !== void 0 && refConstraints.width !== void 0 && refConstraints.width !== constraints.width) {
|
|
494
521
|
return true;
|
|
495
522
|
}
|
|
@@ -501,8 +528,8 @@ function refContradictsConstraints(ref, constraints) {
|
|
|
501
528
|
}
|
|
502
529
|
return false;
|
|
503
530
|
}
|
|
504
|
-
function refPinsConstraints(ref, constraints) {
|
|
505
|
-
const refConstraints = legacyRefParameterConstraints(ref);
|
|
531
|
+
function refPinsConstraints(ref, constraints, selectorParams) {
|
|
532
|
+
const refConstraints = legacyRefParameterConstraints(ref, selectorParams);
|
|
506
533
|
if (constraints.width !== void 0 && refConstraints.width === void 0) return false;
|
|
507
534
|
if (constraints.height !== void 0 && refConstraints.height === void 0) return false;
|
|
508
535
|
if (constraints.durationMs !== void 0 && typeof refConstraints.durationMs !== "number") return false;
|
|
@@ -514,8 +541,8 @@ function legacyIdPinsDimensions(ref) {
|
|
|
514
541
|
const params = record(declaration.params) ?? {};
|
|
515
542
|
return typeof params.width === "number" || typeof params.height === "number" || typeof params.duration_ms_exact === "number" || Array.isArray(params.sizes);
|
|
516
543
|
}
|
|
517
|
-
function refConstraintKey(ref) {
|
|
518
|
-
const constraints = legacyRefParameterConstraints(ref);
|
|
544
|
+
function refConstraintKey(ref, selectorParams) {
|
|
545
|
+
const constraints = legacyRefParameterConstraints(ref, selectorParams);
|
|
519
546
|
return [
|
|
520
547
|
agentIdentity(ref.agent_url),
|
|
521
548
|
constraints.width ?? "",
|
|
@@ -525,14 +552,21 @@ function refConstraintKey(ref) {
|
|
|
525
552
|
}
|
|
526
553
|
function preferMostConstrainedLegacyCandidates(candidates, creative) {
|
|
527
554
|
let remaining = candidates;
|
|
528
|
-
const
|
|
555
|
+
const mediaKind = ["image", "video_hosted", "audio_hosted"].includes(String(creative.format_kind));
|
|
556
|
+
const constraints = creativeFormatParameterConstraints(creative) ?? (remaining.length > 1 ? primaryMediaConstraints(creative) : void 0);
|
|
529
557
|
if (constraints) {
|
|
530
|
-
remaining = remaining.filter(
|
|
531
|
-
|
|
558
|
+
remaining = remaining.filter(
|
|
559
|
+
(candidate) => !refContradictsConstraints(candidate.ref, constraints, mediaKind ? candidate.selectorParams : void 0)
|
|
560
|
+
);
|
|
561
|
+
const pinned = remaining.filter(
|
|
562
|
+
(candidate) => refPinsConstraints(candidate.ref, constraints, mediaKind ? candidate.selectorParams : void 0)
|
|
563
|
+
);
|
|
532
564
|
if (pinned.length > 0) remaining = pinned;
|
|
533
565
|
}
|
|
534
566
|
if (remaining.length <= 1) return remaining;
|
|
535
|
-
const constraintKeys = new Set(
|
|
567
|
+
const constraintKeys = new Set(
|
|
568
|
+
remaining.map((candidate) => refConstraintKey(candidate.ref, mediaKind ? candidate.selectorParams : void 0))
|
|
569
|
+
);
|
|
536
570
|
if (constraintKeys.size !== 1) return remaining;
|
|
537
571
|
const specific = remaining.filter((candidate) => legacyIdPinsDimensions(candidate.ref) === true);
|
|
538
572
|
return specific.length > 0 && specific.length < remaining.length ? specific : remaining;
|
|
@@ -571,43 +605,82 @@ function selectLegacyRef(creative, container, canonicalFormatLegacyResolver, ope
|
|
|
571
605
|
matching = preferMostConstrainedLegacyCandidates(matching, creative);
|
|
572
606
|
return matching.length === 1 ? matching[0].ref : void 0;
|
|
573
607
|
}
|
|
608
|
+
function legacyUrlTrackerSlotMatches(slot, tracker) {
|
|
609
|
+
return slot.asset_type === "url" && slot.requirements?.url_type === "tracker_pixel" && (slot.asset_id === tracker.assetId || slot.requirements.role === tracker.assetId);
|
|
610
|
+
}
|
|
574
611
|
function projectLegacyAssetKeys(assetsValue, definition) {
|
|
612
|
+
const unchanged = { assets: assetsValue, drifts: [] };
|
|
575
613
|
const assets = record(assetsValue);
|
|
576
|
-
if (!assets || !Array.isArray(definition?.assets)) return
|
|
614
|
+
if (!assets || !Array.isArray(definition?.assets)) return unchanged;
|
|
577
615
|
const slots = definition.assets.filter((slot) => record(slot) !== void 0);
|
|
578
|
-
if (slots.some((slot) => slot.item_type !== void 0 && slot.item_type !== "individual")) return
|
|
616
|
+
if (slots.some((slot) => slot.item_type !== void 0 && slot.item_type !== "individual")) return unchanged;
|
|
579
617
|
const declaredIds = new Set(slots.map((slot) => slot.asset_id));
|
|
580
618
|
const availableSlots = slots.filter(
|
|
581
|
-
(slot) =>
|
|
619
|
+
(slot) => typeof slot.asset_id === "string" && slot.asset_id.length > 0 && !Object.hasOwn(assets, slot.asset_id)
|
|
582
620
|
);
|
|
583
621
|
const targetBySource = /* @__PURE__ */ new Map();
|
|
584
622
|
const sourcesByTarget = /* @__PURE__ */ new Map();
|
|
623
|
+
const trackersBySource = /* @__PURE__ */ new Map();
|
|
585
624
|
for (const [key, value] of Object.entries(assets)) {
|
|
586
|
-
|
|
625
|
+
const candidates = (Array.isArray(value) ? value : [value]).map(downgradePixelTracker);
|
|
626
|
+
const trackers = candidates.length > 0 && candidates.every((tracker) => tracker !== void 0) ? candidates : void 0;
|
|
627
|
+
const trackerSlotMatches = (slot2) => trackers !== void 0 && trackers.every((tracker) => legacyUrlTrackerSlotMatches(slot2, tracker));
|
|
628
|
+
if (declaredIds.has(key)) {
|
|
629
|
+
const slot2 = slots.find((slot3) => slot3.asset_id === key);
|
|
630
|
+
if (trackers && slot2 && trackerSlotMatches(slot2)) trackersBySource.set(key, trackers);
|
|
631
|
+
continue;
|
|
632
|
+
}
|
|
587
633
|
const asset = record(value);
|
|
588
|
-
if (!asset || typeof asset.asset_type !== "string") continue;
|
|
589
|
-
const matches = availableSlots.filter((
|
|
590
|
-
if (
|
|
634
|
+
if (!trackers && (!asset || typeof asset.asset_type !== "string")) continue;
|
|
635
|
+
const matches = availableSlots.filter((slot2) => {
|
|
636
|
+
if (trackerSlotMatches(slot2)) return true;
|
|
637
|
+
if (!asset || slot2.asset_type !== asset.asset_type) return false;
|
|
591
638
|
if (asset.asset_type === "url") {
|
|
592
|
-
return typeof asset.url_type === "string" && asset.url_type ===
|
|
639
|
+
return typeof asset.url_type === "string" && asset.url_type === slot2.requirements?.url_type;
|
|
593
640
|
}
|
|
594
641
|
if (asset.asset_type === "pixel_tracker") {
|
|
595
|
-
return typeof asset.event === "string" && asset.event ===
|
|
642
|
+
return typeof asset.event === "string" && asset.event === slot2.event && (asset.event !== "custom" || typeof asset.custom_event_name === "string" && asset.custom_event_name === slot2.custom_event_name);
|
|
596
643
|
}
|
|
597
644
|
return true;
|
|
598
645
|
});
|
|
599
646
|
if (matches.length !== 1) continue;
|
|
600
|
-
const
|
|
647
|
+
const slot = matches[0];
|
|
648
|
+
const target = slot.asset_id;
|
|
601
649
|
targetBySource.set(key, target);
|
|
650
|
+
if (trackers && trackerSlotMatches(slot)) trackersBySource.set(key, trackers);
|
|
602
651
|
const sources = sourcesByTarget.get(target) ?? [];
|
|
603
652
|
sources.push(key);
|
|
604
653
|
sourcesByTarget.set(target, sources);
|
|
605
654
|
}
|
|
606
655
|
for (const sources of sourcesByTarget.values()) {
|
|
607
|
-
if (sources.length > 1)
|
|
656
|
+
if (sources.length > 1) {
|
|
657
|
+
for (const source of sources) {
|
|
658
|
+
targetBySource.delete(source);
|
|
659
|
+
trackersBySource.delete(source);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
if (targetBySource.size === 0 && trackersBySource.size === 0) return unchanged;
|
|
664
|
+
const drifts = [];
|
|
665
|
+
for (const [key, trackers] of trackersBySource) {
|
|
666
|
+
trackers.forEach((tracker, index) => {
|
|
667
|
+
const path = `assets.${key}${Array.isArray(assets[key]) ? `[${index}]` : ""}`;
|
|
668
|
+
const drift = pixelTrackerDrift(path, tracker);
|
|
669
|
+
if (drift) drifts.push(drift);
|
|
670
|
+
});
|
|
608
671
|
}
|
|
609
|
-
|
|
610
|
-
|
|
672
|
+
return {
|
|
673
|
+
assets: Object.fromEntries(
|
|
674
|
+
Object.entries(assets).map(([key, value]) => {
|
|
675
|
+
const trackers = trackersBySource.get(key);
|
|
676
|
+
return [
|
|
677
|
+
targetBySource.get(key) ?? key,
|
|
678
|
+
trackers ? Array.isArray(value) ? trackers.map((tracker) => tracker.asset) : trackers[0].asset : value
|
|
679
|
+
];
|
|
680
|
+
})
|
|
681
|
+
),
|
|
682
|
+
drifts
|
|
683
|
+
};
|
|
611
684
|
}
|
|
612
685
|
function projectCreative(creative, formatId, legacyFormatDefinitions) {
|
|
613
686
|
const next = { ...creative };
|
|
@@ -619,7 +692,12 @@ function projectCreative(creative, formatId, legacyFormatDefinitions) {
|
|
|
619
692
|
return ref !== void 0 && sameLegacyIdentity(ref, formatId);
|
|
620
693
|
});
|
|
621
694
|
const definition = supplied?.length ? supplied.length === 1 ? supplied[0] : void 0 : lookupV1Format(formatId);
|
|
622
|
-
if (Object.hasOwn(creative, "assets"))
|
|
695
|
+
if (Object.hasOwn(creative, "assets")) {
|
|
696
|
+
const projected = projectLegacyAssetKeys(creative.assets, definition);
|
|
697
|
+
next.assets = projected.assets;
|
|
698
|
+
transferLegacyCreativeMetadata(creative, next);
|
|
699
|
+
rememberCreativeDeliveryDiagnostics(next, projected.drifts);
|
|
700
|
+
}
|
|
623
701
|
return next;
|
|
624
702
|
}
|
|
625
703
|
function dedupeLegacyRefs(refs) {
|
|
@@ -857,6 +935,7 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
|
|
|
857
935
|
const inputRecord = creative;
|
|
858
936
|
const originalLegacyRef = legacyRef(inputRecord.format_id);
|
|
859
937
|
const creativeRecord = canonicalizeCreative(inputRecord, selectorContainer, operation, legacyFormatConverter);
|
|
938
|
+
transferLegacyCreativeMetadata(inputRecord, creativeRecord);
|
|
860
939
|
if (wireMode === "canonical") return creativeRecord;
|
|
861
940
|
if (originalLegacyRef) {
|
|
862
941
|
const selectedOriginal = selectLegacyRef(inputRecord, selectorContainer, canonicalFormatLegacyResolver, operation);
|
|
@@ -928,14 +1007,32 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
|
|
|
928
1007
|
throw new CreativeFormatProjectionError(
|
|
929
1008
|
operation,
|
|
930
1009
|
creativeId,
|
|
931
|
-
`the seller advertised ${candidates.length} legacy refs for canonical kind ${creativeRecord.format_kind}`
|
|
1010
|
+
`the seller advertised ${candidates.length} legacy refs for canonical kind ${creativeRecord.format_kind}` + (candidates.some((candidate) => legacyIdPinsDimensions(candidate.ref) === true) ? "; set format_parameters.width/height or give the asset one rendered width/height to select one" : "")
|
|
932
1011
|
);
|
|
933
1012
|
}
|
|
934
|
-
const reason = pinned ? "the creative is pinned to a format option that names none of the selected seller product legacy format references" :
|
|
1013
|
+
const reason = pinned ? "the creative is pinned to a format option that names none of the selected seller product legacy format references" : describeUnmatchedLegacyCandidates(creativeRecord, allCandidates);
|
|
935
1014
|
throw new CreativeFormatProjectionError(operation, creativeId, reason);
|
|
936
1015
|
}
|
|
937
1016
|
return creative;
|
|
938
1017
|
}
|
|
1018
|
+
function describeUnmatchedLegacyCandidates(creative, allCandidates) {
|
|
1019
|
+
const generic = "the selected seller product did not provide one unambiguous legacy format reference";
|
|
1020
|
+
const kind = String(creative.format_kind);
|
|
1021
|
+
if (allCandidates.length === 0) return generic;
|
|
1022
|
+
const sameKind = allCandidates.filter((candidate) => candidate.formatKind === kind);
|
|
1023
|
+
if (sameKind.length === 0) {
|
|
1024
|
+
const offered = [
|
|
1025
|
+
...new Set(allCandidates.flatMap((candidate) => candidate.formatKind ? [candidate.formatKind] : []))
|
|
1026
|
+
];
|
|
1027
|
+
if (offered.length === 0) return generic;
|
|
1028
|
+
return `the selected seller product offers legacy refs for canonical kind ${offered.join(", ")}, not ${kind}`;
|
|
1029
|
+
}
|
|
1030
|
+
const size = creativeFormatParameterConstraints(creative);
|
|
1031
|
+
if (size?.width !== void 0 && size.height !== void 0) {
|
|
1032
|
+
return `none of the seller's ${sameKind.length} ${kind} legacy refs matches the creative's ${size.width}x${size.height} size`;
|
|
1033
|
+
}
|
|
1034
|
+
return generic;
|
|
1035
|
+
}
|
|
939
1036
|
function projectMediaBuyCreativesForDelivery(request, wireMode = "canonical", operation = "create_media_buy", legacyFormatConverter, canonicalFormatLegacyResolver, legacyFormatDefinitions) {
|
|
940
1037
|
const requestRecord = record(request);
|
|
941
1038
|
if (!requestRecord) return request;
|
|
@@ -47,6 +47,7 @@ export { canonicalFormatLegacyResolverFromRoutes, carryFormatOptionOrigins, lega
|
|
|
47
47
|
export { augmentProductWithFormatOptions, withFormatOptions, toCanonicalFormatOptionsWithRoutes, toAdditiveCanonicalProduct, withAdditiveCanonicalFormatOptions, toCanonicalOnlyProduct, toCanonicalOnlyResponse, type V2AugmentedProduct, type AdditiveCanonicalProduct, type CanonicalOnlyProduct, } from './augment-response.mjs';
|
|
48
48
|
export { CanonicalFormat, audioDaastFormatDeclaration, audioHostedFormatDeclaration, audioVastFormatDeclaration, agentPlacementFormatDeclaration, canonicalFormatDeclaration, customFormatDeclaration, displayTagFormatDeclaration, legacyFormatRef, legacyFormatRefs, html5FormatDeclaration, imageCarouselFormatDeclaration, imageFormatDeclaration, nativeInFeedFormatDeclaration, productCard, productCardDetailed, responsiveCreativeFormatDeclaration, sellerRenderedStatefulDisplayFormatDeclaration, sponsoredPlacementFormatDeclaration, coordinatedPlacementsFormatDeclaration, videoHostedFormatDeclaration, videoVastFormatDeclaration, type CanonicalFormatDeclaration, type CanonicalFormatDeclarationFields, type CanonicalFormatKind, type CanonicalFormatParams, type FormatReferenceInput, type ProductCardDetailedFields, type ProductCardFields, } from './builders.mjs';
|
|
49
49
|
export { packageRefsForFormatOptions, packageRefsForCapabilities, legacyFormatIdsFromOptions, tryLegacyFormatIdsFromOptions, legacyFormatIdsForFormatOption, legacyFormatIdsForCapability, lintPackageFormatSelectorDimensions, FormatOptionRefsLookupError, CapabilityIdsLookupError, type PackageFormatRefs, type PackageCapabilityRefs, type FormatOptionRef, type FormatOptionSelector, type FormatOptionRefsLookupErrorCode, type CapabilityIdsLookupErrorCode, type PackageFormatSelectorInput, type PackageFormatSelectorDimensionOptions, type FixedSizeDimensions, type PackageFormatSelectorDimensionDiagnosticCode, type PackageFormatSelectorDimensionDiagnostic, } from './write-side.mjs';
|
|
50
|
+
export { getCreativeDeliveryDiagnostics } from './legacy-metadata.mjs';
|
|
50
51
|
export type { V1FormatId, V2ProductFormatDeclaration, V2ProductInput, V2Product, V1ProductInput, V1Product, ProjectionProductInput, ProjectionDiagnostic, } from './types.mjs';
|
|
51
52
|
export { isProjectionProductInput } from './types.mjs';
|
|
52
53
|
export { legacyFormatConverterFromCatalogSnapshots, canonicalFormatLegacyResolverFromCatalogSnapshots, projectionAdaptersFromCatalogSnapshots, type ProjectionCatalogAdapters, type ProjectionCatalogSnapshot, type ProjectionCatalogSource, } from './catalog-snapshot.mjs';
|
|
@@ -47,6 +47,7 @@ export { canonicalFormatLegacyResolverFromRoutes, carryFormatOptionOrigins, lega
|
|
|
47
47
|
export { augmentProductWithFormatOptions, withFormatOptions, toCanonicalFormatOptionsWithRoutes, toAdditiveCanonicalProduct, withAdditiveCanonicalFormatOptions, toCanonicalOnlyProduct, toCanonicalOnlyResponse, type V2AugmentedProduct, type AdditiveCanonicalProduct, type CanonicalOnlyProduct, } from './augment-response';
|
|
48
48
|
export { CanonicalFormat, audioDaastFormatDeclaration, audioHostedFormatDeclaration, audioVastFormatDeclaration, agentPlacementFormatDeclaration, canonicalFormatDeclaration, customFormatDeclaration, displayTagFormatDeclaration, legacyFormatRef, legacyFormatRefs, html5FormatDeclaration, imageCarouselFormatDeclaration, imageFormatDeclaration, nativeInFeedFormatDeclaration, productCard, productCardDetailed, responsiveCreativeFormatDeclaration, sellerRenderedStatefulDisplayFormatDeclaration, sponsoredPlacementFormatDeclaration, coordinatedPlacementsFormatDeclaration, videoHostedFormatDeclaration, videoVastFormatDeclaration, type CanonicalFormatDeclaration, type CanonicalFormatDeclarationFields, type CanonicalFormatKind, type CanonicalFormatParams, type FormatReferenceInput, type ProductCardDetailedFields, type ProductCardFields, } from './builders';
|
|
49
49
|
export { packageRefsForFormatOptions, packageRefsForCapabilities, legacyFormatIdsFromOptions, tryLegacyFormatIdsFromOptions, legacyFormatIdsForFormatOption, legacyFormatIdsForCapability, lintPackageFormatSelectorDimensions, FormatOptionRefsLookupError, CapabilityIdsLookupError, type PackageFormatRefs, type PackageCapabilityRefs, type FormatOptionRef, type FormatOptionSelector, type FormatOptionRefsLookupErrorCode, type CapabilityIdsLookupErrorCode, type PackageFormatSelectorInput, type PackageFormatSelectorDimensionOptions, type FixedSizeDimensions, type PackageFormatSelectorDimensionDiagnosticCode, type PackageFormatSelectorDimensionDiagnostic, } from './write-side';
|
|
50
|
+
export { getCreativeDeliveryDiagnostics } from './legacy-metadata';
|
|
50
51
|
export type { V1FormatId, V2ProductFormatDeclaration, V2ProductInput, V2Product, V1ProductInput, V1Product, ProjectionProductInput, ProjectionDiagnostic, } from './types';
|
|
51
52
|
export { isProjectionProductInput } from './types';
|
|
52
53
|
export { legacyFormatConverterFromCatalogSnapshots, canonicalFormatLegacyResolverFromCatalogSnapshots, projectionAdaptersFromCatalogSnapshots, type ProjectionCatalogAdapters, type ProjectionCatalogSnapshot, type ProjectionCatalogSource, } from './catalog-snapshot';
|
|
@@ -38,6 +38,7 @@ __export(projection_exports, {
|
|
|
38
38
|
customFormatDeclaration: () => import_builders.customFormatDeclaration,
|
|
39
39
|
displayTagFormatDeclaration: () => import_builders.displayTagFormatDeclaration,
|
|
40
40
|
findCatalogEntryByCanonicalAndSize: () => import_catalog.findCatalogEntryByCanonicalAndSize,
|
|
41
|
+
getCreativeDeliveryDiagnostics: () => import_legacy_metadata.getCreativeDeliveryDiagnostics,
|
|
41
42
|
html5FormatDeclaration: () => import_builders.html5FormatDeclaration,
|
|
42
43
|
imageCarouselFormatDeclaration: () => import_builders.imageCarouselFormatDeclaration,
|
|
43
44
|
imageFormatDeclaration: () => import_builders.imageFormatDeclaration,
|
|
@@ -89,6 +90,7 @@ var import_legacy_routes = require('./legacy-routes.js');
|
|
|
89
90
|
var import_augment_response = require('./augment-response.js');
|
|
90
91
|
var import_builders = require('./builders.js');
|
|
91
92
|
var import_write_side = require('./write-side.js');
|
|
93
|
+
var import_legacy_metadata = require('./legacy-metadata.js');
|
|
92
94
|
var import_types = require('./types.js');
|
|
93
95
|
var import_catalog_snapshot = require('./catalog-snapshot.js');
|
|
94
96
|
var import_catalog = require('./catalog.js');
|
|
@@ -117,6 +119,7 @@ var import_creative_delivery = require('./creative-delivery.js');
|
|
|
117
119
|
customFormatDeclaration,
|
|
118
120
|
displayTagFormatDeclaration,
|
|
119
121
|
findCatalogEntryByCanonicalAndSize,
|
|
122
|
+
getCreativeDeliveryDiagnostics,
|
|
120
123
|
html5FormatDeclaration,
|
|
121
124
|
imageCarouselFormatDeclaration,
|
|
122
125
|
imageFormatDeclaration,
|
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
FormatOptionRefsLookupError,
|
|
50
50
|
CapabilityIdsLookupError
|
|
51
51
|
} from "./write-side.mjs";
|
|
52
|
+
import { getCreativeDeliveryDiagnostics } from "./legacy-metadata.mjs";
|
|
52
53
|
import { isProjectionProductInput } from "./types.mjs";
|
|
53
54
|
import {
|
|
54
55
|
legacyFormatConverterFromCatalogSnapshots,
|
|
@@ -94,6 +95,7 @@ export {
|
|
|
94
95
|
customFormatDeclaration,
|
|
95
96
|
displayTagFormatDeclaration,
|
|
96
97
|
findCatalogEntryByCanonicalAndSize,
|
|
98
|
+
getCreativeDeliveryDiagnostics,
|
|
97
99
|
html5FormatDeclaration,
|
|
98
100
|
imageCarouselFormatDeclaration,
|
|
99
101
|
imageFormatDeclaration,
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import type { ProductFormatDeclaration } from '../../types/tools.generated.mjs';
|
|
2
2
|
import type { V1FormatId, V2ProductFormatDeclaration } from './types.mjs';
|
|
3
|
+
import type { VersionDrift } from '../../adapters/version/types.mjs';
|
|
4
|
+
type Json = Record<string, unknown>;
|
|
5
|
+
export interface LegacyPixelTracker {
|
|
6
|
+
asset: Json;
|
|
7
|
+
assetId: string;
|
|
8
|
+
lostFields: string[];
|
|
9
|
+
}
|
|
10
|
+
/** Apply the AdCP 3.1 pixel-tracker schema's normative 3.0 downgrade table. */
|
|
11
|
+
export declare function downgradePixelTracker(value: unknown): LegacyPixelTracker | undefined;
|
|
12
|
+
export declare function pixelTrackerDrift(path: string, tracker: LegacyPixelTracker): VersionDrift | undefined;
|
|
13
|
+
/** Keep delivery advisories out of creative JSON sent to the seller. */
|
|
14
|
+
export declare function rememberCreativeDeliveryDiagnostics(value: object, entries: readonly VersionDrift[]): void;
|
|
15
|
+
export declare function transferCreativeDeliveryDiagnostics(source: object, target: object): void;
|
|
16
|
+
/**
|
|
17
|
+
* Read advisories from a projected creative or a sync/create/update request.
|
|
18
|
+
* Pure projection callers can surface these alongside the returned wire object.
|
|
19
|
+
* SingleAgentClient includes them in the task's debug logs automatically.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getCreativeDeliveryDiagnostics(value: unknown): VersionDrift[];
|
|
3
22
|
/**
|
|
4
23
|
* SDK-private projection metadata held out-of-band. WeakMaps keep seller
|
|
5
24
|
* origin evidence and legacy routing identifiers absent from canonical objects
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import type { ProductFormatDeclaration } from '../../types/tools.generated';
|
|
2
2
|
import type { V1FormatId, V2ProductFormatDeclaration } from './types';
|
|
3
|
+
import type { VersionDrift } from '../../adapters/version/types';
|
|
4
|
+
type Json = Record<string, unknown>;
|
|
5
|
+
export interface LegacyPixelTracker {
|
|
6
|
+
asset: Json;
|
|
7
|
+
assetId: string;
|
|
8
|
+
lostFields: string[];
|
|
9
|
+
}
|
|
10
|
+
/** Apply the AdCP 3.1 pixel-tracker schema's normative 3.0 downgrade table. */
|
|
11
|
+
export declare function downgradePixelTracker(value: unknown): LegacyPixelTracker | undefined;
|
|
12
|
+
export declare function pixelTrackerDrift(path: string, tracker: LegacyPixelTracker): VersionDrift | undefined;
|
|
13
|
+
/** Keep delivery advisories out of creative JSON sent to the seller. */
|
|
14
|
+
export declare function rememberCreativeDeliveryDiagnostics(value: object, entries: readonly VersionDrift[]): void;
|
|
15
|
+
export declare function transferCreativeDeliveryDiagnostics(source: object, target: object): void;
|
|
16
|
+
/**
|
|
17
|
+
* Read advisories from a projected creative or a sync/create/update request.
|
|
18
|
+
* Pure projection callers can surface these alongside the returned wire object.
|
|
19
|
+
* SingleAgentClient includes them in the task's debug logs automatically.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getCreativeDeliveryDiagnostics(value: unknown): VersionDrift[];
|
|
3
22
|
/**
|
|
4
23
|
* SDK-private projection metadata held out-of-band. WeakMaps keep seller
|
|
5
24
|
* origin evidence and legacy routing identifiers absent from canonical objects
|