2023-11-13 22:04:41 +00:00
|
|
|
import type { Plugin } from "rollup";
|
2023-12-24 17:39:43 +00:00
|
|
|
// eslint-disable-next-line import/no-named-as-default
|
2023-11-06 02:22:33 +00:00
|
|
|
import glob from "fast-glob";
|
|
|
|
import { readFile } from "fs/promises";
|
|
|
|
import { createRequire } from "module";
|
2023-12-24 17:39:43 +00:00
|
|
|
import { dirname } from "path";
|
|
|
|
import { fileURLToPath } from "url";
|
2023-04-07 16:39:59 +00:00
|
|
|
|
|
|
|
// https://stackoverflow.com/a/62499498/242365
|
|
|
|
const require = createRequire(import.meta.url);
|
|
|
|
|
2024-02-18 14:03:26 +00:00
|
|
|
const coreIcons = [
|
|
|
|
"arrow-left", "arrow-right", "car", "check", "circle-info", "cog", "copy", "info-sign",
|
2024-03-05 05:12:57 +00:00
|
|
|
"menu-hamburger", "minus", "new-window", "person-biking", "person-walking", "plus",
|
|
|
|
"question-sign", "qrcode", "remove", "resize-horizontal", "resize-vertical", "screenshot",
|
|
|
|
"search", "slash", "triangle-bottom", "triangle-top", "unchecked", "zoom-in"
|
2024-02-18 14:03:26 +00:00
|
|
|
];
|
|
|
|
|
2024-02-18 04:56:50 +00:00
|
|
|
async function getIconFilenames(): Promise<Record<string, Record<string, string>>> {
|
|
|
|
const icons: Record<string, Record<string, string>> = {};
|
|
|
|
|
|
|
|
for (const path of await glob(`${dirname(fileURLToPath(import.meta.url))}/assets/icons/*/*.svg`)) {
|
|
|
|
const [set, fname] = path.split("/").slice(-2);
|
|
|
|
|
|
|
|
if (!icons[set])
|
|
|
|
icons[set] = {};
|
|
|
|
|
|
|
|
icons[set][fname.replace(/\.svg$/, "")] = path;
|
|
|
|
}
|
|
|
|
|
|
|
|
icons["fontawesome"] = {};
|
|
|
|
for (const name of ["arrow-left", "arrow-right", "person-biking", "car", "chart-line", "copy", "circle-info", "slash", "person-walking"]) {
|
|
|
|
icons["fontawesome"][name] = require.resolve(`@fortawesome/fontawesome-free/svgs/solid/${name}.svg`);
|
|
|
|
}
|
|
|
|
|
|
|
|
return icons;
|
|
|
|
}
|
|
|
|
|
2024-02-18 14:03:26 +00:00
|
|
|
function pickIcons(icons: Record<string, Record<string, string>>, pick: (set: string, key: string) => boolean): Record<string, Record<string, string>> {
|
|
|
|
return Object.fromEntries(Object.entries(icons).map(([k1, v2]) => (
|
|
|
|
[k1, Object.fromEntries(Object.entries(v2).filter(([k2]) => pick(k1, k2)))]
|
|
|
|
)));
|
|
|
|
}
|
|
|
|
|
|
|
|
async function getIcons(iconFilenames: Record<string, Record<string, string>>): Promise<Record<string, Record<string, string>>> {
|
|
|
|
const icons: Record<string, Record<string, string>> = {};
|
|
|
|
for (const [set, fnames] of Object.entries(iconFilenames)) {
|
|
|
|
icons[set] = {};
|
|
|
|
for (const [key, fname] of Object.entries(fnames)) {
|
|
|
|
icons[set][key] = (await readFile(fname)).toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return icons;
|
|
|
|
}
|
|
|
|
|
2023-04-07 16:39:59 +00:00
|
|
|
export default function iconPlugin(): Plugin {
|
|
|
|
return {
|
2023-11-13 22:04:41 +00:00
|
|
|
name: 'virtual:icons',
|
2023-04-07 16:39:59 +00:00
|
|
|
resolveId: (id) => {
|
2024-02-18 14:03:26 +00:00
|
|
|
if (['virtual:icons:core', 'virtual:icons:extra', 'virtual:icons:keys'].includes(id)) {
|
2023-04-07 16:39:59 +00:00
|
|
|
return id;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
load: async (id) => {
|
2024-02-18 04:56:50 +00:00
|
|
|
if (id === 'virtual:icons:keys') {
|
|
|
|
const iconFilenames = await getIconFilenames();
|
|
|
|
const icons = Object.fromEntries(Object.entries(iconFilenames).map(([set, fnames]) => [set, Object.keys(fnames)]));
|
2024-02-18 14:03:26 +00:00
|
|
|
return (
|
|
|
|
`export const coreIconKeys = ${JSON.stringify(coreIcons)};\n\n` +
|
|
|
|
`export default ${JSON.stringify(icons, undefined, '\t')}`
|
|
|
|
);
|
|
|
|
} else if (id === 'virtual:icons:core') {
|
|
|
|
const iconFilenames = pickIcons(await getIconFilenames(), (set, key) => coreIcons.includes(key));
|
|
|
|
const icons = await getIcons(iconFilenames);
|
2024-02-18 04:56:50 +00:00
|
|
|
return `export default ${JSON.stringify(icons, undefined, '\t')}`;
|
2024-02-18 14:03:26 +00:00
|
|
|
} else if (id === 'virtual:icons:extra') {
|
|
|
|
const iconFilenames = pickIcons(await getIconFilenames(), (set, key) => !coreIcons.includes(key));
|
|
|
|
const icons = await getIcons(iconFilenames);
|
2023-04-07 16:39:59 +00:00
|
|
|
return `export default ${JSON.stringify(icons, undefined, '\t')}`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|