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.
@@ -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
- if (!chalk) {
391
- chalk = (await import('chalk')).default;
392
- }
393
- return chalk;
392
+ return moduleManagerRef().ensureModuleLoaded('chalk');
394
393
  }
395
394
  async function loadLinter() {
396
- if (!ESLint || !OxLint) {
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
- if (!minifyJS) {
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
- if (!getCodeFile) {
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
- if (!generateTailwindCSS) {
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
- if (!estandarizaCode) {
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
- if (!preCompileTS) {
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
- if (!preCompileVue) {
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
- return hash.digest('hex').substring(0, 16);
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
- return createHash('sha256')
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
- // Verificar si el archivo de salida existe
620
- await stat(entry.outputPath);
621
- // Verificar si el contenido ha cambiado
622
- const currentContentHash = await this.generateContentHash(filePath);
623
- if (entry.contentHash !== currentContentHash) {
624
- this.cache.delete(filePath);
625
- return false;
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.envHash !== currentEnvHash) {
636
- this.cache.delete(filePath);
637
- return false;
638
- }
639
- // Verificar si las dependencias han cambiado
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', (path) => {
849
- logger.info(`📦 Nueva dependencia instalada: ${path.split(/[/\\]/).pop()}`);
847
+ nodeModulesWatcher.on('addDir', (dirPath) => {
848
+ logger.info(`📦 Nueva dependencia instalada: ${dirPath.split(/[/\\]/).pop()}`);
850
849
  this.invalidateByDependencyChange();
851
850
  });
852
- nodeModulesWatcher.on('unlinkDir', (path) => {
853
- logger.info(`📦 Dependencia eliminada: ${path.split(/[/\\]/).pop()}`);
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 chalk = await loadChalk();
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(chalk.red(`❌ Error en etapa ${stageColor(stage)} - ${baseName}:`));
1052
- logger.error(chalk.red(errorMessage));
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(chalk.gray(` ${line.trim()}`));
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(chalk.red(`❌ Error en ${stageColor(stage)}: ${baseName}`));
1067
- logger.error(chalk.red(` ${firstLine}`));
1068
- logger.info(chalk.yellow(`💡 Usa --verbose para ver detalles completos`));
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 chalk = await loadChalk();
1091
+ const chalkLib = await loadChalk();
1091
1092
  if (compilationErrors.length === 0 && compilationResults.length === 0) {
1092
- logger.info(chalk.green('✅ No hay errores de compilación para mostrar.'));
1093
+ logger.info(chalkLib.green('✅ No hay errores de compilación para mostrar.'));
1093
1094
  if (totalTime) {
1094
- logger.info(chalk.bold(`\n⏱️ TIEMPO TOTAL DE COMPILACIÓN: ${totalTime}`));
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(chalk.bold.cyan('📊 Resumen de Compilación'));
1102
- logger.info(chalk.gray(summaryLine)); // ⏱️ Tiempo total con formato elegante
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(chalk.bold(`⏱️ Tiempo Total: ${chalk.green(totalTime)}`));
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(chalk.bold.blue('🔧 Estadísticas por Etapa:'));
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 ? chalk.green : chalk.red;
1117
+ const statusColor = result.errors === 0 ? chalkLib.green : chalkLib.red;
1117
1118
  const progressBar = createProgressBarWithPercentage(successRate, 20);
1118
- logger.info(` ${stageIcon} ${chalk.bold(result.stage)}`);
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(` ${chalk.red('⚠')} ${result.errors} ${result.errors === 1 ? 'error' : 'errores'}`);
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(chalk.red(`\n❌ Se encontraron ${compilationErrors.length} errores:`));
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(chalk.cyan(`\n📄 ${fileIndex}. ${baseName}`));
1145
- logger.info(chalk.gray(` Ruta: ${filePath}`));
1146
- logger.info(chalk.yellow(` ${errorCount} errores, ${warningCount} advertencias`));
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(chalk.gray(` ${line.trim()}`));
1157
+ logger.info(chalkLib.gray(` ${line.trim()}`));
1157
1158
  }
1158
1159
  });
1159
1160
  }
1160
1161
  if (error.help) {
1161
- logger.info(chalk.blue(` 💡 ${error.help}`));
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(chalk.bold.cyan(statLine));
1173
- logger.info(chalk.bold.cyan(' 📊 RESUMEN FINAL'));
1174
- logger.info(chalk.bold.cyan(statLine));
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(chalk.bold('🎯 Resultados:'));
1178
- logger.info(` 📁 Archivos afectados: ${chalk.cyan.bold(totalFiles)}`);
1179
- logger.info(` ${totalErrors > 0 ? chalk.red('●') : chalk.green('○')} Errores: ${totalErrors > 0 ? chalk.red.bold(totalErrors) : chalk.green.bold('0')}`);
1180
- logger.info(` ${totalWarnings > 0 ? chalk.yellow('●') : chalk.green('○')} Advertencias: ${totalWarnings > 0 ? chalk.yellow.bold(totalWarnings) : chalk.green.bold('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(chalk.red.bold('🚨 COMPILACIÓN COMPLETADA CON ERRORES'));
1185
- logger.info(chalk.red(' Por favor revisa y corrige los problemas anteriores.'));
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(chalk.yellow.bold('⚠️ COMPILACIÓN COMPLETADA CON ADVERTENCIAS'));
1189
- logger.info(chalk.yellow(' Considera revisar las advertencias anteriores.'));
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(chalk.green.bold('✅ COMPILACIÓN EXITOSA'));
1193
- logger.info(chalk.green(' ¡Todos los archivos se compilaron sin problemas!'));
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(chalk.bold.cyan(statLine));
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(chalk.bold.green(successLine));
1203
- logger.info(chalk.bold.green(' ✨ ÉXITO'));
1204
- logger.info(chalk.bold.green(successLine));
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(chalk.green.bold('🎉 COMPILACIÓN COMPLETADA EXITOSAMENTE'));
1207
- logger.info(chalk.green(' ¡No se encontraron errores ni advertencias!'));
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(chalk.bold.green(successLine));
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 chalk = await loadChalk();
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(chalk.bold.rgb(255, 120, 120)('╭─────────────────────────────────────────────────────────────╮'));
1231
- logger.info(chalk.bold.rgb(255, 120, 120)('│ ') +
1232
- chalk.bold.white('🔍 LINTER REPORT') +
1233
- chalk.bold.rgb(255, 120, 120)(' │'));
1234
- logger.info(chalk.bold.rgb(255, 120, 120)('╰─────────────────────────────────────────────────────────────╯'));
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 ? chalk.red('●') : chalk.green('○');
1237
- const warningIcon = totalWarnings > 0 ? chalk.yellow('●') : chalk.green('○');
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(chalk.bold('📊 Summary:'));
1240
- logger.info(` ${errorIcon} ${chalk.bold(totalErrors)} ${chalk.red('errors')}`);
1241
- logger.info(` ${warningIcon} ${chalk.bold(totalWarnings)} ${chalk.yellow('warnings')}`);
1242
- logger.info(` 📁 ${chalk.bold(totalFiles)} ${chalk.cyan('files')}`);
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(chalk.green.bold('✨ All checks passed! No issues found.'));
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(chalk.gray('─'.repeat(80))); // Separador entre archivos
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(chalk.bold.rgb(255, 120, 120)('╭─────────────────────────────────────────────────────────────╮'));
1260
- logger.info(chalk.bold.rgb(255, 120, 120)('│ ') +
1261
- chalk.bold.white(`Found ${totalErrors + totalWarnings} issues in ${totalFiles} files`) +
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
- chalk.bold.rgb(255, 120, 120)(' │'));
1266
- logger.info(chalk.bold.rgb(255, 120, 120)('╰─────────────────────────────────────────────────────────────╯'));
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 chalk = await loadChalk();
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 ? chalk.red('✕') : chalk.yellow('⚠');
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(chalk.bold(`${statusIcon} ${fileIcon} ${chalk.cyan(path.relative(process.cwd(), filePath))}`));
1286
- logger.info(chalk.gray(` ${errorCount} errors, ${warningCount} warnings`));
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 chalk = await loadChalk();
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 ? chalk.red : chalk.yellow;
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)} ${chalk.bold(error.message)}`;
1309
- const ruleInfo = `${chalk.gray(ruleId)}`;
1310
- const locationInfo = `${chalk.blue(`${line}:${column}`)}`;
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(` ${chalk.gray('at')} ${locationInfo} ${chalk.gray('·')} ${ruleInfo}`);
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(` ${chalk.red('>')} ${chalk.gray(lineNumStr)} ${chalk.gray('│')} ${currentLine}`);
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(` ${chalk.gray(' ')} ${chalk.gray(' '.repeat(maxLineNumWidth))} ${chalk.gray('│')} ${pointer}`);
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(` ${chalk.gray(' ')} ${chalk.gray(lineNumStr)} ${chalk.gray('│')} ${chalk.gray(currentLine)}`);
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(` ${chalk.gray('│')} ${chalk.gray('(Unable to read file content)')}`);
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(` ${chalk.blue('💡')} ${chalk.blue('Help:')} ${chalk.gray(helpText)}`);
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 chalk = await loadChalk();
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 = `${chalk.red(icon)} ${chalk.cyan(`${error.from}(${ruleInfo.replace(/^Regla \w+: /, '')})`)}: ${error.message}`;
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(chalk.blue(` ╭─[${filePath}:${line}:${column}]`));
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(chalk.blue(` ${prefix} │ `) + currentLine);
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
- chalk.red('───────┬──────');
1398
- logger.info(chalk.blue(indent + '·') + pointer);
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(chalk.blue(indent + '·') +
1402
+ logger.info(chalkLib.blue(indent + '·') +
1402
1403
  messageIndent +
1403
- chalk.red('╰── ') +
1404
- chalk.gray(getErrorLocationMessage(error)));
1404
+ chalkLib.red('╰── ') +
1405
+ chalkLib.gray(getErrorLocationMessage(error)));
1405
1406
  }
1406
1407
  else {
1407
1408
  // Líneas de contexto
1408
- logger.info(chalk.blue(` ${prefix} │ `) + chalk.gray(currentLine));
1409
+ logger.info(chalkLib.blue(` ${prefix} │ `) + chalkLib.gray(currentLine));
1409
1410
  }
1410
1411
  }
1411
- logger.info(chalk.blue(' ╰────'));
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(chalk.blue(` ╭─[${filePath}:${line}:${column}]`));
1417
- logger.info(chalk.blue(' │ ') +
1418
- chalk.gray('(No se pudo leer el contenido del archivo)'));
1419
- logger.info(chalk.blue(' ╰────'));
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(chalk.blue(' help: ') + chalk.yellow(helpMessage));
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 chalk = await loadChalk();
1454
+ const chalkLib = await loadChalk();
1454
1455
  switch (stage) {
1455
1456
  case 'vue':
1456
- return chalk.green;
1457
+ return chalkLib.green;
1457
1458
  case 'typescript':
1458
- return chalk.blue;
1459
+ return chalkLib.blue;
1459
1460
  case 'standardization':
1460
- return chalk.yellow;
1461
+ return chalkLib.yellow;
1461
1462
  case 'minification':
1462
- return chalk.red;
1463
+ return chalkLib.red;
1463
1464
  case 'tailwind':
1464
- return chalk.magenta;
1465
+ return chalkLib.magenta;
1465
1466
  case 'file-read':
1466
- return chalk.gray;
1467
+ return chalkLib.gray;
1467
1468
  default:
1468
- return chalk.white;
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 getCodeFile = await loadParser();
1572
- const result = await getCodeFile(inPath);
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 preCompileVue = await loadVue();
1597
- if (typeof preCompileVue !== 'function') {
1598
- throw new Error(`loadVue devolvió ${typeof preCompileVue} en lugar de una función para archivo: ${inPath}`);
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 preCompileVue(code, inPath, env.isPROD === 'true');
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 preCompileTS = await loadTypeScript();
1630
- if (typeof preCompileTS !== 'function') {
1631
- throw new Error(`loadTypeScript devolvió ${typeof preCompileTS} en lugar de una función para archivo: ${inPath}`);
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 preCompileTS(code, inPath, vueResult?.scriptInfo);
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 estandarizaCode = await loadTransforms();
1669
- const resultSTD = await estandarizaCode(code, inPath);
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 minifyJS = await loadMinify();
1693
- const resultMinify = await minifyJS(code, inPath, true);
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 generateTailwindCSS = await loadTailwind();
1745
- const resultTW = await generateTailwindCSS();
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 chalk = await loadChalk();
1793
- logger.info(chalk.green(`✅ Compilación exitosa: ${path.basename(file)}`));
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 = ESLint(item)
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 = OxLint(item)
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 chalk = await loadChalk();
2144
- logger.info(chalk.green('✅ No se encontraron errores ni advertencias de linting.'));
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 generateTailwindCSS = await loadTailwind();
2349
- const resultTW = await generateTailwindCSS();
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 chalk = await loadChalk();
2441
- logger.warn(chalk.yellow(`⚠️ Solo se usarán ${maxConcurrency} hilos para ${fileCount} archivos.`));
2442
- logger.info(chalk.yellow(` 💡 Tip: export VERSACOMPILER_MAX_THREADS=${optimalThreads}`));
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) {