@odla-ai/brand 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +113 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +115 -4
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,7 @@ __export(src_exports, {
|
|
|
31
31
|
BRAND_EMITTED_TOKENS: () => BRAND_EMITTED_TOKENS,
|
|
32
32
|
BRAND_INSTRUCTIONS: () => BRAND_INSTRUCTIONS,
|
|
33
33
|
BRAND_NS: () => BRAND_NS,
|
|
34
|
+
BRAND_PROMOTION_ADAPTER: () => BRAND_PROMOTION_ADAPTER,
|
|
34
35
|
BRAND_REQUIRED_TOKENS: () => BRAND_REQUIRED_TOKENS,
|
|
35
36
|
BRAND_RULES: () => BRAND_RULES,
|
|
36
37
|
BRAND_SCHEMA: () => BRAND_SCHEMA,
|
|
@@ -119,6 +120,7 @@ __export(src_exports, {
|
|
|
119
120
|
digestDesignBundle: () => digestDesignBundle,
|
|
120
121
|
digestDesignHtml: () => digestDesignHtml,
|
|
121
122
|
dispatchBrandTurn: () => dispatchBrandTurn,
|
|
123
|
+
exportBrandPromotion: () => exportBrandPromotion,
|
|
122
124
|
extractColors: () => extractColors,
|
|
123
125
|
extractDesignTokens: () => extractDesignTokens,
|
|
124
126
|
extractFonts: () => extractFonts,
|
|
@@ -843,14 +845,14 @@ var SNAPSHOT_REQUIRED = [
|
|
|
843
845
|
];
|
|
844
846
|
function validSnapshotShape(value) {
|
|
845
847
|
if (!record3(value) || !exactKeys(value, SNAPSHOT_REQUIRED)) return false;
|
|
846
|
-
const
|
|
847
|
-
return boundedString(value.id) && boundedString(value.bookId) && typeof value.kind === "string" && PROPOSAL_KINDS.includes(value.kind) && value.status === "open" && record3(value.payload) && boundedString(value.rationale, 2e3) && record3(
|
|
848
|
+
const provenance2 = value.provenance;
|
|
849
|
+
return boundedString(value.id) && boundedString(value.bookId) && typeof value.kind === "string" && PROPOSAL_KINDS.includes(value.kind) && value.status === "open" && record3(value.payload) && boundedString(value.rationale, 2e3) && record3(provenance2) && exactKeys(provenance2, [
|
|
848
850
|
"sourceAssetId",
|
|
849
851
|
"sourceAsset",
|
|
850
852
|
"messageId",
|
|
851
853
|
"turnId",
|
|
852
854
|
"taintLabels"
|
|
853
|
-
]) && (
|
|
855
|
+
]) && (provenance2.sourceAssetId === null || boundedString(provenance2.sourceAssetId)) && (provenance2.sourceAsset === null || record3(provenance2.sourceAsset) && exactKeys(provenance2.sourceAsset, [
|
|
854
856
|
"assetId",
|
|
855
857
|
"contentDigest",
|
|
856
858
|
"objectEtag",
|
|
@@ -859,7 +861,7 @@ function validSnapshotShape(value) {
|
|
|
859
861
|
"contentType",
|
|
860
862
|
"analysisRevision",
|
|
861
863
|
"analysisDigest"
|
|
862
|
-
]) && boundedString(
|
|
864
|
+
]) && boundedString(provenance2.sourceAsset.assetId) && typeof provenance2.sourceAsset.contentDigest === "string" && DIGEST.test(provenance2.sourceAsset.contentDigest) && boundedString(provenance2.sourceAsset.objectEtag) && Number.isSafeInteger(provenance2.sourceAsset.objectSize) && provenance2.sourceAsset.objectSize > 0 && typeof provenance2.sourceAsset.pathDigest === "string" && DIGEST.test(provenance2.sourceAsset.pathDigest) && (provenance2.sourceAsset.contentType === null || boundedString(provenance2.sourceAsset.contentType, 160)) && (provenance2.sourceAsset.analysisRevision === null || Number.isSafeInteger(provenance2.sourceAsset.analysisRevision) && provenance2.sourceAsset.analysisRevision >= 0) && (provenance2.sourceAsset.analysisDigest === null || typeof provenance2.sourceAsset.analysisDigest === "string" && DIGEST.test(provenance2.sourceAsset.analysisDigest))) && (provenance2.sourceAssetId === null && provenance2.sourceAsset === null || provenance2.sourceAssetId !== null && provenance2.sourceAsset !== null && provenance2.sourceAsset.assetId === provenance2.sourceAssetId) && (provenance2.messageId === null || boundedString(provenance2.messageId)) && (provenance2.turnId === null || boundedString(provenance2.turnId)) && Array.isArray(provenance2.taintLabels) && provenance2.taintLabels.length <= 16 && provenance2.taintLabels.every((label) => boundedString(label, 120)) && new Set(provenance2.taintLabels).size === provenance2.taintLabels.length && typeof value.reviewDigest === "string" && DIGEST.test(value.reviewDigest) && Array.isArray(value.audience) && value.audience.length > 0 && value.audience.length <= 100 && value.audience.every((id) => boundedString(id)) && new Set(value.audience).size === value.audience.length && boundedString(value.createdBy) && boundedString(value.createdAuthorityRef) && safeTime(value.createdAt);
|
|
863
865
|
}
|
|
864
866
|
var CONSUMPTION_REQUIRED = [
|
|
865
867
|
"id",
|
|
@@ -5455,4 +5457,111 @@ function createBrandIntegration(options = {}) {
|
|
|
5455
5457
|
probes: [{ path: `${basePath}/books`, expectedStatus: 401 }]
|
|
5456
5458
|
};
|
|
5457
5459
|
}
|
|
5460
|
+
|
|
5461
|
+
// src/promotion.ts
|
|
5462
|
+
var import_promotion = require("@odla-ai/promotion");
|
|
5463
|
+
var BRAND_PROMOTION_ADAPTER = "@odla-ai/brand/v1";
|
|
5464
|
+
var provenance = (sourceIds, receiptDigests = []) => ({
|
|
5465
|
+
adapter: BRAND_PROMOTION_ADAPTER,
|
|
5466
|
+
sourceIds: [...sourceIds].sort(),
|
|
5467
|
+
receiptDigests: [...receiptDigests].sort()
|
|
5468
|
+
});
|
|
5469
|
+
var exclusions = (book) => [
|
|
5470
|
+
{
|
|
5471
|
+
kind: "brand.runtime",
|
|
5472
|
+
id: book.slug,
|
|
5473
|
+
reason: "environment_local",
|
|
5474
|
+
paths: [`${BRAND_NS.book}.ownerId`, `${BRAND_NS.book}.memberIds`, `${BRAND_NS.book}.channelId`, `${BRAND_NS.book}.*At`],
|
|
5475
|
+
detail: "Ownership, roster, channel, and timestamps remain local to the target environment."
|
|
5476
|
+
},
|
|
5477
|
+
{
|
|
5478
|
+
kind: "brand.drafts",
|
|
5479
|
+
id: book.slug,
|
|
5480
|
+
reason: "draft_state",
|
|
5481
|
+
paths: [`${BRAND_NS.proposal}.*`, `${BRAND_NS.section}[status=draft]`],
|
|
5482
|
+
detail: "Open proposals and unapproved sections are review state, not published brand content."
|
|
5483
|
+
},
|
|
5484
|
+
{
|
|
5485
|
+
kind: "brand.assets",
|
|
5486
|
+
id: book.slug,
|
|
5487
|
+
reason: "provider_identity",
|
|
5488
|
+
paths: [`${BRAND_NS.asset}.storageObjectId`, `${BRAND_NS.asset}.path`, `${BRAND_NS.asset}.*AuthorityRef`],
|
|
5489
|
+
detail: "Stored files and provider object identities require a separate asset-transfer contract."
|
|
5490
|
+
},
|
|
5491
|
+
{
|
|
5492
|
+
kind: "brand.authority",
|
|
5493
|
+
id: book.slug,
|
|
5494
|
+
reason: "authority_history",
|
|
5495
|
+
paths: [`${BRAND_NS.approvalReceipt}.*`, `${BRAND_NS.palette}.audience`],
|
|
5496
|
+
detail: "Authority rows stay immutable in their source environment; artifacts retain only receipt digests and ids."
|
|
5497
|
+
}
|
|
5498
|
+
];
|
|
5499
|
+
function exportBrandPromotion(input) {
|
|
5500
|
+
const { book } = input;
|
|
5501
|
+
if (book.status !== "active") throw new TypeError(`brand book ${book.slug} is not active`);
|
|
5502
|
+
const revision = `brand:${book.slug}:${book.activationRevision}`;
|
|
5503
|
+
const artifacts = [];
|
|
5504
|
+
if (book.tokens) {
|
|
5505
|
+
const {
|
|
5506
|
+
compiledAt: _compiledAt,
|
|
5507
|
+
paletteReceiptId,
|
|
5508
|
+
paletteActionDigest,
|
|
5509
|
+
typographyReceiptId,
|
|
5510
|
+
typographyActionDigest,
|
|
5511
|
+
sourceDigest,
|
|
5512
|
+
...stableTokens
|
|
5513
|
+
} = book.tokens;
|
|
5514
|
+
artifacts.push({
|
|
5515
|
+
kind: "brand.tokens",
|
|
5516
|
+
id: book.slug,
|
|
5517
|
+
sourceRevision: revision,
|
|
5518
|
+
provenance: provenance(
|
|
5519
|
+
[book.id, book.tokens.paletteId, paletteReceiptId, typographyReceiptId].filter((value) => Boolean(value)),
|
|
5520
|
+
[sourceDigest, paletteActionDigest, typographyActionDigest].filter((value) => Boolean(value))
|
|
5521
|
+
),
|
|
5522
|
+
content: (0, import_promotion.canonicalPromotionValue)({ bookSlug: book.slug, tokens: stableTokens })
|
|
5523
|
+
});
|
|
5524
|
+
}
|
|
5525
|
+
for (const section of input.sections.filter((row) => row.bookId === book.id && row.status === "approved")) {
|
|
5526
|
+
if (!section.approvalReceiptId || !section.approvalActionDigest) {
|
|
5527
|
+
throw new TypeError(`approved brand section ${section.key} lacks approval provenance`);
|
|
5528
|
+
}
|
|
5529
|
+
artifacts.push({
|
|
5530
|
+
kind: "brand.section",
|
|
5531
|
+
id: `${book.slug}/${section.kind}`,
|
|
5532
|
+
sourceRevision: revision,
|
|
5533
|
+
provenance: provenance([book.id, section.id, section.approvalReceiptId], [section.approvalActionDigest]),
|
|
5534
|
+
content: (0, import_promotion.canonicalPromotionValue)({ bookSlug: book.slug, kind: section.kind, content: section.content })
|
|
5535
|
+
});
|
|
5536
|
+
}
|
|
5537
|
+
const activePalette2 = input.palettes.find((row) => row.bookId === book.id && row.id === book.activePaletteId && row.status === "active");
|
|
5538
|
+
if (book.activePaletteId && !activePalette2) throw new TypeError(`active palette ${book.activePaletteId} is unavailable`);
|
|
5539
|
+
if (activePalette2) {
|
|
5540
|
+
artifacts.push({
|
|
5541
|
+
kind: "brand.palette",
|
|
5542
|
+
id: `${book.slug}/${activePalette2.id}`,
|
|
5543
|
+
sourceRevision: revision,
|
|
5544
|
+
provenance: provenance([book.id, activePalette2.id, activePalette2.proposalId, activePalette2.approvalReceiptId], [activePalette2.approvalActionDigest]),
|
|
5545
|
+
content: (0, import_promotion.canonicalPromotionValue)({
|
|
5546
|
+
bookSlug: book.slug,
|
|
5547
|
+
name: activePalette2.name,
|
|
5548
|
+
swatches: activePalette2.swatches,
|
|
5549
|
+
source: activePalette2.source,
|
|
5550
|
+
...activePalette2.seedHex ? { seedHex: activePalette2.seedHex } : {},
|
|
5551
|
+
...activePalette2.rationale ? { rationale: activePalette2.rationale } : {}
|
|
5552
|
+
})
|
|
5553
|
+
});
|
|
5554
|
+
}
|
|
5555
|
+
return {
|
|
5556
|
+
adapter: BRAND_PROMOTION_ADAPTER,
|
|
5557
|
+
artifacts,
|
|
5558
|
+
exclusions: exclusions(book),
|
|
5559
|
+
preconditions: [{
|
|
5560
|
+
code: "brand.schema",
|
|
5561
|
+
path: "services.brand.schemaVersion",
|
|
5562
|
+
expected: 1,
|
|
5563
|
+
detail: "The target must expose the Brand v1 approved-content schema."
|
|
5564
|
+
}]
|
|
5565
|
+
};
|
|
5566
|
+
}
|
|
5458
5567
|
//# sourceMappingURL=index.cjs.map
|