backend-scaffold-cli 1.5.1 → 1.7.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/bin/cli.js +145 -38
- package/package.json +5 -2
package/bin/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
const { program } = require('commander');
|
|
@@ -7,8 +7,9 @@ const inquirer = require('inquirer');
|
|
|
7
7
|
const fs = require('fs-extra');
|
|
8
8
|
const path = require('path');
|
|
9
9
|
const { execSync } = require('child_process');
|
|
10
|
+
const packageJson = require('../package.json');
|
|
10
11
|
|
|
11
|
-
const version =
|
|
12
|
+
const version = packageJson.version;
|
|
12
13
|
|
|
13
14
|
program
|
|
14
15
|
.version(version)
|
|
@@ -31,6 +32,12 @@ program
|
|
|
31
32
|
message: 'Include input validation?',
|
|
32
33
|
default: true
|
|
33
34
|
},
|
|
35
|
+
{
|
|
36
|
+
type: 'confirm',
|
|
37
|
+
name: 'useDNSFix',
|
|
38
|
+
message: 'Use custom DNS (fixes MongoDB connection issues on some networks)?',
|
|
39
|
+
default: true
|
|
40
|
+
},
|
|
34
41
|
{
|
|
35
42
|
type: 'confirm',
|
|
36
43
|
name: 'useRateLimit',
|
|
@@ -82,6 +89,7 @@ program
|
|
|
82
89
|
}
|
|
83
90
|
if(answers.useAxios){
|
|
84
91
|
createAxiosUtil(projectPath);
|
|
92
|
+
createAuthController(projectPath);
|
|
85
93
|
}
|
|
86
94
|
|
|
87
95
|
console.log(chalk.cyan(' Initializing git repository...'));
|
|
@@ -184,11 +192,7 @@ NODE_ENV=development
|
|
|
184
192
|
# MongoDB Configuration
|
|
185
193
|
MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/myappdb
|
|
186
194
|
DB_NAME=myapp
|
|
187
|
-
|
|
188
|
-
# DNS Configuration
|
|
189
|
-
DNS_SERVERS=8.8.8.8,8.8.4.4
|
|
190
|
-
PRIMARY_DNS=8.8.8.8
|
|
191
|
-
SECONDARY_DNS=8.8.4.4
|
|
195
|
+
${answers.useDNSFix ? '\n# DNS Configuration (for MongoDB connection issues)\nDNS_SERVERS=8.8.8.8,8.8.4.4' : ''}
|
|
192
196
|
|
|
193
197
|
# JWT Configuration
|
|
194
198
|
JWT_SECRET=your-secret-key-change-this-in-production
|
|
@@ -199,6 +203,7 @@ CORS_ORIGIN=http://localhost:3000
|
|
|
199
203
|
|
|
200
204
|
# Logging
|
|
201
205
|
LOG_LEVEL=debug
|
|
206
|
+
${answers.useAxios ? '\n# External API\nAPI_BASE_URL=' : ''}
|
|
202
207
|
`;
|
|
203
208
|
|
|
204
209
|
fs.writeFileSync(path.join(projectPath, '.env.example'), env);
|
|
@@ -464,6 +469,7 @@ const createRouteFiles = (projectPath, answers) => {
|
|
|
464
469
|
const routes = `const express = require('express');
|
|
465
470
|
const router = express.Router();
|
|
466
471
|
${answers.useAuth ? "const authenticateToken = require('../middleware/auth');" : ''}
|
|
472
|
+
${answers.useAuth ? "const {register,login} = require('../controllers/authController');" : ''}
|
|
467
473
|
${answers.useFileUpload ? "const upload = require('../middleware/upload');" : ''}
|
|
468
474
|
|
|
469
475
|
// Public routes
|
|
@@ -471,6 +477,13 @@ router.get('/health', (req, res) => {
|
|
|
471
477
|
res.json({ status: 'API is running' });
|
|
472
478
|
});
|
|
473
479
|
|
|
480
|
+
${answers.useAuth? `
|
|
481
|
+
// Auth routes
|
|
482
|
+
// Register and Login routes
|
|
483
|
+
router.post('/auth/register', register);
|
|
484
|
+
router.post('/auth/login', login);
|
|
485
|
+
` : ''}
|
|
486
|
+
|
|
474
487
|
${answers.useAuth ? `
|
|
475
488
|
// Protected routes
|
|
476
489
|
router.get('/protected', authenticateToken, (req, res) => {
|
|
@@ -512,34 +525,23 @@ module.exports = router;
|
|
|
512
525
|
|
|
513
526
|
|
|
514
527
|
const dbConfig = `const mongoose = require('mongoose');
|
|
515
|
-
const dns = require('dns');
|
|
528
|
+
${answers.useDNSFix ? "const dns = require('dns');" : ''}
|
|
516
529
|
|
|
517
|
-
|
|
530
|
+
${answers.useDNSFix ? `// Set custom DNS servers (fixes connection issues on some networks)
|
|
518
531
|
const dnsServers = (process.env.DNS_SERVERS || '8.8.8.8,8.8.4.4').split(',');
|
|
519
532
|
dns.setServers(dnsServers);
|
|
533
|
+
` : ''}
|
|
520
534
|
|
|
521
535
|
const connectDB = async () => {
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
serverSelectionTimeoutMS: 5000,
|
|
529
|
-
socketTimeoutMS: 45000,
|
|
530
|
-
});
|
|
536
|
+
${answers.useDNSFix ? "console.log(`Using DNS servers: ${dnsServers.join(', ')}`);" : ''}
|
|
537
|
+
|
|
538
|
+
const conn = await mongoose.connect(process.env.MONGODB_URI, {
|
|
539
|
+
serverSelectionTimeoutMS: 5000,
|
|
540
|
+
socketTimeoutMS: 45000,
|
|
541
|
+
});
|
|
531
542
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
} catch (error) {
|
|
535
|
-
console.error(' MongoDB Connection Error:', error.message);
|
|
536
|
-
|
|
537
|
-
if (process.env.NODE_ENV === 'production') {
|
|
538
|
-
process.exit(1);
|
|
539
|
-
} else {
|
|
540
|
-
console.warn('⚠ Warning: Running without MongoDB connection');
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
+
console.log(\`MongoDB Connected: \${conn.connection.host}\`);
|
|
544
|
+
return conn;
|
|
543
545
|
};
|
|
544
546
|
|
|
545
547
|
module.exports = connectDB;
|
|
@@ -566,16 +568,15 @@ const app = express();
|
|
|
566
568
|
${answers.useRateLimit ? "const limiter = require('./middleware/rateLimiter');" : ''}
|
|
567
569
|
const PORT = process.env.PORT || 5000;
|
|
568
570
|
|
|
569
|
-
|
|
570
|
-
connectDB();
|
|
571
|
+
|
|
571
572
|
|
|
572
573
|
// Middleware
|
|
573
574
|
app.use(cors({
|
|
574
575
|
origin: process.env.CORS_ORIGIN || '*'
|
|
575
576
|
}));
|
|
576
577
|
|
|
577
|
-
app.use(express.json());
|
|
578
|
-
app.use(express.urlencoded({ extended: true }));
|
|
578
|
+
app.use(express.json({limit: '10kb'}));
|
|
579
|
+
app.use(express.urlencoded({ extended: true, limit: '10kb' }));
|
|
579
580
|
app.use(loggerMiddleware);
|
|
580
581
|
${answers.useRateLimit ? 'app.use(limiter);' : ''}
|
|
581
582
|
|
|
@@ -594,11 +595,22 @@ app.get('/', (req, res) => {
|
|
|
594
595
|
app.use(errorMiddleware);
|
|
595
596
|
|
|
596
597
|
|
|
597
|
-
//
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
598
|
+
//connect to MongoDB
|
|
599
|
+
const startServer = async() =>{
|
|
600
|
+
try{
|
|
601
|
+
await connectDB();
|
|
602
|
+
app.listen(PORT, () =>{
|
|
603
|
+
console.log(\` Server running on port \${PORT}\`);
|
|
604
|
+
console.log(\`Environment: \${process.env.NODE_ENV || 'development'}\`);
|
|
605
|
+
});
|
|
606
|
+
}catch(error){
|
|
607
|
+
console.error('Failed to start server:', error.message);
|
|
608
|
+
process.exit(1);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
startServer();
|
|
602
614
|
|
|
603
615
|
process.on('unhandledRejection', (err) => {
|
|
604
616
|
console.error('Unhandled Rejection:', err);
|
|
@@ -679,6 +691,101 @@ function createUserModel(projectPath) {
|
|
|
679
691
|
|
|
680
692
|
|
|
681
693
|
|
|
694
|
+
function createAuthController(projectPath) {
|
|
695
|
+
const authController = `const jwt= require('jsonwebtoken');
|
|
696
|
+
const User=require('../models/User');
|
|
697
|
+
const { ErrorHandler } = require('../middleware/errorHandler');
|
|
698
|
+
|
|
699
|
+
//generate JWT token
|
|
700
|
+
const generateToken = (userId) => {
|
|
701
|
+
return jwt.sign({ id: userId }, process.env.JWT_SECRET, {
|
|
702
|
+
expiresIn: process.env.JWT_EXPIRE || '7d'
|
|
703
|
+
});
|
|
704
|
+
};
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
//register user
|
|
708
|
+
const register= async(req,res,next) =>{
|
|
709
|
+
try{
|
|
710
|
+
const {name,email,password}=req.body;
|
|
711
|
+
|
|
712
|
+
const existingUser= await User.findOne({email});
|
|
713
|
+
if(existingUser){
|
|
714
|
+
return next(new ErrorHandler('Email already Registered',400));
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
const user= await User.create({name,email,password});
|
|
718
|
+
const tocken= generateToken(user._id);
|
|
719
|
+
|
|
720
|
+
res.status(201).json({
|
|
721
|
+
success:true,
|
|
722
|
+
message:'User registered successfully',
|
|
723
|
+
token,
|
|
724
|
+
user:{
|
|
725
|
+
id:user._id,
|
|
726
|
+
name:user.name,
|
|
727
|
+
email:user.email
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
}catch(error){
|
|
731
|
+
next(error);
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
//login user
|
|
738
|
+
const login =async(req,res,next) =>{
|
|
739
|
+
try{
|
|
740
|
+
const {email,password}=req.body;
|
|
741
|
+
|
|
742
|
+
const user=await User.findOne({email}).select('+password');
|
|
743
|
+
if(!user){
|
|
744
|
+
return next(new ErrorHandler('Invalid email or password',401));
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
const isMatch= await user.comparePassword(password);
|
|
748
|
+
if(!isMatch){
|
|
749
|
+
return next(new ErrorHandler('Invalid email or password',401));
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
const token=generateToken(user._id);
|
|
753
|
+
|
|
754
|
+
res.status(200).json({
|
|
755
|
+
success:true,
|
|
756
|
+
message:'User logged in successfully',
|
|
757
|
+
token,
|
|
758
|
+
user:{
|
|
759
|
+
id:user._id,
|
|
760
|
+
name:user.name,
|
|
761
|
+
email: user.email
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
}catch(error){
|
|
765
|
+
next(error);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
module.exports = {
|
|
771
|
+
register,
|
|
772
|
+
login
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
`;
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
fs.writeFileSync(
|
|
780
|
+
path.join(projectPath, 'src/controllers/authController.js'),
|
|
781
|
+
authController
|
|
782
|
+
);
|
|
783
|
+
|
|
784
|
+
console.log(chalk.green('Auth controller created'));
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
|
|
682
789
|
function createAxiosUtil(projectPath){
|
|
683
790
|
const axiosUtil = ` const axios = require('axios');
|
|
684
791
|
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-scaffold-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "CLI tool to scaffold Express.js backend projects with MongoDB, middleware, and common setup",
|
|
5
5
|
"main": "bin/cli.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"create-express-backend": "./bin/cli.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"test": "
|
|
10
|
+
"test": "jest"
|
|
11
11
|
},
|
|
12
12
|
"keywords": [
|
|
13
13
|
"express",
|
|
@@ -32,5 +32,8 @@
|
|
|
32
32
|
"commander": "^11.0.0",
|
|
33
33
|
"fs-extra": "^11.1.0",
|
|
34
34
|
"inquirer": "^8.2.5"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"jest": "^30.4.2"
|
|
35
38
|
}
|
|
36
39
|
}
|