@adcp/sdk 15.9.5 → 15.9.6

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 (44) hide show
  1. package/dist/lib/core/AgentClient.d.mts +4 -2
  2. package/dist/lib/core/AgentClient.d.ts +4 -2
  3. package/dist/lib/core/AgentClient.js +4 -2
  4. package/dist/lib/core/AgentClient.mjs +4 -2
  5. package/dist/lib/core/SingleAgentClient.d.mts +7 -3
  6. package/dist/lib/core/SingleAgentClient.d.ts +7 -3
  7. package/dist/lib/core/SingleAgentClient.js +204 -13
  8. package/dist/lib/core/SingleAgentClient.mjs +209 -13
  9. package/dist/lib/core/product-cache.d.mts +3 -1
  10. package/dist/lib/core/product-cache.d.ts +3 -1
  11. package/dist/lib/core/product-cache.js +2 -1
  12. package/dist/lib/core/product-cache.mjs +2 -1
  13. package/dist/lib/registry/types.d.mts +3 -2
  14. package/dist/lib/registry/types.d.ts +3 -2
  15. package/dist/lib/registry/types.generated.d.mts +21 -9
  16. package/dist/lib/registry/types.generated.d.ts +21 -9
  17. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  18. package/dist/lib/server/decisioning/runtime/from-platform.js +6 -2
  19. package/dist/lib/server/decisioning/runtime/from-platform.mjs +6 -2
  20. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  21. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  22. package/dist/lib/v2/projection/augment-response.js +6 -3
  23. package/dist/lib/v2/projection/augment-response.mjs +8 -5
  24. package/dist/lib/v2/projection/creative-delivery.d.mts +2 -0
  25. package/dist/lib/v2/projection/creative-delivery.d.ts +2 -0
  26. package/dist/lib/v2/projection/creative-delivery.js +36 -17
  27. package/dist/lib/v2/projection/creative-delivery.mjs +37 -18
  28. package/dist/lib/v2/projection/legacy-metadata.d.mts +12 -0
  29. package/dist/lib/v2/projection/legacy-metadata.d.ts +12 -0
  30. package/dist/lib/v2/projection/legacy-metadata.js +41 -1
  31. package/dist/lib/v2/projection/legacy-metadata.mjs +37 -1
  32. package/dist/lib/v2/projection/v1-to-v2.d.mts +7 -0
  33. package/dist/lib/v2/projection/v1-to-v2.d.ts +7 -0
  34. package/dist/lib/v2/projection/v1-to-v2.js +83 -2
  35. package/dist/lib/v2/projection/v1-to-v2.mjs +86 -1
  36. package/dist/lib/version.d.mts +3 -3
  37. package/dist/lib/version.d.ts +3 -3
  38. package/dist/lib/version.js +3 -3
  39. package/dist/lib/version.mjs +3 -3
  40. package/docs/TYPE-SUMMARY.md +2 -2
  41. package/docs/guides/CREATIVE-DELIVERY.md +45 -6
  42. package/docs/llms.txt +2 -2
  43. package/docs/migration-14.x-rc-worksheet.md +4 -4
  44. package/package.json +1 -1
