versacompiler 2.1.0 → 2.2.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 +1 -1
- package/dist/compiler/compile.js +2520 -25
- package/dist/compiler/error-reporter.js +467 -38
- package/dist/compiler/linter.js +72 -1
- package/dist/compiler/minify.js +272 -1
- package/dist/compiler/minifyTemplate.js +230 -1
- package/dist/compiler/module-resolution-optimizer.js +844 -1
- package/dist/compiler/parser.js +336 -1
- package/dist/compiler/performance-monitor.js +204 -56
- package/dist/compiler/tailwindcss.js +39 -1
- package/dist/compiler/transform-optimizer.js +392 -1
- package/dist/compiler/transformTStoJS.js +16 -1
- package/dist/compiler/transforms.js +554 -1
- package/dist/compiler/typescript-compiler.js +172 -2
- package/dist/compiler/typescript-error-parser.js +281 -10
- package/dist/compiler/typescript-manager.js +304 -2
- package/dist/compiler/typescript-sync-validator.js +295 -31
- package/dist/compiler/typescript-worker-pool.js +936 -1
- package/dist/compiler/typescript-worker-thread.cjs +466 -22
- package/dist/compiler/typescript-worker.js +339 -1
- package/dist/compiler/vuejs.js +396 -37
- package/dist/hrm/VueHRM.js +359 -1
- package/dist/hrm/errorScreen.js +83 -1
- package/dist/hrm/getInstanciaVue.js +313 -1
- package/dist/hrm/initHRM.js +586 -1
- package/dist/main.js +353 -7
- package/dist/servicios/browserSync.js +589 -2
- package/dist/servicios/file-watcher.js +425 -4
- package/dist/servicios/logger.js +63 -3
- package/dist/servicios/readConfig.js +399 -53
- package/dist/utils/excluded-modules.js +37 -1
- package/dist/utils/module-resolver.js +466 -1
- package/dist/utils/promptUser.js +48 -2
- package/dist/utils/proxyValidator.js +68 -1
- package/dist/utils/resolve-bin.js +58 -1
- package/dist/utils/utils.js +21 -1
- package/dist/utils/vue-types-setup.js +435 -241
- package/dist/wrappers/eslint-node.js +1 -1
- package/dist/wrappers/oxlint-node.js +122 -1
- package/dist/wrappers/tailwind-node.js +94 -1
- package/package.json +106 -103
|
@@ -1,2 +1,172 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import * as process from 'node:process';
|
|
4
|
+
import { env } from 'node:process';
|
|
5
|
+
import * as typescript from 'typescript';
|
|
6
|
+
import { createUnifiedErrorMessage, parseTypeScriptErrors, } from './typescript-error-parser.js';
|
|
7
|
+
import { validateTypesWithLanguageService } from './typescript-sync-validator.js';
|
|
8
|
+
import { TypeScriptWorkerManager } from './typescript-worker.js';
|
|
9
|
+
/**
|
|
10
|
+
* Cache para la configuración de TypeScript para evitar lecturas repetidas
|
|
11
|
+
*/
|
|
12
|
+
let configCache = {};
|
|
13
|
+
/**
|
|
14
|
+
* Carga la configuración de TypeScript desde tsconfig.json
|
|
15
|
+
* @param fileName - Nombre del archivo para buscar el tsconfig.json relativo
|
|
16
|
+
* @returns Opciones del compilador TypeScript
|
|
17
|
+
*/
|
|
18
|
+
export const loadTypeScriptConfig = (fileName) => {
|
|
19
|
+
const fileDir = path.dirname(fileName);
|
|
20
|
+
const configPath = typescript.findConfigFile(fileDir, typescript.sys.fileExists, 'tsconfig.json') || path.resolve(process.cwd(), 'tsconfig.json');
|
|
21
|
+
// Usar cache si el path no ha cambiado
|
|
22
|
+
if (configCache.path === configPath && configCache.options) {
|
|
23
|
+
return configCache.options;
|
|
24
|
+
}
|
|
25
|
+
let compilerOptions;
|
|
26
|
+
if (configPath && fs.existsSync(configPath)) {
|
|
27
|
+
try {
|
|
28
|
+
const { config, error: configError } = typescript.readConfigFile(configPath, typescript.sys.readFile);
|
|
29
|
+
if (!configError) {
|
|
30
|
+
const parsedConfig = typescript.parseJsonConfigFileContent(config, typescript.sys, path.dirname(configPath)); // Usar exactamente la configuración del tsconfig.json del usuario
|
|
31
|
+
compilerOptions = parsedConfig.options;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
throw new Error(`Error al leer tsconfig.json: ${configError.messageText}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.warn(`[loadTypeScriptConfig] Error cargando ${configPath}:`, error);
|
|
39
|
+
// Fallback a opciones por defecto
|
|
40
|
+
compilerOptions = getDefaultCompilerOptions();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// Opciones por defecto si no se encuentra tsconfig.json
|
|
45
|
+
compilerOptions = getDefaultCompilerOptions();
|
|
46
|
+
}
|
|
47
|
+
// Guardar en cache
|
|
48
|
+
configCache = { path: configPath, options: compilerOptions };
|
|
49
|
+
return compilerOptions;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Obtiene las opciones por defecto del compilador TypeScript
|
|
53
|
+
*/
|
|
54
|
+
const getDefaultCompilerOptions = () => ({
|
|
55
|
+
target: typescript.ScriptTarget.ES2020,
|
|
56
|
+
module: typescript.ModuleKind.ES2020,
|
|
57
|
+
lib: ['es2020', 'dom', 'dom.iterable'],
|
|
58
|
+
strict: false,
|
|
59
|
+
skipLibCheck: true,
|
|
60
|
+
allowJs: true,
|
|
61
|
+
esModuleInterop: true,
|
|
62
|
+
allowSyntheticDefaultImports: true,
|
|
63
|
+
isolatedModules: true,
|
|
64
|
+
});
|
|
65
|
+
/**
|
|
66
|
+
* Crea una versión optimizada y serializable de las opciones del compilador typescript.
|
|
67
|
+
* @param options - Opciones originales del compilador
|
|
68
|
+
* @returns Opciones serializables seguras para workers
|
|
69
|
+
*/
|
|
70
|
+
const createSerializableCompilerOptions = (options) => {
|
|
71
|
+
// Respetar completamente la configuración del usuario del tsconfig.json
|
|
72
|
+
return {
|
|
73
|
+
...options,
|
|
74
|
+
// NO modificar configuraciones del usuario - solo optimizaciones internas del worker que no afectan la validación
|
|
75
|
+
declaration: false, // No necesitamos declaraciones en el worker
|
|
76
|
+
sourceMap: false, // No necesitamos source maps en el worker
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Valida tipos en archivos Vue antes de la compilación
|
|
81
|
+
* @param vueContent - Contenido del archivo Vue
|
|
82
|
+
* @param fileName - Nombre del archivo Vue
|
|
83
|
+
* @returns Resultado de la validación de tipos
|
|
84
|
+
*/
|
|
85
|
+
export const validateVueTypes = (vueContent, fileName) => {
|
|
86
|
+
const compilerOptions = loadTypeScriptConfig(fileName);
|
|
87
|
+
return validateTypesWithLanguageService(fileName, vueContent, compilerOptions);
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Precompila el código TypeScript con pipeline optimizado para máxima performance.
|
|
91
|
+
* @param {string} data - El código TypeScript a precompilar.
|
|
92
|
+
* @param {string} fileName - El nombre del archivo que contiene el código typescript.
|
|
93
|
+
* @returns {Promise<CompileResult>} - Un objeto con el código precompilado o un error.
|
|
94
|
+
*/
|
|
95
|
+
export const preCompileTS = async (data, fileName) => {
|
|
96
|
+
try {
|
|
97
|
+
// Validación temprana: contenido vacío
|
|
98
|
+
if (!data.trim()) {
|
|
99
|
+
return { error: null, data: data, lang: 'ts' };
|
|
100
|
+
}
|
|
101
|
+
// Cargar configuración de TypeScript desde tsconfig.json
|
|
102
|
+
const compilerOptions = loadTypeScriptConfig(fileName); // PASO 1: Transpilación rápida con detección de errores críticos
|
|
103
|
+
const transpileResult = typescript.transpileModule(data, {
|
|
104
|
+
compilerOptions: {
|
|
105
|
+
...compilerOptions,
|
|
106
|
+
noLib: true,
|
|
107
|
+
skipLibCheck: true,
|
|
108
|
+
isolatedModules: true,
|
|
109
|
+
},
|
|
110
|
+
fileName,
|
|
111
|
+
reportDiagnostics: true,
|
|
112
|
+
});
|
|
113
|
+
// const transpileResult = traspileTStoJS(
|
|
114
|
+
// fileName,data)
|
|
115
|
+
// Verificar errores críticos de sintaxis
|
|
116
|
+
if (transpileResult.diagnostics?.length) {
|
|
117
|
+
const criticalErrors = transpileResult.diagnostics.filter((diag) => {
|
|
118
|
+
if (diag.category !== typescript.DiagnosticCategory.Error)
|
|
119
|
+
return false;
|
|
120
|
+
const messageText = typescript.flattenDiagnosticMessageText(diag.messageText, '\n');
|
|
121
|
+
// Ignorar errores de módulo no encontrado
|
|
122
|
+
return (!messageText.includes('Cannot find module') &&
|
|
123
|
+
!messageText.includes('Could not find source file') &&
|
|
124
|
+
diag.code !== 2307 &&
|
|
125
|
+
diag.code !== 6059);
|
|
126
|
+
});
|
|
127
|
+
if (criticalErrors.length > 0) {
|
|
128
|
+
const errorMessage = createUnifiedErrorMessage(parseTypeScriptErrors(criticalErrors, fileName, data));
|
|
129
|
+
return {
|
|
130
|
+
error: new Error(errorMessage),
|
|
131
|
+
data: null,
|
|
132
|
+
lang: 'ts',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// PASO 2: Type checking opcional (solo si está habilitado)
|
|
137
|
+
if (env.typeCheck === 'true') {
|
|
138
|
+
try {
|
|
139
|
+
const workerManager = TypeScriptWorkerManager.getInstance();
|
|
140
|
+
const serializableOptions = createSerializableCompilerOptions(compilerOptions);
|
|
141
|
+
const typeCheckResult = await workerManager.typeCheck(fileName, data, serializableOptions);
|
|
142
|
+
if (typeCheckResult.hasErrors) {
|
|
143
|
+
const errorMessage = createUnifiedErrorMessage(parseTypeScriptErrors(typeCheckResult.diagnostics, fileName, data));
|
|
144
|
+
return {
|
|
145
|
+
error: new Error(errorMessage),
|
|
146
|
+
data: null,
|
|
147
|
+
lang: 'ts',
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
catch (typeCheckError) {
|
|
152
|
+
// Type checking falla, pero continuar con transpilación
|
|
153
|
+
console.warn('[preCompileTS] Type checking failed:', typeCheckError);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// PASO 3: Devolver resultado optimizado
|
|
157
|
+
const output = transpileResult.outputText;
|
|
158
|
+
// Limpiar output vacío
|
|
159
|
+
if (output.trim() === 'export {};') {
|
|
160
|
+
return { error: null, data: '', lang: 'ts' };
|
|
161
|
+
}
|
|
162
|
+
return { error: null, data: output, lang: 'ts' };
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
return {
|
|
166
|
+
error: error instanceof Error ? error : new Error('Error desconocido'),
|
|
167
|
+
data: null,
|
|
168
|
+
lang: 'ts',
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
//# sourceMappingURL=typescript-compiler.js.map
|
|
@@ -1,10 +1,281 @@
|
|
|
1
|
-
import*as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import * as typescript from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Parsea errores de TypeScript y los convierte a un formato limpio
|
|
4
|
+
* que incluye solo: archivo, mensaje, severidad y ubicación como ayuda
|
|
5
|
+
*/
|
|
6
|
+
export function parseTypeScriptErrors(diagnostics, fileName, sourceCode) {
|
|
7
|
+
return diagnostics.map(diagnostic => {
|
|
8
|
+
// Usar el mejorador de errores para obtener mensaje detallado
|
|
9
|
+
const enhancedMessage = enhanceErrorMessage(diagnostic, fileName, sourceCode); // Determinar la severidad
|
|
10
|
+
let severity;
|
|
11
|
+
switch (diagnostic.category) {
|
|
12
|
+
case typescript.DiagnosticCategory.Error:
|
|
13
|
+
severity = 'error';
|
|
14
|
+
break;
|
|
15
|
+
case typescript.DiagnosticCategory.Warning:
|
|
16
|
+
severity = 'warning';
|
|
17
|
+
break;
|
|
18
|
+
default:
|
|
19
|
+
severity = 'info';
|
|
20
|
+
break;
|
|
21
|
+
} // Construir información de ubicación limpia
|
|
22
|
+
let help = `Código TS${diagnostic.code}`;
|
|
23
|
+
if (diagnostic.file && diagnostic.start !== undefined) {
|
|
24
|
+
const sourceFile = diagnostic.file;
|
|
25
|
+
// Verificar que el método getLineAndCharacterOfPosition existe (para compatibilidad con mocks)
|
|
26
|
+
if (typeof sourceFile.getLineAndCharacterOfPosition === 'function') {
|
|
27
|
+
try {
|
|
28
|
+
const lineAndChar = sourceFile.getLineAndCharacterOfPosition(diagnostic.start);
|
|
29
|
+
help += ` | Línea ${lineAndChar.line + 1}, Columna ${lineAndChar.character + 1}`;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Si falla, solo mostrar la posición de carácter
|
|
33
|
+
help += ` | Posición ${diagnostic.start}`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Fallback para cuando no está disponible el método (como en tests)
|
|
38
|
+
help += ` | Posición ${diagnostic.start}`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
file: fileName,
|
|
43
|
+
message: enhancedMessage,
|
|
44
|
+
severity,
|
|
45
|
+
help,
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Limpia el mensaje de error eliminando información redundante
|
|
51
|
+
*/
|
|
52
|
+
function cleanErrorMessage(message) {
|
|
53
|
+
return (message
|
|
54
|
+
// Remover prefijos verbosos
|
|
55
|
+
.replace(/^error TS\d+:\s*/i, '')
|
|
56
|
+
// Remover información de archivo duplicada al inicio
|
|
57
|
+
.replace(/^.*\.ts\(\d+,\d+\):\s*/, '')
|
|
58
|
+
// Limpiar espacios múltiples
|
|
59
|
+
.replace(/\s+/g, ' ')
|
|
60
|
+
.trim());
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Mejora significativamente el mensaje de error TypeScript con contexto visual
|
|
64
|
+
*/
|
|
65
|
+
function enhanceErrorMessage(diagnostic, fileName, sourceCode) {
|
|
66
|
+
// Extraer el mensaje del error
|
|
67
|
+
const message = typeof diagnostic.messageText === 'string'
|
|
68
|
+
? diagnostic.messageText
|
|
69
|
+
: typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
|
70
|
+
const enhancedMessage = cleanErrorMessage(message); // Información de ubicación
|
|
71
|
+
let location = `Código TS${diagnostic.code}`;
|
|
72
|
+
let codeContext = '';
|
|
73
|
+
if (diagnostic.file && diagnostic.start !== undefined) {
|
|
74
|
+
const sourceFile = diagnostic.file;
|
|
75
|
+
// Verificar que el método getLineAndCharacterOfPosition existe (para compatibilidad con mocks)
|
|
76
|
+
if (typeof sourceFile.getLineAndCharacterOfPosition === 'function') {
|
|
77
|
+
try {
|
|
78
|
+
const lineAndChar = sourceFile.getLineAndCharacterOfPosition(diagnostic.start);
|
|
79
|
+
const line = lineAndChar.line + 1;
|
|
80
|
+
const column = lineAndChar.character + 1;
|
|
81
|
+
location = `Línea ${line}, Columna ${column} | Código TS${diagnostic.code}`;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Si falla, solo mostrar la posición de carácter
|
|
85
|
+
location = `Posición ${diagnostic.start} | Código TS${diagnostic.code}`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// Fallback para cuando no está disponible el método (como en tests)
|
|
90
|
+
location = `Posición ${diagnostic.start} | Código TS${diagnostic.code}`;
|
|
91
|
+
} // Agregar contexto del código si está disponible
|
|
92
|
+
if ((sourceCode || sourceFile.text) &&
|
|
93
|
+
typeof sourceFile.getLineAndCharacterOfPosition === 'function') {
|
|
94
|
+
try {
|
|
95
|
+
const lineAndChar = sourceFile.getLineAndCharacterOfPosition(diagnostic.start);
|
|
96
|
+
const text = sourceCode || sourceFile.text;
|
|
97
|
+
const lines = text.split('\n');
|
|
98
|
+
const errorLine = lines[lineAndChar.line];
|
|
99
|
+
if (errorLine) {
|
|
100
|
+
// Mostrar hasta 2 líneas antes y después para contexto
|
|
101
|
+
const startLine = Math.max(0, lineAndChar.line - 2);
|
|
102
|
+
const endLine = Math.min(lines.length - 1, lineAndChar.line + 2);
|
|
103
|
+
codeContext = '\n\n📝 Contexto del código:\n';
|
|
104
|
+
for (let i = startLine; i <= endLine; i++) {
|
|
105
|
+
const currentLine = i + 1;
|
|
106
|
+
const lineContent = lines[i] || '';
|
|
107
|
+
const isErrorLine = i === lineAndChar.line;
|
|
108
|
+
if (isErrorLine) {
|
|
109
|
+
codeContext += ` ${currentLine.toString().padStart(3, ' ')} ❌ ${lineContent}\n`;
|
|
110
|
+
// Agregar flecha apuntando al error
|
|
111
|
+
const arrow = ' '.repeat(6 + lineAndChar.character + 1) +
|
|
112
|
+
'^^^';
|
|
113
|
+
codeContext += ` ${arrow}\n`;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
codeContext += ` ${currentLine.toString().padStart(3, ' ')} ${lineContent}\n`;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// Si falla obtener el contexto, continuar sin él
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Agregar sugerencias basadas en el tipo de error
|
|
127
|
+
const suggestions = getErrorSuggestions(diagnostic.code, enhancedMessage);
|
|
128
|
+
const suggestionsText = suggestions.length > 0
|
|
129
|
+
? `\n\n💡 Sugerencias:\n${suggestions.map(s => ` • ${s}`).join('\n')}`
|
|
130
|
+
: '';
|
|
131
|
+
return `${enhancedMessage}\n 📍 ${location}${codeContext}${suggestionsText}`;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Proporciona sugerencias específicas basadas en el código de error TypeScript
|
|
135
|
+
*/
|
|
136
|
+
function getErrorSuggestions(errorCode, message) {
|
|
137
|
+
const suggestions = [];
|
|
138
|
+
switch (errorCode) {
|
|
139
|
+
case 2304: // Cannot find name
|
|
140
|
+
suggestions.push('Verifica que la variable esté declarada');
|
|
141
|
+
suggestions.push('Asegúrate de importar el módulo correspondiente');
|
|
142
|
+
suggestions.push('Revisa la ortografía del nombre');
|
|
143
|
+
break;
|
|
144
|
+
case 2322: // Type assignment error
|
|
145
|
+
suggestions.push('Verifica que los tipos sean compatibles');
|
|
146
|
+
suggestions.push('Considera usar type assertion: valor as TipoEsperado');
|
|
147
|
+
break;
|
|
148
|
+
case 2307: // Cannot find module
|
|
149
|
+
suggestions.push('Verifica que el archivo exista en la ruta especificada');
|
|
150
|
+
suggestions.push('Revisa las rutas en tsconfig.json');
|
|
151
|
+
suggestions.push('Asegúrate de que el paquete esté instalado');
|
|
152
|
+
break;
|
|
153
|
+
case 2451: // Cannot redeclare block-scoped variable
|
|
154
|
+
suggestions.push('Cambia el nombre de la variable');
|
|
155
|
+
suggestions.push('Usa un scope diferente (function, block)');
|
|
156
|
+
break;
|
|
157
|
+
case 7006: // Parameter implicitly has 'any' type
|
|
158
|
+
suggestions.push('Agrega tipos explícitos a los parámetros');
|
|
159
|
+
suggestions.push('Considera habilitar "noImplicitAny": false en tsconfig.json');
|
|
160
|
+
break;
|
|
161
|
+
case 1155: // 'const' declarations must be initialized
|
|
162
|
+
suggestions.push('Agrega un valor inicial: const variable = valor;');
|
|
163
|
+
suggestions.push('O cambia a "let" si quieres asignar después');
|
|
164
|
+
break;
|
|
165
|
+
case 2339: // Property does not exist
|
|
166
|
+
suggestions.push('Verifica que la propiedad exista en el tipo');
|
|
167
|
+
suggestions.push('Considera usar optional chaining: objeto?.propiedad');
|
|
168
|
+
break;
|
|
169
|
+
default:
|
|
170
|
+
// Sugerencias genéricas basadas en el mensaje
|
|
171
|
+
if (message.includes('Cannot find')) {
|
|
172
|
+
suggestions.push('Verifica que el elemento exista y esté importado');
|
|
173
|
+
}
|
|
174
|
+
if (message.includes('Type')) {
|
|
175
|
+
suggestions.push('Revisa la compatibilidad de tipos');
|
|
176
|
+
}
|
|
177
|
+
if (message.includes('missing')) {
|
|
178
|
+
suggestions.push('Agrega el elemento faltante');
|
|
179
|
+
}
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
return suggestions;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Crea un mensaje de error unificado para errores múltiples
|
|
186
|
+
*/
|
|
187
|
+
export function createUnifiedErrorMessage(errors) {
|
|
188
|
+
if (errors.length === 0) {
|
|
189
|
+
return 'Error de TypeScript desconocido';
|
|
190
|
+
}
|
|
191
|
+
if (errors.length === 1) {
|
|
192
|
+
const error = errors[0];
|
|
193
|
+
if (error) {
|
|
194
|
+
return `${error.message}\n └─ ${error.help}`;
|
|
195
|
+
}
|
|
196
|
+
return 'Error de TypeScript desconocido';
|
|
197
|
+
}
|
|
198
|
+
const errorCount = errors.filter(e => e.severity === 'error').length;
|
|
199
|
+
const warningCount = errors.filter(e => e.severity === 'warning').length;
|
|
200
|
+
// Mostrar hasta los primeros 10 errores con detalles
|
|
201
|
+
const maxErrorsToShow = 10;
|
|
202
|
+
const errorsToShow = errors.slice(0, maxErrorsToShow);
|
|
203
|
+
const hasMoreErrors = errors.length > maxErrorsToShow;
|
|
204
|
+
let result = '';
|
|
205
|
+
// Agregar resumen
|
|
206
|
+
let summary = '';
|
|
207
|
+
if (errorCount > 0) {
|
|
208
|
+
summary += `${errorCount} error${errorCount > 1 ? 'es' : ''}`;
|
|
209
|
+
}
|
|
210
|
+
if (warningCount > 0) {
|
|
211
|
+
if (summary)
|
|
212
|
+
summary += ', ';
|
|
213
|
+
summary += `${warningCount} advertencia${warningCount > 1 ? 's' : ''}`;
|
|
214
|
+
}
|
|
215
|
+
result += `TypeScript: ${summary} encontrado${errorCount + warningCount > 1 ? 's' : ''}:\n\n`;
|
|
216
|
+
// Agregar detalles de cada error
|
|
217
|
+
errorsToShow.forEach((error, index) => {
|
|
218
|
+
const icon = error.severity === 'error'
|
|
219
|
+
? '❌'
|
|
220
|
+
: error.severity === 'warning'
|
|
221
|
+
? '⚠️'
|
|
222
|
+
: 'ℹ️';
|
|
223
|
+
result += `${icon} ${error.message}\n`;
|
|
224
|
+
result += ` └─ ${error.help}\n`;
|
|
225
|
+
if (index < errorsToShow.length - 1)
|
|
226
|
+
result += '\n';
|
|
227
|
+
});
|
|
228
|
+
// Si hay más errores, indicarlo
|
|
229
|
+
if (hasMoreErrors) {
|
|
230
|
+
const remainingCount = errors.length - maxErrorsToShow;
|
|
231
|
+
result += `\n... y ${remainingCount} error${remainingCount > 1 ? 'es' : ''} más`;
|
|
232
|
+
}
|
|
233
|
+
return result;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Crea un mensaje de error simplificado para modo normal
|
|
237
|
+
*/
|
|
238
|
+
export function createSimpleErrorMessage(diagnostics, _fileName) {
|
|
239
|
+
if (diagnostics.length === 0)
|
|
240
|
+
return '';
|
|
241
|
+
const firstDiagnostic = diagnostics[0];
|
|
242
|
+
if (!firstDiagnostic)
|
|
243
|
+
return '';
|
|
244
|
+
const message = typescript.flattenDiagnosticMessageText(firstDiagnostic.messageText, '\n');
|
|
245
|
+
// Extraer solo la primera línea del mensaje para simplicidad
|
|
246
|
+
const simplifiedMessage = message.split('\n')[0];
|
|
247
|
+
let location = '';
|
|
248
|
+
if (firstDiagnostic.file && firstDiagnostic.start !== undefined) {
|
|
249
|
+
const sourceFile = firstDiagnostic.file;
|
|
250
|
+
// Verificar que el método getLineAndCharacterOfPosition existe (para compatibilidad con mocks)
|
|
251
|
+
if (typeof sourceFile.getLineAndCharacterOfPosition === 'function') {
|
|
252
|
+
try {
|
|
253
|
+
const lineAndChar = sourceFile.getLineAndCharacterOfPosition(firstDiagnostic.start);
|
|
254
|
+
location = ` (línea ${lineAndChar.line + 1})`;
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
// Si falla, continuar sin información de ubicación
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const errorCount = diagnostics.length;
|
|
262
|
+
const countText = errorCount > 1 ? ` (+${errorCount - 1} más)` : '';
|
|
263
|
+
return `${simplifiedMessage}${location}${countText}`;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Crea un mensaje de error detallado para modo verbose
|
|
267
|
+
*/
|
|
268
|
+
export function createDetailedErrorMessage(diagnostics, fileName, sourceCode) {
|
|
269
|
+
const cleanErrors = parseTypeScriptErrors(diagnostics, fileName, sourceCode);
|
|
270
|
+
return createUnifiedErrorMessage(cleanErrors);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Registra errores de TypeScript en el inventario usando el parser limpio
|
|
274
|
+
*/
|
|
275
|
+
export function registerCleanTypeScriptErrors(diagnostics, fileName, registerInventoryError) {
|
|
276
|
+
const cleanErrors = parseTypeScriptErrors(diagnostics, fileName);
|
|
277
|
+
cleanErrors.forEach(error => {
|
|
278
|
+
registerInventoryError(error.file, error.message, error.severity, error.help);
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=typescript-error-parser.js.map
|