versacompiler 1.0.5 → 2.0.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 (42) hide show
  1. package/README.md +357 -145
  2. package/dist/compiler/compile.js +1120 -0
  3. package/dist/compiler/error-reporter.js +467 -0
  4. package/dist/compiler/linter.js +72 -0
  5. package/dist/{services → compiler}/minify.js +40 -31
  6. package/dist/compiler/parser.js +30 -0
  7. package/dist/compiler/tailwindcss.js +39 -0
  8. package/dist/compiler/transformTStoJS.js +16 -0
  9. package/dist/compiler/transforms.js +544 -0
  10. package/dist/compiler/typescript-error-parser.js +282 -0
  11. package/dist/compiler/typescript-sync-validator.js +230 -0
  12. package/dist/compiler/typescript-worker-thread.cjs +457 -0
  13. package/dist/compiler/typescript-worker.js +309 -0
  14. package/dist/compiler/typescript.js +382 -0
  15. package/dist/compiler/vuejs.js +296 -0
  16. package/dist/hrm/VueHRM.js +353 -0
  17. package/dist/hrm/errorScreen.js +23 -1
  18. package/dist/hrm/getInstanciaVue.js +313 -0
  19. package/dist/hrm/initHRM.js +140 -0
  20. package/dist/main.js +287 -0
  21. package/dist/servicios/browserSync.js +177 -0
  22. package/dist/servicios/chokidar.js +178 -0
  23. package/dist/servicios/logger.js +33 -0
  24. package/dist/servicios/readConfig.js +429 -0
  25. package/dist/utils/module-resolver.js +506 -0
  26. package/dist/utils/promptUser.js +48 -0
  27. package/dist/utils/resolve-bin.js +29 -0
  28. package/dist/utils/utils.js +8 -35
  29. package/dist/wrappers/eslint-node.js +145 -0
  30. package/dist/wrappers/oxlint-node.js +120 -0
  31. package/dist/wrappers/tailwind-node.js +92 -0
  32. package/package.json +62 -17
  33. package/dist/hrm/devMode.js +0 -346
  34. package/dist/hrm/instanciaVue.js +0 -35
  35. package/dist/hrm/setupHMR.js +0 -57
  36. package/dist/index.js +0 -1010
  37. package/dist/services/acorn.js +0 -29
  38. package/dist/services/linter.js +0 -55
  39. package/dist/services/typescript.js +0 -89
  40. package/dist/services/vueLoader.js +0 -326
  41. package/dist/services/vuejs.js +0 -259
  42. package/dist/utils/transformWithAcorn.js +0 -316
