vako 1.3.17 → 1.3.18

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.
@@ -282,16 +282,73 @@ app.listen();
282
282
 
283
283
  ${description || 'A modern web application built with Vako'}
284
284
 
285
- ## Getting Started
285
+ ## 🚀 Getting Started
286
+
287
+ ### Installation
286
288
 
287
289
  \`\`\`bash
288
290
  npm install
291
+ \`\`\`
292
+
293
+ ### Development
294
+
295
+ Démarrer le serveur de développement avec hot reload :
296
+
297
+ \`\`\`bash
289
298
  npm run dev
299
+ # ou
300
+ vako dev
290
301
  \`\`\`
291
302
 
292
- ## Documentation
303
+ L'application sera disponible sur [http://localhost:3000](http://localhost:3000)
293
304
 
294
- Visit [https://vako.js.org](https://vako.js.org) for more information.
305
+ ### Production
306
+
307
+ \`\`\`bash
308
+ npm run build
309
+ npm start
310
+ \`\`\`
311
+
312
+ ## 📁 Project Structure
313
+
314
+ \`\`\`
315
+ ${projectName}/
316
+ ├── views/ # Templates EJS
317
+ │ ├── index.ejs # Page d'accueil
318
+ │ └── about.ejs # Page à propos
319
+ ├── routes/ # Routes Express
320
+ │ └── index.js # Routes principales
321
+ ├── public/ # Fichiers statiques
322
+ │ ├── css/ # Styles CSS
323
+ │ └── js/ # JavaScript client
324
+ ├── locales/ # Fichiers de traduction
325
+ ├── config/ # Configuration
326
+ ├── middleware/ # Middleware personnalisé
327
+ └── app.js # Point d'entrée
328
+ \`\`\`
329
+
330
+ ## 🎯 Features
331
+
332
+ - ✅ Hot Reload Development Server
333
+ - ✅ Plugin System
334
+ - ✅ Authentication Ready
335
+ - ✅ Modern Architecture
336
+ - ✅ EJS Templates
337
+ - ✅ RESTful API Routes
338
+
339
+ ## 📚 Documentation
340
+
341
+ - [Vako Documentation](https://vako.js.org)
342
+ - [Express.js Guide](https://expressjs.com)
343
+ - [EJS Templates](https://ejs.co)
344
+
345
+ ## 🤝 Contributing
346
+
347
+ Les contributions sont les bienvenues ! N'hésitez pas à ouvrir une issue ou une pull request.
348
+
349
+ ## 📝 License
350
+
351
+ ${license || 'MIT'}
295
352
  `;
296
353
 
297
354
  // .gitignore
