vako 1.3.12 → 1.3.14

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.
@@ -154,7 +154,21 @@ class SetupExecutor {
154
154
  }
155
155
 
156
156
  generateFiles() {
157
- const { projectName, description, author, license, template, features, database, auth, styling } = this.config;
157
+ const { projectName, description, author, license, template, features, database, auth, styling, codeType } = this.config;
158
+ const files = {};
159
+
160
+ // Générer les fichiers selon le type de code
161
+ if (codeType === 'nextjs') {
162
+ return this.generateNextJsFiles();
163
+ } else if (codeType === 'typescript') {
164
+ return this.generateTypeScriptFiles();
165
+ } else {
166
+ return this.generateEjsFiles();
167
+ }
168
+ }
169
+
170
+ generateEjsFiles() {
171
+ const { projectName, description, author, license } = this.config;
158
172
  const files = {};
159
173
 
160
174
  // package.json
@@ -168,11 +182,11 @@ class SetupExecutor {
168
182
  start: 'vako start',
169
183
  build: 'vako build'
170
184
  },
171
- keywords: ['vako', 'framework', 'web'],
185
+ keywords: ['vako', 'framework', 'web', 'ejs'],
172
186
  author: author || '',
173
187
  license: license || 'MIT',
174
188
  dependencies: {
175
- vako: '^1.3.6'
189
+ vako: '^1.3.13'
176
190
  }
177
191
  }, null, 2);
178
192
 
@@ -265,6 +279,357 @@ h1 {
265
279
  return files;
266
280
  }
267
281
 