@@ -1,29 +0,0 @@
1
- import * as Parser from 'acorn';
2
- import chalk from 'chalk';
3
- /**
4
- * Parses the given JavaScript code using Acorn and returns the Abstract Syntax Tree (AST).
5
- *
6
- * @param {string} data - The JavaScript code to be parsed.
7
- * @returns {Promise<Object|null>} The parsed AST object if successful, or null if an error occurs.
8
- * @throws {Error} If there is an error during parsing, it logs the error details and stack trace.
9
- */
10
- export const checkSintaxysAcorn = async data => {
11
- try {
12
- const ast = await Parser.parse(data, {
13
- ecmaVersion: 2020,
14
- sourceType: 'module',
15
- locations: true,
16
- ranges: true,
17
- });
18
-
19
- return { ast, error: null };
20
- } catch (error) {
21
- console.log(
22
- chalk.red(
23
- `🚩 :Error durante la compilación JS:${error.loc.line}:${error.loc.column}: ${error.message}\n`,
24
- ),
25
- );
26
- console.error(error.stack); // Imprime la pila de llamadas para depuración
27
- return { ast: null, error };
28
- }
29
- };
@@ -1,55 +0,0 @@
1
- import { spawnSync } from 'node:child_process';
2
- import chalk from 'chalk';
3
- export const linter = async filePath => {
4
- // 1. Calcula la ruta del binario
5
- const oxlintExe = 'npx oxlint';
6
- const args = filePath ? [filePath] : [];
7
- // const args = filePath ? [`${filePath}`] : [];
8
- const processOXC = spawnSync(
9
- oxlintExe,
10
- args, // Ejecuta en lote (ej: ['src/**/*.js', 'lib/*.ts', 'lib/*.vue'])
11
- {
12
- stdio: 'pipe',
13
- encoding: 'utf-8', // Evita .toString()
14
- shell: true, // ¡Más rápido sin shell!
15
- },
16
- );
17
- if (processOXC.error) {
18
- console.error(
19
- chalk.red('🚨 Error ejecutando oxlint:', processOXC.error),
20
- );
21
- return false;
22
- }
23
-
24
- const output = processOXC.stdout.trim();
25
- if (!output) {
26
- console.log(chalk.green('✅ No se encontraron errores de linting.'));
27
- return true;
28
- }
29
-
30
- // Regex optimizado (unificado)
31
- const LINT_REGEX =
32
- /([×x!]|warning)\s+([^:]+):\s+([^\n]+)\n\s+[,╭][-─]\[([^\]]+)\][\s\S]+?help:\s+([^\n]+)/gi;
33
- const matches = output.matchAll(LINT_REGEX);
34
- let errorFiles = 0; // Reiniciar el contador de archivos con errores
35
- const errorList = []; // Lista de errores
36
- for (const match of matches) {
37
- const [_, severitySymbol, ruleId, message, filePath, help] = match;
38
- const normalizedPath = filePath.trim().replace(/\\/g, '/');
39
-
40
- errorFiles++;
41
- errorList.push({
42
- file: normalizedPath,
43
- error: `${ruleId}: ${message.trim()}`,
44
- proceso: 'Linting',
45
- help: help.trim(),
46
- severity: severitySymbol === '!' ? 'warning' : 'error',
47
- });
48
- }
49
-
50
- return {
51
- error: errorFiles > 0,
52
- errorFiles,
53
- errorList,
54
- };
55
- };
@@ -1,89 +0,0 @@
1
- import { readFile } from 'node:fs/promises';
2
- import path from 'node:path';
3
- import * as ts from 'typescript';
4
- /**
5
- * Precompila el código TypeScript proporcionado.
6
- * @param {string} data - El código TypeScript a precompilar.
7
- * @param {string} fileName - El nombre del archivo que contiene el código TypeScript.
8
- *
9
- * @returns {Promise<Object>} - Un objeto con el código precompilado o un error.
10
- */
11
- export const preCompileTS = async (data, fileName, PATH_CONFIG_FILE) => {
12
- try {
13
- // Leer tsconfig.json
14
- const tsConfigContent = await readFile(PATH_CONFIG_FILE, 'utf-8');
15
- if (!tsConfigContent) {
16
- throw new Error(
17
- `No se pudo leer el archivo tsconfig.json en: ${PATH_CONFIG_FILE}`,
18
- );
19
- }
20
-
21
- const tsConfig = JSON.parse(tsConfigContent);
22
-
23
- // Obtener las opciones del compilador
24
- const { compilerOptions } = tsConfig;
25
-
26
- if (!compilerOptions) {
27
- throw new Error(
28
- 'No se encontraron compilerOptions en tsconfig.json',
29
- );
30
- }
31
-
32
- // Crear host de configuración de parseo
33
- const parseConfigHost = {
34
- useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,
35
- readDirectory: ts.sys.readDirectory,
36
- fileExists: ts.sys.fileExists,
37
- readFile: ts.sys.readFile,
38
- onUnRecoverableConfigFileDiagnostic: diagnostic => {
39
- throw new Error(
40
- ts.flattenDiagnosticMessageText(
41
- diagnostic.messageText,
42
- '\n',
43
- ),
44
- );
45
- },
46
- };
47
-
48
- // Parsear la configuración para que TS la entienda
49
- const parsedConfig = ts.parseJsonConfigFileContent(
50
- tsConfig,
51
- parseConfigHost,
52
- path.dirname(PATH_CONFIG_FILE),
53
- );
54
- if (parsedConfig.errors.length) {
55
- const errors = parsedConfig.errors.map(diagnostic =>
56
- ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'),
57
- );
58
- throw new Error(
59
- `Error al parsear tsconfig.json:\n${errors.join('\n')}`,
60
- );
61
- }
62
-
63
- // Transpilar el código
64
- const result = ts.transpileModule(data, {
65
- compilerOptions: parsedConfig.options,
66
- reportDiagnostics: true,
67
- fileName,
68
- });
69
- if (result.diagnostics && result.diagnostics.length > 0) {
70
- const errors = result.diagnostics.map(diagnostic => {
71
- if (diagnostic.file) {
72
- const { line, character } =
73
- diagnostic.file.getLineAndCharacterOfPosition(
74
- diagnostic.start,
75
- );
76
- return `${ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')} - ${diagnostic.file.fileName} (${line + 1},${character + 1})`;
77
- } else {
78
- return `${ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`;
79
- }
80
- });
81
-
82
- throw new Error(`${errors.join('\n')}`);
83
- }
84
-
85
- return { error: null, data: result.outputText };
86
- } catch (error) {
87
- return { error, data: null };
88
- }
89
- };
@@ -1,326 +0,0 @@
1
- let getInstancia,
2
- getVueInstance,
3
- showErrorOverlay,
4
- hideErrorOverlay,
5
- reloadComponent,
6
- reloadJS;
7
-
8
- // En navegador: usar rutas relativas estáticas
9
- (async () => {
10
- try {
11
- // Importa todas las dependencias HMR necesarias aquí
12
- // CORREGIR RUTA DE IMPORTACIÓN PARA devMode.js
13
- const devModeModule = await import('./hrm/devMode.js');
14
- reloadComponent = devModeModule.reloadComponent;
15
- reloadJS = devModeModule.reloadJS;
16
-
17
- // Log para verificar la carga de reloadComponent
18
- if (typeof reloadComponent === 'function') {
19
- console.log(
20
- '[HMR] La función reloadComponent se cargó correctamente.',
21
- );
22
- } else {
23
- console.error(
24
- '[HMR] ERROR: La función reloadComponent NO se cargó o no es una función después de la importación.',
25
- devModeModule,
26
- );
27
- }
28
-
29
- getInstancia = (await import('./hrm/instanciaVue.js')).default; // Asumiendo que está en dist/hrm/
30
- getVueInstance = (await import('./hrm/setupHMR.js')).getVueInstance; // Asumiendo que está en dist/hrm/
31
-
32
- const errorScreenModule = await import('./hrm/errorScreen.js'); // Asumiendo que está en dist/hrm/
33
- showErrorOverlay = errorScreenModule.showErrorOverlay;
34
- hideErrorOverlay = errorScreenModule.hideErrorOverlay;
35
-
36
- // Esperar a que BrowserSync client esté listo y haya definido ___browserSync___
37
- let bsReadyRetries = 0;
38
- const maxBsReadyRetries = 30; // 30 * 500ms = 15 segundos de espera máxima
39
- const bsReadyCheckInterval = 500;
40
-
41
- while (
42
- !window.___browserSync___ &&
43
- bsReadyRetries < maxBsReadyRetries
44
- ) {
45
- console.warn(
46
- `[HMR] Esperando a que el script cliente de BrowserSync se inicialice... (${
47
- bsReadyRetries + 1
48
- }/${maxBsReadyRetries})`,
49
- );
50
- await new Promise(resolve =>
51
- setTimeout(resolve, bsReadyCheckInterval),
52
- );
53
- bsReadyRetries++;
54
- }
55
-
56
- if (!window.___browserSync___) {
57
- console.error(
58
- '❌ Versa HMR: El script cliente de BrowserSync no se inicializó después de múltiples reintentos. HMR no funcionará.',
59
- );
60
- if (showErrorOverlay) {
61
- // Verificar si showErrorOverlay se cargó
62
- showErrorOverlay(
63
- 'Falló la inicialización de HMR',
64
- 'El cliente de BrowserSync no se inicializó. Revisa la consola y el servidor de BrowserSync.',
65
- );
66
- }
67
- return; // Detener la ejecución si BrowserSync no está listo
68
- }
69
-
70
- console.log(
71
- '✔️ Versa HMR: Cliente de BrowserSync detectado. Procediendo con la configuración de HMR.',
72
- );
73
- await initSocket(); // Llama a initSocket DESPUÉS de que las importaciones y la espera de BS hayan terminado
74
- } catch (error) {
75
- console.error(
76
- '❌ Versa HMR: Error durante la carga dinámica de módulos o initSocket:',
77
- error,
78
- );
79
- if (showErrorOverlay) {
80
- showErrorOverlay(
81
- 'Falló la inicialización de HMR',
82
- error.stack || error.message,
83
- );
84
- } else {
85
- const errDiv = document.createElement('div');
86
- errDiv.textContent =
87
- 'Falló la inicialización de HMR: ' + error.message;
88
- errDiv.style.cssText =
89
- 'position:fixed;top:10px;left:10px;padding:10px;background:red;color:white;z-index:1000000;';
90
- document.body.appendChild(errDiv);
91
- }
92
- }
93
- })();
94
-
95
- // Obtención robusta de la instancia de Vue
96
- const getInstanceVue = async () => {
97
- let instance = getVueInstance && getVueInstance();
98
- if (instance) return instance;
99
- if (typeof window !== 'undefined') {
100
- if (window.__VUE_APP__) return window.__VUE_APP__;
101
- if (
102
- window.__VUE_APP_INSTANCE__ &&
103
- typeof window.__VUE_APP_INSTANCE__.get === 'function'
104
- ) {
105
- const winInstance = window.__VUE_APP_INSTANCE__.get();
106
- if (winInstance) return winInstance;
107
- }
108
- }
109
- instance = getInstancia && getInstancia.methods.get();
110
- if (instance) return instance;
111
- return null;
112
- };
113
-
114
- // Reintentos con backoff exponencial para obtener la instancia
115
- async function waitForVueInstance(maxTries = 5, delay = 300) {
116
- let tries = 0;
117
- while (tries < maxTries) {
118
- const instance = await getInstanceVue();
119
- if (instance) return instance;
120
- await new Promise(resolve =>
121
- globalThis.setTimeout(resolve, delay * 2 ** tries),
122
- );
123
- tries++;
124
- }
125
- // Si no se encuentra, muestra overlay y no recarga
126
- const errorMsg =
127
- 'Instancia de Vue no encontrada después de múltiples reintentos.';
128
- const detailMsg =
129
- 'La aplicación no pudo iniciarse. Esperando una corrección para recargar.';
130
- if (typeof showErrorOverlay === 'function') {
131
- showErrorOverlay(errorMsg, detailMsg);
132
- } else {
133
- console.error(
134
- '[HMR] showErrorOverlay no disponible, pero la instancia de Vue no se encontró.',
135
- );
136
- }
137
- console.error(errorMsg);
138
- return null; // Indica que falló
139
- }
140
-
141
- // Initialize socket connection and HMR con reconexión automática
142
- const initSocket = async (retries = 0) => {
143
- const maxRetries = 10;
144
- const retryDelay = Math.min(2000 * (retries + 1), 10000); // backoff hasta 10s
145
-
146
- // Se asume que window.___browserSync___ ya existe debido a la espera en la IIFE
147
- // Pero se verifica window.___browserSync___.socket
148
- if (window.___browserSync___ && window.___browserSync___.socket) {
149
- const socket = window.___browserSync___.socket;
150
- let connected = socket.connected; // Verificar estado inicial
151
-
152
- // Listener para conexión
153
- socket.on('connect', async () => {
154
- connected = true;
155
- if (typeof hideErrorOverlay === 'function') {
156
- hideErrorOverlay();
157
- } else {
158
- console.warn(
159
- '[HMR] hideErrorOverlay no es una función al momento de la conexión',
160
- );
161
- }
162
- await waitForVueInstance();
163
- // if (vueAppInstance && vueAppInstance._instance) {
164
- // if (typeof socketReload === 'function') {
165
- // socketReload(vueAppInstance);
166
- // } else {
167
- // console.warn(
168
- // '[HMR] socketReload no es una función al momento de la conexión',
169
- // );
170
- // }
171
- // } else {
172
- // console.error(
173
- // '❌ Versa HMR: Instancia de Vue no encontrada después de la conexión del socket',
174
- // );
175
- // }
176
- console.log('✔️ Versa HMR: Socket conectado');
177
- });
178
-
179
- // Listener para desconexión
180
- socket.on('disconnect', () => {
181
- connected = false;
182
- console.log('❌ Versa HMR: Socket desconectado, reintentando...');
183
- // La lógica de reintentos original para desconexión
184
- setTimeout(() => {
185
- if (!socket.connected && retries < maxRetries) {
186
- // Usar socket.connected aquí
187
- initSocket(retries + 1);
188
- } else if (!socket.connected) {
189
- console.error(
190
- `❌ Versa HMR: Socket no conectado después de ${maxRetries} reintentos tras desconexión.`,
191
- );
192
- if (typeof showErrorOverlay === 'function') {
193
- showErrorOverlay(
194
- 'HMR Desconectado',
195
- 'No se pudo reconectar a BrowserSync después de múltiples reintentos.',
196
- );
197
- }
198
- }
199
- }, retryDelay);
200
- });
201
-
202
- socket.on('vue:update', async data => {
203
- // Log para verificar reloadComponent al inicio del evento
204
- if (typeof reloadComponent !== 'function') {
205
- console.error(
206
- '[HMR] ERROR en vue:update: reloadComponent no es una función.',
207
- );
208
- if (typeof showErrorOverlay === 'function') {
209
- showErrorOverlay(
210
- 'Error Crítico de HMR',
211
- 'reloadComponent no está disponible. Verifique la consola para errores de carga.',
212
- );
213
- }
214
- return;
215
- }
216
-
217
- if (typeof hideErrorOverlay === 'function') hideErrorOverlay();
218
- else
219
- console.warn(
220
- '[HMR] hideErrorOverlay no disponible en vue:update',
221
- );
222
-
223
- const { component, relativePath, extension, type, timestamp } =
224
- data;
225
- const appInstance = await getInstanceVue();
226
-
227
- if (!appInstance) {
228
- // Si la instancia de Vue no existe, la carga inicial probablemente falló.
229
- // Una actualización de módulo (presumiblemente la corrección del error) ha llegado.
230
- // Recargar la página completa para permitir que vue-loader.ts intente de nuevo.
231
- console.log(
232
- '[HMR] La instancia de Vue no existe (posible fallo en la carga inicial). Se recibió una actualización de módulo. Recargando la página...',
233
- );
234
- window.location.reload();
235
- return; // Detener la ejecución adicional de HMR para esta actualización.
236
- }
237
-
238
- try {
239
- let result;
240
- if (extension === 'vue') {
241
- result = await reloadComponent(
242
- appInstance,
243
- component,
244
- `${relativePath}`,
245
- type,
246
- extension,
247
- );
248
- if (result && result.msg) {
249
- throw new Error(result.msg);
250
- }
251
- } else {
252
- // Asumiendo que reloadJS existe
253
- result = await reloadJS(`/${relativePath}?t=${timestamp}`);
254
- if (result && result.msg) {
255
- throw new Error(result.msg);
256
- }
257
- }
258
- } catch (hmrError) {
259
- const errorMsg = `HMR falló para ${relativePath}`;
260
- const errorStack =
261
- hmrError.stack ||
262
- (hmrError.toString
263
- ? hmrError.toString()
264
- : 'No hay stack disponible');
265
- if (typeof showErrorOverlay === 'function') {
266
- showErrorOverlay(errorMsg, errorStack);
267
- } else {
268
- console.error(
269
- '[HMR] showErrorOverlay no disponible. Error HMR:',
270
- errorMsg,
271
- hmrError,
272
- );
273
- }
274
- console.error(errorMsg, hmrError);
275
- }
276
- });
277
-
278
- // Watchdog para la conexión inicial si el socket existe pero no está conectado
279
- if (!connected) {
280
- console.log(
281
- `Versa HMR: Objeto socket encontrado, intentando conexión (Intento ${
282
- retries + 1
283
- }/${maxRetries})`,
284
- );
285
- setTimeout(() => {
286
- if (!socket.connected && retries < maxRetries) {
287
- console.warn(
288
- 'Versa HMR: Sin conexión de socket después del tiempo de espera inicial, reintentando initSocket...',
289
- );
290
- initSocket(retries + 1);
291
- } else if (!socket.connected) {
292
- console.error(
293
- `❌ Versa HMR: Socket aún no conectado después de ${maxRetries} intentos iniciales.`,
294
- );
295
- if (typeof showErrorOverlay === 'function') {
296
- showErrorOverlay(
297
- 'Falló HMR de BrowserSync',
298
- 'No se pudo conectar al socket de BrowserSync después de intentos iniciales.',
299
- );
300
- }
301
- }
302
- }, 5000); // Timeout de 5s para el watchdog inicial
303
- }
304
- } else {
305
- // Este bloque se ejecuta si window.___browserSync___ existe pero window.___browserSync___.socket no,
306
- // o si window.___browserSync___ no existe (aunque la IIFE debería haberlo esperado).
307
- console.warn(
308
- `[HMR] Socket de BrowserSync no encontrado o BrowserSync no completamente inicializado. Reintentando initSocket... (${
309
- retries + 1
310
- }/${maxRetries})`,
311
- );
312
- if (retries < maxRetries) {
313
- setTimeout(() => initSocket(retries + 1), retryDelay);
314
- } else {
315
- console.error(
316
- `❌ Versa HMR: Socket de BrowserSync no encontrado después de ${maxRetries} reintentos.`,
317
- );
318
- if (typeof showErrorOverlay === 'function') {
319
- showErrorOverlay(
320
- 'Falló HMR de BrowserSync',
321
- 'Socket o cliente de BrowserSync no encontrado después de múltiples reintentos.',
322
- );
323
- }
324
- }
325
- }
326
- };