@adcp/sdk 16.0.0-beta.9 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +2 -2
  2. package/dist/lib/identity-3.3/revocation.js +6 -7
  3. package/dist/lib/identity-3.3/revocation.mjs +6 -7
  4. package/dist/lib/server/create-adcp-server.js +1 -1
  5. package/dist/lib/server/create-adcp-server.mjs +1 -1
  6. package/dist/lib/signing/crypto.d.mts +1 -1
  7. package/dist/lib/signing/crypto.d.ts +1 -1
  8. package/dist/lib/signing/crypto.js +2 -45
  9. package/dist/lib/signing/crypto.mjs +2 -46
  10. package/dist/lib/signing/web-bot-auth.d.mts +18 -10
  11. package/dist/lib/signing/web-bot-auth.d.ts +18 -10
  12. package/dist/lib/signing/web-bot-auth.js +29 -24
  13. package/dist/lib/signing/web-bot-auth.mjs +29 -24
  14. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  15. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  16. package/dist/lib/v2/projection/catalog.d.mts +4 -0
  17. package/dist/lib/v2/projection/catalog.d.ts +4 -0
  18. package/dist/lib/v2/projection/creative-delivery.d.mts +15 -9
  19. package/dist/lib/v2/projection/creative-delivery.d.ts +15 -9
  20. package/dist/lib/v2/projection/creative-delivery.js +71 -10
  21. package/dist/lib/v2/projection/creative-delivery.mjs +71 -10
  22. package/dist/lib/version.d.mts +3 -3
  23. package/dist/lib/version.d.ts +3 -3
  24. package/dist/lib/version.js +3 -3
  25. package/dist/lib/version.mjs +3 -3
  26. package/docs/TYPE-SUMMARY.md +1 -1
  27. package/docs/guides/CREATIVE-DELIVERY.md +18 -1
  28. package/docs/guides/REPORTING-STABILITY.md +7 -7
  29. package/docs/llms.txt +2 -2
  30. package/docs/migration-14.x-rc-worksheet.md +4 -4
  31. package/docs/migration-agent-identity-3.3.md +44 -19
  32. package/docs/migration-reporting-storage-package.md +3 -3
  33. package/docs/releases/16.0.0.md +20 -0
  34. package/package.json +1 -1
@@ -26,8 +26,9 @@ const WEB_BOT_AUTH_PROFILE = "web-bot-auth";
26
26
  const WEB_BOT_AUTH_DRAFT_REVISION = "draft-ietf-webbotauth-httpsig-protocol-00";
27
27
  const SIGNATURE_DIRECTORY_PATH = "/.well-known/http-message-signatures-directory";
28
28
  const SIGNATURE_DIRECTORY_MEDIA_TYPE = "application/http-message-signatures-directory+json";
29
- const WEB_BOT_AUTH_ALGORITHMS = Object.freeze(["ed25519", "rsa-pss-sha512"]);
29
+ const WEB_BOT_AUTH_ALGORITHMS = Object.freeze(["ed25519"]);
30
30
  const DIRECTORY_TAG = "http-message-signatures-directory";
31
+ const PRIVATE_JWK_MEMBERS = /* @__PURE__ */ new Set(["d", "p", "q", "dp", "dq", "qi", "oth", "k"]);
31
32
  const CLOCK_SKEW_SECONDS = 60;
32
33
  const MAX_LIFETIME_SECONDS = 300;
33
34
  const REQUIRED_PARAMETERS = ["created", "expires", "nonce", "keyid", "alg", "tag"];
@@ -138,26 +139,29 @@ function jwkThumbprint(jwk) {
138
139
  else return denied("unsupported_key");
139
140
  return createHash("sha256").update(JSON.stringify(fields)).digest("base64url");
140
141
  }
142
+ function keyAlgorithm(jwk) {
143
+ return jwk.kty === "OKP" && jwk.crv === "Ed25519" ? "ed25519" : void 0;
144
+ }
141
145
  function algorithm(jwk) {
142
- if (jwk.kty === "OKP" && jwk.crv === "Ed25519") return "ed25519";
143
- if (jwk.kty === "RSA" && typeof jwk.n === "string" && jwk.e === "AQAB") {
144
- const bytes = Buffer.from(jwk.n, "base64url").length;
145
- if (bytes >= 256 && bytes <= 512) return "rsa-pss-sha512";
146
- }
147
- return denied("unsupported_key");
146
+ return keyAlgorithm(jwk) ?? denied("unsupported_key");
148
147
  }
149
148
  function signingAlgorithm(jwk) {
150
149
  try {
151
150
  return algorithm(jwk);
152
151
  } catch {
153
- throw new TypeError(
154
- "Web Bot Auth signs with Ed25519 or RSA-PSS-SHA512 (2048-4096 bit, e=65537) keys only; ES256 remains on the AdCP RFC 9421 profile"
155
- );
152
+ throw new TypeError("Web Bot Auth signs with Ed25519 keys only; ES256 remains on the AdCP RFC 9421 profile");
156
153
  }
157
154
  }
158
155
  function assertWebBotAuthSigningKey(key) {
159
156
  signingAlgorithm("privateKey" in key ? key.privateKey : key.publicKey);
160
157
  }
158
+ function signingOrigin(value) {
159
+ try {
160
+ return receivedAgentOrigin(canonicalAgentOrigin(value));
161
+ } catch {
162
+ throw new TypeError("Web Bot Auth signs as an https origin only (WBA section 5.2.1)");
163
+ }
164
+ }
161
165
  function inputs(headers, limit) {
162
166
  const members = dictionary(getHeaderValue(headers, "signature-input"), "Signature-Input");
163
167
  if (members.size > limit) bad("signature_input");
@@ -170,6 +174,7 @@ function inputs(headers, limit) {
170
174
  });
171
175
  }
