versacompiler 2.0.7 → 2.0.8
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/dist/compiler/compile.js +26 -2332
- package/dist/compiler/error-reporter.js +38 -467
- package/dist/compiler/linter.js +1 -72
- package/dist/compiler/minify.js +1 -229
- package/dist/compiler/module-resolution-optimizer.js +1 -821
- package/dist/compiler/parser.js +1 -203
- package/dist/compiler/performance-monitor.js +56 -192
- package/dist/compiler/tailwindcss.js +1 -39
- package/dist/compiler/transform-optimizer.js +1 -392
- package/dist/compiler/transformTStoJS.js +1 -16
- package/dist/compiler/transforms.js +1 -550
- package/dist/compiler/typescript-compiler.js +2 -172
- package/dist/compiler/typescript-error-parser.js +10 -281
- package/dist/compiler/typescript-manager.js +2 -273
- package/dist/compiler/typescript-sync-validator.js +31 -295
- package/dist/compiler/typescript-worker-pool.js +1 -842
- package/dist/compiler/typescript-worker-thread.cjs +41 -466
- package/dist/compiler/typescript-worker.js +1 -339
- package/dist/compiler/vuejs.js +37 -392
- package/dist/hrm/VueHRM.js +1 -353
- package/dist/hrm/errorScreen.js +1 -83
- package/dist/hrm/getInstanciaVue.js +1 -313
- package/dist/hrm/initHRM.js +1 -141
- package/dist/main.js +7 -347
- package/dist/servicios/browserSync.js +5 -501
- package/dist/servicios/file-watcher.js +4 -379
- package/dist/servicios/logger.js +3 -63
- package/dist/servicios/readConfig.js +105 -430
- package/dist/utils/excluded-modules.js +1 -36
- package/dist/utils/module-resolver.js +1 -466
- package/dist/utils/promptUser.js +2 -48
- package/dist/utils/proxyValidator.js +1 -68
- package/dist/utils/resolve-bin.js +1 -48
- package/dist/utils/utils.js +1 -21
- package/dist/utils/vue-types-setup.js +241 -435
- package/dist/wrappers/eslint-node.js +1 -145
- package/dist/wrappers/oxlint-node.js +1 -120
- package/dist/wrappers/tailwind-node.js +1 -92
- package/package.json +36 -35
|
@@ -1,273 +1,2 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
|
|
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 { TypeScriptWorkerPool } from './typescript-worker-pool.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
|
-
// Siempre buscar primero en la raíz del proyecto
|
|
20
|
-
const rootConfigPath = path.resolve(process.cwd(), 'tsconfig.json');
|
|
21
|
-
// Si no existe en la raíz, buscar desde el directorio del archivo
|
|
22
|
-
const fileDir = path.dirname(fileName);
|
|
23
|
-
const configPath = fs.existsSync(rootConfigPath)
|
|
24
|
-
? rootConfigPath
|
|
25
|
-
: typescript.findConfigFile(fileDir, typescript.sys.fileExists, 'tsconfig.json');
|
|
26
|
-
// Usar cache si el path no ha cambiado
|
|
27
|
-
if (configCache.path === configPath && configCache.options) {
|
|
28
|
-
return configCache.options;
|
|
29
|
-
}
|
|
30
|
-
let compilerOptions;
|
|
31
|
-
if (configPath && fs.existsSync(configPath)) {
|
|
32
|
-
try {
|
|
33
|
-
const { config, error: configError } = typescript.readConfigFile(configPath, typescript.sys.readFile);
|
|
34
|
-
if (!configError) {
|
|
35
|
-
const parsedConfig = typescript.parseJsonConfigFileContent(config, typescript.sys, path.dirname(configPath)); // Usar exactamente la configuración del tsconfig.json del usuario sin modificaciones
|
|
36
|
-
compilerOptions = parsedConfig.options;
|
|
37
|
-
// DEBUG: Verificar las opciones cargadas
|
|
38
|
-
// console.log(`[DEBUG] Opciones de TypeScript cargadas desde ${configPath}:`);
|
|
39
|
-
// console.log(` noImplicitAny: ${compilerOptions.noImplicitAny}`);
|
|
40
|
-
// console.log(` strict: ${compilerOptions.strict}`);
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
throw new Error(`Error al leer tsconfig.json: ${configError.messageText}`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
console.warn(`[loadTypeScriptConfig] Error cargando ${configPath}:`, error);
|
|
48
|
-
throw new Error(`No se puede continuar sin un tsconfig.json válido. Error: ${error}`);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
throw new Error(`No se encontró tsconfig.json en la raíz del proyecto (${rootConfigPath}) ni en el directorio del archivo. ` +
|
|
53
|
-
`El compilador requiere un tsconfig.json para funcionar correctamente.`);
|
|
54
|
-
}
|
|
55
|
-
// Guardar en cache
|
|
56
|
-
configCache = { path: configPath, options: compilerOptions };
|
|
57
|
-
return compilerOptions;
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* Crea una versión optimizada y serializable de las opciones del compilador typescript.
|
|
61
|
-
* @param options - Opciones originales del compilador
|
|
62
|
-
* @returns Opciones serializables seguras para workers
|
|
63
|
-
*/
|
|
64
|
-
const createSerializableCompilerOptions = (options) => {
|
|
65
|
-
// Respetar exactamente las opciones del tsconfig.json del usuario // Respetar completamente la configuración del usuario del tsconfig.json
|
|
66
|
-
const result = { ...options };
|
|
67
|
-
// NO modificar ninguna opción del usuario - usar configuración exacta del tsconfig.json
|
|
68
|
-
return result;
|
|
69
|
-
};
|
|
70
|
-
/**
|
|
71
|
-
* Crea un Language Service Host optimizado para validación de tipos eficiente.
|
|
72
|
-
*/
|
|
73
|
-
/**
|
|
74
|
-
* Valida tipos en archivos Vue antes de la compilación con soporte mejorado
|
|
75
|
-
* @param vueContent - Contenido del archivo Vue
|
|
76
|
-
* @param fileName - Nombre del archivo Vue
|
|
77
|
-
* @param options - Opciones adicionales para la validación
|
|
78
|
-
* @returns Resultado de la validación de tipos
|
|
79
|
-
*/
|
|
80
|
-
export const validateVueTypes = (vueContent, fileName, options) => {
|
|
81
|
-
// Extraer contenido del script de Vue
|
|
82
|
-
let scriptContent = '';
|
|
83
|
-
if (fileName.endsWith('.vue')) {
|
|
84
|
-
// Extraer contenido entre <script> y </script>
|
|
85
|
-
const scriptMatch = vueContent.match(/<script[^>]*>([\s\S]*?)<\/script>/i);
|
|
86
|
-
if (scriptMatch && scriptMatch[1]) {
|
|
87
|
-
scriptContent = scriptMatch[1].trim();
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
// Si no hay script, no hay nada que validar
|
|
91
|
-
return { diagnostics: [], hasErrors: false };
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
// Para archivos .ts/.js normales, usar todo el contenido
|
|
96
|
-
scriptContent = vueContent;
|
|
97
|
-
}
|
|
98
|
-
// Si el script está vacío, no validar
|
|
99
|
-
if (!scriptContent.trim()) {
|
|
100
|
-
return { diagnostics: [], hasErrors: false };
|
|
101
|
-
}
|
|
102
|
-
// Cargar la configuración del usuario como base
|
|
103
|
-
const userConfig = loadTypeScriptConfig(fileName);
|
|
104
|
-
// Crear opciones del compilador respetando la configuración del usuario
|
|
105
|
-
let compilerOptions;
|
|
106
|
-
if (options?.compilerOptions) {
|
|
107
|
-
// Si se proporcionaron opciones explícitas, usarlas como base
|
|
108
|
-
compilerOptions = { ...options.compilerOptions };
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
// Usar la configuración del usuario como base
|
|
112
|
-
compilerOptions = { ...userConfig };
|
|
113
|
-
}
|
|
114
|
-
// Solo forzar las opciones ABSOLUTAMENTE necesarias para Vue
|
|
115
|
-
// Estas opciones se fuerzan porque son técnicamente requeridas para el funcionamiento correcto
|
|
116
|
-
if (fileName.endsWith('.vue')) {
|
|
117
|
-
// JSX: Necesario para que funcione el template compilation de Vue
|
|
118
|
-
compilerOptions.jsx = typescript.JsxEmit.Preserve;
|
|
119
|
-
// ModuleResolution: Necesario para resolver módulos Vue correctamente
|
|
120
|
-
if (!compilerOptions.moduleResolution) {
|
|
121
|
-
compilerOptions.moduleResolution =
|
|
122
|
-
typescript.ModuleResolutionKind.NodeJs;
|
|
123
|
-
}
|
|
124
|
-
// Lib: Asegurar que DOM esté disponible para archivos Vue, pero respetar otras libs del usuario
|
|
125
|
-
const currentLibs = compilerOptions.lib || userConfig.lib || ['ES2020'];
|
|
126
|
-
const hasDOM = currentLibs.some(lib => typeof lib === 'string' &&
|
|
127
|
-
(lib.toLowerCase().includes('dom') ||
|
|
128
|
-
lib.toLowerCase() === 'dom'));
|
|
129
|
-
if (!hasDOM) {
|
|
130
|
-
compilerOptions.lib = [...currentLibs, 'DOM', 'DOM.Iterable'];
|
|
131
|
-
}
|
|
132
|
-
// Types: Agregar 'vue' si no está presente, pero mantener otros types del usuario
|
|
133
|
-
const currentTypes = compilerOptions.types || userConfig.types || [];
|
|
134
|
-
if (!currentTypes.includes('vue')) {
|
|
135
|
-
compilerOptions.types = [...currentTypes, 'vue'];
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
// Configuraciones que mejoran la detección de errores pero respetan preferencias del usuario
|
|
139
|
-
// Solo se aplican si el usuario no las ha configurado explícitamente
|
|
140
|
-
if (compilerOptions.skipLibCheck === undefined) {
|
|
141
|
-
compilerOptions.skipLibCheck = true; // Para evitar errores en librerías externas
|
|
142
|
-
}
|
|
143
|
-
// Aplicar strictMode solo si el usuario no ha configurado estas opciones individualmente
|
|
144
|
-
if (options?.strictMode !== undefined) {
|
|
145
|
-
if (compilerOptions.noImplicitReturns === undefined) {
|
|
146
|
-
compilerOptions.noImplicitReturns = options.strictMode;
|
|
147
|
-
}
|
|
148
|
-
if (compilerOptions.noImplicitThis === undefined) {
|
|
149
|
-
compilerOptions.noImplicitThis = options.strictMode;
|
|
150
|
-
}
|
|
151
|
-
if (compilerOptions.strictNullChecks === undefined) {
|
|
152
|
-
compilerOptions.strictNullChecks = options.strictMode;
|
|
153
|
-
}
|
|
154
|
-
if (compilerOptions.strictFunctionTypes === undefined) {
|
|
155
|
-
compilerOptions.strictFunctionTypes = options.strictMode;
|
|
156
|
-
}
|
|
157
|
-
if (compilerOptions.exactOptionalPropertyTypes === undefined) {
|
|
158
|
-
compilerOptions.exactOptionalPropertyTypes = false; // Menos estricto por defecto
|
|
159
|
-
}
|
|
160
|
-
if (compilerOptions.noFallthroughCasesInSwitch === undefined) {
|
|
161
|
-
compilerOptions.noFallthroughCasesInSwitch = options.strictMode;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return validateTypesWithLanguageService(fileName, scriptContent, // Usar solo el contenido del script
|
|
165
|
-
compilerOptions);
|
|
166
|
-
};
|
|
167
|
-
/**
|
|
168
|
-
* Limpia los export {} innecesarios que TypeScript agrega automáticamente
|
|
169
|
-
* @param compiledOutput - Código JavaScript compilado
|
|
170
|
-
* @param originalSource - Código TypeScript original
|
|
171
|
-
* @returns Código limpio sin export {} innecesarios
|
|
172
|
-
*/
|
|
173
|
-
const cleanupUnnecessaryExports = (compiledOutput, originalSource) => {
|
|
174
|
-
// Si el output está vacío o solo contiene export {}
|
|
175
|
-
if (compiledOutput.trim() === 'export {};') {
|
|
176
|
-
return '';
|
|
177
|
-
}
|
|
178
|
-
// Verificar si el código fuente original tiene imports/exports reales
|
|
179
|
-
const hasRealImportsExports = /(?:^|\s)(?:import|export)\s+(?!(?:\s*\{\s*\}\s*;?\s*$))/m.test(originalSource);
|
|
180
|
-
// Si no hay imports/exports reales, eliminar export {} del final
|
|
181
|
-
if (!hasRealImportsExports) {
|
|
182
|
-
// Buscar el patrón exacto en el archivo
|
|
183
|
-
const exportPattern = /export\s*\{\s*\}\s*;\s*$/m;
|
|
184
|
-
const hasExportAtEnd = exportPattern.test(compiledOutput);
|
|
185
|
-
if (hasExportAtEnd) {
|
|
186
|
-
return compiledOutput.replace(exportPattern, '');
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
return compiledOutput;
|
|
190
|
-
};
|
|
191
|
-
/**
|
|
192
|
-
* Precompila el código TypeScript con pipeline optimizado para máxima performance.
|
|
193
|
-
* @param {string} data - El código TypeScript a precompilar.
|
|
194
|
-
* @param {string} fileName - El nombre del archivo que contiene el código typescript.
|
|
195
|
-
* @returns {Promise<CompileResult>} - Un objeto con el código precompilado o un error.
|
|
196
|
-
*/
|
|
197
|
-
export const preCompileTS = async (data, fileName) => {
|
|
198
|
-
try {
|
|
199
|
-
// Validación temprana: contenido vacío
|
|
200
|
-
if (!data.trim()) {
|
|
201
|
-
return { error: null, data: data, lang: 'ts' };
|
|
202
|
-
}
|
|
203
|
-
// Cargar configuración de TypeScript desde tsconfig.json
|
|
204
|
-
const compilerOptions = loadTypeScriptConfig(fileName); // PASO 1: Transpilación rápida con detección de errores críticos
|
|
205
|
-
const transpileResult = typescript.transpileModule(data, {
|
|
206
|
-
compilerOptions: {
|
|
207
|
-
...compilerOptions,
|
|
208
|
-
noLib: true,
|
|
209
|
-
skipLibCheck: true,
|
|
210
|
-
isolatedModules: true,
|
|
211
|
-
},
|
|
212
|
-
fileName,
|
|
213
|
-
reportDiagnostics: true,
|
|
214
|
-
});
|
|
215
|
-
// const transpileResult = traspileTStoJS(
|
|
216
|
-
// fileName,data)
|
|
217
|
-
// Verificar errores críticos de sintaxis
|
|
218
|
-
if (transpileResult.diagnostics?.length) {
|
|
219
|
-
const criticalErrors = transpileResult.diagnostics.filter((diag) => {
|
|
220
|
-
if (diag.category !== typescript.DiagnosticCategory.Error)
|
|
221
|
-
return false;
|
|
222
|
-
const messageText = typescript.flattenDiagnosticMessageText(diag.messageText, '\n');
|
|
223
|
-
// Ignorar errores de módulo no encontrado
|
|
224
|
-
return (!messageText.includes('Cannot find module') &&
|
|
225
|
-
!messageText.includes('Could not find source file') &&
|
|
226
|
-
diag.code !== 2307 &&
|
|
227
|
-
diag.code !== 6059);
|
|
228
|
-
});
|
|
229
|
-
if (criticalErrors.length > 0) {
|
|
230
|
-
const errorMessage = createUnifiedErrorMessage(parseTypeScriptErrors(criticalErrors, fileName, data));
|
|
231
|
-
return {
|
|
232
|
-
error: new Error(errorMessage),
|
|
233
|
-
data: null,
|
|
234
|
-
lang: 'ts',
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
} // PASO 2: Type checking opcional (solo si está habilitado)
|
|
238
|
-
// console.log(`[DEBUG] env.typeCheck: ${env.typeCheck}`);
|
|
239
|
-
if (env.typeCheck === 'true') {
|
|
240
|
-
// console.log(`[DEBUG] Iniciando verificación de tipos para: ${fileName}`);
|
|
241
|
-
try {
|
|
242
|
-
const workerPool = TypeScriptWorkerPool.getInstance();
|
|
243
|
-
const serializableOptions = createSerializableCompilerOptions(compilerOptions);
|
|
244
|
-
const typeCheckResult = await workerPool.typeCheck(fileName, data, serializableOptions);
|
|
245
|
-
if (typeCheckResult.hasErrors) {
|
|
246
|
-
const errorMessage = createUnifiedErrorMessage(parseTypeScriptErrors(typeCheckResult.diagnostics, fileName, data));
|
|
247
|
-
return {
|
|
248
|
-
error: new Error(errorMessage),
|
|
249
|
-
data: null,
|
|
250
|
-
lang: 'ts',
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
catch (typeCheckError) {
|
|
255
|
-
// Type checking falla, pero continuar con transpilación
|
|
256
|
-
console.warn('[preCompileTS] ❌ Type checking falló, usando transpilación sin verificación de tipos:', typeCheckError);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
// PASO 3: Devolver resultado optimizado
|
|
260
|
-
let output = transpileResult.outputText;
|
|
261
|
-
// Limpiar export {} innecesarios
|
|
262
|
-
output = cleanupUnnecessaryExports(output, data);
|
|
263
|
-
return { error: null, data: output, lang: 'ts' };
|
|
264
|
-
}
|
|
265
|
-
catch (error) {
|
|
266
|
-
return {
|
|
267
|
-
error: error instanceof Error ? error : new Error('Error desconocido'),
|
|
268
|
-
data: null,
|
|
269
|
-
lang: 'ts',
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
};
|
|
273
|
-
//# sourceMappingURL=typescript-manager.js.map
|
|
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{TypeScriptWorkerPool as d}from"./typescript-worker-pool.js";let f={};export const loadTypeScriptConfig=o=>{let c=i.resolve(a.cwd(),`tsconfig.json`),l=i.dirname(o),u=e.existsSync(c)?c:s.findConfigFile(l,s.sys.fileExists,`tsconfig.json`);if(f.path===u&&f.options)return f.options;let d;if(u&&e.existsSync(u))try{let{config:e,error:a}=s.readConfigFile(u,s.sys.readFile);if(a)throw Error(`Error al leer tsconfig.json: ${a.messageText}`);{let a=s.parseJsonConfigFileContent(e,s.sys,i.dirname(u));d=a.options}}catch(e){throw console.warn(`[loadTypeScriptConfig] Error cargando ${u}:`,e),Error(`No se puede continuar sin un tsconfig.json válido. Error: ${e}`)}else throw Error(`No se encontró tsconfig.json en la raíz del proyecto (${c}) ni en el directorio del archivo. El compilador requiere un tsconfig.json para funcionar correctamente.`);return f={path:u,options:d},d};const p=e=>{let i={...e};return i};export const validateVueTypes=(e,i,a)=>{let o=``;if(i.endsWith(`.vue`)){let i=e.match(/<script[^>]*>([\s\S]*?)<\/script>/i);if(i&&i[1])o=i[1].trim();else return{diagnostics:[],hasErrors:!1}}else o=e;if(!o.trim())return{diagnostics:[],hasErrors:!1};let c=loadTypeScriptConfig(i),l;if(l=a?.compilerOptions?{...a.compilerOptions}:{...c},i.endsWith(`.vue`)){l.jsx=s.JsxEmit.Preserve,l.moduleResolution||=s.ModuleResolutionKind.NodeJs;let e=l.lib||c.lib||[`ES2020`],i=e.some(e=>typeof e==`string`&&(e.toLowerCase().includes(`dom`)||e.toLowerCase()===`dom`));i||(l.lib=[...e,`DOM`,`DOM.Iterable`]);let a=l.types||c.types||[];a.includes(`vue`)||(l.types=[...a,`vue`])}return l.skipLibCheck===void 0&&(l.skipLibCheck=!0),a?.strictMode!==void 0&&(l.noImplicitReturns===void 0&&(l.noImplicitReturns=a.strictMode),l.noImplicitThis===void 0&&(l.noImplicitThis=a.strictMode),l.strictNullChecks===void 0&&(l.strictNullChecks=a.strictMode),l.strictFunctionTypes===void 0&&(l.strictFunctionTypes=a.strictMode),l.exactOptionalPropertyTypes===void 0&&(l.exactOptionalPropertyTypes=!1),l.noFallthroughCasesInSwitch===void 0&&(l.noFallthroughCasesInSwitch=a.strictMode)),u(i,o,l)};const m=(e,i)=>{if(e.trim()===`export {};`)return``;let a=/(?:^|\s)(?:import|export)\s+(?!(?:\s*\{\s*\}\s*;?\s*$))/m.test(i);if(!a){let i=/export\s*\{\s*\}\s*;\s*$/m,a=i.test(e);if(a)return e.replace(i,``)}return e};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=p(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 falló, usando transpilación sin verificación de tipos:`,e)}let f=u.outputText;return f=m(f,e),{error:null,data:f,lang:`ts`}}catch(e){return{error:e instanceof Error?e:Error(`Error desconocido`),data:null,lang:`ts`}}};
|
|
@@ -1,296 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
function
|
|
16
|
-
function
|
|
17
|
-
function
|
|
18
|
-
function
|
|
19
|
-
function
|
|
20
|
-
function
|
|
21
|
-
function
|
|
22
|
-
function
|
|
23
|
-
function
|
|
24
|
-
function
|
|
25
|
-
function
|
|
26
|
-
function onUpdated(fn: () => void): void;
|
|
27
|
-
function onBeforeUpdate(fn: () => void): void;
|
|
28
|
-
function provide<T>(key: string | symbol, value: T): void;
|
|
29
|
-
function inject<T>(key: string | symbol, defaultValue?: T): T | undefined;
|
|
30
|
-
function useSlots(): { [key: string]: (...args: any[]) => any };
|
|
31
|
-
function useAttrs(): { [key: string]: any };
|
|
32
|
-
function useModel<T>(modelName?: string): { value: T };
|
|
33
|
-
function watch<T>(source: () => T, callback: (newValue: T, oldValue: T) => void): void;
|
|
34
|
-
function watchEffect(effect: () => void): void;
|
|
35
|
-
function nextTick(callback?: () => void): Promise<void>;
|
|
36
|
-
function getCurrentInstance(): any;
|
|
37
|
-
function mergeModels<T>(models: T): T;
|
|
38
|
-
}
|
|
39
|
-
declare module '*.vue' {
|
|
40
|
-
const component: any;
|
|
41
|
-
export default component;
|
|
42
|
-
}
|
|
43
|
-
export {};`;
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* Language Service Host para validación de tipos eficiente
|
|
47
|
-
*/
|
|
48
|
-
class TypeScriptLanguageServiceHost {
|
|
49
|
-
files = new Map();
|
|
50
|
-
compilerOptions;
|
|
51
|
-
constructor(compilerOptions) {
|
|
52
|
-
this.compilerOptions = {
|
|
53
|
-
...compilerOptions,
|
|
54
|
-
// Asegurar que las librerías DOM estén incluidas para archivos Vue
|
|
55
|
-
lib: compilerOptions.lib || ['ES2020', 'DOM', 'DOM.Iterable'],
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
addFile(fileName, content) {
|
|
59
|
-
const existing = this.files.get(fileName);
|
|
60
|
-
this.files.set(fileName, {
|
|
61
|
-
version: existing ? existing.version + 1 : 1,
|
|
62
|
-
content,
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
getCompilationSettings() {
|
|
66
|
-
return this.compilerOptions;
|
|
67
|
-
}
|
|
68
|
-
getScriptFileNames() {
|
|
69
|
-
return Array.from(this.files.keys());
|
|
70
|
-
}
|
|
71
|
-
getScriptVersion(fileName) {
|
|
72
|
-
const file = this.files.get(fileName);
|
|
73
|
-
return file ? file.version.toString() : '0';
|
|
74
|
-
}
|
|
75
|
-
getScriptSnapshot(fileName) {
|
|
76
|
-
const file = this.files.get(fileName);
|
|
77
|
-
if (file) {
|
|
78
|
-
return typescript.ScriptSnapshot.fromString(file.content);
|
|
79
|
-
} // Intentar leer el archivo del sistema de archivos para dependencias
|
|
80
|
-
if (fs.existsSync(fileName)) {
|
|
81
|
-
try {
|
|
82
|
-
const content = fs.readFileSync(fileName, 'utf-8');
|
|
83
|
-
return typescript.ScriptSnapshot.fromString(content);
|
|
84
|
-
}
|
|
85
|
-
catch {
|
|
86
|
-
return undefined;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return undefined;
|
|
90
|
-
}
|
|
91
|
-
getCurrentDirectory() {
|
|
92
|
-
return process.cwd();
|
|
93
|
-
}
|
|
94
|
-
getDefaultLibFileName(options) {
|
|
95
|
-
return typescript.getDefaultLibFilePath(options);
|
|
96
|
-
}
|
|
97
|
-
fileExists(path) {
|
|
98
|
-
return this.files.has(path) || fs.existsSync(path);
|
|
99
|
-
}
|
|
100
|
-
readFile(path) {
|
|
101
|
-
const file = this.files.get(path);
|
|
102
|
-
if (file) {
|
|
103
|
-
return file.content;
|
|
104
|
-
}
|
|
105
|
-
if (fs.existsSync(path)) {
|
|
106
|
-
try {
|
|
107
|
-
return fs.readFileSync(path, 'utf-8');
|
|
108
|
-
}
|
|
109
|
-
catch {
|
|
110
|
-
return undefined;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return undefined;
|
|
114
|
-
}
|
|
115
|
-
getNewLine() {
|
|
116
|
-
return typescript.sys.newLine;
|
|
117
|
-
}
|
|
1
|
+
import*as e from"node:fs";import*as t from"node:path";import*as n from"node:process";import*as r from"typescript";const i=()=>`// Declaraciones básicas de tipos Vue para validación
|
|
2
|
+
declare global {
|
|
3
|
+
function ref<T>(value: T): { value: T };
|
|
4
|
+
function reactive<T extends object>(target: T): T;
|
|
5
|
+
function computed<T>(getter: () => T): { value: T };
|
|
6
|
+
function defineComponent<T>(options: T): T;
|
|
7
|
+
function defineProps<T = {}>(): T;
|
|
8
|
+
function defineEmits<T = {}>(): T;
|
|
9
|
+
function defineExpose<T = {}>(exposed: T): void;
|
|
10
|
+
function onMounted(fn: () => void): void;
|
|
11
|
+
function onUnmounted(fn: () => void): void;
|
|
12
|
+
function onBeforeMount(fn: () => void): void;
|
|
13
|
+
function onBeforeUnmount(fn: () => void): void;
|
|
14
|
+
function onUpdated(fn: () => void): void;
|
|
15
|
+
function onBeforeUpdate(fn: () => void): void;
|
|
16
|
+
function provide<T>(key: string | symbol, value: T): void;
|
|
17
|
+
function inject<T>(key: string | symbol, defaultValue?: T): T | undefined;
|
|
18
|
+
function useSlots(): { [key: string]: (...args: any[]) => any };
|
|
19
|
+
function useAttrs(): { [key: string]: any };
|
|
20
|
+
function useModel<T>(modelName?: string): { value: T };
|
|
21
|
+
function watch<T>(source: () => T, callback: (newValue: T, oldValue: T) => void): void;
|
|
22
|
+
function watchEffect(effect: () => void): void;
|
|
23
|
+
function nextTick(callback?: () => void): Promise<void>;
|
|
24
|
+
function getCurrentInstance(): any;
|
|
25
|
+
function mergeModels<T>(models: T): T;
|
|
118
26
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
*/
|
|
126
|
-
export const validateTypesWithLanguageService = (fileName, content, compilerOptions) => {
|
|
127
|
-
try {
|
|
128
|
-
// Si el script está vacío o es solo espacios en blanco, no validar
|
|
129
|
-
if (!content.trim()) {
|
|
130
|
-
return { diagnostics: [], hasErrors: false };
|
|
131
|
-
} // Crear Language Service Host
|
|
132
|
-
const host = new TypeScriptLanguageServiceHost(compilerOptions);
|
|
133
|
-
// Para archivos Vue, crear un archivo virtual .ts
|
|
134
|
-
let actualFileName = fileName;
|
|
135
|
-
if (fileName.endsWith('.vue')) {
|
|
136
|
-
// Crear un nombre de archivo virtual con extensión .ts
|
|
137
|
-
actualFileName = fileName.replace('.vue', '.vue.ts');
|
|
138
|
-
}
|
|
139
|
-
// Agregar el archivo al host con el nombre correcto
|
|
140
|
-
host.addFile(actualFileName, content);
|
|
141
|
-
// Agregar declaraciones de tipos para Vue si es necesario
|
|
142
|
-
if (fileName.endsWith('.vue')) {
|
|
143
|
-
// Cargar declaraciones de tipos Vue desde archivo shims
|
|
144
|
-
const projectRoot = process.cwd();
|
|
145
|
-
const vueShimsPath = path.join(projectRoot, 'src/types/vue-shims.d.ts');
|
|
146
|
-
try {
|
|
147
|
-
if (fs.existsSync(vueShimsPath)) {
|
|
148
|
-
const vueShimsContent = fs.readFileSync(vueShimsPath, 'utf-8');
|
|
149
|
-
host.addFile(vueShimsPath, vueShimsContent);
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
// Fallback a declaraciones básicas si no se encuentra el archivo shims
|
|
153
|
-
const basicVueTypes = generateBasicVueTypes();
|
|
154
|
-
const fallbackTypesPath = path.join(path.dirname(fileName), 'vue-fallback.d.ts');
|
|
155
|
-
host.addFile(fallbackTypesPath, basicVueTypes);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
catch (error) {
|
|
159
|
-
// Si hay error cargando los tipos, usar fallback básico
|
|
160
|
-
console.warn('Error al cargar tipos Vue:', error);
|
|
161
|
-
const basicVueTypes = generateBasicVueTypes();
|
|
162
|
-
const fallbackTypesPath = path.join(path.dirname(fileName), 'vue-fallback.d.ts');
|
|
163
|
-
host.addFile(fallbackTypesPath, basicVueTypes);
|
|
164
|
-
}
|
|
165
|
-
} // Crear Language Service
|
|
166
|
-
const languageService = typescript.createLanguageService(host);
|
|
167
|
-
try {
|
|
168
|
-
// Verificar que el archivo existe en el host antes de solicitar diagnósticos
|
|
169
|
-
if (!host.fileExists(actualFileName)) {
|
|
170
|
-
console.log('File does not exist in host, returning empty result');
|
|
171
|
-
return { diagnostics: [], hasErrors: false };
|
|
172
|
-
} // Obtener diagnósticos de tipos con manejo de errores
|
|
173
|
-
let syntacticDiagnostics = [];
|
|
174
|
-
let semanticDiagnostics = [];
|
|
175
|
-
try {
|
|
176
|
-
syntacticDiagnostics =
|
|
177
|
-
languageService.getSyntacticDiagnostics(actualFileName);
|
|
178
|
-
}
|
|
179
|
-
catch {
|
|
180
|
-
// Ignorar errores de diagnósticos sintácticos
|
|
181
|
-
}
|
|
182
|
-
try {
|
|
183
|
-
semanticDiagnostics =
|
|
184
|
-
languageService.getSemanticDiagnostics(actualFileName);
|
|
185
|
-
}
|
|
186
|
-
catch {
|
|
187
|
-
// Ignorar errores de diagnósticos semánticos
|
|
188
|
-
}
|
|
189
|
-
// Combinar todos los diagnósticos
|
|
190
|
-
const allDiagnostics = [
|
|
191
|
-
...syntacticDiagnostics,
|
|
192
|
-
...semanticDiagnostics,
|
|
193
|
-
];
|
|
194
|
-
// Filtrar diagnósticos relevantes con mejor manejo para Vue
|
|
195
|
-
const filteredDiagnostics = allDiagnostics.filter((diag) => {
|
|
196
|
-
const messageText = typescript.flattenDiagnosticMessageText(diag.messageText, '\n');
|
|
197
|
-
// Solo errores de categoría Error (no warnings)
|
|
198
|
-
if (diag.category !== typescript.DiagnosticCategory.Error) {
|
|
199
|
-
return false;
|
|
200
|
-
} // Errores de infraestructura que siempre se filtran
|
|
201
|
-
const infrastructureErrors = [
|
|
202
|
-
'Cannot find module',
|
|
203
|
-
'Could not find source file',
|
|
204
|
-
"has no exported member 'mergeModels'",
|
|
205
|
-
'Unable to resolve signature of method decorator',
|
|
206
|
-
'The runtime will invoke the decorator with',
|
|
207
|
-
'Module resolution kind is not specified',
|
|
208
|
-
'Cannot resolve module',
|
|
209
|
-
"Cannot find name 'console'", // Error común al usar console en entorno sin DOM
|
|
210
|
-
'Do you need to change your target library', // Sugerencia de librerías
|
|
211
|
-
];
|
|
212
|
-
for (const errorPattern of infrastructureErrors) {
|
|
213
|
-
if (messageText.includes(errorPattern)) {
|
|
214
|
-
return false;
|
|
215
|
-
}
|
|
216
|
-
} // Códigos de error específicos que se filtran
|
|
217
|
-
const filteredErrorCodes = [
|
|
218
|
-
1241, // decorator signature mismatch
|
|
219
|
-
2307, // Cannot find module (redundant but explicit)
|
|
220
|
-
2584, // Cannot find name (ej: console sin DOM lib)
|
|
221
|
-
6133, // unused variables (warnings, not errors in this context)
|
|
222
|
-
];
|
|
223
|
-
if (filteredErrorCodes.includes(diag.code)) {
|
|
224
|
-
return false;
|
|
225
|
-
}
|
|
226
|
-
// Para archivos Vue, filtrar solo errores específicos de infraestructura
|
|
227
|
-
if (fileName.endsWith('.vue')) {
|
|
228
|
-
// Parámetros implícitos generados automáticamente por Vue
|
|
229
|
-
const vueImplicitParams = [
|
|
230
|
-
'$props',
|
|
231
|
-
'$setup',
|
|
232
|
-
'$data',
|
|
233
|
-
'$options',
|
|
234
|
-
'$event',
|
|
235
|
-
'_ctx',
|
|
236
|
-
'_cache',
|
|
237
|
-
'__expose',
|
|
238
|
-
'__emit',
|
|
239
|
-
'__slots',
|
|
240
|
-
'__props',
|
|
241
|
-
'__defaults',
|
|
242
|
-
];
|
|
243
|
-
// Solo filtrar errores de 'any' implícito para parámetros de infraestructura de Vue
|
|
244
|
-
if (messageText.includes("implicitly has an 'any' type")) {
|
|
245
|
-
const hasVueImplicitParam = vueImplicitParams.some(param => messageText.includes(`'${param}'`) ||
|
|
246
|
-
messageText.includes(`"${param}"`));
|
|
247
|
-
if (hasVueImplicitParam) {
|
|
248
|
-
return false;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
// Filtrar errores específicos de setup function
|
|
252
|
-
if (messageText.includes('Parameter') &&
|
|
253
|
-
messageText.includes('implicitly has an') &&
|
|
254
|
-
vueImplicitParams.some(param => messageText.includes(param))) {
|
|
255
|
-
return false;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
// Mantener TODOS los demás errores - especialmente errores de tipos del usuario
|
|
259
|
-
return true;
|
|
260
|
-
});
|
|
261
|
-
return {
|
|
262
|
-
diagnostics: filteredDiagnostics,
|
|
263
|
-
hasErrors: filteredDiagnostics.length > 0,
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
catch {
|
|
267
|
-
return { diagnostics: [], hasErrors: false };
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
catch (error) {
|
|
271
|
-
// En caso de error, devolver diagnóstico de error
|
|
272
|
-
const errorDiagnostic = {
|
|
273
|
-
file: undefined,
|
|
274
|
-
start: undefined,
|
|
275
|
-
length: undefined,
|
|
276
|
-
messageText: `Error en validación de tipos: ${error instanceof Error ? error.message : 'Error desconocido'}`,
|
|
277
|
-
category: typescript.DiagnosticCategory.Error,
|
|
278
|
-
code: 0,
|
|
279
|
-
};
|
|
280
|
-
return {
|
|
281
|
-
diagnostics: [errorDiagnostic],
|
|
282
|
-
hasErrors: true,
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
/**
|
|
287
|
-
* Valida tipos en archivos Vue antes de la compilación (versión síncrona)
|
|
288
|
-
* @param vueContent - Contenido del archivo Vue
|
|
289
|
-
* @param fileName - Nombre del archivo Vue
|
|
290
|
-
* @param compilerOptions - Opciones del compilador
|
|
291
|
-
* @returns Resultado de la validación de tipos
|
|
292
|
-
*/
|
|
293
|
-
export const validateVueTypes = (vueContent, fileName, compilerOptions) => {
|
|
294
|
-
return validateTypesWithLanguageService(fileName, vueContent, compilerOptions);
|
|
295
|
-
};
|
|
296
|
-
//# sourceMappingURL=typescript-sync-validator.js.map
|
|
27
|
+
declare module '*.vue' {
|
|
28
|
+
const component: any;
|
|
29
|
+
export default component;
|
|
30
|
+
}
|
|
31
|
+
export {};`;class a{files=new Map;compilerOptions;constructor(e){this.compilerOptions={...e,lib:e.lib||[`ES2020`,`DOM`,`DOM.Iterable`]}}addFile(e,t){let n=this.files.get(e);this.files.set(e,{version:n?n.version+1:1,content:t})}getCompilationSettings(){return this.compilerOptions}getScriptFileNames(){return Array.from(this.files.keys())}getScriptVersion(e){let t=this.files.get(e);return t?t.version.toString():`0`}getScriptSnapshot(t){let n=this.files.get(t);if(n)return r.ScriptSnapshot.fromString(n.content);if(e.existsSync(t))try{let n=e.readFileSync(t,`utf-8`);return r.ScriptSnapshot.fromString(n)}catch{return}}getCurrentDirectory(){return n.cwd()}getDefaultLibFileName(e){return r.getDefaultLibFilePath(e)}fileExists(t){return this.files.has(t)||e.existsSync(t)}readFile(t){let n=this.files.get(t);if(n)return n.content;if(e.existsSync(t))try{return e.readFileSync(t,`utf-8`)}catch{return}}getNewLine(){return r.sys.newLine}}export const validateTypesWithLanguageService=(o,s,c)=>{try{if(!s.trim())return{diagnostics:[],hasErrors:!1};let l=new a(c),u=o;if(o.endsWith(`.vue`)&&(u=o.replace(`.vue`,`.vue.ts`)),l.addFile(u,s),o.endsWith(`.vue`)){let r=n.cwd(),a=t.join(r,`src/types/vue-shims.d.ts`);try{if(e.existsSync(a)){let t=e.readFileSync(a,`utf-8`);l.addFile(a,t)}else{let e=i(),n=t.join(t.dirname(o),`vue-fallback.d.ts`);l.addFile(n,e)}}catch(e){console.warn(`Error al cargar tipos Vue:`,e);let n=i(),r=t.join(t.dirname(o),`vue-fallback.d.ts`);l.addFile(r,n)}}let d=r.createLanguageService(l);try{if(!l.fileExists(u))return console.log(`File does not exist in host, returning empty result`),{diagnostics:[],hasErrors:!1};let e=[],t=[];try{e=d.getSyntacticDiagnostics(u)}catch{}try{t=d.getSemanticDiagnostics(u)}catch{}let n=[...e,...t],i=n.filter(e=>{let t=r.flattenDiagnosticMessageText(e.messageText,`
|
|
32
|
+
`);if(e.category!==r.DiagnosticCategory.Error)return!1;let n=[`Cannot find module`,`Could not find source file`,`has no exported member 'mergeModels'`,`Unable to resolve signature of method decorator`,`The runtime will invoke the decorator with`,`Module resolution kind is not specified`,`Cannot resolve module`,`Cannot find name 'console'`,`Do you need to change your target library`];for(let e of n)if(t.includes(e))return!1;let i=[1241,2307,2584,6133];if(i.includes(e.code))return!1;if(o.endsWith(`.vue`)){let e=[`$props`,`$setup`,`$data`,`$options`,`$event`,`_ctx`,`_cache`,`__expose`,`__emit`,`__slots`,`__props`,`__defaults`];if(t.includes(`implicitly has an 'any' type`)){let n=e.some(e=>t.includes(`'${e}'`)||t.includes(`"${e}"`));if(n)return!1}if(t.includes(`Parameter`)&&t.includes(`implicitly has an`)&&e.some(e=>t.includes(e)))return!1}return!0});return{diagnostics:i,hasErrors:i.length>0}}catch{return{diagnostics:[],hasErrors:!1}}}catch(e){let t={file:void 0,start:void 0,length:void 0,messageText:`Error en validación de tipos: ${e instanceof Error?e.message:`Error desconocido`}`,category:r.DiagnosticCategory.Error,code:0};return{diagnostics:[t],hasErrors:!0}}};export const validateVueTypes=(e,t,n)=>validateTypesWithLanguageService(t,e,n);
|