@@ -309,7 +309,10 @@ function projectResponseCreativeIdentities(value, operation, legacyFormatConvert
309
309
  let projected = dataRecord;
310
310
  if ((0, import_types2.isProjectionProductInput)(projected)) {
311
311
  if (wireMode === "canonical") {
312
- const canonical = (0, import_augment_response.toCanonicalOnlyResponse)({ products: [projected] }, { legacyFormatConverter });
312
+ const canonical = (0, import_augment_response.toCanonicalOnlyResponse)(
313
+ { products: [projected] },
314
+ { legacyFormatConverter, _inferDualEmissionLegacyRefs: false }
315
+ );
313
316
  if (canonical.diagnostics.length > 0 || canonical.response.products.length !== 1) {
314
317
  throw new import_creative_delivery.CreativeFormatProjectionError(
315
318
  operation,
@@ -548,7 +551,8 @@ function asCanonicalProductResponse(response, legacyFormatConverter) {
548
551
  assertSafeGetProductsResponse(response);
549
552
  validateDualProductFormatDeclarations(response, legacyFormatConverter);
550
553
  const projected = (0, import_augment_response.toCanonicalOnlyResponse)(response, {
551
- legacyFormatConverter
554
+ legacyFormatConverter,
555
+ _inferDualEmissionLegacyRefs: false
552
556
  });
553
557
  const blockingDiagnostics = projected.diagnostics.filter(
554
558
  (diagnostic) => diagnostic.code !== "LEGACY_FORMAT_ID_DROPPED_UNMAPPED"
@@ -338,7 +338,10 @@ function projectResponseCreativeIdentities(value, operation, legacyFormatConvert
338
338
  let projected = dataRecord;
339
339
  if (isProjectionProductInput(projected)) {
340
340
  if (wireMode === "canonical") {
341
- const canonical = toCanonicalOnlyResponse({ products: [projected] }, { legacyFormatConverter });
341
+ const canonical = toCanonicalOnlyResponse(
342
+ { products: [projected] },
343
+ { legacyFormatConverter, _inferDualEmissionLegacyRefs: false }
344
+ );
342
345
  if (canonical.diagnostics.length > 0 || canonical.response.products.length !== 1) {
343
346
  throw new CreativeFormatProjectionError(
344
347
  operation,
@@ -577,7 +580,8 @@ function asCanonicalProductResponse(response, legacyFormatConverter) {
577
580
  assertSafeGetProductsResponse(response);
578
581
  validateDualProductFormatDeclarations(response, legacyFormatConverter);
579
582
  const projected = toCanonicalOnlyResponse(response, {
580
- legacyFormatConverter
583
+ legacyFormatConverter,
584
+ _inferDualEmissionLegacyRefs: false
581
585
  });
582
586
  const blockingDiagnostics = projected.diagnostics.filter(
583
587
  (diagnostic) => diagnostic.code !== "LEGACY_FORMAT_ID_DROPPED_UNMAPPED"
@@ -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 = "15.9.5";
200
+ export declare const RUNNER_CAPABILITY_VERSION = "15.9.6";
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 = "15.9.5";
200
+ export declare const RUNNER_CAPABILITY_VERSION = "15.9.6";
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
  /**
@@ -224,7 +224,10 @@ function toCanonicalFormatOptionsWithRoutes(productId, formatOptions) {
224
224
  }
225
225
  function toAdditiveCanonicalProduct(product, options) {
226
226
  const { product: augmented, diagnostics } = augmentProductWithFormatOptions(product, options);
227
- const projected = toCanonicalFormatOptionsWithRoutes(product.product_id, augmented.format_options);
227
+ const projected = toCanonicalFormatOptionsWithRoutes(
228
+ product.product_id,
229
+ options?._inferDualEmissionLegacyRefs === false ? augmented.format_options : (0, import_v1_to_v2.withDualEmissionLegacyRefs)(augmented.format_options, product.format_ids)
230
+ );
228
231
  return {
229
232
  product: {
230
233
  ...augmented,
@@ -299,13 +302,13 @@ function formatRefCoverageKey(ref) {
299
302
  function toCanonicalOnlyProduct(product, options) {
300
303
  const existing = product.format_options;
301
304
  if (Array.isArray(existing)) {
302
- const formatOptions = existing;
305
+ const formatOptions = options?._inferDualEmissionLegacyRefs === false ? existing : (0, import_v1_to_v2.withDualEmissionLegacyRefs)(existing, product.format_ids);
303
306
  const diagnostics2 = [];
304
307
  const inputIds = Array.isArray(product.format_ids) ? product.format_ids : [];
305
308
  if (inputIds.length > 0) {
306
309
  const covered = /* @__PURE__ */ new Set();
307
310
  for (const opt of formatOptions) {
308
- const refs = Array.isArray(opt?.v1_format_ref) ? opt.v1_format_ref : [];
311
+ const refs = (0, import_legacy_metadata.legacyFormatRefsForDeclaration)(opt);
309
312
  for (const ref of refs) covered.add(formatRefCoverageKey(ref));
310
313
  }
311
314
  for (let k = 0; k < inputIds.length; k++) {
@@ -1,7 +1,7 @@
1
- import { projectV1ProductToV2 } from "./v1-to-v2.mjs";
1
+ import { projectV1ProductToV2, withDualEmissionLegacyRefs } from "./v1-to-v2.mjs";
2
2
  import { LIBRARY_VERSION } from "../../version.mjs";
3
3
  import { canonicalize as canonicalizeJson } from "../../utils/jcs.mjs";
4
- import { concealLegacyFormatRefs } from "./legacy-metadata.mjs";
4
+ import { concealLegacyFormatRefs, legacyFormatRefsForDeclaration } from "./legacy-metadata.mjs";
5
5
  import { legacyRoutesForProduct } from "./legacy-routes.mjs";
6
6
  const SDK_ID = `@adcp/sdk@${LIBRARY_VERSION}`;
7
7
  const DIRECT_LEGACY_FORMAT_IDENTITY_KEYS = /* @__PURE__ */ new Set(["agenturl", "formatid", "formatids", "v1formatref"]);
@@ -194,7 +194,10 @@ function toCanonicalFormatOptionsWithRoutes(productId, formatOptions) {
194
194
  }
195
195
  function toAdditiveCanonicalProduct(product, options) {
196
196
  const { product: augmented, diagnostics } = augmentProductWithFormatOptions(product, options);
197
- const projected = toCanonicalFormatOptionsWithRoutes(product.product_id, augmented.format_options);
197
+ const projected = toCanonicalFormatOptionsWithRoutes(
198
+ product.product_id,
199
+ options?._inferDualEmissionLegacyRefs === false ? augmented.format_options : withDualEmissionLegacyRefs(augmented.format_options, product.format_ids)
200
+ );
198
201
  return {
199
202
  product: {
200
203
  ...augmented,
@@ -269,13 +272,13 @@ function formatRefCoverageKey(ref) {
269
272
  function toCanonicalOnlyProduct(product, options) {
270
273
  const existing = product.format_options;
271
274
  if (Array.isArray(existing)) {
272
- const formatOptions = existing;
275
+ const formatOptions = options?._inferDualEmissionLegacyRefs === false ? existing : withDualEmissionLegacyRefs(existing, product.format_ids);
273
276
  const diagnostics2 = [];
274
277
  const inputIds = Array.isArray(product.format_ids) ? product.format_ids : [];
275
278
  if (inputIds.length > 0) {
276
279
  const covered = /* @__PURE__ */ new Set();
277
280
  for (const opt of formatOptions) {
278
- const refs = Array.isArray(opt?.v1_format_ref) ? opt.v1_format_ref : [];
281
+ const refs = legacyFormatRefsForDeclaration(opt);
279
282
  for (const ref of refs) covered.add(formatRefCoverageKey(ref));
280
283
  }
281
284
  for (let k = 0; k < inputIds.length; k++) {
@@ -230,6 +230,8 @@ export interface CreativeFormatSelectorContainer {
230
230
  /** Canonical package/product selectors accepted by the primary sync API. */
231
231
  export interface CanonicalCreativeFormatSelectorContainer {
232
232
  package_id?: string;
233
+ /** Target product, used to recover seller declarations after serializing selectors. */
234
+ product_id?: string;
233
235
  format_options?: ReadonlyArray<CanonicalFormatDeclaration>;
234
236
  format_option_refs?: ReadonlyArray<FormatOptionReference>;
235
237
  format_kind?: CanonicalFormatKind;
@@ -230,6 +230,8 @@ export interface CreativeFormatSelectorContainer {
230
230
  /** Canonical package/product selectors accepted by the primary sync API. */
231
231
  export interface CanonicalCreativeFormatSelectorContainer {
232
232
  package_id?: string;
233
+ /** Target product, used to recover seller declarations after serializing selectors. */
234
+ product_id?: string;
233
235
  format_options?: ReadonlyArray<CanonicalFormatDeclaration>;
234
236
  format_option_refs?: ReadonlyArray<FormatOptionReference>;
235
237
  format_kind?: CanonicalFormatKind;
@@ -20,6 +20,7 @@ var creative_delivery_exports = {};
20
20
  __export(creative_delivery_exports, {
21
21
  CreativeFormatCapabilityError: () => CreativeFormatCapabilityError,
22
22
  CreativeFormatProjectionError: () => CreativeFormatProjectionError,
23
+ canUseProductOptionsForCreativeWire: () => canUseProductOptionsForCreativeWire,
23
24
  projectCreativeForDelivery: () => projectCreativeForDelivery,
24
25
  projectMediaBuyCreativesForDelivery: () => projectMediaBuyCreativesForDelivery,
25
26
  projectSyncCreativesForDelivery: () => projectSyncCreativesForDelivery,
@@ -378,26 +379,15 @@ function candidatesFromContainer(container, canonicalFormatLegacyResolver, opera
378
379
  );
379
380
  }
380
381
  const candidates = [];
381
- const containerKind = typeof container.format_kind === "string" ? container.format_kind : void 0;
382
- for (const key of ["format_ids", "formats"]) {
383
- for (const ref of refsFromValue(container[key])) {
384
- candidates.push({
385
- ref,
386
- formatKind: (0, import_v1_to_v2.resolveCanonicalFormatKind)(ref.id) ?? containerKind,
387
- selectorParams: container.params
388
- });
389
- }
390
- }
391
- const formatOptions = [
392
- ...Array.isArray(container.format_options) ? container.format_options : [],
393
- ...(0, import_legacy_metadata.selectedFormatOptions)(container)
394
- ];
395
- for (const optionValue of formatOptions) {
382
+ const nativeOptions = Array.isArray(container.format_options) ? container.format_options : [];
383
+ const formatOptions = [...nativeOptions, ...(0, import_legacy_metadata.selectedFormatOptions)(container)];
384
+ const resolvedOptions = formatOptions.map((optionValue) => {
396
385
  const option = record(optionValue);
397
- if (!option) continue;
386
+ if (!option) return optionValue;
398
387
  const formatKind = typeof option.format_kind === "string" ? option.format_kind : void 0;
399
388
  const formatOptionRef = optionReference(option);
400
389
  let refs = [...(0, import_legacy_metadata.legacyFormatRefsForDeclaration)(option)];
390
+ if (refs.length > 0) return optionValue;
401
391
  if (refs.length === 0 && option.canonical_formats_only !== true && formatKind) {
402
392
  try {
403
393
  refs = (0, import_v2_to_v1.resolveCanonicalFormatLegacyRefs)(canonicalFormatLegacyResolver, {
@@ -415,10 +405,33 @@ function candidatesFromContainer(container, canonicalFormatLegacyResolver, opera
415
405
  );
416
406
  }
417
407
  }
418
- for (const ref of refs) {
408
+ return refs.length > 0 ? { ...option, v1_format_ref: refs } : optionValue;
409
+ });
410
+ const pairedOptions = [
411
+ ...(0, import_v1_to_v2.withDualEmissionLegacyRefs)(resolvedOptions.slice(0, nativeOptions.length), container.format_ids),
412
+ ...resolvedOptions.slice(nativeOptions.length)
413
+ ];
414
+ for (const optionValue of pairedOptions) {
415
+ const option = record(optionValue);
416
+ if (!option) continue;
417
+ const formatKind = typeof option.format_kind === "string" ? option.format_kind : void 0;
418
+ const formatOptionRef = optionReference(option);
419
+ for (const ref of (0, import_legacy_metadata.legacyFormatRefsForDeclaration)(option)) {
419
420
  candidates.push({ ref, formatKind, formatOptionRef, selectorParams: option.params ?? container.params });
420
421
  }
421
422
  }
423
+ const linkedRefs = new Set(candidates.map((candidate) => candidateKey({ ref: candidate.ref })));
424
+ const containerKind = typeof container.format_kind === "string" ? container.format_kind : void 0;
425
+ for (const key of ["format_ids", "formats"]) {
426
+ for (const ref of refsFromValue(container[key])) {
427
+ if (linkedRefs.has(candidateKey({ ref }))) continue;
428
+ candidates.push({
429
+ ref,
430
+ formatKind: (0, import_v1_to_v2.resolveCanonicalFormatKind)(ref.id) ?? containerKind,
431
+ selectorParams: container.params
432
+ });
433
+ }
434
+ }
422
435
  return uniqueCandidates(candidates);
423
436
  }
424
437
  function containerOptsOutOfLegacy(container, formatKind, formatOptionRef) {
@@ -1106,10 +1119,16 @@ function resolveCreativeFormatWireMode(capabilities, negotiatedVersion) {
1106
1119
  if (explicitCanonical === false) return "legacy";
1107
1120
  return "unknown";
1108
1121
  }
1122
+ function canUseProductOptionsForCreativeWire(capabilities, requestedVersion) {
1123
+ const caps = record(capabilities);
1124
+ const negotiated = mutuallyServedRelease(caps, record(caps?._raw), requestedVersion);
1125
+ return negotiated?.major === 3 && negotiated.minor === 1;
1126
+ }
1109
1127
  // Annotate the CommonJS export names for ESM import in node:
1110
1128
  0 && (module.exports = {
1111
1129
  CreativeFormatCapabilityError,
1112
1130
  CreativeFormatProjectionError,
1131
+ canUseProductOptionsForCreativeWire,
1113
1132
  projectCreativeForDelivery,
1114
1133
  projectMediaBuyCreativesForDelivery,
1115
1134
  projectSyncCreativesForDelivery,
@@ -2,7 +2,8 @@ import {
2
2
  canonicalDeclarationFromBareId,
3
3
  migratedFormatOptionId,
4
4
  projectV1ProductToV2,
5
- resolveCanonicalFormatKind
5
+ resolveCanonicalFormatKind,
6
+ withDualEmissionLegacyRefs
6
7
  } from "./v1-to-v2.mjs";
7
8
  import { CanonicalFormatLegacyResolutionError, resolveCanonicalFormatLegacyRefs } from "./v2-to-v1.mjs";
8
9
  import {
@@ -357,26 +358,15 @@ function candidatesFromContainer(container, canonicalFormatLegacyResolver, opera
357
358
  );
358
359
  }
359
360
  const candidates = [];
360
- const containerKind = typeof container.format_kind === "string" ? container.format_kind : void 0;
361
- for (const key of ["format_ids", "formats"]) {
362
- for (const ref of refsFromValue(container[key])) {
363
- candidates.push({
364
- ref,
365
- formatKind: resolveCanonicalFormatKind(ref.id) ?? containerKind,
366
- selectorParams: container.params
367
- });
368
- }
369
- }
370
- const formatOptions = [
371
- ...Array.isArray(container.format_options) ? container.format_options : [],
372
- ...selectedFormatOptions(container)
373
- ];
374
- for (const optionValue of formatOptions) {
361
+ const nativeOptions = Array.isArray(container.format_options) ? container.format_options : [];
362
+ const formatOptions = [...nativeOptions, ...selectedFormatOptions(container)];
363
+ const resolvedOptions = formatOptions.map((optionValue) => {
375
364
  const option = record(optionValue);
376
- if (!option) continue;
365
+ if (!option) return optionValue;
377
366
  const formatKind = typeof option.format_kind === "string" ? option.format_kind : void 0;
378
367
  const formatOptionRef = optionReference(option);
379
368
  let refs = [...legacyFormatRefsForDeclaration(option)];
369
+ if (refs.length > 0) return optionValue;
380
370
  if (refs.length === 0 && option.canonical_formats_only !== true && formatKind) {
381
371
  try {
382
372
  refs = resolveCanonicalFormatLegacyRefs(canonicalFormatLegacyResolver, {
@@ -394,10 +384,33 @@ function candidatesFromContainer(container, canonicalFormatLegacyResolver, opera
394
384
  );
395
385
  }
396
386
  }
397
- for (const ref of refs) {
387
+ return refs.length > 0 ? { ...option, v1_format_ref: refs } : optionValue;
388
+ });
389
+ const pairedOptions = [
390
+ ...withDualEmissionLegacyRefs(resolvedOptions.slice(0, nativeOptions.length), container.format_ids),
391
+ ...resolvedOptions.slice(nativeOptions.length)
392
+ ];
393
+ for (const optionValue of pairedOptions) {
394
+ const option = record(optionValue);
395
+ if (!option) continue;
396
+ const formatKind = typeof option.format_kind === "string" ? option.format_kind : void 0;
397
+ const formatOptionRef = optionReference(option);
398
+ for (const ref of legacyFormatRefsForDeclaration(option)) {
398
399
  candidates.push({ ref, formatKind, formatOptionRef, selectorParams: option.params ?? container.params });
399
400
  }
400
401
  }
402
+ const linkedRefs = new Set(candidates.map((candidate) => candidateKey({ ref: candidate.ref })));
403
+ const containerKind = typeof container.format_kind === "string" ? container.format_kind : void 0;
404
+ for (const key of ["format_ids", "formats"]) {
405
+ for (const ref of refsFromValue(container[key])) {
406
+ if (linkedRefs.has(candidateKey({ ref }))) continue;
407
+ candidates.push({
408
+ ref,
409
+ formatKind: resolveCanonicalFormatKind(ref.id) ?? containerKind,
410
+ selectorParams: container.params
411
+ });
412
+ }
413
+ }
401
414
  return uniqueCandidates(candidates);
402
415
  }
403
416
  function containerOptsOutOfLegacy(container, formatKind, formatOptionRef) {
@@ -1085,9 +1098,15 @@ function resolveCreativeFormatWireMode(capabilities, negotiatedVersion) {
1085
1098
  if (explicitCanonical === false) return "legacy";
1086
1099
  return "unknown";
1087
1100
  }
1101
+ function canUseProductOptionsForCreativeWire(capabilities, requestedVersion) {
1102
+ const caps = record(capabilities);
1103
+ const negotiated = mutuallyServedRelease(caps, record(caps?._raw), requestedVersion);
1104
+ return negotiated?.major === 3 && negotiated.minor === 1;
1105
+ }
1088
1106
  export {
1089
1107
  CreativeFormatCapabilityError,
1090
1108
  CreativeFormatProjectionError,
1109
+ canUseProductOptionsForCreativeWire,
1091
1110
  projectCreativeForDelivery,
1092
1111
  projectMediaBuyCreativesForDelivery,
1093
1112
  projectSyncCreativesForDelivery,
@@ -12,9 +12,21 @@ type DeclarationWithMetadata = CanonicalFormatDeclaration;
12
12
  export type PackageSelectionMetadata = {
13
13
  format_option_refs?: readonly unknown[];
14
14
  };
15
+ export interface SellerFormatEvidence {
16
+ scopeKey: string;
17
+ accountScope: string;
18
+ productId: string;
19
+ expiresAt: number;
20
+ }
21
+ /** Positive evidence is client/account-bound and cannot survive a JSON round trip on its own. */
22
+ export declare function rememberSellerFormatEvidence(declaration: object, evidence: SellerFormatEvidence): void;
23
+ export declare function sellerFormatEvidence(declaration: object): SellerFormatEvidence | undefined;
15
24
  /** Keep seller-origin evidence private while canonical products pass through the cache. */
16
25
  export declare function rememberSellerDeclaredFormatOption(declaration: object, declared: boolean): void;
17
26
  export declare function sellerDeclaredFormatOption(declaration: object): boolean | undefined;
27
+ /** A pure legacy projection cannot establish what the original seller advertised. */
28
+ export declare function rememberSynthesizedFormatOption(declaration: object): void;
29
+ export declare function isSynthesizedFormatOption(declaration: object): boolean;
18
30
  export declare function concealLegacyFormatRefs(declaration: ProductFormatDeclaration | V2ProductFormatDeclaration | CanonicalFormatDeclaration): DeclarationWithMetadata;
19
31
  export declare function legacyFormatRefsForDeclaration(value: unknown): readonly V1FormatId[];
20
32
  export declare function selectedFormatOptions(value: unknown): readonly DeclarationWithMetadata[];
@@ -12,9 +12,21 @@ type DeclarationWithMetadata = CanonicalFormatDeclaration;
12
12
  export type PackageSelectionMetadata = {
13
13
  format_option_refs?: readonly unknown[];
14
14
  };
15
+ export interface SellerFormatEvidence {
16
+ scopeKey: string;
17
+ accountScope: string;
18
+ productId: string;
19
+ expiresAt: number;
20
+ }
21
+ /** Positive evidence is client/account-bound and cannot survive a JSON round trip on its own. */
22
+ export declare function rememberSellerFormatEvidence(declaration: object, evidence: SellerFormatEvidence): void;
23
+ export declare function sellerFormatEvidence(declaration: object): SellerFormatEvidence | undefined;
15
24
  /** Keep seller-origin evidence private while canonical products pass through the cache. */
16
25
  export declare function rememberSellerDeclaredFormatOption(declaration: object, declared: boolean): void;
17
26
  export declare function sellerDeclaredFormatOption(declaration: object): boolean | undefined;
27
+ /** A pure legacy projection cannot establish what the original seller advertised. */
28
+ export declare function rememberSynthesizedFormatOption(declaration: object): void;
29
+ export declare function isSynthesizedFormatOption(declaration: object): boolean;
18
30
  export declare function concealLegacyFormatRefs(declaration: ProductFormatDeclaration | V2ProductFormatDeclaration | CanonicalFormatDeclaration): DeclarationWithMetadata;
19
31
  export declare function legacyFormatRefsForDeclaration(value: unknown): readonly V1FormatId[];
20
32
  export declare function selectedFormatOptions(value: unknown): readonly DeclarationWithMetadata[];
@@ -20,22 +20,52 @@ var legacy_metadata_exports = {};
20
20
  __export(legacy_metadata_exports, {
21
21
  concealLegacyFormatRefs: () => concealLegacyFormatRefs,
22
22
  concealSelectedFormatOptions: () => concealSelectedFormatOptions,
23
+ isSynthesizedFormatOption: () => isSynthesizedFormatOption,
23
24
  legacyFormatRefsForDeclaration: () => legacyFormatRefsForDeclaration,
24
25
  rememberSellerDeclaredFormatOption: () => rememberSellerDeclaredFormatOption,
26
+ rememberSellerFormatEvidence: () => rememberSellerFormatEvidence,
27
+ rememberSynthesizedFormatOption: () => rememberSynthesizedFormatOption,
25
28
  selectedFormatOptions: () => selectedFormatOptions,
26
29
  sellerDeclaredFormatOption: () => sellerDeclaredFormatOption,
30
+ sellerFormatEvidence: () => sellerFormatEvidence,
27
31
  structuredCloneWithLegacyCreativeMetadata: () => structuredCloneWithLegacyCreativeMetadata,
28
32
  transferLegacyCreativeMetadata: () => transferLegacyCreativeMetadata
29
33
  });
30
34
  module.exports = __toCommonJS(legacy_metadata_exports);
35
+ var import_jcs = require('../../utils/jcs.js');
31
36
  const legacyRefsByDeclaration = /* @__PURE__ */ new WeakMap();
32
37
  const selectedOptionsByRefs = /* @__PURE__ */ new WeakMap();
33
38
  const sellerDeclaredByDeclaration = /* @__PURE__ */ new WeakMap();
39
+ const sellerEvidenceByDeclaration = /* @__PURE__ */ new WeakMap();
40
+ function rememberSellerFormatEvidence(declaration, evidence) {
41
+ try {
42
+ sellerEvidenceByDeclaration.set(
43
+ declaration,
44
+ Object.freeze({ ...evidence, fingerprint: (0, import_jcs.canonicalize)(declaration) })
45
+ );
46
+ } catch {
47
+ }
48
+ }
49
+ function sellerFormatEvidence(declaration) {
50
+ const evidence = sellerEvidenceByDeclaration.get(declaration);
51
+ try {
52
+ return evidence?.fingerprint === (0, import_jcs.canonicalize)(declaration) ? evidence : void 0;
53
+ } catch {
54
+ return void 0;
55
+ }
56
+ }
34
57
  function rememberSellerDeclaredFormatOption(declaration, declared) {
35
58
  sellerDeclaredByDeclaration.set(declaration, declared);
36
59
  }
37
60
  function sellerDeclaredFormatOption(declaration) {
38
- return sellerDeclaredByDeclaration.get(declaration);
61
+ const origin = sellerDeclaredByDeclaration.get(declaration);
62
+ return typeof origin === "boolean" ? origin : void 0;
63
+ }
64
+ function rememberSynthesizedFormatOption(declaration) {
65
+ sellerDeclaredByDeclaration.set(declaration, "synthesized");
66
+ }
67
+ function isSynthesizedFormatOption(declaration) {
68
+ return sellerDeclaredByDeclaration.get(declaration) === "synthesized";
39
69
  }
40
70
  function concealLegacyFormatRefs(declaration) {
41
71
  const { v1_format_ref: refs, ...canonical } = declaration;
@@ -43,6 +73,8 @@ function concealLegacyFormatRefs(declaration) {
43
73
  const refsToConceal = Array.isArray(existingHidden) && existingHidden.length > 0 ? existingHidden : refs;
44
74
  const declared = sellerDeclaredByDeclaration.get(declaration);
45
75
  if (declared !== void 0) sellerDeclaredByDeclaration.set(canonical, declared);
76
+ const evidence = sellerEvidenceByDeclaration.get(declaration);
77
+ if (evidence) sellerEvidenceByDeclaration.set(canonical, evidence);
46
78
  if (Array.isArray(refsToConceal) && refsToConceal.length > 0) {
47
79
  legacyRefsByDeclaration.set(
48
80
  canonical,
@@ -75,6 +107,8 @@ function transferLegacyCreativeMetadata(source, target) {
75
107
  if (selected) selectedOptionsByRefs.set(target, selected);
76
108
  const declared = sellerDeclaredByDeclaration.get(source);
77
109
  if (declared !== void 0) sellerDeclaredByDeclaration.set(target, declared);
110
+ const evidence = sellerEvidenceByDeclaration.get(source);
111
+ if (evidence) sellerEvidenceByDeclaration.set(target, evidence);
78
112
  }
79
113
  function structuredCloneWithLegacyCreativeMetadata(value) {
80
114
  const clone = structuredClone(value);
@@ -82,6 +116,8 @@ function structuredCloneWithLegacyCreativeMetadata(value) {
82
116
  const snapshotMetadata = (source, target) => {
83
117
  const declared = sellerDeclaredByDeclaration.get(source);
84
118
  if (declared !== void 0) sellerDeclaredByDeclaration.set(target, declared);
119
+ const evidence = sellerEvidenceByDeclaration.get(source);
120
+ if (evidence) sellerEvidenceByDeclaration.set(target, evidence);
85
121
  const refs = legacyRefsByDeclaration.get(source);
86
122
  if (refs) legacyRefsByDeclaration.set(target, structuredClone(refs));
87
123
  const selected = selectedOptionsByRefs.get(source);
@@ -119,10 +155,14 @@ function structuredCloneWithLegacyCreativeMetadata(value) {
119
155
  0 && (module.exports = {
120
156
  concealLegacyFormatRefs,
121
157
  concealSelectedFormatOptions,
158
+ isSynthesizedFormatOption,
122
159
  legacyFormatRefsForDeclaration,
123
160
  rememberSellerDeclaredFormatOption,
161
+ rememberSellerFormatEvidence,
162
+ rememberSynthesizedFormatOption,
124
163
  selectedFormatOptions,
125
164
  sellerDeclaredFormatOption,
165
+ sellerFormatEvidence,
126
166
  structuredCloneWithLegacyCreativeMetadata,
127
167
  transferLegacyCreativeMetadata
128
168
  });
@@ -1,11 +1,37 @@
1
+ import { canonicalize } from "../../utils/jcs.mjs";
1
2
  const legacyRefsByDeclaration = /* @__PURE__ */ new WeakMap();
2
3
  const selectedOptionsByRefs = /* @__PURE__ */ new WeakMap();
3
4
  const sellerDeclaredByDeclaration = /* @__PURE__ */ new WeakMap();
5
+ const sellerEvidenceByDeclaration = /* @__PURE__ */ new WeakMap();
6
+ function rememberSellerFormatEvidence(declaration, evidence) {
7
+ try {
8
+ sellerEvidenceByDeclaration.set(
9
+ declaration,
10
+ Object.freeze({ ...evidence, fingerprint: canonicalize(declaration) })
11
+ );
12
+ } catch {
13
+ }
14
+ }
15
+ function sellerFormatEvidence(declaration) {
16
+ const evidence = sellerEvidenceByDeclaration.get(declaration);
17
+ try {
18
+ return evidence?.fingerprint === canonicalize(declaration) ? evidence : void 0;
19
+ } catch {
20
+ return void 0;
21
+ }
22
+ }
4
23
  function rememberSellerDeclaredFormatOption(declaration, declared) {
5
24
  sellerDeclaredByDeclaration.set(declaration, declared);
6
25
  }
7
26
  function sellerDeclaredFormatOption(declaration) {
8
- return sellerDeclaredByDeclaration.get(declaration);
27
+ const origin = sellerDeclaredByDeclaration.get(declaration);
28
+ return typeof origin === "boolean" ? origin : void 0;
29
+ }
30
+ function rememberSynthesizedFormatOption(declaration) {
31
+ sellerDeclaredByDeclaration.set(declaration, "synthesized");
32
+ }
33
+ function isSynthesizedFormatOption(declaration) {
34
+ return sellerDeclaredByDeclaration.get(declaration) === "synthesized";
9
35
  }
10
36
  function concealLegacyFormatRefs(declaration) {
11
37
  const { v1_format_ref: refs, ...canonical } = declaration;
@@ -13,6 +39,8 @@ function concealLegacyFormatRefs(declaration) {
13
39
  const refsToConceal = Array.isArray(existingHidden) && existingHidden.length > 0 ? existingHidden : refs;
14
40
  const declared = sellerDeclaredByDeclaration.get(declaration);
15
41
  if (declared !== void 0) sellerDeclaredByDeclaration.set(canonical, declared);
42
+ const evidence = sellerEvidenceByDeclaration.get(declaration);
43
+ if (evidence) sellerEvidenceByDeclaration.set(canonical, evidence);
16
44
  if (Array.isArray(refsToConceal) && refsToConceal.length > 0) {
17
45
  legacyRefsByDeclaration.set(
18
46
  canonical,
@@ -45,6 +73,8 @@ function transferLegacyCreativeMetadata(source, target) {
45
73
  if (selected) selectedOptionsByRefs.set(target, selected);
46
74
  const declared = sellerDeclaredByDeclaration.get(source);
47
75
  if (declared !== void 0) sellerDeclaredByDeclaration.set(target, declared);
76
+ const evidence = sellerEvidenceByDeclaration.get(source);
77
+ if (evidence) sellerEvidenceByDeclaration.set(target, evidence);
48
78
  }
49
79
  function structuredCloneWithLegacyCreativeMetadata(value) {
50
80
  const clone = structuredClone(value);
@@ -52,6 +82,8 @@ function structuredCloneWithLegacyCreativeMetadata(value) {
52
82
  const snapshotMetadata = (source, target) => {
53
83
  const declared = sellerDeclaredByDeclaration.get(source);
54
84
  if (declared !== void 0) sellerDeclaredByDeclaration.set(target, declared);
85
+ const evidence = sellerEvidenceByDeclaration.get(source);
86
+ if (evidence) sellerEvidenceByDeclaration.set(target, evidence);
55
87
  const refs = legacyRefsByDeclaration.get(source);
56
88
  if (refs) legacyRefsByDeclaration.set(target, structuredClone(refs));
57
89
  const selected = selectedOptionsByRefs.get(source);
@@ -88,10 +120,14 @@ function structuredCloneWithLegacyCreativeMetadata(value) {
88
120
  export {
89
121
  concealLegacyFormatRefs,
90
122
  concealSelectedFormatOptions,
123
+ isSynthesizedFormatOption,
91
124
  legacyFormatRefsForDeclaration,
92
125
  rememberSellerDeclaredFormatOption,
126
+ rememberSellerFormatEvidence,
127
+ rememberSynthesizedFormatOption,
93
128
  selectedFormatOptions,
94
129
  sellerDeclaredFormatOption,
130
+ sellerFormatEvidence,
95
131
  structuredCloneWithLegacyCreativeMetadata,
96
132
  transferLegacyCreativeMetadata
97
133
  };
@@ -211,3 +211,10 @@ export declare function canonicalDeclarationFromBareId(id: string, options?: Bar
211
211
  * the `agentUrl` default, and the `assetType` disambiguator.
212
212
  */
213
213
  export declare function resolveCanonicalFormatKind(id: string, options?: BareFormatIdResolveOptions): CanonicalFormatKind | null;
214
+ /**
215
+ * Preserve index pairing only when the whole seller-authored alignment is credible.
216
+ * AdCP 3.1.24 core/product.json defines this correspondence: "the format_options[i]
217
+ * narrows the canonical that the named format in format_ids[i] resolves to via the
218
+ * registry / explicit canonical field". Explicit routes remain authoritative.
219
+ */
220
+ export declare function withDualEmissionLegacyRefs<T>(formatOptions: T[], formatIds: unknown): T[];
@@ -211,3 +211,10 @@ export declare function canonicalDeclarationFromBareId(id: string, options?: Bar
211
211
  * the `agentUrl` default, and the `assetType` disambiguator.
212
212
  */
213
213
  export declare function resolveCanonicalFormatKind(id: string, options?: BareFormatIdResolveOptions): CanonicalFormatKind | null;
214
+ /**
215
+ * Preserve index pairing only when the whole seller-authored alignment is credible.
216
+ * AdCP 3.1.24 core/product.json defines this correspondence: "the format_options[i]
217
+ * narrows the canonical that the named format in format_ids[i] resolves to via the
218
+ * registry / explicit canonical field". Explicit routes remain authoritative.
219
+ */
220
+ export declare function withDualEmissionLegacyRefs<T>(formatOptions: T[], formatIds: unknown): T[];