create-project-cli-cm 1.0.0
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/LICENSE +21 -0
- package/NPM_PUBLISH_GUIDE.md +155 -0
- package/README.md +124 -0
- package/SUBMISSION.md +194 -0
- package/index.js +176 -0
- package/package.json +38 -0
- package/screenShot_collection.pdf +0 -0
- package/test.js +208 -0
- package/utils/argumentParser.js +61 -0
- package/utils/logger.js +43 -0
- package/utils/templateGenerator.js +1707 -0
|
@@ -0,0 +1,1707 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TemplateGenerator
|
|
3
|
+
* Generates different project templates with appropriate folder structures
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
class TemplateGenerator {
|
|
10
|
+
/**
|
|
11
|
+
* Generates a project based on the specified template
|
|
12
|
+
* @param {string} projectPath - Path where project will be created
|
|
13
|
+
* @param {string} template - Template type (web, api, cli, basic, fullstack)
|
|
14
|
+
* @param {Object} options - Additional options (projectName, author)
|
|
15
|
+
*/
|
|
16
|
+
generate(projectPath, template, options) {
|
|
17
|
+
switch (template) {
|
|
18
|
+
case 'web':
|
|
19
|
+
this.generateWebTemplate(projectPath, options);
|
|
20
|
+
break;
|
|
21
|
+
case 'api':
|
|
22
|
+
this.generateApiTemplate(projectPath, options);
|
|
23
|
+
break;
|
|
24
|
+
case 'cli':
|
|
25
|
+
this.generateCliTemplate(projectPath, options);
|
|
26
|
+
break;
|
|
27
|
+
case 'fullstack':
|
|
28
|
+
this.generateFullstackTemplate(projectPath, options);
|
|
29
|
+
break;
|
|
30
|
+
case 'basic':
|
|
31
|
+
default:
|
|
32
|
+
this.generateBasicTemplate(projectPath, options);
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Creates a directory if it doesn't exist
|
|
39
|
+
*/
|
|
40
|
+
createDir(dirPath) {
|
|
41
|
+
if (!fs.existsSync(dirPath)) {
|
|
42
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Writes content to a file
|
|
48
|
+
*/
|
|
49
|
+
writeFile(filePath, content) {
|
|
50
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Generates a basic project template
|
|
55
|
+
*/
|
|
56
|
+
generateBasicTemplate(projectPath, options) {
|
|
57
|
+
const { projectName, author } = options;
|
|
58
|
+
|
|
59
|
+
// Create folders
|
|
60
|
+
this.createDir(path.join(projectPath, 'src'));
|
|
61
|
+
this.createDir(path.join(projectPath, 'utils'));
|
|
62
|
+
this.createDir(path.join(projectPath, 'tests'));
|
|
63
|
+
|
|
64
|
+
// Create main entry file
|
|
65
|
+
this.writeFile(
|
|
66
|
+
path.join(projectPath, 'src', 'index.js'),
|
|
67
|
+
`// ${projectName}\n// Main entry point\n\nfunction main() {\n console.log('Hello from ${projectName}!');\n}\n\nmain();\n`
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// Create utility file
|
|
71
|
+
this.writeFile(
|
|
72
|
+
path.join(projectPath, 'utils', 'helpers.js'),
|
|
73
|
+
`// Helper functions for ${projectName}\n\nfunction formatDate(date) {\n return date.toLocaleDateString();\n}\n\nfunction capitalizeString(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nmodule.exports = {\n formatDate,\n capitalizeString\n};\n`
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// Create README
|
|
77
|
+
this.writeFile(
|
|
78
|
+
path.join(projectPath, 'README.md'),
|
|
79
|
+
this.generateReadme(projectName, 'basic', author)
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// Create .gitignore
|
|
83
|
+
this.writeFile(
|
|
84
|
+
path.join(projectPath, '.gitignore'),
|
|
85
|
+
'node_modules/\n*.log\n.DS_Store\n.env\n'
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
// Create package.json
|
|
89
|
+
this.writeFile(
|
|
90
|
+
path.join(projectPath, 'package.json'),
|
|
91
|
+
JSON.stringify({
|
|
92
|
+
name: projectName,
|
|
93
|
+
version: '1.0.0',
|
|
94
|
+
description: `${projectName} - A basic project`,
|
|
95
|
+
main: 'src/index.js',
|
|
96
|
+
scripts: {
|
|
97
|
+
start: 'node src/index.js',
|
|
98
|
+
test: 'echo "Error: no test specified" && exit 1'
|
|
99
|
+
},
|
|
100
|
+
keywords: [],
|
|
101
|
+
author: author || '',
|
|
102
|
+
license: 'MIT'
|
|
103
|
+
}, null, 2)
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Generates a web project template
|
|
109
|
+
*/
|
|
110
|
+
generateWebTemplate(projectPath, options) {
|
|
111
|
+
const { projectName, author } = options;
|
|
112
|
+
|
|
113
|
+
// Create folders
|
|
114
|
+
this.createDir(path.join(projectPath, 'src'));
|
|
115
|
+
this.createDir(path.join(projectPath, 'src', 'css'));
|
|
116
|
+
this.createDir(path.join(projectPath, 'src', 'js'));
|
|
117
|
+
this.createDir(path.join(projectPath, 'public'));
|
|
118
|
+
this.createDir(path.join(projectPath, 'assets'));
|
|
119
|
+
|
|
120
|
+
// Create HTML file
|
|
121
|
+
this.writeFile(
|
|
122
|
+
path.join(projectPath, 'src', 'index.html'),
|
|
123
|
+
`<!DOCTYPE html>
|
|
124
|
+
<html lang="en">
|
|
125
|
+
<head>
|
|
126
|
+
<meta charset="UTF-8">
|
|
127
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
128
|
+
<title>${projectName}</title>
|
|
129
|
+
<link rel="stylesheet" href="css/style.css">
|
|
130
|
+
</head>
|
|
131
|
+
<body>
|
|
132
|
+
<div class="container">
|
|
133
|
+
<header>
|
|
134
|
+
<h1>Welcome to ${projectName}</h1>
|
|
135
|
+
</header>
|
|
136
|
+
<main>
|
|
137
|
+
<p>Your web project is ready to go!</p>
|
|
138
|
+
<button id="actionBtn">Click Me</button>
|
|
139
|
+
</main>
|
|
140
|
+
<footer>
|
|
141
|
+
<p>© 2026 ${author || 'Your Name'}. All rights reserved.</p>
|
|
142
|
+
</footer>
|
|
143
|
+
</div>
|
|
144
|
+
<script src="js/app.js"></script>
|
|
145
|
+
</body>
|
|
146
|
+
</html>
|
|
147
|
+
`
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// Create CSS file
|
|
151
|
+
this.writeFile(
|
|
152
|
+
path.join(projectPath, 'src', 'css', 'style.css'),
|
|
153
|
+
`/* ${projectName} Styles */
|
|
154
|
+
|
|
155
|
+
* {
|
|
156
|
+
margin: 0;
|
|
157
|
+
padding: 0;
|
|
158
|
+
box-sizing: border-box;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
body {
|
|
162
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
163
|
+
line-height: 1.6;
|
|
164
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
165
|
+
min-height: 100vh;
|
|
166
|
+
display: flex;
|
|
167
|
+
justify-content: center;
|
|
168
|
+
align-items: center;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.container {
|
|
172
|
+
background: white;
|
|
173
|
+
padding: 2rem;
|
|
174
|
+
border-radius: 10px;
|
|
175
|
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
|
|
176
|
+
max-width: 600px;
|
|
177
|
+
width: 90%;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
header h1 {
|
|
181
|
+
color: #333;
|
|
182
|
+
margin-bottom: 1rem;
|
|
183
|
+
text-align: center;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
main {
|
|
187
|
+
padding: 2rem 0;
|
|
188
|
+
text-align: center;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
button {
|
|
192
|
+
background: #667eea;
|
|
193
|
+
color: white;
|
|
194
|
+
border: none;
|
|
195
|
+
padding: 12px 30px;
|
|
196
|
+
font-size: 16px;
|
|
197
|
+
border-radius: 5px;
|
|
198
|
+
cursor: pointer;
|
|
199
|
+
transition: background 0.3s;
|
|
200
|
+
margin-top: 1rem;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
button:hover {
|
|
204
|
+
background: #764ba2;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
footer {
|
|
208
|
+
text-align: center;
|
|
209
|
+
color: #666;
|
|
210
|
+
font-size: 14px;
|
|
211
|
+
margin-top: 2rem;
|
|
212
|
+
}
|
|
213
|
+
`
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
// Create JavaScript file
|
|
217
|
+
this.writeFile(
|
|
218
|
+
path.join(projectPath, 'src', 'js', 'app.js'),
|
|
219
|
+
`// ${projectName} - Main JavaScript
|
|
220
|
+
|
|
221
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
222
|
+
const btn = document.getElementById('actionBtn');
|
|
223
|
+
|
|
224
|
+
btn.addEventListener('click', () => {
|
|
225
|
+
alert('Hello from ${projectName}! 🚀');
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
console.log('${projectName} loaded successfully!');
|
|
229
|
+
});
|
|
230
|
+
`
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
// Create README
|
|
234
|
+
this.writeFile(
|
|
235
|
+
path.join(projectPath, 'README.md'),
|
|
236
|
+
this.generateReadme(projectName, 'web', author)
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
// Create .gitignore
|
|
240
|
+
this.writeFile(
|
|
241
|
+
path.join(projectPath, '.gitignore'),
|
|
242
|
+
'node_modules/\n*.log\n.DS_Store\ndist/\nbuild/\n'
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
// Create package.json
|
|
246
|
+
this.writeFile(
|
|
247
|
+
path.join(projectPath, 'package.json'),
|
|
248
|
+
JSON.stringify({
|
|
249
|
+
name: projectName,
|
|
250
|
+
version: '1.0.0',
|
|
251
|
+
description: `${projectName} - A web application`,
|
|
252
|
+
main: 'src/index.html',
|
|
253
|
+
scripts: {
|
|
254
|
+
start: 'echo "Open src/index.html in your browser"'
|
|
255
|
+
},
|
|
256
|
+
keywords: ['web', 'html', 'css', 'javascript'],
|
|
257
|
+
author: author || '',
|
|
258
|
+
license: 'MIT'
|
|
259
|
+
}, null, 2)
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Generates an API project template
|
|
265
|
+
*/
|
|
266
|
+
generateApiTemplate(projectPath, options) {
|
|
267
|
+
const { projectName, author } = options;
|
|
268
|
+
|
|
269
|
+
// Create folders
|
|
270
|
+
this.createDir(path.join(projectPath, 'src'));
|
|
271
|
+
this.createDir(path.join(projectPath, 'src', 'routes'));
|
|
272
|
+
this.createDir(path.join(projectPath, 'src', 'controllers'));
|
|
273
|
+
this.createDir(path.join(projectPath, 'src', 'models'));
|
|
274
|
+
this.createDir(path.join(projectPath, 'src', 'middleware'));
|
|
275
|
+
this.createDir(path.join(projectPath, 'utils'));
|
|
276
|
+
this.createDir(path.join(projectPath, 'config'));
|
|
277
|
+
|
|
278
|
+
// Create main server file
|
|
279
|
+
this.writeFile(
|
|
280
|
+
path.join(projectPath, 'src', 'server.js'),
|
|
281
|
+
`// ${projectName} - API Server
|
|
282
|
+
const http = require('http');
|
|
283
|
+
const url = require('url');
|
|
284
|
+
const routes = require('./routes');
|
|
285
|
+
|
|
286
|
+
const PORT = process.env.PORT || 3000;
|
|
287
|
+
|
|
288
|
+
const server = http.createServer((req, res) => {
|
|
289
|
+
const parsedUrl = url.parse(req.url, true);
|
|
290
|
+
const path = parsedUrl.pathname;
|
|
291
|
+
const method = req.method;
|
|
292
|
+
|
|
293
|
+
// Set CORS headers
|
|
294
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
295
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
|
|
296
|
+
res.setHeader('Content-Type', 'application/json');
|
|
297
|
+
|
|
298
|
+
// Route handling
|
|
299
|
+
routes.handleRequest(path, method, req, res);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
server.listen(PORT, () => {
|
|
303
|
+
console.log(\`🚀 ${projectName} API server running on http://localhost:\${PORT}\`);
|
|
304
|
+
});
|
|
305
|
+
`
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
// Create routes file
|
|
309
|
+
this.writeFile(
|
|
310
|
+
path.join(projectPath, 'src', 'routes', 'index.js'),
|
|
311
|
+
`// Routes handler
|
|
312
|
+
const controllers = require('../controllers');
|
|
313
|
+
|
|
314
|
+
function handleRequest(path, method, req, res) {
|
|
315
|
+
// API root
|
|
316
|
+
if (path === '/' && method === 'GET') {
|
|
317
|
+
res.writeHead(200);
|
|
318
|
+
res.end(JSON.stringify({
|
|
319
|
+
message: 'Welcome to the API',
|
|
320
|
+
version: '1.0.0',
|
|
321
|
+
endpoints: {
|
|
322
|
+
'/api/status': 'GET - Check API status',
|
|
323
|
+
'/api/data': 'GET - Get data'
|
|
324
|
+
}
|
|
325
|
+
}));
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Status endpoint
|
|
330
|
+
if (path === '/api/status' && method === 'GET') {
|
|
331
|
+
controllers.getStatus(req, res);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Data endpoint
|
|
336
|
+
if (path === '/api/data' && method === 'GET') {
|
|
337
|
+
controllers.getData(req, res);
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// 404 Not Found
|
|
342
|
+
res.writeHead(404);
|
|
343
|
+
res.end(JSON.stringify({ error: 'Route not found' }));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
module.exports = { handleRequest };
|
|
347
|
+
`
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
// Create controllers
|
|
351
|
+
this.writeFile(
|
|
352
|
+
path.join(projectPath, 'src', 'controllers', 'index.js'),
|
|
353
|
+
`// Controllers for API endpoints
|
|
354
|
+
|
|
355
|
+
function getStatus(req, res) {
|
|
356
|
+
res.writeHead(200);
|
|
357
|
+
res.end(JSON.stringify({
|
|
358
|
+
status: 'OK',
|
|
359
|
+
timestamp: new Date().toISOString(),
|
|
360
|
+
uptime: process.uptime()
|
|
361
|
+
}));
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function getData(req, res) {
|
|
365
|
+
const sampleData = {
|
|
366
|
+
items: [
|
|
367
|
+
{ id: 1, name: 'Item 1', value: 100 },
|
|
368
|
+
{ id: 2, name: 'Item 2', value: 200 },
|
|
369
|
+
{ id: 3, name: 'Item 3', value: 300 }
|
|
370
|
+
],
|
|
371
|
+
total: 3
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
res.writeHead(200);
|
|
375
|
+
res.end(JSON.stringify(sampleData));
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
module.exports = {
|
|
379
|
+
getStatus,
|
|
380
|
+
getData
|
|
381
|
+
};
|
|
382
|
+
`
|
|
383
|
+
);
|
|
384
|
+
|
|
385
|
+
// Create config file
|
|
386
|
+
this.writeFile(
|
|
387
|
+
path.join(projectPath, 'config', 'config.js'),
|
|
388
|
+
`// Configuration settings
|
|
389
|
+
module.exports = {
|
|
390
|
+
port: process.env.PORT || 3000,
|
|
391
|
+
environment: process.env.NODE_ENV || 'development',
|
|
392
|
+
apiVersion: '1.0.0'
|
|
393
|
+
};
|
|
394
|
+
`
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
// Create README
|
|
398
|
+
this.writeFile(
|
|
399
|
+
path.join(projectPath, 'README.md'),
|
|
400
|
+
this.generateReadme(projectName, 'api', author)
|
|
401
|
+
);
|
|
402
|
+
|
|
403
|
+
// Create .gitignore
|
|
404
|
+
this.writeFile(
|
|
405
|
+
path.join(projectPath, '.gitignore'),
|
|
406
|
+
'node_modules/\n*.log\n.DS_Store\n.env\n'
|
|
407
|
+
);
|
|
408
|
+
|
|
409
|
+
// Create package.json
|
|
410
|
+
this.writeFile(
|
|
411
|
+
path.join(projectPath, 'package.json'),
|
|
412
|
+
JSON.stringify({
|
|
413
|
+
name: projectName,
|
|
414
|
+
version: '1.0.0',
|
|
415
|
+
description: `${projectName} - REST API`,
|
|
416
|
+
main: 'src/server.js',
|
|
417
|
+
scripts: {
|
|
418
|
+
start: 'node src/server.js',
|
|
419
|
+
dev: 'node src/server.js'
|
|
420
|
+
},
|
|
421
|
+
keywords: ['api', 'rest', 'backend'],
|
|
422
|
+
author: author || '',
|
|
423
|
+
license: 'MIT'
|
|
424
|
+
}, null, 2)
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Generates a CLI project template
|
|
430
|
+
*/
|
|
431
|
+
generateCliTemplate(projectPath, options) {
|
|
432
|
+
const { projectName, author } = options;
|
|
433
|
+
|
|
434
|
+
// Create folders
|
|
435
|
+
this.createDir(path.join(projectPath, 'src'));
|
|
436
|
+
this.createDir(path.join(projectPath, 'utils'));
|
|
437
|
+
this.createDir(path.join(projectPath, 'commands'));
|
|
438
|
+
|
|
439
|
+
// Create main CLI file
|
|
440
|
+
this.writeFile(
|
|
441
|
+
path.join(projectPath, 'src', 'cli.js'),
|
|
442
|
+
`#!/usr/bin/env node
|
|
443
|
+
// ${projectName} - CLI Tool
|
|
444
|
+
|
|
445
|
+
const commands = require('../commands');
|
|
446
|
+
|
|
447
|
+
function main() {
|
|
448
|
+
const args = process.argv.slice(2);
|
|
449
|
+
|
|
450
|
+
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
|
|
451
|
+
showHelp();
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
const command = args[0];
|
|
456
|
+
|
|
457
|
+
switch (command) {
|
|
458
|
+
case 'hello':
|
|
459
|
+
commands.hello(args.slice(1));
|
|
460
|
+
break;
|
|
461
|
+
case 'version':
|
|
462
|
+
commands.version();
|
|
463
|
+
break;
|
|
464
|
+
default:
|
|
465
|
+
console.error(\`Unknown command: \${command}\`);
|
|
466
|
+
console.log('Use --help to see available commands');
|
|
467
|
+
process.exit(1);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
function showHelp() {
|
|
472
|
+
console.log(\`
|
|
473
|
+
╔════════════════════════════════════════╗
|
|
474
|
+
║ ${projectName.toUpperCase()} ║
|
|
475
|
+
╚════════════════════════════════════════╝
|
|
476
|
+
|
|
477
|
+
USAGE:
|
|
478
|
+
${projectName} <command> [options]
|
|
479
|
+
|
|
480
|
+
COMMANDS:
|
|
481
|
+
hello [name] Say hello to someone
|
|
482
|
+
version Show version information
|
|
483
|
+
--help, -h Show this help message
|
|
484
|
+
|
|
485
|
+
EXAMPLES:
|
|
486
|
+
${projectName} hello John
|
|
487
|
+
${projectName} version
|
|
488
|
+
\`);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
main();
|
|
492
|
+
`
|
|
493
|
+
);
|
|
494
|
+
|
|
495
|
+
// Create commands
|
|
496
|
+
this.writeFile(
|
|
497
|
+
path.join(projectPath, 'commands', 'index.js'),
|
|
498
|
+
`// Command implementations
|
|
499
|
+
|
|
500
|
+
function hello(args) {
|
|
501
|
+
const name = args[0] || 'World';
|
|
502
|
+
console.log(\`Hello, \${name}! 👋\`);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function version() {
|
|
506
|
+
const pkg = require('../package.json');
|
|
507
|
+
console.log(\`\${pkg.name} v\${pkg.version}\`);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
module.exports = {
|
|
511
|
+
hello,
|
|
512
|
+
version
|
|
513
|
+
};
|
|
514
|
+
`
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
// Create README
|
|
518
|
+
this.writeFile(
|
|
519
|
+
path.join(projectPath, 'README.md'),
|
|
520
|
+
this.generateReadme(projectName, 'cli', author)
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
// Create .gitignore
|
|
524
|
+
this.writeFile(
|
|
525
|
+
path.join(projectPath, '.gitignore'),
|
|
526
|
+
'node_modules/\n*.log\n.DS_Store\n'
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
// Create package.json
|
|
530
|
+
this.writeFile(
|
|
531
|
+
path.join(projectPath, 'package.json'),
|
|
532
|
+
JSON.stringify({
|
|
533
|
+
name: projectName,
|
|
534
|
+
version: '1.0.0',
|
|
535
|
+
description: `${projectName} - Command-line tool`,
|
|
536
|
+
main: 'src/cli.js',
|
|
537
|
+
bin: {
|
|
538
|
+
[projectName]: './src/cli.js'
|
|
539
|
+
},
|
|
540
|
+
scripts: {
|
|
541
|
+
start: 'node src/cli.js'
|
|
542
|
+
},
|
|
543
|
+
keywords: ['cli', 'command-line', 'tool'],
|
|
544
|
+
author: author || '',
|
|
545
|
+
license: 'MIT'
|
|
546
|
+
}, null, 2)
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Generates a full-stack project template with Frontend and Backend
|
|
552
|
+
*/
|
|
553
|
+
generateFullstackTemplate(projectPath, options) {
|
|
554
|
+
const { projectName, author } = options;
|
|
555
|
+
|
|
556
|
+
// ============ FRONTEND STRUCTURE ============
|
|
557
|
+
|
|
558
|
+
// Create frontend folders
|
|
559
|
+
this.createDir(path.join(projectPath, 'frontend'));
|
|
560
|
+
this.createDir(path.join(projectPath, 'frontend', 'src'));
|
|
561
|
+
this.createDir(path.join(projectPath, 'frontend', 'src', 'components'));
|
|
562
|
+
this.createDir(path.join(projectPath, 'frontend', 'src', 'pages'));
|
|
563
|
+
this.createDir(path.join(projectPath, 'frontend', 'src', 'styles'));
|
|
564
|
+
this.createDir(path.join(projectPath, 'frontend', 'src', 'services'));
|
|
565
|
+
this.createDir(path.join(projectPath, 'frontend', 'public'));
|
|
566
|
+
|
|
567
|
+
// Frontend: Main App.js
|
|
568
|
+
this.writeFile(
|
|
569
|
+
path.join(projectPath, 'frontend', 'src', 'App.js'),
|
|
570
|
+
`// ${projectName} - Frontend App
|
|
571
|
+
import { fetchUsers, createUser } from './services/api.js';
|
|
572
|
+
|
|
573
|
+
class App {
|
|
574
|
+
constructor() {
|
|
575
|
+
this.apiUrl = 'http://localhost:5000';
|
|
576
|
+
this.init();
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
async init() {
|
|
580
|
+
console.log('${projectName} Frontend Loaded!');
|
|
581
|
+
this.setupEventListeners();
|
|
582
|
+
await this.loadUsers();
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
setupEventListeners() {
|
|
586
|
+
const form = document.getElementById('userForm');
|
|
587
|
+
if (form) {
|
|
588
|
+
form.addEventListener('submit', (e) => this.handleSubmit(e));
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
const refreshBtn = document.getElementById('refreshBtn');
|
|
592
|
+
if (refreshBtn) {
|
|
593
|
+
refreshBtn.addEventListener('click', () => this.loadUsers());
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
async loadUsers() {
|
|
598
|
+
try {
|
|
599
|
+
const users = await fetchUsers();
|
|
600
|
+
this.displayUsers(users);
|
|
601
|
+
} catch (error) {
|
|
602
|
+
console.error('Error loading users:', error);
|
|
603
|
+
document.getElementById('userList').innerHTML =
|
|
604
|
+
'<p class="error">Failed to load users. Is backend running?</p>';
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
displayUsers(users) {
|
|
609
|
+
const userList = document.getElementById('userList');
|
|
610
|
+
if (users.length === 0) {
|
|
611
|
+
userList.innerHTML = '<p>No users found. Add one below!</p>';
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
userList.innerHTML = users.map(user => \`
|
|
616
|
+
<div class="user-card">
|
|
617
|
+
<h3>\${user.name}</h3>
|
|
618
|
+
<p>\${user.email}</p>
|
|
619
|
+
<small>ID: \${user.id}</small>
|
|
620
|
+
</div>
|
|
621
|
+
\`).join('');
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
async handleSubmit(e) {
|
|
625
|
+
e.preventDefault();
|
|
626
|
+
const name = document.getElementById('name').value;
|
|
627
|
+
const email = document.getElementById('email').value;
|
|
628
|
+
|
|
629
|
+
try {
|
|
630
|
+
await createUser({ name, email });
|
|
631
|
+
e.target.reset();
|
|
632
|
+
await this.loadUsers();
|
|
633
|
+
alert('User added successfully!');
|
|
634
|
+
} catch (error) {
|
|
635
|
+
alert('Failed to add user: ' + error.message);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// Initialize app when DOM is ready
|
|
641
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
642
|
+
new App();
|
|
643
|
+
});
|
|
644
|
+
`
|
|
645
|
+
);
|
|
646
|
+
|
|
647
|
+
// Frontend: API Service
|
|
648
|
+
this.writeFile(
|
|
649
|
+
path.join(projectPath, 'frontend', 'src', 'services', 'api.js'),
|
|
650
|
+
`// API Service - Connects to Backend
|
|
651
|
+
const API_URL = 'http://localhost:5000/api';
|
|
652
|
+
|
|
653
|
+
export async function fetchUsers() {
|
|
654
|
+
const response = await fetch(\`\${API_URL}/users\`);
|
|
655
|
+
if (!response.ok) throw new Error('Failed to fetch users');
|
|
656
|
+
return response.json();
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
export async function createUser(userData) {
|
|
660
|
+
const response = await fetch(\`\${API_URL}/users\`, {
|
|
661
|
+
method: 'POST',
|
|
662
|
+
headers: {
|
|
663
|
+
'Content-Type': 'application/json'
|
|
664
|
+
},
|
|
665
|
+
body: JSON.stringify(userData)
|
|
666
|
+
});
|
|
667
|
+
if (!response.ok) throw new Error('Failed to create user');
|
|
668
|
+
return response.json();
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
export async function deleteUser(id) {
|
|
672
|
+
const response = await fetch(\`\${API_URL}/users/\${id}\`, {
|
|
673
|
+
method: 'DELETE'
|
|
674
|
+
});
|
|
675
|
+
if (!response.ok) throw new Error('Failed to delete user');
|
|
676
|
+
return response.json();
|
|
677
|
+
}
|
|
678
|
+
`
|
|
679
|
+
);
|
|
680
|
+
|
|
681
|
+
// Frontend: Header Component
|
|
682
|
+
this.writeFile(
|
|
683
|
+
path.join(projectPath, 'frontend', 'src', 'components', 'Header.js'),
|
|
684
|
+
`// Header Component
|
|
685
|
+
export function createHeader() {
|
|
686
|
+
return \`
|
|
687
|
+
<header class="header">
|
|
688
|
+
<h1>${projectName}</h1>
|
|
689
|
+
<p>Full-Stack Application Demo</p>
|
|
690
|
+
</header>
|
|
691
|
+
\`;
|
|
692
|
+
}
|
|
693
|
+
`
|
|
694
|
+
);
|
|
695
|
+
|
|
696
|
+
// Frontend: User List Page
|
|
697
|
+
this.writeFile(
|
|
698
|
+
path.join(projectPath, 'frontend', 'src', 'pages', 'UsersPage.js'),
|
|
699
|
+
`// Users Page Component
|
|
700
|
+
export function createUsersPage() {
|
|
701
|
+
return \`
|
|
702
|
+
<div class="page">
|
|
703
|
+
<h2>User Management</h2>
|
|
704
|
+
<button id="refreshBtn" class="btn btn-secondary">Refresh Users</button>
|
|
705
|
+
|
|
706
|
+
<div id="userList" class="user-list">
|
|
707
|
+
<p>Loading users...</p>
|
|
708
|
+
</div>
|
|
709
|
+
|
|
710
|
+
<div class="form-section">
|
|
711
|
+
<h3>Add New User</h3>
|
|
712
|
+
<form id="userForm">
|
|
713
|
+
<input type="text" id="name" placeholder="Name" required />
|
|
714
|
+
<input type="email" id="email" placeholder="Email" required />
|
|
715
|
+
<button type="submit" class="btn btn-primary">Add User</button>
|
|
716
|
+
</form>
|
|
717
|
+
</div>
|
|
718
|
+
</div>
|
|
719
|
+
\`;
|
|
720
|
+
}
|
|
721
|
+
`
|
|
722
|
+
);
|
|
723
|
+
|
|
724
|
+
// Frontend: Main HTML
|
|
725
|
+
this.writeFile(
|
|
726
|
+
path.join(projectPath, 'frontend', 'public', 'index.html'),
|
|
727
|
+
`<!DOCTYPE html>
|
|
728
|
+
<html lang="en">
|
|
729
|
+
<head>
|
|
730
|
+
<meta charset="UTF-8">
|
|
731
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
732
|
+
<title>${projectName} - Full-Stack App</title>
|
|
733
|
+
<link rel="stylesheet" href="../src/styles/main.css">
|
|
734
|
+
</head>
|
|
735
|
+
<body>
|
|
736
|
+
<div class="container">
|
|
737
|
+
<header>
|
|
738
|
+
<h1>${projectName}</h1>
|
|
739
|
+
<p>Full-Stack Application</p>
|
|
740
|
+
<small>Frontend + Backend Connected</small>
|
|
741
|
+
</header>
|
|
742
|
+
|
|
743
|
+
<main>
|
|
744
|
+
<section class="status">
|
|
745
|
+
<h2>Connection Status</h2>
|
|
746
|
+
<p id="status">Checking backend connection...</p>
|
|
747
|
+
</section>
|
|
748
|
+
|
|
749
|
+
<section class="users">
|
|
750
|
+
<div class="section-header">
|
|
751
|
+
<h2>Users</h2>
|
|
752
|
+
<button id="refreshBtn" class="btn btn-secondary">🔄 Refresh</button>
|
|
753
|
+
</div>
|
|
754
|
+
<div id="userList" class="user-list">
|
|
755
|
+
<p>Loading users...</p>
|
|
756
|
+
</div>
|
|
757
|
+
</section>
|
|
758
|
+
|
|
759
|
+
<section class="form-section">
|
|
760
|
+
<h2>Add New User</h2>
|
|
761
|
+
<form id="userForm">
|
|
762
|
+
<div class="form-group">
|
|
763
|
+
<label for="name">Name:</label>
|
|
764
|
+
<input type="text" id="name" placeholder="Enter name" required />
|
|
765
|
+
</div>
|
|
766
|
+
<div class="form-group">
|
|
767
|
+
<label for="email">Email:</label>
|
|
768
|
+
<input type="email" id="email" placeholder="Enter email" required />
|
|
769
|
+
</div>
|
|
770
|
+
<button type="submit" class="btn btn-primary">Add User</button>
|
|
771
|
+
</form>
|
|
772
|
+
</section>
|
|
773
|
+
</main>
|
|
774
|
+
|
|
775
|
+
<footer>
|
|
776
|
+
<p>Created with create-project-cli | Backend: Node.js | Frontend: Vanilla JS</p>
|
|
777
|
+
</footer>
|
|
778
|
+
</div>
|
|
779
|
+
|
|
780
|
+
<script type="module" src="../src/App.js"></script>
|
|
781
|
+
</body>
|
|
782
|
+
</html>
|
|
783
|
+
`
|
|
784
|
+
);
|
|
785
|
+
|
|
786
|
+
// Frontend: CSS
|
|
787
|
+
this.writeFile(
|
|
788
|
+
path.join(projectPath, 'frontend', 'src', 'styles', 'main.css'),
|
|
789
|
+
`/* ${projectName} - Main Styles */
|
|
790
|
+
|
|
791
|
+
* {
|
|
792
|
+
margin: 0;
|
|
793
|
+
padding: 0;
|
|
794
|
+
box-sizing: border-box;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
body {
|
|
798
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
799
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
800
|
+
min-height: 100vh;
|
|
801
|
+
padding: 20px;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
.container {
|
|
805
|
+
max-width: 1000px;
|
|
806
|
+
margin: 0 auto;
|
|
807
|
+
background: white;
|
|
808
|
+
border-radius: 15px;
|
|
809
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
810
|
+
overflow: hidden;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
header {
|
|
814
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
815
|
+
color: white;
|
|
816
|
+
padding: 30px;
|
|
817
|
+
text-align: center;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
header h1 {
|
|
821
|
+
font-size: 2.5rem;
|
|
822
|
+
margin-bottom: 10px;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
header p {
|
|
826
|
+
font-size: 1.2rem;
|
|
827
|
+
opacity: 0.9;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
header small {
|
|
831
|
+
display: block;
|
|
832
|
+
margin-top: 10px;
|
|
833
|
+
opacity: 0.8;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
main {
|
|
837
|
+
padding: 30px;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
section {
|
|
841
|
+
margin-bottom: 30px;
|
|
842
|
+
padding: 20px;
|
|
843
|
+
background: #f8f9fa;
|
|
844
|
+
border-radius: 10px;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
h2 {
|
|
848
|
+
color: #333;
|
|
849
|
+
margin-bottom: 15px;
|
|
850
|
+
font-size: 1.5rem;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
.status p {
|
|
854
|
+
padding: 15px;
|
|
855
|
+
background: #fff;
|
|
856
|
+
border-radius: 5px;
|
|
857
|
+
border-left: 4px solid #667eea;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
.section-header {
|
|
861
|
+
display: flex;
|
|
862
|
+
justify-content: space-between;
|
|
863
|
+
align-items: center;
|
|
864
|
+
margin-bottom: 15px;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
.user-list {
|
|
868
|
+
display: grid;
|
|
869
|
+
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
|
870
|
+
gap: 15px;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
.user-card {
|
|
874
|
+
background: white;
|
|
875
|
+
padding: 20px;
|
|
876
|
+
border-radius: 8px;
|
|
877
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
878
|
+
transition: transform 0.2s;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
.user-card:hover {
|
|
882
|
+
transform: translateY(-5px);
|
|
883
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
.user-card h3 {
|
|
887
|
+
color: #667eea;
|
|
888
|
+
margin-bottom: 8px;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
.user-card p {
|
|
892
|
+
color: #666;
|
|
893
|
+
margin-bottom: 5px;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
.user-card small {
|
|
897
|
+
color: #999;
|
|
898
|
+
font-size: 0.85rem;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
.form-section {
|
|
902
|
+
background: #fff;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
.form-group {
|
|
906
|
+
margin-bottom: 15px;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
label {
|
|
910
|
+
display: block;
|
|
911
|
+
margin-bottom: 5px;
|
|
912
|
+
color: #555;
|
|
913
|
+
font-weight: 500;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
input[type="text"],
|
|
917
|
+
input[type="email"] {
|
|
918
|
+
width: 100%;
|
|
919
|
+
padding: 12px;
|
|
920
|
+
border: 2px solid #e0e0e0;
|
|
921
|
+
border-radius: 5px;
|
|
922
|
+
font-size: 1rem;
|
|
923
|
+
transition: border-color 0.3s;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
input:focus {
|
|
927
|
+
outline: none;
|
|
928
|
+
border-color: #667eea;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
.btn {
|
|
932
|
+
padding: 12px 24px;
|
|
933
|
+
border: none;
|
|
934
|
+
border-radius: 5px;
|
|
935
|
+
font-size: 1rem;
|
|
936
|
+
cursor: pointer;
|
|
937
|
+
transition: all 0.3s;
|
|
938
|
+
font-weight: 500;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
.btn-primary {
|
|
942
|
+
background: #667eea;
|
|
943
|
+
color: white;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
.btn-primary:hover {
|
|
947
|
+
background: #5568d3;
|
|
948
|
+
transform: translateY(-2px);
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
.btn-secondary {
|
|
952
|
+
background: #6c757d;
|
|
953
|
+
color: white;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
.btn-secondary:hover {
|
|
957
|
+
background: #5a6268;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
.error {
|
|
961
|
+
color: #dc3545;
|
|
962
|
+
padding: 15px;
|
|
963
|
+
background: #f8d7da;
|
|
964
|
+
border-radius: 5px;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
footer {
|
|
968
|
+
background: #f8f9fa;
|
|
969
|
+
padding: 20px;
|
|
970
|
+
text-align: center;
|
|
971
|
+
color: #666;
|
|
972
|
+
border-top: 1px solid #e0e0e0;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
@media (max-width: 768px) {
|
|
976
|
+
.user-list {
|
|
977
|
+
grid-template-columns: 1fr;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
header h1 {
|
|
981
|
+
font-size: 2rem;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
`
|
|
985
|
+
);
|
|
986
|
+
|
|
987
|
+
// Frontend: Dev Server
|
|
988
|
+
this.writeFile(
|
|
989
|
+
path.join(projectPath, 'frontend', 'server.js'),
|
|
990
|
+
`// Frontend Development Server
|
|
991
|
+
const http = require('http');
|
|
992
|
+
const fs = require('fs');
|
|
993
|
+
const path = require('path');
|
|
994
|
+
|
|
995
|
+
const PORT = process.env.PORT || 3000;
|
|
996
|
+
|
|
997
|
+
const mimeTypes = {
|
|
998
|
+
'.html': 'text/html',
|
|
999
|
+
'.js': 'text/javascript',
|
|
1000
|
+
'.css': 'text/css',
|
|
1001
|
+
'.json': 'application/json',
|
|
1002
|
+
'.png': 'image/png',
|
|
1003
|
+
'.jpg': 'image/jpg',
|
|
1004
|
+
'.gif': 'image/gif',
|
|
1005
|
+
'.svg': 'image/svg+xml',
|
|
1006
|
+
'.ico': 'image/x-icon'
|
|
1007
|
+
};
|
|
1008
|
+
|
|
1009
|
+
const server = http.createServer((req, res) => {
|
|
1010
|
+
let filePath = req.url === '/' ? '/public/index.html' : req.url;
|
|
1011
|
+
|
|
1012
|
+
// Remove query strings
|
|
1013
|
+
filePath = filePath.split('?')[0];
|
|
1014
|
+
|
|
1015
|
+
// Build full file path
|
|
1016
|
+
let fullPath = path.join(__dirname, filePath);
|
|
1017
|
+
|
|
1018
|
+
// Check if file exists
|
|
1019
|
+
fs.access(fullPath, fs.constants.F_OK, (err) => {
|
|
1020
|
+
if (err) {
|
|
1021
|
+
res.writeHead(404);
|
|
1022
|
+
res.end('404 Not Found');
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
// Get file extension
|
|
1027
|
+
const extname = String(path.extname(fullPath)).toLowerCase();
|
|
1028
|
+
const contentType = mimeTypes[extname] || 'application/octet-stream';
|
|
1029
|
+
|
|
1030
|
+
// Read and serve file
|
|
1031
|
+
fs.readFile(fullPath, (error, content) => {
|
|
1032
|
+
if (error) {
|
|
1033
|
+
res.writeHead(500);
|
|
1034
|
+
res.end('500 Internal Server Error: ' + error.code);
|
|
1035
|
+
} else {
|
|
1036
|
+
res.writeHead(200, { 'Content-Type': contentType });
|
|
1037
|
+
res.end(content, 'utf-8');
|
|
1038
|
+
}
|
|
1039
|
+
});
|
|
1040
|
+
});
|
|
1041
|
+
});
|
|
1042
|
+
|
|
1043
|
+
server.listen(PORT, () => {
|
|
1044
|
+
console.log(\`\\n🎨 ${projectName} Frontend Server Started!\`);
|
|
1045
|
+
console.log(\`📱 Frontend running on http://localhost:\${PORT}\`);
|
|
1046
|
+
console.log(\`\\n✅ Open http://localhost:\${PORT} in your browser!\\n\`);
|
|
1047
|
+
});
|
|
1048
|
+
`
|
|
1049
|
+
);
|
|
1050
|
+
|
|
1051
|
+
// Frontend: package.json
|
|
1052
|
+
this.writeFile(
|
|
1053
|
+
path.join(projectPath, 'frontend', 'package.json'),
|
|
1054
|
+
JSON.stringify({
|
|
1055
|
+
name: `${projectName}-frontend`,
|
|
1056
|
+
version: '1.0.0',
|
|
1057
|
+
description: `${projectName} - Frontend Application`,
|
|
1058
|
+
main: 'server.js',
|
|
1059
|
+
scripts: {
|
|
1060
|
+
dev: 'node server.js',
|
|
1061
|
+
start: 'node server.js'
|
|
1062
|
+
},
|
|
1063
|
+
keywords: ['frontend', 'fullstack'],
|
|
1064
|
+
author: author || '',
|
|
1065
|
+
license: 'MIT'
|
|
1066
|
+
}, null, 2)
|
|
1067
|
+
);
|
|
1068
|
+
|
|
1069
|
+
// ============ BACKEND STRUCTURE ============
|
|
1070
|
+
|
|
1071
|
+
// Create backend folders (flat structure - no src/)
|
|
1072
|
+
this.createDir(path.join(projectPath, 'backend'));
|
|
1073
|
+
this.createDir(path.join(projectPath, 'backend', 'routes'));
|
|
1074
|
+
this.createDir(path.join(projectPath, 'backend', 'controllers'));
|
|
1075
|
+
this.createDir(path.join(projectPath, 'backend', 'models'));
|
|
1076
|
+
this.createDir(path.join(projectPath, 'backend', 'middleware'));
|
|
1077
|
+
this.createDir(path.join(projectPath, 'backend', 'config'));
|
|
1078
|
+
|
|
1079
|
+
// Backend: Main Server
|
|
1080
|
+
this.writeFile(
|
|
1081
|
+
path.join(projectPath, 'backend', 'server.js'),
|
|
1082
|
+
`// ${projectName} - Backend Server
|
|
1083
|
+
const http = require('http');
|
|
1084
|
+
const url = require('url');
|
|
1085
|
+
const routes = require('./routes/index');
|
|
1086
|
+
|
|
1087
|
+
const PORT = process.env.PORT || 5000;
|
|
1088
|
+
|
|
1089
|
+
const server = http.createServer((req, res) => {
|
|
1090
|
+
const parsedUrl = url.parse(req.url, true);
|
|
1091
|
+
const path = parsedUrl.pathname;
|
|
1092
|
+
const method = req.method;
|
|
1093
|
+
|
|
1094
|
+
// CORS headers (allow frontend to connect)
|
|
1095
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
1096
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
1097
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
1098
|
+
res.setHeader('Content-Type', 'application/json');
|
|
1099
|
+
|
|
1100
|
+
// Handle preflight requests
|
|
1101
|
+
if (method === 'OPTIONS') {
|
|
1102
|
+
res.writeHead(200);
|
|
1103
|
+
res.end();
|
|
1104
|
+
return;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
// Route handling
|
|
1108
|
+
routes.handleRequest(path, method, req, res, parsedUrl.query);
|
|
1109
|
+
});
|
|
1110
|
+
|
|
1111
|
+
server.listen(PORT, () => {
|
|
1112
|
+
console.log(\`\\n🚀 ${projectName} Backend Server Started!\`);
|
|
1113
|
+
console.log(\`📡 Server running on http://localhost:\${PORT}\`);
|
|
1114
|
+
console.log(\`📋 API Endpoints:\`);
|
|
1115
|
+
console.log(\` GET http://localhost:\${PORT}/api/users\`);
|
|
1116
|
+
console.log(\` POST http://localhost:\${PORT}/api/users\`);
|
|
1117
|
+
console.log(\` GET http://localhost:\${PORT}/api/status\`);
|
|
1118
|
+
console.log(\`\\n✅ Ready to receive requests from frontend!\\n\`);
|
|
1119
|
+
});
|
|
1120
|
+
`
|
|
1121
|
+
);
|
|
1122
|
+
|
|
1123
|
+
// Backend: Routes
|
|
1124
|
+
this.writeFile(
|
|
1125
|
+
path.join(projectPath, 'backend', 'routes', 'index.js'),
|
|
1126
|
+
`// Routes Handler
|
|
1127
|
+
const userController = require('../controllers/userController');
|
|
1128
|
+
|
|
1129
|
+
function handleRequest(path, method, req, res, query) {
|
|
1130
|
+
// Root endpoint
|
|
1131
|
+
if (path === '/' && method === 'GET') {
|
|
1132
|
+
res.writeHead(200);
|
|
1133
|
+
res.end(JSON.stringify({
|
|
1134
|
+
message: 'Backend API is running',
|
|
1135
|
+
version: '1.0.0',
|
|
1136
|
+
endpoints: {
|
|
1137
|
+
'GET /api/status': 'Check API status',
|
|
1138
|
+
'GET /api/users': 'Get all users',
|
|
1139
|
+
'POST /api/users': 'Create new user'
|
|
1140
|
+
}
|
|
1141
|
+
}));
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
// Status endpoint
|
|
1146
|
+
if (path === '/api/status' && method === 'GET') {
|
|
1147
|
+
res.writeHead(200);
|
|
1148
|
+
res.end(JSON.stringify({
|
|
1149
|
+
status: 'OK',
|
|
1150
|
+
message: 'Backend is connected!',
|
|
1151
|
+
timestamp: new Date().toISOString()
|
|
1152
|
+
}));
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
// User routes
|
|
1157
|
+
if (path === '/api/users' && method === 'GET') {
|
|
1158
|
+
userController.getUsers(req, res);
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
if (path === '/api/users' && method === 'POST') {
|
|
1163
|
+
userController.createUser(req, res);
|
|
1164
|
+
return;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
if (path.startsWith('/api/users/') && method === 'DELETE') {
|
|
1168
|
+
const id = path.split('/')[3];
|
|
1169
|
+
userController.deleteUser(req, res, id);
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
// 404 Not Found
|
|
1174
|
+
res.writeHead(404);
|
|
1175
|
+
res.end(JSON.stringify({
|
|
1176
|
+
error: 'Route not found',
|
|
1177
|
+
path: path,
|
|
1178
|
+
method: method
|
|
1179
|
+
}));
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
module.exports = { handleRequest };
|
|
1183
|
+
`
|
|
1184
|
+
);
|
|
1185
|
+
|
|
1186
|
+
// Backend: User Controller
|
|
1187
|
+
this.writeFile(
|
|
1188
|
+
path.join(projectPath, 'backend', 'controllers', 'userController.js'),
|
|
1189
|
+
`// User Controller - Handles user operations
|
|
1190
|
+
const User = require('../models/User');
|
|
1191
|
+
|
|
1192
|
+
// Get all users
|
|
1193
|
+
function getUsers(req, res) {
|
|
1194
|
+
try {
|
|
1195
|
+
const users = User.getAll();
|
|
1196
|
+
res.writeHead(200);
|
|
1197
|
+
res.end(JSON.stringify(users));
|
|
1198
|
+
} catch (error) {
|
|
1199
|
+
res.writeHead(500);
|
|
1200
|
+
res.end(JSON.stringify({ error: error.message }));
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
// Create new user
|
|
1205
|
+
function createUser(req, res) {
|
|
1206
|
+
let body = '';
|
|
1207
|
+
|
|
1208
|
+
req.on('data', chunk => {
|
|
1209
|
+
body += chunk.toString();
|
|
1210
|
+
});
|
|
1211
|
+
|
|
1212
|
+
req.on('end', () => {
|
|
1213
|
+
try {
|
|
1214
|
+
const userData = JSON.parse(body);
|
|
1215
|
+
|
|
1216
|
+
// Validation
|
|
1217
|
+
if (!userData.name || !userData.email) {
|
|
1218
|
+
res.writeHead(400);
|
|
1219
|
+
res.end(JSON.stringify({
|
|
1220
|
+
error: 'Name and email are required'
|
|
1221
|
+
}));
|
|
1222
|
+
return;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
const newUser = User.create(userData);
|
|
1226
|
+
res.writeHead(201);
|
|
1227
|
+
res.end(JSON.stringify({
|
|
1228
|
+
message: 'User created successfully',
|
|
1229
|
+
user: newUser
|
|
1230
|
+
}));
|
|
1231
|
+
} catch (error) {
|
|
1232
|
+
res.writeHead(400);
|
|
1233
|
+
res.end(JSON.stringify({ error: error.message }));
|
|
1234
|
+
}
|
|
1235
|
+
});
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
// Delete user
|
|
1239
|
+
function deleteUser(req, res, id) {
|
|
1240
|
+
try {
|
|
1241
|
+
User.delete(id);
|
|
1242
|
+
res.writeHead(200);
|
|
1243
|
+
res.end(JSON.stringify({
|
|
1244
|
+
message: 'User deleted successfully',
|
|
1245
|
+
id: id
|
|
1246
|
+
}));
|
|
1247
|
+
} catch (error) {
|
|
1248
|
+
res.writeHead(404);
|
|
1249
|
+
res.end(JSON.stringify({ error: error.message }));
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
module.exports = {
|
|
1254
|
+
getUsers,
|
|
1255
|
+
createUser,
|
|
1256
|
+
deleteUser
|
|
1257
|
+
};
|
|
1258
|
+
`
|
|
1259
|
+
);
|
|
1260
|
+
|
|
1261
|
+
// Backend: User Model (In-Memory Database)
|
|
1262
|
+
this.writeFile(
|
|
1263
|
+
path.join(projectPath, 'backend', 'models', 'User.js'),
|
|
1264
|
+
`// User Model - In-Memory Database
|
|
1265
|
+
let users = [
|
|
1266
|
+
{ id: 1, name: 'John Doe', email: 'john@example.com' },
|
|
1267
|
+
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' },
|
|
1268
|
+
{ id: 3, name: 'Bob Johnson', email: 'bob@example.com' }
|
|
1269
|
+
];
|
|
1270
|
+
|
|
1271
|
+
let nextId = 4;
|
|
1272
|
+
|
|
1273
|
+
class User {
|
|
1274
|
+
static getAll() {
|
|
1275
|
+
return users;
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
static getById(id) {
|
|
1279
|
+
return users.find(user => user.id === parseInt(id));
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
static create(userData) {
|
|
1283
|
+
const newUser = {
|
|
1284
|
+
id: nextId++,
|
|
1285
|
+
name: userData.name,
|
|
1286
|
+
email: userData.email,
|
|
1287
|
+
createdAt: new Date().toISOString()
|
|
1288
|
+
};
|
|
1289
|
+
users.push(newUser);
|
|
1290
|
+
return newUser;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
static delete(id) {
|
|
1294
|
+
const index = users.findIndex(user => user.id === parseInt(id));
|
|
1295
|
+
if (index === -1) {
|
|
1296
|
+
throw new Error('User not found');
|
|
1297
|
+
}
|
|
1298
|
+
users.splice(index, 1);
|
|
1299
|
+
return true;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
static update(id, userData) {
|
|
1303
|
+
const user = this.getById(id);
|
|
1304
|
+
if (!user) {
|
|
1305
|
+
throw new Error('User not found');
|
|
1306
|
+
}
|
|
1307
|
+
Object.assign(user, userData);
|
|
1308
|
+
return user;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
module.exports = User;
|
|
1313
|
+
`
|
|
1314
|
+
);
|
|
1315
|
+
|
|
1316
|
+
// Backend: Database Config
|
|
1317
|
+
this.writeFile(
|
|
1318
|
+
path.join(projectPath, 'backend', 'config', 'db.js'),
|
|
1319
|
+
`// Database Configuration
|
|
1320
|
+
// Currently using in-memory storage
|
|
1321
|
+
// Replace this with real database connection (MongoDB, PostgreSQL, etc.)
|
|
1322
|
+
|
|
1323
|
+
const dbConfig = {
|
|
1324
|
+
type: 'in-memory',
|
|
1325
|
+
name: '${projectName}-db',
|
|
1326
|
+
version: '1.0.0'
|
|
1327
|
+
};
|
|
1328
|
+
|
|
1329
|
+
// Example MongoDB connection (commented out)
|
|
1330
|
+
/*
|
|
1331
|
+
const mongoose = require('mongoose');
|
|
1332
|
+
|
|
1333
|
+
async function connectDB() {
|
|
1334
|
+
try {
|
|
1335
|
+
await mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/${projectName}', {
|
|
1336
|
+
useNewUrlParser: true,
|
|
1337
|
+
useUnifiedTopology: true
|
|
1338
|
+
});
|
|
1339
|
+
console.log('✅ Database connected successfully');
|
|
1340
|
+
} catch (error) {
|
|
1341
|
+
console.error('❌ Database connection failed:', error);
|
|
1342
|
+
process.exit(1);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
module.exports = { connectDB };
|
|
1347
|
+
*/
|
|
1348
|
+
|
|
1349
|
+
module.exports = dbConfig;
|
|
1350
|
+
`
|
|
1351
|
+
);
|
|
1352
|
+
|
|
1353
|
+
// Backend: .env
|
|
1354
|
+
this.writeFile(
|
|
1355
|
+
path.join(projectPath, 'backend', '.env'),
|
|
1356
|
+
`# Backend Environment Variables
|
|
1357
|
+
PORT=5000
|
|
1358
|
+
NODE_ENV=development
|
|
1359
|
+
|
|
1360
|
+
# Database (example)
|
|
1361
|
+
# MONGODB_URI=mongodb://localhost:27017/${projectName}
|
|
1362
|
+
# DB_HOST=localhost
|
|
1363
|
+
# DB_PORT=5432
|
|
1364
|
+
# DB_NAME=${projectName}
|
|
1365
|
+
|
|
1366
|
+
# API Keys (example)
|
|
1367
|
+
# JWT_SECRET=your-secret-key-here
|
|
1368
|
+
# API_KEY=your-api-key-here
|
|
1369
|
+
`
|
|
1370
|
+
);
|
|
1371
|
+
|
|
1372
|
+
// Backend: package.json
|
|
1373
|
+
this.writeFile(
|
|
1374
|
+
path.join(projectPath, 'backend', 'package.json'),
|
|
1375
|
+
JSON.stringify({
|
|
1376
|
+
name: `${projectName}-backend`,
|
|
1377
|
+
version: '1.0.0',
|
|
1378
|
+
description: `${projectName} - Backend API`,
|
|
1379
|
+
main: 'server.js',
|
|
1380
|
+
scripts: {
|
|
1381
|
+
dev: 'node server.js',
|
|
1382
|
+
start: 'node server.js'
|
|
1383
|
+
},
|
|
1384
|
+
keywords: ['backend', 'api', 'fullstack'],
|
|
1385
|
+
author: author || '',
|
|
1386
|
+
license: 'MIT'
|
|
1387
|
+
}, null, 2)
|
|
1388
|
+
);
|
|
1389
|
+
|
|
1390
|
+
// ============ ROOT FILES ============
|
|
1391
|
+
|
|
1392
|
+
// Root: README
|
|
1393
|
+
this.writeFile(
|
|
1394
|
+
path.join(projectPath, 'README.md'),
|
|
1395
|
+
`# ${projectName}
|
|
1396
|
+
|
|
1397
|
+
A full-stack application with React-style frontend and Node.js backend.
|
|
1398
|
+
|
|
1399
|
+
## Project Structure
|
|
1400
|
+
|
|
1401
|
+
\`\`\`
|
|
1402
|
+
${projectName}/
|
|
1403
|
+
├── frontend/ # Frontend application
|
|
1404
|
+
│ ├── src/
|
|
1405
|
+
│ │ ├── components/ # Reusable components
|
|
1406
|
+
│ │ ├── pages/ # Page components
|
|
1407
|
+
│ │ ├── styles/ # CSS styles
|
|
1408
|
+
│ │ ├── services/ # API services
|
|
1409
|
+
│ │ └── App.js # Main app logic
|
|
1410
|
+
│ └── public/
|
|
1411
|
+
│ └── index.html # Main HTML file
|
|
1412
|
+
│
|
|
1413
|
+
├── backend/ # Backend API
|
|
1414
|
+
│ ├── routes/ # API routes
|
|
1415
|
+
│ ├── controllers/ # Request handlers
|
|
1416
|
+
│ ├── models/ # Data models
|
|
1417
|
+
│ ├── middleware/ # Custom middleware
|
|
1418
|
+
│ ├── config/ # Configuration files
|
|
1419
|
+
│ ├── server.js # Main server
|
|
1420
|
+
│ ├── .env # Environment variables
|
|
1421
|
+
│ └── package.json # Dependencies
|
|
1422
|
+
│
|
|
1423
|
+
└── README.md
|
|
1424
|
+
\`\`\`
|
|
1425
|
+
|
|
1426
|
+
## Getting Started
|
|
1427
|
+
|
|
1428
|
+
### 1. Start the Backend
|
|
1429
|
+
|
|
1430
|
+
\`\`\`bash
|
|
1431
|
+
cd backend
|
|
1432
|
+
npm run dev
|
|
1433
|
+
\`\`\`
|
|
1434
|
+
|
|
1435
|
+
Backend will run on: **http://localhost:5000**
|
|
1436
|
+
|
|
1437
|
+
### 2. Start the Frontend (in a new terminal)
|
|
1438
|
+
|
|
1439
|
+
\`\`\`bash
|
|
1440
|
+
cd frontend
|
|
1441
|
+
npm run dev
|
|
1442
|
+
\`\`\`
|
|
1443
|
+
|
|
1444
|
+
Frontend will run on: **http://localhost:3000**
|
|
1445
|
+
|
|
1446
|
+
### 3. Access the Application
|
|
1447
|
+
|
|
1448
|
+
Open your browser and go to: **http://localhost:3000**
|
|
1449
|
+
|
|
1450
|
+
## Features
|
|
1451
|
+
|
|
1452
|
+
### Frontend:
|
|
1453
|
+
- ✅ User Management Interface
|
|
1454
|
+
- ✅ API Integration
|
|
1455
|
+
- ✅ Responsive Design
|
|
1456
|
+
- ✅ Modern UI with Gradient Styling
|
|
1457
|
+
- ✅ Component-based Architecture
|
|
1458
|
+
|
|
1459
|
+
### Backend:
|
|
1460
|
+
- ✅ RESTful API
|
|
1461
|
+
- ✅ User CRUD Operations
|
|
1462
|
+
- ✅ CORS Enabled
|
|
1463
|
+
- ✅ In-Memory Database (easily replaceable)
|
|
1464
|
+
- ✅ Modular Structure
|
|
1465
|
+
|
|
1466
|
+
## API Endpoints
|
|
1467
|
+
|
|
1468
|
+
| Method | Endpoint | Description |
|
|
1469
|
+
|--------|----------|-------------|
|
|
1470
|
+
| GET | /api/users | Get all users |
|
|
1471
|
+
| POST | /api/users | Create new user |
|
|
1472
|
+
| DELETE | /api/users/:id | Delete user |
|
|
1473
|
+
| GET | /api/status | Check API status |
|
|
1474
|
+
|
|
1475
|
+
## How to Use
|
|
1476
|
+
|
|
1477
|
+
1. **Start Backend**:
|
|
1478
|
+
\`\`\`bash
|
|
1479
|
+
cd backend
|
|
1480
|
+
npm run dev
|
|
1481
|
+
\`\`\`
|
|
1482
|
+
|
|
1483
|
+
2. **Start Frontend** (in new terminal):
|
|
1484
|
+
\`\`\`bash
|
|
1485
|
+
cd frontend
|
|
1486
|
+
npm run dev
|
|
1487
|
+
\`\`\`
|
|
1488
|
+
|
|
1489
|
+
3. **Open Browser**: Go to http://localhost:3000
|
|
1490
|
+
4. **Test Connection**: Check if users load automatically
|
|
1491
|
+
5. **Add Users**: Fill the form and submit
|
|
1492
|
+
6. **Refresh**: Click refresh button to reload users
|
|
1493
|
+
|
|
1494
|
+
## Technologies Used
|
|
1495
|
+
|
|
1496
|
+
- **Frontend**: Vanilla JavaScript, HTML5, CSS3
|
|
1497
|
+
- **Backend**: Node.js (standard libraries only)
|
|
1498
|
+
- **Database**: In-memory (can be replaced with MongoDB, PostgreSQL, etc.)
|
|
1499
|
+
|
|
1500
|
+
## Future Enhancements
|
|
1501
|
+
|
|
1502
|
+
- [ ] Add database integration (MongoDB/PostgreSQL)
|
|
1503
|
+
- [ ] Add authentication (JWT)
|
|
1504
|
+
- [ ] Add user edit functionality
|
|
1505
|
+
- [ ] Add pagination
|
|
1506
|
+
- [ ] Add search/filter
|
|
1507
|
+
- [ ] Deploy to cloud
|
|
1508
|
+
|
|
1509
|
+
## Author
|
|
1510
|
+
|
|
1511
|
+
${author || 'Your Name'}
|
|
1512
|
+
|
|
1513
|
+
## License
|
|
1514
|
+
|
|
1515
|
+
MIT License
|
|
1516
|
+
|
|
1517
|
+
---
|
|
1518
|
+
|
|
1519
|
+
*Generated with create-project-cli*
|
|
1520
|
+
`
|
|
1521
|
+
);
|
|
1522
|
+
|
|
1523
|
+
// Root: .gitignore
|
|
1524
|
+
this.writeFile(
|
|
1525
|
+
path.join(projectPath, '.gitignore'),
|
|
1526
|
+
`# Dependencies
|
|
1527
|
+
node_modules/
|
|
1528
|
+
package-lock.json
|
|
1529
|
+
|
|
1530
|
+
# Environment variables
|
|
1531
|
+
.env
|
|
1532
|
+
.env.local
|
|
1533
|
+
.env.production
|
|
1534
|
+
|
|
1535
|
+
# Logs
|
|
1536
|
+
*.log
|
|
1537
|
+
npm-debug.log*
|
|
1538
|
+
|
|
1539
|
+
# OS
|
|
1540
|
+
.DS_Store
|
|
1541
|
+
Thumbs.db
|
|
1542
|
+
|
|
1543
|
+
# IDE
|
|
1544
|
+
.vscode/
|
|
1545
|
+
.idea/
|
|
1546
|
+
*.swp
|
|
1547
|
+
*.swo
|
|
1548
|
+
|
|
1549
|
+
# Build
|
|
1550
|
+
dist/
|
|
1551
|
+
build/
|
|
1552
|
+
`
|
|
1553
|
+
);
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
/**
|
|
1557
|
+
* Generates a README file for the project
|
|
1558
|
+
*/
|
|
1559
|
+
generateReadme(projectName, template, author) {
|
|
1560
|
+
const templateDescriptions = {
|
|
1561
|
+
basic: 'A simple project structure with source code and utilities.',
|
|
1562
|
+
web: 'A web application with HTML, CSS, and JavaScript.',
|
|
1563
|
+
api: 'A REST API server with routes and controllers.',
|
|
1564
|
+
cli: 'A command-line tool for terminal usage.',
|
|
1565
|
+
fullstack: 'A full-stack application with React frontend and Node.js backend.'
|
|
1566
|
+
};
|
|
1567
|
+
|
|
1568
|
+
const runInstructions = {
|
|
1569
|
+
basic: '```bash\nnode src/index.js\n```',
|
|
1570
|
+
web: '```bash\n# Open sTerminal 1 - Start Backend\ncd backend\nnpm run dev\n\n# Terminal 2 - Start Frontend\ncd frontend\nnpm run dev\n\n# Open http://localhost:3000/src/\n```',
|
|
1571
|
+
api: '```bash\nnode src/server.js\n# API will be available at http://localhost:3000\n```',
|
|
1572
|
+
cli: '```bash\nnode src/cli.js --help\n```',
|
|
1573
|
+
fullstack: '```bash\n# Start Backend\ncd backend\nnode server.js\n\n# In another terminal, start Frontend\ncd frontend\nopen public/index.html in browser\n```'
|
|
1574
|
+
};
|
|
1575
|
+
|
|
1576
|
+
return `# ${projectName}
|
|
1577
|
+
|
|
1578
|
+
${templateDescriptions[template]}
|
|
1579
|
+
|
|
1580
|
+
## Project Structure
|
|
1581
|
+
|
|
1582
|
+
\`\`\`
|
|
1583
|
+
${this.getProjectStructure(template)}
|
|
1584
|
+
\`\`\`
|
|
1585
|
+
|
|
1586
|
+
## Getting Started
|
|
1587
|
+
|
|
1588
|
+
### Prerequisites
|
|
1589
|
+
- Node.js (v14 or higher)
|
|
1590
|
+
|
|
1591
|
+
### Installation
|
|
1592
|
+
|
|
1593
|
+
1. Navigate to the project directory:
|
|
1594
|
+
\`\`\`bash
|
|
1595
|
+
cd ${projectName}
|
|
1596
|
+
\`\`\`
|
|
1597
|
+
|
|
1598
|
+
2. Install dependencies (if any):
|
|
1599
|
+
\`\`\`bash
|
|
1600
|
+
npm install
|
|
1601
|
+
\`\`\`
|
|
1602
|
+
|
|
1603
|
+
### Running the Project
|
|
1604
|
+
|
|
1605
|
+
${runInstructions[template]}
|
|
1606
|
+
|
|
1607
|
+
## Features
|
|
1608
|
+
|
|
1609
|
+
- Clean and organized project structure
|
|
1610
|
+
- Standard libraries only (no external dependencies required)
|
|
1611
|
+
- Ready-to-use boilerplate code
|
|
1612
|
+
- Comprehensive comments and documentation
|
|
1613
|
+
|
|
1614
|
+
## Author
|
|
1615
|
+
|
|
1616
|
+
${author || 'Your Name'}
|
|
1617
|
+
|
|
1618
|
+
## License
|
|
1619
|
+
|
|
1620
|
+
This project is licensed under the MIT License.
|
|
1621
|
+
|
|
1622
|
+
## Generated By
|
|
1623
|
+
|
|
1624
|
+
This project was scaffolded using [create-project-cli](https://github.com/yourusername/create-project-cli) - A tool to quickly generate project structures.
|
|
1625
|
+
|
|
1626
|
+
---
|
|
1627
|
+
|
|
1628
|
+
*Created on ${new Date().toLocaleDateString()}*
|
|
1629
|
+
`;
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
/**
|
|
1633
|
+
* Returns the project structure based on template
|
|
1634
|
+
*/
|
|
1635
|
+
getProjectStructure(template) {
|
|
1636
|
+
const structures = {
|
|
1637
|
+
basic: `${template}-project/
|
|
1638
|
+
├── src/
|
|
1639
|
+
│ └── index.js
|
|
1640
|
+
├── utils/
|
|
1641
|
+
│ └── helpers.js
|
|
1642
|
+
├── tests/
|
|
1643
|
+
├── package.json
|
|
1644
|
+
├── .gitignore
|
|
1645
|
+
└── README.md`,
|
|
1646
|
+
web: `${template}-project/
|
|
1647
|
+
├── src/
|
|
1648
|
+
│ ├── index.html
|
|
1649
|
+
│ ├── css/
|
|
1650
|
+
│ │ └── style.css
|
|
1651
|
+
│ └── js/
|
|
1652
|
+
│ └── app.js
|
|
1653
|
+
├── public/
|
|
1654
|
+
├── assets/
|
|
1655
|
+
├── package.json
|
|
1656
|
+
├── .gitignore
|
|
1657
|
+
└── README.md`,
|
|
1658
|
+
api: `${template}-project/
|
|
1659
|
+
├── src/
|
|
1660
|
+
│ ├── server.js
|
|
1661
|
+
│ ├── routes/
|
|
1662
|
+
│ │ └── index.js
|
|
1663
|
+
│ ├── controllers/
|
|
1664
|
+
│ │ └── index.js
|
|
1665
|
+
│ ├── models/
|
|
1666
|
+
│ └── middleware/
|
|
1667
|
+
├── config/
|
|
1668
|
+
│ └── config.js
|
|
1669
|
+
├── utils/
|
|
1670
|
+
├── package.json
|
|
1671
|
+
├── .gitignore
|
|
1672
|
+
└── README.md`,
|
|
1673
|
+
cli: `${template}-project/
|
|
1674
|
+
├── src/
|
|
1675
|
+
│ └── cli.js
|
|
1676
|
+
├── commands/
|
|
1677
|
+
│ └── index.js
|
|
1678
|
+
├── utils/
|
|
1679
|
+
├── package.json
|
|
1680
|
+
├── .gitignore
|
|
1681
|
+
└── README.md`,
|
|
1682
|
+
fullstack: `${template}-project/
|
|
1683
|
+
├── frontend/
|
|
1684
|
+
│ ├── src/
|
|
1685
|
+
│ │ ├── components/
|
|
1686
|
+
│ │ ├── pages/
|
|
1687
|
+
│ │ ├── styles/
|
|
1688
|
+
│ │ └── App.js
|
|
1689
|
+
│ ├── public/
|
|
1690
|
+
│ └── package.json
|
|
1691
|
+
├── backend/
|
|
1692
|
+
│ ├── routes/
|
|
1693
|
+
│ ├── controllers/
|
|
1694
|
+
│ ├── models/
|
|
1695
|
+
│ ├── middleware/
|
|
1696
|
+
│ ├── config/
|
|
1697
|
+
│ ├── server.js
|
|
1698
|
+
│ ├── .env
|
|
1699
|
+
│ └── package.json
|
|
1700
|
+
└── README.md`
|
|
1701
|
+
};
|
|
1702
|
+
|
|
1703
|
+
return structures[template] || structures.basic;
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
module.exports = TemplateGenerator;
|