create-jinmankn-app 1.0.5 → 1.0.7

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 +170 -134
  2. package/package.json +4 -2
package/bin/index.js CHANGED
@@ -1,186 +1,222 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const inquirer = require("inquirer").default;
4
- const fs = require("fs-extra");
3
+ const fs = require("fs");
5
4
  const path = require("path");
6
- const ora = require("ora").default;
7
- const chalk = require("chalk");
8
- const { execSync } = require("child_process");
5
+ const readline = require("readline");
9
6
 
10
- const templatesDir = path.join(__dirname, "../templates");
7
+ const PKG_ROOT = path.join(__dirname, "..");
11
8
 
12
- // Check templates folder exists
13
- if (!fs.existsSync(templatesDir)) {
14
- console.log(chalk.red("Templates folder not found!"));
15
- process.exit(1);
9
+ const TEMPLATES = path.join(
10
+ PKG_ROOT,
11
+ "templates"
12
+ );
13
+
14
+ const MANIFEST = path.join(
15
+ TEMPLATES,
16
+ "projects.json"
17
+ );
18
+
19
+ // Question helper
20
+ function question(rl, prompt) {
21
+ return new Promise((resolve) =>
22
+ rl.question(prompt, resolve)
23
+ );
16
24
  }
17
25
 
18
- // Template metadata
19
- const templateChoices = [
20
- {
21
- name: "🏥 Hospital Management System",
22
- value: "hospital-faisal"
23
- },
24
- {
25
- name: "🗳️ BLUEPRINT",
26
- value: "blueprint"
27
- },
28
- {
29
- name: "📦 Student Fee Management System",
30
- value: "chom"
26
+ // Copy folder recursively
27
+ function copyTree(src, dest) {
28
+
29
+ fs.mkdirSync(dest, {
30
+ recursive: true
31
+ });
32
+
33
+ for (const name of fs.readdirSync(src, {
34
+ withFileTypes: true
35
+ })) {
36
+
37
+ const s = path.join(src, name.name);
38
+
39
+ const d = path.join(dest, name.name);
40
+
41
+ if (name.isDirectory()) {
42
+
43
+ // Ignore unnecessary folders
44
+ if (
45
+ name.name === "node_modules" ||
46
+ name.name === ".git" ||
47
+ name.name === "dist"
48
+ ) {
49
+ continue;
50
+ }
51
+
52
+ copyTree(s, d);
53
+
54
+ } else {
55
+
56
+ fs.copyFileSync(s, d);
57
+ }
31
58
  }
32
- ];
59
+ }
60
+
61
+ // Create .env from example
62
+ function ensureEnvFromExample(projectRoot) {
33
63
 
34
- // Get actual template folders
35
- const templates = fs
36
- .readdirSync(templatesDir)
37
- .filter((dir) =>
38
- fs.lstatSync(path.join(templatesDir, dir)).isDirectory()
64
+ const backend = path.join(
65
+ projectRoot,
66
+ "backend"
39
67
  );
40
68
 
41
- // Filter only existing templates
42
- const availableTemplates = templateChoices.filter((template) =>
43
- templates.includes(template.value)
44
- );
69
+ const example = path.join(
70
+ backend,
71
+ ".env.example"
72
+ );
45
73
 
46
- // No templates check
47
- if (availableTemplates.length === 0) {
48
- console.log(chalk.red("No templates found!"));
49
- process.exit(1);
74
+ const envFile = path.join(
75
+ backend,
76
+ ".env"
77
+ );
78
+
79
+ if (
80
+ fs.existsSync(example) &&
81
+ !fs.existsSync(envFile)
82
+ ) {
83
+
84
+ fs.copyFileSync(example, envFile);
85
+ }
50
86
  }
51
87
 
52
- async function createProject() {
53
-
54
- // Prompt user
55
- const answers = await inquirer.prompt([
56
- {
57
- type: "input",
58
- name: "projectName",
59
- message: "Project name:"
60
- },
61
- {
62
- type: "list",
63
- name: "templates",
64
- message: "Choose a template:",
65
- choices: availableTemplates
66
- }
67
- ]);
88
+ async function main() {
68
89
 
69
- const projectPath = path.join(
70
- process.cwd(),
71
- answers.projectName
90
+ // Read manifest
91
+ const manifest = JSON.parse(
92
+ fs.readFileSync(MANIFEST, "utf8")
72
93
  );
73
94
 
74
- const templatePath = path.join(
75
- templatesDir,
76
- answers.template
77
- );
95
+ const projects = manifest.projects;
96
+
97
+ if (!projects.length) {
78
98
 
79
- // Prevent overwrite
80
- if (fs.existsSync(projectPath)) {
81
99
  console.log(
82
- chalk.red("Folder already exists!")
100
+ "No templates found."
83
101
  );
84
102
 
85
103
  process.exit(1);
86
104
  }
87
105
 
88
- // Spinner
89
- const spinner = ora(
90
- "Creating project..."
91
- ).start();
106
+ // Show projects
107
+ console.log("");
92
108
 
93
- try {
109
+ for (let i = 0; i < projects.length; i++) {
94
110
 
95
- // Copy template
96
- await fs.copy(templatePath, projectPath);
111
+ const p = projects[i];
97
112
 
98
- // Install frontend dependencies
99
- const frontendPath = path.join(
100
- projectPath,
101
- "frontend"
113
+ console.log(
114
+ `[${i + 1}] ${p.title}`
102
115
  );
116
+ }
103
117
 
104
- if (fs.existsSync(frontendPath)) {
118
+ console.log("");
105
119
 
106
- spinner.text =
107
- "Installing frontend dependencies...";
120
+ // CLI input
121
+ const rl = readline.createInterface({
122
+ input: process.stdin,
123
+ output: process.stdout
124
+ });
108
125
 
109
- execSync("npm install", {
110
- cwd: frontendPath,
111
- stdio: "inherit"
112
- });
113
- }
126
+ // Choose template
127
+ const ans = await question(
128
+ rl,
129
+ `Pick (1-${projects.length}): `
130
+ );
114
131
 
115
- // Install backend dependencies
116
- const backendPath = path.join(
117
- projectPath,
118
- "backend"
119
- );
132
+ let choice = parseInt(ans);
120
133
 
121
- if (fs.existsSync(backendPath)) {
134
+ if (
135
+ isNaN(choice) ||
136
+ choice < 1 ||
137
+ choice > projects.length
138
+ ) {
122
139
 
123
- spinner.text =
124
- "Installing backend dependencies...";
140
+ choice = 1;
141
+ }
125
142
 
126
- execSync("npm install", {
127
- cwd: backendPath,
128
- stdio: "inherit"
129
- });
130
- }
143
+ const selected =
144
+ projects[choice - 1];
131
145
 
132
- spinner.succeed(
133
- chalk.green(
134
- "Project created successfully!"
135
- )
136
- );
146
+ // Ask project name
147
+ const projectName = await question(
148
+ rl,
149
+ "Project name: "
150
+ );
137
151
 
138
- console.log("\n");
152
+ rl.close();
139
153
 
140
- console.log(
141
- chalk.cyan("Next steps:")
142
- );
154
+ const target = path.resolve(
155
+ process.cwd(),
156
+ projectName
157
+ );
143
158
 
144
- console.log(
145
- chalk.white(
146
- `cd ${answers.projectName}`
147
- )
148
- );
159
+ // Prevent overwrite
160
+ if (fs.existsSync(target)) {
149
161
 
150
162
  console.log("");
151
-
152
163
  console.log(
153
- chalk.yellow("Frontend:")
164
+ "Folder already exists."
154
165
  );
155
166
 
156
- console.log(
157
- chalk.white(
158
- "cd frontend && npm run dev"
159
- )
160
- );
167
+ process.exit(1);
168
+ }
161
169
 
162
- console.log("");
170
+ // Template path
171
+ const templatePath = path.join(
172
+ TEMPLATES,
173
+ selected.templateDir
174
+ );
163
175
 
164
- console.log(
165
- chalk.yellow("Backend:")
166
- );
176
+ console.log("");
177
+ console.log(
178
+ "Creating project..."
179
+ );
167
180
 
168
- console.log(
169
- chalk.white(
170
- "cd backend && npm run dev"
171
- )
172
- );
181
+ // Copy files
182
+ copyTree(templatePath, target);
173
183
 
174
- } catch (err) {
184
+ // Create env
185
+ ensureEnvFromExample(target);
175
186
 
176
- spinner.fail(
177
- chalk.red(
178
- "Failed to create project"
179
- )
180
- );
187
+ console.log("");
188
+ console.log(
189
+ "Project created successfully!"
190
+ );
181
191
 
182
- console.log(err);
183
- }
192
+ console.log("");
193
+
194
+ console.log(`cd ${projectName}`);
195
+
196
+ console.log("");
197
+
198
+ console.log(
199
+ "Frontend:"
200
+ );
201
+
202
+ console.log(
203
+ "cd frontend && npm install && npm run dev"
204
+ );
205
+
206
+ console.log("");
207
+
208
+ console.log(
209
+ "Backend:"
210
+ );
211
+
212
+ console.log(
213
+ "cd backend && npm install && npm run dev"
214
+ );
184
215
  }
185
216
 
186
- createProject();
217
+ main().catch((err) => {
218
+
219
+ console.error(err);
220
+
221
+ process.exit(1);
222
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-jinmankn-app",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "",
5
5
  "bin": {
6
6
  "create-jinmankn-app": "./bin/index.js"
@@ -14,7 +14,9 @@
14
14
  "license": "ISC",
15
15
  "type": "commonjs",
16
16
  "dependencies": {
17
+ "chalk": "^5.6.2",
17
18
  "fs-extra": "^11.3.5",
18
- "inquirer": "^13.4.3"
19
+ "inquirer": "^13.4.3",
20
+ "ora": "^9.4.0"
19
21
  }
20
22
  }