rejuvallife/resources/js/@iconify/build-icons.js
2024-10-25 01:02:11 +05:00

245 lines
8.1 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* This is an advanced example for creating icon bundles for Iconify SVG Framework.
*
* It creates a bundle from:
* - All SVG files in a directory.
* - Custom JSON files.
* - Iconify icon sets.
* - SVG framework.
*
* This example uses Iconify Tools to import and clean up icons.
* For Iconify Tools documentation visit https://docs.iconify.design/tools/tools2/
*/
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
// Installation: npm install --save-dev @iconify/tools @iconify/utils @iconify/json @iconify/iconify
const tools_1 = require("@iconify/tools");
const utils_1 = require("@iconify/utils");
const sources = {
svg: [
{
dir: 'resources/images/iconify-svg',
monotone: false,
prefix: 'custom',
},
// {
// dir: 'emojis',
// monotone: false,
// prefix: 'emoji',
// },
],
icons: [
// 'mdi:home',
// 'mdi:account',
// 'mdi:login',
// 'mdi:logout',
// 'octicon:book-24',
// 'octicon:code-square-24',
],
json: [
// Custom JSON file
// 'json/gg.json',
// Iconify JSON file (@iconify/json is a package name, /json/ is directory where files are, then filename)
require.resolve('@iconify-json/bx/icons.json'),
require.resolve('@iconify-json/bxs/icons.json'),
require.resolve('@iconify-json/bxl/icons.json'),
{
filename: require.resolve('@iconify-json/mdi/icons.json'),
icons: [
'file-remove-outline',
'translate',
'vuetify',
'information-variant',
'arrow-top-right',
'arrow-bottom-right',
'arrow-bottom-left',
'arrow-top-left',
'arrow-collapse-all',
'arrow-down-left',
'web',
'cpu-32-bit',
'alpha-r',
'alpha-g',
'alpha-b',
'map-marker-off-outline',
'alpha-t-box-outline',
'form-select',
'account-cog-outline',
'laptop',
],
},
// Custom file with only few icons
// {
// filename: require.resolve('@iconify-json/line-md/icons.json'),
// icons: [
// 'home-twotone-alt',
// 'github',
// 'document-list',
// 'document-code',
// 'image-twotone',
// ],
// },
],
};
// Iconify component (this changes import statement in generated file)
// Available options: '@iconify/react' for React, '@iconify/vue' for Vue 3, '@iconify/vue2' for Vue 2, '@iconify/svelte' for Svelte
const component = '@iconify/vue';
// Set to true to use require() instead of import
const commonJS = false;
// File to save bundle to
const target = (0, node_path_1.join)(__dirname, 'icons-bundle.js');
/**
* Do stuff!
*/
// eslint-disable-next-line sonarjs/cognitive-complexity
(async function () {
let bundle = commonJS
? `const { addCollection } = require('${component}');\n\n`
: `import { addCollection } from '${component}';\n\n`;
// Create directory for output if missing
const dir = (0, node_path_1.dirname)(target);
try {
await node_fs_1.promises.mkdir(dir, {
recursive: true,
});
}
catch (err) {
//
}
/**
* Convert sources.icons to sources.json
*/
if (sources.icons) {
const sourcesJSON = sources.json ? sources.json : (sources.json = []);
// Sort icons by prefix
const organizedList = organizeIconsList(sources.icons);
for (const prefix in organizedList) {
const filename = require.resolve(`@iconify/json/json/${prefix}.json`);
sourcesJSON.push({
filename,
icons: organizedList[prefix],
});
}
}
/**
* Bundle JSON files
*/
if (sources.json) {
for (let i = 0; i < sources.json.length; i++) {
const item = sources.json[i];
// Load icon set
const filename = typeof item === 'string' ? item : item.filename;
let content = JSON.parse(await node_fs_1.promises.readFile(filename, 'utf8'));
// Filter icons
if (typeof item !== 'string' && item.icons?.length) {
const filteredContent = (0, utils_1.getIcons)(content, item.icons);
if (!filteredContent)
throw new Error(`Cannot find required icons in ${filename}`);
content = filteredContent;
}
// Remove metadata and add to bundle
removeMetaData(content);
(0, utils_1.minifyIconSet)(content);
bundle += `addCollection(${JSON.stringify(content)});\n`;
console.log(`Bundled icons from ${filename}`);
}
}
/**
* Custom SVG
*/
if (sources.svg) {
for (let i = 0; i < sources.svg.length; i++) {
const source = sources.svg[i];
// Import icons
const iconSet = await (0, tools_1.importDirectory)(source.dir, {
prefix: source.prefix,
});
// Validate, clean up, fix palette and optimise
await iconSet.forEach(async (name, type) => {
if (type !== 'icon')
return;
// Get SVG instance for parsing
const svg = iconSet.toSVG(name);
if (!svg) {
// Invalid icon
iconSet.remove(name);
return;
}
// Clean up and optimise icons
try {
// Clean up icon code
await (0, tools_1.cleanupSVG)(svg);
if (source.monotone) {
// Replace color with currentColor, add if missing
// If icon is not monotone, remove this code
await (0, tools_1.parseColors)(svg, {
defaultColor: 'currentColor',
callback: (attr, colorStr, color) => {
return (!color || (0, tools_1.isEmptyColor)(color))
? colorStr
: 'currentColor';
},
});
}
// Optimise
await (0, tools_1.runSVGO)(svg);
}
catch (err) {
// Invalid icon
console.error(`Error parsing ${name} from ${source.dir}:`, err);
iconSet.remove(name);
return;
}
// Update icon from SVG instance
iconSet.fromSVG(name, svg);
});
console.log(`Bundled ${iconSet.count()} icons from ${source.dir}`);
// Export to JSON
const content = iconSet.export();
bundle += `addCollection(${JSON.stringify(content)});\n`;
}
}
// Save to file
await node_fs_1.promises.writeFile(target, bundle, 'utf8');
console.log(`Saved ${target} (${bundle.length} bytes)`);
})().catch(err => {
console.error(err);
});
/**
* Remove metadata from icon set
*/
function removeMetaData(iconSet) {
const props = [
'info',
'chars',
'categories',
'themes',
'prefixes',
'suffixes',
];
props.forEach(prop => {
delete iconSet[prop];
});
}
/**
* Sort icon names by prefix
*/
function organizeIconsList(icons) {
const sorted = Object.create(null);
icons.forEach(icon => {
const item = (0, utils_1.stringToIcon)(icon);
if (!item)
return;
const prefix = item.prefix;
const prefixList = sorted[prefix]
? sorted[prefix]
: (sorted[prefix] = []);
const name = item.name;
if (!prefixList.includes(name))
prefixList.push(name);
});
return sorted;
}