wad-lab 1.0.0 → 1.0.1

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 (2) hide show
  1. package/bin/index.js +81 -48
  2. package/package.json +2 -2
package/bin/index.js CHANGED
@@ -2,66 +2,99 @@
2
2
 
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
+ const readline = require('readline');
5
6
 
6
- const availableTemplates = [
7
- 'html-css-js',
8
- 'servlet-basic',
9
- 'servlet-jdbc',
10
- 'servlet-flow',
11
- 'springboot-mongo-crud',
12
- 'springboot-mongo-aggregation',
13
- 'springboot-mockmvc',
14
- 'springboot-mongo-aggregation-mockmvc',
15
- 'vue-basics',
16
- 'vue-props-emits',
17
- 'vue-router',
18
- 'vue-pinia',
19
- 'vue-router-pinia',
20
- 'vue-fetch',
21
- 'vue-axios',
22
- 'vue-router-pinia-props',
23
- 'vue-springboot-mongo-crud',
24
- 'vue-springboot-mongo-aggregation',
25
- 'vue-router-pinia-springboot'
7
+ const templates = [
8
+ { name: 'all (Unpack All 17 Templates)', value: 'all' },
9
+ { name: 'html-css-js (Form Validation & DOM)', value: 'html-css-js' },
10
+ { name: 'servlet-basic (Tomcat GET + POST)', value: 'servlet-basic' },
11
+ { name: 'servlet-jdbc (Tomcat + MySQL JDBC)', value: 'servlet-jdbc' },
12
+ { name: 'servlet-flow (HelloServlet with GET/POST)', value: 'servlet-flow' },
13
+ { name: 'springboot-mongo-crud (4-Layer REST API)', value: 'springboot-mongo-crud' },
14
+ { name: 'springboot-mongo-aggregation ($group, $sum, $avg, $sort)', value: 'springboot-mongo-aggregation' },
15
+ { name: 'springboot-mockmvc (Controller Tests)', value: 'springboot-mockmvc' },
16
+ { name: 'springboot-mongo-aggregation-mockmvc (Full Tests)', value: 'springboot-mongo-aggregation-mockmvc' },
17
+ { name: 'vue-basics (ref, reactive, computed, v-model)', value: 'vue-basics' },
18
+ { name: 'vue-props-emits (Parent/Child Component Communication)', value: 'vue-props-emits' },
19
+ { name: 'vue-router (Parent Layout & Nested Children)', value: 'vue-router' },
20
+ { name: 'vue-pinia (Centralized State Store)', value: 'vue-pinia' },
21
+ { name: 'vue-router-pinia (Router with Children + Pinia)', value: 'vue-router-pinia' },
22
+ { name: 'vue-fetch (Native fetch CRUD)', value: 'vue-fetch' },
23
+ { name: 'vue-axios (Axios CRUD Service)', value: 'vue-axios' },
24
+ { name: 'vue-router-pinia-props (Router + Pinia + Props + Emits)', value: 'vue-router-pinia-props' },
25
+ { name: 'vue-springboot-mongo-crud (Fullstack CRUD)', value: 'vue-springboot-mongo-crud' },
26
+ { name: 'vue-springboot-mongo-aggregation (Fullstack Dashboard)', value: 'vue-springboot-mongo-aggregation' },
27
+ { name: 'vue-router-pinia-springboot (Fullstack Enterprise)', value: 'vue-router-pinia-springboot' }
26
28
  ];
27
29
 
28
- const selected = process.argv[2];
29
- const targetDir = process.argv[3] || process.cwd();
30
+ let selectedIndex = 0;
31
+ const templatesRoot = path.join(__dirname, '..', 'templates');
30
32
 
31
- if (!selected || selected === 'list' || selected === '--help' || selected === '-h') {
32
- console.log('Usage: npx wad-lab <template-name> [destination-folder]');
33
- console.log('Example: npx wad-lab vue-axios my-app');
34
- console.log('Example: npx wad-lab all ./all-templates\n');
35
- console.log('Available Templates:');
36
- availableTemplates.forEach(t => console.log(' - ' + t));
37
- console.log(' - all (unpacks all templates)');
38
- process.exit(0);
33
+ function renderMenu() {
34
+ console.clear();
35
+ console.log('=== WAD LAB STARTER TEMPLATES ===');
36
+ console.log('Use [UP / DOWN] arrow keys to navigate, press [ENTER] to select:\n');
37
+
38
+ templates.forEach((t, i) => {
39
+ if (i === selectedIndex) {
40
+ console.log('> [*] ' + t.name);
41
+ } else {
42
+ console.log(' [ ] ' + t.name);
43
+ }
44
+ });
45
+
46
+ console.log('\nPress Ctrl+C to cancel.');
39
47
  }
40
48
 
41
- const templatesRoot = path.join(__dirname, '..', 'templates');
49
+ function unpack(choice) {
50
+ const destDir = process.cwd();
42
51
 
43
- if (selected === 'all') {
44
- const dest = path.resolve(targetDir);
45
- if (!fs.existsSync(dest)) {
46
- fs.mkdirSync(dest, { recursive: true });
52
+ if (choice === 'all') {
53
+ fs.cpSync(templatesRoot, destDir, { recursive: true });
54
+ console.log('\nSuccessfully unpacked ALL templates into: ' + destDir);
55
+ } else {
56
+ const src = path.join(templatesRoot, choice);
57
+ const dest = path.join(destDir, choice);
58
+ fs.cpSync(src, dest, { recursive: true });
59
+ console.log('\nSuccessfully unpacked [' + choice + '] into: ' + dest);
47
60
  }
48
- fs.cpSync(templatesRoot, dest, { recursive: true });
49
- console.log('Successfully unpacked all 17 templates to: ' + dest);
50
61
  process.exit(0);
51
62
  }
52
63
 
53
- if (!availableTemplates.includes(selected)) {
54
- console.error('Error: Template "' + selected + '" not found.');
55
- console.log('Run "npx wad-lab list" to view all available templates.');
56
- process.exit(1);
64
+ if (process.argv[2]) {
65
+ const arg = process.argv[2];
66
+ const found = templates.find(t => t.value === arg);
67
+ if (found) {
68
+ unpack(found.value);
69
+ } else {
70
+ console.error('Unknown template: ' + arg);
71
+ process.exit(1);
72
+ }
57
73
  }
58
74
 
59
- const src = path.join(templatesRoot, selected);
60
- const dest = path.resolve(targetDir);
61
-
62
- if (!fs.existsSync(dest)) {
63
- fs.mkdirSync(dest, { recursive: true });
75
+ readline.emitKeypressEvents(process.stdin);
76
+ if (process.stdin.isTTY) {
77
+ process.stdin.setRawMode(true);
64
78
  }
65
79
 
66
- fs.cpSync(src, dest, { recursive: true });
67
- console.log('Successfully unpacked template [' + selected + '] into: ' + dest);
80
+ renderMenu();
81
+
82
+ process.stdin.on('keypress', (str, key) => {
83
+ if (key.ctrl && key.name === 'c') {
84
+ process.exit(0);
85
+ }
86
+
87
+ if (key.name === 'up') {
88
+ selectedIndex = (selectedIndex - 1 + templates.length) % templates.length;
89
+ renderMenu();
90
+ } else if (key.name === 'down') {
91
+ selectedIndex = (selectedIndex + 1) % templates.length;
92
+ renderMenu();
93
+ } else if (key.name === 'return' || key.name === 'enter') {
94
+ if (process.stdin.isTTY) {
95
+ process.stdin.setRawMode(false);
96
+ }
97
+ const chosen = templates[selectedIndex].value;
98
+ unpack(chosen);
99
+ }
100
+ });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "wad-lab",
3
- "version": "1.0.0",
4
- "description": "Lab-ready starter templates for Web Application Development",
3
+ "version": "1.0.1",
4
+ "description": "Interactive CLI for WAD Lab starter templates (Spring Boot, MongoDB, Vue 3, Servlets)",
5
5
  "bin": {
6
6
  "wad-lab": "./bin/index.js"
7
7
  },