chore(icon_pack): generate src declaration

This commit is contained in:
Elian Doran 2025-12-26 18:04:39 +02:00
parent 2f24703690
commit b157cd909c
No known key found for this signature in database
3 changed files with 45 additions and 25 deletions

View File

@ -1,6 +1,21 @@
import { buildNote } from "../test/becca_easy_mocking";
import { determineBestFontAttachment, generateCss, IconPackManifest, processIconPack } from "./icon_packs";
const manifest: IconPackManifest = {
name: "Boxicons v2",
prefix: "bx",
icons: {
"bx-ball": "\ue9c2",
"bxs-party": "\uec92"
}
};
const defaultAttachment = {
role: "file",
title: "Font",
mime: "font/woff2"
};
describe("Processing icon packs", () => {
it("doesn't crash if icon pack is incorrect type", () => {
const iconPack = processIconPack(buildNote({
@ -11,18 +26,12 @@ describe("Processing icon packs", () => {
});
it("processes manifest", () => {
const manifest: IconPackManifest = {
name: "Boxicons v2",
prefix: "bx",
icons: {
"bx-ball": "\ue9c2",
"bxs-party": "\uec92"
}
};
const iconPack = processIconPack(buildNote({
type: "text",
content: JSON.stringify(manifest)
content: JSON.stringify(manifest),
attachments: [ defaultAttachment ]
}));
expect(iconPack).toBeTruthy();
expect(iconPack?.manifest).toMatchObject(manifest);
});
});
@ -31,13 +40,7 @@ describe("Mapping attachments", () => {
it("handles woff2", () => {
const iconPackNote = buildNote({
type: "text",
attachments: [
{
role: "file",
title: "Font",
mime: "font/woff2"
}
]
attachments: [ defaultAttachment ]
});
const attachment = determineBestFontAttachment(iconPackNote);
expect(attachment?.mime).toStrictEqual("font/woff2");
@ -109,7 +112,7 @@ describe("CSS generation", () => {
"bxs-party": "\uec92"
}
};
const iconPackNote = buildNote({
const processedResult = processIconPack(buildNote({
type: "text",
content: JSON.stringify(manifest),
attachments: [
@ -119,13 +122,12 @@ describe("CSS generation", () => {
mime: "font/woff2"
}
]
});
const processedResult = processIconPack(iconPackNote);
}));
expect(processedResult).toBeTruthy();
const css = generateCss(processedResult!, iconPackNote);
const css = generateCss(processedResult!);
console.log(css);
expect(css).toContain("@font-face");
expect(css).toContain("font-family: 'trilium-icon-pack-bx'");
expect(css).toContain(`src: url('/api/attachments/${processedResult?.fontAttachmentId}/download') format('woff2');`);
});
});

View File

@ -6,7 +6,13 @@ const PREFERRED_MIME_TYPE = [
"font/woff2",
"font/woff",
"font/ttf"
];
] as const;
const MIME_TO_CSS_FORMAT_MAPPINGS: Record<typeof PREFERRED_MIME_TYPE[number], string> = {
"font/ttf": "truetype",
"font/woff": "woff",
"font/woff2": "woff2"
};
export interface IconPackManifest {
name: string;
@ -16,6 +22,8 @@ export interface IconPackManifest {
interface ProcessResult {
manifest: IconPackManifest;
fontMime: string;
fontAttachmentId: string;
}
export function processIconPack(iconPackNote: BNote): ProcessResult | undefined {
@ -25,8 +33,16 @@ export function processIconPack(iconPackNote: BNote): ProcessResult | undefined
return;
}
const attachment = determineBestFontAttachment(iconPackNote);
if (!attachment || !attachment.attachmentId) {
log.error(`Icon pack is missing WOFF/WOFF2/TTF attachment: ${iconPackNote.title} (${iconPackNote.noteId})`);
return;
}
return {
manifest
manifest,
fontMime: attachment.mime,
fontAttachmentId: attachment.attachmentId
};
}
@ -46,12 +62,13 @@ export function determineBestFontAttachment(iconPackNote: BNote) {
return null;
}
export function generateCss(processedIconPack: ProcessResult, iconPackNote: BNote) {
export function generateCss(processedIconPack: ProcessResult) {
return `\
@font-face {
font-family: 'trilium-icon-pack-${processedIconPack.manifest.prefix}';
font-weight: normal;
font-style: normal;
src: url('/api/attachments/${processedIconPack.fontAttachmentId}/download') format('${MIME_TO_CSS_FORMAT_MAPPINGS[processedIconPack.fontMime]}');
}
`;
}

View File

@ -4,7 +4,7 @@ import BAttachment from "../becca/entities/battachment.js";
import BAttribute from "../becca/entities/battribute.js";
import BBranch from "../becca/entities/bbranch.js";
import BNote from "../becca/entities/bnote.js";
import utils from "../services/utils.js";
import utils, { randomString } from "../services/utils.js";
type AttributeDefinitions = { [key in `#${string}`]: string; };
type RelationDefinitions = { [key in `~${string}`]: string; };
@ -118,6 +118,7 @@ export function buildNote(noteDef: NoteDefinition) {
const allAttachments: BAttachment[] = [];
for (const { title, role, mime } of noteDef.attachments) {
const attachment = new BAttachment({
attachmentId: randomString(10),
ownerId: note.noteId,
title,
role,