// Extracts the SVG path data of a few Carbon icons into src/pdf/decor/icons.generated.ts, so the PDF code // carries plain path strings and never imports React icon components (src/pdf stays free of the DOM). // Run: npm run decor:icons import { readFileSync, writeFileSync } from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); const ICONS = { phone: "Phone", email: "Email", location: "Location" }; const out = {}; for (const [key, name] of Object.entries(ICONS)) { const src = readFileSync(path.join(ROOT, "node_modules/@carbon/icons-react/es", `${name}.js`), "utf8"); const viewBox = /viewBox: "([^"]+)"/.exec(src)?.[1]; const paths = [...src.matchAll(/jsx\("path", \{ d: "([^"]+)" \}\)/g)].map((m) => m[1]); if (!viewBox || paths.length === 0 || /jsx\("(circle|rect|polygon)"/.test(src)) throw new Error(`${name}: unexpected icon structure`); out[key] = { viewBox, paths }; } const body = `// Generated by \`npm run decor:icons\` (scripts/decor/icons.mjs). Do not edit by hand. // Path data of IBM Carbon icons, Apache-2.0 (see ICONS-NOTICE.md). export interface IconArt { /** "minX minY width height", as in the Carbon source. */ viewBox: string; paths: string[]; } export const ICONS = ${JSON.stringify(out, null, 2)} as const satisfies Record; export type IconName = keyof typeof ICONS; `; writeFileSync(path.join(ROOT, "src/pdf/decor/icons.generated.ts"), body); console.log(`icons.generated.ts: ${Object.keys(out).join(", ")}`);