@@ -307,9 +364,34 @@ coverage/
307
364
  files['routes/index.js'] = `const { Router } = require('express');
308
365
  const router = Router();
309
366
 
367
+ // Page d'accueil
310
368
  router.get('/', (req, res) => {
311
369
  res.render('index', {
312
- title: 'Welcome to ${projectName}'
370
+ title: '${translations.title || 'Welcome to'} ${projectName}',
371
+ message: '${translations.welcome || 'Welcome to your Vako application!'}',
372
+ features: [
373
+ 'Hot Reload Development Server',
374
+ 'Plugin System',
375
+ 'Authentication Ready',
376
+ 'Modern Architecture'
377
+ ]
378
+ });
379
+ });
380
+
381
+ // Page à propos
382
+ router.get('/about', (req, res) => {
383
+ res.render('about', {
384
+ title: 'About - ${projectName}',
385
+ description: '${description || translations.description || 'A modern web application built with Vako'}'
386
+ });
387
+ });
388
+
389
+ // API exemple
390
+ router.get('/api/status', (req, res) => {
391
+ res.json({
392
+ status: 'ok',
393
+ message: 'Vako API is running',
394
+ timestamp: new Date().toISOString()
313
395
  });
314
396
  });
315
397
 
@@ -323,11 +405,110 @@ module.exports = router;
323
405
  <head>
324
406
  <meta charset="UTF-8">
325
407
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
408
+ <meta name="description" content="${description || translations.description || 'A modern web application built with Vako'}">
326
409
  <title><%= title %></title>
410
+ <link rel="stylesheet" href="/css/style.css">
327
411
  </head>
328
412
  <body>
329
- <h1><%= title %></h1>
330
- <p>${translations.welcome || 'Welcome to your Vako application!'}</p>
413
+ <header>
414
+ <nav>
415
+ <div class="container">
416
+ <h1 class="logo">${projectName}</h1>
417
+ <ul class="nav-menu">
418
+ <li><a href="/" class="active">Home</a></li>
419
+ <li><a href="/about">About</a></li>
420
+ <li><a href="/api/status">API Status</a></li>
421
+ </ul>
422
+ </div>
423
+ </nav>
424
+ </header>
425
+
426
+ <main>
427
+ <section class="hero">
428
+ <div class="container">
429
+ <h1><%= title %></h1>
430
+ <p class="lead"><%= message %></p>
431
+ <div class="cta-buttons">
432
+ <a href="/about" class="btn btn-primary">Learn More</a>
433
+ <a href="/api/status" class="btn btn-secondary">API Status</a>
434
+ </div>
435
+ </div>
436
+ </section>
437
+
438
+ <section class="features">
439
+ <div class="container">
440
+ <h2>Features</h2>
441
+ <div class="features-grid">
442
+ <% features.forEach(function(feature) { %>
443
+ <div class="feature-card">
444
+ <div class="feature-icon">✨</div>
445
+ <h3><%= feature %></h3>
446
+ </div>
447
+ <% }); %>
448
+ </div>
449
+ </div>
450
+ </section>
451
+ </main>
452
+
453
+ <footer>
454
+ <div class="container">
455
+ <p>&copy; ${new Date().getFullYear()} ${projectName}. Built with <a href="https://vako.js.org" target="_blank">Vako</a>.</p>
456
+ </div>
457
+ </footer>
458
+
459
+ <script src="/js/main.js"></script>
460
+ </body>
461
+ </html>
462
+ `;
463
+
464
+ // views/about.ejs
465
+ files['views/about.ejs'] = `<!DOCTYPE html>
466
+ <html lang="${langAttr}">
467
+ <head>
468
+ <meta charset="UTF-8">
469
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
470
+ <title><%= title %></title>
471
+ <link rel="stylesheet" href="/css/style.css">
472
+ </head>
473
+ <body>
474
+ <header>
475
+ <nav>
476
+ <div class="container">
477
+ <h1 class="logo">${projectName}</h1>
478
+ <ul class="nav-menu">
479
+ <li><a href="/">Home</a></li>
480
+ <li><a href="/about" class="active">About</a></li>
481
+ <li><a href="/api/status">API Status</a></li>
482
+ </ul>
483
+ </div>
484
+ </nav>
485
+ </header>
486
+
487
+ <main>
488
+ <section class="content">
489
+ <div class="container">
490
+ <h1><%= title %></h1>
491
+ <p><%= description %></p>
492
+ <div class="info-box">
493
+ <h3>Technology Stack</h3>
494
+ <ul>
495
+ <li>Vako Framework</li>
496
+ <li>Express.js</li>
497
+ <li>EJS Templates</li>
498
+ <li>Node.js</li>
499
+ </ul>
500
+ </div>
501
+ </div>
502
+ </section>
503
+ </main>
504
+
505
+ <footer>
506
+ <div class="container">
507
+ <p>&copy; ${new Date().getFullYear()} ${projectName}. Built with <a href="https://vako.js.org" target="_blank">Vako</a>.</p>
508
+ </div>
509
+ </footer>
510
+
511
+ <script src="/js/main.js"></script>
331
512
  </body>
332
513
  </html>
333
514
  `;
@@ -352,20 +533,365 @@ module.exports = router;
352
533
  }
353
534
 
354
535
  // public/css/style.css
355
- files['public/css/style.css'] = `body {
356
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
536
+ files['public/css/style.css'] = `* {
357
537
  margin: 0;
358
- padding: 20px;
359
- background-color: #f5f5f5;
538
+ padding: 0;
539
+ box-sizing: border-box;
360
540
  }