172
176
  function receivedAgentOrigin(value) {
177
+ if (!value.startsWith("https://")) return denied("agent_origin");
173
178
  try {
174
179
  canonicalAgentUrl(value);
175
180
  const origin = canonicalAgentOrigin(value);
@@ -392,8 +397,10 @@ async function verifyWebBotAuth(request, options) {
392
397
  if (!(member2[0] instanceof ArrayBuffer) || member2[1].size !== 0) bad("signature");
393
398
  for (const member2 of agents?.values() ?? []) if (typeof member2[0] !== "string") bad("signature_agent");
394
399
  if (!inputMembers || !signatureMembers) return denied("headers_missing");
395
- if (inputMembers.size !== 1 || signatureMembers.size !== 1) denied("signature_count");
396
- label = inputMembers.keys().next().value;
400
+ const tagged = [...inputMembers].filter(([, member2]) => member2[1].get("tag") === WEB_BOT_AUTH_PROFILE);
401
+ if (tagged.length === 0) denied("profile");
402
+ if (tagged.length > 1) denied("signature_count");
403
+ label = tagged[0][0];
397
404
  if (!signatureMembers.has(label)) denied("signature_label");
398
405
  try {
399
406
  parseSignature(signatureHeader, label, "rfc8941-base64");
@@ -406,7 +413,6 @@ async function verifyWebBotAuth(request, options) {
406
413
  } catch {
407
414
  return denied("parameters");
408
415
  }
409
- if (input.params.tag !== WEB_BOT_AUTH_PROFILE) denied("profile");
410
416
  if (!agents || agents.size !== 1) denied(agents ? "agent_count" : "agent_missing");
411
417
  const agentMember = `signature-agent;key="${label}"`;
412
418
  const agentComponents = input.components.filter((c) => c.startsWith("signature-agent;"));
@@ -414,7 +420,7 @@ async function verifyWebBotAuth(request, options) {
414
420
  const member = agents.get(label);
415
421
  if (!member) denied("agent_not_covered");
416
422
  const type = member[1].get("type");
417
- if (type !== void 0 && type !== "directory") denied("agent_type");
423
+ if (type !== void 0 && String(type) !== "directory") denied("agent_type");
418
424
  const origin = receivedAgentOrigin(member[0]);
419
425
  const { created, expires, nonce, keyid, alg } = input.params;
420
426
  if ([created, expires, nonce, keyid, alg].some((value) => value === void 0)) denied("parameters_missing");
@@ -538,11 +544,13 @@ async function verifyKeyDirectory(response, now = Date.now() / 1e3, options = {}
538
544
  let expires = Infinity;
539
545
  for (const raw of document.keys) {
540
546
  if (!raw || typeof raw !== "object") denied("directory_key");
547
+ if (Object.keys(raw).some((k) => PRIVATE_JWK_MEMBERS.has(k.toLowerCase()) || k.startsWith("_private")))
548
+ denied("directory_key");
549
+ if (!keyAlgorithm(raw)) continue;
541
550
  const thumbprint = jwkThumbprint(raw);
542
551
  const key = { ...raw, kid: raw.kid ?? thumbprint };
543
- if (key.kid !== thumbprint || kids.has(key.kid) || key.d !== void 0 || Object.keys(key).some((k) => k.startsWith("_private")) || key.adcp_use !== void 0 || !testKeysAllowed(options.allowTestKeys) && TEST_KIDS.has(key.kid))
552
+ if (key.kid !== thumbprint || kids.has(key.kid) || key.adcp_use !== void 0 || !testKeysAllowed(options.allowTestKeys) && TEST_KIDS.has(key.kid))
544
553
  denied("directory_key");
545
- algorithm(key);
546
554
  kids.add(key.kid);
547
555
  keys.push(key);
548
556
  const proof = signatures.find((input) => input.params.keyid === key.kid && input.params.tag === DIRECTORY_TAG);
@@ -585,6 +593,7 @@ async function verifyKeyDirectory(response, now = Date.now() / 1e3, options = {}
585
593
  );
586
594
  expires = Math.min(expires, proof.params.expires);
587
595
  }
596
+ if (!keys.length) denied("directory_keys");
588
597
  return { keys, expires, signed: true, proof: response };
589
598
  } catch (error) {
590
599
  if (error instanceof WebBotAuthError) {
@@ -714,7 +723,7 @@ async function signWebBotAuth(request, key, options) {
714
723
  throw new TypeError(
715
724
  "Web Bot Auth relays were removed from the profile (adcp#7894): an intermediary signs as itself with one signature"
716
725
  );
717
- const origin = canonicalAgentOrigin(options.origin);
726
+ const origin = signingOrigin(options.origin);
718
727
  const label = options.label ?? "sig1";
719
728
  if (!/^[a-z][a-z0-9_.*-]*$/.test(label)) throw new TypeError("Invalid signature label");
720
729
  const jwk = "privateKey" in key ? key.privateKey : key.publicKey;
@@ -769,7 +778,7 @@ async function signWebBotAuth(request, key, options) {
769
778
  return headers;
770
779
  }
771
780
  async function createSignedSignatureDirectory(originUrl, signingKeys, options = {}) {
772
- const origin = canonicalAgentOrigin(originUrl);
781
+ const origin = signingOrigin(originUrl);
773
782
  const now = Math.floor((options.now ?? (() => Date.now() / 1e3))());
774
783
  const lifetime = options.lifetimeSeconds ?? 86400;
775
784
  if (!Number.isFinite(now) || !Number.isSafeInteger(lifetime) || lifetime < 1 || !Number.isSafeInteger(now + lifetime))
@@ -778,12 +787,7 @@ async function createSignedSignatureDirectory(originUrl, signingKeys, options =
778
787
  const keys = signingKeys.map((key) => {
779
788
  const jwk = "privateKey" in key ? key.privateKey : key.publicKey;
780
789
  signingAlgorithm(jwk);
781
- return {
782
- kty: jwk.kty,
783
- ...jwk.kty === "RSA" ? { n: jwk.n, e: jwk.e } : { crv: jwk.crv, x: jwk.x },
784
- kid: jwkThumbprint(jwk),
785
- use: "sig"
786
- };
790
+ return { kty: jwk.kty, crv: jwk.crv, x: jwk.x, kid: jwkThumbprint(jwk), use: "sig" };
787
791
  });
788
792
  if (new Set(keys.map((k) => k.kid)).size !== keys.length) throw new TypeError("Duplicate directory key");
789
793
  const body = JSON.stringify({ keys });
@@ -829,6 +833,7 @@ async function createSignedSignatureDirectory(originUrl, signingKeys, options =
829
833
  }
830
834
  function createWebBotAuthFetch(upstream, key, options) {
831
835
  assertWebBotAuthSigningKey(key);
836
+ signingOrigin(options.origin);
832
837
  return async (input, init) => {
833
838
  const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
834
839
  if (options.shouldSign && !options.shouldSign(url, init)) return upstream(input, init);
@@ -197,7 +197,7 @@ export interface UpstreamTrafficQueryResult {
197
197
  */
198
198
  export declare function runValidations(validations: StoryboardValidation[], context: ValidationContext): ValidationResult[];
199
199
  /** Capability semver emitted in run summaries and used for advisory expiry. */
200
- export declare const RUNNER_CAPABILITY_VERSION = "16.0.0-beta.9";
200
+ export declare const RUNNER_CAPABILITY_VERSION = "16.0.0";
201
201
  /** True when a failed validation contributes to the owning step's grade. */
202
202
  export declare function validationFailsStep(result: ValidationResult): boolean;
203
203
  /**
@@ -197,7 +197,7 @@ export interface UpstreamTrafficQueryResult {
197
197
  */
198
198
  export declare function runValidations(validations: StoryboardValidation[], context: ValidationContext): ValidationResult[];
199
199
  /** Capability semver emitted in run summaries and used for advisory expiry. */
200
- export declare const RUNNER_CAPABILITY_VERSION = "16.0.0-beta.9";
200
+ export declare const RUNNER_CAPABILITY_VERSION = "16.0.0";
201
201
  /** True when a failed validation contributes to the owning step's grade. */
202
202
  export declare function validationFailsStep(result: ValidationResult): boolean;
203
203
  /**
@@ -70,6 +70,10 @@ export interface V1FormatDefinition {
70
70
  required?: boolean;
71
71
  asset_type?: string;
72
72
  requirements?: Record<string, unknown>;
73
+ /** Reference-catalog extension used to match pixel-tracker slots. */
74
+ event?: string;
75
+ /** Caller-defined tracker extension; required to match a custom event. */
76
+ custom_event_name?: string;
73
77
  }>;
74
78
  /**
75
79
  * v2 canonical projection. Always object-shaped per
@@ -70,6 +70,10 @@ export interface V1FormatDefinition {
70
70
  required?: boolean;
71
71
  asset_type?: string;
72
72
  requirements?: Record<string, unknown>;
73
+ /** Reference-catalog extension used to match pixel-tracker slots. */
74
+ event?: string;
75
+ /** Caller-defined tracker extension; required to match a custom event. */
76
+ custom_event_name?: string;
73
77
  }>;
74
78
  /**
75
79
  * v2 canonical projection. Always object-shaped per
@@ -4,6 +4,7 @@ import type { CanonicalFormatLegacyResolver } from './v2-to-v1.mjs';
4
4
  import type { CanonicalFormatKind, ProjectionDiagnostic, V1FormatId } from './types.mjs';
5
5
  import type { CanonicalFormatDeclaration } from './legacy-metadata.mjs';
6
6
  import type { UndeclaredFormatOptionSelector } from './legacy-routes.mjs';
7
+ import { type V1FormatDefinition } from './catalog.mjs';
7
8
  type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, Extract<keyof T, K>> : never;
8
9
  /**
9
10
  * Primary SDK creative shape. Spell out the named fields rather than using
@@ -276,15 +277,20 @@ export declare class CreativeFormatCapabilityError extends Error {
276
277
  readonly code = "ADCP_CREATIVE_FORMAT_CAPABILITY_CONTRADICTION";
277
278
  constructor(message: string);
278
279
  }
279
- export declare function projectCreativeForDelivery<T extends CreativeAsset>(creative: T, selectorContainer: CreativeFormatSelectorContainer, wireMode?: 'canonical', operation?: string, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): CanonicalProjectedCreative<T>;
280
- export declare function projectCreativeForDelivery<T extends CreativeAsset>(creative: T, selectorContainer: CreativeFormatSelectorContainer, wireMode: 'legacy' | 'unknown', operation?: string, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): LegacyProjectedCreative<T>;
281
- export declare function projectCreativeForDelivery<T extends CreativeAsset>(creative: T, selectorContainer: CreativeFormatSelectorContainer, wireMode: CreativeFormatWireMode, operation?: string, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): CanonicalProjectedCreative<T> | LegacyProjectedCreative<T>;
282
- export declare function projectMediaBuyCreativesForDelivery<T>(request: T, wireMode: 'canonical', operation?: 'create_media_buy' | 'update_media_buy', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): ProjectedMediaBuyCreativeRequest<T, 'canonical'>;
283
- export declare function projectMediaBuyCreativesForDelivery<T>(request: T, wireMode: 'legacy' | 'unknown', operation?: 'create_media_buy' | 'update_media_buy', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): ProjectedMediaBuyCreativeRequest<T, 'legacy'>;
284
- export declare function projectMediaBuyCreativesForDelivery<T>(request: T, wireMode: CreativeFormatWireMode, operation?: 'create_media_buy' | 'update_media_buy', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): ProjectedMediaBuyCreativeRequest<T, 'canonical'> | ProjectedMediaBuyCreativeRequest<T, 'legacy'>;
285
- export declare function projectSyncCreativesForDelivery<T>(request: T, selectorContainers: ReadonlyArray<CreativeFormatSelectorContainer>, wireMode: 'canonical', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): ProjectedSyncCreativeRequest<T, 'canonical'>;
286
- export declare function projectSyncCreativesForDelivery<T>(request: T, selectorContainers: ReadonlyArray<CreativeFormatSelectorContainer>, wireMode: 'legacy' | 'unknown', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): ProjectedSyncCreativeRequest<T, 'legacy'>;
287
- export declare function projectSyncCreativesForDelivery<T>(request: T, selectorContainers: ReadonlyArray<CreativeFormatSelectorContainer>, wireMode: CreativeFormatWireMode, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): ProjectedSyncCreativeRequest<T, 'canonical'> | ProjectedSyncCreativeRequest<T, 'legacy'>;
280
+ /**
281
+ * Project identity and asset keys for the selected wire mode. Optional
282
+ * `legacyFormatDefinitions` override bundled definitions by exact format owner
283
+ * and ID; ambiguous definitions leave asset keys unchanged.
284
+ */
285
+ export declare function projectCreativeForDelivery<T extends CreativeAsset>(creative: T, selectorContainer: CreativeFormatSelectorContainer, wireMode?: 'canonical', operation?: string, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): CanonicalProjectedCreative<T>;
286
+ export declare function projectCreativeForDelivery<T extends CreativeAsset>(creative: T, selectorContainer: CreativeFormatSelectorContainer, wireMode: 'legacy' | 'unknown', operation?: string, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): LegacyProjectedCreative<T>;
287
+ export declare function projectCreativeForDelivery<T extends CreativeAsset>(creative: T, selectorContainer: CreativeFormatSelectorContainer, wireMode: CreativeFormatWireMode, operation?: string, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): CanonicalProjectedCreative<T> | LegacyProjectedCreative<T>;
288
+ export declare function projectMediaBuyCreativesForDelivery<T>(request: T, wireMode: 'canonical', operation?: 'create_media_buy' | 'update_media_buy', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): ProjectedMediaBuyCreativeRequest<T, 'canonical'>;
289
+ export declare function projectMediaBuyCreativesForDelivery<T>(request: T, wireMode: 'legacy' | 'unknown', operation?: 'create_media_buy' | 'update_media_buy', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): ProjectedMediaBuyCreativeRequest<T, 'legacy'>;
290
+ export declare function projectMediaBuyCreativesForDelivery<T>(request: T, wireMode: CreativeFormatWireMode, operation?: 'create_media_buy' | 'update_media_buy', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): ProjectedMediaBuyCreativeRequest<T, 'canonical'> | ProjectedMediaBuyCreativeRequest<T, 'legacy'>;
291
+ export declare function projectSyncCreativesForDelivery<T>(request: T, selectorContainers: ReadonlyArray<CreativeFormatSelectorContainer>, wireMode: 'canonical', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): ProjectedSyncCreativeRequest<T, 'canonical'>;
292
+ export declare function projectSyncCreativesForDelivery<T>(request: T, selectorContainers: ReadonlyArray<CreativeFormatSelectorContainer>, wireMode: 'legacy' | 'unknown', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): ProjectedSyncCreativeRequest<T, 'legacy'>;
293
+ export declare function projectSyncCreativesForDelivery<T>(request: T, selectorContainers: ReadonlyArray<CreativeFormatSelectorContainer>, wireMode: CreativeFormatWireMode, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): ProjectedSyncCreativeRequest<T, 'canonical'> | ProjectedSyncCreativeRequest<T, 'legacy'>;
288
294
  export type { UndeclaredFormatOptionSelector } from './legacy-routes.mjs';
289
295
  /**
290
296
  * Looks up a format option the SDK derived from a seller's legacy `format_ids`.
@@ -4,6 +4,7 @@ import type { CanonicalFormatLegacyResolver } from './v2-to-v1';
4
4
  import type { CanonicalFormatKind, ProjectionDiagnostic, V1FormatId } from './types';
5
5
  import type { CanonicalFormatDeclaration } from './legacy-metadata';
6
6
  import type { UndeclaredFormatOptionSelector } from './legacy-routes';
7
+ import { type V1FormatDefinition } from './catalog';
7
8
  type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, Extract<keyof T, K>> : never;
8
9
  /**
9
10
  * Primary SDK creative shape. Spell out the named fields rather than using
@@ -276,15 +277,20 @@ export declare class CreativeFormatCapabilityError extends Error {
276
277
  readonly code = "ADCP_CREATIVE_FORMAT_CAPABILITY_CONTRADICTION";
277
278
  constructor(message: string);
278
279
  }
279
- export declare function projectCreativeForDelivery<T extends CreativeAsset>(creative: T, selectorContainer: CreativeFormatSelectorContainer, wireMode?: 'canonical', operation?: string, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): CanonicalProjectedCreative<T>;
280
- export declare function projectCreativeForDelivery<T extends CreativeAsset>(creative: T, selectorContainer: CreativeFormatSelectorContainer, wireMode: 'legacy' | 'unknown', operation?: string, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): LegacyProjectedCreative<T>;
281
- export declare function projectCreativeForDelivery<T extends CreativeAsset>(creative: T, selectorContainer: CreativeFormatSelectorContainer, wireMode: CreativeFormatWireMode, operation?: string, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): CanonicalProjectedCreative<T> | LegacyProjectedCreative<T>;
282
- export declare function projectMediaBuyCreativesForDelivery<T>(request: T, wireMode: 'canonical', operation?: 'create_media_buy' | 'update_media_buy', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): ProjectedMediaBuyCreativeRequest<T, 'canonical'>;
283
- export declare function projectMediaBuyCreativesForDelivery<T>(request: T, wireMode: 'legacy' | 'unknown', operation?: 'create_media_buy' | 'update_media_buy', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): ProjectedMediaBuyCreativeRequest<T, 'legacy'>;
284
- export declare function projectMediaBuyCreativesForDelivery<T>(request: T, wireMode: CreativeFormatWireMode, operation?: 'create_media_buy' | 'update_media_buy', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): ProjectedMediaBuyCreativeRequest<T, 'canonical'> | ProjectedMediaBuyCreativeRequest<T, 'legacy'>;
285
- export declare function projectSyncCreativesForDelivery<T>(request: T, selectorContainers: ReadonlyArray<CreativeFormatSelectorContainer>, wireMode: 'canonical', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): ProjectedSyncCreativeRequest<T, 'canonical'>;
286
- export declare function projectSyncCreativesForDelivery<T>(request: T, selectorContainers: ReadonlyArray<CreativeFormatSelectorContainer>, wireMode: 'legacy' | 'unknown', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): ProjectedSyncCreativeRequest<T, 'legacy'>;
287
- export declare function projectSyncCreativesForDelivery<T>(request: T, selectorContainers: ReadonlyArray<CreativeFormatSelectorContainer>, wireMode: CreativeFormatWireMode, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver): ProjectedSyncCreativeRequest<T, 'canonical'> | ProjectedSyncCreativeRequest<T, 'legacy'>;
280
+ /**
281
+ * Project identity and asset keys for the selected wire mode. Optional
282
+ * `legacyFormatDefinitions` override bundled definitions by exact format owner
283
+ * and ID; ambiguous definitions leave asset keys unchanged.
284
+ */
285
+ export declare function projectCreativeForDelivery<T extends CreativeAsset>(creative: T, selectorContainer: CreativeFormatSelectorContainer, wireMode?: 'canonical', operation?: string, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): CanonicalProjectedCreative<T>;
286
+ export declare function projectCreativeForDelivery<T extends CreativeAsset>(creative: T, selectorContainer: CreativeFormatSelectorContainer, wireMode: 'legacy' | 'unknown', operation?: string, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): LegacyProjectedCreative<T>;
287
+ export declare function projectCreativeForDelivery<T extends CreativeAsset>(creative: T, selectorContainer: CreativeFormatSelectorContainer, wireMode: CreativeFormatWireMode, operation?: string, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): CanonicalProjectedCreative<T> | LegacyProjectedCreative<T>;
288
+ export declare function projectMediaBuyCreativesForDelivery<T>(request: T, wireMode: 'canonical', operation?: 'create_media_buy' | 'update_media_buy', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): ProjectedMediaBuyCreativeRequest<T, 'canonical'>;
289
+ export declare function projectMediaBuyCreativesForDelivery<T>(request: T, wireMode: 'legacy' | 'unknown', operation?: 'create_media_buy' | 'update_media_buy', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): ProjectedMediaBuyCreativeRequest<T, 'legacy'>;
290
+ export declare function projectMediaBuyCreativesForDelivery<T>(request: T, wireMode: CreativeFormatWireMode, operation?: 'create_media_buy' | 'update_media_buy', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): ProjectedMediaBuyCreativeRequest<T, 'canonical'> | ProjectedMediaBuyCreativeRequest<T, 'legacy'>;
291
+ export declare function projectSyncCreativesForDelivery<T>(request: T, selectorContainers: ReadonlyArray<CreativeFormatSelectorContainer>, wireMode: 'canonical', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): ProjectedSyncCreativeRequest<T, 'canonical'>;
292
+ export declare function projectSyncCreativesForDelivery<T>(request: T, selectorContainers: ReadonlyArray<CreativeFormatSelectorContainer>, wireMode: 'legacy' | 'unknown', legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): ProjectedSyncCreativeRequest<T, 'legacy'>;
293
+ export declare function projectSyncCreativesForDelivery<T>(request: T, selectorContainers: ReadonlyArray<CreativeFormatSelectorContainer>, wireMode: CreativeFormatWireMode, legacyFormatConverter?: LegacyFormatConverter, canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver, legacyFormatDefinitions?: readonly V1FormatDefinition[]): ProjectedSyncCreativeRequest<T, 'canonical'> | ProjectedSyncCreativeRequest<T, 'legacy'>;
288
294
  export type { UndeclaredFormatOptionSelector } from './legacy-routes';
289
295
  /**
290
296
  * Looks up a format option the SDK derived from a seller's legacy `format_ids`.
@@ -33,6 +33,7 @@ var import_v1_to_v2 = require('./v1-to-v2.js');
33
33
  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
+ var import_catalog = require('./catalog.js');
36
37
  function stripLegacyCreativeIdentity(value) {
37
38
  const legacyTokens = /* @__PURE__ */ new Set();
38
39
  const legacyUrlTokens = /* @__PURE__ */ new Set();
@@ -591,11 +592,55 @@ function selectLegacyRef(creative, container, canonicalFormatLegacyResolver, ope
591
592
  matching = preferMostConstrainedLegacyCandidates(matching, creative);
592
593
  return matching.length === 1 ? matching[0].ref : void 0;
593
594
  }
594
- function projectCreative(creative, formatId) {
595
+ function projectLegacyAssetKeys(assetsValue, definition) {
596
+ const assets = record(assetsValue);
597
+ if (!assets || !Array.isArray(definition?.assets)) return assetsValue;
598
+ 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 assetsValue;
600
+ const declaredIds = new Set(slots.map((slot) => slot.asset_id));
601
+ const availableSlots = slots.filter(
602
+ (slot) => (slot.item_type === void 0 || slot.item_type === "individual") && typeof slot.asset_id === "string" && slot.asset_id.length > 0 && !Object.hasOwn(assets, slot.asset_id)
603
+ );
604
+ const targetBySource = /* @__PURE__ */ new Map();
605
+ const sourcesByTarget = /* @__PURE__ */ new Map();
606
+ for (const [key, value] of Object.entries(assets)) {
607
+ if (declaredIds.has(key)) continue;
608
+ const asset = record(value);
609
+ if (!asset || typeof asset.asset_type !== "string") continue;
610
+ const matches = availableSlots.filter((slot) => {
611
+ if (slot.asset_type !== asset.asset_type) return false;
612
+ if (asset.asset_type === "url") {
613
+ return typeof asset.url_type === "string" && asset.url_type === slot.requirements?.url_type;
614
+ }
615
+ if (asset.asset_type === "pixel_tracker") {
616
+ return typeof asset.event === "string" && asset.event === slot.event && (asset.event !== "custom" || typeof asset.custom_event_name === "string" && asset.custom_event_name === slot.custom_event_name);
617
+ }
618
+ return true;
619
+ });
620
+ if (matches.length !== 1) continue;
621
+ const target = matches[0].asset_id;
622
+ targetBySource.set(key, target);
623
+ const sources = sourcesByTarget.get(target) ?? [];
624
+ sources.push(key);
625
+ sourcesByTarget.set(target, sources);
626
+ }
627
+ for (const sources of sourcesByTarget.values()) {
628
+ if (sources.length > 1) for (const source of sources) targetBySource.delete(source);
629
+ }
630
+ if (targetBySource.size === 0) return assetsValue;
631
+ return Object.fromEntries(Object.entries(assets).map(([key, value]) => [targetBySource.get(key) ?? key, value]));
632
+ }
633
+ function projectCreative(creative, formatId, legacyFormatDefinitions) {
595
634
  const next = { ...creative };
596
635
  delete next.format_kind;
597
636
  delete next.format_option_ref;
598
637
  next.format_id = { ...formatId };
638
+ const supplied = legacyFormatDefinitions?.filter((definition2) => {
639
+ const ref = legacyRef(record(definition2)?.format_id);
640
+ return ref !== void 0 && sameLegacyIdentity(ref, formatId);
641
+ });
642
+ const definition = supplied?.length ? supplied.length === 1 ? supplied[0] : void 0 : (0, import_catalog.lookupV1Format)(formatId);
643
+ if (Object.hasOwn(creative, "assets")) next.assets = projectLegacyAssetKeys(creative.assets, definition);
599
644
  return next;
600
645
  }
601
646
  function dedupeLegacyRefs(refs) {
@@ -829,7 +874,7 @@ function canonicalizeCreative(creative, selectorContainer, operation, legacyForm
829
874
  }
830
875
  return next;
831
876
  }
832
- function projectCreativeForDelivery(creative, selectorContainer, wireMode = "canonical", operation = "creative_delivery", legacyFormatConverter, canonicalFormatLegacyResolver) {
877
+ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "canonical", operation = "creative_delivery", legacyFormatConverter, canonicalFormatLegacyResolver, legacyFormatDefinitions) {
833
878
  const inputRecord = creative;
834
879
  const originalLegacyRef = legacyRef(inputRecord.format_id);
835
880
  const creativeRecord = canonicalizeCreative(inputRecord, selectorContainer, operation, legacyFormatConverter);
@@ -837,7 +882,11 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
837
882
  if (originalLegacyRef) {
838
883
  const selectedOriginal = selectLegacyRef(inputRecord, selectorContainer, canonicalFormatLegacyResolver, operation);
839
884
  if (selectedOriginal) {
840
- return projectCreative(creativeRecord, selectedOriginal);
885
+ return projectCreative(
886
+ creativeRecord,
887
+ selectedOriginal,
888
+ legacyFormatDefinitions
889
+ );
841
890
  }
842
891
  throw new CreativeFormatProjectionError(
843
892
  operation,
@@ -846,7 +895,8 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
846
895
  );
847
896
  }
848
897
  const formatId = selectLegacyRef(creativeRecord, selectorContainer, canonicalFormatLegacyResolver, operation);
849
- if (formatId) return projectCreative(creativeRecord, formatId);
898
+ if (formatId)
899
+ return projectCreative(creativeRecord, formatId, legacyFormatDefinitions);
850
900
  if (typeof creativeRecord.format_kind === "string") {
851
901
  const creativeId = typeof creativeRecord.creative_id === "string" ? creativeRecord.creative_id : "(unknown)";
852
902
  const allCandidates = candidatesFromContainer(selectorContainer, canonicalFormatLegacyResolver, operation);
@@ -881,10 +931,19 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
881
931
  "canonical format legacy resolver returned an invalid or ambiguous creative mapping"
882
932
  );
883
933
  }
884
- if (resolved) return projectCreative(creativeRecord, resolved[0]);
934
+ if (resolved)
935
+ return projectCreative(
936
+ creativeRecord,
937
+ resolved[0],
938
+ legacyFormatDefinitions
939
+ );
885
940
  const pinned = optionReference(creativeRecord.format_option_ref) !== void 0;
886
941
  if (candidates.length === 1 && !pinned) {
887
- return projectCreative(creativeRecord, candidates[0].ref);
942
+ return projectCreative(
943
+ creativeRecord,
944
+ candidates[0].ref,
945
+ legacyFormatDefinitions
946
+ );
888
947
  }
889
948
  if (candidates.length > 1) {
890
949
  throw new CreativeFormatProjectionError(
@@ -898,7 +957,7 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
898
957
  }
899
958
  return creative;
900
959
  }
901
- function projectMediaBuyCreativesForDelivery(request, wireMode = "canonical", operation = "create_media_buy", legacyFormatConverter, canonicalFormatLegacyResolver) {
960
+ function projectMediaBuyCreativesForDelivery(request, wireMode = "canonical", operation = "create_media_buy", legacyFormatConverter, canonicalFormatLegacyResolver, legacyFormatDefinitions) {
902
961
  const requestRecord = record(request);
903
962
  if (!requestRecord) return request;
904
963
  let changed = false;
@@ -918,7 +977,8 @@ function projectMediaBuyCreativesForDelivery(request, wireMode = "canonical", op
918
977
  wireMode,
919
978
  operation,
920
979
  legacyFormatConverter,
921
- canonicalFormatLegacyResolver
980
+ canonicalFormatLegacyResolver,
981
+ legacyFormatDefinitions
922
982
  );
923
983
  if (projected !== creativeValue) changed = true;
924
984
  return projected;
@@ -936,7 +996,7 @@ function projectMediaBuyCreativesForDelivery(request, wireMode = "canonical", op
936
996
  }
937
997
  return changed ? next : request;
938
998
  }
939
- function projectSyncCreativesForDelivery(request, selectorContainers, wireMode = "canonical", legacyFormatConverter, canonicalFormatLegacyResolver) {
999
+ function projectSyncCreativesForDelivery(request, selectorContainers, wireMode = "canonical", legacyFormatConverter, canonicalFormatLegacyResolver, legacyFormatDefinitions) {
940
1000
  const requestRecord = record(request);
941
1001
  if (!requestRecord || !Array.isArray(requestRecord.creatives)) {
942
1002
  return request;
@@ -965,7 +1025,8 @@ function projectSyncCreativesForDelivery(request, selectorContainers, wireMode =
965
1025
  wireMode,
966
1026
  "sync_creatives",
967
1027
  legacyFormatConverter,
968
- canonicalFormatLegacyResolver
1028
+ canonicalFormatLegacyResolver,
1029
+ legacyFormatDefinitions
969
1030
  );
970
1031
  if (projected !== creativeValue) changed = true;
971
1032
  return projected;
@@ -12,6 +12,7 @@ import {
12
12
  transferLegacyCreativeMetadata
13
13
  } from "./legacy-metadata.mjs";
14
14
  import { canonicalize as canonicalizeJson } from "../../utils/jcs.mjs";
15
+ import { lookupV1Format } from "./catalog.mjs";
15
16
  function stripLegacyCreativeIdentity(value) {
16
17
  const legacyTokens = /* @__PURE__ */ new Set();
17
18
  const legacyUrlTokens = /* @__PURE__ */ new Set();
@@ -570,11 +571,55 @@ function selectLegacyRef(creative, container, canonicalFormatLegacyResolver, ope
570
571
  matching = preferMostConstrainedLegacyCandidates(matching, creative);
571
572
  return matching.length === 1 ? matching[0].ref : void 0;
572
573
  }
573
- function projectCreative(creative, formatId) {
574
+ function projectLegacyAssetKeys(assetsValue, definition) {
575
+ const assets = record(assetsValue);
576
+ if (!assets || !Array.isArray(definition?.assets)) return assetsValue;
577
+ 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 assetsValue;
579
+ const declaredIds = new Set(slots.map((slot) => slot.asset_id));
580
+ const availableSlots = slots.filter(
581
+ (slot) => (slot.item_type === void 0 || slot.item_type === "individual") && typeof slot.asset_id === "string" && slot.asset_id.length > 0 && !Object.hasOwn(assets, slot.asset_id)
582
+ );
583
+ const targetBySource = /* @__PURE__ */ new Map();
584
+ const sourcesByTarget = /* @__PURE__ */ new Map();
585
+ for (const [key, value] of Object.entries(assets)) {
586
+ if (declaredIds.has(key)) continue;
587
+ const asset = record(value);
588
+ if (!asset || typeof asset.asset_type !== "string") continue;
589
+ const matches = availableSlots.filter((slot) => {
590
+ if (slot.asset_type !== asset.asset_type) return false;
591
+ if (asset.asset_type === "url") {
592
+ return typeof asset.url_type === "string" && asset.url_type === slot.requirements?.url_type;
593
+ }
594
+ if (asset.asset_type === "pixel_tracker") {
595
+ return typeof asset.event === "string" && asset.event === slot.event && (asset.event !== "custom" || typeof asset.custom_event_name === "string" && asset.custom_event_name === slot.custom_event_name);
596
+ }
597
+ return true;
598
+ });
599
+ if (matches.length !== 1) continue;
600
+ const target = matches[0].asset_id;
601
+ targetBySource.set(key, target);
602
+ const sources = sourcesByTarget.get(target) ?? [];
603
+ sources.push(key);
604
+ sourcesByTarget.set(target, sources);
605
+ }
606
+ for (const sources of sourcesByTarget.values()) {
607
+ if (sources.length > 1) for (const source of sources) targetBySource.delete(source);
608
+ }
609
+ if (targetBySource.size === 0) return assetsValue;
610
+ return Object.fromEntries(Object.entries(assets).map(([key, value]) => [targetBySource.get(key) ?? key, value]));
611
+ }
612
+ function projectCreative(creative, formatId, legacyFormatDefinitions) {
574
613
  const next = { ...creative };
575
614
  delete next.format_kind;
576
615
  delete next.format_option_ref;
577
616
  next.format_id = { ...formatId };
617
+ const supplied = legacyFormatDefinitions?.filter((definition2) => {
618
+ const ref = legacyRef(record(definition2)?.format_id);
619
+ return ref !== void 0 && sameLegacyIdentity(ref, formatId);
620
+ });
621
+ const definition = supplied?.length ? supplied.length === 1 ? supplied[0] : void 0 : lookupV1Format(formatId);
622
+ if (Object.hasOwn(creative, "assets")) next.assets = projectLegacyAssetKeys(creative.assets, definition);
578
623
  return next;
579
624
  }
580
625
  function dedupeLegacyRefs(refs) {
@@ -808,7 +853,7 @@ function canonicalizeCreative(creative, selectorContainer, operation, legacyForm
808
853
  }
809
854
  return next;
810
855
  }
811
- function projectCreativeForDelivery(creative, selectorContainer, wireMode = "canonical", operation = "creative_delivery", legacyFormatConverter, canonicalFormatLegacyResolver) {
856
+ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "canonical", operation = "creative_delivery", legacyFormatConverter, canonicalFormatLegacyResolver, legacyFormatDefinitions) {
812
857
  const inputRecord = creative;
813
858
  const originalLegacyRef = legacyRef(inputRecord.format_id);
814
859
  const creativeRecord = canonicalizeCreative(inputRecord, selectorContainer, operation, legacyFormatConverter);
@@ -816,7 +861,11 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
816
861
  if (originalLegacyRef) {
817
862
  const selectedOriginal = selectLegacyRef(inputRecord, selectorContainer, canonicalFormatLegacyResolver, operation);
818
863
  if (selectedOriginal) {
819
- return projectCreative(creativeRecord, selectedOriginal);
864
+ return projectCreative(
865
+ creativeRecord,
866
+ selectedOriginal,
867
+ legacyFormatDefinitions
868
+ );
820
869
  }
821
870
  throw new CreativeFormatProjectionError(
822
871
  operation,
@@ -825,7 +874,8 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
825
874
  );
826
875
  }
827
876
  const formatId = selectLegacyRef(creativeRecord, selectorContainer, canonicalFormatLegacyResolver, operation);
828
- if (formatId) return projectCreative(creativeRecord, formatId);
877
+ if (formatId)
878
+ return projectCreative(creativeRecord, formatId, legacyFormatDefinitions);
829
879
  if (typeof creativeRecord.format_kind === "string") {
830
880
  const creativeId = typeof creativeRecord.creative_id === "string" ? creativeRecord.creative_id : "(unknown)";
831
881
  const allCandidates = candidatesFromContainer(selectorContainer, canonicalFormatLegacyResolver, operation);
@@ -860,10 +910,19 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
860
910
  "canonical format legacy resolver returned an invalid or ambiguous creative mapping"
861
911
  );
862
912
  }
863
- if (resolved) return projectCreative(creativeRecord, resolved[0]);
913
+ if (resolved)
914
+ return projectCreative(
915
+ creativeRecord,
916
+ resolved[0],
917
+ legacyFormatDefinitions
918
+ );
864
919
  const pinned = optionReference(creativeRecord.format_option_ref) !== void 0;
865
920
  if (candidates.length === 1 && !pinned) {
866
- return projectCreative(creativeRecord, candidates[0].ref);
921
+ return projectCreative(
922
+ creativeRecord,
923
+ candidates[0].ref,
924
+ legacyFormatDefinitions
925
+ );
867
926
  }
868
927
  if (candidates.length > 1) {
869
928
  throw new CreativeFormatProjectionError(
@@ -877,7 +936,7 @@ function projectCreativeForDelivery(creative, selectorContainer, wireMode = "can
877
936
  }
878
937
  return creative;
879
938
  }
880
- function projectMediaBuyCreativesForDelivery(request, wireMode = "canonical", operation = "create_media_buy", legacyFormatConverter, canonicalFormatLegacyResolver) {
939
+ function projectMediaBuyCreativesForDelivery(request, wireMode = "canonical", operation = "create_media_buy", legacyFormatConverter, canonicalFormatLegacyResolver, legacyFormatDefinitions) {
881
940
  const requestRecord = record(request);
882
941
  if (!requestRecord) return request;
883
942
  let changed = false;
@@ -897,7 +956,8 @@ function projectMediaBuyCreativesForDelivery(request, wireMode = "canonical", op
897
956
  wireMode,
898
957
  operation,
899
958
  legacyFormatConverter,
900
- canonicalFormatLegacyResolver
959
+ canonicalFormatLegacyResolver,
960
+ legacyFormatDefinitions
901
961
  );
902
962
  if (projected !== creativeValue) changed = true;
903
963
  return projected;
@@ -915,7 +975,7 @@ function projectMediaBuyCreativesForDelivery(request, wireMode = "canonical", op
915
975
  }
916
976
  return changed ? next : request;
917
977
  }
918
- function projectSyncCreativesForDelivery(request, selectorContainers, wireMode = "canonical", legacyFormatConverter, canonicalFormatLegacyResolver) {
978
+ function projectSyncCreativesForDelivery(request, selectorContainers, wireMode = "canonical", legacyFormatConverter, canonicalFormatLegacyResolver, legacyFormatDefinitions) {
919
979
  const requestRecord = record(request);
920
980
  if (!requestRecord || !Array.isArray(requestRecord.creatives)) {
921
981
  return request;
@@ -944,7 +1004,8 @@ function projectSyncCreativesForDelivery(request, selectorContainers, wireMode =
944
1004
  wireMode,
945
1005
  "sync_creatives",
946
1006
  legacyFormatConverter,
947
- canonicalFormatLegacyResolver
1007
+ canonicalFormatLegacyResolver,
1008
+ legacyFormatDefinitions
948
1009
  );
949
1010
  if (projected !== creativeValue) changed = true;
950
1011
  return projected;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AdCP SDK library version
3
3
  */
4
- export declare const LIBRARY_VERSION = "16.0.0-beta.9";
4
+ export declare const LIBRARY_VERSION = "16.0.0";
5
5
  /**
6
6
  * AdCP specification version this library is built for
7
7
  */
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
33
33
  * Full version information
34
34
  */
35
35
  export declare const VERSION_INFO: {
36
- readonly library: "16.0.0-beta.9";
36
+ readonly library: "16.0.0";
37
37
  readonly adcp: "3.2.5";
38
38
  readonly compatibleVersions: readonly ["v3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.0.13", "3.0.14", "3.0.15", "3.0.16", "3.0.17", "3.0.18", "3.0.19", "3.0.20", "3.0.21", "3.0.22", "3.0.23", "3.0.24", "3.0.25", "3.1.0", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.1.4", "3.1.5", "3.1.6", "3.1.7", "3.1.8", "3.1.9", "3.1.10", "3.1.11", "3.1.12", "3.1.13", "3.1.14", "3.1.15", "3.1.16", "3.1.17", "3.1.18", "3.1.19", "3.1.20", "3.1.21", "3.1.22", "3.1.23", "3.1.24", "3.1.25", "3.1.26", "3.1.27", "3.1.28", "3.1.29", "3.2.1", "3.2", "3.2.2", "3.2.3", "3.2.4", "3.2.5"];
39
- readonly generatedAt: "2026-10-19T19:41:05.601Z";
39
+ readonly generatedAt: "2026-10-19T23:27:30.750Z";
40
40
  };
41
41
  /**
42
42
  * Get the AdCP specification version this library is built for