Files
lucide/docs/scripts/writeIconRelatedIcons.mjs
Eric Fennis 077242cfa0 refactor(scripts): Cleaning up scripts (#2092)
* cleanup scripts

* Move helpers to package

* Fixes scripts

* Fix scripts

* Formatting

* Fix helpers import paths

* Remove lucide-figma

* Rename helpers package

* Fix build

* formatting

* Adjust main build-icons file

* Add export casing

* Adds `exportModuleNameCasing` fro lab project

* format files

* Bump package version @lucide/build-icons

* Revert changes in icons

* Revert changes in PR yml

* Fix lint issues

* Fix site build

* fix lint errors

* Attempt fix linting

* Fix lint errors
2024-06-28 11:24:37 +02:00

74 lines
2.2 KiB
JavaScript

import fs from 'fs';
import path from 'path';
import { readSvgDirectory } from '@lucide/helpers';
const currentDir = process.cwd();
const ICONS_DIR = path.resolve(currentDir, '../icons');
const svgFiles = readSvgDirectory(ICONS_DIR, '.json');
const location = path.resolve(currentDir, '.vitepress/data', 'relatedIcons.json');
if (fs.existsSync(location)) {
fs.unlinkSync(location);
}
const nameWeight = 5;
const tagWeight = 4;
const categoryWeight = 3;
const MAX_RELATED_ICONS = 4 * 17; // grid of 4x17 icons, = 68 icons
const arrayMatches = (a, b) => {
return a.filter((item) => b.includes(item)).length;
};
const nameParts = (icon) =>
[
icon.name,
...(icon.aliases?.map((alias) => (typeof alias === 'string' ? alias : alias.name)) ?? []),
]
.join('-')
.split('-')
.filter((word) => word.length > 2);
const getRelatedIcons = (currentIcon, icons) => {
const iconSimilarity = (item) =>
nameWeight * arrayMatches(nameParts(item), nameParts(currentIcon)) +
categoryWeight * arrayMatches(item.categories ?? [], currentIcon.categories ?? []) +
tagWeight * arrayMatches(item.tags ?? [], currentIcon.tags ?? []);
return icons
.filter((i) => i.name !== currentIcon.name)
.map((icon) => ({ icon, similarity: iconSimilarity(icon) }))
.filter((a) => a.similarity > 0) // @todo: maybe require a minimal non-zero similarity
.sort((a, b) => b.similarity - a.similarity)
.map((i) => i.icon)
.slice(0, MAX_RELATED_ICONS);
};
const iconsMetaDataPromises = svgFiles.map(async (iconName) => {
const metaData = JSON.parse(fs.readFileSync(`../icons/${iconName}`));
const name = iconName.replace('.json', '');
return {
name,
...metaData.default,
};
});
const iconsMetaData = await Promise.all(iconsMetaDataPromises);
const relatedIcons = iconsMetaData.map((icon) => {
const iconRelatedIcons = getRelatedIcons(icon, iconsMetaData);
return [icon.name, iconRelatedIcons.map((i) => i.name)];
});
fs.promises
.writeFile(location, JSON.stringify(Object.fromEntries(relatedIcons), null, 2), 'utf-8')
.then(() => {
console.log('Successfully written relatedIcons.json file');
})
.catch((error) => {
throw new Error(`Something went wrong generating iconNode files,\n ${error}`);
});