361
541
 
362
- h1 {
363
- color: #333;
542
+ :root {
543
+ --primary-color: #007bff;
544
+ --secondary-color: #6c757d;
545
+ --success-color: #28a745;
546
+ --danger-color: #dc3545;
547
+ --warning-color: #ffc107;
548
+ --info-color: #17a2b8;
549
+ --light-color: #f8f9fa;
550
+ --dark-color: #343a40;
551
+ --white: #ffffff;
552
+ --gray: #6c757d;
553
+ --border-radius: 8px;
554
+ --shadow: 0 2px 4px rgba(0,0,0,0.1);
555
+ --transition: all 0.3s ease;
556
+ }
557
+
558
+ body {
559
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
560
+ line-height: 1.6;
561
+ color: var(--dark-color);
562
+ background-color: var(--light-color);
563
+ min-height: 100vh;
564
+ display: flex;
565
+ flex-direction: column;
566
+ }
567
+
568
+ .container {
569
+ max-width: 1200px;
570
+ margin: 0 auto;
571
+ padding: 0 20px;
572
+ width: 100%;
573
+ }
574
+
575
+ /* Header & Navigation */
576
+ header {
577
+ background: var(--white);
578
+ box-shadow: var(--shadow);
579
+ position: sticky;
580
+ top: 0;
581
+ z-index: 1000;
582
+ }
583
+
584
+ nav {
585
+ padding: 1rem 0;
586
+ }
587
+
588
+ nav .container {
589
+ display: flex;
590
+ justify-content: space-between;
591
+ align-items: center;
592
+ }
593
+
594
+ .logo {
595
+ font-size: 1.5rem;
596
+ font-weight: bold;
597
+ color: var(--primary-color);
598
+ }
599
+
600
+ .nav-menu {
601
+ display: flex;
602
+ list-style: none;
603
+ gap: 2rem;
604
+ }
605
+
606
+ .nav-menu a {
607
+ text-decoration: none;
608
+ color: var(--dark-color);
609
+ font-weight: 500;
610
+ transition: var(--transition);
611
+ padding: 0.5rem 1rem;
612
+ border-radius: var(--border-radius);
613
+ }
614
+
615
+ .nav-menu a:hover,
616
+ .nav-menu a.active {
617
+ color: var(--primary-color);
618
+ background-color: var(--light-color);
619
+ }
620
+
621
+ /* Main Content */
622
+ main {
623
+ flex: 1;
624
+ padding: 2rem 0;
625
+ }
626
+
627
+ /* Hero Section */
628
+ .hero {
629
+ background: linear-gradient(135deg, var(--primary-color) 0%, #0056b3 100%);
630
+ color: var(--white);
631
+ padding: 4rem 0;
632
+ text-align: center;
633
+ margin-bottom: 3rem;
634
+ }
635
+
636
+ .hero h1 {
637
+ font-size: 3rem;
638
+ margin-bottom: 1rem;
639
+ color: var(--white);
640
+ }
641
+
642
+ .lead {
643
+ font-size: 1.25rem;
644
+ margin-bottom: 2rem;
645
+ opacity: 0.9;
646
+ }
647
+
648
+ .cta-buttons {
649
+ display: flex;
650
+ gap: 1rem;
651
+ justify-content: center;
652
+ flex-wrap: wrap;
653
+ }
654
+
655
+ /* Buttons */
656
+ .btn {
657
+ display: inline-block;
658
+ padding: 0.75rem 1.5rem;
659
+ border-radius: var(--border-radius);
660
+ text-decoration: none;
661
+ font-weight: 600;
662
+ transition: var(--transition);
663
+ border: 2px solid transparent;
664
+ cursor: pointer;
665
+ }
666
+
667
+ .btn-primary {
668
+ background-color: var(--white);
669
+ color: var(--primary-color);
670
+ }
671
+
672
+ .btn-primary:hover {
673
+ background-color: var(--light-color);
674
+ transform: translateY(-2px);
675
+ box-shadow: 0 4px 8px rgba(0,0,0,0.2);
676
+ }
677
+
678
+ .btn-secondary {
679
+ background-color: transparent;
680
+ color: var(--white);
681
+ border-color: var(--white);
682
+ }
683
+
684
+ .btn-secondary:hover {
685
+ background-color: var(--white);
686
+ color: var(--primary-color);
687
+ }
688
+
689
+ /* Features Section */
690
+ .features {
691
+ padding: 3rem 0;
692
+ }
693
+
694
+ .features h2 {
695
+ text-align: center;
696
+ font-size: 2.5rem;
697
+ margin-bottom: 3rem;
698
+ color: var(--dark-color);
699
+ }
700
+
701
+ .features-grid {
702
+ display: grid;
703
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
704
+ gap: 2rem;
705
+ }
706
+
707
+ .feature-card {
708
+ background: var(--white);
709
+ padding: 2rem;
710
+ border-radius: var(--border-radius);
711
+ box-shadow: var(--shadow);
712
+ text-align: center;
713
+ transition: var(--transition);
714
+ }
715
+
716
+ .feature-card:hover {
717
+ transform: translateY(-5px);
718
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
719
+ }
720
+
721
+ .feature-icon {
722
+ font-size: 3rem;
723
+ margin-bottom: 1rem;
724
+ }
725
+
726
+ .feature-card h3 {
727
+ color: var(--dark-color);
728
+ margin-top: 1rem;
729
+ }
730
+
731
+ /* Content Section */
732
+ .content {
733
+ max-width: 800px;
734
+ margin: 0 auto;
735
+ }
736
+
737
+ .content h1 {
738
+ font-size: 2.5rem;
739
+ margin-bottom: 1.5rem;
740
+ color: var(--dark-color);
741
+ }
742
+
743
+ .content p {
744
+ font-size: 1.1rem;
745
+ margin-bottom: 2rem;
746
+ color: var(--gray);
747
+ }
748
+
749
+ .info-box {
750
+ background: var(--white);
751
+ padding: 2rem;
752
+ border-radius: var(--border-radius);
753
+ box-shadow: var(--shadow);
754
+ margin-top: 2rem;
755
+ }
756
+
757
+ .info-box h3 {
758
+ margin-bottom: 1rem;
759
+ color: var(--primary-color);
760
+ }
761
+
762
+ .info-box ul {
763
+ list-style: none;
764
+ padding-left: 0;
765
+ }
766
+
767
+ .info-box li {
768
+ padding: 0.5rem 0;
769
+ border-bottom: 1px solid var(--light-color);
770
+ }
771
+
772
+ .info-box li:last-child {
773
+ border-bottom: none;
774
+ }
775
+
776
+ .info-box li:before {
777
+ content: "✓ ";
778
+ color: var(--success-color);
779
+ font-weight: bold;
780
+ margin-right: 0.5rem;
781
+ }
782
+
783
+ /* Footer */
784
+ footer {
785
+ background: var(--dark-color);
786
+ color: var(--white);
787
+ padding: 2rem 0;
788
+ margin-top: auto;
789
+ text-align: center;
790
+ }
791
+
792
+ footer a {
793
+ color: var(--primary-color);
794
+ text-decoration: none;
795
+ }
796
+
797
+ footer a:hover {
798
+ text-decoration: underline;
799
+ }
800
+
801
+ /* Responsive */
802
+ @media (max-width: 768px) {
803
+ .nav-menu {
804
+ flex-direction: column;
805
+ gap: 0.5rem;
806
+ }
807
+
808
+ .hero h1 {
809
+ font-size: 2rem;
810
+ }
811
+
812
+ .features-grid {
813
+ grid-template-columns: 1fr;
814
+ }
815
+
816
+ .cta-buttons {
817
+ flex-direction: column;
818
+ align-items: center;
819
+ }
820
+
821
+ .btn {
822
+ width: 100%;
823
+ max-width: 300px;
824
+ }
364
825
  }
365
826
  `;
366
827
 
367
828
  // public/js/main.js
368
- files['public/js/main.js'] = `console.log('Vako loaded');
829
+ files['public/js/main.js'] = `// Vako Application JavaScript
830
+ console.log('🚀 Vako application loaded');
831
+
832
+ // Smooth scroll for anchor links
833
+ document.querySelectorAll('a[href^="#"]').forEach(anchor => {
834
+ anchor.addEventListener('click', function (e) {
835
+ e.preventDefault();
836
+ const target = document.querySelector(this.getAttribute('href'));
837
+ if (target) {
838
+ target.scrollIntoView({
839
+ behavior: 'smooth',
840
+ block: 'start'
841
+ });
842
+ }
843
+ });
844
+ });
845
+
846
+ // API Status Check
847
+ async function checkApiStatus() {
848
+ try {
849
+ const response = await fetch('/api/status');
850
+ const data = await response.json();
851
+ console.log('API Status:', data);
852
+ return data;
853
+ } catch (error) {
854
+ console.error('API Status check failed:', error);
855
+ }
856
+ }
857
+
858
+ // Initialize on page load
859
+ document.addEventListener('DOMContentLoaded', () => {
860
+ console.log('DOM loaded');
861
+
862
+ // Check API status if on home page
863
+ if (window.location.pathname === '/') {
864
+ checkApiStatus();
865
+ }
866
+
867
+ // Add animation to feature cards
868
+ const featureCards = document.querySelectorAll('.feature-card');
869
+ featureCards.forEach((card, index) => {
870
+ card.style.animationDelay = \`\${index * 0.1}s\`;
871
+ card.classList.add('fade-in');
872
+ });
873
+ });
874
+
875
+ // Add fade-in animation
876
+ const style = document.createElement('style');
877
+ style.textContent = \`
878
+ @keyframes fadeIn {
879
+ from {
880
+ opacity: 0;
881
+ transform: translateY(20px);
882
+ }
883
+ to {
884
+ opacity: 1;
885
+ transform: translateY(0);
886
+ }
887
+ }
888
+
889
+ .fade-in {
890
+ animation: fadeIn 0.6s ease-out forwards;
891
+ opacity: 0;
892
+ }
893
+ \`;
894
+ document.head.appendChild(style);
369
895
  `;
370
896
 
371
897
  return files;
@@ -316,21 +316,28 @@ class SetupWizard {
316
316
  }
317
317
  ];
318
318
 
319
- const { language } = await inquirer.prompt([{
320
- type: 'list',
321
- name: 'language',
322
- message: '🌍 Select the language for your site:',
323
- choices: languageChoices.map(choice => ({
324
- name: choice.name,
325
- value: choice.value
326
- })),
327
- pageSize: 10
328
- }]);
319
+ try {
320
+ const { language } = await inquirer.prompt([{
321
+ type: 'list',
322
+ name: 'language',
323
+ message: '🌍 Select the language for your site:',
324
+ choices: languageChoices.map(choice => ({
325
+ name: choice.name,
326
+ value: choice.value
327
+ })),
328
+ pageSize: 10
329
+ }]);
329
330
 
330
- this.config.language = language;
331
-
332
- const selectedChoice = languageChoices.find(c => c.value === language);
333
- console.log(chalk.gray(`\n✓ Selected: ${selectedChoice.description}\n`));
331
+ this.config.language = language || 'fr'; // Par défaut français
332
+
333
+ const selectedChoice = languageChoices.find(c => c.value === language);
334
+ if (selectedChoice) {
335
+ console.log(chalk.gray(`\n✓ Selected: ${selectedChoice.description}\n`));
336
+ }
337
+ } catch (error) {
338
+ console.error(chalk.red('Error selecting language:'), error.message);
339
+ this.config.language = 'fr'; // Par défaut français en cas d'erreur
340
+ }
334
341
  }
335
342
 
336
343
  /**
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.17');
24
+ .version('1.3.18');
25
25
 
26
26
  // ============= DEV COMMAND =============
27
27
  program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vako",
3
- "version": "1.3.17",
3
+ "version": "1.3.18",
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",