@adcp/sdk 17.0.0-beta.0 → 17.0.0-beta.2
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/keyed-account-store.js +1 -1
- package/dist/lib/adapters/keyed-account-store.mjs +1 -1
- 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 +122 -7
- package/dist/lib/core/SingleAgentClient.d.ts +122 -7
- package/dist/lib/core/SingleAgentClient.js +601 -96
- package/dist/lib/core/SingleAgentClient.mjs +590 -84
- 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 +7 -53
- package/dist/lib/index.d.ts +7 -53
- package/dist/lib/index.js +13 -0
- package/dist/lib/index.mjs +9 -0
- package/dist/lib/media-buy/compatibility.js +6 -1
- package/dist/lib/media-buy/compatibility.mjs +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/reporting/ledger/coverage.d.mts +5 -0
- package/dist/lib/reporting/ledger/coverage.d.ts +5 -0
- package/dist/lib/reporting/ledger/coverage.js +37 -3
- package/dist/lib/reporting/ledger/coverage.mjs +36 -3
- package/dist/lib/reporting/ledger/handler.js +7 -4
- package/dist/lib/reporting/ledger/handler.mjs +7 -4
- package/dist/lib/reporting/ledger/producer.js +215 -69
- package/dist/lib/reporting/ledger/producer.mjs +217 -70
- package/dist/lib/reporting/ledger/schedule.d.mts +2 -2
- package/dist/lib/reporting/ledger/schedule.d.ts +2 -2
- package/dist/lib/reporting/ledger/schedule.js +8 -5
- package/dist/lib/reporting/ledger/schedule.mjs +8 -5
- package/dist/lib/reporting/ledger/status-ingest.d.mts +1 -1
- package/dist/lib/reporting/ledger/status-ingest.d.ts +1 -1
- package/dist/lib/reporting/ledger/status-ingest.js +4 -3
- package/dist/lib/reporting/ledger/status-ingest.mjs +4 -3
- package/dist/lib/reporting/ledger/types.d.mts +36 -1
- package/dist/lib/reporting/ledger/types.d.ts +36 -1
- package/dist/lib/reporting/service/index.d.mts +14 -1
- package/dist/lib/reporting/service/index.d.ts +14 -1
- package/dist/lib/reporting/service/index.js +24 -12
- package/dist/lib/reporting/service/index.mjs +24 -12
- 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 -3
- package/dist/lib/schemas/index.d.ts +5 -3
- 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 +2 -2
- package/dist/lib/server/account-sync-contract.mjs +2 -2
- package/dist/lib/server/create-adcp-server.js +33 -20
- package/dist/lib/server/create-adcp-server.mjs +36 -12
- package/dist/lib/server/decisioning/account.d.mts +36 -10
- package/dist/lib/server/decisioning/account.d.ts +36 -10
- package/dist/lib/server/decisioning/account.js +33 -14
- package/dist/lib/server/decisioning/account.mjs +33 -14
- 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 +4 -4
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +4 -4
- 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/notification-subscriptions/runtime.d.mts +1 -1
- package/dist/lib/server/notification-subscriptions/runtime.d.ts +1 -1
- package/dist/lib/server/notification-subscriptions/runtime.js +4 -0
- package/dist/lib/server/notification-subscriptions/runtime.mjs +4 -0
- package/dist/lib/server/responses.js +9 -1
- package/dist/lib/server/responses.mjs +9 -1
- 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/agent-routing.d.mts +5 -2
- package/dist/lib/testing/storyboard/agent-routing.d.ts +5 -2
- package/dist/lib/testing/storyboard/agent-routing.js +11 -4
- package/dist/lib/testing/storyboard/agent-routing.mjs +11 -4
- 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/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 +141 -13
- package/dist/lib/testing/storyboard/runner.mjs +141 -13
- 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/accept-proposal.d.ts +20 -28
- package/dist/lib/types/asset-instances.d.mts +1 -1
- package/dist/lib/types/asset-instances.d.ts +1 -1
- package/dist/lib/types/buy-products.d.ts +20 -28
- package/dist/lib/types/check-governance.d.ts +20 -28
- package/dist/lib/types/comply-test-controller.d.ts +20 -28
- package/dist/lib/types/control-media-buy.d.ts +20 -28
- package/dist/lib/types/core.generated.d.mts +273 -184
- package/dist/lib/types/core.generated.d.ts +273 -184
- package/dist/lib/types/create-media-buy.d.ts +20 -28
- package/dist/lib/types/get-media-buys.d.ts +20 -28
- package/dist/lib/types/get-products.d.ts +20 -28
- package/dist/lib/types/index.d.mts +6 -1
- package/dist/lib/types/index.d.ts +6 -1
- 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/list-products.d.ts +20 -28
- package/dist/lib/types/list-proposals.d.ts +20 -28
- package/dist/lib/types/media-buy-delivery-report.d.mts +6 -0
- package/dist/lib/types/media-buy-delivery-report.d.ts +6 -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/refine-proposals.d.ts +20 -28
- package/dist/lib/types/request-proposals.d.ts +20 -28
- package/dist/lib/types/schemas.generated.d.ts +63113 -127273
- package/dist/lib/types/schemas.generated.js +759 -770
- package/dist/lib/types/schemas.generated.mjs +759 -770
- 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 +109 -0
- package/dist/lib/types/targeting-keys.generated.mjs +84 -0
- package/dist/lib/types/tools.generated.d.mts +2 -68
- package/dist/lib/types/tools.generated.d.ts +2 -68
- package/dist/lib/types/update-media-buy.d.ts +20 -28
- 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 +159 -39
- package/dist/lib/v2/projection/creative-delivery.mjs +163 -39
- 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/v2/projection/v1-to-v2.d.mts +1 -1
- package/dist/lib/v2/projection/v1-to-v2.d.ts +1 -1
- package/dist/lib/v2/projection/v1-to-v2.js +12 -9
- package/dist/lib/v2/projection/v1-to-v2.mjs +12 -9
- package/dist/lib/validation/budget-allocation.d.mts +3 -3
- package/dist/lib/validation/budget-allocation.d.ts +3 -3
- 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/nonempty-array.d.mts +15 -0
- package/dist/lib/validation/nonempty-array.d.ts +15 -0
- package/dist/lib/validation/nonempty-array.js +41 -0
- package/dist/lib/validation/nonempty-array.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/validation/sync-creatives.d.mts +22 -22
- package/dist/lib/validation/sync-creatives.d.ts +22 -22
- 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/COLLECTION-FIXTURE-FOUNDATION.md +11 -0
- package/docs/guides/DELIVERY-WEBHOOK-PARSING.md +142 -0
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +27 -1
- package/docs/guides/REPORTING-LEDGER.md +93 -0
- package/docs/guides/REPORTING-STABILITY.md +1 -1
- package/docs/guides/TYPED-CLIENT-TOOLS.md +49 -0
- package/docs/llms.txt +2 -2
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-16-to-17.md +202 -2
- package/docs/migration-6.6-to-6.7.md +14 -0
- package/docs/migration-account-change-feed.md +15 -0
- package/docs/migration-reporting-storage-package.md +1 -1
- package/docs/recipes/verifying-inbound-webhooks.md +18 -2
- package/package.json +2 -2
|
@@ -36,6 +36,7 @@ var import_jcs = require('../../utils/jcs.js');
|
|
|
36
36
|
var import_catalog = require('./catalog.js');
|
|
37
37
|
var import_resolve_agent_properties = require('../../discovery/resolve-agent-properties.js');
|
|
38
38
|
var import_address_guards = require('../../net/address-guards.js');
|
|
39
|
+
var import_legacy_metadata2 = require('./legacy-metadata.js');
|
|
39
40
|
function stripLegacyCreativeIdentity(value) {
|
|
40
41
|
const legacyTokens = /* @__PURE__ */ new Set();
|
|
41
42
|
const legacyUrlTokens = /* @__PURE__ */ new Set();
|
|
@@ -531,16 +532,38 @@ function creativeFormatParameterConstraints(creative) {
|
|
|
531
532
|
if (width === void 0 && height === void 0 && durationMs === void 0) return void 0;
|
|
532
533
|
return { width, height, durationMs };
|
|
533
534
|
}
|
|
534
|
-
function
|
|
535
|
+
function primaryMediaConstraints(creative) {
|
|
536
|
+
const assetType = creative.format_kind === "image" ? "image" : creative.format_kind === "video_hosted" ? "video" : creative.format_kind === "audio_hosted" ? "audio" : void 0;
|
|
537
|
+
if (!assetType) return void 0;
|
|
538
|
+
const assets = Object.values(record(creative.assets) ?? {}).flatMap(
|
|
539
|
+
(value) => (Array.isArray(value) ? value : [value]).flatMap((item) => {
|
|
540
|
+
const asset2 = record(item);
|
|
541
|
+
return asset2?.asset_type === assetType ? [asset2] : [];
|
|
542
|
+
})
|
|
543
|
+
);
|
|
544
|
+
if (assets.length !== 1) return void 0;
|
|
545
|
+
const asset = assets[0];
|
|
546
|
+
const width = assetType === "audio" ? void 0 : positiveConstraint(asset.width);
|
|
547
|
+
const height = assetType === "audio" ? void 0 : positiveConstraint(asset.height);
|
|
548
|
+
const durationMs = assetType === "image" ? void 0 : positiveConstraint(asset.duration_ms);
|
|
549
|
+
return width === void 0 && height === void 0 && durationMs === void 0 ? void 0 : { width, height, durationMs };
|
|
550
|
+
}
|
|
551
|
+
function positiveConstraint(value) {
|
|
552
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
553
|
+
}
|
|
554
|
+
function legacyRefParameterConstraints(ref, selectorParams) {
|
|
535
555
|
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;
|
|
556
|
+
const selector = record(selectorParams);
|
|
557
|
+
const sizes = Array.isArray(selector?.sizes) ? selector.sizes : [];
|
|
558
|
+
const size = sizes.length === 1 ? record(sizes[0]) : void 0;
|
|
536
559
|
return {
|
|
537
|
-
width: typeof ref.width === "number" ? ref.width : typeof params?.width === "number" ? params.width :
|
|
538
|
-
height: typeof ref.height === "number" ? ref.height : typeof params?.height === "number" ? params.height :
|
|
539
|
-
durationMs: ref.duration_ms
|
|
560
|
+
width: typeof ref.width === "number" ? ref.width : typeof params?.width === "number" ? params.width : positiveConstraint(selector?.width) ?? positiveConstraint(size?.width),
|
|
561
|
+
height: typeof ref.height === "number" ? ref.height : typeof params?.height === "number" ? params.height : positiveConstraint(selector?.height) ?? positiveConstraint(size?.height),
|
|
562
|
+
durationMs: ref.duration_ms ?? positiveConstraint(selector?.duration_ms_exact) ?? positiveConstraint(selector?.duration_ms)
|
|
540
563
|
};
|
|
541
564
|
}
|
|
542
|
-
function refContradictsConstraints(ref, constraints) {
|
|
543
|
-
const refConstraints = legacyRefParameterConstraints(ref);
|
|
565
|
+
function refContradictsConstraints(ref, constraints, selectorParams) {
|
|
566
|
+
const refConstraints = legacyRefParameterConstraints(ref, selectorParams);
|
|
544
567
|
if (constraints.width !== void 0 && refConstraints.width !== void 0 && refConstraints.width !== constraints.width) {
|
|
545
568
|
return true;
|
|
546
569
|
}
|
|
@@ -552,8 +575,8 @@ function refContradictsConstraints(ref, constraints) {
|
|
|
552
575
|
}
|
|
553
576
|
return false;
|
|
554
577
|
}
|
|
555
|
-
function refPinsConstraints(ref, constraints) {
|
|
556
|
-
const refConstraints = legacyRefParameterConstraints(ref);
|
|
578
|
+
function refPinsConstraints(ref, constraints, selectorParams) {
|
|
579
|
+
const refConstraints = legacyRefParameterConstraints(ref, selectorParams);
|
|
557
580
|
if (constraints.width !== void 0 && refConstraints.width === void 0) return false;
|
|
558
581
|
if (constraints.height !== void 0 && refConstraints.height === void 0) return false;
|
|
559
582
|
if (constraints.durationMs !== void 0 && typeof refConstraints.durationMs !== "number") return false;
|
|
@@ -565,8 +588,8 @@ function legacyIdPinsDimensions(ref) {
|
|
|
565
588
|
const params = record(declaration.params) ?? {};
|
|
566
589
|
return typeof params.width === "number" || typeof params.height === "number" || typeof params.duration_ms_exact === "number" || Array.isArray(params.sizes);
|
|
567
590
|
}
|
|
568
|
-
function refConstraintKey(ref) {
|
|
569
|
-
const constraints = legacyRefParameterConstraints(ref);
|
|
591
|
+
function refConstraintKey(ref, selectorParams) {
|
|
592
|
+
const constraints = legacyRefParameterConstraints(ref, selectorParams);
|
|
570
593
|
return [
|
|
571
594
|
agentIdentity(ref.agent_url),
|
|
572
595
|
constraints.width ?? "",
|
|
@@ -593,6 +616,7 @@ function candidateDeliveryTypes(candidate) {
|
|
|
593
616
|
}
|
|
594
617
|
function preferMostConstrainedLegacyCandidates(candidates, creative) {
|
|
595
618
|
let remaining = candidates;
|
|
619
|
+
const mediaKind = ["image", "video_hosted", "audio_hosted"].includes(String(creative.format_kind));
|
|
596
620
|
const deliveryTypes = creativeDisplayTagDeliveryTypes(creative);
|
|
597
621
|
if (deliveryTypes) {
|
|
598
622
|
remaining = remaining.filter((candidate) => {
|
|
@@ -604,17 +628,25 @@ function preferMostConstrainedLegacyCandidates(candidates, creative) {
|
|
|
604
628
|
const supportedSizes = assetRenderedSizes(creative);
|
|
605
629
|
if (supportedSizes.length > 1)
|
|
606
630
|
remaining = remaining.filter(
|
|
607
|
-
(candidate) => supportedSizes.some(
|
|
631
|
+
(candidate) => supportedSizes.some(
|
|
632
|
+
(size) => !refContradictsConstraints(candidate.ref, size, mediaKind ? candidate.selectorParams : void 0)
|
|
633
|
+
)
|
|
608
634
|
);
|
|
609
635
|
}
|
|
610
|
-
const constraints = creativeFormatParameterConstraints(creative);
|
|
636
|
+
const constraints = creativeFormatParameterConstraints(creative) ?? (remaining.length > 1 ? primaryMediaConstraints(creative) : void 0);
|
|
611
637
|
if (constraints) {
|
|
612
|
-
remaining = remaining.filter(
|
|
613
|
-
|
|
638
|
+
remaining = remaining.filter(
|
|
639
|
+
(candidate) => !refContradictsConstraints(candidate.ref, constraints, mediaKind ? candidate.selectorParams : void 0)
|
|
640
|
+
);
|
|
641
|
+
const pinned = remaining.filter(
|
|
642
|
+
(candidate) => refPinsConstraints(candidate.ref, constraints, mediaKind ? candidate.selectorParams : void 0)
|
|
643
|
+
);
|
|
614
644
|
if (pinned.length > 0) remaining = pinned;
|
|
615
645
|
}
|
|
616
646
|
if (remaining.length <= 1) return remaining;
|
|
617
|
-
const constraintKeys = new Set(
|
|
647
|
+
const constraintKeys = new Set(
|
|
648
|
+
remaining.map((candidate) => refConstraintKey(candidate.ref, mediaKind ? candidate.selectorParams : void 0))
|
|
649
|
+
);
|
|
618
650
|
if (constraintKeys.size !== 1) return remaining;
|
|
619
651
|
const specific = remaining.filter((candidate) => legacyIdPinsDimensions(candidate.ref) === true);
|
|
620
652
|
return specific.length > 0 && specific.length < remaining.length ? specific : remaining;
|
|
@@ -653,43 +685,82 @@ function selectLegacyRef(creative, container, canonicalFormatLegacyResolver, ope
|
|
|
653
685
|
matching = preferMostConstrainedLegacyCandidates(matching, creative);
|
|
654
686
|
return matching.length === 1 ? matching[0].ref : void 0;
|
|
655
687
|
}
|
|
688
|
+
function legacyUrlTrackerSlotMatches(slot, tracker) {
|
|
689
|
+
return slot.asset_type === "url" && slot.requirements?.url_type === "tracker_pixel" && (slot.asset_id === tracker.assetId || slot.requirements.role === tracker.assetId);
|
|
690
|
+
}
|
|
656
691
|
function projectLegacyAssetKeys(assetsValue, definition) {
|
|
692
|
+
const unchanged = { assets: assetsValue, drifts: [] };
|
|
657
693
|
const assets = record(assetsValue);
|
|
658
|
-
if (!assets || !Array.isArray(definition?.assets)) return
|
|
694
|
+
if (!assets || !Array.isArray(definition?.assets)) return unchanged;
|
|
659
695
|
const slots = definition.assets.filter((slot) => record(slot) !== void 0);
|
|
660
|
-
if (slots.some((slot) => slot.item_type !== void 0 && slot.item_type !== "individual")) return
|
|
696
|
+
if (slots.some((slot) => slot.item_type !== void 0 && slot.item_type !== "individual")) return unchanged;
|
|
661
697
|
const declaredIds = new Set(slots.map((slot) => slot.asset_id));
|
|
662
698
|
const availableSlots = slots.filter(
|
|
663
|
-
(slot) =>
|
|
699
|
+
(slot) => typeof slot.asset_id === "string" && slot.asset_id.length > 0 && !Object.hasOwn(assets, slot.asset_id)
|
|
664
700
|
);
|
|
665
701
|
const targetBySource = /* @__PURE__ */ new Map();
|
|
666
702
|
const sourcesByTarget = /* @__PURE__ */ new Map();
|
|
703
|
+
const trackersBySource = /* @__PURE__ */ new Map();
|
|
667
704
|
for (const [key, value] of Object.entries(assets)) {
|
|
668
|
-
|
|
705
|
+
const candidates = (Array.isArray(value) ? value : [value]).map(import_legacy_metadata2.downgradePixelTracker);
|
|
706
|
+
const trackers = candidates.length > 0 && candidates.every((tracker) => tracker !== void 0) ? candidates : void 0;
|
|
707
|
+
const trackerSlotMatches = (slot2) => trackers !== void 0 && trackers.every((tracker) => legacyUrlTrackerSlotMatches(slot2, tracker));
|
|
708
|
+
if (declaredIds.has(key)) {
|
|
709
|
+
const slot2 = slots.find((slot3) => slot3.asset_id === key);
|
|
710
|
+
if (trackers && slot2 && trackerSlotMatches(slot2)) trackersBySource.set(key, trackers);
|
|
711
|
+
continue;
|
|
712
|
+
}
|
|
669
713
|
const asset = record(value);
|
|
670
|
-
if (!asset || typeof asset.asset_type !== "string") continue;
|
|
671
|
-
const matches = availableSlots.filter((
|
|
672
|
-
if (
|
|
714
|
+
if (!trackers && (!asset || typeof asset.asset_type !== "string")) continue;
|
|
715
|
+
const matches = availableSlots.filter((slot2) => {
|
|
716
|
+
if (trackerSlotMatches(slot2)) return true;
|
|
717
|
+
if (!asset || slot2.asset_type !== asset.asset_type) return false;
|
|
673
718
|
if (asset.asset_type === "url") {
|
|
674
|
-
return typeof asset.url_type === "string" && asset.url_type ===
|
|
719
|
+
return typeof asset.url_type === "string" && asset.url_type === slot2.requirements?.url_type;
|
|
675
720
|
}
|
|
676
721
|
if (asset.asset_type === "pixel_tracker") {
|
|
677
|
-
return typeof asset.event === "string" && asset.event ===
|
|
722
|
+
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);
|
|
678
723
|
}
|
|
679
724
|
return true;
|
|
680
725
|
});
|
|
681
726
|
if (matches.length !== 1) continue;
|
|
682
|
-
const
|
|
727
|
+
const slot = matches[0];
|
|
728
|
+
const target = slot.asset_id;
|
|
683
729
|
targetBySource.set(key, target);
|
|
730
|
+
if (trackers && trackerSlotMatches(slot)) trackersBySource.set(key, trackers);
|
|
684
731
|
const sources = sourcesByTarget.get(target) ?? [];
|
|
685
732
|
sources.push(key);
|
|
686
733
|
sourcesByTarget.set(target, sources);
|
|
687
734
|
}
|
|
688
735
|
for (const sources of sourcesByTarget.values()) {
|
|
689
|
-
if (sources.length > 1)
|
|
736
|
+
if (sources.length > 1) {
|
|
737
|
+
for (const source of sources) {
|
|
738
|
+
targetBySource.delete(source);
|
|
739
|
+
trackersBySource.delete(source);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
690
742
|
}
|
|
691
|
-
if (targetBySource.size === 0) return
|
|
692
|
-
|
|
743
|
+
if (targetBySource.size === 0 && trackersBySource.size === 0) return unchanged;
|
|
744
|
+
const drifts = [];
|
|
745
|
+
for (const [key, trackers] of trackersBySource) {
|
|
746
|
+
trackers.forEach((tracker, index) => {
|
|
747
|
+
const path = `assets.${key}${Array.isArray(assets[key]) ? `[${index}]` : ""}`;
|
|
748
|
+
const drift = (0, import_legacy_metadata2.pixelTrackerDrift)(path, tracker);
|
|
749
|
+
if (drift) drifts.push(drift);
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
return {
|
|
753
|
+
assets: Object.fromEntries(
|
|
754
|
+
Object.entries(assets).map(([key, value]) => {
|
|
755
|
+
const trackers = trackersBySource.get(key);
|
|
756
|
+
return [
|
|
757
|
+
targetBySource.get(key) ?? key,
|
|
758
|
+
trackers ? Array.isArray(value) ? trackers.map((tracker) => tracker.asset) : trackers[0].asset : value
|
|
759
|
+
];
|
|
760
|
+
})
|
|
761
|
+
),
|
|
762
|
+
drifts
|
|
763
|
+
};
|
|
693
764
|
}
|
|
694
765
|
function renderedSizeFields(asset) {
|
|
695
766
|
if (asset.width !== void 0 || asset.height !== void 0)
|
|
@@ -725,7 +796,6 @@ function projectInlineMarkupToLegacyHtml(assetsValue, definition, operation, cre
|
|
|
725
796
|
{
|
|
726
797
|
asset_type: "html",
|
|
727
798
|
content: asset.markup,
|
|
728
|
-
...renderedSizeFields(asset),
|
|
729
799
|
...asset.provenance !== void 0 && { provenance: asset.provenance }
|
|
730
800
|
}
|
|
731
801
|
];
|
|
@@ -787,15 +857,34 @@ function projectCreative(creative, formatId, legacyFormatDefinitions, operation
|
|
|
787
857
|
}
|
|
788
858
|
}
|
|
789
859
|
if (Object.hasOwn(creative, "assets")) {
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
typeof creative.creative_id === "string" ? creative.creative_id : "(unknown)"
|
|
796
|
-
),
|
|
797
|
-
definition
|
|
860
|
+
const legacyAssets = projectInlineMarkupToLegacyHtml(
|
|
861
|
+
creative.assets,
|
|
862
|
+
markupDefinition,
|
|
863
|
+
operation,
|
|
864
|
+
typeof creative.creative_id === "string" ? creative.creative_id : "(unknown)"
|
|
798
865
|
);
|
|
866
|
+
const refSize = legacyRefParameterConstraints(formatId);
|
|
867
|
+
const acceptsDimensions = Array.isArray(markupDefinition?.accepts_parameters) && markupDefinition.accepts_parameters.includes("dimensions");
|
|
868
|
+
const hasFixedRender = Array.isArray(markupDefinition?.renders) && markupDefinition.renders.some(
|
|
869
|
+
(render) => typeof render.dimensions?.width === "number" || typeof render.dimensions?.height === "number"
|
|
870
|
+
);
|
|
871
|
+
if (legacyAssets !== creative.assets && acceptsDimensions && !hasFixedRender && refSize.width === void 0 && refSize.height === void 0) {
|
|
872
|
+
const inlineAssets = Object.fromEntries(
|
|
873
|
+
Object.entries(record(creative.assets) ?? {}).filter(([, value]) => {
|
|
874
|
+
const asset = record(value);
|
|
875
|
+
return asset?.asset_type === "display_tag" && asset.delivery_type === "inline_markup";
|
|
876
|
+
})
|
|
877
|
+
);
|
|
878
|
+
const size = assetRenderedSize({ assets: inlineAssets });
|
|
879
|
+
const requested = creativeFormatParameterConstraints(creative);
|
|
880
|
+
if (typeof size?.width === "number" && typeof size.height === "number" && Number.isSafeInteger(size.width) && Number.isSafeInteger(size.height) && size.width > 0 && size.height > 0 && (requested?.width === void 0 || requested.width === size.width) && (requested?.height === void 0 || requested.height === size.height)) {
|
|
881
|
+
next.format_id = { ...formatId, width: size.width, height: size.height };
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
const projected = projectLegacyAssetKeys(legacyAssets, definition);
|
|
885
|
+
next.assets = projected.assets;
|
|
886
|
+
(0, import_legacy_metadata.transferLegacyCreativeMetadata)(creative, next);
|
|
887
|
+
(0, import_legacy_metadata2.rememberCreativeDeliveryDiagnostics)(next, projected.drifts);
|
|
799
888
|
}
|
|
800
889
|
return next;
|
|
801
890
|
}
|
|
@@ -1051,6 +1140,7 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
|
|
|
1051
1140
|
legacyFormatConverter,
|
|
1052
1141
|
wireMode === "canonical"
|
|
1053
1142
|
);
|
|
1143
|
+
(0, import_legacy_metadata.transferLegacyCreativeMetadata)(inputRecord, creativeRecord);
|
|
1054
1144
|
if (wireMode === "canonical") return creativeRecord;
|
|
1055
1145
|
if (originalLegacyRef) {
|
|
1056
1146
|
const selectedOriginal = selectLegacyRef(inputRecord, selectorContainer, canonicalFormatLegacyResolver, operation);
|
|
@@ -1130,14 +1220,44 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
|
|
|
1130
1220
|
throw new CreativeFormatProjectionError(
|
|
1131
1221
|
operation,
|
|
1132
1222
|
creativeId,
|
|
1133
|
-
`the seller advertised ${candidates.length} legacy refs for canonical kind ${creativeRecord.format_kind}`
|
|
1223
|
+
`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" : "")
|
|
1134
1224
|
);
|
|
1135
1225
|
}
|
|
1136
|
-
const reason = pinned ? "the creative is pinned to a format option that names none of the selected seller product legacy format references" :
|
|
1226
|
+
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);
|
|
1137
1227
|
throw new CreativeFormatProjectionError(operation, creativeId, reason);
|
|
1138
1228
|
}
|
|
1139
1229
|
return creative;
|
|
1140
1230
|
}
|
|
1231
|
+
function describeUnmatchedLegacyCandidates(creative, allCandidates) {
|
|
1232
|
+
const generic = "the selected seller product did not provide one unambiguous legacy format reference";
|
|
1233
|
+
const kind = String(creative.format_kind);
|
|
1234
|
+
if (allCandidates.length === 0) return generic;
|
|
1235
|
+
const sameKind = allCandidates.filter((candidate) => candidate.formatKind === kind);
|
|
1236
|
+
if (sameKind.length === 0) {
|
|
1237
|
+
const offered = [
|
|
1238
|
+
...new Set(allCandidates.flatMap((candidate) => candidate.formatKind ? [candidate.formatKind] : []))
|
|
1239
|
+
];
|
|
1240
|
+
if (offered.length === 0) return generic;
|
|
1241
|
+
const htmlMarkupHint = kind === "html5" && offered.includes("display_tag") ? ". HTML-markup formats (display_html, display_WxH_html) take display_tag inline markup since SDK 17; send HTML snippets as a display_tag asset with delivery_type inline_markup (docs/migration-16-to-17.md)" : "";
|
|
1242
|
+
return `the selected seller product offers legacy refs for canonical kind ${offered.join(", ")}, not ${kind}${htmlMarkupHint}`;
|
|
1243
|
+
}
|
|
1244
|
+
const deliveryTypes = creativeDisplayTagDeliveryTypes(creative);
|
|
1245
|
+
if (deliveryTypes) {
|
|
1246
|
+
const accepting = sameKind.filter((candidate) => {
|
|
1247
|
+
const accepted = candidateDeliveryTypes(candidate);
|
|
1248
|
+
return [...deliveryTypes].every((type) => accepted.includes(type));
|
|
1249
|
+
});
|
|
1250
|
+
if (accepting.length === 0) {
|
|
1251
|
+
const accepted = [...new Set(sameKind.flatMap((candidate) => candidateDeliveryTypes(candidate).map(String)))];
|
|
1252
|
+
return `none of the seller's ${sameKind.length} ${kind} legacy refs accepts delivery_type ${[...deliveryTypes].join(", ")} (they accept ${accepted.join(", ")})`;
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
const size = creativeFormatParameterConstraints(creative);
|
|
1256
|
+
if (size?.width !== void 0 && size.height !== void 0) {
|
|
1257
|
+
return `none of the seller's ${sameKind.length} ${kind} legacy refs matches the creative's ${size.width}x${size.height} size`;
|
|
1258
|
+
}
|
|
1259
|
+
return generic;
|
|
1260
|
+
}
|
|
1141
1261
|
function projectMediaBuyCreativesForDelivery(request, wireMode = "canonical", operation = "create_media_buy", legacyFormatConverter, canonicalFormatLegacyResolver, legacyFormatDefinitions) {
|
|
1142
1262
|
const requestRecord = record(request);
|
|
1143
1263
|
if (!requestRecord) return request;
|
|
@@ -15,6 +15,11 @@ import { canonicalize as canonicalizeJson } from "../../utils/jcs.mjs";
|
|
|
15
15
|
import { lookupUniqueV1FormatById, lookupV1Format } from "./catalog.mjs";
|
|
16
16
|
import { canonicalizeAgentUrl } from "../../discovery/resolve-agent-properties.mjs";
|
|
17
17
|
import { isLikelyPrivateUrl } from "../../net/address-guards.mjs";
|
|
18
|
+
import {
|
|
19
|
+
downgradePixelTracker,
|
|
20
|
+
pixelTrackerDrift,
|
|
21
|
+
rememberCreativeDeliveryDiagnostics
|
|
22
|
+
} from "./legacy-metadata.mjs";
|
|
18
23
|
function stripLegacyCreativeIdentity(value) {
|
|
19
24
|
const legacyTokens = /* @__PURE__ */ new Set();
|
|
20
25
|
const legacyUrlTokens = /* @__PURE__ */ new Set();
|
|
@@ -510,16 +515,38 @@ function creativeFormatParameterConstraints(creative) {
|
|
|
510
515
|
if (width === void 0 && height === void 0 && durationMs === void 0) return void 0;
|
|
511
516
|
return { width, height, durationMs };
|
|
512
517
|
}
|
|
513
|
-
function
|
|
518
|
+
function primaryMediaConstraints(creative) {
|
|
519
|
+
const assetType = creative.format_kind === "image" ? "image" : creative.format_kind === "video_hosted" ? "video" : creative.format_kind === "audio_hosted" ? "audio" : void 0;
|
|
520
|
+
if (!assetType) return void 0;
|
|
521
|
+
const assets = Object.values(record(creative.assets) ?? {}).flatMap(
|
|
522
|
+
(value) => (Array.isArray(value) ? value : [value]).flatMap((item) => {
|
|
523
|
+
const asset2 = record(item);
|
|
524
|
+
return asset2?.asset_type === assetType ? [asset2] : [];
|
|
525
|
+
})
|
|
526
|
+
);
|
|
527
|
+
if (assets.length !== 1) return void 0;
|
|
528
|
+
const asset = assets[0];
|
|
529
|
+
const width = assetType === "audio" ? void 0 : positiveConstraint(asset.width);
|
|
530
|
+
const height = assetType === "audio" ? void 0 : positiveConstraint(asset.height);
|
|
531
|
+
const durationMs = assetType === "image" ? void 0 : positiveConstraint(asset.duration_ms);
|
|
532
|
+
return width === void 0 && height === void 0 && durationMs === void 0 ? void 0 : { width, height, durationMs };
|
|
533
|
+
}
|
|
534
|
+
function positiveConstraint(value) {
|
|
535
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
536
|
+
}
|
|
537
|
+
function legacyRefParameterConstraints(ref, selectorParams) {
|
|
514
538
|
const params = typeof ref.width !== "number" || typeof ref.height !== "number" ? record(canonicalDeclarationFromBareId(ref.id, { agentUrl: ref.agent_url })?.params) : void 0;
|
|
539
|
+
const selector = record(selectorParams);
|
|
540
|
+
const sizes = Array.isArray(selector?.sizes) ? selector.sizes : [];
|
|
541
|
+
const size = sizes.length === 1 ? record(sizes[0]) : void 0;
|
|
515
542
|
return {
|
|
516
|
-
width: typeof ref.width === "number" ? ref.width : typeof params?.width === "number" ? params.width :
|
|
517
|
-
height: typeof ref.height === "number" ? ref.height : typeof params?.height === "number" ? params.height :
|
|
518
|
-
durationMs: ref.duration_ms
|
|
543
|
+
width: typeof ref.width === "number" ? ref.width : typeof params?.width === "number" ? params.width : positiveConstraint(selector?.width) ?? positiveConstraint(size?.width),
|
|
544
|
+
height: typeof ref.height === "number" ? ref.height : typeof params?.height === "number" ? params.height : positiveConstraint(selector?.height) ?? positiveConstraint(size?.height),
|
|
545
|
+
durationMs: ref.duration_ms ?? positiveConstraint(selector?.duration_ms_exact) ?? positiveConstraint(selector?.duration_ms)
|
|
519
546
|
};
|
|
520
547
|
}
|
|
521
|
-
function refContradictsConstraints(ref, constraints) {
|
|
522
|
-
const refConstraints = legacyRefParameterConstraints(ref);
|
|
548
|
+
function refContradictsConstraints(ref, constraints, selectorParams) {
|
|
549
|
+
const refConstraints = legacyRefParameterConstraints(ref, selectorParams);
|
|
523
550
|
if (constraints.width !== void 0 && refConstraints.width !== void 0 && refConstraints.width !== constraints.width) {
|
|
524
551
|
return true;
|
|
525
552
|
}
|
|
@@ -531,8 +558,8 @@ function refContradictsConstraints(ref, constraints) {
|
|
|
531
558
|
}
|
|
532
559
|
return false;
|
|
533
560
|
}
|
|
534
|
-
function refPinsConstraints(ref, constraints) {
|
|
535
|
-
const refConstraints = legacyRefParameterConstraints(ref);
|
|
561
|
+
function refPinsConstraints(ref, constraints, selectorParams) {
|
|
562
|
+
const refConstraints = legacyRefParameterConstraints(ref, selectorParams);
|
|
536
563
|
if (constraints.width !== void 0 && refConstraints.width === void 0) return false;
|
|
537
564
|
if (constraints.height !== void 0 && refConstraints.height === void 0) return false;
|
|
538
565
|
if (constraints.durationMs !== void 0 && typeof refConstraints.durationMs !== "number") return false;
|
|
@@ -544,8 +571,8 @@ function legacyIdPinsDimensions(ref) {
|
|
|
544
571
|
const params = record(declaration.params) ?? {};
|
|
545
572
|
return typeof params.width === "number" || typeof params.height === "number" || typeof params.duration_ms_exact === "number" || Array.isArray(params.sizes);
|
|
546
573
|
}
|
|
547
|
-
function refConstraintKey(ref) {
|
|
548
|
-
const constraints = legacyRefParameterConstraints(ref);
|
|
574
|
+
function refConstraintKey(ref, selectorParams) {
|
|
575
|
+
const constraints = legacyRefParameterConstraints(ref, selectorParams);
|
|
549
576
|
return [
|
|
550
577
|
agentIdentity(ref.agent_url),
|
|
551
578
|
constraints.width ?? "",
|
|
@@ -572,6 +599,7 @@ function candidateDeliveryTypes(candidate) {
|
|
|
572
599
|
}
|
|
573
600
|
function preferMostConstrainedLegacyCandidates(candidates, creative) {
|
|
574
601
|
let remaining = candidates;
|
|
602
|
+
const mediaKind = ["image", "video_hosted", "audio_hosted"].includes(String(creative.format_kind));
|
|
575
603
|
const deliveryTypes = creativeDisplayTagDeliveryTypes(creative);
|
|
576
604
|
if (deliveryTypes) {
|
|
577
605
|
remaining = remaining.filter((candidate) => {
|
|
@@ -583,17 +611,25 @@ function preferMostConstrainedLegacyCandidates(candidates, creative) {
|
|
|
583
611
|
const supportedSizes = assetRenderedSizes(creative);
|
|
584
612
|
if (supportedSizes.length > 1)
|
|
585
613
|
remaining = remaining.filter(
|
|
586
|
-
(candidate) => supportedSizes.some(
|
|
614
|
+
(candidate) => supportedSizes.some(
|
|
615
|
+
(size) => !refContradictsConstraints(candidate.ref, size, mediaKind ? candidate.selectorParams : void 0)
|
|
616
|
+
)
|
|
587
617
|
);
|
|
588
618
|
}
|
|
589
|
-
const constraints = creativeFormatParameterConstraints(creative);
|
|
619
|
+
const constraints = creativeFormatParameterConstraints(creative) ?? (remaining.length > 1 ? primaryMediaConstraints(creative) : void 0);
|
|
590
620
|
if (constraints) {
|
|
591
|
-
remaining = remaining.filter(
|
|
592
|
-
|
|
621
|
+
remaining = remaining.filter(
|
|
622
|
+
(candidate) => !refContradictsConstraints(candidate.ref, constraints, mediaKind ? candidate.selectorParams : void 0)
|
|
623
|
+
);
|
|
624
|
+
const pinned = remaining.filter(
|
|
625
|
+
(candidate) => refPinsConstraints(candidate.ref, constraints, mediaKind ? candidate.selectorParams : void 0)
|
|
626
|
+
);
|
|
593
627
|
if (pinned.length > 0) remaining = pinned;
|
|
594
628
|
}
|
|
595
629
|
if (remaining.length <= 1) return remaining;
|
|
596
|
-
const constraintKeys = new Set(
|
|
630
|
+
const constraintKeys = new Set(
|
|
631
|
+
remaining.map((candidate) => refConstraintKey(candidate.ref, mediaKind ? candidate.selectorParams : void 0))
|
|
632
|
+
);
|
|
597
633
|
if (constraintKeys.size !== 1) return remaining;
|
|
598
634
|
const specific = remaining.filter((candidate) => legacyIdPinsDimensions(candidate.ref) === true);
|
|
599
635
|
return specific.length > 0 && specific.length < remaining.length ? specific : remaining;
|
|
@@ -632,43 +668,82 @@ function selectLegacyRef(creative, container, canonicalFormatLegacyResolver, ope
|
|
|
632
668
|
matching = preferMostConstrainedLegacyCandidates(matching, creative);
|
|
633
669
|
return matching.length === 1 ? matching[0].ref : void 0;
|
|
634
670
|
}
|
|
671
|
+
function legacyUrlTrackerSlotMatches(slot, tracker) {
|
|
672
|
+
return slot.asset_type === "url" && slot.requirements?.url_type === "tracker_pixel" && (slot.asset_id === tracker.assetId || slot.requirements.role === tracker.assetId);
|
|
673
|
+
}
|
|
635
674
|
function projectLegacyAssetKeys(assetsValue, definition) {
|
|
675
|
+
const unchanged = { assets: assetsValue, drifts: [] };
|
|
636
676
|
const assets = record(assetsValue);
|
|
637
|
-
if (!assets || !Array.isArray(definition?.assets)) return
|
|
677
|
+
if (!assets || !Array.isArray(definition?.assets)) return unchanged;
|
|
638
678
|
const slots = definition.assets.filter((slot) => record(slot) !== void 0);
|
|
639
|
-
if (slots.some((slot) => slot.item_type !== void 0 && slot.item_type !== "individual")) return
|
|
679
|
+
if (slots.some((slot) => slot.item_type !== void 0 && slot.item_type !== "individual")) return unchanged;
|
|
640
680
|
const declaredIds = new Set(slots.map((slot) => slot.asset_id));
|
|
641
681
|
const availableSlots = slots.filter(
|
|
642
|
-
(slot) =>
|
|
682
|
+
(slot) => typeof slot.asset_id === "string" && slot.asset_id.length > 0 && !Object.hasOwn(assets, slot.asset_id)
|
|
643
683
|
);
|
|
644
684
|
const targetBySource = /* @__PURE__ */ new Map();
|
|
645
685
|
const sourcesByTarget = /* @__PURE__ */ new Map();
|
|
686
|
+
const trackersBySource = /* @__PURE__ */ new Map();
|
|
646
687
|
for (const [key, value] of Object.entries(assets)) {
|
|
647
|
-
|
|
688
|
+
const candidates = (Array.isArray(value) ? value : [value]).map(downgradePixelTracker);
|
|
689
|
+
const trackers = candidates.length > 0 && candidates.every((tracker) => tracker !== void 0) ? candidates : void 0;
|
|
690
|
+
const trackerSlotMatches = (slot2) => trackers !== void 0 && trackers.every((tracker) => legacyUrlTrackerSlotMatches(slot2, tracker));
|
|
691
|
+
if (declaredIds.has(key)) {
|
|
692
|
+
const slot2 = slots.find((slot3) => slot3.asset_id === key);
|
|
693
|
+
if (trackers && slot2 && trackerSlotMatches(slot2)) trackersBySource.set(key, trackers);
|
|
694
|
+
continue;
|
|
695
|
+
}
|
|
648
696
|
const asset = record(value);
|
|
649
|
-
if (!asset || typeof asset.asset_type !== "string") continue;
|
|
650
|
-
const matches = availableSlots.filter((
|
|
651
|
-
if (
|
|
697
|
+
if (!trackers && (!asset || typeof asset.asset_type !== "string")) continue;
|
|
698
|
+
const matches = availableSlots.filter((slot2) => {
|
|
699
|
+
if (trackerSlotMatches(slot2)) return true;
|
|
700
|
+
if (!asset || slot2.asset_type !== asset.asset_type) return false;
|
|
652
701
|
if (asset.asset_type === "url") {
|
|
653
|
-
return typeof asset.url_type === "string" && asset.url_type ===
|
|
702
|
+
return typeof asset.url_type === "string" && asset.url_type === slot2.requirements?.url_type;
|
|
654
703
|
}
|
|
655
704
|
if (asset.asset_type === "pixel_tracker") {
|
|
656
|
-
return typeof asset.event === "string" && asset.event ===
|
|
705
|
+
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);
|
|
657
706
|
}
|
|
658
707
|
return true;
|
|
659
708
|
});
|
|
660
709
|
if (matches.length !== 1) continue;
|
|
661
|
-
const
|
|
710
|
+
const slot = matches[0];
|
|
711
|
+
const target = slot.asset_id;
|
|
662
712
|
targetBySource.set(key, target);
|
|
713
|
+
if (trackers && trackerSlotMatches(slot)) trackersBySource.set(key, trackers);
|
|
663
714
|
const sources = sourcesByTarget.get(target) ?? [];
|
|
664
715
|
sources.push(key);
|
|
665
716
|
sourcesByTarget.set(target, sources);
|
|
666
717
|
}
|
|
667
718
|
for (const sources of sourcesByTarget.values()) {
|
|
668
|
-
if (sources.length > 1)
|
|
719
|
+
if (sources.length > 1) {
|
|
720
|
+
for (const source of sources) {
|
|
721
|
+
targetBySource.delete(source);
|
|
722
|
+
trackersBySource.delete(source);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
669
725
|
}
|
|
670
|
-
if (targetBySource.size === 0) return
|
|
671
|
-
|
|
726
|
+
if (targetBySource.size === 0 && trackersBySource.size === 0) return unchanged;
|
|
727
|
+
const drifts = [];
|
|
728
|
+
for (const [key, trackers] of trackersBySource) {
|
|
729
|
+
trackers.forEach((tracker, index) => {
|
|
730
|
+
const path = `assets.${key}${Array.isArray(assets[key]) ? `[${index}]` : ""}`;
|
|
731
|
+
const drift = pixelTrackerDrift(path, tracker);
|
|
732
|
+
if (drift) drifts.push(drift);
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
return {
|
|
736
|
+
assets: Object.fromEntries(
|
|
737
|
+
Object.entries(assets).map(([key, value]) => {
|
|
738
|
+
const trackers = trackersBySource.get(key);
|
|
739
|
+
return [
|
|
740
|
+
targetBySource.get(key) ?? key,
|
|
741
|
+
trackers ? Array.isArray(value) ? trackers.map((tracker) => tracker.asset) : trackers[0].asset : value
|
|
742
|
+
];
|
|
743
|
+
})
|
|
744
|
+
),
|
|
745
|
+
drifts
|
|
746
|
+
};
|
|
672
747
|
}
|
|
673
748
|
function renderedSizeFields(asset) {
|
|
674
749
|
if (asset.width !== void 0 || asset.height !== void 0)
|
|
@@ -704,7 +779,6 @@ function projectInlineMarkupToLegacyHtml(assetsValue, definition, operation, cre
|
|
|
704
779
|
{
|
|
705
780
|
asset_type: "html",
|
|
706
781
|
content: asset.markup,
|
|
707
|
-
...renderedSizeFields(asset),
|
|
708
782
|
...asset.provenance !== void 0 && { provenance: asset.provenance }
|
|
709
783
|
}
|
|
710
784
|
];
|
|
@@ -766,15 +840,34 @@ function projectCreative(creative, formatId, legacyFormatDefinitions, operation
|
|
|
766
840
|
}
|
|
767
841
|
}
|
|
768
842
|
if (Object.hasOwn(creative, "assets")) {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
843
|
+
const legacyAssets = projectInlineMarkupToLegacyHtml(
|
|
844
|
+
creative.assets,
|
|
845
|
+
markupDefinition,
|
|
846
|
+
operation,
|
|
847
|
+
typeof creative.creative_id === "string" ? creative.creative_id : "(unknown)"
|
|
848
|
+
);
|
|
849
|
+
const refSize = legacyRefParameterConstraints(formatId);
|
|
850
|
+
const acceptsDimensions = Array.isArray(markupDefinition?.accepts_parameters) && markupDefinition.accepts_parameters.includes("dimensions");
|
|
851
|
+
const hasFixedRender = Array.isArray(markupDefinition?.renders) && markupDefinition.renders.some(
|
|
852
|
+
(render) => typeof render.dimensions?.width === "number" || typeof render.dimensions?.height === "number"
|
|
777
853
|
);
|
|
854
|
+
if (legacyAssets !== creative.assets && acceptsDimensions && !hasFixedRender && refSize.width === void 0 && refSize.height === void 0) {
|
|
855
|
+
const inlineAssets = Object.fromEntries(
|
|
856
|
+
Object.entries(record(creative.assets) ?? {}).filter(([, value]) => {
|
|
857
|
+
const asset = record(value);
|
|
858
|
+
return asset?.asset_type === "display_tag" && asset.delivery_type === "inline_markup";
|
|
859
|
+
})
|
|
860
|
+
);
|
|
861
|
+
const size = assetRenderedSize({ assets: inlineAssets });
|
|
862
|
+
const requested = creativeFormatParameterConstraints(creative);
|
|
863
|
+
if (typeof size?.width === "number" && typeof size.height === "number" && Number.isSafeInteger(size.width) && Number.isSafeInteger(size.height) && size.width > 0 && size.height > 0 && (requested?.width === void 0 || requested.width === size.width) && (requested?.height === void 0 || requested.height === size.height)) {
|
|
864
|
+
next.format_id = { ...formatId, width: size.width, height: size.height };
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
const projected = projectLegacyAssetKeys(legacyAssets, definition);
|
|
868
|
+
next.assets = projected.assets;
|
|
869
|
+
transferLegacyCreativeMetadata(creative, next);
|
|
870
|
+
rememberCreativeDeliveryDiagnostics(next, projected.drifts);
|
|
778
871
|
}
|
|
779
872
|
return next;
|
|
780
873
|
}
|
|
@@ -1030,6 +1123,7 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
|
|
|
1030
1123
|
legacyFormatConverter,
|
|
1031
1124
|
wireMode === "canonical"
|
|
1032
1125
|
);
|
|
1126
|
+
transferLegacyCreativeMetadata(inputRecord, creativeRecord);
|
|
1033
1127
|
if (wireMode === "canonical") return creativeRecord;
|
|
1034
1128
|
if (originalLegacyRef) {
|
|
1035
1129
|
const selectedOriginal = selectLegacyRef(inputRecord, selectorContainer, canonicalFormatLegacyResolver, operation);
|
|
@@ -1109,14 +1203,44 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
|
|
|
1109
1203
|
throw new CreativeFormatProjectionError(
|
|
1110
1204
|
operation,
|
|
1111
1205
|
creativeId,
|
|
1112
|
-
`the seller advertised ${candidates.length} legacy refs for canonical kind ${creativeRecord.format_kind}`
|
|
1206
|
+
`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" : "")
|
|
1113
1207
|
);
|
|
1114
1208
|
}
|
|
1115
|
-
const reason = pinned ? "the creative is pinned to a format option that names none of the selected seller product legacy format references" :
|
|
1209
|
+
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);
|
|
1116
1210
|
throw new CreativeFormatProjectionError(operation, creativeId, reason);
|
|
1117
1211
|
}
|
|
1118
1212
|
return creative;
|
|
1119
1213
|
}
|
|
1214
|
+
function describeUnmatchedLegacyCandidates(creative, allCandidates) {
|
|
1215
|
+
const generic = "the selected seller product did not provide one unambiguous legacy format reference";
|
|
1216
|
+
const kind = String(creative.format_kind);
|
|
1217
|
+
if (allCandidates.length === 0) return generic;
|
|
1218
|
+
const sameKind = allCandidates.filter((candidate) => candidate.formatKind === kind);
|
|
1219
|
+
if (sameKind.length === 0) {
|
|
1220
|
+
const offered = [
|
|
1221
|
+
...new Set(allCandidates.flatMap((candidate) => candidate.formatKind ? [candidate.formatKind] : []))
|
|
1222
|
+
];
|
|
1223
|
+
if (offered.length === 0) return generic;
|
|
1224
|
+
const htmlMarkupHint = kind === "html5" && offered.includes("display_tag") ? ". HTML-markup formats (display_html, display_WxH_html) take display_tag inline markup since SDK 17; send HTML snippets as a display_tag asset with delivery_type inline_markup (docs/migration-16-to-17.md)" : "";
|
|
1225
|
+
return `the selected seller product offers legacy refs for canonical kind ${offered.join(", ")}, not ${kind}${htmlMarkupHint}`;
|
|
1226
|
+
}
|
|
1227
|
+
const deliveryTypes = creativeDisplayTagDeliveryTypes(creative);
|
|
1228
|
+
if (deliveryTypes) {
|
|
1229
|
+
const accepting = sameKind.filter((candidate) => {
|
|
1230
|
+
const accepted = candidateDeliveryTypes(candidate);
|
|
1231
|
+
return [...deliveryTypes].every((type) => accepted.includes(type));
|
|
1232
|
+
});
|
|
1233
|
+
if (accepting.length === 0) {
|
|
1234
|
+
const accepted = [...new Set(sameKind.flatMap((candidate) => candidateDeliveryTypes(candidate).map(String)))];
|
|
1235
|
+
return `none of the seller's ${sameKind.length} ${kind} legacy refs accepts delivery_type ${[...deliveryTypes].join(", ")} (they accept ${accepted.join(", ")})`;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
const size = creativeFormatParameterConstraints(creative);
|
|
1239
|
+
if (size?.width !== void 0 && size.height !== void 0) {
|
|
1240
|
+
return `none of the seller's ${sameKind.length} ${kind} legacy refs matches the creative's ${size.width}x${size.height} size`;
|
|
1241
|
+
}
|
|
1242
|
+
return generic;
|
|
1243
|
+
}
|
|
1120
1244
|
function projectMediaBuyCreativesForDelivery(request, wireMode = "canonical", operation = "create_media_buy", legacyFormatConverter, canonicalFormatLegacyResolver, legacyFormatDefinitions) {
|
|
1121
1245
|
const requestRecord = record(request);
|
|
1122
1246
|
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';
|