Files
Font_Avasome_Logseg/build-icons-json.js

864 lines
28 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const fs = require('fs');
const path = require('path');
// ================= CONFIGURACIÓN =================
const CONFIG = {
// Rutas de entrada (archivos procesados)
PROCESSED_METADATA: path.join(__dirname, 'assets', 'processed', 'metadata.json'),
PROCESSED_STYLES: path.join(__dirname, 'assets', 'processed', 'styles.json'),
PROCESSED_CATEGORIES: path.join(__dirname, 'assets', 'processed', 'categories.json'),
// Rutas de salida (plugin)
OUTPUT_ICONS: path.join(__dirname, 'assets', 'icons.json'),
OUTPUT_DYNAMIC_CSS: path.join(__dirname, 'assets', 'dynamic-styles.css'),
OUTPUT_CUSTOM_CSS: path.join(__dirname, 'assets', 'custom-styles.css'),
// Configuración del plugin
PLUGIN_NAME: 'FontAwesome Pro',
VERSION: '2.0.0'
};
// ================= ESTILOS POSIBLES =================
const ALL_STYLES = [
// Estilos clásicos
{
id: 'solid',
name: 'Solid',
prefix: 'fas',
class: 'fas',
weight: 900,
pro: true,
sharp: false,
family: 'Font Awesome 6 Pro',
file: 'fa-solid-900.woff2'
},
{
id: 'regular',
name: 'Regular',
prefix: 'far',
class: 'far',
weight: 400,
pro: true,
sharp: false,
family: 'Font Awesome 6 Pro',
file: 'fa-regular-400.woff2'
},
{
id: 'light',
name: 'Light',
prefix: 'fal',
class: 'fal',
weight: 300,
pro: true,
sharp: false,
family: 'Font Awesome 6 Pro',
file: 'fa-light-300.woff2'
},
{
id: 'thin',
name: 'Thin',
prefix: 'fat',
class: 'fat',
weight: 100,
pro: true,
sharp: false,
family: 'Font Awesome 6 Pro',
file: 'fa-thin-100.woff2'
},
{
id: 'duotone',
name: 'Duotone',
prefix: 'fad',
class: 'fad',
weight: 900,
pro: true,
sharp: false,
family: 'Font Awesome 6 Duotone',
file: 'fa-duotone-900.woff2'
},
// Estilos Sharp
{
id: 'sharp-solid',
name: 'Sharp Solid',
prefix: 'fass',
class: 'fass',
weight: 900,
pro: true,
sharp: true,
family: 'Font Awesome 6 Sharp',
file: 'fa-sharp-solid-900.woff2'
},
{
id: 'sharp-regular',
name: 'Sharp Regular',
prefix: 'fasr',
class: 'fasr',
weight: 400,
pro: true,
sharp: true,
family: 'Font Awesome 6 Sharp',
file: 'fa-sharp-regular-400.woff2'
},
{
id: 'sharp-light',
name: 'Sharp Light',
prefix: 'fasl',
class: 'fasl',
weight: 300,
pro: true,
sharp: true,
family: 'Font Awesome 6 Sharp',
file: 'fa-sharp-light-300.woff2'
},
{
id: 'sharp-thin',
name: 'Sharp Thin',
prefix: 'fast',
class: 'fast',
weight: 100,
pro: true,
sharp: true,
family: 'Font Awesome 6 Sharp',
file: 'fa-sharp-thin-100.woff2'
},
{
id: 'sharp-duotone',
name: 'Sharp Duotone',
prefix: 'fasd',
class: 'fasd',
weight: 900,
pro: true,
sharp: true,
family: 'Font Awesome 6 Sharp Duotone',
file: 'fa-sharp-duotone-900.woff2'
},
// Brands
{
id: 'brands',
name: 'Brands',
prefix: 'fab',
class: 'fab',
weight: 400,
pro: false,
sharp: false,
family: 'Font Awesome 6 Brands',
file: 'fa-brands-400.woff2'
}
];
// Estilos detectados (se llenará automáticamente)
let DETECTED_STYLES = [];
// ================= FUNCIONES PRINCIPALES =================
/**
* Verificar si los archivos procesados existen
*/
function checkProcessedFiles() {
console.log('🔍 Verificando archivos procesados...\n');
const requiredFiles = [
{ path: CONFIG.PROCESSED_METADATA, name: 'metadata.json' },
{ path: CONFIG.PROCESSED_STYLES, name: 'styles.json' },
{ path: CONFIG.PROCESSED_CATEGORIES, name: 'categories.json' }
];
let allExist = true;
requiredFiles.forEach(file => {
if (fs.existsSync(file.path)) {
const stats = fs.statSync(file.path);
console.log(`${file.name}: ${(stats.size / 1024).toFixed(2)} KB`);
} else {
console.log(`${file.name}: NO ENCONTRADO`);
allExist = false;
}
});
if (!allExist) {
console.log('\n⚠ Archivos procesados no encontrados.');
console.log(' Ejecuta primero: npm run extract');
console.log(' O: npm run build (que ejecuta extract automáticamente)');
}
console.log('');
return allExist;
}
/**
* Detectar estilos disponibles automáticamente
*/
function detectAvailableStyles() {
console.log('🔍 Detectando estilos disponibles...\n');
const webfontsDir = path.join(__dirname, 'assets', 'fontawesome', 'webfonts');
if (!fs.existsSync(webfontsDir)) {
console.error('❌ Carpeta de webfonts no encontrada:', webfontsDir);
console.log(' Asegúrate de copiar los archivos de FontAwesome Pro');
return [];
}
const availableStyles = [];
const fontFiles = fs.readdirSync(webfontsDir);
ALL_STYLES.forEach(style => {
const expectedFile = style.file;
const fontPath = path.join(webfontsDir, expectedFile);
// Verificar archivo principal (.woff2)
if (fs.existsSync(fontPath)) {
availableStyles.push(style);
console.log(`${style.name.padEnd(20)} ${expectedFile}`);
} else {
// Verificar variantes
const variants = ['.ttf', '.eot', '.woff'].map(ext =>
expectedFile.replace('.woff2', ext)
);
const foundVariant = variants.find(variant =>
fs.existsSync(path.join(webfontsDir, variant))
);
if (foundVariant) {
availableStyles.push(style);
console.log(`${style.name.padEnd(20)} ${foundVariant} (variante)`);
} else {
console.log(` ⚠️ ${style.name.padEnd(20)} No encontrado`);
}
}
});
console.log('\n' + '='.repeat(60));
console.log(`📊 RESUMEN: ${availableStyles.length} de ${ALL_STYLES.length} estilos detectados`);
// Estadísticas
const classicCount = availableStyles.filter(s => !s.sharp && s.id !== 'brands').length;
const sharpCount = availableStyles.filter(s => s.sharp).length;
const brandsCount = availableStyles.filter(s => s.id === 'brands').length;
console.log(` • Clásicos: ${classicCount}/5`);
console.log(` • Sharp: ${sharpCount}/5`);
console.log(` • Brands: ${brandsCount}/1`);
console.log('='.repeat(60) + '\n');
return availableStyles;
}
/**
* Cargar metadata procesado
*/
function loadProcessedMetadata() {
try {
console.log('📥 Cargando metadata procesado...');
if (!fs.existsSync(CONFIG.PROCESSED_METADATA)) {
throw new Error(`Archivo no encontrado: ${CONFIG.PROCESSED_METADATA}`);
}
const content = fs.readFileSync(CONFIG.PROCESSED_METADATA, 'utf8');
const data = JSON.parse(content);
if (!data.icons || typeof data.icons !== 'object') {
throw new Error('Estructura de metadata inválida');
}
console.log(`✅ Metadata cargado: ${Object.keys(data.icons).length} íconos`);
// Convertir objeto a array
const iconsArray = Object.values(data.icons);
// Filtrar íconos que tienen estilos disponibles
const filteredIcons = iconsArray.filter(icon => {
if (!icon.styles || !Array.isArray(icon.styles)) {
return false;
}
// Verificar si al menos un estilo está disponible
return icon.styles.some(style =>
DETECTED_STYLES.some(s => s.id === style)
);
});
console.log(`📊 Íconos con estilos disponibles: ${filteredIcons.length}/${iconsArray.length}`);
return filteredIcons;
} catch (error) {
console.error('❌ Error cargando metadata procesado:', error.message);
return null;
}
}
/**
* Cargar información de estilos procesada
*/
function loadProcessedStylesInfo() {
try {
if (!fs.existsSync(CONFIG.PROCESSED_STYLES)) {
console.log('⚠️ Archivo de estilos procesado no encontrado');
return null;
}
const content = fs.readFileSync(CONFIG.PROCESSED_STYLES, 'utf8');
const data = JSON.parse(content);
if (!data.styles || typeof data.styles !== 'object') {
console.log('⚠️ Estructura de estilos inválida');
return null;
}
console.log('✅ Información de estilos cargada');
return data.styles;
} catch (error) {
console.log('⚠️ Error cargando información de estilos:', error.message);
return null;
}
}
/**
* Cargar categorías procesadas
*/
function loadProcessedCategories() {
try {
if (!fs.existsSync(CONFIG.PROCESSED_CATEGORIES)) {
console.log('⚠️ Archivo de categorías procesado no encontrado');
return null;
}
const content = fs.readFileSync(CONFIG.PROCESSED_CATEGORIES, 'utf8');
const data = JSON.parse(content);
if (!data.categories || !Array.isArray(data.categories)) {
console.log('⚠️ Estructura de categorías inválida');
return null;
}
console.log(`✅ Categorías cargadas: ${data.categories.length}`);
return data.categories;
} catch (error) {
console.log('⚠️ Error cargando categorías:', error.message);
return null;
}
}
/**
* Generar CSS dinámico basado en estilos detectados
*/
function generateDynamicCSS(styles) {
console.log('🎨 Generando CSS dinámico...');
let cssContent = `/* ============================================\n`;
cssContent += ` FontAwesome Dynamic Styles\n`;
cssContent += ` Generado: ${new Date().toISOString()}\n`;
cssContent += ` Estilos detectados: ${styles.length}\n`;
cssContent += `============================================ */\n\n`;
// Agrupar por familia de fuentes
const families = {};
styles.forEach(style => {
if (!families[style.family]) {
families[style.family] = [];
}
families[style.family].push(style);
});
// Generar @font-face para cada familia
Object.entries(families).forEach(([familyName, familyStyles]) => {
cssContent += `/* ${familyName} */\n`;
familyStyles.forEach(style => {
const fontWeight = style.weight;
const fontFile = style.file;
const fontPath = `../webfonts/${fontFile}`;
cssContent += `@font-face {\n`;
cssContent += ` font-family: '${familyName}';\n`;
cssContent += ` font-style: normal;\n`;
cssContent += ` font-weight: ${fontWeight};\n`;
cssContent += ` font-display: block;\n`;
cssContent += ` src: url("${fontPath}") format("woff2");\n`;
cssContent += `}\n\n`;
});
});
// Reglas de clase para cada estilo
cssContent += `/* Reglas de clase */\n`;
styles.forEach(style => {
cssContent += `.${style.prefix} {\n`;
cssContent += ` font-family: '${style.family}';\n`;
cssContent += ` font-weight: ${style.weight};\n`;
cssContent += `}\n`;
});
// Variables CSS para Duotone
const hasDuotone = styles.some(s => s.id.includes('duotone'));
if (hasDuotone) {
cssContent += `\n/* Variables para Duotone */\n`;
cssContent += `.fad, .fasd {\n`;
cssContent += ` --fa-primary-color: currentColor;\n`;
cssContent += ` --fa-secondary-color: rgba(0, 0, 0, 0.4);\n`;
cssContent += ` --fa-primary-opacity: 1;\n`;
cssContent += ` --fa-secondary-opacity: 0.4;\n`;
cssContent += `}\n`;
}
// Guardar archivo
fs.writeFileSync(CONFIG.OUTPUT_DYNAMIC_CSS, cssContent, 'utf8');
console.log(`✅ CSS dinámico generado: ${CONFIG.OUTPUT_DYNAMIC_CSS}`);
}
/**
* Generar CSS personalizado para características avanzadas
*/
function generateCustomCSS() {
console.log('🎨 Generando CSS personalizado...');
const cssContent = `/* ============================================\n`;
cssContent += ` FontAwesome Custom Styles\n`;
cssContent += ` Características avanzadas: Color, Tamaño, Animaciones\n`;
cssContent += ` Generado: ${new Date().toISOString()}\n`;
cssContent += `============================================ */\n\n`;
// Tamaños personalizados
cssContent += `/* Tamaños */\n`;
const sizes = [
{ class: 'fa-xs', size: '0.75em' },
{ class: 'fa-sm', size: '0.875em' },
{ class: 'fa-lg', size: '1.33em' },
{ class: 'fa-xl', size: '1.75em' },
{ class: 'fa-2x', size: '2em' },
{ class: 'fa-3x', size: '3em' },
{ class: 'fa-4x', size: '4em' },
{ class: 'fa-5x', size: '5em' },
{ class: 'fa-6x', size: '6em' },
{ class: 'fa-7x', size: '7em' },
{ class: 'fa-8x', size: '8em' },
{ class: 'fa-9x', size: '9em' },
{ class: 'fa-10x', size: '10em' }
];
sizes.forEach(({ class: sizeClass, size }) => {
cssContent += `.${sizeClass} { font-size: ${size} !important; }\n`;
});
// Animaciones
cssContent += `\n/* Animaciones */\n`;
cssContent += `.fa-spin { animation: fa-spin 2s linear infinite; }\n`;
cssContent += `.fa-pulse { animation: fa-spin 1s steps(8) infinite; }\n`;
cssContent += `.fa-beat { animation: fa-beat 1s ease infinite; }\n`;
cssContent += `.fa-fade { animation: fa-fade 2s ease infinite; }\n`;
cssContent += `.fa-bounce { animation: fa-bounce 1s ease infinite; }\n`;
cssContent += `.fa-flip { animation: fa-flip 2s ease infinite; }\n`;
cssContent += `.fa-shake { animation: fa-shake 1s ease infinite; }\n`;
// Keyframes para animaciones
cssContent += `\n/* Keyframes */\n`;
cssContent += `@keyframes fa-beat {\n`;
cssContent += ` 0%, 90% { transform: scale(1); }\n`;
cssContent += ` 45% { transform: scale(1.1); }\n`;
cssContent += `}\n\n`;
cssContent += `@keyframes fa-fade {\n`;
cssContent += ` 0%, 100% { opacity: 1; }\n`;
cssContent += ` 50% { opacity: 0.5; }\n`;
cssContent += `}\n\n`;
cssContent += `@keyframes fa-bounce {\n`;
cssContent += ` 0%, 100% { transform: translateY(0); }\n`;
cssContent += ` 50% { transform: translateY(-5px); }\n`;
cssContent += `}\n\n`;
cssContent += `@keyframes fa-flip {\n`;
cssContent += ` 0% { transform: perspective(400px) rotateY(0); }\n`;
cssContent += ` 100% { transform: perspective(400px) rotateY(360deg); }\n`;
cssContent += `}\n\n`;
cssContent += `@keyframes fa-shake {\n`;
cssContent += ` 0%, 100% { transform: translateX(0); }\n`;
cssContent += ` 25% { transform: translateX(-3px); }\n`;
cssContent += ` 75% { transform: translateX(3px); }\n`;
cssContent += `}\n`;
// Colores temáticos
cssContent += `\n/* Colores temáticos */\n`;
const themeColors = [
{ class: 'fa-primary', color: 'var(--ls-link-text-color, #0451a5)' },
{ class: 'fa-success', color: '#10b981' },
{ class: 'fa-danger', color: '#ef4444' },
{ class: 'fa-warning', color: '#f59e0b' },
{ class: 'fa-info', color: '#3b82f6' },
{ class: 'fa-purple', color: '#8b5cf6' },
{ class: 'fa-pink', color: '#ec4899' },
{ class: 'fa-gray', color: '#6b7280' },
{ class: 'fa-black', color: '#000000' },
{ class: 'fa-white', color: '#ffffff' }
];
themeColors.forEach(({ class: colorClass, color }) => {
cssContent += `.${colorClass} { color: ${color} !important; }\n`;
});
// Efectos especiales
cssContent += `\n/* Efectos especiales */\n`;
cssContent += `.fa-shadow { filter: drop-shadow(0 2px 4px rgba(0,0,0,0.2)); }\n`;
cssContent += `.fa-shadow-lg { filter: drop-shadow(0 4px 8px rgba(0,0,0,0.3)); }\n`;
cssContent += `.fa-glow { filter: drop-shadow(0 0 8px currentColor); }\n`;
// Gradientes
cssContent += `.fa-gradient {\n`;
cssContent += ` background: linear-gradient(45deg, #8b5cf6, #3b82f6);\n`;
cssContent += ` -webkit-background-clip: text;\n`;
cssContent += ` -webkit-text-fill-color: transparent;\n`;
cssContent += ` background-clip: text;\n`;
cssContent += `}\n`;
// Guardar archivo
fs.writeFileSync(CONFIG.OUTPUT_CUSTOM_CSS, cssContent, 'utf8');
console.log(`✅ CSS personalizado generado: ${CONFIG.OUTPUT_CUSTOM_CSS}`);
}
/**
* Crear base de datos final
*/
function createDatabase(icons, categories, stylesInfo) {
console.log('📊 Creando base de datos final...');
// Preparar estilos para la base de datos
const dbStyles = DETECTED_STYLES.map(style => {
const styleInfoData = stylesInfo && stylesInfo[style.id] ? stylesInfo[style.id] : {};
return {
id: style.id,
name: style.name,
prefix: style.prefix,
class: style.class,
weight: style.weight,
pro: style.pro,
sharp: style.sharp,
available: true,
count: styleInfoData.count || 0,
percentage: styleInfoData.percentage || '0.0'
};
});
// Actualizar conteos en categorías
const updatedCategories = categories ? categories.map(category => {
if (category.id === 'all') {
return { ...category, count: icons.length };
} else if (category.type === 'fontawesome') {
// Contar íconos en esta categoría
const count = icons.filter(icon =>
icon.categories && icon.categories.includes(category.id)
).length;
return { ...category, count };
}
return category;
}) : getDefaultCategories(icons.length);
// Crear estructura final
const database = {
meta: {
generated: new Date().toISOString(),
fontawesomeVersion: '6.0.0',
pluginVersion: CONFIG.VERSION,
totalIcons: icons.length,
totalCategories: updatedCategories.length,
detectedStyles: DETECTED_STYLES.length,
stylesAvailable: DETECTED_STYLES.map(s => s.id),
proIcons: icons.filter(icon =>
icon.styles && icon.styles.some(style =>
['solid', 'regular', 'light', 'thin', 'duotone',
'sharp-solid', 'sharp-regular', 'sharp-light', 'sharp-thin', 'sharp-duotone']
.includes(style)
)
).length,
freeIcons: icons.filter(icon =>
icon.styles && icon.styles.includes('brands')
).length
},
icons: icons.map(icon => ({
id: icon.id,
name: icon.name,
label: icon.label,
categories: icon.categories || ['uncategorized'],
styles: icon.styles || [],
searchTerms: icon.searchTerms || [],
unicode: icon.unicode || '',
version: icon.version || '6.0.0',
free: (icon.styles && icon.styles.includes('brands')) || false,
pro: icon.styles && icon.styles.some(style =>
['solid', 'regular', 'light', 'thin', 'duotone',
'sharp-solid', 'sharp-regular', 'sharp-light', 'sharp-thin', 'sharp-duotone']
.includes(style)
)
})),
categories: updatedCategories,
styles: dbStyles,
search: {
languages: ['en', 'es'],
synonyms: true
},
features: {
colorCustomization: true,
sizeCustomization: true,
animations: true,
transformations: true,
presets: true
}
};
return database;
}
/**
* Obtener categorías por defecto
*/
function getDefaultCategories(totalIcons) {
return [
{
id: 'all',
name: 'Todos los Íconos',
icon: 'fas fa-th',
count: totalIcons,
type: 'special'
},
{
id: 'favorites',
name: 'Favoritos',
icon: 'fas fa-star',
count: 0,
type: 'special'
},
{
id: 'recent',
name: 'Recientes',
icon: 'fas fa-history',
count: 0,
type: 'special'
}
];
}
/**
* Guardar base de datos
*/
function saveDatabase(database) {
try {
// Asegurar directorio
const assetsDir = path.dirname(CONFIG.OUTPUT_ICONS);
if (!fs.existsSync(assetsDir)) {
fs.mkdirSync(assetsDir, { recursive: true });
}
// Guardar JSON
fs.writeFileSync(
CONFIG.OUTPUT_ICONS,
JSON.stringify(database, null, 2),
'utf8'
);
console.log(`✅ Base de datos guardada: ${CONFIG.OUTPUT_ICONS}`);
console.log(`📊 Tamaño: ${(fs.statSync(CONFIG.OUTPUT_ICONS).size / 1024 / 1024).toFixed(2)} MB`);
} catch (error) {
console.error('❌ Error guardando base de datos:', error.message);
throw error;
}
}
/**
* Generar base de datos de ejemplo
*/
function generateSampleDatabase() {
console.log('📝 Generando base de datos de ejemplo...');
const sampleIcons = [
{
id: "home",
name: "home",
label: "Home",
categories: ["household", "buildings"],
styles: ["solid", "regular", "light"],
searchTerms: ["casa", "hogar", "inicio"],
unicode: "f015",
version: "6.0.0",
free: true,
pro: true
},
{
id: "user",
name: "user",
label: "User",
categories: ["users-people"],
styles: ["solid", "regular"],
searchTerms: ["persona", "perfil", "cuenta"],
unicode: "f007",
version: "6.0.0",
free: true,
pro: true
}
];
const sampleStyles = DETECTED_STYLES.length > 0 ?
DETECTED_STYLES.slice(0, 3) :
ALL_STYLES.slice(0, 3);
const database = {
meta: {
generated: new Date().toISOString(),
fontawesomeVersion: "6.0.0",
pluginVersion: CONFIG.VERSION,
totalIcons: sampleIcons.length,
totalCategories: 3,
detectedStyles: sampleStyles.length,
proIcons: sampleIcons.length,
freeIcons: 0,
note: "BASE DE DATOS DE EJEMPLO - Ejecuta 'npm run build' para generar la versión completa"
},
icons: sampleIcons,
categories: [
{ id: "all", name: "Todos los Íconos", icon: "fas fa-th", count: sampleIcons.length, type: "special" },
{ id: "household", name: "Hogar", icon: "fas fa-home", count: 1, type: "fontawesome" },
{ id: "users-people", name: "Personas", icon: "fas fa-user", count: 1, type: "fontawesome" }
],
styles: sampleStyles.map(s => ({
id: s.id,
name: s.name,
prefix: s.prefix,
class: s.class,
available: true
}))
};
saveDatabase(database);
return database;
}
/**
* Función principal
*/
async function generateIconDatabase() {
console.log('🎨 ' + '='.repeat(60));
console.log(' GENERADOR DE BASE DE DATOS FONTAWESOME PRO');
console.log(' Versión: ' + CONFIG.VERSION);
console.log('='.repeat(60) + '\n');
try {
// 1. Verificar archivos procesados
const hasProcessedFiles = checkProcessedFiles();
if (!hasProcessedFiles) {
console.log('⚠️ Ejecutando en modo fallback (sin archivos procesados)...');
console.log(' Para mejor rendimiento, ejecuta: npm run extract');
}
// 2. Detectar estilos disponibles
DETECTED_STYLES = detectAvailableStyles();
if (DETECTED_STYLES.length === 0) {
console.warn('⚠️ No se detectaron estilos. Generando base de datos de ejemplo...');
return generateSampleDatabase();
}
// 3. Generar CSS
generateDynamicCSS(DETECTED_STYLES);
generateCustomCSS();
// 4. Cargar datos procesados
let icons, stylesInfo, categories;
if (hasProcessedFiles) {
icons = loadProcessedMetadata();
stylesInfo = loadProcessedStylesInfo();
categories = loadProcessedCategories();
if (!icons || icons.length === 0) {
throw new Error('No se pudieron cargar íconos del metadata procesado');
}
} else {
// Modo fallback: cargar metadata original
console.log('📥 Cargando metadata original (modo fallback)...');
const metadataPath = path.join(__dirname, 'assets', 'fontawesome', 'metadata', 'icons.json');
if (!fs.existsSync(metadataPath)) {
throw new Error('No se encontró metadata original. ¿Copiaste los archivos de FontAwesome?');
}
const content = fs.readFileSync(metadataPath, 'utf8');
const rawMetadata = JSON.parse(content);
// Procesar íconos básicamente
icons = Object.values(rawMetadata).map(icon => ({
id: icon.name || Object.keys(rawMetadata).find(key => rawMetadata[key] === icon),
name: icon.name || '',
label: icon.label || '',
categories: icon.categories || ['uncategorized'],
styles: icon.styles || [],
searchTerms: [],
unicode: icon.unicode || '',
version: icon.version || '6.0.0'
}));
categories = getDefaultCategories(icons.length);
}
// 5. Crear base de datos
console.log('\n📊 Creando estructura de datos...');
const database = createDatabase(icons, categories, stylesInfo);
// 6. Guardar
saveDatabase(database);
console.log('\n' + '='.repeat(60));
console.log('✅ ¡GENERACIÓN COMPLETADA EXITOSAMENTE!');
console.log('='.repeat(60));
console.log(`📊 Total íconos: ${database.icons.length}`);
console.log(`📁 Categorías: ${database.categories.length}`);
console.log(`🎨 Estilos: ${database.meta.detectedStyles}`);
console.log(`📍 Archivos generados:`);
console.log(`${CONFIG.OUTPUT_ICONS}`);
console.log(`${CONFIG.OUTPUT_DYNAMIC_CSS}`);
console.log(`${CONFIG.OUTPUT_CUSTOM_CSS}`);
console.log('='.repeat(60));
// Mostrar resumen de estilos
console.log('\n🎨 ESTILOS DISPONIBLES:');
database.styles.forEach(style => {
if (style.available) {
console.log(`${style.name.padEnd(15)}: ${style.count || 0} íconos`);
}
});
return database;
} catch (error) {
console.error('\n❌ ERROR CRÍTICO:', error.message);
console.log('\n🔄 Generando base de datos de ejemplo...');
return generateSampleDatabase();
}
}
// ================= EJECUCIÓN =================
const args = process.argv.slice(2);
const isSampleMode = args.includes('--sample');
if (require.main === module) {
if (isSampleMode) {
generateSampleDatabase();
} else {
generateIconDatabase();
}
}
// Exportar
module.exports = {
generateIconDatabase,
generateSampleDatabase,
CONFIG,
ALL_STYLES
};