versacompiler 2.1.0 → 2.3.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.
Files changed (41) hide show
  1. package/README.md +1 -1
  2. package/dist/compiler/compile.js +2520 -25
  3. package/dist/compiler/error-reporter.js +467 -38
  4. package/dist/compiler/linter.js +72 -1
  5. package/dist/compiler/minify.js +272 -1
  6. package/dist/compiler/minifyTemplate.js +230 -1
  7. package/dist/compiler/module-resolution-optimizer.js +888 -1
  8. package/dist/compiler/parser.js +336 -1
  9. package/dist/compiler/performance-monitor.js +204 -56
  10. package/dist/compiler/tailwindcss.js +39 -1
  11. package/dist/compiler/transform-optimizer.js +392 -1
  12. package/dist/compiler/transformTStoJS.js +16 -1
  13. package/dist/compiler/transforms.js +554 -1
  14. package/dist/compiler/typescript-compiler.js +172 -2
  15. package/dist/compiler/typescript-error-parser.js +281 -10
  16. package/dist/compiler/typescript-manager.js +304 -2
  17. package/dist/compiler/typescript-sync-validator.js +295 -31
  18. package/dist/compiler/typescript-worker-pool.js +936 -1
  19. package/dist/compiler/typescript-worker-thread.cjs +466 -22
  20. package/dist/compiler/typescript-worker.js +339 -1
  21. package/dist/compiler/vuejs.js +396 -37
  22. package/dist/hrm/VueHRM.js +359 -1
  23. package/dist/hrm/errorScreen.js +83 -1
  24. package/dist/hrm/getInstanciaVue.js +313 -1
  25. package/dist/hrm/initHRM.js +586 -1
  26. package/dist/main.js +353 -7
  27. package/dist/servicios/browserSync.js +589 -2
  28. package/dist/servicios/file-watcher.js +425 -4
  29. package/dist/servicios/logger.js +63 -3
  30. package/dist/servicios/readConfig.js +399 -53
  31. package/dist/utils/excluded-modules.js +37 -1
  32. package/dist/utils/module-resolver.js +552 -1
  33. package/dist/utils/promptUser.js +48 -2
  34. package/dist/utils/proxyValidator.js +68 -1
  35. package/dist/utils/resolve-bin.js +58 -1
  36. package/dist/utils/utils.js +21 -1
  37. package/dist/utils/vue-types-setup.js +435 -241
  38. package/dist/wrappers/eslint-node.js +1 -1
  39. package/dist/wrappers/oxlint-node.js +122 -1
  40. package/dist/wrappers/tailwind-node.js +94 -1
  41. package/package.json +109 -104
