@adcp/sdk 13.0.0-rc.11 → 13.0.0-rc.13
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/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +4 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +4 -0
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/registry/types.generated.d.mts +48 -1
- package/dist/lib/registry/types.generated.d.ts +48 -1
- package/dist/lib/registry/types.generated.d.ts.map +1 -1
- package/dist/lib/registry/types.generated.js.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
- package/dist/lib/testing/compliance/comply.js +8 -2
- package/dist/lib/testing/compliance/comply.js.map +1 -1
- package/dist/lib/testing/compliance/comply.mjs +8 -2
- package/dist/lib/testing/compliance/comply.mjs.map +1 -1
- package/dist/lib/testing/compliance/spec-conformance.d.ts.map +1 -1
- package/dist/lib/testing/compliance/spec-conformance.js +2 -0
- package/dist/lib/testing/compliance/spec-conformance.js.map +1 -1
- package/dist/lib/testing/compliance/spec-conformance.mjs +2 -0
- package/dist/lib/testing/compliance/spec-conformance.mjs.map +1 -1
- package/dist/lib/testing/compliance/summary.d.mts +2 -0
- package/dist/lib/testing/compliance/summary.d.ts +2 -0
- package/dist/lib/testing/compliance/summary.d.ts.map +1 -1
- package/dist/lib/testing/compliance/summary.js +3 -2
- package/dist/lib/testing/compliance/summary.js.map +1 -1
- package/dist/lib/testing/compliance/summary.mjs +3 -2
- package/dist/lib/testing/compliance/summary.mjs.map +1 -1
- package/dist/lib/testing/compliance/types.d.mts +4 -0
- package/dist/lib/testing/compliance/types.d.ts +4 -0
- package/dist/lib/testing/compliance/types.d.ts.map +1 -1
- package/dist/lib/testing/compliance/types.js.map +1 -1
- package/dist/lib/testing/storyboard/junit.js +49 -32
- package/dist/lib/testing/storyboard/junit.js.map +1 -1
- package/dist/lib/testing/storyboard/junit.mjs +49 -32
- package/dist/lib/testing/storyboard/junit.mjs.map +1 -1
- package/dist/lib/testing/storyboard/loader.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/loader.js +26 -0
- package/dist/lib/testing/storyboard/loader.js.map +1 -1
- package/dist/lib/testing/storyboard/loader.mjs +26 -0
- package/dist/lib/testing/storyboard/loader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +66 -15
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.mjs +70 -16
- package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
- package/dist/lib/testing/storyboard/types.d.mts +26 -1
- package/dist/lib/testing/storyboard/types.d.ts +26 -1
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/types.js.map +1 -1
- package/dist/lib/testing/storyboard/types.mjs.map +1 -1
- package/dist/lib/testing/storyboard/validations.d.mts +11 -0
- package/dist/lib/testing/storyboard/validations.d.ts +11 -0
- package/dist/lib/testing/storyboard/validations.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/validations.js +30 -13
- package/dist/lib/testing/storyboard/validations.js.map +1 -1
- package/dist/lib/testing/storyboard/validations.mjs +27 -13
- package/dist/lib/testing/storyboard/validations.mjs.map +1 -1
- package/dist/lib/v2/projection/augment-response.d.mts +45 -0
- package/dist/lib/v2/projection/augment-response.d.ts +45 -0
- package/dist/lib/v2/projection/augment-response.d.ts.map +1 -1
- package/dist/lib/v2/projection/augment-response.js +54 -0
- package/dist/lib/v2/projection/augment-response.js.map +1 -1
- package/dist/lib/v2/projection/augment-response.mjs +52 -0
- package/dist/lib/v2/projection/augment-response.mjs.map +1 -1
- package/dist/lib/v2/projection/index.d.mts +6 -1
- package/dist/lib/v2/projection/index.d.ts +6 -1
- package/dist/lib/v2/projection/index.d.ts.map +1 -1
- package/dist/lib/v2/projection/index.js +4 -0
- package/dist/lib/v2/projection/index.js.map +1 -1
- package/dist/lib/v2/projection/index.mjs +4 -0
- package/dist/lib/v2/projection/index.mjs.map +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/version.mjs +3 -3
- package/dist/lib/version.mjs.map +1 -1
- package/docs/migration-12-to-13.md +28 -0
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/v2/projection/augment-response.ts"],"sourcesContent":["/**\n * Buyer-side helpers that augment a v1-shaped agent response with v2\n * `format_options[]` derived from the existing `format_ids[]` on each\n * Product.\n *\n * Buyers who want the canonical creative-format model call\n * `withFormatOptions(response)` and read `format_options` instead of\n * relying only on legacy `format_ids`.\n *\n * The SDK also auto-projects compatible `AgentClient.getProducts()`\n * responses; this helper remains useful for cached responses, fixtures,\n * upstream seller/storefront composition, and explicit migration code.\n *\n * Pure functions — no IO, no caching. Each Product is projected\n * independently; diagnostics aggregate so a multi-product response\n * surfaces every projection issue at once. The helpers preserve the\n * input shape verbatim and add `format_options[]` (additive). They do\n * NOT drop `format_ids[]` — that's the 8.0 narrowing. To DROP\n * `format_ids[]` once a consumer has fully migrated, use\n * `toCanonicalOnlyProduct` / `toCanonicalOnlyResponse`.\n */\n\nimport type { V1Product, V1FormatId, V2ProductFormatDeclaration, ProjectionDiagnostic } from './types';\nimport { projectV1ProductToV2 } from './v1-to-v2';\nimport type { V1ToV2ProjectionOptions } from './v1-to-v2';\nimport { LIBRARY_VERSION } from '../../version';\nimport { canonicalize as canonicalizeJson } from '../../utils/jcs';\nimport { concealLegacyFormatRefs } from './legacy-metadata';\nimport type { CanonicalFormatDeclaration } from './legacy-metadata';\n\nconst SDK_ID = `@adcp/sdk@${LIBRARY_VERSION}`;\n\nfunction canonicalDiagnostic(diagnostic: ProjectionDiagnostic): ProjectionDiagnostic {\n return {\n ...diagnostic,\n // A source `format_ids[i]` index is not an index into the projected\n // `format_options[]`: earlier source refs may have failed while later refs\n // projected successfully. Point at the canonical collection instead of\n // claiming that a successful projected option is the failing value.\n field: diagnostic.field.replace(/\\.format_ids\\[\\d+\\]/g, '.format_options'),\n };\n}\n\n/** Protocol Error shape used for portable response-level projection advisories. */\nexport interface CanonicalProjectionError {\n code: ProjectionDiagnostic['code'];\n message: string;\n field: string;\n recovery: 'correctable';\n source: 'sdk';\n sdk_id: string;\n details: ProjectionDiagnostic['error']['details'];\n}\n\nfunction projectionErrorMessage(code: ProjectionDiagnostic['code']): string {\n switch (code) {\n case 'CANONICAL_PRODUCT_FORMATS_UNAVAILABLE':\n return 'Product has no format declaration representable on the canonical-only surface';\n case 'FORMAT_PROJECTION_FAILED':\n return 'Legacy creative format could not be projected to a canonical declaration';\n case 'FORMAT_DECLARATION_V1_AMBIGUOUS':\n return 'Canonical creative format has no unambiguous legacy declaration';\n case 'FORMAT_DECLARATION_V1_NOT_APPLICABLE':\n return 'Canonical-only creative format cannot be represented on a legacy format path';\n case 'CANONICAL_NOT_V1_TRANSLATABLE':\n return 'Canonical creative format has no legacy representation';\n case 'FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE':\n return 'Canonical multi-size format has incomplete legacy coverage';\n case 'LEGACY_FORMAT_ID_DROPPED_UNMAPPED':\n return 'Redundant legacy creative identity has no canonical counterpart';\n }\n}\n\n/** Flatten the projector's internal diagnostic into the protocol `Error` shape. */\nexport function projectionDiagnosticToError(diagnostic: ProjectionDiagnostic): CanonicalProjectionError {\n return {\n code: diagnostic.code,\n message: projectionErrorMessage(diagnostic.code),\n field: diagnostic.field,\n recovery: 'correctable',\n source: diagnostic.source,\n sdk_id: diagnostic.sdk_id,\n details: diagnostic.error.details,\n } as CanonicalProjectionError;\n}\n\nfunction canonicalFormatsUnavailableForProduct(\n product: V1Product,\n reason: Extract<ProjectionDiagnostic, { code: 'CANONICAL_PRODUCT_FORMATS_UNAVAILABLE' }>['error']['details']['reason']\n): ProjectionDiagnostic {\n return {\n source: 'sdk',\n sdk_id: SDK_ID,\n field: `products[${product.product_id}].format_options`,\n code: 'CANONICAL_PRODUCT_FORMATS_UNAVAILABLE',\n error: {\n details: {\n product_id: product.product_id,\n reason,\n },\n },\n };\n}\n\nfunction errorIdentity(value: Record<string, unknown>): string | undefined {\n if (typeof value.code !== 'string' || typeof value.field !== 'string') return undefined;\n try {\n return `${value.code}\\u0000${value.field}\\u0000${canonicalizeJson(value.details ?? null)}`;\n } catch {\n // Preserve unreadable third-party errors instead of falsely deduplicating.\n return undefined;\n }\n}\n\nfunction mergeProjectionErrors(existing: unknown, diagnostics: readonly ProjectionDiagnostic[]): unknown[] {\n const merged = Array.isArray(existing) ? [...existing] : [];\n const seen = new Set<string>();\n for (const value of merged) {\n if (!value || typeof value !== 'object' || Array.isArray(value)) continue;\n const record = value as Record<string, unknown>;\n const key = errorIdentity(record);\n if (key) seen.add(key);\n }\n for (const diagnostic of diagnostics) {\n const error = projectionDiagnosticToError(diagnostic) as unknown as Record<string, unknown>;\n const key = errorIdentity(error)!;\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(error);\n }\n return merged;\n}\n\nfunction remapExistingProductErrors(\n existing: unknown,\n originalToOutputIndex: ReadonlyMap<number, number | undefined>,\n products: readonly V1Product[]\n): unknown {\n if (!Array.isArray(existing)) return existing;\n return existing.map(value => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return value;\n const record = value as Record<string, unknown>;\n let issuesChanged = false;\n const issues = Array.isArray(record.issues)\n ? record.issues.map(issue => {\n if (!issue || typeof issue !== 'object' || Array.isArray(issue)) return issue;\n const issueRecord = issue as Record<string, unknown>;\n if (typeof issueRecord.pointer !== 'string') return issue;\n const pointerMatch = /^\\/products\\/(\\d+)(\\/.*)?$/.exec(issueRecord.pointer);\n if (!pointerMatch) return issue;\n const originalIssueIndex = Number(pointerMatch[1]);\n if (!originalToOutputIndex.has(originalIssueIndex)) return issue;\n const outputIssueIndex = originalToOutputIndex.get(originalIssueIndex);\n issuesChanged = true;\n return {\n ...issueRecord,\n pointer:\n outputIssueIndex === undefined ? '/products' : `/products/${outputIssueIndex}${pointerMatch[2] ?? ''}`,\n };\n })\n : record.issues;\n const withIssues = issuesChanged ? { ...record, issues } : record;\n if (typeof record.field !== 'string') return issuesChanged ? withIssues : value;\n const match = /^products\\[(\\d+)\\](.*)$/.exec(record.field);\n if (!match) return issuesChanged ? withIssues : value;\n const originalIndex = Number(match[1]);\n if (!originalToOutputIndex.has(originalIndex)) return issuesChanged ? withIssues : value;\n const outputIndex = originalToOutputIndex.get(originalIndex);\n if (outputIndex !== undefined) {\n return { ...withIssues, field: `products[${outputIndex}]${match[2] ?? ''}` };\n }\n const productId = products[originalIndex]?.product_id;\n const details =\n record.details && typeof record.details === 'object' && !Array.isArray(record.details)\n ? { ...(record.details as Record<string, unknown>) }\n : {};\n if (typeof productId === 'string' && details.product_id === undefined) details.product_id = productId;\n return { ...withIssues, field: 'products', ...(Object.keys(details).length > 0 ? { details } : {}) };\n });\n}\n\nfunction hasEmptyPlacementFormatOptions(product: CanonicalOnlyProduct<V1Product>): boolean {\n const placements = (product as Record<string, unknown>).placements;\n if (!Array.isArray(placements)) return false;\n return placements.some(value => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return false;\n const options = (value as Record<string, unknown>).format_options;\n return Array.isArray(options) && options.length === 0;\n });\n}\n\n/**\n * A Product that has been augmented with `format_options[]` while\n * preserving the original `format_ids[]`. Carries the projection\n * diagnostics that were generated mapping each `format_id` so the\n * buyer can see what (if anything) didn't project cleanly.\n *\n * **Write-side bridge.** After picking a `format_options[i]` entry,\n * use {@link formatIdsFromOptions} (from `@adcp/sdk/v2/projection`)\n * to extract the `format_ids[]` value for a `create_media_buy`\n * package. Inlining `decl.v1_format_ref` works but bypasses the\n * fail-closed semantics (canonical_formats_only / inherently-v2\n * canonical → throw). The spec gap that forces this bridge is tracked\n * at adcontextprotocol/adcp#4842.\n *\n * @see formatIdsFromOptions\n * @see formatIdsForCapability\n */\nexport type V2AugmentedProduct<P> = P & {\n format_options: V2ProductFormatDeclaration[];\n};\n\n/**\n * Augment a single Product. Idempotent — when `format_options[]` is\n * already present (the seller is v2-native), passes the Product\n * through unchanged. Otherwise projects from `format_ids[]`.\n *\n * Returns `{ product, diagnostics }`. `diagnostics` is empty for a\n * clean projection; populated when individual format_ids don't have\n * a v2 mapping (catalog gap, structural unreachability, etc.).\n *\n * @see toCanonicalOnlyProduct — the canonical-only counterpart that DROPS\n * `format_ids[]` for a fully-migrated consumer.\n */\nexport function augmentProductWithFormatOptions<P extends V1Product>(\n product: P,\n options?: V1ToV2ProjectionOptions\n): { product: V2AugmentedProduct<P>; diagnostics: ProjectionDiagnostic[] } {\n // Already v2-shaped (seller sent format_options directly) — pass through.\n const existing = (product as unknown as { format_options?: unknown }).format_options;\n if (Array.isArray(existing)) {\n return {\n product: product as V2AugmentedProduct<P>,\n diagnostics: [],\n };\n }\n // v1 shape — project to add format_options[].\n if (!Array.isArray(product.format_ids)) {\n // Neither shape — nothing to project. Return as-is with an empty\n // format_options so the buyer doesn't have to special-case.\n return {\n product: { ...product, format_options: [] },\n diagnostics: [],\n };\n }\n const { v2, diagnostics } = projectV1ProductToV2(product, options);\n // Preserve the original product shape (especially format_ids); just\n // add format_options.\n return {\n product: {\n ...product,\n format_options: v2.format_options,\n },\n diagnostics,\n };\n}\n\n/**\n * Augment every Product in a `get_products` response with\n * `format_options[]`. Returns `{ response, diagnostics }` so callers\n * can surface projection diagnostics alongside the response's existing\n * `errors[]` array (or filter by `source: 'sdk'` to distinguish SDK\n * diagnostics from seller-emitted errors).\n *\n * Idempotent: if the seller is v2-native and every Product already\n * carries `format_options[]`, returns the response verbatim with no\n * diagnostics.\n *\n * @see toCanonicalOnlyResponse — the canonical-only counterpart that DROPS\n * `format_ids[]` for a fully-migrated consumer.\n */\nexport function withFormatOptions<R extends { products?: V1Product[] }>(\n response: R,\n options?: V1ToV2ProjectionOptions\n): { response: R & { products: V2AugmentedProduct<V1Product>[] }; diagnostics: ProjectionDiagnostic[] } {\n if (!Array.isArray(response?.products)) {\n return {\n response: { ...response, products: [] } as R & { products: V2AugmentedProduct<V1Product>[] },\n diagnostics: [],\n };\n }\n const out: V2AugmentedProduct<V1Product>[] = [];\n const diagnostics: ProjectionDiagnostic[] = [];\n for (const p of response.products) {\n const { product, diagnostics: d } = augmentProductWithFormatOptions(p, options);\n out.push(product);\n diagnostics.push(...d);\n }\n return {\n response: { ...response, products: out } as R & { products: V2AugmentedProduct<V1Product>[] },\n diagnostics,\n };\n}\n\n/**\n * A Product reduced to the canonical creative-format surface:\n * `format_options[]` only, with the legacy `format_ids[]` removed. The\n * read-side counterpart to a fully-migrated consumer — naive downstream\n * code can no longer fall back to the stale `{ agent_url, id }` shape and\n * silently bypass the canonical model.\n */\nexport type CanonicalOnlyProduct<P> = Omit<P, 'format_ids'> & {\n format_ids?: never;\n format_options: CanonicalFormatDeclaration[];\n};\n\nfunction canonicalDeclarations(values: readonly V2ProductFormatDeclaration[]): CanonicalFormatDeclaration[] {\n return values.map(value => concealLegacyFormatRefs(value));\n}\n\nfunction canonicalPlacements(\n product: Record<string, unknown>,\n options: V1ToV2ProjectionOptions | undefined,\n diagnostics: ProjectionDiagnostic[]\n): unknown {\n if (!Array.isArray(product.placements)) return product.placements;\n return product.placements.map((value, placementIndex) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return value;\n const placement = value as Record<string, unknown>;\n const { format_ids: _drop, ...rest } = placement;\n void _drop;\n const hasLegacyFormats = Array.isArray(placement.format_ids);\n const hasCanonicalFormats = Array.isArray(placement.format_options);\n if (!hasLegacyFormats && !hasCanonicalFormats) return rest;\n\n const productId = typeof product.product_id === 'string' ? product.product_id : '(unknown)';\n const placementId = typeof placement.placement_id === 'string' ? placement.placement_id : String(placementIndex);\n const pseudoProduct = {\n product_id: `${productId}:placement:${placementId}`,\n name: typeof placement.name === 'string' ? placement.name : placementId,\n description: `Nested placement ${placementId}`,\n ...(hasLegacyFormats ? { format_ids: placement.format_ids } : {}),\n ...(hasCanonicalFormats ? { format_options: placement.format_options } : {}),\n } as unknown as V1Product;\n const projected = toCanonicalOnlyProduct(pseudoProduct, options);\n for (const diagnostic of projected.diagnostics) {\n diagnostics.push({\n ...diagnostic,\n field: diagnostic.field.replace(/^products\\[[^\\]]+\\]/, `products[${productId}].placements[${placementIndex}]`),\n });\n }\n return {\n ...rest,\n format_options: projected.product.format_options,\n };\n });\n}\n\n/**\n * Identity key for a `format_id` ref used by the coverage check.\n * Trailing-slash-insensitive on `agent_url` (folds the AAO host's slash /\n * no-slash forms, per `catalog.ts`'s `normalizeAgentUrl`), and includes the\n * dimensional discriminators so multi-size declarations sharing one\n * `{ agent_url, id }` but differing by size/duration are NOT collapsed —\n * the same key shape `write-side.ts` uses for v1 ref de-dup. Without the\n * size half, a `format_ids[]` entry for a size no `v1_format_ref` covers\n * would read as covered and be dropped silently.\n */\nfunction formatRefCoverageKey(ref: V1FormatId): string {\n const url = ref.agent_url && !ref.agent_url.endsWith('/') ? ref.agent_url + '/' : ref.agent_url;\n return `${url}::${ref.id}::${ref.width ?? ''}x${ref.height ?? ''}::${ref.duration_ms ?? ''}`;\n}\n\n/**\n * Project a single Product to the canonical-only shape: `format_options[]`\n * present, `format_ids[]` dropped.\n *\n * **Dropping legacy never silently loses a format.** Every input\n * `format_id` is either represented in the returned `format_options[]` or\n * surfaced in `diagnostics` — never discarded without a trace:\n *\n * - **v1-shaped input** (`format_ids[]`, no `format_options[]`): runs the\n * v1 → v2 projection. Mapped refs become `format_options[]`; any ref\n * the projection can't map is surfaced as `FORMAT_PROJECTION_FAILED`.\n * - **v2-native input** (`format_options[]` already present): keeps the\n * seller's canonical surface and drops the redundant v1 fallback. If a\n * legacy routing entry exists that no canonical option covers, it\n * surfaces a canonical-safe `LEGACY_FORMAT_ID_DROPPED_UNMAPPED`\n * diagnostic without echoing the routing identifier.\n * - **neither shape**: returns `format_options: []`; there is nothing to\n * project and nothing to lose.\n *\n * Pure and subtractive: unlike {@link augmentProductWithFormatOptions}\n * (which preserves `format_ids[]`), this drops it — the opt-in narrowing for\n * a consumer that has fully migrated. Complements the write-side\n * non-invertibility tracked at adcontextprotocol/adcp#4842 — this is the\n * read-side transparency half.\n */\nexport function toCanonicalOnlyProduct<P extends V1Product>(\n product: P,\n options?: V1ToV2ProjectionOptions\n): { product: CanonicalOnlyProduct<P>; diagnostics: ProjectionDiagnostic[] } {\n const existing = (product as unknown as { format_options?: unknown }).format_options;\n\n // v2-native: the seller already sent format_options[]. Drop the\n // redundant v1 fallback, but flag any legacy ref no v1_format_ref covers.\n if (Array.isArray(existing)) {\n const formatOptions = existing as V2ProductFormatDeclaration[];\n const diagnostics: ProjectionDiagnostic[] = [];\n const inputIds = Array.isArray(product.format_ids) ? product.format_ids : [];\n if (inputIds.length > 0) {\n const covered = new Set<string>();\n for (const opt of formatOptions) {\n const refs = Array.isArray(opt?.v1_format_ref) ? opt.v1_format_ref : [];\n for (const ref of refs) covered.add(formatRefCoverageKey(ref));\n }\n for (let k = 0; k < inputIds.length; k++) {\n const fid = inputIds[k]!;\n if (!covered.has(formatRefCoverageKey(fid))) {\n diagnostics.push({\n source: 'sdk',\n sdk_id: SDK_ID,\n field: `products[${product.product_id}].format_options`,\n code: 'LEGACY_FORMAT_ID_DROPPED_UNMAPPED',\n error: {\n details: {\n product_id: product.product_id,\n resolution_failure: 'unmapped_legacy_format',\n },\n },\n });\n }\n }\n }\n const { format_ids: _dropV2, ...rest } = product as P & { format_ids?: unknown };\n void _dropV2;\n return {\n product: {\n ...rest,\n format_options: canonicalDeclarations(formatOptions),\n ...(Array.isArray((product as Record<string, unknown>).placements)\n ? { placements: canonicalPlacements(product as Record<string, unknown>, options, diagnostics) }\n : {}),\n } as CanonicalOnlyProduct<P>,\n diagnostics: diagnostics.map(canonicalDiagnostic),\n };\n }\n\n // v1 shape: project. projectV1ProductToV2 already omits format_ids and\n // emits a diagnostic for every ref it couldn't map.\n if (Array.isArray(product.format_ids)) {\n const { v2, diagnostics } = projectV1ProductToV2(product, options);\n const { format_ids: _dropV1, ...rest } = product as P & { format_ids?: unknown };\n void _dropV1;\n return {\n product: {\n ...(rest as Omit<P, 'format_ids'>),\n format_options: canonicalDeclarations(v2.format_options),\n ...(Array.isArray((product as Record<string, unknown>).placements)\n ? { placements: canonicalPlacements(product as Record<string, unknown>, options, diagnostics) }\n : {}),\n } as CanonicalOnlyProduct<P>,\n diagnostics: diagnostics.map(canonicalDiagnostic),\n };\n }\n\n // Neither shape — nothing to project, nothing to lose.\n const { format_ids: _dropNone, ...rest } = product as P & { format_ids?: unknown };\n void _dropNone;\n const diagnostics: ProjectionDiagnostic[] = [];\n return {\n product: {\n ...(rest as Omit<P, 'format_ids'>),\n format_options: [],\n ...(Array.isArray((product as Record<string, unknown>).placements)\n ? { placements: canonicalPlacements(product as Record<string, unknown>, options, diagnostics) }\n : {}),\n } as CanonicalOnlyProduct<P>,\n diagnostics: diagnostics.map(canonicalDiagnostic),\n };\n}\n\n/**\n * Reduce every Product in a `get_products` response to the canonical-only\n * shape — `format_options[]` present, `format_ids[]` dropped. Returns\n * `{ response, diagnostics }` so callers surface projection diagnostics\n * alongside the response's existing `errors[]`.\n *\n * Response-level counterpart to {@link toCanonicalOnlyProduct}; same\n * fail-closed guarantee, aggregated across products. A wholly unmappable\n * legacy product cannot be represented as a canonical Product because the\n * protocol requires `format_options` to contain at least one declaration. It\n * is therefore omitted from the canonical list and surfaced through the\n * response's portable `errors[]` plus the SDK convenience diagnostics. A\n * partially mappable product remains with its mapped options and advisories\n * for the refs that could not be projected.\n */\nexport function toCanonicalOnlyResponse<R extends { products?: V1Product[] }>(\n response: R,\n options?: V1ToV2ProjectionOptions\n): {\n response: Omit<R, 'products'> & { products: CanonicalOnlyProduct<V1Product>[]; errors?: unknown[] };\n diagnostics: ProjectionDiagnostic[];\n} {\n if (!Array.isArray(response?.products)) {\n return {\n response: { ...response, products: [] } as Omit<R, 'products'> & {\n products: CanonicalOnlyProduct<V1Product>[];\n errors?: unknown[];\n },\n diagnostics: [],\n };\n }\n const out: CanonicalOnlyProduct<V1Product>[] = [];\n const diagnostics: ProjectionDiagnostic[] = [];\n const originalToOutputIndex = new Map<number, number | undefined>();\n for (let productIndex = 0; productIndex < response.products.length; productIndex++) {\n const p = response.products[productIndex]!;\n const { product, diagnostics: rawDiagnostics } = toCanonicalOnlyProduct(p, options);\n const hasEmptyPlacement = hasEmptyPlacementFormatOptions(product);\n const keep = product.format_options.length > 0 && !hasEmptyPlacement;\n const outputIndex = keep ? out.length : undefined;\n originalToOutputIndex.set(productIndex, outputIndex);\n const d = rawDiagnostics.map(diagnostic => ({\n ...diagnostic,\n field: keep ? diagnostic.field.replace(/^products\\[[^\\]]+\\]/, `products[${outputIndex}]`) : 'products',\n error: keep\n ? diagnostic.error\n : {\n details: {\n ...diagnostic.error.details,\n product_id: p.product_id,\n },\n },\n })) as ProjectionDiagnostic[];\n if (!keep && d.length === 0) {\n const reason = hasEmptyPlacement\n ? 'nested_placement_format_list_empty'\n : Array.isArray((p as Record<string, unknown>).format_options)\n ? 'canonical_format_list_empty'\n : Array.isArray(p.format_ids)\n ? 'legacy_format_list_empty'\n : 'missing_format_declaration';\n d.push({\n ...canonicalFormatsUnavailableForProduct(p, reason),\n field: 'products',\n });\n }\n diagnostics.push(...d);\n if (keep) out.push(product);\n }\n const remappedExistingErrors = remapExistingProductErrors(\n (response as { errors?: unknown }).errors,\n originalToOutputIndex,\n response.products\n );\n const errors = mergeProjectionErrors(remappedExistingErrors, diagnostics);\n return {\n response: {\n ...response,\n products: out,\n ...(errors.length > 0 ? { errors } : {}),\n } as Omit<R, 'products'> & { products: CanonicalOnlyProduct<V1Product>[]; errors?: unknown[] },\n diagnostics,\n };\n}\n"],"mappings":"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","names":["diagnostics","rest"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/v2/projection/augment-response.ts"],"sourcesContent":["/**\n * Buyer-side helpers that augment a v1-shaped agent response with v2\n * `format_options[]` derived from the existing `format_ids[]` on each\n * Product.\n *\n * Buyers who want the canonical creative-format model call\n * `withFormatOptions(response)` and read `format_options` instead of\n * relying only on legacy `format_ids`.\n *\n * The SDK also auto-projects compatible `AgentClient.getProducts()`\n * responses; this helper remains useful for cached responses, fixtures,\n * upstream seller/storefront composition, and explicit migration code.\n *\n * Pure functions — no IO, no caching. Each Product is projected\n * independently; diagnostics aggregate so a multi-product response\n * surfaces every projection issue at once. The helpers preserve the\n * input shape verbatim and add `format_options[]` (additive). They do\n * NOT drop `format_ids[]` — that's the 8.0 narrowing. To DROP\n * `format_ids[]` once a consumer has fully migrated, use\n * `toCanonicalOnlyProduct` / `toCanonicalOnlyResponse`.\n */\n\nimport type { V1Product, V1FormatId, V2ProductFormatDeclaration, ProjectionDiagnostic } from './types';\nimport { projectV1ProductToV2 } from './v1-to-v2';\nimport type { V1ToV2ProjectionOptions } from './v1-to-v2';\nimport { LIBRARY_VERSION } from '../../version';\nimport { canonicalize as canonicalizeJson } from '../../utils/jcs';\nimport { concealLegacyFormatRefs } from './legacy-metadata';\nimport type { CanonicalFormatDeclaration } from './legacy-metadata';\nimport { legacyRoutesForProduct } from './legacy-routes';\nimport type { CanonicalFormatLegacyRoute } from './legacy-routes';\n\nconst SDK_ID = `@adcp/sdk@${LIBRARY_VERSION}`;\nconst DIRECT_LEGACY_FORMAT_IDENTITY_KEYS = new Set(['agenturl', 'formatid', 'formatids', 'v1formatref']);\n\nfunction canonicalDiagnostic(diagnostic: ProjectionDiagnostic): ProjectionDiagnostic {\n return {\n ...diagnostic,\n // A source `format_ids[i]` index is not an index into the projected\n // `format_options[]`: earlier source refs may have failed while later refs\n // projected successfully. Point at the canonical collection instead of\n // claiming that a successful projected option is the failing value.\n field: diagnostic.field.replace(/\\.format_ids\\[\\d+\\]/g, '.format_options'),\n };\n}\n\n/** Protocol Error shape used for portable response-level projection advisories. */\nexport interface CanonicalProjectionError {\n code: ProjectionDiagnostic['code'];\n message: string;\n field: string;\n recovery: 'correctable';\n source: 'sdk';\n sdk_id: string;\n details: ProjectionDiagnostic['error']['details'];\n}\n\nfunction projectionErrorMessage(code: ProjectionDiagnostic['code']): string {\n switch (code) {\n case 'CANONICAL_PRODUCT_FORMATS_UNAVAILABLE':\n return 'Product has no format declaration representable on the canonical-only surface';\n case 'FORMAT_PROJECTION_FAILED':\n return 'Legacy creative format could not be projected to a canonical declaration';\n case 'FORMAT_DECLARATION_V1_AMBIGUOUS':\n return 'Canonical creative format has no unambiguous legacy declaration';\n case 'FORMAT_DECLARATION_V1_NOT_APPLICABLE':\n return 'Canonical-only creative format cannot be represented on a legacy format path';\n case 'CANONICAL_NOT_V1_TRANSLATABLE':\n return 'Canonical creative format has no legacy representation';\n case 'FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE':\n return 'Canonical multi-size format has incomplete legacy coverage';\n case 'LEGACY_FORMAT_ID_DROPPED_UNMAPPED':\n return 'Redundant legacy creative identity has no canonical counterpart';\n }\n}\n\n/** Flatten the projector's internal diagnostic into the protocol `Error` shape. */\nexport function projectionDiagnosticToError(diagnostic: ProjectionDiagnostic): CanonicalProjectionError {\n return {\n code: diagnostic.code,\n message: projectionErrorMessage(diagnostic.code),\n field: diagnostic.field,\n recovery: 'correctable',\n source: diagnostic.source,\n sdk_id: diagnostic.sdk_id,\n details: diagnostic.error.details,\n } as CanonicalProjectionError;\n}\n\nfunction canonicalFormatsUnavailableForProduct(\n product: V1Product,\n reason: Extract<ProjectionDiagnostic, { code: 'CANONICAL_PRODUCT_FORMATS_UNAVAILABLE' }>['error']['details']['reason']\n): ProjectionDiagnostic {\n return {\n source: 'sdk',\n sdk_id: SDK_ID,\n field: `products[${product.product_id}].format_options`,\n code: 'CANONICAL_PRODUCT_FORMATS_UNAVAILABLE',\n error: {\n details: {\n product_id: product.product_id,\n reason,\n },\n },\n };\n}\n\nfunction errorIdentity(value: Record<string, unknown>): string | undefined {\n if (typeof value.code !== 'string' || typeof value.field !== 'string') return undefined;\n try {\n return `${value.code}\\u0000${value.field}\\u0000${canonicalizeJson(value.details ?? null)}`;\n } catch {\n // Preserve unreadable third-party errors instead of falsely deduplicating.\n return undefined;\n }\n}\n\nfunction mergeProjectionErrors(existing: unknown, diagnostics: readonly ProjectionDiagnostic[]): unknown[] {\n const merged = Array.isArray(existing) ? [...existing] : [];\n const seen = new Set<string>();\n for (const value of merged) {\n if (!value || typeof value !== 'object' || Array.isArray(value)) continue;\n const record = value as Record<string, unknown>;\n const key = errorIdentity(record);\n if (key) seen.add(key);\n }\n for (const diagnostic of diagnostics) {\n const error = projectionDiagnosticToError(diagnostic) as unknown as Record<string, unknown>;\n const key = errorIdentity(error)!;\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(error);\n }\n return merged;\n}\n\nfunction remapExistingProductErrors(\n existing: unknown,\n originalToOutputIndex: ReadonlyMap<number, number | undefined>,\n products: readonly V1Product[]\n): unknown {\n if (!Array.isArray(existing)) return existing;\n return existing.map(value => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return value;\n const record = value as Record<string, unknown>;\n let issuesChanged = false;\n const issues = Array.isArray(record.issues)\n ? record.issues.map(issue => {\n if (!issue || typeof issue !== 'object' || Array.isArray(issue)) return issue;\n const issueRecord = issue as Record<string, unknown>;\n if (typeof issueRecord.pointer !== 'string') return issue;\n const pointerMatch = /^\\/products\\/(\\d+)(\\/.*)?$/.exec(issueRecord.pointer);\n if (!pointerMatch) return issue;\n const originalIssueIndex = Number(pointerMatch[1]);\n if (!originalToOutputIndex.has(originalIssueIndex)) return issue;\n const outputIssueIndex = originalToOutputIndex.get(originalIssueIndex);\n issuesChanged = true;\n return {\n ...issueRecord,\n pointer:\n outputIssueIndex === undefined ? '/products' : `/products/${outputIssueIndex}${pointerMatch[2] ?? ''}`,\n };\n })\n : record.issues;\n const withIssues = issuesChanged ? { ...record, issues } : record;\n if (typeof record.field !== 'string') return issuesChanged ? withIssues : value;\n const match = /^products\\[(\\d+)\\](.*)$/.exec(record.field);\n if (!match) return issuesChanged ? withIssues : value;\n const originalIndex = Number(match[1]);\n if (!originalToOutputIndex.has(originalIndex)) return issuesChanged ? withIssues : value;\n const outputIndex = originalToOutputIndex.get(originalIndex);\n if (outputIndex !== undefined) {\n return { ...withIssues, field: `products[${outputIndex}]${match[2] ?? ''}` };\n }\n const productId = products[originalIndex]?.product_id;\n const details =\n record.details && typeof record.details === 'object' && !Array.isArray(record.details)\n ? { ...(record.details as Record<string, unknown>) }\n : {};\n if (typeof productId === 'string' && details.product_id === undefined) details.product_id = productId;\n return { ...withIssues, field: 'products', ...(Object.keys(details).length > 0 ? { details } : {}) };\n });\n}\n\nfunction hasEmptyPlacementFormatOptions(product: CanonicalOnlyProduct<V1Product>): boolean {\n const placements = (product as Record<string, unknown>).placements;\n if (!Array.isArray(placements)) return false;\n return placements.some(value => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return false;\n const options = (value as Record<string, unknown>).format_options;\n return Array.isArray(options) && options.length === 0;\n });\n}\n\n/**\n * A Product that has been augmented with `format_options[]` while\n * preserving the original `format_ids[]`. Carries the projection\n * diagnostics that were generated mapping each `format_id` so the\n * buyer can see what (if anything) didn't project cleanly.\n *\n * **Write-side bridge.** After picking a `format_options[i]` entry,\n * use {@link formatIdsFromOptions} (from `@adcp/sdk/v2/projection`)\n * to extract the `format_ids[]` value for a `create_media_buy`\n * package. Inlining `decl.v1_format_ref` works but bypasses the\n * fail-closed semantics (canonical_formats_only / inherently-v2\n * canonical → throw). The spec gap that forces this bridge is tracked\n * at adcontextprotocol/adcp#4842.\n *\n * @see formatIdsFromOptions\n * @see formatIdsForCapability\n */\nexport type V2AugmentedProduct<P> = P & {\n format_options: V2ProductFormatDeclaration[];\n};\n\n/**\n * Augment a single Product. Idempotent — when `format_options[]` is\n * already present (the seller is v2-native), passes the Product\n * through unchanged. Otherwise projects from `format_ids[]`.\n *\n * Returns `{ product, diagnostics }`. `diagnostics` is empty for a\n * clean projection; populated when individual format_ids don't have\n * a v2 mapping (catalog gap, structural unreachability, etc.).\n *\n * @see toCanonicalOnlyProduct — the canonical-only counterpart that DROPS\n * `format_ids[]` for a fully-migrated consumer.\n */\nexport function augmentProductWithFormatOptions<P extends V1Product>(\n product: P,\n options?: V1ToV2ProjectionOptions\n): { product: V2AugmentedProduct<P>; diagnostics: ProjectionDiagnostic[] } {\n // Already v2-shaped (seller sent format_options directly) — pass through.\n const existing = (product as unknown as { format_options?: unknown }).format_options;\n if (Array.isArray(existing)) {\n return {\n product: product as V2AugmentedProduct<P>,\n diagnostics: [],\n };\n }\n // v1 shape — project to add format_options[].\n if (!Array.isArray(product.format_ids)) {\n // Neither shape — nothing to project. Return as-is with an empty\n // format_options so the buyer doesn't have to special-case.\n return {\n product: { ...product, format_options: [] },\n diagnostics: [],\n };\n }\n const { v2, diagnostics } = projectV1ProductToV2(product, options);\n // Preserve the original product shape (especially format_ids); just\n // add format_options.\n return {\n product: {\n ...product,\n format_options: v2.format_options,\n },\n diagnostics,\n };\n}\n\n/**\n * Augment every Product in a `get_products` response with\n * `format_options[]`. Returns `{ response, diagnostics }` so callers\n * can surface projection diagnostics alongside the response's existing\n * `errors[]` array (or filter by `source: 'sdk'` to distinguish SDK\n * diagnostics from seller-emitted errors).\n *\n * Idempotent: if the seller is v2-native and every Product already\n * carries `format_options[]`, returns the response verbatim with no\n * diagnostics.\n *\n * @see toCanonicalOnlyResponse — the canonical-only counterpart that DROPS\n * `format_ids[]` for a fully-migrated consumer.\n */\nexport function withFormatOptions<R extends { products?: V1Product[] }>(\n response: R,\n options?: V1ToV2ProjectionOptions\n): { response: R & { products: V2AugmentedProduct<V1Product>[] }; diagnostics: ProjectionDiagnostic[] } {\n if (!Array.isArray(response?.products)) {\n return {\n response: { ...response, products: [] } as R & { products: V2AugmentedProduct<V1Product>[] },\n diagnostics: [],\n };\n }\n const out: V2AugmentedProduct<V1Product>[] = [];\n const diagnostics: ProjectionDiagnostic[] = [];\n for (const p of response.products) {\n const { product, diagnostics: d } = augmentProductWithFormatOptions(p, options);\n out.push(product);\n diagnostics.push(...d);\n }\n return {\n response: { ...response, products: out } as R & { products: V2AugmentedProduct<V1Product>[] },\n diagnostics,\n };\n}\n\n/**\n * An additive canonical Product: canonical declarations contain no legacy\n * routing identity, while the Product's top-level `format_ids[]` remains\n * available to compatibility consumers.\n */\nexport type AdditiveCanonicalProduct<P> = Omit<P, 'format_options'> & {\n format_options: CanonicalFormatDeclaration[];\n};\n\nfunction assertNoDirectLegacyFormatAliases(declarations: readonly V2ProductFormatDeclaration[]): void {\n for (let index = 0; index < declarations.length; index++) {\n const declaration = declarations[index] as unknown as Record<string, unknown>;\n for (const field of Object.keys(declaration)) {\n if (\n field !== 'v1_format_ref' &&\n DIRECT_LEGACY_FORMAT_IDENTITY_KEYS.has(field.replaceAll('_', '').toLowerCase())\n ) {\n throw new TypeError(\n `format_options[${index}] must not use legacy identity field ${field}; use v1_format_ref for migration routing`\n );\n }\n }\n }\n}\n\n/**\n * Project a Product to an additive, URL-free canonical surface.\n *\n * Unlike {@link augmentProductWithFormatOptions}, this always returns fresh\n * `format_options[]` declarations with `v1_format_ref` concealed. Unlike\n * {@link toCanonicalOnlyProduct}, it preserves the Product's top-level\n * `format_ids[]`. Exact canonical-to-legacy downgrade identity is returned\n * separately as JSON-safe {@link CanonicalFormatLegacyRoute} sidecars.\n *\n * Extract `routes` before any JSON round-trip — WeakMap metadata is gone after\n * deserialization. This helper enforces that ordering internally; persist its\n * returned `routes` whenever a canonical selection may cross a process boundary\n * before being forwarded to a legacy seller. Rebuild the write-side resolver\n * with `canonicalFormatLegacyResolverFromRoutes(restoredRoutes)`.\n *\n * @throws TypeError when a canonical declaration uses a direct legacy identity\n * alias such as `agent_url` or `agentUrl` instead of `v1_format_ref`.\n */\nexport function toAdditiveCanonicalProduct<P extends V1Product>(\n product: P,\n options?: V1ToV2ProjectionOptions\n): {\n product: AdditiveCanonicalProduct<P>;\n diagnostics: ProjectionDiagnostic[];\n routes: CanonicalFormatLegacyRoute[];\n} {\n const { product: augmented, diagnostics } = augmentProductWithFormatOptions(product, options);\n const routes = legacyRoutesForProduct(product.product_id, augmented.format_options);\n assertNoDirectLegacyFormatAliases(augmented.format_options);\n return {\n product: {\n ...augmented,\n format_options: canonicalDeclarations(augmented.format_options),\n } as AdditiveCanonicalProduct<P>,\n diagnostics,\n routes,\n };\n}\n\n/**\n * Response-level companion to {@link toAdditiveCanonicalProduct}. Projects\n * every Product and accumulates its serializable legacy routes.\n */\nexport function withAdditiveCanonicalFormatOptions<R extends { products?: V1Product[] }>(\n response: R,\n options?: V1ToV2ProjectionOptions\n): {\n response: Omit<R, 'products'> & { products: AdditiveCanonicalProduct<V1Product>[] };\n diagnostics: ProjectionDiagnostic[];\n routes: CanonicalFormatLegacyRoute[];\n} {\n if (!Array.isArray(response?.products)) {\n return {\n response: { ...response, products: [] } as Omit<R, 'products'> & {\n products: AdditiveCanonicalProduct<V1Product>[];\n },\n diagnostics: [],\n routes: [],\n };\n }\n const products: AdditiveCanonicalProduct<V1Product>[] = [];\n const diagnostics: ProjectionDiagnostic[] = [];\n const routes: CanonicalFormatLegacyRoute[] = [];\n for (const sourceProduct of response.products) {\n const projected = toAdditiveCanonicalProduct(sourceProduct, options);\n products.push(projected.product);\n diagnostics.push(...projected.diagnostics);\n routes.push(...projected.routes);\n }\n return {\n response: { ...response, products } as Omit<R, 'products'> & {\n products: AdditiveCanonicalProduct<V1Product>[];\n },\n diagnostics,\n routes,\n };\n}\n\n/**\n * A Product reduced to the canonical creative-format surface:\n * `format_options[]` only, with the legacy `format_ids[]` removed. The\n * read-side counterpart to a fully-migrated consumer — naive downstream\n * code can no longer fall back to the stale `{ agent_url, id }` shape and\n * silently bypass the canonical model.\n */\nexport type CanonicalOnlyProduct<P> = Omit<P, 'format_ids'> & {\n format_ids?: never;\n format_options: CanonicalFormatDeclaration[];\n};\n\nfunction canonicalDeclarations(values: readonly V2ProductFormatDeclaration[]): CanonicalFormatDeclaration[] {\n return values.map(value => concealLegacyFormatRefs(value));\n}\n\nfunction canonicalPlacements(\n product: Record<string, unknown>,\n options: V1ToV2ProjectionOptions | undefined,\n diagnostics: ProjectionDiagnostic[]\n): unknown {\n if (!Array.isArray(product.placements)) return product.placements;\n return product.placements.map((value, placementIndex) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return value;\n const placement = value as Record<string, unknown>;\n const { format_ids: _drop, ...rest } = placement;\n void _drop;\n const hasLegacyFormats = Array.isArray(placement.format_ids);\n const hasCanonicalFormats = Array.isArray(placement.format_options);\n if (!hasLegacyFormats && !hasCanonicalFormats) return rest;\n\n const productId = typeof product.product_id === 'string' ? product.product_id : '(unknown)';\n const placementId = typeof placement.placement_id === 'string' ? placement.placement_id : String(placementIndex);\n const pseudoProduct = {\n product_id: `${productId}:placement:${placementId}`,\n name: typeof placement.name === 'string' ? placement.name : placementId,\n description: `Nested placement ${placementId}`,\n ...(hasLegacyFormats ? { format_ids: placement.format_ids } : {}),\n ...(hasCanonicalFormats ? { format_options: placement.format_options } : {}),\n } as unknown as V1Product;\n const projected = toCanonicalOnlyProduct(pseudoProduct, options);\n for (const diagnostic of projected.diagnostics) {\n diagnostics.push({\n ...diagnostic,\n field: diagnostic.field.replace(/^products\\[[^\\]]+\\]/, `products[${productId}].placements[${placementIndex}]`),\n });\n }\n return {\n ...rest,\n format_options: projected.product.format_options,\n };\n });\n}\n\n/**\n * Identity key for a `format_id` ref used by the coverage check.\n * Trailing-slash-insensitive on `agent_url` (folds the AAO host's slash /\n * no-slash forms, per `catalog.ts`'s `normalizeAgentUrl`), and includes the\n * dimensional discriminators so multi-size declarations sharing one\n * `{ agent_url, id }` but differing by size/duration are NOT collapsed —\n * the same key shape `write-side.ts` uses for v1 ref de-dup. Without the\n * size half, a `format_ids[]` entry for a size no `v1_format_ref` covers\n * would read as covered and be dropped silently.\n */\nfunction formatRefCoverageKey(ref: V1FormatId): string {\n const url = ref.agent_url && !ref.agent_url.endsWith('/') ? ref.agent_url + '/' : ref.agent_url;\n return `${url}::${ref.id}::${ref.width ?? ''}x${ref.height ?? ''}::${ref.duration_ms ?? ''}`;\n}\n\n/**\n * Project a single Product to the canonical-only shape: `format_options[]`\n * present, `format_ids[]` dropped.\n *\n * **Dropping legacy never silently loses a format.** Every input\n * `format_id` is either represented in the returned `format_options[]` or\n * surfaced in `diagnostics` — never discarded without a trace:\n *\n * - **v1-shaped input** (`format_ids[]`, no `format_options[]`): runs the\n * v1 → v2 projection. Mapped refs become `format_options[]`; any ref\n * the projection can't map is surfaced as `FORMAT_PROJECTION_FAILED`.\n * - **v2-native input** (`format_options[]` already present): keeps the\n * seller's canonical surface and drops the redundant v1 fallback. If a\n * legacy routing entry exists that no canonical option covers, it\n * surfaces a canonical-safe `LEGACY_FORMAT_ID_DROPPED_UNMAPPED`\n * diagnostic without echoing the routing identifier.\n * - **neither shape**: returns `format_options: []`; there is nothing to\n * project and nothing to lose.\n *\n * Pure and subtractive: unlike {@link augmentProductWithFormatOptions}\n * (which preserves `format_ids[]`), this drops it — the opt-in narrowing for\n * a consumer that has fully migrated. Complements the write-side\n * non-invertibility tracked at adcontextprotocol/adcp#4842 — this is the\n * read-side transparency half.\n */\nexport function toCanonicalOnlyProduct<P extends V1Product>(\n product: P,\n options?: V1ToV2ProjectionOptions\n): { product: CanonicalOnlyProduct<P>; diagnostics: ProjectionDiagnostic[] } {\n const existing = (product as unknown as { format_options?: unknown }).format_options;\n\n // v2-native: the seller already sent format_options[]. Drop the\n // redundant v1 fallback, but flag any legacy ref no v1_format_ref covers.\n if (Array.isArray(existing)) {\n const formatOptions = existing as V2ProductFormatDeclaration[];\n const diagnostics: ProjectionDiagnostic[] = [];\n const inputIds = Array.isArray(product.format_ids) ? product.format_ids : [];\n if (inputIds.length > 0) {\n const covered = new Set<string>();\n for (const opt of formatOptions) {\n const refs = Array.isArray(opt?.v1_format_ref) ? opt.v1_format_ref : [];\n for (const ref of refs) covered.add(formatRefCoverageKey(ref));\n }\n for (let k = 0; k < inputIds.length; k++) {\n const fid = inputIds[k]!;\n if (!covered.has(formatRefCoverageKey(fid))) {\n diagnostics.push({\n source: 'sdk',\n sdk_id: SDK_ID,\n field: `products[${product.product_id}].format_options`,\n code: 'LEGACY_FORMAT_ID_DROPPED_UNMAPPED',\n error: {\n details: {\n product_id: product.product_id,\n resolution_failure: 'unmapped_legacy_format',\n },\n },\n });\n }\n }\n }\n const { format_ids: _dropV2, ...rest } = product as P & { format_ids?: unknown };\n void _dropV2;\n return {\n product: {\n ...rest,\n format_options: canonicalDeclarations(formatOptions),\n ...(Array.isArray((product as Record<string, unknown>).placements)\n ? { placements: canonicalPlacements(product as Record<string, unknown>, options, diagnostics) }\n : {}),\n } as CanonicalOnlyProduct<P>,\n diagnostics: diagnostics.map(canonicalDiagnostic),\n };\n }\n\n // v1 shape: project. projectV1ProductToV2 already omits format_ids and\n // emits a diagnostic for every ref it couldn't map.\n if (Array.isArray(product.format_ids)) {\n const { v2, diagnostics } = projectV1ProductToV2(product, options);\n const { format_ids: _dropV1, ...rest } = product as P & { format_ids?: unknown };\n void _dropV1;\n return {\n product: {\n ...(rest as Omit<P, 'format_ids'>),\n format_options: canonicalDeclarations(v2.format_options),\n ...(Array.isArray((product as Record<string, unknown>).placements)\n ? { placements: canonicalPlacements(product as Record<string, unknown>, options, diagnostics) }\n : {}),\n } as CanonicalOnlyProduct<P>,\n diagnostics: diagnostics.map(canonicalDiagnostic),\n };\n }\n\n // Neither shape — nothing to project, nothing to lose.\n const { format_ids: _dropNone, ...rest } = product as P & { format_ids?: unknown };\n void _dropNone;\n const diagnostics: ProjectionDiagnostic[] = [];\n return {\n product: {\n ...(rest as Omit<P, 'format_ids'>),\n format_options: [],\n ...(Array.isArray((product as Record<string, unknown>).placements)\n ? { placements: canonicalPlacements(product as Record<string, unknown>, options, diagnostics) }\n : {}),\n } as CanonicalOnlyProduct<P>,\n diagnostics: diagnostics.map(canonicalDiagnostic),\n };\n}\n\n/**\n * Reduce every Product in a `get_products` response to the canonical-only\n * shape — `format_options[]` present, `format_ids[]` dropped. Returns\n * `{ response, diagnostics }` so callers surface projection diagnostics\n * alongside the response's existing `errors[]`.\n *\n * Response-level counterpart to {@link toCanonicalOnlyProduct}; same\n * fail-closed guarantee, aggregated across products. A wholly unmappable\n * legacy product cannot be represented as a canonical Product because the\n * protocol requires `format_options` to contain at least one declaration. It\n * is therefore omitted from the canonical list and surfaced through the\n * response's portable `errors[]` plus the SDK convenience diagnostics. A\n * partially mappable product remains with its mapped options and advisories\n * for the refs that could not be projected.\n */\nexport function toCanonicalOnlyResponse<R extends { products?: V1Product[] }>(\n response: R,\n options?: V1ToV2ProjectionOptions\n): {\n response: Omit<R, 'products'> & { products: CanonicalOnlyProduct<V1Product>[]; errors?: unknown[] };\n diagnostics: ProjectionDiagnostic[];\n} {\n if (!Array.isArray(response?.products)) {\n return {\n response: { ...response, products: [] } as Omit<R, 'products'> & {\n products: CanonicalOnlyProduct<V1Product>[];\n errors?: unknown[];\n },\n diagnostics: [],\n };\n }\n const out: CanonicalOnlyProduct<V1Product>[] = [];\n const diagnostics: ProjectionDiagnostic[] = [];\n const originalToOutputIndex = new Map<number, number | undefined>();\n for (let productIndex = 0; productIndex < response.products.length; productIndex++) {\n const p = response.products[productIndex]!;\n const { product, diagnostics: rawDiagnostics } = toCanonicalOnlyProduct(p, options);\n const hasEmptyPlacement = hasEmptyPlacementFormatOptions(product);\n const keep = product.format_options.length > 0 && !hasEmptyPlacement;\n const outputIndex = keep ? out.length : undefined;\n originalToOutputIndex.set(productIndex, outputIndex);\n const d = rawDiagnostics.map(diagnostic => ({\n ...diagnostic,\n field: keep ? diagnostic.field.replace(/^products\\[[^\\]]+\\]/, `products[${outputIndex}]`) : 'products',\n error: keep\n ? diagnostic.error\n : {\n details: {\n ...diagnostic.error.details,\n product_id: p.product_id,\n },\n },\n })) as ProjectionDiagnostic[];\n if (!keep && d.length === 0) {\n const reason = hasEmptyPlacement\n ? 'nested_placement_format_list_empty'\n : Array.isArray((p as Record<string, unknown>).format_options)\n ? 'canonical_format_list_empty'\n : Array.isArray(p.format_ids)\n ? 'legacy_format_list_empty'\n : 'missing_format_declaration';\n d.push({\n ...canonicalFormatsUnavailableForProduct(p, reason),\n field: 'products',\n });\n }\n diagnostics.push(...d);\n if (keep) out.push(product);\n }\n const remappedExistingErrors = remapExistingProductErrors(\n (response as { errors?: unknown }).errors,\n originalToOutputIndex,\n response.products\n );\n const errors = mergeProjectionErrors(remappedExistingErrors, diagnostics);\n return {\n response: {\n ...response,\n products: out,\n ...(errors.length > 0 ? { errors } : {}),\n } as Omit<R, 'products'> & { products: CanonicalOnlyProduct<V1Product>[]; errors?: unknown[] },\n diagnostics,\n };\n}\n"],"mappings":"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","names":["diagnostics","rest"]}
|
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
* can read the canonical model regardless of the seller's wire
|
|
20
20
|
* version. Additive — `format_ids[]` is preserved.
|
|
21
21
|
*
|
|
22
|
+
* - `toAdditiveCanonicalProduct` — additive projection with URL-free
|
|
23
|
+
* `format_options[]`, preserved top-level `format_ids[]`, and explicit
|
|
24
|
+
* serializable legacy-route sidecars for later forwarding.
|
|
25
|
+
* `withAdditiveCanonicalFormatOptions` is the response-level companion.
|
|
26
|
+
*
|
|
22
27
|
* - `toCanonicalOnlyProduct` / `toCanonicalOnlyResponse` — the
|
|
23
28
|
* read-side narrowing for a fully-migrated consumer. Returns
|
|
24
29
|
* `format_options[]` with `format_ids[]` dropped, surfacing a
|
|
@@ -37,7 +42,7 @@ export type { V1ToV2Result, V1ToV2ProjectionOptions, BareFormatIdResolveOptions,
|
|
|
37
42
|
export { projectV2ProductToV1 } from './v2-to-v1.mjs';
|
|
38
43
|
export type { V2ToV1Result, V2ToV1ProjectionOptions, CanonicalFormatLegacyResolver, CanonicalFormatLegacyResolutionContext, CanonicalProductFormatLegacyResolutionContext, CanonicalCreativeFormatLegacyResolutionContext, CanonicalSelectorFormatLegacyResolutionContext, } from './v2-to-v1.mjs';
|
|
39
44
|
export { canonicalFormatLegacyResolverFromRoutes, legacyRoutesForProduct, type CanonicalFormatLegacyRoute, } from './legacy-routes.mjs';
|
|
40
|
-
export { augmentProductWithFormatOptions, withFormatOptions, toCanonicalOnlyProduct, toCanonicalOnlyResponse, type V2AugmentedProduct, type CanonicalOnlyProduct, } from './augment-response.mjs';
|
|
45
|
+
export { augmentProductWithFormatOptions, withFormatOptions, toAdditiveCanonicalProduct, withAdditiveCanonicalFormatOptions, toCanonicalOnlyProduct, toCanonicalOnlyResponse, type V2AugmentedProduct, type AdditiveCanonicalProduct, type CanonicalOnlyProduct, } from './augment-response.mjs';
|
|
41
46
|
export { CanonicalFormat, audioDaastFormatDeclaration, audioHostedFormatDeclaration, agentPlacementFormatDeclaration, canonicalFormatDeclaration, customFormatDeclaration, displayTagFormatDeclaration, legacyFormatRef, legacyFormatRefs, html5FormatDeclaration, imageCarouselFormatDeclaration, imageFormatDeclaration, nativeInFeedFormatDeclaration, productCard, productCardDetailed, responsiveCreativeFormatDeclaration, sponsoredPlacementFormatDeclaration, videoHostedFormatDeclaration, videoVastFormatDeclaration, type CanonicalFormatDeclaration, type CanonicalFormatDeclarationFields, type CanonicalFormatKind, type CanonicalFormatParams, type FormatReferenceInput, type ProductCardDetailedFields, type ProductCardFields, } from './builders.mjs';
|
|
42
47
|
export { packageRefsForFormatOptions, packageRefsForCapabilities, legacyFormatIdsFromOptions, tryLegacyFormatIdsFromOptions, legacyFormatIdsForFormatOption, legacyFormatIdsForCapability, FormatOptionRefsLookupError, CapabilityIdsLookupError, type PackageFormatRefs, type PackageCapabilityRefs, type FormatOptionRef, type FormatOptionSelector, type FormatOptionRefsLookupErrorCode, type CapabilityIdsLookupErrorCode, } from './write-side.mjs';
|
|
43
48
|
export type { V1FormatId, V2ProductFormatDeclaration, V2Product, V1Product, ProjectionDiagnostic } from './types.mjs';
|
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
* can read the canonical model regardless of the seller's wire
|
|
20
20
|
* version. Additive — `format_ids[]` is preserved.
|
|
21
21
|
*
|
|
22
|
+
* - `toAdditiveCanonicalProduct` — additive projection with URL-free
|
|
23
|
+
* `format_options[]`, preserved top-level `format_ids[]`, and explicit
|
|
24
|
+
* serializable legacy-route sidecars for later forwarding.
|
|
25
|
+
* `withAdditiveCanonicalFormatOptions` is the response-level companion.
|
|
26
|
+
*
|
|
22
27
|
* - `toCanonicalOnlyProduct` / `toCanonicalOnlyResponse` — the
|
|
23
28
|
* read-side narrowing for a fully-migrated consumer. Returns
|
|
24
29
|
* `format_options[]` with `format_ids[]` dropped, surfacing a
|
|
@@ -37,7 +42,7 @@ export type { V1ToV2Result, V1ToV2ProjectionOptions, BareFormatIdResolveOptions,
|
|
|
37
42
|
export { projectV2ProductToV1 } from './v2-to-v1';
|
|
38
43
|
export type { V2ToV1Result, V2ToV1ProjectionOptions, CanonicalFormatLegacyResolver, CanonicalFormatLegacyResolutionContext, CanonicalProductFormatLegacyResolutionContext, CanonicalCreativeFormatLegacyResolutionContext, CanonicalSelectorFormatLegacyResolutionContext, } from './v2-to-v1';
|
|
39
44
|
export { canonicalFormatLegacyResolverFromRoutes, legacyRoutesForProduct, type CanonicalFormatLegacyRoute, } from './legacy-routes';
|
|
40
|
-
export { augmentProductWithFormatOptions, withFormatOptions, toCanonicalOnlyProduct, toCanonicalOnlyResponse, type V2AugmentedProduct, type CanonicalOnlyProduct, } from './augment-response';
|
|
45
|
+
export { augmentProductWithFormatOptions, withFormatOptions, toAdditiveCanonicalProduct, withAdditiveCanonicalFormatOptions, toCanonicalOnlyProduct, toCanonicalOnlyResponse, type V2AugmentedProduct, type AdditiveCanonicalProduct, type CanonicalOnlyProduct, } from './augment-response';
|
|
41
46
|
export { CanonicalFormat, audioDaastFormatDeclaration, audioHostedFormatDeclaration, agentPlacementFormatDeclaration, canonicalFormatDeclaration, customFormatDeclaration, displayTagFormatDeclaration, legacyFormatRef, legacyFormatRefs, html5FormatDeclaration, imageCarouselFormatDeclaration, imageFormatDeclaration, nativeInFeedFormatDeclaration, productCard, productCardDetailed, responsiveCreativeFormatDeclaration, sponsoredPlacementFormatDeclaration, videoHostedFormatDeclaration, videoVastFormatDeclaration, type CanonicalFormatDeclaration, type CanonicalFormatDeclarationFields, type CanonicalFormatKind, type CanonicalFormatParams, type FormatReferenceInput, type ProductCardDetailedFields, type ProductCardFields, } from './builders';
|
|
42
47
|
export { packageRefsForFormatOptions, packageRefsForCapabilities, legacyFormatIdsFromOptions, tryLegacyFormatIdsFromOptions, legacyFormatIdsForFormatOption, legacyFormatIdsForCapability, FormatOptionRefsLookupError, CapabilityIdsLookupError, type PackageFormatRefs, type PackageCapabilityRefs, type FormatOptionRef, type FormatOptionSelector, type FormatOptionRefsLookupErrorCode, type CapabilityIdsLookupErrorCode, } from './write-side';
|
|
43
48
|
export type { V1FormatId, V2ProductFormatDeclaration, V2Product, V1Product, ProjectionDiagnostic } from './types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/v2/projection/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/v2/projection/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -65,11 +65,13 @@ __export(projection_exports, {
|
|
|
65
65
|
responsiveCreativeFormatDeclaration: () => import_builders.responsiveCreativeFormatDeclaration,
|
|
66
66
|
sponsoredPlacementFormatDeclaration: () => import_builders.sponsoredPlacementFormatDeclaration,
|
|
67
67
|
stripLegacyCreativeIdentity: () => import_creative_delivery.stripLegacyCreativeIdentity,
|
|
68
|
+
toAdditiveCanonicalProduct: () => import_augment_response.toAdditiveCanonicalProduct,
|
|
68
69
|
toCanonicalOnlyProduct: () => import_augment_response.toCanonicalOnlyProduct,
|
|
69
70
|
toCanonicalOnlyResponse: () => import_augment_response.toCanonicalOnlyResponse,
|
|
70
71
|
tryLegacyFormatIdsFromOptions: () => import_write_side.tryLegacyFormatIdsFromOptions,
|
|
71
72
|
videoHostedFormatDeclaration: () => import_builders.videoHostedFormatDeclaration,
|
|
72
73
|
videoVastFormatDeclaration: () => import_builders.videoVastFormatDeclaration,
|
|
74
|
+
withAdditiveCanonicalFormatOptions: () => import_augment_response.withAdditiveCanonicalFormatOptions,
|
|
73
75
|
withFormatOptions: () => import_augment_response.withFormatOptions
|
|
74
76
|
});
|
|
75
77
|
module.exports = __toCommonJS(projection_exports);
|
|
@@ -132,11 +134,13 @@ var import_creative_delivery = require('./creative-delivery.js');
|
|
|
132
134
|
responsiveCreativeFormatDeclaration,
|
|
133
135
|
sponsoredPlacementFormatDeclaration,
|
|
134
136
|
stripLegacyCreativeIdentity,
|
|
137
|
+
toAdditiveCanonicalProduct,
|
|
135
138
|
toCanonicalOnlyProduct,
|
|
136
139
|
toCanonicalOnlyResponse,
|
|
137
140
|
tryLegacyFormatIdsFromOptions,
|
|
138
141
|
videoHostedFormatDeclaration,
|
|
139
142
|
videoVastFormatDeclaration,
|
|
143
|
+
withAdditiveCanonicalFormatOptions,
|
|
140
144
|
withFormatOptions
|
|
141
145
|
});
|
|
142
146
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/v2/projection/index.ts"],"sourcesContent":["/**\n * v1 ↔ v2 Product projection layer (AdCP 3.1).\n *\n * Public surfaces:\n *\n * - `projectV1ProductToV2` / `projectV2ProductToV1` — the symmetric\n * core projections. Read a Product on one side, return a Product\n * on the other plus structured diagnostics (`source: 'sdk'`,\n * normative spec codes + SDK-local codes).\n *\n * - `resolveCanonicalFormatKind` / `canonicalDeclarationFromBareId` —\n * resolve a single bare format-id string (no surrounding Product,\n * no `agent_url`) to its canonical `format_kind` or full declaration.\n * Registry- and catalog-backed; fails closed to `null`.\n *\n * - `withFormatOptions` / `augmentProductWithFormatOptions` —\n * buyer-side response augmentation. Adds `format_options[]` to a\n * v1-shaped get_products response so canonical-format-aware buyers\n * can read the canonical model regardless of the seller's wire\n * version. Additive — `format_ids[]` is preserved.\n *\n * - `toCanonicalOnlyProduct` / `toCanonicalOnlyResponse` — the\n * read-side narrowing for a fully-migrated consumer. Returns\n * `format_options[]` with `format_ids[]` dropped, surfacing a\n * diagnostic for any ref that couldn't be carried over.\n *\n * - Catalog + registry primitives (`lookupV1Format`,\n * `findCatalogEntryByCanonicalAndSize`, registry exports) for\n * callers wiring projection into their own code paths.\n *\n * Legacy-preserving and raw wire projection helpers are exposed only from\n * `@adcp/sdk/v2/projection`. The package root exports the canonical authoring\n * surface so ordinary buyers do not accidentally retain legacy identities.\n */\n\nexport { projectV1ProductToV2, canonicalDeclarationFromBareId, resolveCanonicalFormatKind } from './v1-to-v2';\nexport type {\n V1ToV2Result,\n V1ToV2ProjectionOptions,\n BareFormatIdResolveOptions,\n LegacyFormatConversionContext,\n LegacyFormatConverter,\n} from './v1-to-v2';\n\nexport { projectV2ProductToV1 } from './v2-to-v1';\nexport type {\n V2ToV1Result,\n V2ToV1ProjectionOptions,\n CanonicalFormatLegacyResolver,\n CanonicalFormatLegacyResolutionContext,\n CanonicalProductFormatLegacyResolutionContext,\n CanonicalCreativeFormatLegacyResolutionContext,\n CanonicalSelectorFormatLegacyResolutionContext,\n} from './v2-to-v1';\n\nexport {\n canonicalFormatLegacyResolverFromRoutes,\n legacyRoutesForProduct,\n type CanonicalFormatLegacyRoute,\n} from './legacy-routes';\n\nexport {\n augmentProductWithFormatOptions,\n withFormatOptions,\n toCanonicalOnlyProduct,\n toCanonicalOnlyResponse,\n type V2AugmentedProduct,\n type CanonicalOnlyProduct,\n} from './augment-response';\n\nexport {\n CanonicalFormat,\n audioDaastFormatDeclaration,\n audioHostedFormatDeclaration,\n agentPlacementFormatDeclaration,\n canonicalFormatDeclaration,\n customFormatDeclaration,\n displayTagFormatDeclaration,\n legacyFormatRef,\n legacyFormatRefs,\n html5FormatDeclaration,\n imageCarouselFormatDeclaration,\n imageFormatDeclaration,\n nativeInFeedFormatDeclaration,\n productCard,\n productCardDetailed,\n responsiveCreativeFormatDeclaration,\n sponsoredPlacementFormatDeclaration,\n videoHostedFormatDeclaration,\n videoVastFormatDeclaration,\n type CanonicalFormatDeclaration,\n type CanonicalFormatDeclarationFields,\n type CanonicalFormatKind,\n type CanonicalFormatParams,\n type FormatReferenceInput,\n type ProductCardDetailedFields,\n type ProductCardFields,\n} from './builders';\n\nexport {\n packageRefsForFormatOptions,\n packageRefsForCapabilities,\n legacyFormatIdsFromOptions,\n tryLegacyFormatIdsFromOptions,\n legacyFormatIdsForFormatOption,\n legacyFormatIdsForCapability,\n FormatOptionRefsLookupError,\n CapabilityIdsLookupError,\n type PackageFormatRefs,\n type PackageCapabilityRefs,\n type FormatOptionRef,\n type FormatOptionSelector,\n type FormatOptionRefsLookupErrorCode,\n type CapabilityIdsLookupErrorCode,\n} from './write-side';\n\nexport type { V1FormatId, V2ProductFormatDeclaration, V2Product, V1Product, ProjectionDiagnostic } from './types';\nexport {\n legacyFormatConverterFromCatalogSnapshots,\n canonicalFormatLegacyResolverFromCatalogSnapshots,\n projectionAdaptersFromCatalogSnapshots,\n type ProjectionCatalogAdapters,\n type ProjectionCatalogSnapshot,\n type ProjectionCatalogSource,\n} from './catalog-snapshot';\n\nexport {\n loadCatalog,\n lookupV1Format,\n findCatalogEntryByCanonicalAndSize,\n parseSizedIdTemplate,\n _resetCatalogCache,\n type V1FormatDefinition,\n type CanonicalProjectionRef,\n} from './catalog';\n\nexport { isCanonicalV1Translatable } from './canonical-properties';\n\nexport {\n CreativeFormatProjectionError,\n CreativeFormatCapabilityError,\n projectCreativeForDelivery,\n projectMediaBuyCreativesForDelivery,\n projectSyncCreativesForDelivery,\n stripLegacyCreativeIdentity,\n resolveCreativeFormatWireMode,\n type CreativeFormatSelectorContainer,\n type CanonicalCreativeFormatSelectorContainer,\n type CreativeFormatWireMode,\n type CanonicalCreativeAsset,\n type CanonicalCreativeResponse,\n type CanonicalGetProductsResponse,\n type CanonicalGetProductsRequest,\n type CanonicalCreateMediaBuyRequest,\n type CanonicalCreateMediaBuyResponse,\n type CanonicalCreativeFilters,\n type CanonicalListCreativesRequest,\n type CanonicalListCreativesResponse,\n type CanonicalGetCreativeDeliveryResponse,\n type CanonicalGetMediaBuyDeliveryResponse,\n type CanonicalGetMediaBuysResponse,\n type CanonicalListedCreative,\n type CanonicalPackageRequest,\n type CanonicalPackageUpdate,\n type CanonicalPackage,\n type CanonicalPlacement,\n type CanonicalProduct,\n type CanonicalProjectedCreative,\n type CanonicalSyncCreativesRequest,\n type CanonicalSyncCreativesResponse,\n type CanonicalUpdateMediaBuyRequest,\n type CanonicalUpdateMediaBuyResponse,\n type LegacyCreativeAsset,\n type LegacyProjectedCreative,\n type ProjectedMediaBuyCreativeRequest,\n type ProjectedSyncCreativeRequest,\n type SyncCreativeFormatProjection,\n} from './creative-delivery';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/v2/projection/index.ts"],"sourcesContent":["/**\n * v1 ↔ v2 Product projection layer (AdCP 3.1).\n *\n * Public surfaces:\n *\n * - `projectV1ProductToV2` / `projectV2ProductToV1` — the symmetric\n * core projections. Read a Product on one side, return a Product\n * on the other plus structured diagnostics (`source: 'sdk'`,\n * normative spec codes + SDK-local codes).\n *\n * - `resolveCanonicalFormatKind` / `canonicalDeclarationFromBareId` —\n * resolve a single bare format-id string (no surrounding Product,\n * no `agent_url`) to its canonical `format_kind` or full declaration.\n * Registry- and catalog-backed; fails closed to `null`.\n *\n * - `withFormatOptions` / `augmentProductWithFormatOptions` —\n * buyer-side response augmentation. Adds `format_options[]` to a\n * v1-shaped get_products response so canonical-format-aware buyers\n * can read the canonical model regardless of the seller's wire\n * version. Additive — `format_ids[]` is preserved.\n *\n * - `toAdditiveCanonicalProduct` — additive projection with URL-free\n * `format_options[]`, preserved top-level `format_ids[]`, and explicit\n * serializable legacy-route sidecars for later forwarding.\n * `withAdditiveCanonicalFormatOptions` is the response-level companion.\n *\n * - `toCanonicalOnlyProduct` / `toCanonicalOnlyResponse` — the\n * read-side narrowing for a fully-migrated consumer. Returns\n * `format_options[]` with `format_ids[]` dropped, surfacing a\n * diagnostic for any ref that couldn't be carried over.\n *\n * - Catalog + registry primitives (`lookupV1Format`,\n * `findCatalogEntryByCanonicalAndSize`, registry exports) for\n * callers wiring projection into their own code paths.\n *\n * Legacy-preserving and raw wire projection helpers are exposed only from\n * `@adcp/sdk/v2/projection`. The package root exports the canonical authoring\n * surface so ordinary buyers do not accidentally retain legacy identities.\n */\n\nexport { projectV1ProductToV2, canonicalDeclarationFromBareId, resolveCanonicalFormatKind } from './v1-to-v2';\nexport type {\n V1ToV2Result,\n V1ToV2ProjectionOptions,\n BareFormatIdResolveOptions,\n LegacyFormatConversionContext,\n LegacyFormatConverter,\n} from './v1-to-v2';\n\nexport { projectV2ProductToV1 } from './v2-to-v1';\nexport type {\n V2ToV1Result,\n V2ToV1ProjectionOptions,\n CanonicalFormatLegacyResolver,\n CanonicalFormatLegacyResolutionContext,\n CanonicalProductFormatLegacyResolutionContext,\n CanonicalCreativeFormatLegacyResolutionContext,\n CanonicalSelectorFormatLegacyResolutionContext,\n} from './v2-to-v1';\n\nexport {\n canonicalFormatLegacyResolverFromRoutes,\n legacyRoutesForProduct,\n type CanonicalFormatLegacyRoute,\n} from './legacy-routes';\n\nexport {\n augmentProductWithFormatOptions,\n withFormatOptions,\n toAdditiveCanonicalProduct,\n withAdditiveCanonicalFormatOptions,\n toCanonicalOnlyProduct,\n toCanonicalOnlyResponse,\n type V2AugmentedProduct,\n type AdditiveCanonicalProduct,\n type CanonicalOnlyProduct,\n} from './augment-response';\n\nexport {\n CanonicalFormat,\n audioDaastFormatDeclaration,\n audioHostedFormatDeclaration,\n agentPlacementFormatDeclaration,\n canonicalFormatDeclaration,\n customFormatDeclaration,\n displayTagFormatDeclaration,\n legacyFormatRef,\n legacyFormatRefs,\n html5FormatDeclaration,\n imageCarouselFormatDeclaration,\n imageFormatDeclaration,\n nativeInFeedFormatDeclaration,\n productCard,\n productCardDetailed,\n responsiveCreativeFormatDeclaration,\n sponsoredPlacementFormatDeclaration,\n videoHostedFormatDeclaration,\n videoVastFormatDeclaration,\n type CanonicalFormatDeclaration,\n type CanonicalFormatDeclarationFields,\n type CanonicalFormatKind,\n type CanonicalFormatParams,\n type FormatReferenceInput,\n type ProductCardDetailedFields,\n type ProductCardFields,\n} from './builders';\n\nexport {\n packageRefsForFormatOptions,\n packageRefsForCapabilities,\n legacyFormatIdsFromOptions,\n tryLegacyFormatIdsFromOptions,\n legacyFormatIdsForFormatOption,\n legacyFormatIdsForCapability,\n FormatOptionRefsLookupError,\n CapabilityIdsLookupError,\n type PackageFormatRefs,\n type PackageCapabilityRefs,\n type FormatOptionRef,\n type FormatOptionSelector,\n type FormatOptionRefsLookupErrorCode,\n type CapabilityIdsLookupErrorCode,\n} from './write-side';\n\nexport type { V1FormatId, V2ProductFormatDeclaration, V2Product, V1Product, ProjectionDiagnostic } from './types';\nexport {\n legacyFormatConverterFromCatalogSnapshots,\n canonicalFormatLegacyResolverFromCatalogSnapshots,\n projectionAdaptersFromCatalogSnapshots,\n type ProjectionCatalogAdapters,\n type ProjectionCatalogSnapshot,\n type ProjectionCatalogSource,\n} from './catalog-snapshot';\n\nexport {\n loadCatalog,\n lookupV1Format,\n findCatalogEntryByCanonicalAndSize,\n parseSizedIdTemplate,\n _resetCatalogCache,\n type V1FormatDefinition,\n type CanonicalProjectionRef,\n} from './catalog';\n\nexport { isCanonicalV1Translatable } from './canonical-properties';\n\nexport {\n CreativeFormatProjectionError,\n CreativeFormatCapabilityError,\n projectCreativeForDelivery,\n projectMediaBuyCreativesForDelivery,\n projectSyncCreativesForDelivery,\n stripLegacyCreativeIdentity,\n resolveCreativeFormatWireMode,\n type CreativeFormatSelectorContainer,\n type CanonicalCreativeFormatSelectorContainer,\n type CreativeFormatWireMode,\n type CanonicalCreativeAsset,\n type CanonicalCreativeResponse,\n type CanonicalGetProductsResponse,\n type CanonicalGetProductsRequest,\n type CanonicalCreateMediaBuyRequest,\n type CanonicalCreateMediaBuyResponse,\n type CanonicalCreativeFilters,\n type CanonicalListCreativesRequest,\n type CanonicalListCreativesResponse,\n type CanonicalGetCreativeDeliveryResponse,\n type CanonicalGetMediaBuyDeliveryResponse,\n type CanonicalGetMediaBuysResponse,\n type CanonicalListedCreative,\n type CanonicalPackageRequest,\n type CanonicalPackageUpdate,\n type CanonicalPackage,\n type CanonicalPlacement,\n type CanonicalProduct,\n type CanonicalProjectedCreative,\n type CanonicalSyncCreativesRequest,\n type CanonicalSyncCreativesResponse,\n type CanonicalUpdateMediaBuyRequest,\n type CanonicalUpdateMediaBuyResponse,\n type LegacyCreativeAsset,\n type LegacyProjectedCreative,\n type ProjectedMediaBuyCreativeRequest,\n type ProjectedSyncCreativeRequest,\n type SyncCreativeFormatProjection,\n} from './creative-delivery';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwCA,sBAAiG;AASjG,sBAAqC;AAWrC,2BAIO;AAEP,8BAUO;AAEP,sBA2BO;AAEP,wBAeO;AAGP,8BAOO;AAEP,qBAQO;AAEP,kCAA0C;AAE1C,+BAuCO;","names":[]}
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
augmentProductWithFormatOptions,
|
|
9
9
|
withFormatOptions,
|
|
10
|
+
toAdditiveCanonicalProduct,
|
|
11
|
+
withAdditiveCanonicalFormatOptions,
|
|
10
12
|
toCanonicalOnlyProduct,
|
|
11
13
|
toCanonicalOnlyResponse
|
|
12
14
|
} from "./augment-response.mjs";
|
|
@@ -111,11 +113,13 @@ export {
|
|
|
111
113
|
responsiveCreativeFormatDeclaration,
|
|
112
114
|
sponsoredPlacementFormatDeclaration,
|
|
113
115
|
stripLegacyCreativeIdentity,
|
|
116
|
+
toAdditiveCanonicalProduct,
|
|
114
117
|
toCanonicalOnlyProduct,
|
|
115
118
|
toCanonicalOnlyResponse,
|
|
116
119
|
tryLegacyFormatIdsFromOptions,
|
|
117
120
|
videoHostedFormatDeclaration,
|
|
118
121
|
videoVastFormatDeclaration,
|
|
122
|
+
withAdditiveCanonicalFormatOptions,
|
|
119
123
|
withFormatOptions
|
|
120
124
|
};
|
|
121
125
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/v2/projection/index.ts"],"sourcesContent":["/**\n * v1 ↔ v2 Product projection layer (AdCP 3.1).\n *\n * Public surfaces:\n *\n * - `projectV1ProductToV2` / `projectV2ProductToV1` — the symmetric\n * core projections. Read a Product on one side, return a Product\n * on the other plus structured diagnostics (`source: 'sdk'`,\n * normative spec codes + SDK-local codes).\n *\n * - `resolveCanonicalFormatKind` / `canonicalDeclarationFromBareId` —\n * resolve a single bare format-id string (no surrounding Product,\n * no `agent_url`) to its canonical `format_kind` or full declaration.\n * Registry- and catalog-backed; fails closed to `null`.\n *\n * - `withFormatOptions` / `augmentProductWithFormatOptions` —\n * buyer-side response augmentation. Adds `format_options[]` to a\n * v1-shaped get_products response so canonical-format-aware buyers\n * can read the canonical model regardless of the seller's wire\n * version. Additive — `format_ids[]` is preserved.\n *\n * - `toCanonicalOnlyProduct` / `toCanonicalOnlyResponse` — the\n * read-side narrowing for a fully-migrated consumer. Returns\n * `format_options[]` with `format_ids[]` dropped, surfacing a\n * diagnostic for any ref that couldn't be carried over.\n *\n * - Catalog + registry primitives (`lookupV1Format`,\n * `findCatalogEntryByCanonicalAndSize`, registry exports) for\n * callers wiring projection into their own code paths.\n *\n * Legacy-preserving and raw wire projection helpers are exposed only from\n * `@adcp/sdk/v2/projection`. The package root exports the canonical authoring\n * surface so ordinary buyers do not accidentally retain legacy identities.\n */\n\nexport { projectV1ProductToV2, canonicalDeclarationFromBareId, resolveCanonicalFormatKind } from './v1-to-v2';\nexport type {\n V1ToV2Result,\n V1ToV2ProjectionOptions,\n BareFormatIdResolveOptions,\n LegacyFormatConversionContext,\n LegacyFormatConverter,\n} from './v1-to-v2';\n\nexport { projectV2ProductToV1 } from './v2-to-v1';\nexport type {\n V2ToV1Result,\n V2ToV1ProjectionOptions,\n CanonicalFormatLegacyResolver,\n CanonicalFormatLegacyResolutionContext,\n CanonicalProductFormatLegacyResolutionContext,\n CanonicalCreativeFormatLegacyResolutionContext,\n CanonicalSelectorFormatLegacyResolutionContext,\n} from './v2-to-v1';\n\nexport {\n canonicalFormatLegacyResolverFromRoutes,\n legacyRoutesForProduct,\n type CanonicalFormatLegacyRoute,\n} from './legacy-routes';\n\nexport {\n augmentProductWithFormatOptions,\n withFormatOptions,\n toCanonicalOnlyProduct,\n toCanonicalOnlyResponse,\n type V2AugmentedProduct,\n type CanonicalOnlyProduct,\n} from './augment-response';\n\nexport {\n CanonicalFormat,\n audioDaastFormatDeclaration,\n audioHostedFormatDeclaration,\n agentPlacementFormatDeclaration,\n canonicalFormatDeclaration,\n customFormatDeclaration,\n displayTagFormatDeclaration,\n legacyFormatRef,\n legacyFormatRefs,\n html5FormatDeclaration,\n imageCarouselFormatDeclaration,\n imageFormatDeclaration,\n nativeInFeedFormatDeclaration,\n productCard,\n productCardDetailed,\n responsiveCreativeFormatDeclaration,\n sponsoredPlacementFormatDeclaration,\n videoHostedFormatDeclaration,\n videoVastFormatDeclaration,\n type CanonicalFormatDeclaration,\n type CanonicalFormatDeclarationFields,\n type CanonicalFormatKind,\n type CanonicalFormatParams,\n type FormatReferenceInput,\n type ProductCardDetailedFields,\n type ProductCardFields,\n} from './builders';\n\nexport {\n packageRefsForFormatOptions,\n packageRefsForCapabilities,\n legacyFormatIdsFromOptions,\n tryLegacyFormatIdsFromOptions,\n legacyFormatIdsForFormatOption,\n legacyFormatIdsForCapability,\n FormatOptionRefsLookupError,\n CapabilityIdsLookupError,\n type PackageFormatRefs,\n type PackageCapabilityRefs,\n type FormatOptionRef,\n type FormatOptionSelector,\n type FormatOptionRefsLookupErrorCode,\n type CapabilityIdsLookupErrorCode,\n} from './write-side';\n\nexport type { V1FormatId, V2ProductFormatDeclaration, V2Product, V1Product, ProjectionDiagnostic } from './types';\nexport {\n legacyFormatConverterFromCatalogSnapshots,\n canonicalFormatLegacyResolverFromCatalogSnapshots,\n projectionAdaptersFromCatalogSnapshots,\n type ProjectionCatalogAdapters,\n type ProjectionCatalogSnapshot,\n type ProjectionCatalogSource,\n} from './catalog-snapshot';\n\nexport {\n loadCatalog,\n lookupV1Format,\n findCatalogEntryByCanonicalAndSize,\n parseSizedIdTemplate,\n _resetCatalogCache,\n type V1FormatDefinition,\n type CanonicalProjectionRef,\n} from './catalog';\n\nexport { isCanonicalV1Translatable } from './canonical-properties';\n\nexport {\n CreativeFormatProjectionError,\n CreativeFormatCapabilityError,\n projectCreativeForDelivery,\n projectMediaBuyCreativesForDelivery,\n projectSyncCreativesForDelivery,\n stripLegacyCreativeIdentity,\n resolveCreativeFormatWireMode,\n type CreativeFormatSelectorContainer,\n type CanonicalCreativeFormatSelectorContainer,\n type CreativeFormatWireMode,\n type CanonicalCreativeAsset,\n type CanonicalCreativeResponse,\n type CanonicalGetProductsResponse,\n type CanonicalGetProductsRequest,\n type CanonicalCreateMediaBuyRequest,\n type CanonicalCreateMediaBuyResponse,\n type CanonicalCreativeFilters,\n type CanonicalListCreativesRequest,\n type CanonicalListCreativesResponse,\n type CanonicalGetCreativeDeliveryResponse,\n type CanonicalGetMediaBuyDeliveryResponse,\n type CanonicalGetMediaBuysResponse,\n type CanonicalListedCreative,\n type CanonicalPackageRequest,\n type CanonicalPackageUpdate,\n type CanonicalPackage,\n type CanonicalPlacement,\n type CanonicalProduct,\n type CanonicalProjectedCreative,\n type CanonicalSyncCreativesRequest,\n type CanonicalSyncCreativesResponse,\n type CanonicalUpdateMediaBuyRequest,\n type CanonicalUpdateMediaBuyResponse,\n type LegacyCreativeAsset,\n type LegacyProjectedCreative,\n type ProjectedMediaBuyCreativeRequest,\n type ProjectedSyncCreativeRequest,\n type SyncCreativeFormatProjection,\n} from './creative-delivery';\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/v2/projection/index.ts"],"sourcesContent":["/**\n * v1 ↔ v2 Product projection layer (AdCP 3.1).\n *\n * Public surfaces:\n *\n * - `projectV1ProductToV2` / `projectV2ProductToV1` — the symmetric\n * core projections. Read a Product on one side, return a Product\n * on the other plus structured diagnostics (`source: 'sdk'`,\n * normative spec codes + SDK-local codes).\n *\n * - `resolveCanonicalFormatKind` / `canonicalDeclarationFromBareId` —\n * resolve a single bare format-id string (no surrounding Product,\n * no `agent_url`) to its canonical `format_kind` or full declaration.\n * Registry- and catalog-backed; fails closed to `null`.\n *\n * - `withFormatOptions` / `augmentProductWithFormatOptions` —\n * buyer-side response augmentation. Adds `format_options[]` to a\n * v1-shaped get_products response so canonical-format-aware buyers\n * can read the canonical model regardless of the seller's wire\n * version. Additive — `format_ids[]` is preserved.\n *\n * - `toAdditiveCanonicalProduct` — additive projection with URL-free\n * `format_options[]`, preserved top-level `format_ids[]`, and explicit\n * serializable legacy-route sidecars for later forwarding.\n * `withAdditiveCanonicalFormatOptions` is the response-level companion.\n *\n * - `toCanonicalOnlyProduct` / `toCanonicalOnlyResponse` — the\n * read-side narrowing for a fully-migrated consumer. Returns\n * `format_options[]` with `format_ids[]` dropped, surfacing a\n * diagnostic for any ref that couldn't be carried over.\n *\n * - Catalog + registry primitives (`lookupV1Format`,\n * `findCatalogEntryByCanonicalAndSize`, registry exports) for\n * callers wiring projection into their own code paths.\n *\n * Legacy-preserving and raw wire projection helpers are exposed only from\n * `@adcp/sdk/v2/projection`. The package root exports the canonical authoring\n * surface so ordinary buyers do not accidentally retain legacy identities.\n */\n\nexport { projectV1ProductToV2, canonicalDeclarationFromBareId, resolveCanonicalFormatKind } from './v1-to-v2';\nexport type {\n V1ToV2Result,\n V1ToV2ProjectionOptions,\n BareFormatIdResolveOptions,\n LegacyFormatConversionContext,\n LegacyFormatConverter,\n} from './v1-to-v2';\n\nexport { projectV2ProductToV1 } from './v2-to-v1';\nexport type {\n V2ToV1Result,\n V2ToV1ProjectionOptions,\n CanonicalFormatLegacyResolver,\n CanonicalFormatLegacyResolutionContext,\n CanonicalProductFormatLegacyResolutionContext,\n CanonicalCreativeFormatLegacyResolutionContext,\n CanonicalSelectorFormatLegacyResolutionContext,\n} from './v2-to-v1';\n\nexport {\n canonicalFormatLegacyResolverFromRoutes,\n legacyRoutesForProduct,\n type CanonicalFormatLegacyRoute,\n} from './legacy-routes';\n\nexport {\n augmentProductWithFormatOptions,\n withFormatOptions,\n toAdditiveCanonicalProduct,\n withAdditiveCanonicalFormatOptions,\n toCanonicalOnlyProduct,\n toCanonicalOnlyResponse,\n type V2AugmentedProduct,\n type AdditiveCanonicalProduct,\n type CanonicalOnlyProduct,\n} from './augment-response';\n\nexport {\n CanonicalFormat,\n audioDaastFormatDeclaration,\n audioHostedFormatDeclaration,\n agentPlacementFormatDeclaration,\n canonicalFormatDeclaration,\n customFormatDeclaration,\n displayTagFormatDeclaration,\n legacyFormatRef,\n legacyFormatRefs,\n html5FormatDeclaration,\n imageCarouselFormatDeclaration,\n imageFormatDeclaration,\n nativeInFeedFormatDeclaration,\n productCard,\n productCardDetailed,\n responsiveCreativeFormatDeclaration,\n sponsoredPlacementFormatDeclaration,\n videoHostedFormatDeclaration,\n videoVastFormatDeclaration,\n type CanonicalFormatDeclaration,\n type CanonicalFormatDeclarationFields,\n type CanonicalFormatKind,\n type CanonicalFormatParams,\n type FormatReferenceInput,\n type ProductCardDetailedFields,\n type ProductCardFields,\n} from './builders';\n\nexport {\n packageRefsForFormatOptions,\n packageRefsForCapabilities,\n legacyFormatIdsFromOptions,\n tryLegacyFormatIdsFromOptions,\n legacyFormatIdsForFormatOption,\n legacyFormatIdsForCapability,\n FormatOptionRefsLookupError,\n CapabilityIdsLookupError,\n type PackageFormatRefs,\n type PackageCapabilityRefs,\n type FormatOptionRef,\n type FormatOptionSelector,\n type FormatOptionRefsLookupErrorCode,\n type CapabilityIdsLookupErrorCode,\n} from './write-side';\n\nexport type { V1FormatId, V2ProductFormatDeclaration, V2Product, V1Product, ProjectionDiagnostic } from './types';\nexport {\n legacyFormatConverterFromCatalogSnapshots,\n canonicalFormatLegacyResolverFromCatalogSnapshots,\n projectionAdaptersFromCatalogSnapshots,\n type ProjectionCatalogAdapters,\n type ProjectionCatalogSnapshot,\n type ProjectionCatalogSource,\n} from './catalog-snapshot';\n\nexport {\n loadCatalog,\n lookupV1Format,\n findCatalogEntryByCanonicalAndSize,\n parseSizedIdTemplate,\n _resetCatalogCache,\n type V1FormatDefinition,\n type CanonicalProjectionRef,\n} from './catalog';\n\nexport { isCanonicalV1Translatable } from './canonical-properties';\n\nexport {\n CreativeFormatProjectionError,\n CreativeFormatCapabilityError,\n projectCreativeForDelivery,\n projectMediaBuyCreativesForDelivery,\n projectSyncCreativesForDelivery,\n stripLegacyCreativeIdentity,\n resolveCreativeFormatWireMode,\n type CreativeFormatSelectorContainer,\n type CanonicalCreativeFormatSelectorContainer,\n type CreativeFormatWireMode,\n type CanonicalCreativeAsset,\n type CanonicalCreativeResponse,\n type CanonicalGetProductsResponse,\n type CanonicalGetProductsRequest,\n type CanonicalCreateMediaBuyRequest,\n type CanonicalCreateMediaBuyResponse,\n type CanonicalCreativeFilters,\n type CanonicalListCreativesRequest,\n type CanonicalListCreativesResponse,\n type CanonicalGetCreativeDeliveryResponse,\n type CanonicalGetMediaBuyDeliveryResponse,\n type CanonicalGetMediaBuysResponse,\n type CanonicalListedCreative,\n type CanonicalPackageRequest,\n type CanonicalPackageUpdate,\n type CanonicalPackage,\n type CanonicalPlacement,\n type CanonicalProduct,\n type CanonicalProjectedCreative,\n type CanonicalSyncCreativesRequest,\n type CanonicalSyncCreativesResponse,\n type CanonicalUpdateMediaBuyRequest,\n type CanonicalUpdateMediaBuyResponse,\n type LegacyCreativeAsset,\n type LegacyProjectedCreative,\n type ProjectedMediaBuyCreativeRequest,\n type ProjectedSyncCreativeRequest,\n type SyncCreativeFormatProjection,\n} from './creative-delivery';\n"],"mappings":"AAwCA,SAAS,sBAAsB,gCAAgC,kCAAkC;AASjG,SAAS,4BAA4B;AAWrC;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAQK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAOK;AAGP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAEP,SAAS,iCAAiC;AAE1C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAgCK;","names":[]}
|
package/dist/lib/version.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AdCP SDK library version
|
|
3
3
|
*/
|
|
4
|
-
export declare const LIBRARY_VERSION = "13.0.0-rc.
|
|
4
|
+
export declare const LIBRARY_VERSION = "13.0.0-rc.13";
|
|
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: "13.0.0-rc.
|
|
36
|
+
readonly library: "13.0.0-rc.13";
|
|
37
37
|
readonly adcp: "3.1.11";
|
|
38
38
|
readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0-beta.1", "3.0-beta.1", "3.0-beta", "3.0.0-beta.3", "3.0-beta.3", "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.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"];
|
|
39
|
-
readonly generatedAt: "2026-08-
|
|
39
|
+
readonly generatedAt: "2026-08-10T05:35:45.573Z";
|
|
40
40
|
};
|
|
41
41
|
/**
|
|
42
42
|
* Get the AdCP specification version this library is built for
|
package/dist/lib/version.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AdCP SDK library version
|
|
3
3
|
*/
|
|
4
|
-
export declare const LIBRARY_VERSION = "13.0.0-rc.
|
|
4
|
+
export declare const LIBRARY_VERSION = "13.0.0-rc.13";
|
|
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: "13.0.0-rc.
|
|
36
|
+
readonly library: "13.0.0-rc.13";
|
|
37
37
|
readonly adcp: "3.1.11";
|
|
38
38
|
readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0-beta.1", "3.0-beta.1", "3.0-beta", "3.0.0-beta.3", "3.0-beta.3", "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.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"];
|
|
39
|
-
readonly generatedAt: "2026-08-
|
|
39
|
+
readonly generatedAt: "2026-08-10T05:35:45.573Z";
|
|
40
40
|
};
|
|
41
41
|
/**
|
|
42
42
|
* Get the AdCP specification version this library is built for
|
package/dist/lib/version.js
CHANGED
|
@@ -31,7 +31,7 @@ __export(version_exports, {
|
|
|
31
31
|
toReleasePrecisionVersion: () => toReleasePrecisionVersion
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(version_exports);
|
|
34
|
-
const LIBRARY_VERSION = "13.0.0-rc.
|
|
34
|
+
const LIBRARY_VERSION = "13.0.0-rc.13";
|
|
35
35
|
const ADCP_VERSION = "3.1.11";
|
|
36
36
|
const ADCP_MAJOR_VERSION = 3;
|
|
37
37
|
const COMPATIBLE_ADCP_VERSIONS = [
|
|
@@ -72,10 +72,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
|
|
|
72
72
|
"3.1.11"
|
|
73
73
|
];
|
|
74
74
|
const VERSION_INFO = {
|
|
75
|
-
library: "13.0.0-rc.
|
|
75
|
+
library: "13.0.0-rc.13",
|
|
76
76
|
adcp: "3.1.11",
|
|
77
77
|
compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
|
|
78
|
-
generatedAt: "2026-08-
|
|
78
|
+
generatedAt: "2026-08-10T05:35:45.573Z"
|
|
79
79
|
};
|
|
80
80
|
function getAdcpVersion() {
|
|
81
81
|
return ADCP_VERSION;
|
package/dist/lib/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/version.ts"],"sourcesContent":["// Generated version information\n// This file is auto-generated by sync-version.ts\n\n/**\n * AdCP SDK library version\n */\nexport const LIBRARY_VERSION = '13.0.0-rc.
|
|
1
|
+
{"version":3,"sources":["../../src/lib/version.ts"],"sourcesContent":["// Generated version information\n// This file is auto-generated by sync-version.ts\n\n/**\n * AdCP SDK library version\n */\nexport const LIBRARY_VERSION = '13.0.0-rc.13';\n\n/**\n * AdCP specification version this library is built for\n */\nexport const ADCP_VERSION = '3.1.11';\n\n/**\n * AdCP major version sent with every request (adcp_major_version field).\n * Sellers validate this against their supported versions and return\n * VERSION_UNSUPPORTED if the version is not in range.\n */\nexport const ADCP_MAJOR_VERSION = 3;\n\n/**\n * AdCP versions this library maintains backward compatibility with.\n *\n * Auto-derived from `ADCP_VERSION` by scripts/sync-version.ts. Do not edit\n * this list by hand; bumping the AdCP pin via `npm run sync-version`\n * extends it.\n */\nexport const COMPATIBLE_ADCP_VERSIONS = [\n 'v2.5',\n 'v2.6',\n 'v3',\n '3.0.0-beta.1',\n '3.0-beta.1',\n '3.0-beta',\n '3.0.0-beta.3',\n '3.0-beta.3',\n '3.0.0',\n '3.0',\n '3.0.1',\n '3.0.2',\n '3.0.3',\n '3.0.4',\n '3.0.5',\n '3.0.6',\n '3.0.7',\n '3.0.8',\n '3.0.9',\n '3.0.10',\n '3.0.11',\n '3.0.12',\n '3.1.0',\n '3.1',\n '3.1.1',\n '3.1.2',\n '3.1.3',\n '3.1.4',\n '3.1.5',\n '3.1.6',\n '3.1.7',\n '3.1.8',\n '3.1.9',\n '3.1.10',\n '3.1.11',\n] as const;\n\n/**\n * String literal union of every AdCP version the SDK formally supports.\n *\n * Used by the per-instance `adcpVersion` constructor option to give callers\n * autocomplete in editors. The intersection with `(string & {})` in the\n * config type preserves the escape hatch — any string is still accepted at\n * the type level — while the literal union surfaces canonical values first.\n */\nexport type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];\n\n/**\n * Full version information\n */\nexport const VERSION_INFO = {\n library: '13.0.0-rc.13',\n adcp: '3.1.11',\n compatibleVersions: COMPATIBLE_ADCP_VERSIONS,\n generatedAt: '2026-08-10T05:35:45.573Z',\n} as const;\n\n/**\n * Get the AdCP specification version this library is built for\n */\nexport function getAdcpVersion(): string {\n return ADCP_VERSION;\n}\n\n/**\n * Get the library version\n */\nexport function getLibraryVersion(): string {\n return LIBRARY_VERSION;\n}\n\n/**\n * Check if this library version is compatible with a given AdCP version\n */\nexport function isCompatibleWith(adcpVersion: string): boolean {\n return (COMPATIBLE_ADCP_VERSIONS as readonly string[]).includes(adcpVersion);\n}\n\n/**\n * Get all AdCP versions this library is compatible with\n */\nexport function getCompatibleVersions(): readonly string[] {\n return COMPATIBLE_ADCP_VERSIONS;\n}\n\n/**\n * Extract the major version number from an AdCP version string.\n *\n * Accepts:\n * - Semver: '3.0.0', '3.0.1', '3.1.0-beta.1' → 3\n * - Legacy aliases: 'v3' → 3, 'v2.5' / 'v2.6' → 2\n *\n * Returns NaN for unrecognized strings — callers should validate before passing.\n */\nexport function parseAdcpMajorVersion(version: string): number {\n const trimmed = version.trim();\n const semverLike = trimmed.startsWith('v') ? trimmed.slice(1) : trimmed;\n const major = parseInt(semverLike.split('.')[0] ?? '', 10);\n return Number.isFinite(major) ? major : NaN;\n}\n\n/**\n * Normalize a full-semver AdCP version (`MAJOR.MINOR.PATCH[-prerelease]`) to\n * the release-precision form that AdCP 3.1+ requires on the wire:\n * `MAJOR.MINOR[-prerelease]` — the patch digit is dropped.\n *\n * Per the spec note on `adcp_version`: \"SDKs that read full-semver values\n * from bundle metadata (e.g. `ComplianceIndex.published_version =\n * \"3.1.0-beta.1\"`) MUST normalize to release-precision (`\"3.1-beta.1\"`)\n * before emitting on the wire — meta-field values are NOT valid wire\n * values.\" The wire regex (`^\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$`) rejects strings\n * with a patch digit.\n *\n * Behavior:\n * - `\"3.1.0-beta.7\"` → `\"3.1-beta.7\"`\n * - `\"3.1.0\"` → `\"3.1\"`\n * - `\"3.0.12\"` → `\"3.0\"`\n * - Already-release-precision input (`\"3.1\"`, `\"3.1-beta.7\"`) passes through\n * - Legacy aliases (`\"v2.5\"`, `\"v3\"`) pass through unchanged — the wire\n * regex doesn't accept them anyway; the v2.5 path uses\n * `adcp_major_version` instead of `adcp_version` for transport.\n * - Unrecognized strings pass through unchanged so callers can detect drift\n * via the wire validator rather than have it masked by this helper.\n */\nexport function toReleasePrecisionVersion(version: string): string {\n const trimmed = version.trim();\n // Pre-release form `MAJOR.MINOR.PATCH-prerelease` → `MAJOR.MINOR-prerelease`\n const semverMatch = trimmed.match(/^(\\d+)\\.(\\d+)\\.\\d+(-[A-Za-z0-9.-]+)?$/);\n if (semverMatch) {\n const [, major, minor, pre = ''] = semverMatch;\n return `${major}.${minor}${pre}`;\n }\n // Already release-precision (no patch digit). Includes `3.1`, `3.1-beta.7`.\n if (/^\\d+\\.\\d+(-[A-Za-z0-9.-]+)?$/.test(trimmed)) return trimmed;\n // Legacy aliases (`v3`, `v2.5`, `v2.6`) and anything we don't recognize —\n // pass through so the wire validator can flag genuine drift.\n return version;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMO,MAAM,kBAAkB;AAKxB,MAAM,eAAe;AAOrB,MAAM,qBAAqB;AAS3B,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAeO,MAAM,eAAe;AAAA,EAC1B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,oBAAoB;AAAA,EACpB,aAAa;AACf;AAKO,SAAS,iBAAyB;AACvC,SAAO;AACT;AAKO,SAAS,oBAA4B;AAC1C,SAAO;AACT;AAKO,SAAS,iBAAiB,aAA8B;AAC7D,SAAQ,yBAA+C,SAAS,WAAW;AAC7E;AAKO,SAAS,wBAA2C;AACzD,SAAO;AACT;AAWO,SAAS,sBAAsB,SAAyB;AAC7D,QAAM,UAAU,QAAQ,KAAK;AAC7B,QAAM,aAAa,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAChE,QAAM,QAAQ,SAAS,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE;AACzD,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;AAyBO,SAAS,0BAA0B,SAAyB;AACjE,QAAM,UAAU,QAAQ,KAAK;AAE7B,QAAM,cAAc,QAAQ,MAAM,uCAAuC;AACzE,MAAI,aAAa;AACf,UAAM,CAAC,EAAE,OAAO,OAAO,MAAM,EAAE,IAAI;AACnC,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,GAAG;AAAA,EAChC;AAEA,MAAI,+BAA+B,KAAK,OAAO,EAAG,QAAO;AAGzD,SAAO;AACT;","names":[]}
|
package/dist/lib/version.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const LIBRARY_VERSION = "13.0.0-rc.
|
|
1
|
+
const LIBRARY_VERSION = "13.0.0-rc.13";
|
|
2
2
|
const ADCP_VERSION = "3.1.11";
|
|
3
3
|
const ADCP_MAJOR_VERSION = 3;
|
|
4
4
|
const COMPATIBLE_ADCP_VERSIONS = [
|
|
@@ -39,10 +39,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
|
|
|
39
39
|
"3.1.11"
|
|
40
40
|
];
|
|
41
41
|
const VERSION_INFO = {
|
|
42
|
-
library: "13.0.0-rc.
|
|
42
|
+
library: "13.0.0-rc.13",
|
|
43
43
|
adcp: "3.1.11",
|
|
44
44
|
compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
|
|
45
|
-
generatedAt: "2026-08-
|
|
45
|
+
generatedAt: "2026-08-10T05:35:45.573Z"
|
|
46
46
|
};
|
|
47
47
|
function getAdcpVersion() {
|
|
48
48
|
return ADCP_VERSION;
|
package/dist/lib/version.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/version.ts"],"sourcesContent":["// Generated version information\n// This file is auto-generated by sync-version.ts\n\n/**\n * AdCP SDK library version\n */\nexport const LIBRARY_VERSION = '13.0.0-rc.
|
|
1
|
+
{"version":3,"sources":["../../src/lib/version.ts"],"sourcesContent":["// Generated version information\n// This file is auto-generated by sync-version.ts\n\n/**\n * AdCP SDK library version\n */\nexport const LIBRARY_VERSION = '13.0.0-rc.13';\n\n/**\n * AdCP specification version this library is built for\n */\nexport const ADCP_VERSION = '3.1.11';\n\n/**\n * AdCP major version sent with every request (adcp_major_version field).\n * Sellers validate this against their supported versions and return\n * VERSION_UNSUPPORTED if the version is not in range.\n */\nexport const ADCP_MAJOR_VERSION = 3;\n\n/**\n * AdCP versions this library maintains backward compatibility with.\n *\n * Auto-derived from `ADCP_VERSION` by scripts/sync-version.ts. Do not edit\n * this list by hand; bumping the AdCP pin via `npm run sync-version`\n * extends it.\n */\nexport const COMPATIBLE_ADCP_VERSIONS = [\n 'v2.5',\n 'v2.6',\n 'v3',\n '3.0.0-beta.1',\n '3.0-beta.1',\n '3.0-beta',\n '3.0.0-beta.3',\n '3.0-beta.3',\n '3.0.0',\n '3.0',\n '3.0.1',\n '3.0.2',\n '3.0.3',\n '3.0.4',\n '3.0.5',\n '3.0.6',\n '3.0.7',\n '3.0.8',\n '3.0.9',\n '3.0.10',\n '3.0.11',\n '3.0.12',\n '3.1.0',\n '3.1',\n '3.1.1',\n '3.1.2',\n '3.1.3',\n '3.1.4',\n '3.1.5',\n '3.1.6',\n '3.1.7',\n '3.1.8',\n '3.1.9',\n '3.1.10',\n '3.1.11',\n] as const;\n\n/**\n * String literal union of every AdCP version the SDK formally supports.\n *\n * Used by the per-instance `adcpVersion` constructor option to give callers\n * autocomplete in editors. The intersection with `(string & {})` in the\n * config type preserves the escape hatch — any string is still accepted at\n * the type level — while the literal union surfaces canonical values first.\n */\nexport type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];\n\n/**\n * Full version information\n */\nexport const VERSION_INFO = {\n library: '13.0.0-rc.13',\n adcp: '3.1.11',\n compatibleVersions: COMPATIBLE_ADCP_VERSIONS,\n generatedAt: '2026-08-10T05:35:45.573Z',\n} as const;\n\n/**\n * Get the AdCP specification version this library is built for\n */\nexport function getAdcpVersion(): string {\n return ADCP_VERSION;\n}\n\n/**\n * Get the library version\n */\nexport function getLibraryVersion(): string {\n return LIBRARY_VERSION;\n}\n\n/**\n * Check if this library version is compatible with a given AdCP version\n */\nexport function isCompatibleWith(adcpVersion: string): boolean {\n return (COMPATIBLE_ADCP_VERSIONS as readonly string[]).includes(adcpVersion);\n}\n\n/**\n * Get all AdCP versions this library is compatible with\n */\nexport function getCompatibleVersions(): readonly string[] {\n return COMPATIBLE_ADCP_VERSIONS;\n}\n\n/**\n * Extract the major version number from an AdCP version string.\n *\n * Accepts:\n * - Semver: '3.0.0', '3.0.1', '3.1.0-beta.1' → 3\n * - Legacy aliases: 'v3' → 3, 'v2.5' / 'v2.6' → 2\n *\n * Returns NaN for unrecognized strings — callers should validate before passing.\n */\nexport function parseAdcpMajorVersion(version: string): number {\n const trimmed = version.trim();\n const semverLike = trimmed.startsWith('v') ? trimmed.slice(1) : trimmed;\n const major = parseInt(semverLike.split('.')[0] ?? '', 10);\n return Number.isFinite(major) ? major : NaN;\n}\n\n/**\n * Normalize a full-semver AdCP version (`MAJOR.MINOR.PATCH[-prerelease]`) to\n * the release-precision form that AdCP 3.1+ requires on the wire:\n * `MAJOR.MINOR[-prerelease]` — the patch digit is dropped.\n *\n * Per the spec note on `adcp_version`: \"SDKs that read full-semver values\n * from bundle metadata (e.g. `ComplianceIndex.published_version =\n * \"3.1.0-beta.1\"`) MUST normalize to release-precision (`\"3.1-beta.1\"`)\n * before emitting on the wire — meta-field values are NOT valid wire\n * values.\" The wire regex (`^\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$`) rejects strings\n * with a patch digit.\n *\n * Behavior:\n * - `\"3.1.0-beta.7\"` → `\"3.1-beta.7\"`\n * - `\"3.1.0\"` → `\"3.1\"`\n * - `\"3.0.12\"` → `\"3.0\"`\n * - Already-release-precision input (`\"3.1\"`, `\"3.1-beta.7\"`) passes through\n * - Legacy aliases (`\"v2.5\"`, `\"v3\"`) pass through unchanged — the wire\n * regex doesn't accept them anyway; the v2.5 path uses\n * `adcp_major_version` instead of `adcp_version` for transport.\n * - Unrecognized strings pass through unchanged so callers can detect drift\n * via the wire validator rather than have it masked by this helper.\n */\nexport function toReleasePrecisionVersion(version: string): string {\n const trimmed = version.trim();\n // Pre-release form `MAJOR.MINOR.PATCH-prerelease` → `MAJOR.MINOR-prerelease`\n const semverMatch = trimmed.match(/^(\\d+)\\.(\\d+)\\.\\d+(-[A-Za-z0-9.-]+)?$/);\n if (semverMatch) {\n const [, major, minor, pre = ''] = semverMatch;\n return `${major}.${minor}${pre}`;\n }\n // Already release-precision (no patch digit). Includes `3.1`, `3.1-beta.7`.\n if (/^\\d+\\.\\d+(-[A-Za-z0-9.-]+)?$/.test(trimmed)) return trimmed;\n // Legacy aliases (`v3`, `v2.5`, `v2.6`) and anything we don't recognize —\n // pass through so the wire validator can flag genuine drift.\n return version;\n}\n"],"mappings":"AAMO,MAAM,kBAAkB;AAKxB,MAAM,eAAe;AAOrB,MAAM,qBAAqB;AAS3B,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAeO,MAAM,eAAe;AAAA,EAC1B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,oBAAoB;AAAA,EACpB,aAAa;AACf;AAKO,SAAS,iBAAyB;AACvC,SAAO;AACT;AAKO,SAAS,oBAA4B;AAC1C,SAAO;AACT;AAKO,SAAS,iBAAiB,aAA8B;AAC7D,SAAQ,yBAA+C,SAAS,WAAW;AAC7E;AAKO,SAAS,wBAA2C;AACzD,SAAO;AACT;AAWO,SAAS,sBAAsB,SAAyB;AAC7D,QAAM,UAAU,QAAQ,KAAK;AAC7B,QAAM,aAAa,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAChE,QAAM,QAAQ,SAAS,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE;AACzD,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;AAyBO,SAAS,0BAA0B,SAAyB;AACjE,QAAM,UAAU,QAAQ,KAAK;AAE7B,QAAM,cAAc,QAAQ,MAAM,uCAAuC;AACzE,MAAI,aAAa;AACf,UAAM,CAAC,EAAE,OAAO,OAAO,MAAM,EAAE,IAAI;AACnC,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,GAAG;AAAA,EAChC;AAEA,MAAI,+BAA+B,KAAK,OAAO,EAAG,QAAO;AAGzD,SAAO;AACT;","names":[]}
|
|
@@ -307,6 +307,34 @@ Each `CanonicalFormatLegacyRoute` contains `product_id`, the stable
|
|
|
307
307
|
resolver to `AgentClient` or `createAdcpServerFromPlatform()` without changing
|
|
308
308
|
the existing resolver callback contract.
|
|
309
309
|
|
|
310
|
+
Compatibility consumers that must retain top-level `format_ids[]` while
|
|
311
|
+
publishing URL-free canonical declarations can use the additive projection:
|
|
312
|
+
|
|
313
|
+
```ts
|
|
314
|
+
import {
|
|
315
|
+
canonicalFormatLegacyResolverFromRoutes,
|
|
316
|
+
toAdditiveCanonicalProduct,
|
|
317
|
+
} from '@adcp/sdk/v2/projection';
|
|
318
|
+
|
|
319
|
+
const { product, diagnostics, routes } =
|
|
320
|
+
toAdditiveCanonicalProduct(sourceProduct, { legacyFormatConverter });
|
|
321
|
+
|
|
322
|
+
// product.format_ids is preserved, but product.format_options never exposes
|
|
323
|
+
// v1_format_ref. Extract routes before any JSON round-trip — WeakMap metadata
|
|
324
|
+
// is gone after deserialization. Persist the sidecar before crossing a process
|
|
325
|
+
// boundary.
|
|
326
|
+
await products.put(product.product_id, product);
|
|
327
|
+
await creativeRoutes.put(product.product_id, routes);
|
|
328
|
+
|
|
329
|
+
const resolver = canonicalFormatLegacyResolverFromRoutes(
|
|
330
|
+
await creativeRoutes.get(product.product_id)
|
|
331
|
+
);
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Source-authored canonical option ids, kinds, and params are preserved exactly;
|
|
335
|
+
only the legacy compatibility hint moves to `routes`. Legacy-only input
|
|
336
|
+
uses the same declaration and route contract after projection.
|
|
337
|
+
|
|
310
338
|
For a fixed set of temporary seller adapters, prefer one declarative catalog over
|
|
311
339
|
separate forward and reverse callbacks. `projectionAdaptersFromCatalogSnapshots`
|
|
312
340
|
turns exact catalog-authored `v1_format_ref` pairs into client configuration for
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adcp/sdk",
|
|
3
|
-
"version": "13.0.0-rc.
|
|
3
|
+
"version": "13.0.0-rc.13",
|
|
4
4
|
"description": "AdCP SDK — client, server, and compliance harnesses for the AdContext Protocol (MCP + A2A)",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
".",
|
|
@@ -579,6 +579,7 @@
|
|
|
579
579
|
"fast-check": "^3.23.2",
|
|
580
580
|
"jose": "^6.2.2",
|
|
581
581
|
"secure-json-parse": "^4.1.0",
|
|
582
|
+
"semver": "^7.8.5",
|
|
582
583
|
"structured-headers": "2.0.2",
|
|
583
584
|
"tldts": "^7.0.29",
|
|
584
585
|
"undici": "^6.27.0",
|
|
@@ -615,6 +616,7 @@
|
|
|
615
616
|
"@types/express": "4.17.25",
|
|
616
617
|
"@types/node": "^20.19.39",
|
|
617
618
|
"@types/pg": "^8.20.0",
|
|
619
|
+
"@types/semver": "^7.8.0",
|
|
618
620
|
"@types/tar": "^6.1.13",
|
|
619
621
|
"actionlint": "^2.0.6",
|
|
620
622
|
"esbuild": "^0.28.1",
|