@wkovacs64/add-icon
Version:
CLI tool to download and transform icons from Iconify
82 lines (81 loc) • 3.09 kB
JavaScript
import fs from 'node:fs';
import path from 'node:path';
import { defaultConfig } from './config.js';
/**
* Parses an icon reference into iconSet and iconName
* @param iconReference - Reference in format 'iconSet:iconName'
* @returns Object with iconSet and iconName
*/
export function parseIconReference(iconReference) {
const parts = iconReference.split(':');
if (parts.length !== 2 || !parts[0] || !parts[1]) {
throw new Error(`Invalid icon reference: ${iconReference}. Expected format: iconSet:iconName`);
}
return {
iconSet: parts[0],
iconName: parts[1],
};
}
/**
* Fetches icon SVG directly from Iconify API
* @param iconSet - Icon set name
* @param iconName - Icon name
* @returns Promise with SVG string
*/
async function fetchIconSvg(iconSet, iconName) {
// Using width=unset parameter to remove width/height attributes automatically
const apiUrl = `https://api.iconify.design/${iconSet}/${iconName}.svg?width=unset`;
try {
const response = await fetch(apiUrl);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return await response.text();
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to fetch icon SVG: ${errorMessage}`);
}
}
/**
* Downloads an icon and applies transforms
* @param iconReference - Icon reference (e.g., 'heroicons:arrow-up-circle')
* @param config - Configuration options
* @returns Path to saved icon file
*/
export async function downloadIcon(iconReference, config) {
try {
const { iconSet, iconName } = parseIconReference(iconReference);
// Use default output directory if not specified
const outputDir = config.outputDir || defaultConfig.outputDir;
// Ensure the output directory exists
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
// Fetch SVG directly with width=unset parameter to remove width/height attributes
let svg = await fetchIconSvg(iconSet, iconName);
// Apply custom transforms if specified
if (config.transforms && config.transforms.length > 0) {
for (const transform of config.transforms) {
// Create transform arguments object
const transformArgs = {
svg,
iconSet,
iconName,
};
// Apply transform
svg = await Promise.resolve(transform(transformArgs));
}
}
// Create file name
const fileName = `${iconSet}-${iconName}.svg`;
const filePath = path.join(outputDir, fileName);
// Write the SVG file
fs.writeFileSync(filePath, svg, 'utf8');
return filePath;
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to download icon: ${errorMessage}`);
}
}