@odla-ai/brand 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +31 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +31 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1794,6 +1794,13 @@ function contrastReport(swatches) {
|
|
|
1794
1794
|
return report;
|
|
1795
1795
|
}
|
|
1796
1796
|
|
|
1797
|
+
// src/link-shape.ts
|
|
1798
|
+
function hasExactOneLink(value, expectedId) {
|
|
1799
|
+
if (Array.isArray(value))
|
|
1800
|
+
return value.length === 1 && value[0]?.id === expectedId;
|
|
1801
|
+
return typeof value === "object" && value !== null && value.id === expectedId;
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1797
1804
|
// src/skill/asset-tools.ts
|
|
1798
1805
|
var MAX_VIEW_BYTES = 4718592;
|
|
1799
1806
|
var IMAGE_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/gif", "image/webp"]);
|
|
@@ -1836,7 +1843,7 @@ function assetTools(ctx) {
|
|
|
1836
1843
|
}
|
|
1837
1844
|
});
|
|
1838
1845
|
const row = (res[BRAND_NS.asset] ?? [])[0];
|
|
1839
|
-
if (!row || row.status !== "live" || row.deletedAt || !
|
|
1846
|
+
if (!row || row.status !== "live" || row.deletedAt || !hasExactOneLink(row.book, book.id)) throw new BrandNotFoundError(`asset ${assetId}`);
|
|
1840
1847
|
return row;
|
|
1841
1848
|
};
|
|
1842
1849
|
const viewAsset = {
|
|
@@ -1924,7 +1931,7 @@ async function proposalSourceAssetId(ctx, book, value) {
|
|
|
1924
1931
|
});
|
|
1925
1932
|
const rows = result[BRAND_NS.asset] ?? [];
|
|
1926
1933
|
const asset = rows.length === 1 ? rows[0] : void 0;
|
|
1927
|
-
if (!asset || asset.id !== sourceAssetId || asset.bookId !== book.id || asset.status !== "live" || asset.deletedAt !== void 0 || !
|
|
1934
|
+
if (!asset || asset.id !== sourceAssetId || asset.bookId !== book.id || asset.status !== "live" || asset.deletedAt !== void 0 || !hasExactOneLink(asset.book, book.id)) throw new BrandInputError(
|
|
1928
1935
|
"sourceAssetId must be a live asset in this brand book"
|
|
1929
1936
|
);
|
|
1930
1937
|
return sourceAssetId;
|
|
@@ -2366,7 +2373,7 @@ function readTools(ctx) {
|
|
|
2366
2373
|
book: {}
|
|
2367
2374
|
}
|
|
2368
2375
|
});
|
|
2369
|
-
const linked = (rows) => rows.filter((row) => row.bookId === authorizedBook.id &&
|
|
2376
|
+
const linked = (rows) => rows.filter((row) => row.bookId === authorizedBook.id && hasExactOneLink(row.book, authorizedBook.id));
|
|
2370
2377
|
const sections = linked(
|
|
2371
2378
|
res[BRAND_NS.section] ?? []
|
|
2372
2379
|
);
|
|
@@ -2416,7 +2423,7 @@ function readTools(ctx) {
|
|
|
2416
2423
|
book: {}
|
|
2417
2424
|
}
|
|
2418
2425
|
});
|
|
2419
|
-
const rows = (res[BRAND_NS.asset] ?? []).filter((asset) => asset.bookId === ctx.bookId &&
|
|
2426
|
+
const rows = (res[BRAND_NS.asset] ?? []).filter((asset) => asset.bookId === ctx.bookId && hasExactOneLink(asset.book, ctx.bookId));
|
|
2420
2427
|
if (rows.length === 0) {
|
|
2421
2428
|
return { content: input.kind ? `(no ${String(input.kind)} assets uploaded yet)` : "(no assets uploaded yet)" };
|
|
2422
2429
|
}
|
|
@@ -2545,7 +2552,7 @@ async function linkedAsset(ctx, book, assetId, allowDeleting = false) {
|
|
|
2545
2552
|
});
|
|
2546
2553
|
const row = rowAsWritten(BRAND_NS.asset, (result[BRAND_NS.asset] ?? [])[0]);
|
|
2547
2554
|
const links = row?.book;
|
|
2548
|
-
if (!row || row.bookId !== book.id || !
|
|
2555
|
+
if (!row || row.bookId !== book.id || !hasExactOneLink(links, book.id) || row.status !== "live" && !(allowDeleting && row.status === "deleting")) throw new BrandNotFoundError(`asset ${assetId}`);
|
|
2549
2556
|
return row;
|
|
2550
2557
|
}
|
|
2551
2558
|
|
|
@@ -2748,7 +2755,7 @@ async function handleAssetsRoot(ctx, req, bookId) {
|
|
|
2748
2755
|
});
|
|
2749
2756
|
const assets = (result[BRAND_NS.asset] ?? []).filter((value) => {
|
|
2750
2757
|
const row = value;
|
|
2751
|
-
return row.bookId === book.id &&
|
|
2758
|
+
return row.bookId === book.id && hasExactOneLink(row.book, book.id);
|
|
2752
2759
|
});
|
|
2753
2760
|
return json({ assets });
|
|
2754
2761
|
}
|
|
@@ -3234,7 +3241,7 @@ async function proposalReceiptByMutation(ctx, mutationKey) {
|
|
|
3234
3241
|
}
|
|
3235
3242
|
});
|
|
3236
3243
|
const row = (result[BRAND_NS.approvalReceipt] ?? [])[0];
|
|
3237
|
-
if (!row || !
|
|
3244
|
+
if (!row || !hasExactOneLink(row.book, row.bookId)) return void 0;
|
|
3238
3245
|
const { book: _book, ...receipt2 } = row;
|
|
3239
3246
|
return receiptAsWritten(receipt2);
|
|
3240
3247
|
}
|
|
@@ -3269,7 +3276,7 @@ async function receipt(ctx, id, actionDigest, expected) {
|
|
|
3269
3276
|
}
|
|
3270
3277
|
});
|
|
3271
3278
|
const row = (result[BRAND_NS.approvalReceipt] ?? [])[0];
|
|
3272
|
-
if (!row || row.actionDigest !== actionDigest || row.resolution !== "accepted" || row.bookId !== expected.bookId || row.reviewedProposal.bookId !== expected.bookId || row.reviewedProposal.kind !== expected.kind || !
|
|
3279
|
+
if (!row || row.actionDigest !== actionDigest || row.resolution !== "accepted" || row.bookId !== expected.bookId || row.reviewedProposal.bookId !== expected.bookId || row.reviewedProposal.kind !== expected.kind || !hasExactOneLink(row.book, expected.bookId) || expected.paletteId !== void 0 && row.paletteId !== expected.paletteId || expected.proposalId !== void 0 && row.proposalId !== expected.proposalId || expected.content !== void 0 && canonicalBrandJson(row.reviewedProposal.payload.content) !== canonicalBrandJson(expected.content)) throw new BrandConflictError(`approval receipt ${id} is invalid`);
|
|
3273
3280
|
const { book: _book, ...stored } = row;
|
|
3274
3281
|
const unhydrated = receiptAsWritten(stored);
|
|
3275
3282
|
if (!await verifyBrandApprovalReceipt(unhydrated))
|
|
@@ -3284,8 +3291,11 @@ async function activePalette(ctx, book) {
|
|
|
3284
3291
|
book: {}
|
|
3285
3292
|
}
|
|
3286
3293
|
});
|
|
3287
|
-
const palette = (
|
|
3288
|
-
|
|
3294
|
+
const palette = rowAsWritten(
|
|
3295
|
+
BRAND_NS.palette,
|
|
3296
|
+
(result[BRAND_NS.palette] ?? [])[0]
|
|
3297
|
+
);
|
|
3298
|
+
if (!palette || palette.bookId !== book.id || palette.status !== "active" || !palette.proposalId || !palette.approvalReceiptId || !palette.approvalActionDigest || !hasExactOneLink(palette.book, book.id)) throw new BrandConflictError(
|
|
3289
3299
|
"active palette is missing valid approval provenance"
|
|
3290
3300
|
);
|
|
3291
3301
|
const approval = await receipt(
|
|
@@ -3332,9 +3342,12 @@ async function approvedTypography(ctx, book) {
|
|
|
3332
3342
|
book: {}
|
|
3333
3343
|
}
|
|
3334
3344
|
});
|
|
3335
|
-
const section = (
|
|
3345
|
+
const section = rowAsWritten(
|
|
3346
|
+
BRAND_NS.section,
|
|
3347
|
+
(result[BRAND_NS.section] ?? [])[0]
|
|
3348
|
+
);
|
|
3336
3349
|
if (!section || section.status !== "approved") return {};
|
|
3337
|
-
if (section.bookId !== book.id || section.kind !== "typography" || !section.approvalReceiptId || !section.approvalActionDigest || !
|
|
3350
|
+
if (section.bookId !== book.id || section.kind !== "typography" || !section.approvalReceiptId || !section.approvalActionDigest || !hasExactOneLink(section.book, book.id)) throw new BrandConflictError(
|
|
3338
3351
|
"approved typography is missing valid approval provenance"
|
|
3339
3352
|
);
|
|
3340
3353
|
assertSectionContent("typography", section.content);
|
|
@@ -3375,7 +3388,7 @@ async function proposalDecisionState(ctx, req, book, proposal, resolution, recei
|
|
|
3375
3388
|
}
|
|
3376
3389
|
});
|
|
3377
3390
|
sourceAsset = (result[BRAND_NS.asset] ?? [])[0];
|
|
3378
|
-
if (!sourceAsset || sourceAsset.id !== source.assetId || sourceAsset.bookId !== book.id || sourceAsset.status !== "live" || sourceAsset.deletedAt !== void 0 || sourceAsset.contentDigest !== source.contentDigest || sourceAsset.size !== source.objectSize || sourceAsset.contentType !== source.contentType || await brandJsonDigest({ appId: ctx.appId, path: sourceAsset.path }) !== source.pathDigest || sourceAsset.analysisRevision !== source.analysisRevision || (sourceAsset.analysisDigest ?? null) !== source.analysisDigest || !
|
|
3391
|
+
if (!sourceAsset || sourceAsset.id !== source.assetId || sourceAsset.bookId !== book.id || sourceAsset.status !== "live" || sourceAsset.deletedAt !== void 0 || sourceAsset.contentDigest !== source.contentDigest || sourceAsset.size !== source.objectSize || sourceAsset.contentType !== source.contentType || await brandJsonDigest({ appId: ctx.appId, path: sourceAsset.path }) !== source.pathDigest || sourceAsset.analysisRevision !== source.analysisRevision || (sourceAsset.analysisDigest ?? null) !== source.analysisDigest || !hasExactOneLink(sourceAsset.book, book.id)) throw new BrandConflictError(
|
|
3379
3392
|
"source asset changed since the proposal was reviewed"
|
|
3380
3393
|
);
|
|
3381
3394
|
if (!await ctx.verifySourceAssetSnapshot({
|
|
@@ -3559,7 +3572,7 @@ async function handleProposalResolution(ctx, req, bookId, proposalId) {
|
|
|
3559
3572
|
}
|
|
3560
3573
|
});
|
|
3561
3574
|
const proposal = proposalAsWritten((result[BRAND_NS.proposal] ?? [])[0]);
|
|
3562
|
-
if (!proposal || proposal.bookId !== book.id || !
|
|
3575
|
+
if (!proposal || proposal.bookId !== book.id || !hasExactOneLink(proposal.book, book.id)) throw new BrandNotFoundError(`proposal ${proposalId}`);
|
|
3563
3576
|
const current = proposalReviewSnapshot(proposal);
|
|
3564
3577
|
const { reviewDigest, ...unsignedReview } = current;
|
|
3565
3578
|
if (await brandJsonDigest(unsignedReview) !== reviewDigest || canonicalBrandJson(current) !== canonicalBrandJson(reviewed)) throw new BrandConflictError("proposal changed since review");
|
|
@@ -3703,7 +3716,7 @@ async function acceptedReceipt(db, bookId, receiptId, actionDigest) {
|
|
|
3703
3716
|
}
|
|
3704
3717
|
});
|
|
3705
3718
|
const receipt2 = (result[BRAND_NS.approvalReceipt] ?? [])[0];
|
|
3706
|
-
if (!receipt2 || receipt2.resolution !== "accepted" || receipt2.actionDigest !== actionDigest || !
|
|
3719
|
+
if (!receipt2 || receipt2.resolution !== "accepted" || receipt2.actionDigest !== actionDigest || !hasExactOneLink(receipt2.book, bookId)) return missing(bookId);
|
|
3707
3720
|
const { book: _book, ...stored } = receipt2;
|
|
3708
3721
|
const unhydrated = receiptAsWritten(stored);
|
|
3709
3722
|
if (!await verifyBrandApprovalReceipt(unhydrated)) return missing(bookId);
|
|
@@ -3719,7 +3732,7 @@ async function approvedCache(db, book) {
|
|
|
3719
3732
|
}
|
|
3720
3733
|
});
|
|
3721
3734
|
const palette = (paletteResult[BRAND_NS.palette] ?? [])[0];
|
|
3722
|
-
if (!palette || palette.status !== "active" || palette.approvalReceiptId !== cache.paletteReceiptId || palette.approvalActionDigest !== cache.paletteActionDigest || !
|
|
3735
|
+
if (!palette || palette.status !== "active" || palette.approvalReceiptId !== cache.paletteReceiptId || palette.approvalActionDigest !== cache.paletteActionDigest || !hasExactOneLink(palette.book, book.id)) return missing(book.id);
|
|
3723
3736
|
await acceptedReceipt(
|
|
3724
3737
|
db,
|
|
3725
3738
|
book.id,
|
|
@@ -3737,7 +3750,7 @@ async function approvedCache(db, book) {
|
|
|
3737
3750
|
});
|
|
3738
3751
|
const typography = (sectionResult[BRAND_NS.section] ?? [])[0];
|
|
3739
3752
|
if (hasTypeId) {
|
|
3740
|
-
if (!typography || typography.bookId !== book.id || typography.kind !== "typography" || typography.status !== "approved" || typography.approvalReceiptId !== cache.typographyReceiptId || typography.approvalActionDigest !== cache.typographyActionDigest || !
|
|
3753
|
+
if (!typography || typography.bookId !== book.id || typography.kind !== "typography" || typography.status !== "approved" || typography.approvalReceiptId !== cache.typographyReceiptId || typography.approvalActionDigest !== cache.typographyActionDigest || !hasExactOneLink(typography.book, book.id)) return missing(book.id);
|
|
3741
3754
|
await acceptedReceipt(
|
|
3742
3755
|
db,
|
|
3743
3756
|
book.id,
|
|
@@ -4142,7 +4155,7 @@ async function attachedBrandAssetIds(db, book, row) {
|
|
|
4142
4155
|
const rows = result[BRAND_NS.asset] ?? [];
|
|
4143
4156
|
if (rows.length !== 1) return null;
|
|
4144
4157
|
const asset = rows[0];
|
|
4145
|
-
return asset.id === id && asset.bookId === book.id && asset.status === "live" && asset.deletedAt === void 0 &&
|
|
4158
|
+
return asset.id === id && asset.bookId === book.id && asset.status === "live" && asset.deletedAt === void 0 && hasExactOneLink(asset.book, book.id) ? id : null;
|
|
4146
4159
|
}));
|
|
4147
4160
|
return assets.filter((id) => id !== null);
|
|
4148
4161
|
}
|