versacompiler 2.3.4 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -17
- package/dist/compiler/compile.js +221 -205
- package/dist/compiler/integrity-validator.js +525 -0
- package/dist/compiler/minify.js +18 -1
- package/dist/compiler/minifyTemplate.js +16 -0
- package/dist/compiler/transforms.js +17 -0
- package/dist/compiler/typescript-error-parser.js +0 -133
- package/dist/compiler/typescript-sync-validator.js +12 -7
- package/dist/compiler/typescript-worker-pool.js +96 -24
- package/dist/compiler/typescript-worker-thread.cjs +9 -6
- package/dist/compiler/vuejs.js +12 -6
- package/dist/hrm/initHRM.js +2 -2
- package/dist/main.js +18 -6
- package/dist/servicios/file-watcher.js +3 -1
- package/dist/servicios/readConfig.js +17 -4
- package/package.json +32 -32
package/dist/compiler/compile.js
CHANGED
|
@@ -8,6 +8,7 @@ const { argv, cwd, env } = process;
|
|
|
8
8
|
import { logger, setProgressManagerGetter } from '../servicios/logger.js';
|
|
9
9
|
import { promptUser } from '../utils/promptUser.js';
|
|
10
10
|
import { showTimingForHumans } from '../utils/utils.js';
|
|
11
|
+
import { integrityValidator } from './integrity-validator.js';
|
|
11
12
|
// Configurar el getter del ProgressManager para el logger
|
|
12
13
|
setProgressManagerGetter(() => ProgressManager.getInstance());
|
|
13
14
|
/**
|
|
@@ -385,63 +386,31 @@ class OptimizedModuleManager {
|
|
|
385
386
|
this.startBackgroundPreloading();
|
|
386
387
|
}
|
|
387
388
|
}
|
|
388
|
-
// Lazy loading helper functions
|
|
389
|
+
// Lazy loading helper functions - delegan al OptimizedModuleManager para evitar duplicación
|
|
390
|
+
const moduleManagerRef = () => OptimizedModuleManager.getInstance();
|
|
389
391
|
async function loadChalk() {
|
|
390
|
-
|
|
391
|
-
chalk = (await import('chalk')).default;
|
|
392
|
-
}
|
|
393
|
-
return chalk;
|
|
392
|
+
return moduleManagerRef().ensureModuleLoaded('chalk');
|
|
394
393
|
}
|
|
395
394
|
async function loadLinter() {
|
|
396
|
-
|
|
397
|
-
const linterModule = await import('./linter.js');
|
|
398
|
-
ESLint = linterModule.ESLint;
|
|
399
|
-
OxLint = linterModule.OxLint;
|
|
400
|
-
}
|
|
401
|
-
return { ESLint, OxLint };
|
|
395
|
+
return moduleManagerRef().ensureModuleLoaded('linter');
|
|
402
396
|
}
|
|
403
397
|
async function loadMinify() {
|
|
404
|
-
|
|
405
|
-
const minifyModule = await import('./minify.js');
|
|
406
|
-
// ✨ Usar minifyWithTemplates para minificar templates HTML ANTES del JS
|
|
407
|
-
minifyJS = minifyModule.minifyWithTemplates;
|
|
408
|
-
}
|
|
409
|
-
return minifyJS;
|
|
398
|
+
return moduleManagerRef().ensureModuleLoaded('minify');
|
|
410
399
|
}
|
|
411
400
|
async function loadParser() {
|
|
412
|
-
|
|
413
|
-
const parserModule = await import('./parser.js');
|
|
414
|
-
getCodeFile = parserModule.getCodeFile;
|
|
415
|
-
}
|
|
416
|
-
return getCodeFile;
|
|
401
|
+
return moduleManagerRef().ensureModuleLoaded('parser');
|
|
417
402
|
}
|
|
418
403
|
async function loadTailwind() {
|
|
419
|
-
|
|
420
|
-
const tailwindModule = await import('./tailwindcss.js');
|
|
421
|
-
generateTailwindCSS = tailwindModule.generateTailwindCSS;
|
|
422
|
-
}
|
|
423
|
-
return generateTailwindCSS;
|
|
404
|
+
return moduleManagerRef().ensureModuleLoaded('tailwind');
|
|
424
405
|
}
|
|
425
406
|
async function loadTransforms() {
|
|
426
|
-
|
|
427
|
-
const transformsModule = await import('./transforms.js');
|
|
428
|
-
estandarizaCode = transformsModule.estandarizaCode;
|
|
429
|
-
}
|
|
430
|
-
return estandarizaCode;
|
|
407
|
+
return moduleManagerRef().ensureModuleLoaded('transforms');
|
|
431
408
|
}
|
|
432
409
|
async function loadTypeScript() {
|
|
433
|
-
|
|
434
|
-
const typescriptModule = await import('./typescript-manager.js');
|
|
435
|
-
preCompileTS = typescriptModule.preCompileTS;
|
|
436
|
-
}
|
|
437
|
-
return preCompileTS;
|
|
410
|
+
return moduleManagerRef().ensureModuleLoaded('typescript');
|
|
438
411
|
}
|
|
439
412
|
async function loadVue() {
|
|
440
|
-
|
|
441
|
-
const vueModule = await import('./vuejs.js');
|
|
442
|
-
preCompileVue = vueModule.preCompileVue;
|
|
443
|
-
}
|
|
444
|
-
return preCompileVue;
|
|
413
|
+
return moduleManagerRef().ensureModuleLoaded('vue');
|
|
445
414
|
}
|
|
446
415
|
// Almacenamiento global de errores y resultados
|
|
447
416
|
const compilationErrors = [];
|
|
@@ -464,6 +433,10 @@ class SmartCompilationCache {
|
|
|
464
433
|
maxEntries = 200; // Reducido para tests de estrés
|
|
465
434
|
maxMemory = 50 * 1024 * 1024; // 50MB límite (reducido)
|
|
466
435
|
currentMemoryUsage = 0;
|
|
436
|
+
// Cache para dependencyHash con TTL de 5 minutos para evitar stat() redundantes
|
|
437
|
+
_cachedDepHash = null;
|
|
438
|
+
_depHashExpiry = 0;
|
|
439
|
+
DEP_HASH_TTL = 5 * 60 * 1000; // 5 minutos
|
|
467
440
|
// ✨ ISSUE #3: Sistema de vigilancia de dependencias
|
|
468
441
|
fileWatchers = new Map(); // chokidar watchers
|
|
469
442
|
dependencyGraph = new Map(); // archivo -> dependencias
|
|
@@ -471,6 +444,7 @@ class SmartCompilationCache {
|
|
|
471
444
|
packageJsonPath = path.join(cwd(), 'package.json');
|
|
472
445
|
nodeModulesPath = path.join(cwd(), 'node_modules');
|
|
473
446
|
isWatchingDependencies = false;
|
|
447
|
+
_depWatcherFailed = false; // Flag para indicar que el watcher de deps falló
|
|
474
448
|
/**
|
|
475
449
|
* Genera hash SHA-256 del contenido del archivo
|
|
476
450
|
*/ async generateContentHash(filePath) {
|
|
@@ -528,6 +502,11 @@ class SmartCompilationCache {
|
|
|
528
502
|
* Incluye vigilancia de package.json, node_modules y versiones instaladas
|
|
529
503
|
*/
|
|
530
504
|
async generateDependencyHash() {
|
|
505
|
+
// Retornar hash cacheado si sigue vigente (evita 10+ stat() por ciclo)
|
|
506
|
+
const now = Date.now();
|
|
507
|
+
if (this._cachedDepHash && now < this._depHashExpiry) {
|
|
508
|
+
return this._cachedDepHash;
|
|
509
|
+
}
|
|
531
510
|
try {
|
|
532
511
|
const hash = createHash('sha256');
|
|
533
512
|
// 1. Hash del package.json con versiones
|
|
@@ -588,16 +567,29 @@ class SmartCompilationCache {
|
|
|
588
567
|
// node_modules no existe
|
|
589
568
|
hash.update('nmtime:none');
|
|
590
569
|
}
|
|
591
|
-
|
|
570
|
+
const result = hash.digest('hex').substring(0, 16);
|
|
571
|
+
this._cachedDepHash = result;
|
|
572
|
+
this._depHashExpiry = Date.now() + this.DEP_HASH_TTL;
|
|
573
|
+
return result;
|
|
592
574
|
}
|
|
593
575
|
catch (error) {
|
|
594
576
|
// Incluir información del error en el hash para debugging
|
|
595
|
-
|
|
577
|
+
const result = createHash('sha256')
|
|
596
578
|
.update(`error:${error instanceof Error ? error.message : 'unknown'}`)
|
|
597
579
|
.digest('hex')
|
|
598
580
|
.substring(0, 16);
|
|
581
|
+
this._cachedDepHash = result;
|
|
582
|
+
this._depHashExpiry = Date.now() + this.DEP_HASH_TTL;
|
|
583
|
+
return result;
|
|
599
584
|
}
|
|
600
585
|
}
|
|
586
|
+
/**
|
|
587
|
+
* Invalida el cache de dependencyHash (llamar cuando package.json cambie)
|
|
588
|
+
*/
|
|
589
|
+
invalidateDepHashCache() {
|
|
590
|
+
this._cachedDepHash = null;
|
|
591
|
+
this._depHashExpiry = 0;
|
|
592
|
+
}
|
|
601
593
|
/**
|
|
602
594
|
* Genera clave de cache granular que incluye todos los factores
|
|
603
595
|
*/
|
|
@@ -616,35 +608,21 @@ class SmartCompilationCache {
|
|
|
616
608
|
if (!entry)
|
|
617
609
|
return false;
|
|
618
610
|
try {
|
|
619
|
-
//
|
|
620
|
-
await
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
// Verificar si la configuración ha cambiado
|
|
611
|
+
// Ejecutar todas las verificaciones independientes en paralelo
|
|
612
|
+
const [currentContentHash, currentDependencyHash, fileStat, _outputStat] = await Promise.all([
|
|
613
|
+
this.generateContentHash(filePath),
|
|
614
|
+
this.generateDependencyHash(),
|
|
615
|
+
stat(filePath),
|
|
616
|
+
stat(entry.outputPath),
|
|
617
|
+
]);
|
|
618
|
+
// Los hashes síncronos son baratos, evaluarlos tras el await
|
|
628
619
|
const currentConfigHash = this.generateConfigHash();
|
|
629
|
-
if (entry.configHash !== currentConfigHash) {
|
|
630
|
-
this.cache.delete(filePath);
|
|
631
|
-
return false;
|
|
632
|
-
}
|
|
633
|
-
// Verificar si las variables de entorno han cambiado
|
|
634
620
|
const currentEnvHash = this.generateEnvHash();
|
|
635
|
-
if (entry.
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
const currentDependencyHash = await this.generateDependencyHash();
|
|
641
|
-
if (entry.dependencyHash !== currentDependencyHash) {
|
|
642
|
-
this.cache.delete(filePath);
|
|
643
|
-
return false;
|
|
644
|
-
}
|
|
645
|
-
// Verificar tiempo de modificación como backup
|
|
646
|
-
const stats = await stat(filePath);
|
|
647
|
-
if (stats.mtimeMs > entry.mtime) {
|
|
621
|
+
if (entry.contentHash !== currentContentHash ||
|
|
622
|
+
entry.configHash !== currentConfigHash ||
|
|
623
|
+
entry.envHash !== currentEnvHash ||
|
|
624
|
+
entry.dependencyHash !== currentDependencyHash ||
|
|
625
|
+
fileStat.mtimeMs > entry.mtime) {
|
|
648
626
|
this.cache.delete(filePath);
|
|
649
627
|
return false;
|
|
650
628
|
}
|
|
@@ -727,7 +705,27 @@ class SmartCompilationCache {
|
|
|
727
705
|
if (entry) {
|
|
728
706
|
this.currentMemoryUsage -= entry.size;
|
|
729
707
|
this.cache.delete(oldestKey);
|
|
708
|
+
// Podar el grafo de dependencias para evitar entradas obsoletas
|
|
709
|
+
this.pruneDependencyGraph(oldestKey);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Elimina entradas obsoletas del grafo de dependencias para un archivo
|
|
715
|
+
*/
|
|
716
|
+
pruneDependencyGraph(filePath) {
|
|
717
|
+
const deps = this.dependencyGraph.get(filePath);
|
|
718
|
+
if (deps) {
|
|
719
|
+
for (const dep of deps) {
|
|
720
|
+
const reverseDeps = this.reverseDependencyGraph.get(dep);
|
|
721
|
+
if (reverseDeps) {
|
|
722
|
+
reverseDeps.delete(filePath);
|
|
723
|
+
if (reverseDeps.size === 0) {
|
|
724
|
+
this.reverseDependencyGraph.delete(dep);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
730
727
|
}
|
|
728
|
+
this.dependencyGraph.delete(filePath);
|
|
731
729
|
}
|
|
732
730
|
}
|
|
733
731
|
/**
|
|
@@ -833,6 +831,7 @@ class SmartCompilationCache {
|
|
|
833
831
|
});
|
|
834
832
|
packageWatcher.on('change', () => {
|
|
835
833
|
logger.info('📦 package.json modificado - invalidando cache de dependencias');
|
|
834
|
+
this.invalidateDepHashCache();
|
|
836
835
|
this.invalidateByDependencyChange();
|
|
837
836
|
});
|
|
838
837
|
this.fileWatchers.set('package.json', packageWatcher);
|
|
@@ -845,12 +844,12 @@ class SmartCompilationCache {
|
|
|
845
844
|
depth: 1, // Solo primer nivel para performance
|
|
846
845
|
ignored: /(^|[/\\])\../, // Ignorar archivos ocultos
|
|
847
846
|
});
|
|
848
|
-
nodeModulesWatcher.on('addDir', (
|
|
849
|
-
logger.info(`📦 Nueva dependencia instalada: ${
|
|
847
|
+
nodeModulesWatcher.on('addDir', (dirPath) => {
|
|
848
|
+
logger.info(`📦 Nueva dependencia instalada: ${dirPath.split(/[/\\]/).pop()}`);
|
|
850
849
|
this.invalidateByDependencyChange();
|
|
851
850
|
});
|
|
852
|
-
nodeModulesWatcher.on('unlinkDir', (
|
|
853
|
-
logger.info(`📦 Dependencia eliminada: ${
|
|
851
|
+
nodeModulesWatcher.on('unlinkDir', (dirPath) => {
|
|
852
|
+
logger.info(`📦 Dependencia eliminada: ${dirPath.split(/[/\\]/).pop()}`);
|
|
854
853
|
this.invalidateByDependencyChange();
|
|
855
854
|
});
|
|
856
855
|
this.fileWatchers.set('node_modules', nodeModulesWatcher);
|
|
@@ -860,6 +859,8 @@ class SmartCompilationCache {
|
|
|
860
859
|
}
|
|
861
860
|
catch (error) {
|
|
862
861
|
logger.warn('⚠️ No se pudo iniciar vigilancia de dependencias:', error);
|
|
862
|
+
// Marcar fallo para que el sistema lo tenga en cuenta
|
|
863
|
+
this._depWatcherFailed = true;
|
|
863
864
|
}
|
|
864
865
|
}
|
|
865
866
|
/**
|
|
@@ -1043,19 +1044,19 @@ async function handleCompilationError(error, fileName, stage, mode, isVerbose =
|
|
|
1043
1044
|
registerCompilationError(fileName, stage, errorMessage, 'error', errorDetails);
|
|
1044
1045
|
registerCompilationResult(stage, 1, 0, [fileName]); // Mostrar error inmediatamente solo en modo individual y watch
|
|
1045
1046
|
if (mode === 'individual' || mode === 'watch') {
|
|
1046
|
-
const
|
|
1047
|
+
const chalkLib = await loadChalk();
|
|
1047
1048
|
const baseName = path.basename(fileName);
|
|
1048
1049
|
const stageColor = await getStageColor(stage);
|
|
1049
1050
|
if (isVerbose) {
|
|
1050
1051
|
// Modo verbose: Mostrar error completo con contexto
|
|
1051
|
-
logger.error(
|
|
1052
|
-
logger.error(
|
|
1052
|
+
logger.error(chalkLib.red(`❌ Error en etapa ${stageColor(stage)} - ${baseName}:`));
|
|
1053
|
+
logger.error(chalkLib.red(errorMessage));
|
|
1053
1054
|
if (errorDetails && (stage === 'typescript' || stage === 'vue')) {
|
|
1054
1055
|
// Mostrar stack trace limitado para TypeScript y Vue
|
|
1055
1056
|
const stackLines = errorDetails.split('\n').slice(0, 5);
|
|
1056
1057
|
stackLines.forEach(line => {
|
|
1057
1058
|
if (line.trim()) {
|
|
1058
|
-
logger.error(
|
|
1059
|
+
logger.error(chalkLib.gray(` ${line.trim()}`));
|
|
1059
1060
|
}
|
|
1060
1061
|
});
|
|
1061
1062
|
}
|
|
@@ -1063,9 +1064,9 @@ async function handleCompilationError(error, fileName, stage, mode, isVerbose =
|
|
|
1063
1064
|
else {
|
|
1064
1065
|
// Modo normal: Mostrar error simplificado
|
|
1065
1066
|
const firstLine = errorMessage.split('\n')[0];
|
|
1066
|
-
logger.error(
|
|
1067
|
-
logger.error(
|
|
1068
|
-
logger.info(
|
|
1067
|
+
logger.error(chalkLib.red(`❌ Error en ${stageColor(stage)}: ${baseName}`));
|
|
1068
|
+
logger.error(chalkLib.red(` ${firstLine}`));
|
|
1069
|
+
logger.info(chalkLib.yellow(`💡 Usa --verbose para ver detalles completos`));
|
|
1069
1070
|
}
|
|
1070
1071
|
}
|
|
1071
1072
|
// En modo 'all', los errores se acumulan silenciosamente para el resumen final
|
|
@@ -1079,7 +1080,7 @@ function registerCompilationSuccess(fileName, stage) {
|
|
|
1079
1080
|
/**
|
|
1080
1081
|
* Limpia todos los errores y resultados acumulados
|
|
1081
1082
|
*/
|
|
1082
|
-
function clearCompilationState() {
|
|
1083
|
+
export function clearCompilationState() {
|
|
1083
1084
|
compilationErrors.length = 0;
|
|
1084
1085
|
compilationResults.length = 0;
|
|
1085
1086
|
}
|
|
@@ -1087,25 +1088,25 @@ function clearCompilationState() {
|
|
|
1087
1088
|
* Muestra un resumen detallado de todos los errores de compilación
|
|
1088
1089
|
*/
|
|
1089
1090
|
async function displayCompilationSummary(isVerbose = false, totalTime) {
|
|
1090
|
-
const
|
|
1091
|
+
const chalkLib = await loadChalk();
|
|
1091
1092
|
if (compilationErrors.length === 0 && compilationResults.length === 0) {
|
|
1092
|
-
logger.info(
|
|
1093
|
+
logger.info(chalkLib.green('✅ No hay errores de compilación para mostrar.'));
|
|
1093
1094
|
if (totalTime) {
|
|
1094
|
-
logger.info(
|
|
1095
|
+
logger.info(chalkLib.bold(`\n⏱️ TIEMPO TOTAL DE COMPILACIÓN: ${totalTime}`));
|
|
1095
1096
|
}
|
|
1096
1097
|
return;
|
|
1097
1098
|
}
|
|
1098
1099
|
// 🎨 Header moderno del resumen
|
|
1099
1100
|
const summaryLine = '━'.repeat(40);
|
|
1100
1101
|
logger.info('');
|
|
1101
|
-
logger.info(
|
|
1102
|
-
logger.info(
|
|
1102
|
+
logger.info(chalkLib.bold.cyan('📊 Resumen de Compilación'));
|
|
1103
|
+
logger.info(chalkLib.gray(summaryLine)); // ⏱️ Tiempo total con formato elegante
|
|
1103
1104
|
if (totalTime) {
|
|
1104
|
-
logger.info(
|
|
1105
|
+
logger.info(chalkLib.bold(`⏱️ Tiempo Total: ${chalkLib.green(totalTime)}`));
|
|
1105
1106
|
logger.info('');
|
|
1106
1107
|
} // 🔧 Estadísticas por etapa con mejor formato
|
|
1107
1108
|
if (compilationResults.length > 0) {
|
|
1108
|
-
logger.info(
|
|
1109
|
+
logger.info(chalkLib.bold.blue('🔧 Estadísticas por Etapa:'));
|
|
1109
1110
|
for (const result of compilationResults) {
|
|
1110
1111
|
const totalFiles = result.success + result.errors;
|
|
1111
1112
|
const successRate = totalFiles > 0
|
|
@@ -1113,20 +1114,20 @@ async function displayCompilationSummary(isVerbose = false, totalTime) {
|
|
|
1113
1114
|
: 0;
|
|
1114
1115
|
// Iconos y colores dinámicos por etapa
|
|
1115
1116
|
const stageIcon = getStageIcon(result.stage);
|
|
1116
|
-
const statusColor = result.errors === 0 ?
|
|
1117
|
+
const statusColor = result.errors === 0 ? chalkLib.green : chalkLib.red;
|
|
1117
1118
|
const progressBar = createProgressBarWithPercentage(successRate, 20);
|
|
1118
|
-
logger.info(` ${stageIcon} ${
|
|
1119
|
+
logger.info(` ${stageIcon} ${chalkLib.bold(result.stage)}`);
|
|
1119
1120
|
logger.info(` ${statusColor('●')} ${result.success}/${totalFiles} archivos ${statusColor(`(${successRate}%)`)}`);
|
|
1120
1121
|
logger.info(` ${progressBar}`);
|
|
1121
1122
|
if (result.errors > 0) {
|
|
1122
|
-
logger.info(` ${
|
|
1123
|
+
logger.info(` ${chalkLib.red('⚠')} ${result.errors} ${result.errors === 1 ? 'error' : 'errores'}`);
|
|
1123
1124
|
}
|
|
1124
1125
|
logger.info('');
|
|
1125
1126
|
}
|
|
1126
1127
|
}
|
|
1127
1128
|
// Mostrar errores detallados
|
|
1128
1129
|
if (compilationErrors.length > 0) {
|
|
1129
|
-
logger.info(
|
|
1130
|
+
logger.info(chalkLib.red(`\n❌ Se encontraron ${compilationErrors.length} errores:`));
|
|
1130
1131
|
// Agrupar errores por archivo para mejor organización
|
|
1131
1132
|
const errorsByFile = new Map();
|
|
1132
1133
|
compilationErrors.forEach(error => {
|
|
@@ -1141,9 +1142,9 @@ async function displayCompilationSummary(isVerbose = false, totalTime) {
|
|
|
1141
1142
|
const baseName = path.basename(filePath);
|
|
1142
1143
|
const errorCount = fileErrors.filter(e => e.severity === 'error').length;
|
|
1143
1144
|
const warningCount = fileErrors.filter(e => e.severity === 'warning').length;
|
|
1144
|
-
logger.info(
|
|
1145
|
-
logger.info(
|
|
1146
|
-
logger.info(
|
|
1145
|
+
logger.info(chalkLib.cyan(`\n📄 ${fileIndex}. ${baseName}`));
|
|
1146
|
+
logger.info(chalkLib.gray(` Ruta: ${filePath}`));
|
|
1147
|
+
logger.info(chalkLib.yellow(` ${errorCount} errores, ${warningCount} advertencias`));
|
|
1147
1148
|
for (const error of fileErrors) {
|
|
1148
1149
|
const icon = error.severity === 'error' ? '❌' : '⚠️';
|
|
1149
1150
|
const stageColor = await getStageColor(error.stage);
|
|
@@ -1153,12 +1154,12 @@ async function displayCompilationSummary(isVerbose = false, totalTime) {
|
|
|
1153
1154
|
const detailLines = error.details.split('\n').slice(0, 5);
|
|
1154
1155
|
detailLines.forEach(line => {
|
|
1155
1156
|
if (line.trim()) {
|
|
1156
|
-
logger.info(
|
|
1157
|
+
logger.info(chalkLib.gray(` ${line.trim()}`));
|
|
1157
1158
|
}
|
|
1158
1159
|
});
|
|
1159
1160
|
}
|
|
1160
1161
|
if (error.help) {
|
|
1161
|
-
logger.info(
|
|
1162
|
+
logger.info(chalkLib.blue(` 💡 ${error.help}`));
|
|
1162
1163
|
}
|
|
1163
1164
|
}
|
|
1164
1165
|
fileIndex++;
|
|
@@ -1169,44 +1170,44 @@ async function displayCompilationSummary(isVerbose = false, totalTime) {
|
|
|
1169
1170
|
// Header elegante para estadísticas finales
|
|
1170
1171
|
const statLine = '═'.repeat(50);
|
|
1171
1172
|
logger.info('');
|
|
1172
|
-
logger.info(
|
|
1173
|
-
logger.info(
|
|
1174
|
-
logger.info(
|
|
1173
|
+
logger.info(chalkLib.bold.cyan(statLine));
|
|
1174
|
+
logger.info(chalkLib.bold.cyan(' 📊 RESUMEN FINAL'));
|
|
1175
|
+
logger.info(chalkLib.bold.cyan(statLine));
|
|
1175
1176
|
// Estadísticas con iconos y colores modernos
|
|
1176
1177
|
logger.info('');
|
|
1177
|
-
logger.info(
|
|
1178
|
-
logger.info(` 📁 Archivos afectados: ${
|
|
1179
|
-
logger.info(` ${totalErrors > 0 ?
|
|
1180
|
-
logger.info(` ${totalWarnings > 0 ?
|
|
1178
|
+
logger.info(chalkLib.bold('🎯 Resultados:'));
|
|
1179
|
+
logger.info(` 📁 Archivos afectados: ${chalkLib.cyan.bold(totalFiles)}`);
|
|
1180
|
+
logger.info(` ${totalErrors > 0 ? chalkLib.red('●') : chalkLib.green('○')} Errores: ${totalErrors > 0 ? chalkLib.red.bold(totalErrors) : chalkLib.green.bold('0')}`);
|
|
1181
|
+
logger.info(` ${totalWarnings > 0 ? chalkLib.yellow('●') : chalkLib.green('○')} Advertencias: ${totalWarnings > 0 ? chalkLib.yellow.bold(totalWarnings) : chalkLib.green.bold('0')}`);
|
|
1181
1182
|
logger.info('');
|
|
1182
1183
|
// Estado final con diseño visual atractivo
|
|
1183
1184
|
if (totalErrors > 0) {
|
|
1184
|
-
logger.info(
|
|
1185
|
-
logger.info(
|
|
1185
|
+
logger.info(chalkLib.red.bold('🚨 COMPILACIÓN COMPLETADA CON ERRORES'));
|
|
1186
|
+
logger.info(chalkLib.red(' Por favor revisa y corrige los problemas anteriores.'));
|
|
1186
1187
|
}
|
|
1187
1188
|
else if (totalWarnings > 0) {
|
|
1188
|
-
logger.info(
|
|
1189
|
-
logger.info(
|
|
1189
|
+
logger.info(chalkLib.yellow.bold('⚠️ COMPILACIÓN COMPLETADA CON ADVERTENCIAS'));
|
|
1190
|
+
logger.info(chalkLib.yellow(' Considera revisar las advertencias anteriores.'));
|
|
1190
1191
|
}
|
|
1191
1192
|
else {
|
|
1192
|
-
logger.info(
|
|
1193
|
-
logger.info(
|
|
1193
|
+
logger.info(chalkLib.green.bold('✅ COMPILACIÓN EXITOSA'));
|
|
1194
|
+
logger.info(chalkLib.green(' ¡Todos los archivos se compilaron sin problemas!'));
|
|
1194
1195
|
}
|
|
1195
1196
|
logger.info('');
|
|
1196
|
-
logger.info(
|
|
1197
|
+
logger.info(chalkLib.bold.cyan(statLine));
|
|
1197
1198
|
}
|
|
1198
1199
|
else {
|
|
1199
1200
|
// Caso exitoso sin errores
|
|
1200
1201
|
const successLine = '═'.repeat(50);
|
|
1201
1202
|
logger.info('');
|
|
1202
|
-
logger.info(
|
|
1203
|
-
logger.info(
|
|
1204
|
-
logger.info(
|
|
1203
|
+
logger.info(chalkLib.bold.green(successLine));
|
|
1204
|
+
logger.info(chalkLib.bold.green(' ✨ ÉXITO'));
|
|
1205
|
+
logger.info(chalkLib.bold.green(successLine));
|
|
1205
1206
|
logger.info('');
|
|
1206
|
-
logger.info(
|
|
1207
|
-
logger.info(
|
|
1207
|
+
logger.info(chalkLib.green.bold('🎉 COMPILACIÓN COMPLETADA EXITOSAMENTE'));
|
|
1208
|
+
logger.info(chalkLib.green(' ¡No se encontraron errores ni advertencias!'));
|
|
1208
1209
|
logger.info('');
|
|
1209
|
-
logger.info(
|
|
1210
|
+
logger.info(chalkLib.bold.green(successLine));
|
|
1210
1211
|
}
|
|
1211
1212
|
logger.info('');
|
|
1212
1213
|
}
|
|
@@ -1214,7 +1215,7 @@ async function displayCompilationSummary(isVerbose = false, totalTime) {
|
|
|
1214
1215
|
* Muestra errores del linter con formato visual moderno y profesional
|
|
1215
1216
|
*/
|
|
1216
1217
|
async function displayLinterErrors(errors) {
|
|
1217
|
-
const
|
|
1218
|
+
const chalkLib = await loadChalk();
|
|
1218
1219
|
// Agrupar errores por archivo
|
|
1219
1220
|
const errorsByFile = new Map();
|
|
1220
1221
|
errors.forEach(error => {
|
|
@@ -1227,22 +1228,22 @@ async function displayLinterErrors(errors) {
|
|
|
1227
1228
|
const totalWarnings = errors.filter(e => e.severity === 'warning').length;
|
|
1228
1229
|
const totalFiles = errorsByFile.size;
|
|
1229
1230
|
// Header estilo moderno con gradiente visual
|
|
1230
|
-
logger.info(
|
|
1231
|
-
logger.info(
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
logger.info(
|
|
1231
|
+
logger.info(chalkLib.bold.rgb(255, 120, 120)('╭─────────────────────────────────────────────────────────────╮'));
|
|
1232
|
+
logger.info(chalkLib.bold.rgb(255, 120, 120)('│ ') +
|
|
1233
|
+
chalkLib.bold.white('🔍 LINTER REPORT') +
|
|
1234
|
+
chalkLib.bold.rgb(255, 120, 120)(' │'));
|
|
1235
|
+
logger.info(chalkLib.bold.rgb(255, 120, 120)('╰─────────────────────────────────────────────────────────────╯'));
|
|
1235
1236
|
// Resumen con iconos profesionales
|
|
1236
|
-
const errorIcon = totalErrors > 0 ?
|
|
1237
|
-
const warningIcon = totalWarnings > 0 ?
|
|
1237
|
+
const errorIcon = totalErrors > 0 ? chalkLib.red('●') : chalkLib.green('○');
|
|
1238
|
+
const warningIcon = totalWarnings > 0 ? chalkLib.yellow('●') : chalkLib.green('○');
|
|
1238
1239
|
logger.info('');
|
|
1239
|
-
logger.info(
|
|
1240
|
-
logger.info(` ${errorIcon} ${
|
|
1241
|
-
logger.info(` ${warningIcon} ${
|
|
1242
|
-
logger.info(` 📁 ${
|
|
1240
|
+
logger.info(chalkLib.bold('📊 Summary:'));
|
|
1241
|
+
logger.info(` ${errorIcon} ${chalkLib.bold(totalErrors)} ${chalkLib.red('errors')}`);
|
|
1242
|
+
logger.info(` ${warningIcon} ${chalkLib.bold(totalWarnings)} ${chalkLib.yellow('warnings')}`);
|
|
1243
|
+
logger.info(` 📁 ${chalkLib.bold(totalFiles)} ${chalkLib.cyan('files')}`);
|
|
1243
1244
|
logger.info('');
|
|
1244
1245
|
if (totalErrors === 0 && totalWarnings === 0) {
|
|
1245
|
-
logger.info(
|
|
1246
|
+
logger.info(chalkLib.green.bold('✨ All checks passed! No issues found.'));
|
|
1246
1247
|
return;
|
|
1247
1248
|
}
|
|
1248
1249
|
// Mostrar errores por archivo con formato elegante
|
|
@@ -1251,29 +1252,29 @@ async function displayLinterErrors(errors) {
|
|
|
1251
1252
|
await displayFileErrorsGroup(filePath, fileErrors, fileIndex, totalFiles);
|
|
1252
1253
|
fileIndex++;
|
|
1253
1254
|
if (fileIndex <= totalFiles) {
|
|
1254
|
-
logger.info(
|
|
1255
|
+
logger.info(chalkLib.gray('─'.repeat(80))); // Separador entre archivos
|
|
1255
1256
|
}
|
|
1256
1257
|
}
|
|
1257
1258
|
// Footer con estadísticas
|
|
1258
1259
|
logger.info('');
|
|
1259
|
-
logger.info(
|
|
1260
|
-
logger.info(
|
|
1261
|
-
|
|
1260
|
+
logger.info(chalkLib.bold.rgb(255, 120, 120)('╭─────────────────────────────────────────────────────────────╮'));
|
|
1261
|
+
logger.info(chalkLib.bold.rgb(255, 120, 120)('│ ') +
|
|
1262
|
+
chalkLib.bold.white(`Found ${totalErrors + totalWarnings} issues in ${totalFiles} files`) +
|
|
1262
1263
|
' '.repeat(Math.max(0, 52 -
|
|
1263
1264
|
`Found ${totalErrors + totalWarnings} issues in ${totalFiles} files`
|
|
1264
1265
|
.length)) +
|
|
1265
|
-
|
|
1266
|
-
logger.info(
|
|
1266
|
+
chalkLib.bold.rgb(255, 120, 120)(' │'));
|
|
1267
|
+
logger.info(chalkLib.bold.rgb(255, 120, 120)('╰─────────────────────────────────────────────────────────────╯'));
|
|
1267
1268
|
}
|
|
1268
1269
|
/**
|
|
1269
1270
|
* Muestra un grupo de errores para un archivo específico con formato moderno
|
|
1270
1271
|
*/
|
|
1271
1272
|
async function displayFileErrorsGroup(filePath, fileErrors, _fileIndex, _totalFiles) {
|
|
1272
|
-
const
|
|
1273
|
+
const chalkLib = await loadChalk();
|
|
1273
1274
|
// Header del archivo con iconos de estado
|
|
1274
1275
|
const errorCount = fileErrors.filter(e => e.severity === 'error').length;
|
|
1275
1276
|
const warningCount = fileErrors.filter(e => e.severity === 'warning').length;
|
|
1276
|
-
const statusIcon = errorCount > 0 ?
|
|
1277
|
+
const statusIcon = errorCount > 0 ? chalkLib.red('✕') : chalkLib.yellow('⚠');
|
|
1277
1278
|
const fileIcon = filePath.endsWith('.vue')
|
|
1278
1279
|
? '🎨'
|
|
1279
1280
|
: filePath.endsWith('.ts')
|
|
@@ -1282,8 +1283,8 @@ async function displayFileErrorsGroup(filePath, fileErrors, _fileIndex, _totalFi
|
|
|
1282
1283
|
? '📜'
|
|
1283
1284
|
: '📄';
|
|
1284
1285
|
logger.info('');
|
|
1285
|
-
logger.info(
|
|
1286
|
-
logger.info(
|
|
1286
|
+
logger.info(chalkLib.bold(`${statusIcon} ${fileIcon} ${chalkLib.cyan(path.relative(process.cwd(), filePath))}`));
|
|
1287
|
+
logger.info(chalkLib.gray(` ${errorCount} errors, ${warningCount} warnings`));
|
|
1287
1288
|
logger.info('');
|
|
1288
1289
|
// Mostrar cada error con formato elegante
|
|
1289
1290
|
for (let i = 0; i < fileErrors.length; i++) {
|
|
@@ -1295,21 +1296,21 @@ async function displayFileErrorsGroup(filePath, fileErrors, _fileIndex, _totalFi
|
|
|
1295
1296
|
* Muestra un error individual con formato visual moderno tipo ESLint/Prettier
|
|
1296
1297
|
*/
|
|
1297
1298
|
async function displayModernLinterError(error, filePath, errorIndex, totalErrorsInFile) {
|
|
1298
|
-
const
|
|
1299
|
+
const chalkLib = await loadChalk();
|
|
1299
1300
|
const fs = await import('node:fs/promises');
|
|
1300
1301
|
// Determinar tipo y color del error
|
|
1301
1302
|
const isError = error.severity === 'error';
|
|
1302
|
-
const typeColor = isError ?
|
|
1303
|
+
const typeColor = isError ? chalkLib.red : chalkLib.yellow;
|
|
1303
1304
|
const typeIcon = isError ? '✕' : '⚠';
|
|
1304
1305
|
const line = error.line || 1;
|
|
1305
1306
|
const column = error.column || 1;
|
|
1306
1307
|
const ruleId = error.ruleId || error.from || 'unknown';
|
|
1307
1308
|
// Línea principal del error con formato moderno
|
|
1308
|
-
const errorHeader = ` ${typeColor(typeIcon)} ${
|
|
1309
|
-
const ruleInfo = `${
|
|
1310
|
-
const locationInfo = `${
|
|
1309
|
+
const errorHeader = ` ${typeColor(typeIcon)} ${chalkLib.bold(error.message)}`;
|
|
1310
|
+
const ruleInfo = `${chalkLib.gray(ruleId)}`;
|
|
1311
|
+
const locationInfo = `${chalkLib.blue(`${line}:${column}`)}`;
|
|
1311
1312
|
logger.info(errorHeader);
|
|
1312
|
-
logger.info(` ${
|
|
1313
|
+
logger.info(` ${chalkLib.gray('at')} ${locationInfo} ${chalkLib.gray('·')} ${ruleInfo}`);
|
|
1313
1314
|
// Mostrar código con contexto
|
|
1314
1315
|
try {
|
|
1315
1316
|
const absolutePath = path.resolve(filePath);
|
|
@@ -1331,27 +1332,27 @@ async function displayModernLinterError(error, filePath, errorIndex, totalErrors
|
|
|
1331
1332
|
const isErrorLine = i === lineNum;
|
|
1332
1333
|
if (isErrorLine) {
|
|
1333
1334
|
// Línea con el error - destacada
|
|
1334
|
-
logger.info(` ${
|
|
1335
|
+
logger.info(` ${chalkLib.red('>')} ${chalkLib.gray(lineNumStr)} ${chalkLib.gray('│')} ${currentLine}`);
|
|
1335
1336
|
// Indicador de posición del error
|
|
1336
1337
|
const pointer = ' '.repeat(Math.max(0, column - 1)) + typeColor('^');
|
|
1337
|
-
logger.info(` ${
|
|
1338
|
+
logger.info(` ${chalkLib.gray(' ')} ${chalkLib.gray(' '.repeat(maxLineNumWidth))} ${chalkLib.gray('│')} ${pointer}`);
|
|
1338
1339
|
}
|
|
1339
1340
|
else {
|
|
1340
1341
|
// Líneas de contexto
|
|
1341
|
-
logger.info(` ${
|
|
1342
|
+
logger.info(` ${chalkLib.gray(' ')} ${chalkLib.gray(lineNumStr)} ${chalkLib.gray('│')} ${chalkLib.gray(currentLine)}`);
|
|
1342
1343
|
}
|
|
1343
1344
|
}
|
|
1344
1345
|
}
|
|
1345
1346
|
}
|
|
1346
1347
|
catch {
|
|
1347
1348
|
// Si no se puede leer el archivo, mostrar formato simplificado
|
|
1348
|
-
logger.info(` ${
|
|
1349
|
+
logger.info(` ${chalkLib.gray('│')} ${chalkLib.gray('(Unable to read file content)')}`);
|
|
1349
1350
|
}
|
|
1350
1351
|
// Mostrar ayuda si está disponible
|
|
1351
1352
|
if (error.help) {
|
|
1352
1353
|
logger.info('');
|
|
1353
1354
|
const helpText = error.help.replace(/^Regla \w+: /, '').trim();
|
|
1354
|
-
logger.info(` ${
|
|
1355
|
+
logger.info(` ${chalkLib.blue('💡')} ${chalkLib.blue('Help:')} ${chalkLib.gray(helpText)}`);
|
|
1355
1356
|
}
|
|
1356
1357
|
// Separador entre errores (solo si no es el último)
|
|
1357
1358
|
if (errorIndex < totalErrorsInFile) {
|
|
@@ -1363,14 +1364,14 @@ async function displayModernLinterError(error, filePath, errorIndex, totalErrors
|
|
|
1363
1364
|
* @deprecated Use displayModernLinterError instead
|
|
1364
1365
|
*/
|
|
1365
1366
|
async function _displaySingleLinterError(error, filePath) {
|
|
1366
|
-
const
|
|
1367
|
+
const chalkLib = await loadChalk();
|
|
1367
1368
|
const fs = await import('node:fs/promises');
|
|
1368
1369
|
const icon = error.severity === 'error' ? '×' : '⚠';
|
|
1369
1370
|
const ruleInfo = error.help || '';
|
|
1370
1371
|
const line = error.line || 'N/A';
|
|
1371
1372
|
const column = error.column || 10; // Columna por defecto si no está disponible
|
|
1372
1373
|
// Línea principal del error
|
|
1373
|
-
const mainErrorLine = `${
|
|
1374
|
+
const mainErrorLine = `${chalkLib.red(icon)} ${chalkLib.cyan(`${error.from}(${ruleInfo.replace(/^Regla \w+: /, '')})`)}: ${error.message}`;
|
|
1374
1375
|
logger.info(mainErrorLine);
|
|
1375
1376
|
// Intentar leer el contenido del archivo para mostrar contexto
|
|
1376
1377
|
try {
|
|
@@ -1380,7 +1381,7 @@ async function _displaySingleLinterError(error, filePath) {
|
|
|
1380
1381
|
const lineNum = parseInt(line.toString()) - 1; // Convertir a índice 0-based
|
|
1381
1382
|
if (lineNum >= 0 && lineNum < lines.length) {
|
|
1382
1383
|
// Mostrar ubicación
|
|
1383
|
-
logger.info(
|
|
1384
|
+
logger.info(chalkLib.blue(` ╭─[${filePath}:${line}:${column}]`));
|
|
1384
1385
|
// Mostrar líneas de contexto
|
|
1385
1386
|
const startLine = Math.max(0, lineNum - 1);
|
|
1386
1387
|
const endLine = Math.min(lines.length - 1, lineNum + 1);
|
|
@@ -1390,38 +1391,38 @@ async function _displaySingleLinterError(error, filePath) {
|
|
|
1390
1391
|
const prefix = currentLineNum.toString().padStart(2, ' ');
|
|
1391
1392
|
if (i === lineNum) {
|
|
1392
1393
|
// Línea con el error
|
|
1393
|
-
logger.info(
|
|
1394
|
+
logger.info(chalkLib.blue(` ${prefix} │ `) + currentLine);
|
|
1394
1395
|
// Mostrar el indicador de error
|
|
1395
1396
|
const indent = ' '.repeat(prefix.length + 3); // Espacios para alinear
|
|
1396
1397
|
const pointer = ' '.repeat(Math.max(0, (column || 1) - 1)) +
|
|
1397
|
-
|
|
1398
|
-
logger.info(
|
|
1398
|
+
chalkLib.red('───────┬──────');
|
|
1399
|
+
logger.info(chalkLib.blue(indent + '·') + pointer);
|
|
1399
1400
|
// Mensaje de ubicación específica
|
|
1400
1401
|
const messageIndent = ' '.repeat(Math.max(0, (column || 1) + 6));
|
|
1401
|
-
logger.info(
|
|
1402
|
+
logger.info(chalkLib.blue(indent + '·') +
|
|
1402
1403
|
messageIndent +
|
|
1403
|
-
|
|
1404
|
-
|
|
1404
|
+
chalkLib.red('╰── ') +
|
|
1405
|
+
chalkLib.gray(getErrorLocationMessage(error)));
|
|
1405
1406
|
}
|
|
1406
1407
|
else {
|
|
1407
1408
|
// Líneas de contexto
|
|
1408
|
-
logger.info(
|
|
1409
|
+
logger.info(chalkLib.blue(` ${prefix} │ `) + chalkLib.gray(currentLine));
|
|
1409
1410
|
}
|
|
1410
1411
|
}
|
|
1411
|
-
logger.info(
|
|
1412
|
+
logger.info(chalkLib.blue(' ╰────'));
|
|
1412
1413
|
}
|
|
1413
1414
|
}
|
|
1414
1415
|
catch {
|
|
1415
1416
|
// Si no se puede leer el archivo, mostrar formato simplificado
|
|
1416
|
-
logger.info(
|
|
1417
|
-
logger.info(
|
|
1418
|
-
|
|
1419
|
-
logger.info(
|
|
1417
|
+
logger.info(chalkLib.blue(` ╭─[${filePath}:${line}:${column}]`));
|
|
1418
|
+
logger.info(chalkLib.blue(' │ ') +
|
|
1419
|
+
chalkLib.gray('(No se pudo leer el contenido del archivo)'));
|
|
1420
|
+
logger.info(chalkLib.blue(' ╰────'));
|
|
1420
1421
|
}
|
|
1421
1422
|
// Mostrar ayuda si está disponible
|
|
1422
1423
|
if (error.help) {
|
|
1423
1424
|
const helpMessage = error.help.replace(/^Regla \w+: /, '');
|
|
1424
|
-
logger.info(
|
|
1425
|
+
logger.info(chalkLib.blue(' help: ') + chalkLib.yellow(helpMessage));
|
|
1425
1426
|
}
|
|
1426
1427
|
logger.info(''); // Espacio entre errores
|
|
1427
1428
|
}
|
|
@@ -1450,22 +1451,22 @@ function getErrorLocationMessage(error) {
|
|
|
1450
1451
|
* Obtiene el color apropiado para cada etapa de compilación
|
|
1451
1452
|
*/
|
|
1452
1453
|
async function getStageColor(stage) {
|
|
1453
|
-
const
|
|
1454
|
+
const chalkLib = await loadChalk();
|
|
1454
1455
|
switch (stage) {
|
|
1455
1456
|
case 'vue':
|
|
1456
|
-
return
|
|
1457
|
+
return chalkLib.green;
|
|
1457
1458
|
case 'typescript':
|
|
1458
|
-
return
|
|
1459
|
+
return chalkLib.blue;
|
|
1459
1460
|
case 'standardization':
|
|
1460
|
-
return
|
|
1461
|
+
return chalkLib.yellow;
|
|
1461
1462
|
case 'minification':
|
|
1462
|
-
return
|
|
1463
|
+
return chalkLib.red;
|
|
1463
1464
|
case 'tailwind':
|
|
1464
|
-
return
|
|
1465
|
+
return chalkLib.magenta;
|
|
1465
1466
|
case 'file-read':
|
|
1466
|
-
return
|
|
1467
|
+
return chalkLib.gray;
|
|
1467
1468
|
default:
|
|
1468
|
-
return
|
|
1469
|
+
return chalkLib.white;
|
|
1469
1470
|
}
|
|
1470
1471
|
}
|
|
1471
1472
|
export function normalizeRuta(ruta) {
|
|
@@ -1568,8 +1569,8 @@ async function compileJS(inPath, outPath, mode = 'individual') {
|
|
|
1568
1569
|
let start = Date.now();
|
|
1569
1570
|
const extension = path.extname(inPath); // Asegurar que el parser esté cargado
|
|
1570
1571
|
await moduleManager.ensureModuleLoaded('parser');
|
|
1571
|
-
const
|
|
1572
|
-
const result = await
|
|
1572
|
+
const getCodeFileLib = await loadParser();
|
|
1573
|
+
const result = await getCodeFileLib(inPath);
|
|
1573
1574
|
let code = result.code;
|
|
1574
1575
|
const error = result.error;
|
|
1575
1576
|
timings.fileRead = Date.now() - start;
|
|
@@ -1593,11 +1594,11 @@ async function compileJS(inPath, outPath, mode = 'individual') {
|
|
|
1593
1594
|
}
|
|
1594
1595
|
// Asegurar que el módulo Vue esté cargado
|
|
1595
1596
|
await moduleManager.ensureModuleLoaded('vue');
|
|
1596
|
-
const
|
|
1597
|
-
if (typeof
|
|
1598
|
-
throw new Error(`loadVue devolvió ${typeof
|
|
1597
|
+
const preCompileVueLib = await loadVue();
|
|
1598
|
+
if (typeof preCompileVueLib !== 'function') {
|
|
1599
|
+
throw new Error(`loadVue devolvió ${typeof preCompileVueLib} en lugar de una función para archivo: ${inPath}`);
|
|
1599
1600
|
}
|
|
1600
|
-
vueResult = await
|
|
1601
|
+
vueResult = await preCompileVueLib(code, inPath, env.isPROD === 'true');
|
|
1601
1602
|
timings.vueCompile = Date.now() - start;
|
|
1602
1603
|
if (vueResult === undefined || vueResult === null) {
|
|
1603
1604
|
throw new Error(`preCompileVue devolvió ${vueResult} para archivo: ${inPath}`);
|
|
@@ -1626,12 +1627,12 @@ async function compileJS(inPath, outPath, mode = 'individual') {
|
|
|
1626
1627
|
}
|
|
1627
1628
|
// Asegurar que el módulo TypeScript esté cargado
|
|
1628
1629
|
await moduleManager.ensureModuleLoaded('typescript');
|
|
1629
|
-
const
|
|
1630
|
-
if (typeof
|
|
1631
|
-
throw new Error(`loadTypeScript devolvió ${typeof
|
|
1630
|
+
const preCompileTSLib = await loadTypeScript();
|
|
1631
|
+
if (typeof preCompileTSLib !== 'function') {
|
|
1632
|
+
throw new Error(`loadTypeScript devolvió ${typeof preCompileTSLib} en lugar de una función para archivo: ${inPath}`);
|
|
1632
1633
|
}
|
|
1633
1634
|
// 🚀 OPTIMIZACIÓN: Pasar scriptInfo directamente sin crear objeto nuevo
|
|
1634
|
-
tsResult = await
|
|
1635
|
+
tsResult = await preCompileTSLib(code, inPath, vueResult?.scriptInfo);
|
|
1635
1636
|
timings.tsCompile = Date.now() - start;
|
|
1636
1637
|
if (tsResult === undefined || tsResult === null) {
|
|
1637
1638
|
throw new Error(`preCompileTS devolvió ${tsResult} para archivo: ${inPath}`);
|
|
@@ -1665,8 +1666,8 @@ async function compileJS(inPath, outPath, mode = 'individual') {
|
|
|
1665
1666
|
start = Date.now();
|
|
1666
1667
|
// Asegurar que el módulo de transformaciones esté cargado
|
|
1667
1668
|
await moduleManager.ensureModuleLoaded('transforms');
|
|
1668
|
-
const
|
|
1669
|
-
const resultSTD = await
|
|
1669
|
+
const estandarizaCodeLib = await loadTransforms();
|
|
1670
|
+
const resultSTD = await estandarizaCodeLib(code, inPath);
|
|
1670
1671
|
timings.standardization = Date.now() - start;
|
|
1671
1672
|
if (resultSTD === undefined || resultSTD === null) {
|
|
1672
1673
|
throw new Error(`estandarizaCode devolvió ${resultSTD} para archivo: ${inPath}`);
|
|
@@ -1689,8 +1690,9 @@ async function compileJS(inPath, outPath, mode = 'individual') {
|
|
|
1689
1690
|
}
|
|
1690
1691
|
// Asegurar que el módulo de minificación esté cargado
|
|
1691
1692
|
await moduleManager.ensureModuleLoaded('minify');
|
|
1692
|
-
const
|
|
1693
|
-
const
|
|
1693
|
+
const minifyJSLib = await loadMinify();
|
|
1694
|
+
const beforeMinification = code; // Guardar código antes de minificar
|
|
1695
|
+
const resultMinify = await minifyJSLib(code, inPath, true);
|
|
1694
1696
|
timings.minification = Date.now() - start;
|
|
1695
1697
|
if (resultMinify === undefined || resultMinify === null) {
|
|
1696
1698
|
throw new Error(`minifyJS devolvió ${resultMinify} para archivo: ${inPath}`);
|
|
@@ -1705,6 +1707,20 @@ async function compileJS(inPath, outPath, mode = 'individual') {
|
|
|
1705
1707
|
}
|
|
1706
1708
|
registerCompilationSuccess(inPath, 'minification');
|
|
1707
1709
|
code = resultMinify.code;
|
|
1710
|
+
// VALIDACIÓN DE INTEGRIDAD - Solo si flag está activo
|
|
1711
|
+
// Esta es una validación redundante (ya se hizo en minify.ts)
|
|
1712
|
+
// pero crítica para asegurar integridad antes de escribir archivo final
|
|
1713
|
+
if (env.CHECK_INTEGRITY === 'true') {
|
|
1714
|
+
const validation = integrityValidator.validate(beforeMinification, code, `compile:${path.basename(inPath)}`, {
|
|
1715
|
+
skipSyntaxCheck: true, // Ya validado en minify.ts
|
|
1716
|
+
verbose: env.VERBOSE === 'true',
|
|
1717
|
+
throwOnError: true,
|
|
1718
|
+
});
|
|
1719
|
+
if (!validation.valid) {
|
|
1720
|
+
logger.error(`❌ Validación de integridad fallida en compilación para ${path.basename(inPath)}`, validation.errors.join(', '));
|
|
1721
|
+
throw new Error(`Compilation integrity check failed for ${path.basename(inPath)}: ${validation.errors.join(', ')}`);
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1708
1724
|
} // Escribir archivo final
|
|
1709
1725
|
const destinationDir = path.dirname(outPath);
|
|
1710
1726
|
await mkdir(destinationDir, { recursive: true });
|
|
@@ -1741,8 +1757,8 @@ export async function initCompile(ruta, compileTailwind = true, mode = 'individu
|
|
|
1741
1757
|
// Generar TailwindCSS si está habilitado
|
|
1742
1758
|
if (compileTailwind && Boolean(env.TAILWIND)) {
|
|
1743
1759
|
await moduleManager.ensureModuleLoaded('tailwind');
|
|
1744
|
-
const
|
|
1745
|
-
const resultTW = await
|
|
1760
|
+
const generateTailwindCSSLib = await loadTailwind();
|
|
1761
|
+
const resultTW = await generateTailwindCSSLib();
|
|
1746
1762
|
if (typeof resultTW !== 'boolean') {
|
|
1747
1763
|
if (resultTW?.success) {
|
|
1748
1764
|
logger.info(`🎨 ${resultTW.message}`);
|
|
@@ -1789,8 +1805,8 @@ export async function initCompile(ruta, compileTailwind = true, mode = 'individu
|
|
|
1789
1805
|
logger.info(`🔚 Destino: ${outFile}`);
|
|
1790
1806
|
logger.info(`⏱️ Tiempo: ${elapsedTime}`);
|
|
1791
1807
|
}
|
|
1792
|
-
const
|
|
1793
|
-
logger.info(
|
|
1808
|
+
const chalkLib = await loadChalk();
|
|
1809
|
+
logger.info(chalkLib.green(`✅ Compilación exitosa: ${path.basename(file)}`));
|
|
1794
1810
|
}
|
|
1795
1811
|
return {
|
|
1796
1812
|
success: true,
|
|
@@ -2004,11 +2020,11 @@ export async function runLinter(showResult = false) {
|
|
|
2004
2020
|
const parsedLinterEnv = JSON.parse(linterENV);
|
|
2005
2021
|
if (Array.isArray(parsedLinterEnv)) {
|
|
2006
2022
|
// Cargar dependencias de linting de forma lazy
|
|
2007
|
-
const { ESLint, OxLint } = await loadLinter();
|
|
2023
|
+
const { ESLint: ESLintLib, OxLint: OxLintLib } = await loadLinter();
|
|
2008
2024
|
for (const item of parsedLinterEnv) {
|
|
2009
2025
|
if (item.name.toLowerCase() === 'eslint') {
|
|
2010
2026
|
logger.info(`🔧 Ejecutando ESLint con config: ${item.configFile || 'por defecto'}`);
|
|
2011
|
-
const eslintPromise =
|
|
2027
|
+
const eslintPromise = ESLintLib(item)
|
|
2012
2028
|
.then((eslintResult) => {
|
|
2013
2029
|
if (eslintResult && eslintResult.json) {
|
|
2014
2030
|
// Procesar resultados de ESLint
|
|
@@ -2075,7 +2091,7 @@ export async function runLinter(showResult = false) {
|
|
|
2075
2091
|
}
|
|
2076
2092
|
else if (item.name.toLowerCase() === 'oxlint') {
|
|
2077
2093
|
logger.info(`🔧 Ejecutando OxLint con config: ${item.configFile || 'por defecto'}`);
|
|
2078
|
-
const oxlintPromise =
|
|
2094
|
+
const oxlintPromise = OxLintLib(item)
|
|
2079
2095
|
.then((oxlintResult) => {
|
|
2080
2096
|
if (oxlintResult &&
|
|
2081
2097
|
oxlintResult['json'] &&
|
|
@@ -2140,8 +2156,8 @@ export async function runLinter(showResult = false) {
|
|
|
2140
2156
|
await displayLinterErrors(linterErrors);
|
|
2141
2157
|
}
|
|
2142
2158
|
else {
|
|
2143
|
-
const
|
|
2144
|
-
logger.info(
|
|
2159
|
+
const chalkLib = await loadChalk();
|
|
2160
|
+
logger.info(chalkLib.green('✅ No se encontraron errores ni advertencias de linting.'));
|
|
2145
2161
|
}
|
|
2146
2162
|
}
|
|
2147
2163
|
else {
|
|
@@ -2345,8 +2361,8 @@ export async function initCompileAll() {
|
|
|
2345
2361
|
logger.info(`🔚 Destino: ${pathDist}\n`);
|
|
2346
2362
|
// Fase 3: TailwindCSS
|
|
2347
2363
|
progressManager.updateProgress('🎨 Generando TailwindCSS...');
|
|
2348
|
-
const
|
|
2349
|
-
const resultTW = await
|
|
2364
|
+
const generateTailwindCSSLib = await loadTailwind();
|
|
2365
|
+
const resultTW = await generateTailwindCSSLib();
|
|
2350
2366
|
if (typeof resultTW !== 'boolean') {
|
|
2351
2367
|
if (resultTW?.success) {
|
|
2352
2368
|
logger.info(`🎨 ${resultTW.message}\n`);
|
|
@@ -2437,9 +2453,9 @@ export async function initCompileAll() {
|
|
|
2437
2453
|
// ⚠️ Warning si los hilos son muy pocos para el tamaño del proyecto
|
|
2438
2454
|
const optimalThreads = Math.min(cpuCount * 2, 24);
|
|
2439
2455
|
if (fileCount > 50 && maxConcurrency < optimalThreads * 0.5) {
|
|
2440
|
-
const
|
|
2441
|
-
logger.warn(
|
|
2442
|
-
logger.info(
|
|
2456
|
+
const chalkLib = await loadChalk();
|
|
2457
|
+
logger.warn(chalkLib.yellow(`⚠️ Solo se usarán ${maxConcurrency} hilos para ${fileCount} archivos.`));
|
|
2458
|
+
logger.info(chalkLib.yellow(` 💡 Tip: export VERSACOMPILER_MAX_THREADS=${optimalThreads}`));
|
|
2443
2459
|
}
|
|
2444
2460
|
// ⚠️ ADVERTENCIA: Si los hilos son muy bajos para el tamaño del proyecto
|
|
2445
2461
|
if (fileCount > 50 && maxConcurrency < 8) {
|