wad-lab 1.0.0 → 1.0.2
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.
- package/bin/index.js +99 -51
- package/package.json +2 -2
package/bin/index.js
CHANGED
|
@@ -2,66 +2,114 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
|
+
const readline = require('readline');
|
|
5
6
|
|
|
6
|
-
const
|
|
7
|
-
'
|
|
8
|
-
'
|
|
9
|
-
'servlet-
|
|
10
|
-
'servlet-
|
|
11
|
-
'
|
|
12
|
-
'springboot-mongo-
|
|
13
|
-
'springboot-
|
|
14
|
-
'springboot-
|
|
15
|
-
'
|
|
16
|
-
'vue-
|
|
17
|
-
'vue-
|
|
18
|
-
'vue-
|
|
19
|
-
'vue-
|
|
20
|
-
'vue-
|
|
21
|
-
'vue-
|
|
22
|
-
'vue-
|
|
23
|
-
'vue-
|
|
24
|
-
'vue-springboot-mongo-
|
|
25
|
-
'vue-
|
|
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
|
-
|
|
29
|
-
const
|
|
30
|
+
let selectedIndex = 0;
|
|
31
|
+
const templatesRoot = path.join(__dirname, '..', 'templates');
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
console.
|
|
33
|
-
console.log('
|
|
34
|
-
console.log('
|
|
35
|
-
console.log('Available Templates:');
|
|
36
|
-
availableTemplates.forEach(t => console.log(' - ' + t));
|
|
37
|
-
console.log(' - all (unpacks all templates)');
|
|
38
|
-
process.exit(0);
|
|
39
|
-
}
|
|
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');
|
|
40
37
|
|
|
41
|
-
|
|
38
|
+
templates.forEach((t, i) => {
|
|
39
|
+
if (i === selectedIndex) {
|
|
40
|
+
console.log('> [*] ' + t.name);
|
|
41
|
+
} else {
|
|
42
|
+
console.log(' [ ] ' + t.name);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
const dest = path.resolve(targetDir);
|
|
45
|
-
if (!fs.existsSync(dest)) {
|
|
46
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
47
|
-
}
|
|
48
|
-
fs.cpSync(templatesRoot, dest, { recursive: true });
|
|
49
|
-
console.log('Successfully unpacked all 17 templates to: ' + dest);
|
|
50
|
-
process.exit(0);
|
|
46
|
+
console.log('\nPress Ctrl+C to cancel.');
|
|
51
47
|
}
|
|
52
48
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
function promptFolderName(choice) {
|
|
50
|
+
if (process.stdin.isTTY) {
|
|
51
|
+
process.stdin.setRawMode(false);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const defaultFolder = choice === 'all' ? 'wad-all-templates' : choice;
|
|
55
|
+
const rl = readline.createInterface({
|
|
56
|
+
input: process.stdin,
|
|
57
|
+
output: process.stdout
|
|
58
|
+
});
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
console.log('\nSelected: ' + choice);
|
|
61
|
+
rl.question(`Enter destination folder name (default: "${defaultFolder}"): `, (answer) => {
|
|
62
|
+
rl.close();
|
|
63
|
+
const folder = answer.trim() || defaultFolder;
|
|
64
|
+
const dest = path.resolve(process.cwd(), folder);
|
|
61
65
|
|
|
62
|
-
if (!fs.existsSync(dest)) {
|
|
63
|
-
|
|
66
|
+
if (!fs.existsSync(dest)) {
|
|
67
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (choice === 'all') {
|
|
71
|
+
fs.cpSync(templatesRoot, dest, { recursive: true });
|
|
72
|
+
console.log('\nSuccessfully unpacked ALL templates into: ' + dest);
|
|
73
|
+
} else {
|
|
74
|
+
const src = path.join(templatesRoot, choice);
|
|
75
|
+
fs.cpSync(src, dest, { recursive: true });
|
|
76
|
+
console.log('\nSuccessfully unpacked [' + choice + '] into: ' + dest);
|
|
77
|
+
}
|
|
78
|
+
process.exit(0);
|
|
79
|
+
});
|
|
64
80
|
}
|
|
65
81
|
|
|
66
|
-
|
|
67
|
-
|
|
82
|
+
if (process.argv[2]) {
|
|
83
|
+
const arg = process.argv[2];
|
|
84
|
+
const found = templates.find(t => t.value === arg);
|
|
85
|
+
if (found) {
|
|
86
|
+
promptFolderName(found.value);
|
|
87
|
+
} else {
|
|
88
|
+
console.error('Unknown template: ' + arg);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
readline.emitKeypressEvents(process.stdin);
|
|
93
|
+
if (process.stdin.isTTY) {
|
|
94
|
+
process.stdin.setRawMode(true);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
renderMenu();
|
|
98
|
+
|
|
99
|
+
process.stdin.on('keypress', (str, key) => {
|
|
100
|
+
if (key.ctrl && key.name === 'c') {
|
|
101
|
+
process.exit(0);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (key.name === 'up') {
|
|
105
|
+
selectedIndex = (selectedIndex - 1 + templates.length) % templates.length;
|
|
106
|
+
renderMenu();
|
|
107
|
+
} else if (key.name === 'down') {
|
|
108
|
+
selectedIndex = (selectedIndex + 1) % templates.length;
|
|
109
|
+
renderMenu();
|
|
110
|
+
} else if (key.name === 'return' || key.name === 'enter') {
|
|
111
|
+
const chosen = templates[selectedIndex].value;
|
|
112
|
+
promptFolderName(chosen);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wad-lab",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Lab
|
|
3
|
+
"version": "1.0.2",
|
|
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
|
},
|