@@ -1,2 +1,172 @@
1
- import e from"node:fs";import i from"node:path";import*as a from"node:process";import{env as o}from"node:process";import*as s from"typescript";import{createUnifiedErrorMessage as c,parseTypeScriptErrors as l}from"./typescript-error-parser.js";import{validateTypesWithLanguageService as u}from"./typescript-sync-validator.js";import{TypeScriptWorkerManager as d}from"./typescript-worker.js";let f={};export const loadTypeScriptConfig=o=>{let c=i.dirname(o),l=s.findConfigFile(c,s.sys.fileExists,`tsconfig.json`)||i.resolve(a.cwd(),`tsconfig.json`);if(f.path===l&&f.options)return f.options;let u;if(l&&e.existsSync(l))try{let{config:e,error:a}=s.readConfigFile(l,s.sys.readFile);if(!a)u=s.parseJsonConfigFileContent(e,s.sys,i.dirname(l)).options;else throw Error(`Error al leer tsconfig.json: ${a.messageText}`)}catch(e){console.warn(`[loadTypeScriptConfig] Error cargando ${l}:`,e),u=p()}else u=p();return f={path:l,options:u},u};const p=()=>({target:s.ScriptTarget.ES2020,module:s.ModuleKind.ES2020,lib:[`es2020`,`dom`,`dom.iterable`],strict:!1,skipLibCheck:!0,allowJs:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,isolatedModules:!0}),m=e=>({...e,declaration:!1,sourceMap:!1});export const validateVueTypes=(e,i)=>u(i,e,loadTypeScriptConfig(i));export const preCompileTS=async(e,i)=>{try{if(!e.trim())return{error:null,data:e,lang:`ts`};let a=loadTypeScriptConfig(i),u=s.transpileModule(e,{compilerOptions:{...a,noLib:!0,skipLibCheck:!0,isolatedModules:!0},fileName:i,reportDiagnostics:!0});if(u.diagnostics?.length){let a=u.diagnostics.filter(e=>{if(e.category!==s.DiagnosticCategory.Error)return!1;let i=s.flattenDiagnosticMessageText(e.messageText,`
2
- `);return!i.includes(`Cannot find module`)&&!i.includes(`Could not find source file`)&&e.code!==2307&&e.code!==6059});if(a.length>0){let o=c(l(a,i,e));return{error:Error(o),data:null,lang:`ts`}}}if(o.typeCheck===`true`)try{let o=d.getInstance(),s=m(a),u=await o.typeCheck(i,e,s);if(u.hasErrors){let a=c(l(u.diagnostics,i,e));return{error:Error(a),data:null,lang:`ts`}}}catch(e){console.warn(`[preCompileTS] Type checking failed:`,e)}let f=u.outputText;return f.trim()===`export {};`?{error:null,data:``,lang:`ts`}:{error:null,data:f,lang:`ts`}}catch(e){return{error:e instanceof Error?e:Error(`Error desconocido`),data:null,lang:`ts`}}};
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 e from"typescript";export function parseTypeScriptErrors(t,n,i){return t.map(t=>{let a=r(t,n,i),o;switch(t.category){case e.DiagnosticCategory.Error:o=`error`;break;case e.DiagnosticCategory.Warning:o=`warning`;break;default:o=`info`;break}let s=`Código TS${t.code}`;if(t.file&&t.start!==void 0){let e=t.file;if(typeof e.getLineAndCharacterOfPosition==`function`)try{let n=e.getLineAndCharacterOfPosition(t.start);s+=` | Línea ${n.line+1}, Columna ${n.character+1}`}catch{s+=` | Posición ${t.start}`}else s+=` | Posición ${t.start}`}return{file:n,message:a,severity:o,help:s}})}function n(e){return e.replace(/^error TS\d+:\s*/i,``).replace(/^.*\.ts\(\d+,\d+\):\s*/,``).replace(/\s+/g,` `).trim()}function r(t,r,a){let o=n(typeof t.messageText==`string`?t.messageText:e.flattenDiagnosticMessageText(t.messageText,`
2
- `)),s=`Código TS${t.code}`,c=``;if(t.file&&t.start!==void 0){let e=t.file;if(typeof e.getLineAndCharacterOfPosition==`function`)try{let n=e.getLineAndCharacterOfPosition(t.start);s=`Línea ${n.line+1}, Columna ${n.character+1} | Código TS${t.code}`}catch{s=`Posición ${t.start} | Código TS${t.code}`}else s=`Posición ${t.start} | Código TS${t.code}`;if((a||e.text)&&typeof e.getLineAndCharacterOfPosition==`function`)try{let n=e.getLineAndCharacterOfPosition(t.start),r=(a||e.text).split(`
3
- `);if(r[n.line]){let e=Math.max(0,n.line-2),t=Math.min(r.length-1,n.line+2);c=`
4
-
5
- 📝 Contexto del código:
6
- `;for(let i=e;i<=t;i++){let e=i+1,t=r[i]||``;if(i===n.line){c+=` ${e.toString().padStart(3,` `)} ❌ ${t}\n`;let r=` `.repeat(6+n.character+1)+`^^^`;c+=` ${r}\n`}else c+=` ${e.toString().padStart(3,` `)} ${t}\n`}}}catch{}}let l=i(t.code,o),u=l.length>0?`\n\n💡 Sugerencias:\n${l.map(e=>` • ${e}`).join(`
7
- `)}`:``;return`${o}\n 📍 ${s}${c}${u}`}function i(e,t){let n=[];switch(e){case 2304:n.push(`Verifica que la variable esté declarada`),n.push(`Asegúrate de importar el módulo correspondiente`),n.push(`Revisa la ortografía del nombre`);break;case 2322:n.push(`Verifica que los tipos sean compatibles`),n.push(`Considera usar type assertion: valor as TipoEsperado`);break;case 2307:n.push(`Verifica que el archivo exista en la ruta especificada`),n.push(`Revisa las rutas en tsconfig.json`),n.push(`Asegúrate de que el paquete esté instalado`);break;case 2451:n.push(`Cambia el nombre de la variable`),n.push(`Usa un scope diferente (function, block)`);break;case 7006:n.push(`Agrega tipos explícitos a los parámetros`),n.push(`Considera habilitar "noImplicitAny": false en tsconfig.json`);break;case 1155:n.push(`Agrega un valor inicial: const variable = valor;`),n.push(`O cambia a "let" si quieres asignar después`);break;case 2339:n.push(`Verifica que la propiedad exista en el tipo`),n.push(`Considera usar optional chaining: objeto?.propiedad`);break;default:t.includes(`Cannot find`)&&n.push(`Verifica que el elemento exista y esté importado`),t.includes(`Type`)&&n.push(`Revisa la compatibilidad de tipos`),t.includes(`missing`)&&n.push(`Agrega el elemento faltante`);break}return n}export function createUnifiedErrorMessage(e){if(e.length===0)return`Error de TypeScript desconocido`;if(e.length===1){let t=e[0];return t?`${t.message}\n └─ ${t.help}`:`Error de TypeScript desconocido`}let t=e.filter(e=>e.severity===`error`).length,n=e.filter(e=>e.severity===`warning`).length,r=e.slice(0,10),i=e.length>10,a=``,o=``;if(t>0&&(o+=`${t} error${t>1?`es`:``}`),n>0&&(o&&(o+=`, `),o+=`${n} advertencia${n>1?`s`:``}`),a+=`TypeScript: ${o} encontrado${t+n>1?`s`:``}:\n\n`,r.forEach((e,t)=>{let n=e.severity===`error`?`❌`:e.severity===`warning`?`⚠️`:`ℹ️`;a+=`${n} ${e.message}\n`,a+=` └─ ${e.help}\n`,t<r.length-1&&(a+=`
8
- `)}),i){let t=e.length-10;a+=`\n... y ${t} error${t>1?`es`:``} más`}return a}export function createSimpleErrorMessage(t,n){if(t.length===0)return``;let r=t[0];if(!r)return``;let i=e.flattenDiagnosticMessageText(r.messageText,`
9
- `).split(`
10
- `)[0],a=``;if(r.file&&r.start!==void 0){let e=r.file;if(typeof e.getLineAndCharacterOfPosition==`function`)try{a=` (línea ${e.getLineAndCharacterOfPosition(r.start).line+1})`}catch{}}let o=t.length,s=o>1?` (+${o-1} más)`:``;return`${i}${a}${s}`}export function createDetailedErrorMessage(e,n,r){return createUnifiedErrorMessage(parseTypeScriptErrors(e,n,r))}export function registerCleanTypeScriptErrors(e,n,r){parseTypeScriptErrors(e,n).forEach(e=>{r(e.file,e.message,e.severity,e.help)})}
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