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.
@@ -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>&copy; 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;