Files
Kavosh/scripts/build-icons.mjs
T
2026-08-07 21:17:17 +03:30

37 lines
1.6 KiB
JavaScript

/**
* Concatenates selected Lucide icons into one sprite: app/static/dist/icons.svg
* (Chapter 05). Build-time only — never runs on the cPanel host.
*/
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const ICONS_DIR = join(__dirname, '../node_modules/lucide-static/icons');
const OUT_PATH = join(__dirname, '../app/static/dist/icons.svg');
// NOTE: verify against node_modules/lucide-static/icons/ when bumping the
// lucide-static version — icon names get renamed upstream (e.g. 'home' ->
// 'house', 'alert-triangle' -> 'triangle-alert' as of 0.446.0; caught by
// actually running this script against a real install).
const ICON_NAMES = [
'house', 'search', 'shield-alert', 'upload', 'download',
'chevron-down', 'chevron-right', 'x', 'triangle-alert', 'bot',
'sun', 'moon', 'log-out', 'loader-circle',
];
function extractInner(svg) {
const match = svg.match(/<svg[^>]*>([\s\S]*)<\/svg>/);
if (!match) throw new Error('Unexpected SVG shape');
return match[1].trim();
}
const symbols = ICON_NAMES.map((name) => {
const raw = readFileSync(join(ICONS_DIR, `${name}.svg`), 'utf8');
return `<symbol id="${name}" viewBox="0 0 24 24">${extractInner(raw)}</symbol>`;
});
mkdirSync(dirname(OUT_PATH), { recursive: true });
writeFileSync(OUT_PATH, `<svg xmlns="http://www.w3.org/2000/svg" style="display:none">\n${symbols.join('\n')}\n</svg>\n`);
console.log(`Wrote ${ICON_NAMES.length} icons to ${OUT_PATH}`);