mirror of
https://github.com/StepanovPlaton/AboutMe.git
synced 2026-07-28 19:35:51 +04:00
93 lines
3.0 KiB
JavaScript
93 lines
3.0 KiB
JavaScript
import { readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
import { join } from "path";
|
|
import { createRequire } from "module";
|
|
import { getIconData, iconToSVG } from "@iconify/utils";
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const ROOT = join(import.meta.dirname, "..");
|
|
const INVENTORY_FILE = join(ROOT, "src/generated/icon-inventory.json");
|
|
const OUT_DIR = join(ROOT, "src/generated");
|
|
const OUT_FILE = join(OUT_DIR, "site-icon-svgs.ts");
|
|
|
|
const PACKAGE_BY_PREFIX = {
|
|
"fa6-brands": "@iconify-json/fa6-brands",
|
|
"fa6-regular": "@iconify-json/fa6-regular",
|
|
"fa6-solid": "@iconify-json/fa6-solid",
|
|
mdi: "@iconify-json/mdi",
|
|
"material-symbols": "@iconify-json/material-symbols",
|
|
logos: "@iconify-json/logos",
|
|
devicon: "@iconify-json/devicon",
|
|
hugeicons: "@iconify-json/hugeicons",
|
|
mingcute: "@iconify-json/mingcute",
|
|
"skill-icons": "@iconify-json/skill-icons",
|
|
"vscode-icons": "@iconify-json/vscode-icons",
|
|
"material-icon-theme": "@iconify-json/material-icon-theme",
|
|
"game-icons": "@iconify-json/game-icons",
|
|
iconoir: "@iconify-json/iconoir",
|
|
};
|
|
|
|
function loadIconSet(prefix) {
|
|
const pkg = PACKAGE_BY_PREFIX[prefix];
|
|
if (!pkg) return null;
|
|
return require(`${pkg}/icons.json`);
|
|
}
|
|
|
|
function buildSvg(iconName) {
|
|
const [prefix, name] = iconName.split(":");
|
|
const iconSet = loadIconSet(prefix);
|
|
if (!iconSet) {
|
|
console.warn(`Unknown icon set: ${prefix} (${iconName})`);
|
|
return null;
|
|
}
|
|
const data = getIconData(iconSet, name);
|
|
if (!data) {
|
|
console.warn(`Icon not found: ${iconName}`);
|
|
return null;
|
|
}
|
|
const { body, attributes } = iconToSVG(data, { height: "1em" });
|
|
const attrs = Object.entries(attributes)
|
|
.map(([k, v]) => `${k}="${v}"`)
|
|
.join(" ");
|
|
return `<svg xmlns="http://www.w3.org/2000/svg" ${attrs}>${body}</svg>`;
|
|
}
|
|
|
|
function main() {
|
|
const inventory = JSON.parse(readFileSync(INVENTORY_FILE, "utf8"));
|
|
/** @type {Record<string, string>} */
|
|
const svgs = {};
|
|
|
|
for (const [prefix, names] of Object.entries(inventory)) {
|
|
for (const name of names) {
|
|
const fullName = `${prefix}:${name}`;
|
|
const svg = buildSvg(fullName);
|
|
if (svg) svgs[fullName] = svg;
|
|
}
|
|
}
|
|
|
|
const fallback =
|
|
svgs["material-symbols:help-outline"] ??
|
|
svgs["material-symbols:info"] ??
|
|
Object.values(svgs)[0] ??
|
|
"";
|
|
|
|
const lines = [
|
|
"// Generated by scripts/generate-site-icons.mjs — do not edit manually",
|
|
"",
|
|
`export const siteIconFallback = ${JSON.stringify(fallback)};`,
|
|
"",
|
|
"export const siteIconSvgs: Record<string, string> = {",
|
|
];
|
|
|
|
for (const [name, svg] of Object.entries(svgs).sort(([a], [b]) => a.localeCompare(b))) {
|
|
lines.push(` ${JSON.stringify(name)}: ${JSON.stringify(svg)},`);
|
|
}
|
|
|
|
lines.push("};", "");
|
|
|
|
mkdirSync(OUT_DIR, { recursive: true });
|
|
writeFileSync(OUT_FILE, `${lines.join("\n")}\n`, "utf8");
|
|
console.log(`Generated ${Object.keys(svgs).length} SVGs -> ${OUT_FILE}`);
|
|
}
|
|
|
|
main();
|