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,38 +1,467 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
1
|
+
// Lazy loading optimizations - Only import lightweight modules synchronously
|
|
2
|
+
// Heavy dependencies will be loaded dynamically when needed
|
|
3
|
+
let chalk;
|
|
4
|
+
// Función que proporciona chalk sin color como fallback
|
|
5
|
+
function createChalkFallback() {
|
|
6
|
+
// Crear una función que siempre retorna el texto sin modificar
|
|
7
|
+
function createChainableFunction() {
|
|
8
|
+
const fn = (text) => String(text);
|
|
9
|
+
// Lista de métodos de chalk que deben ser encadenables
|
|
10
|
+
const methods = [
|
|
11
|
+
'reset',
|
|
12
|
+
'bold',
|
|
13
|
+
'dim',
|
|
14
|
+
'italic',
|
|
15
|
+
'underline',
|
|
16
|
+
'strikethrough',
|
|
17
|
+
'inverse',
|
|
18
|
+
'hidden',
|
|
19
|
+
'visible',
|
|
20
|
+
'black',
|
|
21
|
+
'red',
|
|
22
|
+
'green',
|
|
23
|
+
'yellow',
|
|
24
|
+
'blue',
|
|
25
|
+
'magenta',
|
|
26
|
+
'cyan',
|
|
27
|
+
'white',
|
|
28
|
+
'gray',
|
|
29
|
+
'grey',
|
|
30
|
+
'blackBright',
|
|
31
|
+
'redBright',
|
|
32
|
+
'greenBright',
|
|
33
|
+
'yellowBright',
|
|
34
|
+
'blueBright',
|
|
35
|
+
'magentaBright',
|
|
36
|
+
'cyanBright',
|
|
37
|
+
'whiteBright',
|
|
38
|
+
'bgBlack',
|
|
39
|
+
'bgRed',
|
|
40
|
+
'bgGreen',
|
|
41
|
+
'bgYellow',
|
|
42
|
+
'bgBlue',
|
|
43
|
+
'bgMagenta',
|
|
44
|
+
'bgCyan',
|
|
45
|
+
'bgWhite',
|
|
46
|
+
'bgGray',
|
|
47
|
+
'bgGrey',
|
|
48
|
+
'bgBlackBright',
|
|
49
|
+
'bgRedBright',
|
|
50
|
+
'bgGreenBright',
|
|
51
|
+
'bgYellowBright',
|
|
52
|
+
'bgBlueBright',
|
|
53
|
+
'bgMagentaBright',
|
|
54
|
+
'bgCyanBright',
|
|
55
|
+
'bgWhiteBright',
|
|
56
|
+
];
|
|
57
|
+
// Añadir todos los métodos como propiedades que retornan nuevas funciones encadenables
|
|
58
|
+
methods.forEach(method => {
|
|
59
|
+
Object.defineProperty(fn, method, {
|
|
60
|
+
get() {
|
|
61
|
+
return createChainableFunction();
|
|
62
|
+
},
|
|
63
|
+
enumerable: true,
|
|
64
|
+
configurable: true,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
// Hacer que la función misma sea callable
|
|
68
|
+
return new Proxy(fn, {
|
|
69
|
+
apply(target, thisArg, argumentsList) {
|
|
70
|
+
return String(argumentsList[0] || '');
|
|
71
|
+
},
|
|
72
|
+
get(target, prop) {
|
|
73
|
+
// Verificar si es una propiedad de la función
|
|
74
|
+
if (typeof prop === 'string' || typeof prop === 'symbol') {
|
|
75
|
+
// Si es un método de chalk, retorna una nueva función encadenable
|
|
76
|
+
if (typeof prop === 'string' && methods.includes(prop)) {
|
|
77
|
+
return createChainableFunction();
|
|
78
|
+
}
|
|
79
|
+
// Retornar propiedades existentes de la función
|
|
80
|
+
return target[prop];
|
|
81
|
+
}
|
|
82
|
+
return undefined;
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return createChainableFunction();
|
|
87
|
+
}
|
|
88
|
+
// Obtener chalk de forma síncrona con fallback
|
|
89
|
+
function getChalkSync() {
|
|
90
|
+
if (!chalk) {
|
|
91
|
+
// Si no tenemos chalk cargado, usar fallback
|
|
92
|
+
chalk = createChalkFallback();
|
|
93
|
+
}
|
|
94
|
+
return chalk;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Clase para generar reportes detallados de errores de parsing
|
|
98
|
+
*/
|
|
99
|
+
export class ErrorReporter {
|
|
100
|
+
options;
|
|
101
|
+
constructor(options = {}) {
|
|
102
|
+
this.options = {
|
|
103
|
+
showLineNumbers: options.showLineNumbers ?? true,
|
|
104
|
+
showCodeContext: options.showCodeContext ?? true,
|
|
105
|
+
contextLines: options.contextLines ?? 2,
|
|
106
|
+
colorize: options.colorize ?? true,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Analiza un error de oxc-parser y extrae información detallada
|
|
111
|
+
*/
|
|
112
|
+
analyzeParsingError(error, sourceCode, fileName) {
|
|
113
|
+
const detailedError = {
|
|
114
|
+
file: fileName,
|
|
115
|
+
message: error.message || 'Error de parsing desconocido',
|
|
116
|
+
severity: 'error',
|
|
117
|
+
};
|
|
118
|
+
// Intentar extraer información de ubicación del error
|
|
119
|
+
if (error.labels && error.labels.length > 0) {
|
|
120
|
+
// oxc-parser proporciona información en labels
|
|
121
|
+
const label = error.labels[0];
|
|
122
|
+
if (label.start !== undefined) {
|
|
123
|
+
const position = this.getLineAndColumnFromOffset(sourceCode, label.start);
|
|
124
|
+
detailedError.line = position.line;
|
|
125
|
+
detailedError.column = position.column;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else if (error.span) {
|
|
129
|
+
// oxc-parser también puede proporcionar información de span
|
|
130
|
+
const position = this.getLineAndColumnFromSpan(sourceCode, error.span.start);
|
|
131
|
+
detailedError.line = position.line;
|
|
132
|
+
detailedError.column = position.column;
|
|
133
|
+
}
|
|
134
|
+
else if (error.offset !== undefined) {
|
|
135
|
+
// Si tenemos un offset, calculamos línea y columna
|
|
136
|
+
const position = this.getLineAndColumnFromOffset(sourceCode, error.offset);
|
|
137
|
+
detailedError.line = position.line;
|
|
138
|
+
detailedError.column = position.column;
|
|
139
|
+
}
|
|
140
|
+
// Agregar contexto del código si está disponible
|
|
141
|
+
if (this.options.showCodeContext && detailedError.line && sourceCode) {
|
|
142
|
+
detailedError.codeContext = this.generateCodeContext(sourceCode, detailedError.line, detailedError.column);
|
|
143
|
+
}
|
|
144
|
+
// Detectar patrones específicos de errores para sugerencias más inteligentes
|
|
145
|
+
detailedError.suggestion = this.generateIntelligentSuggestion(error.message, sourceCode, detailedError.line, detailedError.column);
|
|
146
|
+
// Extraer código de error si está disponible
|
|
147
|
+
if (error.code) {
|
|
148
|
+
detailedError.errorCode = error.code;
|
|
149
|
+
}
|
|
150
|
+
// Si oxc-parser ya proporciona un codeframe, usarlo como referencia adicional
|
|
151
|
+
if (error.codeframe) {
|
|
152
|
+
detailedError.codeContext = this.combineWithOxcCodeframe(detailedError.codeContext, error.codeframe);
|
|
153
|
+
}
|
|
154
|
+
return detailedError;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Calcula línea y columna desde un span de oxc-parser
|
|
158
|
+
*/
|
|
159
|
+
getLineAndColumnFromSpan(sourceCode, spanStart) {
|
|
160
|
+
return this.getLineAndColumnFromOffset(sourceCode, spanStart);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Calcula línea y columna desde un offset
|
|
164
|
+
*/
|
|
165
|
+
getLineAndColumnFromOffset(sourceCode, offset) {
|
|
166
|
+
const lines = sourceCode.split('\n');
|
|
167
|
+
let currentOffset = 0;
|
|
168
|
+
let line = 1;
|
|
169
|
+
let column = 1;
|
|
170
|
+
for (let i = 0; i < lines.length; i++) {
|
|
171
|
+
const currentLine = lines[i];
|
|
172
|
+
if (currentLine === undefined)
|
|
173
|
+
continue;
|
|
174
|
+
const lineLength = currentLine.length + 1; // +1 para el \n
|
|
175
|
+
if (currentOffset + lineLength > offset) {
|
|
176
|
+
line = i + 1;
|
|
177
|
+
column = offset - currentOffset + 1;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
currentOffset += lineLength;
|
|
181
|
+
}
|
|
182
|
+
return { line, column };
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Genera contexto del código alrededor del error
|
|
186
|
+
*/
|
|
187
|
+
generateCodeContext(sourceCode, errorLine, errorColumn) {
|
|
188
|
+
const lines = sourceCode.split('\n');
|
|
189
|
+
const startLine = Math.max(1, errorLine - this.options.contextLines);
|
|
190
|
+
const endLine = Math.min(lines.length, errorLine + this.options.contextLines);
|
|
191
|
+
const chalkSync = getChalkSync();
|
|
192
|
+
let context = '\n' + chalkSync.dim('Contexto del código:') + '\n';
|
|
193
|
+
for (let i = startLine; i <= endLine; i++) {
|
|
194
|
+
const lineContent = lines[i - 1] || '';
|
|
195
|
+
const lineNumber = i.toString().padStart(3, ' ');
|
|
196
|
+
const isErrorLine = i === errorLine;
|
|
197
|
+
if (isErrorLine) {
|
|
198
|
+
if (this.options.colorize) {
|
|
199
|
+
context += chalkSync.red(`${lineNumber} ❌ ${lineContent}\n`);
|
|
200
|
+
// Agregar flecha apuntando al error si tenemos la columna
|
|
201
|
+
if (errorColumn) {
|
|
202
|
+
const spaces = ' '.repeat(6 + (errorColumn - 1));
|
|
203
|
+
const arrow = chalkSync.red('^');
|
|
204
|
+
context += `${spaces}${arrow}\n`;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
context += `${lineNumber} ❌ ${lineContent}\n`;
|
|
209
|
+
if (errorColumn) {
|
|
210
|
+
const spaces = ' '.repeat(6 + (errorColumn - 1));
|
|
211
|
+
context += `${spaces}^\n`;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
const prefix = this.options.colorize
|
|
217
|
+
? chalkSync.dim
|
|
218
|
+
: (s) => s;
|
|
219
|
+
context += prefix(`${lineNumber} ${lineContent}\n`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return context;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Genera sugerencias basadas en el mensaje de error
|
|
226
|
+
*/
|
|
227
|
+
generateSuggestion(errorMessage) {
|
|
228
|
+
const message = errorMessage.toLowerCase();
|
|
229
|
+
if (message.includes('unexpected') && message.includes('identifier')) {
|
|
230
|
+
return 'Verifica si hay una coma faltante antes del identificador o si la línea anterior no está completa.';
|
|
231
|
+
}
|
|
232
|
+
if (message.includes('expected') && message.includes('but found')) {
|
|
233
|
+
return 'Revisa la sintaxis alrededor de este punto. Puede faltar un carácter específico.';
|
|
234
|
+
}
|
|
235
|
+
if (message.includes('missing')) {
|
|
236
|
+
if (message.includes('semicolon')) {
|
|
237
|
+
return 'Agrega un punto y coma (;) al final de la declaración.';
|
|
238
|
+
}
|
|
239
|
+
if (message.includes('comma')) {
|
|
240
|
+
return 'Verifica si falta una coma (,) en una lista o declaración.';
|
|
241
|
+
}
|
|
242
|
+
if (message.includes('parenthesis')) {
|
|
243
|
+
return 'Verifica que los paréntesis estén balanceados.';
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (message.includes('import') || message.includes('export')) {
|
|
247
|
+
return 'Revisa la sintaxis de import/export. Las líneas pueden estar cortadas o malformadas.';
|
|
248
|
+
}
|
|
249
|
+
if (message.includes('const') && message.includes('initializer')) {
|
|
250
|
+
return 'Las declaraciones const requieren un valor inicial. Ejemplos válidos:\n • const variable = "valor";\n • const numero = 42;\n • const objeto = { propiedad: "valor" };';
|
|
251
|
+
}
|
|
252
|
+
return 'Revisa la sintaxis del código alrededor de esta ubicación.';
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Combina nuestro contexto de código con el codeframe de oxc-parser
|
|
256
|
+
*/
|
|
257
|
+
combineWithOxcCodeframe(ourContext, oxcCodeframe) {
|
|
258
|
+
if (!ourContext) {
|
|
259
|
+
return oxcCodeframe;
|
|
260
|
+
}
|
|
261
|
+
// Si ya tenemos nuestro contexto, podemos agregar el de oxc como referencia adicional
|
|
262
|
+
const chalkSync = getChalkSync();
|
|
263
|
+
return (ourContext +
|
|
264
|
+
'\n' +
|
|
265
|
+
chalkSync.dim('Codeframe de oxc-parser:') +
|
|
266
|
+
'\n' +
|
|
267
|
+
oxcCodeframe);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Formatea un error detallado como texto legible
|
|
271
|
+
*/
|
|
272
|
+
formatError(error) {
|
|
273
|
+
let output = '';
|
|
274
|
+
// Encabezado del error
|
|
275
|
+
const severity = error.severity.toUpperCase();
|
|
276
|
+
const chalkSync = getChalkSync();
|
|
277
|
+
const severityColor = error.severity === 'error'
|
|
278
|
+
? chalkSync.red
|
|
279
|
+
: error.severity === 'warning'
|
|
280
|
+
? chalkSync.yellow
|
|
281
|
+
: chalkSync.blue;
|
|
282
|
+
if (this.options.colorize) {
|
|
283
|
+
output +=
|
|
284
|
+
severityColor(`[${severity}]`) +
|
|
285
|
+
` en ${chalkSync.cyan(error.file)}`;
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
output += `[${severity}] en ${error.file}`;
|
|
289
|
+
}
|
|
290
|
+
// Ubicación específica
|
|
291
|
+
if (error.line) {
|
|
292
|
+
const location = error.column
|
|
293
|
+
? `línea ${error.line}, columna ${error.column}`
|
|
294
|
+
: `línea ${error.line}`;
|
|
295
|
+
if (this.options.colorize) {
|
|
296
|
+
output += ` (${chalkSync.dim(location)})`;
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
output += ` (${location})`;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
output += '\n';
|
|
303
|
+
// Mensaje de error
|
|
304
|
+
if (this.options.colorize) {
|
|
305
|
+
output += `💥 ${chalkSync.bold(error.message)}\n`;
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
output += `💥 ${error.message}\n`;
|
|
309
|
+
}
|
|
310
|
+
// Código de error si está disponible
|
|
311
|
+
if (error.errorCode) {
|
|
312
|
+
if (this.options.colorize) {
|
|
313
|
+
output += chalkSync.dim(` Código: ${error.errorCode}\n`);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
output += ` Código: ${error.errorCode}\n`;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
// Contexto del código
|
|
320
|
+
if (error.codeContext) {
|
|
321
|
+
output += error.codeContext;
|
|
322
|
+
}
|
|
323
|
+
// Sugerencia
|
|
324
|
+
if (error.suggestion) {
|
|
325
|
+
if (this.options.colorize) {
|
|
326
|
+
output += `\n💡 ${chalkSync.yellow('Sugerencia:')} ${error.suggestion}\n`;
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
output += `\n💡 Sugerencia: ${error.suggestion}\n`;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return output;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Analiza múltiples errores de un resultado de parsing
|
|
336
|
+
*/
|
|
337
|
+
analyzeMultipleErrors(errors, sourceCode, fileName) {
|
|
338
|
+
return errors.map(error => this.analyzeParsingError(error, sourceCode, fileName));
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Formatea múltiples errores como un reporte completo
|
|
342
|
+
*/
|
|
343
|
+
formatMultipleErrors(errors) {
|
|
344
|
+
if (errors.length === 0) {
|
|
345
|
+
return 'No se encontraron errores.';
|
|
346
|
+
}
|
|
347
|
+
const chalkSync = getChalkSync();
|
|
348
|
+
let output = '';
|
|
349
|
+
if (this.options.colorize) {
|
|
350
|
+
output += chalkSync.bold.red(`\n🚨 Se encontraron ${errors.length} error(es) de parsing:\n\n`);
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
output += `\n🚨 Se encontraron ${errors.length} error(es) de parsing:\n\n`;
|
|
354
|
+
}
|
|
355
|
+
errors.forEach((error, index) => {
|
|
356
|
+
output += this.formatError(error);
|
|
357
|
+
// Separador entre errores (excepto el último)
|
|
358
|
+
if (index < errors.length - 1) {
|
|
359
|
+
if (this.options.colorize) {
|
|
360
|
+
output += chalkSync.dim('─'.repeat(60)) + '\n\n';
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
output += '─'.repeat(60) + '\n\n';
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
return output;
|
|
368
|
+
} /**
|
|
369
|
+
* Genera sugerencias más inteligentes basadas en análisis contextual del error
|
|
370
|
+
*/
|
|
371
|
+
generateIntelligentSuggestion(errorMessage, sourceCode, line, _column) {
|
|
372
|
+
const message = errorMessage.toLowerCase();
|
|
373
|
+
// Análisis contextual del código si tenemos la línea
|
|
374
|
+
if (line && sourceCode) {
|
|
375
|
+
const lines = sourceCode.split('\n');
|
|
376
|
+
const errorLine = lines[line - 1] || '';
|
|
377
|
+
const prevLine = line > 1 ? lines[line - 2] || '' : '';
|
|
378
|
+
// Análisis específico para declaraciones const
|
|
379
|
+
if (message.includes('const') && message.includes('initializer')) {
|
|
380
|
+
// Detectar el tipo de error específico analizando el contexto
|
|
381
|
+
if (errorLine
|
|
382
|
+
.trim()
|
|
383
|
+
.match(/^const\s+[a-zA-Z_][a-zA-Z0-9_]*\s*;/)) {
|
|
384
|
+
return ('Declaración const incompleta. Agrega un valor inicial:\n • const ' +
|
|
385
|
+
errorLine.match(/const\s+([a-zA-Z_][a-zA-Z0-9_]*)/)?.[1] +
|
|
386
|
+
' = "valor";\n • const ' +
|
|
387
|
+
errorLine.match(/const\s+([a-zA-Z_][a-zA-Z0-9_]*)/)?.[1] +
|
|
388
|
+
' = 42;\n • O cambia a "let" si planeas asignar después');
|
|
389
|
+
}
|
|
390
|
+
if (errorLine.includes('=') &&
|
|
391
|
+
!errorLine.trim().endsWith(';')) {
|
|
392
|
+
return 'Parece que la declaración const está incompleta. Verifica:\n • Que la expresión del lado derecho esté completa\n • Que termine con punto y coma (;)\n • Que no falten paréntesis o comillas';
|
|
393
|
+
}
|
|
394
|
+
return 'Las declaraciones const requieren un valor inicial:\n • const variable = "valor";\n • const numero = 42;\n • const objeto = { propiedad: "valor" };\n • const array = [1, 2, 3];';
|
|
395
|
+
}
|
|
396
|
+
// Análisis para identificadores inesperados
|
|
397
|
+
if (message.includes('unexpected') &&
|
|
398
|
+
message.includes('identifier')) {
|
|
399
|
+
if (prevLine.trim() &&
|
|
400
|
+
!prevLine.trim().endsWith(';') &&
|
|
401
|
+
!prevLine.trim().endsWith('{') &&
|
|
402
|
+
!prevLine.trim().endsWith('}')) {
|
|
403
|
+
return 'La línea anterior parece incompleta. Verifica:\n • Que termine con punto y coma (;)\n • Que no falten operadores o comas\n • Que los paréntesis estén balanceados';
|
|
404
|
+
}
|
|
405
|
+
if (errorLine.includes(',') && !errorLine.includes('=')) {
|
|
406
|
+
return 'Posible error en declaración de múltiples variables:\n • const a = 1, b = 2; (para const)\n • let a, b; a = 1; b = 2; (para let)\n • Verifica que cada variable tenga su valor asignado';
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
// Análisis para import/export malformados
|
|
410
|
+
if (message.includes('import') || message.includes('export')) {
|
|
411
|
+
if (errorLine.includes('import') &&
|
|
412
|
+
!errorLine.includes('from')) {
|
|
413
|
+
return 'Import statement incompleto:\n • import { item } from "modulo";\n • import defaultItem from "modulo";\n • import * as alias from "modulo";';
|
|
414
|
+
}
|
|
415
|
+
if (errorLine.includes('export') &&
|
|
416
|
+
errorLine.trim().endsWith('export')) {
|
|
417
|
+
return 'Export statement incompleto:\n • export { item };\n • export default item;\n • export const item = valor;';
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
// Análisis para paréntesis y brackets
|
|
421
|
+
if (message.includes('expected')) {
|
|
422
|
+
const openParens = (errorLine.match(/\(/g) || []).length;
|
|
423
|
+
const closeParens = (errorLine.match(/\)/g) || []).length;
|
|
424
|
+
const openBrackets = (errorLine.match(/\{/g) || []).length;
|
|
425
|
+
const closeBrackets = (errorLine.match(/\}/g) || []).length;
|
|
426
|
+
if (openParens !== closeParens) {
|
|
427
|
+
return `Paréntesis desbalanceados (${openParens} abiertos, ${closeParens} cerrados):\n • Verifica que cada ( tenga su correspondiente )\n • Revisa llamadas a funciones y expresiones`;
|
|
428
|
+
}
|
|
429
|
+
if (openBrackets !== closeBrackets) {
|
|
430
|
+
return `Llaves desbalanceadas (${openBrackets} abiertas, ${closeBrackets} cerradas):\n • Verifica que cada { tenga su correspondiente }\n • Revisa objetos, funciones y bloques de código`;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
// Fallback a sugerencias básicas si no hay análisis contextual específico
|
|
435
|
+
return this.generateSuggestion(errorMessage);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Instancia predeterminada del reporter con configuración estándar
|
|
440
|
+
*/
|
|
441
|
+
export const defaultErrorReporter = new ErrorReporter({
|
|
442
|
+
showLineNumbers: true,
|
|
443
|
+
showCodeContext: true,
|
|
444
|
+
contextLines: 2,
|
|
445
|
+
colorize: true,
|
|
446
|
+
});
|
|
447
|
+
/**
|
|
448
|
+
* Función helper para analizar y formatear rápidamente un error
|
|
449
|
+
*/
|
|
450
|
+
export function analyzeAndFormatError(error, sourceCode, fileName, options) {
|
|
451
|
+
const reporter = options
|
|
452
|
+
? new ErrorReporter(options)
|
|
453
|
+
: defaultErrorReporter;
|
|
454
|
+
const detailedError = reporter.analyzeParsingError(error, sourceCode, fileName);
|
|
455
|
+
return reporter.formatError(detailedError);
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Función helper para analizar y formatear múltiples errores
|
|
459
|
+
*/
|
|
460
|
+
export function analyzeAndFormatMultipleErrors(errors, sourceCode, fileName, options) {
|
|
461
|
+
const reporter = options
|
|
462
|
+
? new ErrorReporter(options)
|
|
463
|
+
: defaultErrorReporter;
|
|
464
|
+
const detailedErrors = reporter.analyzeMultipleErrors(errors, sourceCode, fileName);
|
|
465
|
+
return reporter.formatMultipleErrors(detailedErrors);
|
|
466
|
+
}
|
|
467
|
+
//# sourceMappingURL=error-reporter.js.map
|
package/dist/compiler/linter.js
CHANGED
|
@@ -1 +1,72 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { env } from 'node:process';
|
|
2
|
+
import { logger } from '../servicios/logger.js';
|
|
3
|
+
import { ESLintNode, } from './../wrappers/eslint-node.js';
|
|
4
|
+
import { OxlintNode } from './../wrappers/oxlint-node.js';
|
|
5
|
+
export async function OxLint(oxlintConfig = {}) {
|
|
6
|
+
try {
|
|
7
|
+
if (!oxlintConfig || !oxlintConfig.bin) {
|
|
8
|
+
// configFile es opcional si Oxlint lo encuentra por defecto
|
|
9
|
+
logger.warn('⚠️ Oxlint no se ejecutará: falta la propiedad "bin" en la configuración.');
|
|
10
|
+
return false; // O un resultado que indique fallo/no ejecución
|
|
11
|
+
}
|
|
12
|
+
const oxlintRunner = new OxlintNode({
|
|
13
|
+
binPath: oxlintConfig.bin, // Usar bin de LinterConfig
|
|
14
|
+
configFile: oxlintConfig.configFile, // Usar configFile de LinterConfig
|
|
15
|
+
fix: oxlintConfig.fix || false,
|
|
16
|
+
formats: ['json'], // Mantener json para parseo consistente si es necesario
|
|
17
|
+
tsconfigPath: env.tsconfigFile || './tsconfig.json', // Esto es específico de OxlintNode
|
|
18
|
+
// ... cualquier otra opción específica de oxlintConfig.oxlintConfig
|
|
19
|
+
...oxlintConfig.oxlintConfig,
|
|
20
|
+
});
|
|
21
|
+
const targetPaths = oxlintConfig.paths || [env.PATH_SOURCE || './src']; // Usar paths de LinterConfig
|
|
22
|
+
return await oxlintRunner.run(targetPaths);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
logger.error('❌ :Error al compilar OxLint:', err);
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Ejecuta ESLint en el proyecto con estructura compatible con Oxlint
|
|
31
|
+
*/
|
|
32
|
+
export async function ESLint(config = {}) {
|
|
33
|
+
try {
|
|
34
|
+
if (!config || !config.bin) {
|
|
35
|
+
// configFile es opcional si ESLint lo encuentra por defecto
|
|
36
|
+
logger.warn('⚠️ ESLint no se ejecutará: falta la propiedad "bin" en la configuración.');
|
|
37
|
+
// Devolver un ESLintMultiFormatResult vacío o que indique error
|
|
38
|
+
return {
|
|
39
|
+
json: {
|
|
40
|
+
results: [],
|
|
41
|
+
errorCount: 0,
|
|
42
|
+
warningCount: 0,
|
|
43
|
+
fixableErrorCount: 0,
|
|
44
|
+
fixableWarningCount: 0,
|
|
45
|
+
fatalErrorCount: 0,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// Configuración por defecto para el proyecto
|
|
50
|
+
const eslintRunner = new ESLintNode({
|
|
51
|
+
binPath: config.bin, // Usar bin de LinterConfig
|
|
52
|
+
configFile: config.configFile, // Usar configFile de LinterConfig
|
|
53
|
+
fix: config.fix || false,
|
|
54
|
+
// Las siguientes son opciones más específicas de ESLintNode,
|
|
55
|
+
// podrían moverse a config.eslintConfig si se prefiere mayor anidación.
|
|
56
|
+
extensions: ['.vue', '.ts', '.js'], // Ejemplo, podría venir de eslintConfig
|
|
57
|
+
formats: config.format ? [config.format] : ['stylish', 'json'], // Usar format de LinterConfig
|
|
58
|
+
cache: true, // Ejemplo, podría venir de eslintConfig
|
|
59
|
+
maxWarnings: 100, // Ejemplo, podría venir de eslintConfig
|
|
60
|
+
// Sobrescribir o añadir con configuraciones específicas de eslintConfig
|
|
61
|
+
...config.eslintConfig,
|
|
62
|
+
});
|
|
63
|
+
const targetPaths = config.paths || ['src/']; // Usar paths de LinterConfig
|
|
64
|
+
const result = await eslintRunner.run(targetPaths);
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
logger.error('❌ Error al ejecutar ESLint:', err);
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=linter.js.map
|