Beautiful
at main 73 lines 2.3 kB view raw
1import fs from 'fs'; 2import path from 'path'; 3import { readSvgDirectory } from '@lucide/helpers'; 4 5const currentDir = process.cwd(); 6const ICONS_DIR = path.resolve(currentDir, '../icons'); 7const svgFiles = readSvgDirectory(ICONS_DIR, '.json'); 8 9const location = path.resolve(currentDir, '.vitepress/data', 'relatedIcons.json'); 10 11if (fs.existsSync(location)) { 12 fs.unlinkSync(location); 13} 14 15const nameWeight = 5; 16const tagWeight = 4; 17const categoryWeight = 3; 18 19const MAX_RELATED_ICONS = 4 * 17; // grid of 4x17 icons, = 68 icons 20 21const arrayMatches = (a, b) => { 22 return a.filter((item) => b.includes(item)).length; 23}; 24 25const nameParts = (icon) => 26 [ 27 icon.name, 28 ...(icon.aliases?.map((alias) => (typeof alias === 'string' ? alias : alias.name)) ?? []), 29 ] 30 .join('-') 31 .split('-') 32 .filter((word) => word.length > 2); 33 34const getRelatedIcons = (currentIcon, icons) => { 35 const iconSimilarity = (item) => 36 nameWeight * arrayMatches(nameParts(item), nameParts(currentIcon)) + 37 categoryWeight * arrayMatches(item.categories ?? [], currentIcon.categories ?? []) + 38 tagWeight * arrayMatches(item.tags ?? [], currentIcon.tags ?? []); 39 return icons 40 .filter((i) => i.name !== currentIcon.name) 41 .map((icon) => ({ icon, similarity: iconSimilarity(icon) })) 42 .filter((a) => a.similarity > 0) // @todo: maybe require a minimal non-zero similarity 43 .sort((a, b) => b.similarity - a.similarity) 44 .map((i) => i.icon) 45 .slice(0, MAX_RELATED_ICONS); 46}; 47 48const iconsMetaDataPromises = svgFiles.map(async (iconName) => { 49 const metaData = JSON.parse(fs.readFileSync(`../icons/${iconName}`)); 50 51 const name = iconName.replace('.json', ''); 52 53 return { 54 name, 55 ...metaData.default, 56 }; 57}); 58 59const iconsMetaData = await Promise.all(iconsMetaDataPromises); 60 61const relatedIcons = iconsMetaData.map((icon) => { 62 const iconRelatedIcons = getRelatedIcons(icon, iconsMetaData); 63 return [icon.name, iconRelatedIcons.map((i) => i.name)]; 64}); 65 66fs.promises 67 .writeFile(location, JSON.stringify(Object.fromEntries(relatedIcons), null, 2), 'utf-8') 68 .then(() => { 69 console.log('Successfully written relatedIcons.json file'); 70 }) 71 .catch((error) => { 72 throw new Error(`Something went wrong generating iconNode files,\n ${error}`); 73 });