282
+ generateTypeScriptFiles() {
283
+ const { projectName, description, author, license } = this.config;
284
+ const files = {};
285
+
286
+ // package.json
287
+ files['package.json'] = JSON.stringify({
288
+ name: projectName,
289
+ version: '1.0.0',
290
+ description: description || 'A modern web application built with Vako and TypeScript',
291
+ main: 'dist/app.js',
292
+ scripts: {
293
+ dev: 'ts-node src/app.ts',
294
+ build: 'tsc',
295
+ start: 'node dist/app.js',
296
+ 'type-check': 'tsc --noEmit'
297
+ },
298
+ keywords: ['vako', 'framework', 'web', 'typescript'],
299
+ author: author || '',
300
+ license: license || 'MIT',
301
+ dependencies: {
302
+ vako: '^1.3.13'
303
+ },
304
+ devDependencies: {
305
+ '@types/node': '^20.10.5',
306
+ '@types/express': '^4.17.21',
307
+ 'ts-node': '^10.9.2',
308
+ 'typescript': '^5.3.3'
309
+ }
310
+ }, null, 2);
311
+
312
+ // tsconfig.json
313
+ files['tsconfig.json'] = JSON.stringify({
314
+ compilerOptions: {
315
+ target: 'ES2020',
316
+ module: 'commonjs',
317
+ lib: ['ES2020'],
318
+ outDir: './dist',
319
+ rootDir: './src',
320
+ strict: true,
321
+ esModuleInterop: true,
322
+ skipLibCheck: true,
323
+ forceConsistentCasingInFileNames: true,
324
+ resolveJsonModule: true,
325
+ declaration: true,
326
+ declarationMap: true,
327
+ sourceMap: true
328
+ },
329
+ include: ['src/**/*'],
330
+ exclude: ['node_modules', 'dist']
331
+ }, null, 2);
332
+
333
+ // src/app.ts
334
+ files['src/app.ts'] = `import { App } from 'vako';
335
+
336
+ const app = new App({
337
+ port: 3000,
338
+ isDev: true,
339
+ viewsDir: 'views',
340
+ staticDir: 'public',
341
+ routesDir: 'src/routes'
342
+ });
343
+
344
+ app.loadRoutes();
345
+ app.listen();
346
+ `;
347
+
348
+ // src/routes/index.ts
349
+ files['src/routes/index.ts'] = `import { Router, Request, Response } from 'express';
350
+
351
+ const router = Router();
352
+
353
+ router.get('/', (req: Request, res: Response) => {
354
+ res.render('index', {
355
+ title: 'Welcome to ${projectName}'
356
+ });
357
+ });
358
+
359
+ export default router;
360
+ `;
361
+
362
+ // README.md
363
+ files['README.md'] = `# ${projectName}
364
+
365
+ ${description || 'A modern web application built with Vako and TypeScript'}
366
+
367
+ ## Getting Started
368
+
369
+ \`\`\`bash
370
+ npm install
371
+ npm run dev
372
+ \`\`\`
373
+
374
+ ## Building for Production
375
+
376
+ \`\`\`bash
377
+ npm run build
378
+ npm start
379
+ \`\`\`
380
+
381
+ ## Documentation
382
+
383
+ Visit [https://vako.js.org](https://vako.js.org) for more information.
384
+ `;
385
+
386
+ // .gitignore
387
+ files['.gitignore'] = `node_modules/
388
+ .env
389
+ *.log
390
+ .DS_Store
391
+ dist/
392
+ coverage/
393
+ *.tsbuildinfo
394
+ `;
395
+
396
+ // views/index.ejs
397
+ files['views/index.ejs'] = `<!DOCTYPE html>
398
+ <html lang="en">
399
+ <head>
400
+ <meta charset="UTF-8">
401
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
402
+ <title><%= title %></title>
403
+ </head>
404
+ <body>
405
+ <h1><%= title %></h1>
406
+ <p>Welcome to your Vako TypeScript application!</p>
407
+ </body>
408
+ </html>
409
+ `;
410
+
411
+ return files;
412
+ }
413
+
414
+ generateNextJsFiles() {
415
+ const { projectName, description, author, license } = this.config;
416
+ const files = {};
417
+
418
+ // package.json
419
+ files['package.json'] = JSON.stringify({
420
+ name: projectName,
421
+ version: '1.0.0',
422
+ description: description || 'A modern web application built with Vako and Next.js',
423
+ scripts: {
424
+ dev: 'next dev',
425
+ build: 'next build',
426
+ start: 'next start',
427
+ lint: 'next lint'
428
+ },
429
+ keywords: ['vako', 'framework', 'web', 'nextjs', 'react'],
430
+ author: author || '',
431
+ license: license || 'MIT',
432
+ dependencies: {
433
+ vako: '^1.3.13',
434
+ next: '^14.0.0',
435
+ react: '^18.2.0',
436
+ 'react-dom': '^18.2.0'
437
+ },
438
+ devDependencies: {
439
+ '@types/node': '^20.10.5',
440
+ '@types/react': '^18.2.0',
441
+ '@types/react-dom': '^18.2.0',
442
+ typescript: '^5.3.3',
443
+ eslint: '^8.56.0',
444
+ 'eslint-config-next': '^14.0.0'
445
+ }
446
+ }, null, 2);
447
+
448
+ // next.config.js
449
+ files['next.config.js'] = `/** @type {import('next').NextConfig} */
450
+ const { NextJsAdapter } = require('vako');
451
+ const { App } = require('vako');
452
+
453
+ const nextConfig = {
454
+ reactStrictMode: true,
455
+ // Configuration Vako
456
+ webpack: (config, { isServer }) => {
457
+ if (!isServer) {
458
+ // Configuration pour le client
459
+ }
460
+ return config;
461
+ }
462
+ };
463
+
464
+ module.exports = nextConfig;
465
+ `;
466
+
467
+ // tsconfig.json (pour Next.js)
468
+ files['tsconfig.json'] = JSON.stringify({
469
+ compilerOptions: {
470
+ target: 'ES2020',
471
+ lib: ['dom', 'dom.iterable', 'esnext'],
472
+ allowJs: true,
473
+ skipLibCheck: true,
474
+ strict: true,
475
+ forceConsistentCasingInFileNames: true,
476
+ noEmit: true,
477
+ esModuleInterop: true,
478
+ module: 'esnext',
479
+ moduleResolution: 'bundler',
480
+ resolveJsonModule: true,
481
+ isolatedModules: true,
482
+ jsx: 'preserve',
483
+ incremental: true,
484
+ plugins: [
485
+ {
486
+ name: 'next'
487
+ }
488
+ ],
489
+ paths: {
490
+ '@/*': ['./src/*']
491
+ }
492
+ },
493
+ include: ['next-env.d.ts', '**/*.ts', '**/*.tsx', '.next/types/**/*.ts'],
494
+ exclude: ['node_modules']
495
+ }, null, 2);
496
+
497
+ // server.js (serveur personnalisé avec Vako)
498
+ files['server.js'] = `const { createServer } = require('http');
499
+ const { parse } = require('url');
500
+ const next = require('next');
501
+ const { App } = require('vako');
502
+ const { NextJsAdapter } = require('vako');
503
+
504
+ const dev = process.env.NODE_ENV !== 'production';
505
+ const hostname = 'localhost';
506
+ const port = parseInt(process.env.PORT || '3000', 10);
507
+
508
+ const app = next({ dev, hostname, port });
509
+ const handle = app.getRequestHandler();
510
+
511
+ app.prepare().then(() => {
512
+ // Créer l'instance Vako
513
+ const vakoApp = new App({
514
+ port: port + 1, // Port différent pour Vako
515
+ isDev: dev
516
+ });
517
+
518
+ // Intégrer Vako avec Next.js
519
+ const adapter = new NextJsAdapter({
520
+ nextApp: app,
521
+ enableVakoRoutes: true,
522
+ enableVakoPlugins: true,
523
+ routePrefix: '/api/vako'
524
+ });
525
+
526
+ adapter.integrateRoutes(vakoApp);
527
+ adapter.usePlugins(vakoApp);
528
+
529
+ // Créer le serveur HTTP
530
+ createServer(async (req, res) => {
531
+ try {
532
+ const parsedUrl = parse(req.url, true);
533
+ await handle(req, res, parsedUrl);
534
+ } catch (err) {
535
+ console.error('Error occurred handling', req.url, err);
536
+ res.statusCode = 500;
537
+ res.end('internal server error');
538
+ }
539
+ }).listen(port, (err) => {
540
+ if (err) throw err;
541
+ console.log(\`> Ready on http://\${hostname}:\${port}\`);
542
+ });
543
+ });
544
+ `;
545
+
546
+ // src/app/layout.tsx
547
+ files['src/app/layout.tsx'] = `import type { Metadata } from 'next';
548
+ import './globals.css';
549
+
550
+ export const metadata: Metadata = {
551
+ title: '${projectName}',
552
+ description: '${description || 'A modern web application built with Vako and Next.js'}'
553
+ };
554
+
555
+ export default function RootLayout({
556
+ children
557
+ }: {
558
+ children: React.ReactNode;
559
+ }) {
560
+ return (
561
+ <html lang="en">
562
+ <body>{children}</body>
563
+ </html>
564
+ );
565
+ }
566
+ `;
567
+
568
+ // src/app/page.tsx
569
+ files['src/app/page.tsx'] = `export default function Home() {
570
+ return (
571
+ <main>
572
+ <h1>Welcome to ${projectName}</h1>
573
+ <p>Welcome to your Vako Next.js application!</p>
574
+ </main>
575
+ );
576
+ }
577
+ `;
578
+
579
+ // src/app/globals.css
580
+ files['src/app/globals.css'] = `body {
581
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
582
+ margin: 0;
583
+ padding: 20px;
584
+ background-color: #f5f5f5;
585
+ }
586
+
587
+ h1 {
588
+ color: #333;
589
+ }
590
+ `;
591
+
592
+ // README.md
593
+ files['README.md'] = `# ${projectName}
594
+
595
+ ${description || 'A modern web application built with Vako and Next.js'}
596
+
597
+ ## Getting Started
598
+
599
+ \`\`\`bash
600
+ npm install
601
+ npm run dev
602
+ \`\`\`
603
+
604
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
605
+
606
+ ## Building for Production
607
+
608
+ \`\`\`bash
609
+ npm run build
610
+ npm start
611
+ \`\`\`
612
+
613
+ ## Documentation
614
+
615
+ - [Next.js Documentation](https://nextjs.org/docs)
616
+ - [Vako Documentation](https://vako.js.org)
617
+ `;
618
+
619
+ // .gitignore
620
+ files['.gitignore'] = `node_modules/
621
+ .env
622
+ *.log
623
+ .DS_Store
624
+ .next/
625
+ out/
626
+ dist/
627
+ coverage/
628
+ `;
629
+
630
+ return files;
631
+ }
632
+
268
633
  async configureFeatures() {
269
634
  // Configure features based on this.config.features
270
635
  // This is a placeholder - features are already configured in generateFiles()
@@ -17,6 +17,7 @@ class SetupWizard {
17
17
  this.config = {
18
18
  projectName: '',
19
19
  template: 'default',
20
+ codeType: 'ejs', // 'ejs', 'typescript', 'nextjs'
20
21
  features: [],
21
22
  database: 'sqlite',
22
23
  auth: { enabled: false },
@@ -206,13 +207,64 @@ class SetupWizard {
206
207
  Object.assign(this.config, this.sanitizeProjectInfo(answers));
207
208
  }
208
209
 
210
+ /**
211
+ * Sélection du type de code (EJS, TypeScript, Next.js)
212
+ */
213
+ async selectCodeType() {
214
+ console.log(chalk.blue.bold('\n💻 Choose Your Code Type\n'));
215
+
216
+ const codeTypeChoices = [
217
+ {
218
+ name: '📄 EJS - Traditional server-side rendering with EJS templates',
219
+ value: 'ejs',
220
+ description: 'Classic Vako.js with EJS views, perfect for traditional web apps'
221
+ },
222
+ {
223
+ name: '📘 TypeScript - Type-safe JavaScript with TypeScript',
224
+ value: 'typescript',
225
+ description: 'Modern TypeScript support with type definitions and IntelliSense'
226
+ },
227
+ {
228
+ name: '⚛️ Next.js - React framework with SSR and SSG',
229
+ value: 'nextjs',
230
+ description: 'Next.js integration with React, Server-Side Rendering, and Static Generation'
231
+ }
232
+ ];
233
+
234
+ const { codeType } = await inquirer.prompt([{
235
+ type: 'list',
236
+ name: 'codeType',
237
+ message: '🎯 Select your preferred code type:',
238
+ choices: codeTypeChoices.map(choice => ({
239
+ name: choice.name,
240
+ value: choice.value
241
+ })),
242
+ pageSize: 10
243
+ }]);
244
+
245
+ this.config.codeType = codeType;
246
+
247
+ const selectedChoice = codeTypeChoices.find(c => c.value === codeType);
248
+ console.log(chalk.gray(`\n✓ Selected: ${selectedChoice.description}\n`));
249
+ }
250
+
209
251
  /**
210
252
  * Sélection du template de projet
211
253
  */
212
254
  async selectTemplate() {
213
255
  console.log(chalk.blue.bold('\n🎨 Choose Your Template\n'));
214
256
 
215
- const templateChoices = Array.from(this.templates.entries()).map(([value, template]) => ({
257
+ // Filtrer les templates selon le type de code
258
+ let availableTemplates = Array.from(this.templates.entries());
259
+
260
+ // Si Next.js est sélectionné, limiter les options
261
+ if (this.config.codeType === 'nextjs') {
262
+ availableTemplates = availableTemplates.filter(([key]) =>
263
+ ['default', 'api', 'blog', 'portfolio'].includes(key)
264
+ );
265
+ }
266
+
267
+ const templateChoices = availableTemplates.map(([value, template]) => ({
216
268
  name: template.name,
217
269
  value
218
270
  }));
package/bin/vako.js CHANGED
@@ -21,7 +21,7 @@ const program = new Command();
21
21
  program
22
22
  .name('vako')
23
23
  .description('Vako Framework CLI')
24
- .version('1.3.12');
24
+ .version('1.3.14');
25
25
 
26
26
  // ============= DEV COMMAND =============
27
27
  program
@@ -32,15 +32,47 @@ program
32
32
  .option('-w, --watch <dirs>', 'Watch directories', 'views,routes,public')
33
33
  .action(async (options) => {
34
34
  try {
35
- const devServer = new DevServer({
36
- port: parseInt(options.port),
37
- file: options.file,
38
- watchDirs: options.watch.split(',')
35
+ const { App } = require('../index');
36
+ const path = require('path');
37
+ const fs = require('fs');
38
+
39
+ // Vérifier si le fichier d'entrée existe
40
+ const entryFile = path.resolve(process.cwd(), options.file);
41
+ if (fs.existsSync(entryFile)) {
42
+ // Charger le fichier d'entrée de l'utilisateur s'il existe
43
+ try {
44
+ require(entryFile);
45
+ } catch (err) {
46
+ console.warn(chalk.yellow(`⚠️ Warning: Could not load ${options.file}: ${err.message}`));
47
+ }
48
+ }
49
+
50
+ // Créer l'application en mode développement
51
+ const port = parseInt(options.port);
52
+ const wsPort = port + 8;
53
+
54
+ const app = new App({
55
+ port: port,
56
+ wsPort: wsPort,
57
+ isDev: true,
58
+ watchDirs: options.watch.split(',').map(dir => dir.trim()),
59
+ routesDir: 'routes',
60
+ viewsDir: 'views',
61
+ staticDir: 'public'
39
62
  });
40
63
 
41
- await devServer.start();
64
+ // Utiliser la méthode startDev qui configure automatiquement le devServer
65
+ app.startDev(port);
66
+
67
+ console.log(chalk.green(`\n🚀 Vako dev server running on http://localhost:${port}`));
68
+ console.log(chalk.cyan(`📡 WebSocket server on ws://localhost:${wsPort}`));
69
+ console.log(chalk.gray(`\n👀 Watching: ${options.watch}\n`));
70
+
42
71
  } catch (error) {
43
72
  console.error(chalk.red('❌ Error starting dev server:'), error.message);
73
+ if (error.stack) {
74
+ console.error(chalk.gray(error.stack));
75
+ }
44
76
  process.exit(1);
45
77
  }
46
78
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vako",
3
- "version": "1.3.12",
3
+ "version": "1.3.14",
4
4
  "description": "🚀 Ultra-modern Node.js framework with hot reload, plugins, authentication, TypeScript support, and Next.js integration",
5
5
  "main": "index.js",
6
6
  "types": "types/index.d.ts",