wu-framework 1.1.6 → 1.1.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.
Files changed (90) hide show
  1. package/README.md +511 -977
  2. package/dist/wu-framework.cjs.js +3 -1
  3. package/dist/wu-framework.cjs.js.map +1 -0
  4. package/dist/wu-framework.dev.js +7533 -2761
  5. package/dist/wu-framework.dev.js.map +1 -1
  6. package/dist/wu-framework.esm.js +3 -0
  7. package/dist/wu-framework.esm.js.map +1 -0
  8. package/dist/wu-framework.umd.js +3 -1
  9. package/dist/wu-framework.umd.js.map +1 -0
  10. package/integrations/astro/README.md +127 -0
  11. package/integrations/astro/WuApp.astro +63 -0
  12. package/integrations/astro/WuShell.astro +39 -0
  13. package/integrations/astro/index.js +68 -0
  14. package/integrations/astro/package.json +38 -0
  15. package/integrations/astro/types.d.ts +53 -0
  16. package/package.json +94 -74
  17. package/src/adapters/angular/ai.js +30 -0
  18. package/src/adapters/angular/index.d.ts +154 -0
  19. package/src/adapters/angular/index.js +932 -0
  20. package/src/adapters/angular.d.ts +3 -154
  21. package/src/adapters/angular.js +3 -813
  22. package/src/adapters/index.js +35 -24
  23. package/src/adapters/lit/ai.js +20 -0
  24. package/src/adapters/lit/index.d.ts +120 -0
  25. package/src/adapters/lit/index.js +721 -0
  26. package/src/adapters/lit.d.ts +3 -120
  27. package/src/adapters/lit.js +3 -726
  28. package/src/adapters/preact/ai.js +33 -0
  29. package/src/adapters/preact/index.d.ts +108 -0
  30. package/src/adapters/preact/index.js +661 -0
  31. package/src/adapters/preact.d.ts +3 -108
  32. package/src/adapters/preact.js +3 -665
  33. package/src/adapters/react/ai.js +135 -0
  34. package/src/adapters/react/index.d.ts +246 -0
  35. package/src/adapters/react/index.js +689 -0
  36. package/src/adapters/react.d.ts +3 -212
  37. package/src/adapters/react.js +3 -513
  38. package/src/adapters/shared.js +64 -0
  39. package/src/adapters/solid/ai.js +32 -0
  40. package/src/adapters/solid/index.d.ts +101 -0
  41. package/src/adapters/solid/index.js +586 -0
  42. package/src/adapters/solid.d.ts +3 -101
  43. package/src/adapters/solid.js +3 -591
  44. package/src/adapters/svelte/ai.js +31 -0
  45. package/src/adapters/svelte/index.d.ts +166 -0
  46. package/src/adapters/svelte/index.js +798 -0
  47. package/src/adapters/svelte.d.ts +3 -166
  48. package/src/adapters/svelte.js +3 -803
  49. package/src/adapters/vanilla/ai.js +30 -0
  50. package/src/adapters/vanilla/index.d.ts +179 -0
  51. package/src/adapters/vanilla/index.js +785 -0
  52. package/src/adapters/vanilla.d.ts +3 -179
  53. package/src/adapters/vanilla.js +3 -791
  54. package/src/adapters/vue/ai.js +52 -0
  55. package/src/adapters/vue/index.d.ts +299 -0
  56. package/src/adapters/vue/index.js +608 -0
  57. package/src/adapters/vue.d.ts +3 -299
  58. package/src/adapters/vue.js +3 -611
  59. package/src/ai/wu-ai-actions.js +261 -0
  60. package/src/ai/wu-ai-browser.js +663 -0
  61. package/src/ai/wu-ai-context.js +332 -0
  62. package/src/ai/wu-ai-conversation.js +554 -0
  63. package/src/ai/wu-ai-permissions.js +381 -0
  64. package/src/ai/wu-ai-provider.js +605 -0
  65. package/src/ai/wu-ai-schema.js +225 -0
  66. package/src/ai/wu-ai-triggers.js +396 -0
  67. package/src/ai/wu-ai.js +474 -0
  68. package/src/core/wu-app.js +50 -8
  69. package/src/core/wu-cache.js +1 -1
  70. package/src/core/wu-core.js +645 -677
  71. package/src/core/wu-html-parser.js +121 -211
  72. package/src/core/wu-iframe-sandbox.js +328 -0
  73. package/src/core/wu-mcp-bridge.js +647 -0
  74. package/src/core/wu-overrides.js +510 -0
  75. package/src/core/wu-prefetch.js +414 -0
  76. package/src/core/wu-proxy-sandbox.js +398 -75
  77. package/src/core/wu-sandbox.js +86 -268
  78. package/src/core/wu-script-executor.js +79 -182
  79. package/src/core/wu-snapshot-sandbox.js +149 -106
  80. package/src/core/wu-strategies.js +13 -0
  81. package/src/core/wu-style-bridge.js +0 -2
  82. package/src/index.js +139 -665
  83. package/dist/wu-framework.hex.js +0 -23
  84. package/dist/wu-framework.min.js +0 -1
  85. package/dist/wu-framework.obf.js +0 -1
  86. package/scripts/build-protected.js +0 -366
  87. package/scripts/build.js +0 -212
  88. package/scripts/rollup-plugin-hex.js +0 -143
  89. package/src/core/wu-registry.js +0 -60
  90. package/src/core/wu-sandbox-pool.js +0 -390
