Primera versión del plugin
This commit is contained in:
331
scripts/validate-styles.js
Normal file
331
scripts/validate-styles.js
Normal file
@@ -0,0 +1,331 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
// Configuración
|
||||
const CONFIG = {
|
||||
WEBFONTS_DIR: path.join(__dirname, '..', 'assets', 'fontawesome', 'webfonts'),
|
||||
PROCESSED_DIR: path.join(__dirname, '..', 'assets', 'processed'),
|
||||
OUTPUT_REPORT: path.join(__dirname, '..', 'assets', 'processed', 'validation-report.json'),
|
||||
VERSION: '2.0.0'
|
||||
};
|
||||
|
||||
console.log('🔍 Validando estilos FontAwesome Pro...\n');
|
||||
|
||||
/**
|
||||
* Validar archivos de fuentes
|
||||
*/
|
||||
function validateFontFiles() {
|
||||
console.log('🎨 Validando archivos de fuentes...');
|
||||
|
||||
const expectedFiles = [
|
||||
'fa-solid-900.woff2',
|
||||
'fa-regular-400.woff2',
|
||||
'fa-light-300.woff2',
|
||||
'fa-thin-100.woff2',
|
||||
'fa-duotone-900.woff2',
|
||||
'fa-sharp-solid-900.woff2',
|
||||
'fa-sharp-regular-400.woff2',
|
||||
'fa-sharp-light-300.woff2',
|
||||
'fa-sharp-thin-100.woff2',
|
||||
'fa-sharp-duotone-900.woff2',
|
||||
'fa-brands-400.woff2'
|
||||
];
|
||||
|
||||
const results = {
|
||||
total: expectedFiles.length,
|
||||
found: 0,
|
||||
missing: [],
|
||||
details: {}
|
||||
};
|
||||
|
||||
expectedFiles.forEach(file => {
|
||||
const filePath = path.join(CONFIG.WEBFONTS_DIR, file);
|
||||
const exists = fs.existsSync(filePath);
|
||||
|
||||
results.details[file] = {
|
||||
exists: exists,
|
||||
path: filePath,
|
||||
size: exists ? fs.statSync(filePath).size : 0
|
||||
};
|
||||
|
||||
if (exists) {
|
||||
results.found++;
|
||||
console.log(` ✅ ${file}`);
|
||||
} else {
|
||||
results.missing.push(file);
|
||||
console.log(` ❌ ${file} (FALTANTE)`);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`\n📊 Resumen: ${results.found}/${results.total} archivos encontrados`);
|
||||
|
||||
if (results.missing.length > 0) {
|
||||
console.log('\n⚠️ Archivos faltantes:');
|
||||
results.missing.forEach(file => {
|
||||
console.log(` • ${file}`);
|
||||
});
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validar metadata procesado
|
||||
*/
|
||||
function validateProcessedMetadata() {
|
||||
console.log('\n📊 Validando metadata procesado...');
|
||||
|
||||
const metadataPath = path.join(CONFIG.PROCESSED_DIR, 'metadata.json');
|
||||
const stylesPath = path.join(CONFIG.PROCESSED_DIR, 'styles.json');
|
||||
const categoriesPath = path.join(CONFIG.PROCESSED_DIR, 'categories.json');
|
||||
|
||||
const results = {
|
||||
metadata: { valid: false, error: null, data: null },
|
||||
styles: { valid: false, error: null, data: null },
|
||||
categories: { valid: false, error: null, data: null }
|
||||
};
|
||||
|
||||
// Validar metadata.json
|
||||
try {
|
||||
if (fs.existsSync(metadataPath)) {
|
||||
const content = fs.readFileSync(metadataPath, 'utf8');
|
||||
const data = JSON.parse(content);
|
||||
|
||||
if (data.meta && data.icons && data.statistics) {
|
||||
results.metadata = {
|
||||
valid: true,
|
||||
data: {
|
||||
totalIcons: data.meta.totalIcons || 0,
|
||||
totalStyles: data.statistics.styles?.length || 0,
|
||||
totalCategories: data.statistics.categories?.length || 0
|
||||
}
|
||||
};
|
||||
console.log(` ✅ metadata.json: ${results.metadata.data.totalIcons} íconos`);
|
||||
} else {
|
||||
results.metadata.error = 'Estructura inválida';
|
||||
console.log(` ❌ metadata.json: Estructura inválida`);
|
||||
}
|
||||
} else {
|
||||
results.metadata.error = 'Archivo no encontrado';
|
||||
console.log(` ❌ metadata.json: No encontrado`);
|
||||
}
|
||||
} catch (error) {
|
||||
results.metadata.error = error.message;
|
||||
console.log(` ❌ metadata.json: Error - ${error.message}`);
|
||||
}
|
||||
|
||||
// Validar styles.json
|
||||
try {
|
||||
if (fs.existsSync(stylesPath)) {
|
||||
const content = fs.readFileSync(stylesPath, 'utf8');
|
||||
const data = JSON.parse(content);
|
||||
|
||||
if (data.meta && data.styles) {
|
||||
const stylesWithIcons = Object.values(data.styles).filter(s => s.count > 0).length;
|
||||
results.styles = {
|
||||
valid: true,
|
||||
data: {
|
||||
totalStyles: data.meta.totalStyles || 0,
|
||||
stylesWithIcons: stylesWithIcons
|
||||
}
|
||||
};
|
||||
console.log(` ✅ styles.json: ${stylesWithIcons}/${data.meta.totalStyles} estilos con íconos`);
|
||||
} else {
|
||||
results.styles.error = 'Estructura inválida';
|
||||
console.log(` ❌ styles.json: Estructura inválida`);
|
||||
}
|
||||
} else {
|
||||
results.styles.error = 'Archivo no encontrado';
|
||||
console.log(` ❌ styles.json: No encontrado`);
|
||||
}
|
||||
} catch (error) {
|
||||
results.styles.error = error.message;
|
||||
console.log(` ❌ styles.json: Error - ${error.message}`);
|
||||
}
|
||||
|
||||
// Validar categories.json
|
||||
try {
|
||||
if (fs.existsSync(categoriesPath)) {
|
||||
const content = fs.readFileSync(categoriesPath, 'utf8');
|
||||
const data = JSON.parse(content);
|
||||
|
||||
if (data.meta && data.categories) {
|
||||
const fontawesomeCategories = data.categories.filter(c => c.type === 'fontawesome').length;
|
||||
results.categories = {
|
||||
valid: true,
|
||||
data: {
|
||||
totalCategories: data.meta.totalCategories || 0,
|
||||
fontawesomeCategories: fontawesomeCategories
|
||||
}
|
||||
};
|
||||
console.log(` ✅ categories.json: ${data.meta.totalCategories} categorías totales`);
|
||||
} else {
|
||||
results.categories.error = 'Estructura inválida';
|
||||
console.log(` ❌ categories.json: Estructura inválida`);
|
||||
}
|
||||
} else {
|
||||
results.categories.error = 'Archivo no encontrado';
|
||||
console.log(` ❌ categories.json: No encontrado`);
|
||||
}
|
||||
} catch (error) {
|
||||
results.categories.error = error.message;
|
||||
console.log(` ❌ categories.json: Error - ${error.message}`);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validar compatibilidad
|
||||
*/
|
||||
function validateCompatibility(fontResults, metadataResults) {
|
||||
console.log('\n🔗 Validando compatibilidad...');
|
||||
|
||||
const issues = [];
|
||||
|
||||
// Verificar si hay estilos en metadata pero no en archivos
|
||||
if (metadataResults.styles.valid && metadataResults.styles.data) {
|
||||
const stylesWithIcons = metadataResults.styles.data.stylesWithIcons;
|
||||
|
||||
if (stylesWithIcons > fontResults.found) {
|
||||
issues.push({
|
||||
type: 'warning',
|
||||
message: `Hay ${stylesWithIcons} estilos en metadata pero solo ${fontResults.found} archivos de fuentes`
|
||||
});
|
||||
console.log(` ⚠️ Posible falta de archivos de fuentes`);
|
||||
}
|
||||
}
|
||||
|
||||
// Verificar si hay muchos archivos faltantes
|
||||
if (fontResults.missing.length > 5) {
|
||||
issues.push({
|
||||
type: 'error',
|
||||
message: `Faltan ${fontResults.missing.length} archivos de fuentes esenciales`
|
||||
});
|
||||
console.log(` ❌ Faltan muchos archivos de fuentes`);
|
||||
}
|
||||
|
||||
return issues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generar reporte de validación
|
||||
*/
|
||||
function generateValidationReport(fontResults, metadataResults, compatibilityIssues) {
|
||||
const report = {
|
||||
meta: {
|
||||
generated: new Date().toISOString(),
|
||||
version: CONFIG.VERSION
|
||||
},
|
||||
fontFiles: fontResults,
|
||||
metadata: metadataResults,
|
||||
compatibility: {
|
||||
issues: compatibilityIssues,
|
||||
status: compatibilityIssues.length === 0 ? 'OK' : 'ISSUES'
|
||||
},
|
||||
recommendations: []
|
||||
};
|
||||
|
||||
// Generar recomendaciones
|
||||
if (fontResults.missing.length > 0) {
|
||||
report.recommendations.push({
|
||||
priority: 'high',
|
||||
action: 'download_missing_fonts',
|
||||
message: 'Descarga los archivos de fuentes faltantes de FontAwesome Pro'
|
||||
});
|
||||
}
|
||||
|
||||
if (!metadataResults.metadata.valid) {
|
||||
report.recommendations.push({
|
||||
priority: 'high',
|
||||
action: 'run_extract_metadata',
|
||||
message: 'Ejecuta scripts/extract-metadata.js primero'
|
||||
});
|
||||
}
|
||||
|
||||
if (compatibilityIssues.length > 0) {
|
||||
report.recommendations.push({
|
||||
priority: 'medium',
|
||||
action: 'verify_fontawesome_version',
|
||||
message: 'Verifica que tengas la versión correcta de FontAwesome Pro'
|
||||
});
|
||||
}
|
||||
|
||||
// Guardar reporte
|
||||
fs.writeFileSync(CONFIG.OUTPUT_REPORT, JSON.stringify(report, null, 2), 'utf8');
|
||||
console.log(`\n📋 Reporte de validación guardado: ${CONFIG.OUTPUT_REPORT}`);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Función principal
|
||||
*/
|
||||
function main() {
|
||||
try {
|
||||
console.log('='.repeat(60));
|
||||
console.log(' VALIDACIÓN DE ESTILOS FONTAWESOME PRO');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
// 1. Validar archivos de fuentes
|
||||
const fontResults = validateFontFiles();
|
||||
|
||||
// 2. Validar metadata procesado
|
||||
const metadataResults = validateProcessedMetadata();
|
||||
|
||||
// 3. Validar compatibilidad
|
||||
const compatibilityIssues = validateCompatibility(fontResults, metadataResults);
|
||||
|
||||
// 4. Generar reporte
|
||||
const report = generateValidationReport(fontResults, metadataResults, compatibilityIssues);
|
||||
|
||||
// 5. Mostrar resumen
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log(' RESUMEN DE VALIDACIÓN');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
console.log(`\n🎨 Archivos de fuentes: ${fontResults.found}/${fontResults.total}`);
|
||||
console.log(`📊 Metadata procesado: ${metadataResults.metadata.valid ? '✅ Válido' : '❌ Inválido'}`);
|
||||
console.log(`🔗 Compatibilidad: ${compatibilityIssues.length === 0 ? '✅ OK' : '⚠️ Issues'}`);
|
||||
|
||||
if (report.recommendations.length > 0) {
|
||||
console.log('\n🚀 RECOMENDACIONES:');
|
||||
report.recommendations.forEach((rec, index) => {
|
||||
console.log(` ${index + 1}. [${rec.priority.toUpperCase()}] ${rec.message}`);
|
||||
});
|
||||
}
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
|
||||
// Retornar código de salida apropiado
|
||||
if (fontResults.found === 0 || !metadataResults.metadata.valid) {
|
||||
console.log('\n❌ Validación fallida. Revisa las recomendaciones.');
|
||||
process.exit(1);
|
||||
} else if (compatibilityIssues.length > 0) {
|
||||
console.log('\n⚠️ Validación con advertencias. El plugin puede funcionar con limitaciones.');
|
||||
process.exit(0);
|
||||
} else {
|
||||
console.log('\n✅ Validación exitosa. Listo para construir la base de datos.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error(`\n❌ Error durante la validación: ${error.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Ejecutar
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
validateFontFiles,
|
||||
validateProcessedMetadata,
|
||||
validateCompatibility,
|
||||
generateValidationReport
|
||||
};
|
||||
Reference in New Issue
Block a user