420 lines
14 KiB
JavaScript
420 lines
14 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const { execSync } = require('child_process');
|
||
|
||
// Configuración
|
||
const CONFIG = {
|
||
pluginDir: __dirname,
|
||
assetsDir: path.join(__dirname, 'assets'),
|
||
fontawesomeDir: path.join(__dirname, 'assets', 'fontawesome'),
|
||
webfontsDir: path.join(__dirname, 'assets', 'fontawesome', 'webfonts'),
|
||
metadataDir: path.join(__dirname, 'assets', 'fontawesome', 'metadata'),
|
||
|
||
// URLs de referencia (no para descargar directamente por licencia)
|
||
fontawesomeUrl: 'https://fontawesome.com/download',
|
||
proDownloadUrl: 'https://fontawesome.com/account/download'
|
||
};
|
||
|
||
// Colores para la consola
|
||
const colors = {
|
||
reset: '\x1b[0m',
|
||
bright: '\x1b[1m',
|
||
green: '\x1b[32m',
|
||
yellow: '\x1b[33m',
|
||
blue: '\x1b[34m',
|
||
magenta: '\x1b[35m',
|
||
cyan: '\x1b[36m',
|
||
red: '\x1b[31m'
|
||
};
|
||
|
||
// Función para imprimir con estilo
|
||
function log(message, color = 'reset', type = 'info') {
|
||
const prefix = type === 'success' ? '✅' :
|
||
type === 'warning' ? '⚠️' :
|
||
type === 'error' ? '❌' :
|
||
type === 'info' ? 'ℹ️' : '📝';
|
||
|
||
console.log(`${colors[color] || colors.reset}${prefix} ${message}${colors.reset}`);
|
||
}
|
||
|
||
// Banner
|
||
console.log(colors.cyan + '='.repeat(70));
|
||
console.log(' ACTUALIZADOR DE ESTILOS FONTAWESOME PRO PARA LOGSEQ');
|
||
console.log('='.repeat(70) + colors.reset + '\n');
|
||
|
||
/**
|
||
* Verificar estructura de directorios
|
||
*/
|
||
function checkDirectoryStructure() {
|
||
log('Verificando estructura de directorios...', 'blue');
|
||
|
||
const requiredDirs = [
|
||
CONFIG.assetsDir,
|
||
CONFIG.fontawesomeDir,
|
||
CONFIG.webfontsDir,
|
||
CONFIG.metadataDir
|
||
];
|
||
|
||
let allExist = true;
|
||
|
||
requiredDirs.forEach(dir => {
|
||
if (fs.existsSync(dir)) {
|
||
log(` ${path.basename(dir)}: Existe`, 'green');
|
||
} else {
|
||
log(` ${path.basename(dir)}: No existe - Creando...`, 'yellow');
|
||
try {
|
||
fs.mkdirSync(dir, { recursive: true });
|
||
log(` ${path.basename(dir)}: Creado`, 'green');
|
||
} catch (error) {
|
||
log(` Error creando ${dir}: ${error.message}`, 'red', 'error');
|
||
allExist = false;
|
||
}
|
||
}
|
||
});
|
||
|
||
return allExist;
|
||
}
|
||
|
||
/**
|
||
* Verificar archivos actuales
|
||
*/
|
||
function checkCurrentFiles() {
|
||
log('Analizando archivos actuales...', 'blue');
|
||
|
||
const files = {
|
||
webfonts: [],
|
||
metadata: [],
|
||
css: []
|
||
};
|
||
|
||
// Verificar webfonts
|
||
if (fs.existsSync(CONFIG.webfontsDir)) {
|
||
files.webfonts = fs.readdirSync(CONFIG.webfontsDir)
|
||
.filter(file => /\.(woff2|woff|ttf|eot)$/i.test(file));
|
||
}
|
||
|
||
// Verificar metadata
|
||
if (fs.existsSync(CONFIG.metadataDir)) {
|
||
files.metadata = fs.readdirSync(CONFIG.metadataDir)
|
||
.filter(file => /\.json$/i.test(file));
|
||
}
|
||
|
||
// Verificar CSS
|
||
const cssDir = path.join(CONFIG.fontawesomeDir, 'css');
|
||
if (fs.existsSync(cssDir)) {
|
||
files.css = fs.readdirSync(cssDir)
|
||
.filter(file => /\.css$/i.test(file));
|
||
}
|
||
|
||
// Mostrar resumen
|
||
log(` Webfonts: ${files.webfonts.length} archivos encontrados`,
|
||
files.webfonts.length > 0 ? 'green' : 'yellow');
|
||
log(` Metadata: ${files.metadata.length} archivos encontrados`,
|
||
files.metadata.length > 0 ? 'green' : 'yellow');
|
||
log(` CSS: ${files.css.length} archivos encontrados`,
|
||
files.css.length > 0 ? 'green' : 'yellow');
|
||
|
||
return files;
|
||
}
|
||
|
||
/**
|
||
* Mostrar instrucciones de actualización
|
||
*/
|
||
function showUpdateInstructions(currentFiles) {
|
||
console.log('\n' + colors.yellow + '='.repeat(70));
|
||
console.log(' INSTRUCCIONES PARA ACTUALIZAR ESTILOS');
|
||
console.log('='.repeat(70) + colors.reset + '\n');
|
||
|
||
log('PASO 1: Descargar FontAwesome 6 Pro actualizado', 'magenta');
|
||
console.log(' • Visita: ' + colors.cyan + CONFIG.proDownloadUrl + colors.reset);
|
||
console.log(' • Inicia sesión con tu cuenta Pro');
|
||
console.log(' • Descarga la versión más reciente\n');
|
||
|
||
log('PASO 2: Extraer archivos necesarios', 'magenta');
|
||
console.log('Del ZIP descargado, copia estos archivos:\n');
|
||
|
||
console.log(colors.bright + ' 📁 css/' + colors.reset);
|
||
console.log(' ├── all.min.css');
|
||
console.log(' └── fontawesome.min.css\n');
|
||
|
||
console.log(colors.bright + ' 📁 webfonts/' + colors.reset);
|
||
console.log(' ├── fa-solid-900.woff2');
|
||
console.log(' ├── fa-regular-400.woff2');
|
||
console.log(' ├── fa-light-300.woff2');
|
||
console.log(' ├── fa-thin-100.woff2');
|
||
console.log(' ├── fa-duotone-900.woff2');
|
||
console.log(' ├── fa-sharp-solid-900.woff2');
|
||
console.log(' ├── fa-sharp-regular-400.woff2');
|
||
console.log(' ├── fa-sharp-light-300.woff2');
|
||
console.log(' ├── fa-sharp-thin-100.woff2');
|
||
console.log(' ├── fa-sharp-duotone-900.woff2');
|
||
console.log(' └── fa-brands-400.woff2\n');
|
||
|
||
console.log(colors.bright + ' 📁 metadata/' + colors.reset);
|
||
console.log(' └── icons.json\n');
|
||
|
||
log('PASO 3: Reemplazar archivos', 'magenta');
|
||
console.log(` • Copia los archivos a: ${colors.cyan}${CONFIG.fontawesomeDir}${colors.reset}`);
|
||
|
||
log('PASO 4: Regenerar base de datos', 'magenta');
|
||
console.log(' • Ejecuta: ' + colors.green + 'npm run build' + colors.reset);
|
||
|
||
console.log('\n' + colors.yellow + '='.repeat(70));
|
||
}
|
||
|
||
/**
|
||
* Detectar nuevos estilos disponibles
|
||
*/
|
||
function detectNewStyles() {
|
||
log('Buscando nuevos estilos...', 'blue');
|
||
|
||
// Leer estilos actuales de la base de datos
|
||
const dbPath = path.join(CONFIG.assetsDir, 'icons.json');
|
||
let currentStyles = [];
|
||
|
||
if (fs.existsSync(dbPath)) {
|
||
try {
|
||
const db = JSON.parse(fs.readFileSync(dbPath, 'utf8'));
|
||
currentStyles = db.meta?.stylesAvailable || [];
|
||
log(` Estilos actuales en DB: ${currentStyles.length}`, 'green');
|
||
} catch (error) {
|
||
log(` Error leyendo DB: ${error.message}`, 'yellow', 'warning');
|
||
}
|
||
}
|
||
|
||
// Detectar estilos en webfonts
|
||
let detectedStyles = [];
|
||
if (fs.existsSync(CONFIG.webfontsDir)) {
|
||
const fontFiles = fs.readdirSync(CONFIG.webfontsDir);
|
||
|
||
// Mapear archivos a estilos
|
||
const styleMap = {
|
||
'fa-solid': 'solid',
|
||
'fa-regular': 'regular',
|
||
'fa-light': 'light',
|
||
'fa-thin': 'thin',
|
||
'fa-duotone': 'duotone',
|
||
'fa-sharp-solid': 'sharp-solid',
|
||
'fa-sharp-regular': 'sharp-regular',
|
||
'fa-sharp-light': 'sharp-light',
|
||
'fa-sharp-thin': 'sharp-thin',
|
||
'fa-sharp-duotone': 'sharp-duotone',
|
||
'fa-brands': 'brands'
|
||
};
|
||
|
||
fontFiles.forEach(file => {
|
||
Object.keys(styleMap).forEach(key => {
|
||
if (file.includes(key)) {
|
||
const style = styleMap[key];
|
||
if (!detectedStyles.includes(style)) {
|
||
detectedStyles.push(style);
|
||
}
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
log(` Estilos detectados en archivos: ${detectedStyles.length}`, 'green');
|
||
|
||
// Encontrar nuevos estilos
|
||
const newStyles = detectedStyles.filter(style => !currentStyles.includes(style));
|
||
|
||
if (newStyles.length > 0) {
|
||
log(` ¡Nuevos estilos encontrados: ${newStyles.length}!`, 'magenta', 'success');
|
||
newStyles.forEach(style => {
|
||
log(` • ${style}`, 'green');
|
||
});
|
||
} else {
|
||
log(' No se encontraron nuevos estilos', 'yellow');
|
||
}
|
||
|
||
return { currentStyles, detectedStyles, newStyles };
|
||
}
|
||
|
||
/**
|
||
* Verificar versiones
|
||
*/
|
||
function checkVersions() {
|
||
log('Verificando versiones...', 'blue');
|
||
|
||
// Verificar metadata version
|
||
const metadataPath = path.join(CONFIG.metadataDir, 'icons.json');
|
||
let metadataVersion = 'Desconocida';
|
||
|
||
if (fs.existsSync(metadataPath)) {
|
||
try {
|
||
const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
|
||
const firstIcon = Object.values(metadata)[0];
|
||
metadataVersion = firstIcon?.version || 'Desconocida';
|
||
} catch (error) {
|
||
// Ignorar error
|
||
}
|
||
}
|
||
|
||
log(` Versión en metadata: ${metadataVersion}`, 'green');
|
||
|
||
// Verificar versión del plugin
|
||
const packagePath = path.join(CONFIG.pluginDir, 'package.json');
|
||
let pluginVersion = 'Desconocida';
|
||
|
||
if (fs.existsSync(packagePath)) {
|
||
try {
|
||
const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
||
pluginVersion = pkg.version || 'Desconocida';
|
||
} catch (error) {
|
||
// Ignorar error
|
||
}
|
||
}
|
||
|
||
log(` Versión del plugin: ${pluginVersion}`, 'green');
|
||
|
||
return { metadataVersion, pluginVersion };
|
||
}
|
||
|
||
/**
|
||
* Realizar respaldo de archivos actuales
|
||
*/
|
||
function backupCurrentFiles() {
|
||
log('Creando respaldo de archivos actuales...', 'blue');
|
||
|
||
const backupDir = path.join(CONFIG.pluginDir, 'backup', new Date().toISOString().split('T')[0]);
|
||
|
||
try {
|
||
if (!fs.existsSync(backupDir)) {
|
||
fs.mkdirSync(backupDir, { recursive: true });
|
||
}
|
||
|
||
// Archivos a respaldar
|
||
const filesToBackup = [
|
||
path.join(CONFIG.assetsDir, 'icons.json'),
|
||
path.join(CONFIG.assetsDir, 'dynamic-styles.css'),
|
||
path.join(CONFIG.assetsDir, 'custom-styles.css')
|
||
];
|
||
|
||
let backedUpCount = 0;
|
||
|
||
filesToBackup.forEach(file => {
|
||
if (fs.existsSync(file)) {
|
||
const fileName = path.basename(file);
|
||
const backupPath = path.join(backupDir, fileName);
|
||
|
||
fs.copyFileSync(file, backupPath);
|
||
backedUpCount++;
|
||
log(` Respaldo creado: ${fileName}`, 'green');
|
||
}
|
||
});
|
||
|
||
if (backedUpCount > 0) {
|
||
log(`✅ Respaldo completado (${backedUpCount} archivos)`, 'green', 'success');
|
||
log(` Ubicación: ${backupDir}`, 'cyan');
|
||
} else {
|
||
log('⚠️ No se encontraron archivos para respaldar', 'yellow', 'warning');
|
||
}
|
||
|
||
return backupDir;
|
||
|
||
} catch (error) {
|
||
log(`❌ Error creando respaldo: ${error.message}`, 'red', 'error');
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Regenerar base de datos
|
||
*/
|
||
function regenerateDatabase() {
|
||
log('Regenerando base de datos...', 'blue');
|
||
|
||
try {
|
||
// Ejecutar el script de construcción
|
||
log(' Ejecutando: npm run build', 'cyan');
|
||
|
||
const result = execSync('npm run build', {
|
||
cwd: CONFIG.pluginDir,
|
||
stdio: 'pipe',
|
||
encoding: 'utf8'
|
||
});
|
||
|
||
console.log(result);
|
||
log('✅ Base de datos regenerada exitosamente', 'green', 'success');
|
||
|
||
return true;
|
||
|
||
} catch (error) {
|
||
log(`❌ Error regenerando base de datos: ${error.message}`, 'red', 'error');
|
||
if (error.stdout) console.log(error.stdout);
|
||
if (error.stderr) console.log(error.stderr);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Función principal
|
||
*/
|
||
async function main() {
|
||
try {
|
||
// 1. Verificar estructura
|
||
if (!checkDirectoryStructure()) {
|
||
log('Error en la estructura de directorios', 'red', 'error');
|
||
return;
|
||
}
|
||
|
||
// 2. Verificar archivos actuales
|
||
const currentFiles = checkCurrentFiles();
|
||
|
||
// 3. Verificar versiones
|
||
const versions = checkVersions();
|
||
|
||
// 4. Detectar nuevos estilos
|
||
const styles = detectNewStyles();
|
||
|
||
// 5. Mostrar resumen
|
||
console.log('\n' + colors.cyan + '='.repeat(70));
|
||
console.log(' RESUMEN DEL ANÁLISIS');
|
||
console.log('='.repeat(70) + colors.reset);
|
||
|
||
console.log(`\n${colors.bright}📊 Estadísticas:${colors.reset}`);
|
||
console.log(` • Webfonts: ${currentFiles.webfonts.length} archivos`);
|
||
console.log(` • Estilos detectados: ${styles.detectedStyles.length}`);
|
||
console.log(` • Estilos en DB: ${styles.currentStyles.length}`);
|
||
console.log(` • Nuevos estilos: ${styles.newStyles.length}`);
|
||
console.log(` • Versión metadata: ${versions.metadataVersion}`);
|
||
console.log(` • Versión plugin: ${versions.pluginVersion}`);
|
||
|
||
if (styles.newStyles.length > 0) {
|
||
console.log(`\n${colors.bright}🎉 ¡Nuevos estilos disponibles!${colors.reset}`);
|
||
console.log(` Ejecuta 'npm run build' para actualizar la base de datos.`);
|
||
}
|
||
|
||
// 6. Preguntar al usuario
|
||
console.log(`\n${colors.bright}¿Qué deseas hacer?${colors.reset}`);
|
||
console.log(' 1. Mostrar instrucciones de actualización');
|
||
console.log(' 2. Crear respaldo y regenerar base de datos');
|
||
console.log(' 3. Solo regenerar base de datos');
|
||
console.log(' 4. Salir');
|
||
|
||
// En un entorno real, aquí usarías readline para interactuar
|
||
// Por ahora, mostramos las instrucciones automáticamente
|
||
|
||
console.log('\n' + colors.yellow + 'Mostrando instrucciones...' + colors.reset);
|
||
showUpdateInstructions(currentFiles);
|
||
|
||
// 7. Opción para regenerar
|
||
console.log(`\n${colors.bright}Para regenerar la base de datos con los nuevos estilos:${colors.reset}`);
|
||
console.log(` Ejecuta: ${colors.green}npm run build${colors.reset}`);
|
||
|
||
console.log('\n' + colors.cyan + '='.repeat(70));
|
||
console.log(' ACTUALIZACIÓN COMPLETADA');
|
||
console.log('='.repeat(70) + colors.reset);
|
||
|
||
} catch (error) {
|
||
log(`Error en el proceso de actualización: ${error.message}`, 'red', 'error');
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
// Ejecutar
|
||
main();
|