@@ -1,366 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * 🔒 WU-FRAMEWORK PROTECTED BUILD
5
- *
6
- * Pipeline de protección en secuencia:
7
- * 1. Bundle (Rollup) - Empaquetar todos los módulos
8
- * 2. Minify (Terser) - Minificar el código
9
- * 3. Obfuscate (javascript-obfuscator) - Ofuscar el código
10
- * 4. Hex Encode - Convertir a hexadecimal
11
- *
12
- * Output: UN SOLO archivo protegido
13
- */
14
-
15
- import fs from 'fs';
16
- import path from 'path';
17
- import { fileURLToPath } from 'url';
18
- import { rollup } from 'rollup';
19
- import resolve from '@rollup/plugin-node-resolve';
20
- import commonjs from '@rollup/plugin-commonjs';
21
- import { minify } from 'terser';
22
- import JavaScriptObfuscator from 'javascript-obfuscator';
23
-
24
- const __filename = fileURLToPath(import.meta.url);
25
- const __dirname = path.dirname(__filename);
26
- const rootDir = path.resolve(__dirname, '..');
27
-
28
- // ═══════════════════════════════════════════════════════════
29
- // CONFIGURACIÓN
30
- // ═══════════════════════════════════════════════════════════
31
-
32
- const CONFIG = {
33
- input: path.join(rootDir, 'src/index.js'),
34
- output: path.join(rootDir, 'dist/wu-framework.protected.js'),
35
-
36
- // Opciones de Terser (minificación)
37
- terser: {
38
- compress: {
39
- drop_console: false,
40
- drop_debugger: true,
41
- passes: 3,
42
- dead_code: true,
43
- unused: true,
44
- conditionals: true,
45
- evaluate: true,
46
- booleans: true,
47
- loops: true,
48
- join_vars: true
49
- },
50
- mangle: {
51
- toplevel: true,
52
- properties: false
53
- },
54
- format: {
55
- comments: false,
56
- beautify: false
57
- }
58
- },
59
-
60
- // Opciones de Obfuscator (ofuscación OPTIMIZADA - balance protección/tamaño)
61
- obfuscator: {
62
- compact: true,
63
- controlFlowFlattening: false, // Desactivado - agrega mucho código
64
- deadCodeInjection: false, // Desactivado - agrega código muerto
65
- debugProtection: false,
66
- disableConsoleOutput: false,
67
- identifierNamesGenerator: 'hexadecimal',
68
- log: false,
69
- numbersToExpressions: false, // Desactivado - infla números
70
- renameGlobals: false,
71
- rotateStringArray: true,
72
- selfDefending: false, // Desactivado - agrega código
73
- shuffleStringArray: true,
74
- simplify: true,
75
- splitStrings: false, // Desactivado - divide strings innecesariamente
76
- stringArray: true,
77
- stringArrayCallsTransform: false, // Desactivado - agrega wrappers
78
- stringArrayEncoding: ['base64'],
79
- stringArrayIndexShift: true,
80
- stringArrayRotate: true,
81
- stringArrayShuffle: true,
82
- stringArrayWrappersCount: 1, // Reducido de 2 a 1
83
- stringArrayWrappersChainedCalls: false,
84
- stringArrayWrappersParametersMaxCount: 2,
85
- stringArrayWrappersType: 'variable', // Más ligero que 'function'
86
- stringArrayThreshold: 0.5, // Reducido de 0.75
87
- transformObjectKeys: false, // Desactivado - infla objetos
88
- unicodeEscapeSequence: false
89
- },
90
-
91
- // Opciones de Obfuscator MÁXIMA (para cuando se necesite máxima protección)
92
- obfuscatorMax: {
93
- compact: true,
94
- controlFlowFlattening: true,
95
- controlFlowFlatteningThreshold: 0.5,
96
- deadCodeInjection: true,
97
- deadCodeInjectionThreshold: 0.2,
98
- debugProtection: false,
99
- disableConsoleOutput: false,
100
- identifierNamesGenerator: 'hexadecimal',
101
- log: false,
102
- numbersToExpressions: true,
103
- renameGlobals: false,
104
- rotateStringArray: true,
105
- selfDefending: true,
106
- shuffleStringArray: true,
107
- simplify: true,
108
- splitStrings: true,
109
- splitStringsChunkLength: 10,
110
- stringArray: true,
111
- stringArrayEncoding: ['base64'],
112
- stringArrayThreshold: 0.75,
113
- transformObjectKeys: true,
114
- unicodeEscapeSequence: false
115
- }
116
- };
117
-
118
- // ═══════════════════════════════════════════════════════════
119
- // UTILIDADES
120
- // ═══════════════════════════════════════════════════════════
121
-
122
- const colors = {
123
- reset: '\x1b[0m',
124
- bright: '\x1b[1m',
125
- red: '\x1b[31m',
126
- green: '\x1b[32m',
127
- yellow: '\x1b[33m',
128
- blue: '\x1b[34m',
129
- magenta: '\x1b[35m',
130
- cyan: '\x1b[36m'
131
- };
132
-
133
- function log(msg, color = 'reset') {
134
- console.log(`${colors[color]}${msg}${colors.reset}`);
135
- }
136
-
137
- function logStep(step, total, msg) {
138
- const progress = `[${step}/${total}]`;
139
- console.log(`${colors.cyan}${progress}${colors.reset} ${msg}`);
140
- }
141
-
142
- function logSuccess(msg) {
143
- console.log(` ${colors.green}✓${colors.reset} ${msg}`);
144
- }
145
-
146
- function logInfo(msg) {
147
- console.log(` ${colors.blue}ℹ${colors.reset} ${msg}`);
148
- }
149
-
150
- function formatSize(bytes) {
151
- if (bytes < 1024) return `${bytes} B`;
152
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB`;
153
- return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
154
- }
155
-
156
- function stringToHex(str) {
157
- let hex = '';
158
- for (let i = 0; i < str.length; i++) {
159
- hex += str.charCodeAt(i).toString(16).padStart(2, '0');
160
- }
161
- return hex;
162
- }
163
-
164
- function stringToBase64(str) {
165
- // Convertir string a Base64 (más eficiente que hex)
166
- return Buffer.from(str, 'utf-8').toString('base64');
167
- }
168
-
169
- // ═══════════════════════════════════════════════════════════
170
- // PIPELINE DE BUILD
171
- // ═══════════════════════════════════════════════════════════
172
-
173
- async function build() {
174
- const startTime = Date.now();
175
-
176
- // Banner
177
- console.log(`
178
- ${colors.magenta}╔═══════════════════════════════════════════════════════════════╗
179
- ║ ║
180
- ║ ${colors.bright}🔒 WU-FRAMEWORK PROTECTED BUILD${colors.magenta} ║
181
- ║ ║
182
- ║ Pipeline: Bundle → Minify → Obfuscate → Hexadecimal ║
183
- ║ ║
184
- ╚═══════════════════════════════════════════════════════════════╝${colors.reset}
185
- `);
186
-
187
- let code = '';
188
- const stats = {
189
- original: 0,
190
- bundled: 0,
191
- minified: 0,
192
- obfuscated: 0,
193
- encoded: 0
194
- };
195
-
196
- try {
197
- // ─────────────────────────────────────────────────────────
198
- // PASO 1: BUNDLE (Rollup)
199
- // ─────────────────────────────────────────────────────────
200
- logStep(1, 4, 'Bundling with Rollup...');
201
-
202
- const bundle = await rollup({
203
- input: CONFIG.input,
204
- plugins: [
205
- resolve(),
206
- commonjs()
207
- ]
208
- });
209
-
210
- const { output } = await bundle.generate({
211
- format: 'es',
212
- sourcemap: false
213
- });
214
-
215
- code = output[0].code;
216
- stats.bundled = code.length;
217
-
218
- logSuccess(`Bundled: ${formatSize(stats.bundled)}`);
219
- await bundle.close();
220
-
221
- // ─────────────────────────────────────────────────────────
222
- // PASO 2: MINIFY (Terser)
223
- // ─────────────────────────────────────────────────────────
224
- logStep(2, 4, 'Minifying with Terser...');
225
-
226
- const minified = await minify(code, CONFIG.terser);
227
- code = minified.code;
228
- stats.minified = code.length;
229
-
230
- logSuccess(`Minified: ${formatSize(stats.minified)} (${((1 - stats.minified / stats.bundled) * 100).toFixed(1)}% reduction)`);
231
-
232
- // ─────────────────────────────────────────────────────────
233
- // PASO 3: OBFUSCATE (javascript-obfuscator)
234
- // ─────────────────────────────────────────────────────────
235
- logStep(3, 4, 'Obfuscating with javascript-obfuscator...');
236
-
237
- const obfuscated = JavaScriptObfuscator.obfuscate(code, CONFIG.obfuscator);
238
- code = obfuscated.getObfuscatedCode();
239
- stats.obfuscated = code.length;
240
-
241
- logSuccess(`Obfuscated: ${formatSize(stats.obfuscated)}`);
242
-
243
- // ─────────────────────────────────────────────────────────
244
- // PASO 4: BASE64 ENCODE (más eficiente que hex)
245
- // ─────────────────────────────────────────────────────────
246
- logStep(4, 4, 'Encoding to Base64...');
247
-
248
- const base64Code = stringToBase64(code);
249
- stats.encoded = base64Code.length;
250
-
251
- // Crear loader que decodifica y ejecuta el código
252
- const finalCode = generateBase64Loader(base64Code);
253
-
254
- logSuccess(`Base64 Encoded: ${formatSize(finalCode.length)}`);
255
-
256
- // ─────────────────────────────────────────────────────────
257
- // GUARDAR OUTPUT
258
- // ─────────────────────────────────────────────────────────
259
- const distDir = path.dirname(CONFIG.output);
260
- if (!fs.existsSync(distDir)) {
261
- fs.mkdirSync(distDir, { recursive: true });
262
- }
263
-
264
- fs.writeFileSync(CONFIG.output, finalCode, 'utf-8');
265
-
266
- // ─────────────────────────────────────────────────────────
267
- // RESUMEN
268
- // ─────────────────────────────────────────────────────────
269
- const elapsed = ((Date.now() - startTime) / 1000).toFixed(2);
270
-
271
- console.log(`
272
- ${colors.green}═══════════════════════════════════════════════════════════════${colors.reset}
273
- ${colors.bright} BUILD COMPLETE!${colors.reset}
274
- ${colors.green}═══════════════════════════════════════════════════════════════${colors.reset}
275
-
276
- ${colors.cyan}Pipeline Results:${colors.reset}
277
-
278
- ${colors.yellow}Step 1 - Bundle:${colors.reset} ${formatSize(stats.bundled).padStart(12)}
279
- ${colors.yellow}Step 2 - Minify:${colors.reset} ${formatSize(stats.minified).padStart(12)} (↓ ${((1 - stats.minified / stats.bundled) * 100).toFixed(1)}%)
280
- ${colors.yellow}Step 3 - Obfuscate:${colors.reset} ${formatSize(stats.obfuscated).padStart(12)}
281
- ${colors.yellow}Step 4 - Base64:${colors.reset} ${formatSize(finalCode.length).padStart(12)}
282
-
283
- ${colors.cyan}Output:${colors.reset} ${CONFIG.output}
284
- ${colors.cyan}Time:${colors.reset} ${elapsed}s
285
-
286
- ${colors.green}═══════════════════════════════════════════════════════════════${colors.reset}
287
- `);
288
-
289
- // Mostrar uso
290
- console.log(`${colors.yellow}Usage:${colors.reset}`);
291
- console.log(`
292
- ${colors.cyan}ES Module:${colors.reset}
293
- import * as WuFramework from './dist/wu-framework.protected.js';
294
-
295
- ${colors.cyan}Browser:${colors.reset}
296
- <script type="module" src="./dist/wu-framework.protected.js"></script>
297
-
298
- ${colors.cyan}Dynamic Import:${colors.reset}
299
- const WuFramework = await import('./dist/wu-framework.protected.js');
300
- `);
301
-
302
- } catch (error) {
303
- console.error(`${colors.red}Build failed:${colors.reset}`, error);
304
- process.exit(1);
305
- }
306
- }
307
-
308
- // ═══════════════════════════════════════════════════════════
309
- // GENERADOR DE LOADER HEXADECIMAL
310
- // ═══════════════════════════════════════════════════════════
311
-
312
- function generateBase64Loader(base64Code) {
313
- // Generar nombres de variables ofuscados consistentes
314
- const v = {
315
- data: `_0x${randomHex(4)}`,
316
- decode: `_0x${randomHex(4)}`,
317
- input: `_0x${randomHex(4)}`,
318
- code: `_0x${randomHex(4)}`,
319
- blob: `_0x${randomHex(4)}`,
320
- url: `_0x${randomHex(4)}`,
321
- mod: `_0x${randomHex(4)}`
322
- };
323
-
324
- // Loader que decodifica Base64 y ejecuta como módulo ES
325
- // atob() decodifica Base64 en el browser
326
- return `/*!
327
- * Wu Framework v1.1.1 - Protected Build
328
- * (c) ${new Date().getFullYear()} Wu Framework Team
329
- * This code is protected and encoded.
330
- */
331
- const ${v.data}="${base64Code}";
332
- const ${v.decode}=(${v.input})=>decodeURIComponent(atob(${v.input}).split("").map(c=>"%"+("00"+c.charCodeAt(0).toString(16)).slice(-2)).join(""));
333
- const ${v.code}=${v.decode}(${v.data});
334
- const ${v.blob}=new Blob([${v.code}],{type:"text/javascript"});
335
- const ${v.url}=URL.createObjectURL(${v.blob});
336
- const ${v.mod}=await import(${v.url});
337
- URL.revokeObjectURL(${v.url});
338
- export const WuCore=${v.mod}.WuCore;
339
- export const WuLoader=${v.mod}.WuLoader;
340
- export const WuSandbox=${v.mod}.WuSandbox;
341
- export const WuManifest=${v.mod}.WuManifest;
342
- export const WuEventBus=${v.mod}.WuEventBus;
343
- export const WuStore=${v.mod}.WuStore;
344
- export const WuCache=${v.mod}.WuCache;
345
- export const WuPlugin=${v.mod}.WuPlugin;
346
- export const WuHooks=${v.mod}.WuHooks;
347
- export const WuPerformance=${v.mod}.WuPerformance;
348
- export const adapters=${v.mod}.adapters;
349
- export default ${v.mod}.default||${v.mod}.WuCore;
350
- `;
351
- }
352
-
353
- // Generar identificador hex aleatorio
354
- function randomHex(length) {
355
- let result = '';
356
- for (let i = 0; i < length; i++) {
357
- result += Math.floor(Math.random() * 16).toString(16);
358
- }
359
- return result;
360
- }
361
-
362
- // ═══════════════════════════════════════════════════════════
363
- // EJECUTAR BUILD
364
- // ═══════════════════════════════════════════════════════════
365
-
366
- build().catch(console.error);
package/scripts/build.js DELETED
@@ -1,212 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * 🔨 WU-FRAMEWORK BUILD SCRIPT
5
- *
6
- * Script maestro para construir el framework con diferentes niveles de protección.
7
- *
8
- * Uso:
9
- * node scripts/build.js [target] [options]
10
- *
11
- * Targets:
12
- * dev - Build desarrollo (sin minificar)
13
- * prod - Build producción (minificado)
14
- * obfuscated - Build ofuscado (minificado + ofuscado)
15
- * hex - Build hexadecimal (máxima protección)
16
- * umd - Build UMD para browsers
17
- * cjs - Build CommonJS para Node
18
- * all - Todos los builds (default)
19
- *
20
- * Options:
21
- * --clean - Limpiar directorio dist antes de build
22
- * --watch - Modo watch (solo para dev)
23
- * --analyze - Analizar bundle size
24
- * --verbose - Output detallado
25
- */
26
-
27
- import { spawn, execSync } from 'child_process';
28
- import fs from 'fs';
29
- import path from 'path';
30
- import { fileURLToPath } from 'url';
31
-
32
- const __filename = fileURLToPath(import.meta.url);
33
- const __dirname = path.dirname(__filename);
34
- const rootDir = path.resolve(__dirname, '..');
35
-
36
- // Colores para console
37
- const colors = {
38
- reset: '\x1b[0m',
39
- bright: '\x1b[1m',
40
- red: '\x1b[31m',
41
- green: '\x1b[32m',
42
- yellow: '\x1b[33m',
43
- blue: '\x1b[34m',
44
- magenta: '\x1b[35m',
45
- cyan: '\x1b[36m'
46
- };
47
-
48
- function log(msg, color = 'reset') {
49
- console.log(`${colors[color]}${msg}${colors.reset}`);
50
- }
51
-
52
- function logStep(step, msg) {
53
- console.log(`${colors.cyan}[${step}]${colors.reset} ${msg}`);
54
- }
55
-
56
- function logSuccess(msg) {
57
- console.log(`${colors.green}✓${colors.reset} ${msg}`);
58
- }
59
-
60
- function logError(msg) {
61
- console.log(`${colors.red}✗${colors.reset} ${msg}`);
62
- }
63
-
64
- // Parsear argumentos
65
- const args = process.argv.slice(2);
66
- const target = args.find(a => !a.startsWith('--')) || 'all';
67
- const options = {
68
- clean: args.includes('--clean'),
69
- watch: args.includes('--watch'),
70
- analyze: args.includes('--analyze'),
71
- verbose: args.includes('--verbose')
72
- };
73
-
74
- // Banner
75
- console.log(`
76
- ${colors.cyan}╔═══════════════════════════════════════════════════════════╗
77
- ║ ║
78
- ║ ${colors.bright}🔨 WU-FRAMEWORK BUILD SYSTEM${colors.cyan} ║
79
- ║ ║
80
- ║ Universal Microfrontends Framework ║
81
- ║ Build Pipeline: Bundle → Minify → Obfuscate → Hex ║
82
- ║ ║
83
- ╚═══════════════════════════════════════════════════════════╝${colors.reset}
84
- `);
85
-
86
- // Info del build
87
- log(`Target: ${target}`, 'yellow');
88
- log(`Options: ${JSON.stringify(options)}`, 'yellow');
89
- console.log('');
90
-
91
- // Paso 1: Limpiar dist
92
- if (options.clean) {
93
- logStep('1/4', 'Cleaning dist directory...');
94
- const distDir = path.join(rootDir, 'dist');
95
- if (fs.existsSync(distDir)) {
96
- fs.rmSync(distDir, { recursive: true });
97
- logSuccess('Dist directory cleaned');
98
- } else {
99
- logSuccess('Dist directory does not exist, skipping');
100
- }
101
- } else {
102
- logStep('1/4', 'Skip cleaning (use --clean to enable)');
103
- }
104
-
105
- // Paso 2: Crear directorio dist
106
- logStep('2/4', 'Creating dist directory...');
107
- const distDir = path.join(rootDir, 'dist');
108
- if (!fs.existsSync(distDir)) {
109
- fs.mkdirSync(distDir, { recursive: true });
110
- }
111
- logSuccess('Dist directory ready');
112
-
113
- // Paso 3: Ejecutar Rollup
114
- logStep('3/4', `Building target: ${target}...`);
115
- console.log('');
116
-
117
- const startTime = Date.now();
118
-
119
- try {
120
- // Configurar entorno
121
- const env = {
122
- ...process.env,
123
- BUILD_TARGET: target,
124
- NODE_ENV: target === 'dev' ? 'development' : 'production'
125
- };
126
-
127
- // Comando de Rollup
128
- const rollupArgs = ['-c', 'rollup.config.js'];
129
-
130
- if (options.watch) {
131
- rollupArgs.push('--watch');
132
- }
133
-
134
- if (options.verbose) {
135
- rollupArgs.push('--verbose');
136
- }
137
-
138
- // Ejecutar Rollup
139
- const result = execSync(`npx rollup ${rollupArgs.join(' ')}`, {
140
- cwd: rootDir,
141
- env,
142
- stdio: 'inherit'
143
- });
144
-
145
- const elapsed = ((Date.now() - startTime) / 1000).toFixed(2);
146
- console.log('');
147
- logSuccess(`Build completed in ${elapsed}s`);
148
-
149
- } catch (error) {
150
- logError(`Build failed: ${error.message}`);
151
- process.exit(1);
152
- }
153
-
154
- // Paso 4: Mostrar resultados
155
- logStep('4/4', 'Build summary:');
156
- console.log('');
157
-
158
- // Leer archivos generados
159
- const files = fs.readdirSync(distDir).filter(f => f.endsWith('.js'));
160
-
161
- if (files.length === 0) {
162
- logError('No files generated!');
163
- process.exit(1);
164
- }
165
-
166
- // Tabla de resultados
167
- console.log(`${colors.cyan}┌────────────────────────────────┬──────────────┬──────────────┐${colors.reset}`);
168
- console.log(`${colors.cyan}│${colors.reset} ${colors.bright}File${colors.reset} ${colors.cyan}│${colors.reset} ${colors.bright}Size${colors.reset} ${colors.cyan}│${colors.reset} ${colors.bright}Gzip${colors.reset} ${colors.cyan}│${colors.reset}`);
169
- console.log(`${colors.cyan}├────────────────────────────────┼──────────────┼──────────────┤${colors.reset}`);
170
-
171
- let totalSize = 0;
172
-
173
- files.forEach(file => {
174
- const filePath = path.join(distDir, file);
175
- const stats = fs.statSync(filePath);
176
- const size = stats.size;
177
- totalSize += size;
178
-
179
- // Calcular gzip estimado (aproximadamente 30% del original para código ofuscado)
180
- const gzipSize = Math.round(size * 0.3);
181
-
182
- const sizeStr = formatSize(size).padEnd(10);
183
- const gzipStr = formatSize(gzipSize).padEnd(10);
184
- const fileStr = file.padEnd(30);
185
-
186
- console.log(`${colors.cyan}│${colors.reset} ${fileStr} ${colors.cyan}│${colors.reset} ${sizeStr} ${colors.cyan}│${colors.reset} ${gzipStr} ${colors.cyan}│${colors.reset}`);
187
- });
188
-
189
- console.log(`${colors.cyan}├────────────────────────────────┼──────────────┼──────────────┤${colors.reset}`);
190
- console.log(`${colors.cyan}│${colors.reset} ${colors.bright}Total${colors.reset} ${colors.cyan}│${colors.reset} ${formatSize(totalSize).padEnd(10)} ${colors.cyan}│${colors.reset} ${formatSize(Math.round(totalSize * 0.3)).padEnd(10)} ${colors.cyan}│${colors.reset}`);
191
- console.log(`${colors.cyan}└────────────────────────────────┴──────────────┴──────────────┘${colors.reset}`);
192
-
193
- console.log('');
194
- log('Build complete! Files are in dist/', 'green');
195
- console.log('');
196
-
197
- // Mostrar uso
198
- console.log(`${colors.yellow}Usage:${colors.reset}`);
199
- console.log(` ${colors.cyan}Development:${colors.reset} import WuFramework from './dist/wu-framework.dev.js'`);
200
- console.log(` ${colors.cyan}Production:${colors.reset} import WuFramework from './dist/wu-framework.min.js'`);
201
- console.log(` ${colors.cyan}Obfuscated:${colors.reset} import WuFramework from './dist/wu-framework.obf.js'`);
202
- console.log(` ${colors.cyan}Hex Encoded:${colors.reset} import WuFramework from './dist/wu-framework.hex.js'`);
203
- console.log(` ${colors.cyan}UMD (Browser):${colors.reset} <script src="./dist/wu-framework.umd.js"></script>`);
204
- console.log(` ${colors.cyan}CommonJS:${colors.reset} const WuFramework = require('./dist/wu-framework.cjs.js')`);
205
- console.log('');
206
-
207
- // Utilidades
208
- function formatSize(bytes) {
209
- if (bytes < 1024) return `${bytes} B`;
210
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB`;
211
- return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
212
- }