versacompiler 2.0.0 → 2.0.2
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 +345 -69
- package/dist/compiler/compile.js +762 -183
- package/dist/compiler/minify.js +199 -10
- package/dist/compiler/module-resolution-optimizer.js +822 -0
- package/dist/compiler/parser.js +179 -6
- package/dist/compiler/performance-monitor.js +192 -0
- package/dist/compiler/transform-optimizer.js +392 -0
- package/dist/compiler/transforms.js +124 -118
- package/dist/compiler/{typescript.js → typescript-compiler.js} +27 -30
- package/dist/compiler/typescript-error-parser.js +6 -7
- package/dist/compiler/typescript-manager.js +378 -0
- package/dist/compiler/typescript-sync-validator.js +13 -15
- package/dist/compiler/typescript-worker-pool.js +845 -0
- package/dist/compiler/typescript-worker.js +51 -21
- package/dist/compiler/vuejs.js +131 -37
- package/dist/main.js +5 -6
- package/dist/servicios/browserSync.js +313 -21
- package/dist/servicios/file-watcher.js +367 -0
- package/dist/servicios/logger.js +1 -0
- package/dist/servicios/readConfig.js +1 -0
- package/dist/utils/excluded-modules.js +36 -0
- package/dist/utils/module-resolver.js +9 -48
- package/dist/utils/promptUser.js +1 -1
- package/dist/utils/resolve-bin.js +28 -9
- package/package.json +8 -7
- package/dist/servicios/chokidar.js +0 -178
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { env } from 'node:process';
|
|
3
3
|
import { logger } from '../servicios/logger.js';
|
|
4
|
+
import { EXCLUDED_MODULES } from '../utils/excluded-modules.js';
|
|
4
5
|
import { getModuleSubPath } from '../utils/module-resolver.js';
|
|
5
6
|
import { analyzeAndFormatMultipleErrors } from './error-reporter.js';
|
|
7
|
+
import { getOptimizedAliasPath, getOptimizedModulePath, } from './module-resolution-optimizer.js';
|
|
6
8
|
import { parser } from './parser.js';
|
|
7
9
|
// Módulos built-in de Node.js que no deben ser resueltos
|
|
8
10
|
const NODE_BUILTIN_MODULES = new Set([
|
|
@@ -69,21 +71,6 @@ function isExternalModule(moduleRequest, pathAlias) {
|
|
|
69
71
|
} // NUEVA LÓGICA: Verificar PRIMERO si es un módulo excluido antes de verificar alias
|
|
70
72
|
// Esto es importante porque algunos módulos excluidos pueden tener nombres que
|
|
71
73
|
// coinciden con patrones de alias (como @vue/compiler-sfc con @/*)
|
|
72
|
-
const EXCLUDED_MODULES = new Set([
|
|
73
|
-
'vue/compiler-sfc',
|
|
74
|
-
'vue/dist/vue.runtime.esm-bundler',
|
|
75
|
-
'@vue/compiler-sfc',
|
|
76
|
-
'@vue/compiler-dom',
|
|
77
|
-
'@vue/runtime-core',
|
|
78
|
-
'@vue/runtime-dom',
|
|
79
|
-
'oxc-parser',
|
|
80
|
-
'oxc-parser/wasm',
|
|
81
|
-
'oxc-minify',
|
|
82
|
-
'oxc-minify/browser',
|
|
83
|
-
'@oxc-parser/binding-wasm32-wasi',
|
|
84
|
-
'@oxc-minify/binding-wasm32-wasi',
|
|
85
|
-
'typescript/lib/typescript',
|
|
86
|
-
]);
|
|
87
74
|
if (EXCLUDED_MODULES.has(moduleRequest)) {
|
|
88
75
|
return true;
|
|
89
76
|
} // Descartar alias conocidos
|
|
@@ -118,50 +105,77 @@ export async function replaceAliasImportStatic(file, code) {
|
|
|
118
105
|
if (!moduleRequest)
|
|
119
106
|
continue; // Skip if moduleRequest is undefined
|
|
120
107
|
let newPath = null;
|
|
121
|
-
let transformed = false;
|
|
122
|
-
// 1. PRIMERO: Verificar si es un módulo excluido (prioridad máxima)
|
|
108
|
+
let transformed = false; // 1. PRIMERO: Verificar si es un módulo excluido (prioridad máxima)
|
|
123
109
|
if (!transformed && isExternalModule(moduleRequest, pathAlias)) {
|
|
124
110
|
try {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
//
|
|
111
|
+
// Usar el sistema optimizado primero
|
|
112
|
+
const optimizedPath = await getOptimizedModulePath(moduleRequest, file);
|
|
113
|
+
if (optimizedPath === null) {
|
|
114
|
+
// Si el optimizador retorna null, significa que es un módulo excluido
|
|
129
115
|
continue;
|
|
130
116
|
}
|
|
131
|
-
if (
|
|
132
|
-
newPath =
|
|
117
|
+
if (optimizedPath) {
|
|
118
|
+
newPath = optimizedPath;
|
|
133
119
|
transformed = true;
|
|
134
120
|
}
|
|
121
|
+
else {
|
|
122
|
+
// Fallback al sistema anterior
|
|
123
|
+
const modulePath = getModuleSubPath(moduleRequest, file);
|
|
124
|
+
if (modulePath === null) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (modulePath) {
|
|
128
|
+
newPath = modulePath;
|
|
129
|
+
transformed = true;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
135
132
|
}
|
|
136
133
|
catch (error) {
|
|
137
134
|
if (env.VERBOSE === 'true')
|
|
138
135
|
logger.warn(`Error resolviendo módulo ${moduleRequest}: ${error instanceof Error ? error.message : String(error)}`);
|
|
139
136
|
}
|
|
140
|
-
}
|
|
141
|
-
// 2. Si no es módulo externo/excluido, verificar si es un alias conocido
|
|
137
|
+
} // 2. Si no es módulo externo/excluido, verificar si es un alias conocido
|
|
142
138
|
if (!transformed) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
139
|
+
// Usar el sistema optimizado de alias
|
|
140
|
+
const aliasPath = getOptimizedAliasPath(moduleRequest);
|
|
141
|
+
if (aliasPath) {
|
|
142
|
+
let newImportPath = aliasPath;
|
|
143
|
+
// Transformar extensiones
|
|
144
|
+
if (newImportPath.endsWith('.ts') ||
|
|
145
|
+
newImportPath.endsWith('.vue')) {
|
|
146
|
+
newImportPath = newImportPath.replace(/\.(ts|vue)$/, '.js');
|
|
147
|
+
}
|
|
148
|
+
else if (!/\.(js|mjs|css|json)$/.test(newImportPath)) {
|
|
149
|
+
newImportPath += '.js';
|
|
150
|
+
}
|
|
151
|
+
newPath = newImportPath;
|
|
152
|
+
transformed = true;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// Fallback al sistema anterior
|
|
156
|
+
for (const [alias] of Object.entries(pathAlias)) {
|
|
157
|
+
const aliasPattern = alias.replace('/*', '');
|
|
158
|
+
if (moduleRequest.startsWith(aliasPattern)) {
|
|
159
|
+
// Reemplazar el alias con la ruta del target
|
|
160
|
+
const relativePath = moduleRequest.replace(aliasPattern, '');
|
|
161
|
+
// Para alias que apuntan a la raíz (como @/* -> /src/*),
|
|
162
|
+
// solo usamos PATH_DIST + relativePath
|
|
163
|
+
let newImportPath = path.join('/', env.PATH_DIST, relativePath);
|
|
164
|
+
// Normalizar la ruta para eliminar ./ extra y separadores de Windows
|
|
165
|
+
newImportPath = newImportPath
|
|
166
|
+
.replace(/\/\.\//g, '/')
|
|
167
|
+
.replace(/\\/g, '/');
|
|
168
|
+
if (newImportPath.endsWith('.ts') ||
|
|
169
|
+
newImportPath.endsWith('.vue')) {
|
|
170
|
+
newImportPath = newImportPath.replace(/\.(ts|vue)$/, '.js');
|
|
171
|
+
}
|
|
172
|
+
else if (!/\.(js|mjs|css|json)$/.test(newImportPath)) {
|
|
173
|
+
newImportPath += '.js';
|
|
174
|
+
}
|
|
175
|
+
newPath = newImportPath;
|
|
176
|
+
transformed = true;
|
|
177
|
+
break;
|
|
161
178
|
}
|
|
162
|
-
newPath = newImportPath;
|
|
163
|
-
transformed = true;
|
|
164
|
-
break;
|
|
165
179
|
}
|
|
166
180
|
}
|
|
167
181
|
}
|
|
@@ -206,50 +220,77 @@ async function replaceAliasImportDynamic(code, _imports, file) {
|
|
|
206
220
|
if (!moduleRequest)
|
|
207
221
|
continue; // Skip if moduleRequest is undefined
|
|
208
222
|
let newPath = null;
|
|
209
|
-
let transformed = false;
|
|
210
|
-
// 1. PRIMERO: Verificar si es un módulo excluido (prioridad máxima)
|
|
223
|
+
let transformed = false; // 1. PRIMERO: Verificar si es un módulo excluido (prioridad máxima)
|
|
211
224
|
if (!transformed && isExternalModule(moduleRequest, pathAlias)) {
|
|
212
225
|
try {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
//
|
|
226
|
+
// Usar el sistema optimizado primero
|
|
227
|
+
const optimizedPath = await getOptimizedModulePath(moduleRequest, file);
|
|
228
|
+
if (optimizedPath === null) {
|
|
229
|
+
// Si el optimizador retorna null, significa que es un módulo excluido
|
|
217
230
|
continue;
|
|
218
231
|
}
|
|
219
|
-
if (
|
|
220
|
-
newPath =
|
|
232
|
+
if (optimizedPath) {
|
|
233
|
+
newPath = optimizedPath;
|
|
221
234
|
transformed = true;
|
|
222
235
|
}
|
|
236
|
+
else {
|
|
237
|
+
// Fallback al sistema anterior
|
|
238
|
+
const modulePath = getModuleSubPath(moduleRequest, file);
|
|
239
|
+
if (modulePath === null) {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (modulePath) {
|
|
243
|
+
newPath = modulePath;
|
|
244
|
+
transformed = true;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
223
247
|
}
|
|
224
248
|
catch (error) {
|
|
225
249
|
if (env.VERBOSE === 'true')
|
|
226
250
|
logger.warn(`Error resolviendo módulo dinámico ${moduleRequest}: ${error instanceof Error ? error.message : String(error)}`);
|
|
227
251
|
}
|
|
228
|
-
}
|
|
229
|
-
// 2. Si no es módulo externo/excluido, verificar si es un alias conocido
|
|
252
|
+
} // 2. Si no es módulo externo/excluido, verificar si es un alias conocido
|
|
230
253
|
if (!transformed) {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
254
|
+
// Usar el sistema optimizado de alias
|
|
255
|
+
const aliasPath = getOptimizedAliasPath(moduleRequest);
|
|
256
|
+
if (aliasPath) {
|
|
257
|
+
let newImportPath = aliasPath;
|
|
258
|
+
// Transformar extensiones
|
|
259
|
+
if (newImportPath.endsWith('.ts') ||
|
|
260
|
+
newImportPath.endsWith('.vue')) {
|
|
261
|
+
newImportPath = newImportPath.replace(/\.(ts|vue)$/, '.js');
|
|
262
|
+
}
|
|
263
|
+
else if (!/\.(js|mjs|css|json)$/.test(newImportPath)) {
|
|
264
|
+
newImportPath += '.js';
|
|
265
|
+
}
|
|
266
|
+
newPath = newImportPath;
|
|
267
|
+
transformed = true;
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
// Fallback al sistema anterior
|
|
271
|
+
for (const [alias] of Object.entries(pathAlias)) {
|
|
272
|
+
const aliasPattern = alias.replace('/*', '');
|
|
273
|
+
if (moduleRequest.startsWith(aliasPattern)) {
|
|
274
|
+
// Reemplazar el alias con la ruta del target
|
|
275
|
+
const relativePath = moduleRequest.replace(aliasPattern, '');
|
|
276
|
+
// Para alias que apuntan a la raíz (como @/* -> /src/*),
|
|
277
|
+
// solo usamos PATH_DIST + relativePath
|
|
278
|
+
let newImportPath = path.join('/', pathDist, relativePath);
|
|
279
|
+
// Normalizar la ruta para eliminar ./ extra y separadores de Windows
|
|
280
|
+
newImportPath = newImportPath
|
|
281
|
+
.replace(/\/\.\//g, '/')
|
|
282
|
+
.replace(/\\/g, '/');
|
|
283
|
+
if (newImportPath.endsWith('.ts') ||
|
|
284
|
+
newImportPath.endsWith('.vue')) {
|
|
285
|
+
newImportPath = newImportPath.replace(/\.(ts|vue)$/, '.js');
|
|
286
|
+
}
|
|
287
|
+
else if (!/\.(js|mjs|css|json)$/.test(newImportPath)) {
|
|
288
|
+
newImportPath += '.js';
|
|
289
|
+
}
|
|
290
|
+
newPath = newImportPath;
|
|
291
|
+
transformed = true;
|
|
292
|
+
break;
|
|
249
293
|
}
|
|
250
|
-
newPath = newImportPath;
|
|
251
|
-
transformed = true;
|
|
252
|
-
break;
|
|
253
294
|
}
|
|
254
295
|
}
|
|
255
296
|
}
|
|
@@ -374,48 +415,25 @@ async function replaceAliasInStrings(code) {
|
|
|
374
415
|
// IMPORTANTE: Verificar si es un módulo excluido antes de transformar
|
|
375
416
|
if (isExternalModule(stringContent, pathAlias)) {
|
|
376
417
|
// Para strings que parecen ser módulos externos, verificar si están excluidos
|
|
377
|
-
const EXCLUDED_MODULES = new Set([
|
|
378
|
-
'vue/compiler-sfc',
|
|
379
|
-
'vue/dist/vue.runtime.esm-bundler',
|
|
380
|
-
'@vue/compiler-sfc',
|
|
381
|
-
'@vue/compiler-dom',
|
|
382
|
-
'@vue/runtime-core',
|
|
383
|
-
'@vue/runtime-dom',
|
|
384
|
-
'oxc-parser',
|
|
385
|
-
'oxc-parser/wasm',
|
|
386
|
-
'oxc-minify',
|
|
387
|
-
'oxc-minify/browser',
|
|
388
|
-
'@oxc-parser/binding-wasm32-wasi',
|
|
389
|
-
'@oxc-minify/binding-wasm32-wasi',
|
|
390
|
-
'typescript/lib/typescript',
|
|
391
|
-
]);
|
|
392
418
|
if (EXCLUDED_MODULES.has(stringContent)) {
|
|
393
419
|
// Es un módulo excluido, no transformar
|
|
394
420
|
continue;
|
|
395
421
|
}
|
|
396
|
-
}
|
|
422
|
+
}
|
|
423
|
+
// Reemplazar el alias con la ruta del target
|
|
397
424
|
const relativePath = stringContent.replace(aliasPattern, '');
|
|
398
425
|
// Construir la nueva ruta basada en la configuración del target
|
|
399
426
|
let newPath;
|
|
400
427
|
// El target puede ser un array de strings o un string
|
|
401
428
|
const targetArray = Array.isArray(target) ? target : [target];
|
|
402
429
|
const targetPath = targetArray[0];
|
|
403
|
-
// Debug logs
|
|
404
|
-
if (env.VERBOSE === 'true') {
|
|
405
|
-
console.log(`🔍 DEBUG replaceAliasInStrings:
|
|
406
|
-
- stringContent: "${stringContent}"
|
|
407
|
-
- aliasPattern: "${aliasPattern}"
|
|
408
|
-
- relativePath: "${relativePath}"
|
|
409
|
-
- targetPath: "${targetPath}"
|
|
410
|
-
- pathDist: "${pathDist}"`);
|
|
411
|
-
}
|
|
412
430
|
if (targetPath.startsWith('/')) {
|
|
413
431
|
// Si el target empieza con /, es una ruta absoluta desde la raíz del proyecto
|
|
414
|
-
//
|
|
415
|
-
|
|
416
|
-
newPath = path.join(
|
|
432
|
+
// Para targets como "/src/*", solo usamos PATH_DIST + relativePath
|
|
433
|
+
// sin incluir el directorio del target en la ruta final
|
|
434
|
+
newPath = path.join('/', pathDist, relativePath);
|
|
417
435
|
if (env.VERBOSE === 'true') {
|
|
418
|
-
console.log(` ✅ Ruta absoluta:
|
|
436
|
+
console.log(` ✅ Ruta absoluta: pathDist="${pathDist}", relativePath="${relativePath}", newPath="${newPath}"`);
|
|
419
437
|
}
|
|
420
438
|
}
|
|
421
439
|
else {
|
|
@@ -424,22 +442,13 @@ async function replaceAliasInStrings(code) {
|
|
|
424
442
|
.replace('./', '')
|
|
425
443
|
.replace('/*', '');
|
|
426
444
|
const normalizedPathDist = pathDist.replace('./', '');
|
|
427
|
-
if (env.VERBOSE === 'true') {
|
|
428
|
-
console.log(` 🔍 Ruta relativa: cleanTarget="${cleanTarget}", normalizedPathDist="${normalizedPathDist}"`);
|
|
429
|
-
}
|
|
430
445
|
if (cleanTarget === normalizedPathDist) {
|
|
431
446
|
// Si el target es el mismo que PATH_DIST, no duplicar
|
|
432
447
|
newPath = path.join('/', normalizedPathDist, relativePath);
|
|
433
|
-
if (env.VERBOSE === 'true') {
|
|
434
|
-
console.log(` ✅ Sin duplicación: newPath="${newPath}"`);
|
|
435
|
-
}
|
|
436
448
|
}
|
|
437
449
|
else {
|
|
438
450
|
// Si es diferente, usar PATH_DIST como base
|
|
439
451
|
newPath = path.join('/', normalizedPathDist, cleanTarget, relativePath);
|
|
440
|
-
if (env.VERBOSE === 'true') {
|
|
441
|
-
console.log(` ✅ Con PATH_DIST: newPath="${newPath}"`);
|
|
442
|
-
}
|
|
443
452
|
}
|
|
444
453
|
}
|
|
445
454
|
// Normalizar la ruta para eliminar ./ extra y separadores de Windows
|
|
@@ -460,9 +469,6 @@ async function replaceAliasInStrings(code) {
|
|
|
460
469
|
const escapedOriginal = fullMatch.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
461
470
|
const specificRegex = new RegExp(escapedOriginal, 'g');
|
|
462
471
|
resultCode = resultCode.replace(specificRegex, newFullMatch);
|
|
463
|
-
if (env.VERBOSE === 'true') {
|
|
464
|
-
logger.info(`Alias en string transformado: ${stringContent} -> ${newStringContent}`);
|
|
465
|
-
}
|
|
466
472
|
}
|
|
467
473
|
}
|
|
468
474
|
return resultCode;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import * as process from 'node:process';
|
|
3
4
|
import { env } from 'node:process';
|
|
4
|
-
import * as
|
|
5
|
+
import * as typescript from 'typescript';
|
|
5
6
|
import { createUnifiedErrorMessage, parseTypeScriptErrors, } from './typescript-error-parser.js';
|
|
6
7
|
import { TypeScriptWorkerManager } from './typescript-worker.js';
|
|
7
8
|
/**
|
|
@@ -15,8 +16,7 @@ let configCache = {};
|
|
|
15
16
|
*/
|
|
16
17
|
export const loadTypeScriptConfig = (fileName) => {
|
|
17
18
|
const fileDir = path.dirname(fileName);
|
|
18
|
-
const configPath =
|
|
19
|
-
path.resolve(process.cwd(), 'tsconfig.json');
|
|
19
|
+
const configPath = typescript.findConfigFile(fileDir, typescript.sys.fileExists, 'tsconfig.json') || path.resolve(process.cwd(), 'tsconfig.json');
|
|
20
20
|
// Usar cache si el path no ha cambiado
|
|
21
21
|
if (configCache.path === configPath && configCache.options) {
|
|
22
22
|
return configCache.options;
|
|
@@ -24,9 +24,9 @@ export const loadTypeScriptConfig = (fileName) => {
|
|
|
24
24
|
let compilerOptions;
|
|
25
25
|
if (configPath && fs.existsSync(configPath)) {
|
|
26
26
|
try {
|
|
27
|
-
const { config, error: configError } =
|
|
27
|
+
const { config, error: configError } = typescript.readConfigFile(configPath, typescript.sys.readFile);
|
|
28
28
|
if (!configError) {
|
|
29
|
-
const parsedConfig =
|
|
29
|
+
const parsedConfig = typescript.parseJsonConfigFileContent(config, typescript.sys, path.dirname(configPath));
|
|
30
30
|
compilerOptions = {
|
|
31
31
|
...parsedConfig.options,
|
|
32
32
|
// Asegurar opciones básicas necesarias
|
|
@@ -59,8 +59,8 @@ export const loadTypeScriptConfig = (fileName) => {
|
|
|
59
59
|
* Obtiene las opciones por defecto del compilador TypeScript
|
|
60
60
|
*/
|
|
61
61
|
const getDefaultCompilerOptions = () => ({
|
|
62
|
-
target:
|
|
63
|
-
module:
|
|
62
|
+
target: typescript.ScriptTarget.ES2020,
|
|
63
|
+
module: typescript.ModuleKind.ES2020,
|
|
64
64
|
lib: ['es2020', 'dom', 'dom.iterable'],
|
|
65
65
|
strict: false,
|
|
66
66
|
skipLibCheck: true,
|
|
@@ -70,13 +70,13 @@ const getDefaultCompilerOptions = () => ({
|
|
|
70
70
|
isolatedModules: true,
|
|
71
71
|
});
|
|
72
72
|
/**
|
|
73
|
-
* Crea una versión optimizada y serializable de las opciones del compilador
|
|
73
|
+
* Crea una versión optimizada y serializable de las opciones del compilador typescript.
|
|
74
74
|
* @param options - Opciones originales del compilador
|
|
75
75
|
* @returns Opciones serializables seguras para workers
|
|
76
76
|
*/
|
|
77
77
|
const createSerializableCompilerOptions = (options) => {
|
|
78
78
|
// Usar las opciones del tsconfig.json pero con optimizaciones para el worker
|
|
79
|
-
const { target =
|
|
79
|
+
const { target = typescript.ScriptTarget.ES2020, module = typescript.ModuleKind.ES2020, lib = ['es2020', 'dom', 'dom.iterable'], allowJs = true, jsx, strict = false, skipLibCheck = true, esModuleInterop = true, allowSyntheticDefaultImports = true, isolatedModules = true, } = options;
|
|
80
80
|
return {
|
|
81
81
|
target,
|
|
82
82
|
module,
|
|
@@ -124,13 +124,13 @@ class TypeScriptLanguageServiceHost {
|
|
|
124
124
|
getScriptSnapshot(fileName) {
|
|
125
125
|
const file = this.files.get(fileName);
|
|
126
126
|
if (file) {
|
|
127
|
-
return
|
|
127
|
+
return typescript.ScriptSnapshot.fromString(file.content);
|
|
128
128
|
}
|
|
129
129
|
// Cache de sistema de archivos para evitar lecturas repetidas
|
|
130
130
|
if (this.fileSystemCache.has(fileName)) {
|
|
131
131
|
const cachedContent = this.fileSystemCache.get(fileName);
|
|
132
132
|
return cachedContent
|
|
133
|
-
?
|
|
133
|
+
? typescript.ScriptSnapshot.fromString(cachedContent)
|
|
134
134
|
: undefined;
|
|
135
135
|
}
|
|
136
136
|
// Intentar leer el archivo del sistema de archivos solo si es necesario
|
|
@@ -138,7 +138,7 @@ class TypeScriptLanguageServiceHost {
|
|
|
138
138
|
if (fs.existsSync(fileName)) {
|
|
139
139
|
const content = fs.readFileSync(fileName, 'utf-8');
|
|
140
140
|
this.fileSystemCache.set(fileName, content);
|
|
141
|
-
return
|
|
141
|
+
return typescript.ScriptSnapshot.fromString(content);
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
catch {
|
|
@@ -151,7 +151,7 @@ class TypeScriptLanguageServiceHost {
|
|
|
151
151
|
return process.cwd();
|
|
152
152
|
}
|
|
153
153
|
getDefaultLibFileName(options) {
|
|
154
|
-
return
|
|
154
|
+
return typescript.getDefaultLibFilePath(options);
|
|
155
155
|
}
|
|
156
156
|
fileExists(path) {
|
|
157
157
|
if (this.files.has(path))
|
|
@@ -185,7 +185,7 @@ class TypeScriptLanguageServiceHost {
|
|
|
185
185
|
return undefined;
|
|
186
186
|
}
|
|
187
187
|
getNewLine() {
|
|
188
|
-
return
|
|
188
|
+
return typescript.sys.newLine;
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
/**
|
|
@@ -230,9 +230,8 @@ export {};`;
|
|
|
230
230
|
}
|
|
231
231
|
else {
|
|
232
232
|
host.addFile(actualFileName, content);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const languageService = ts.createLanguageService(host);
|
|
233
|
+
} // Crear Language Service
|
|
234
|
+
const languageService = typescript.createLanguageService(host);
|
|
236
235
|
// Verificar existencia del archivo
|
|
237
236
|
if (!host.fileExists(actualFileName)) {
|
|
238
237
|
return { diagnostics: [], hasErrors: false };
|
|
@@ -246,12 +245,11 @@ export {};`;
|
|
|
246
245
|
catch {
|
|
247
246
|
// Ignorar errores de diagnósticos
|
|
248
247
|
return { diagnostics: [], hasErrors: false };
|
|
249
|
-
}
|
|
250
|
-
// Filtrado optimizado de diagnósticos
|
|
248
|
+
} // Filtrado optimizado de diagnósticos
|
|
251
249
|
const filteredDiagnostics = allDiagnostics.filter(diag => {
|
|
252
|
-
if (diag.category !==
|
|
250
|
+
if (diag.category !== typescript.DiagnosticCategory.Error)
|
|
253
251
|
return false;
|
|
254
|
-
const messageText =
|
|
252
|
+
const messageText = typescript.flattenDiagnosticMessageText(diag.messageText, '\n');
|
|
255
253
|
// Lista optimizada de patrones a ignorar
|
|
256
254
|
const ignorePatterns = [
|
|
257
255
|
'Cannot find module',
|
|
@@ -277,7 +275,7 @@ export {};`;
|
|
|
277
275
|
start: undefined,
|
|
278
276
|
length: undefined,
|
|
279
277
|
messageText: `Error en validación de tipos: ${error instanceof Error ? error.message : 'Error desconocido'}`,
|
|
280
|
-
category:
|
|
278
|
+
category: typescript.DiagnosticCategory.Error,
|
|
281
279
|
code: 0,
|
|
282
280
|
},
|
|
283
281
|
],
|
|
@@ -298,7 +296,7 @@ export const validateVueTypes = (vueContent, fileName) => {
|
|
|
298
296
|
/**
|
|
299
297
|
* Precompila el código TypeScript con pipeline optimizado para máxima performance.
|
|
300
298
|
* @param {string} data - El código TypeScript a precompilar.
|
|
301
|
-
* @param {string} fileName - El nombre del archivo que contiene el código
|
|
299
|
+
* @param {string} fileName - El nombre del archivo que contiene el código typescript.
|
|
302
300
|
* @returns {Promise<CompileResult>} - Un objeto con el código precompilado o un error.
|
|
303
301
|
*/
|
|
304
302
|
export const preCompileTS = async (data, fileName) => {
|
|
@@ -308,9 +306,8 @@ export const preCompileTS = async (data, fileName) => {
|
|
|
308
306
|
return { error: null, data: data, lang: 'ts' };
|
|
309
307
|
}
|
|
310
308
|
// Cargar configuración de TypeScript desde tsconfig.json
|
|
311
|
-
const compilerOptions = loadTypeScriptConfig(fileName);
|
|
312
|
-
|
|
313
|
-
const transpileResult = ts.transpileModule(data, {
|
|
309
|
+
const compilerOptions = loadTypeScriptConfig(fileName); // PASO 1: Transpilación rápida con detección de errores críticos
|
|
310
|
+
const transpileResult = typescript.transpileModule(data, {
|
|
314
311
|
compilerOptions: {
|
|
315
312
|
...compilerOptions,
|
|
316
313
|
noLib: true,
|
|
@@ -324,10 +321,10 @@ export const preCompileTS = async (data, fileName) => {
|
|
|
324
321
|
// fileName,data)
|
|
325
322
|
// Verificar errores críticos de sintaxis
|
|
326
323
|
if (transpileResult.diagnostics?.length) {
|
|
327
|
-
const criticalErrors = transpileResult.diagnostics.filter(diag => {
|
|
328
|
-
if (diag.category !==
|
|
324
|
+
const criticalErrors = transpileResult.diagnostics.filter((diag) => {
|
|
325
|
+
if (diag.category !== typescript.DiagnosticCategory.Error)
|
|
329
326
|
return false;
|
|
330
|
-
const messageText =
|
|
327
|
+
const messageText = typescript.flattenDiagnosticMessageText(diag.messageText, '\n');
|
|
331
328
|
// Ignorar errores de módulo no encontrado
|
|
332
329
|
return (!messageText.includes('Cannot find module') &&
|
|
333
330
|
!messageText.includes('Could not find source file') &&
|
|
@@ -379,4 +376,4 @@ export const preCompileTS = async (data, fileName) => {
|
|
|
379
376
|
};
|
|
380
377
|
}
|
|
381
378
|
};
|
|
382
|
-
//# sourceMappingURL=typescript.js.map
|
|
379
|
+
//# sourceMappingURL=typescript-compiler.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as typescript from 'typescript';
|
|
2
2
|
/**
|
|
3
3
|
* Parsea errores de TypeScript y los convierte a un formato limpio
|
|
4
4
|
* que incluye solo: archivo, mensaje, severidad y ubicación como ayuda
|
|
@@ -6,14 +6,13 @@ import * as ts from 'typescript';
|
|
|
6
6
|
export function parseTypeScriptErrors(diagnostics, fileName, sourceCode) {
|
|
7
7
|
return diagnostics.map(diagnostic => {
|
|
8
8
|
// Usar el mejorador de errores para obtener mensaje detallado
|
|
9
|
-
const enhancedMessage = enhanceErrorMessage(diagnostic, fileName, sourceCode);
|
|
10
|
-
// Determinar la severidad
|
|
9
|
+
const enhancedMessage = enhanceErrorMessage(diagnostic, fileName, sourceCode); // Determinar la severidad
|
|
11
10
|
let severity;
|
|
12
11
|
switch (diagnostic.category) {
|
|
13
|
-
case
|
|
12
|
+
case typescript.DiagnosticCategory.Error:
|
|
14
13
|
severity = 'error';
|
|
15
14
|
break;
|
|
16
|
-
case
|
|
15
|
+
case typescript.DiagnosticCategory.Warning:
|
|
17
16
|
severity = 'warning';
|
|
18
17
|
break;
|
|
19
18
|
default:
|
|
@@ -67,7 +66,7 @@ function enhanceErrorMessage(diagnostic, fileName, sourceCode) {
|
|
|
67
66
|
// Extraer el mensaje del error
|
|
68
67
|
const message = typeof diagnostic.messageText === 'string'
|
|
69
68
|
? diagnostic.messageText
|
|
70
|
-
:
|
|
69
|
+
: typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
|
71
70
|
let enhancedMessage = cleanErrorMessage(message); // Información de ubicación
|
|
72
71
|
let location = `Código TS${diagnostic.code}`;
|
|
73
72
|
let codeContext = '';
|
|
@@ -242,7 +241,7 @@ export function createSimpleErrorMessage(diagnostics, _fileName) {
|
|
|
242
241
|
const firstDiagnostic = diagnostics[0];
|
|
243
242
|
if (!firstDiagnostic)
|
|
244
243
|
return '';
|
|
245
|
-
const message =
|
|
244
|
+
const message = typescript.flattenDiagnosticMessageText(firstDiagnostic.messageText, '\n');
|
|
246
245
|
// Extraer solo la primera línea del mensaje para simplicidad
|
|
247
246
|
const simplifiedMessage = message.split('\n')[0];
|
|
248
247
|
let location = '';
|