create-prod-backend 1.1.2 → 1.1.4
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/README.md +175 -6
- package/bin/index.js +0 -0
- package/package.json +1 -1
- package/src/services/file.service.js +5 -0
- package/src/services/folder.service.js +6 -1
- package/index.js +0 -297
package/README.md
CHANGED
|
@@ -1,12 +1,181 @@
|
|
|
1
|
-
# create-prod-backend
|
|
1
|
+
# create-prod-backend
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Build a **production-ready Express backend** in seconds — no boilerplate, no setup headaches.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
6
8
|
|
|
9
|
+
Use directly with **npx** (recommended):
|
|
10
|
+
|
|
11
|
+
```bash
|
|
7
12
|
npx create-prod-backend
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or install globally:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g create-prod-backend
|
|
19
|
+
create-prod-backend
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
8
23
|
|
|
9
24
|
## Features
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
25
|
+
|
|
26
|
+
* Instant Express.js backend setup
|
|
27
|
+
* Clean and scalable folder structure
|
|
28
|
+
* Optional MongoDB integration
|
|
29
|
+
* Environment variable support (.env)
|
|
30
|
+
* Select dependencies interactively
|
|
31
|
+
* Production-ready scripts
|
|
32
|
+
* Developer-friendly CLI
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## What It Generates
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
project-name/
|
|
40
|
+
│
|
|
41
|
+
├── src/
|
|
42
|
+
│ ├── controllers/
|
|
43
|
+
│ ├── routes/
|
|
44
|
+
│ ├── models/
|
|
45
|
+
│ ├── middlewares/
|
|
46
|
+
│ ├── utils/
|
|
47
|
+
│ ├── db/
|
|
48
|
+
│ │
|
|
49
|
+
│ ├── app.js
|
|
50
|
+
│ ├── index.js
|
|
51
|
+
│ └── constants.js
|
|
52
|
+
│
|
|
53
|
+
├── public/
|
|
54
|
+
│
|
|
55
|
+
├── .env
|
|
56
|
+
├── .gitignore
|
|
57
|
+
├── package.json
|
|
58
|
+
└── README.md
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Usage
|
|
64
|
+
|
|
65
|
+
Run the CLI:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx create-prod-backend
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### You’ll be prompted for:
|
|
72
|
+
|
|
73
|
+
* Project name
|
|
74
|
+
* MongoDB setup (Yes/No)
|
|
75
|
+
* .env file (Yes/No)
|
|
76
|
+
* Dependencies to install
|
|
77
|
+
* Auto install dependencies
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Supported Dependencies
|
|
82
|
+
|
|
83
|
+
* express
|
|
84
|
+
* nodemon
|
|
85
|
+
* cors
|
|
86
|
+
* bcryptjs
|
|
87
|
+
* dotenv
|
|
88
|
+
* jsonwebtoken
|
|
89
|
+
* cookie-parser
|
|
90
|
+
* cloudinary
|
|
91
|
+
* multer
|
|
92
|
+
* mongoose (optional)
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Scripts
|
|
97
|
+
|
|
98
|
+
After setup:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npm run dev # Development (nodemon)
|
|
102
|
+
npm start # Production
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Example
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npx create-prod-backend
|
|
111
|
+
|
|
112
|
+
✔ Enter project name: my-app
|
|
113
|
+
✔ Use MongoDB: Yes
|
|
114
|
+
✔ Use .env: Yes
|
|
115
|
+
✔ Install dependencies: Yes
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Your backend is ready!
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Tech Stack
|
|
123
|
+
|
|
124
|
+
* Node.js
|
|
125
|
+
* Express.js
|
|
126
|
+
* MongoDB (optional)
|
|
127
|
+
* Inquirer (CLI prompts)
|
|
128
|
+
* Chalk (CLI styling)
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Upcoming Features
|
|
133
|
+
|
|
134
|
+
* Service layer support
|
|
135
|
+
* Auth template (JWT)
|
|
136
|
+
* Docker setup
|
|
137
|
+
* API documentation (Swagger)
|
|
138
|
+
* TypeScript support
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Contributing
|
|
143
|
+
|
|
144
|
+
Contributions are welcome!
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
git clone https://github.com/codeurge123/create-prod-backend
|
|
148
|
+
cd create-prod-backend
|
|
149
|
+
npm install
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
ISC License
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Author
|
|
161
|
+
|
|
162
|
+
Made by **codeurge316 - @yashbansal**
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Support
|
|
167
|
+
|
|
168
|
+
If you like this project:
|
|
169
|
+
|
|
170
|
+
* Star the repo
|
|
171
|
+
* Share with others
|
|
172
|
+
* Suggest new features
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Final Thought
|
|
177
|
+
|
|
178
|
+
Stop wasting time setting up backend boilerplate.
|
|
179
|
+
Start building real projects.
|
|
180
|
+
|
|
181
|
+
- **create-prod-backend** does the setup — you build the product.
|
package/bin/index.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -44,6 +44,11 @@ export function createFiles(projectPath, answer) {
|
|
|
44
44
|
fs.writeFileSync(path.join(projectPath, ".env"), envTemplate());
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
fs.writeFileSync(
|
|
48
|
+
path.join(projectPath, "README.md"),
|
|
49
|
+
`# ${answer.projectName}\n\nGenerated with create-prod-backend CLI.`
|
|
50
|
+
);
|
|
51
|
+
|
|
47
52
|
// gitignore
|
|
48
53
|
fs.writeFileSync(
|
|
49
54
|
path.join(projectPath, ".gitignore"),
|
|
@@ -17,7 +17,12 @@ export function createFolders(projectPath) {
|
|
|
17
17
|
];
|
|
18
18
|
|
|
19
19
|
folders.forEach((folder) => {
|
|
20
|
-
|
|
20
|
+
const folderPath =
|
|
21
|
+
folder === "public"
|
|
22
|
+
? path.join(projectPath, folder, 'temp')
|
|
23
|
+
: path.join(projectPath, "src", folder);
|
|
24
|
+
|
|
25
|
+
fs.mkdirSync(folderPath, {
|
|
21
26
|
recursive: true
|
|
22
27
|
});
|
|
23
28
|
});
|
package/index.js
DELETED
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import inquirer from "inquirer";
|
|
4
|
-
import { execSync } from "child_process";
|
|
5
|
-
import fs from "fs";
|
|
6
|
-
import path from "path";
|
|
7
|
-
|
|
8
|
-
console.log("Welcome to the Express Backend Generator !!");
|
|
9
|
-
|
|
10
|
-
// answer object will have projectName, useMongo, ENV, dependencies, npmi
|
|
11
|
-
// to access these values we can use answer.projectName, answer.useMongo, answer.ENV, answer.dependencies, answer.npmi
|
|
12
|
-
|
|
13
|
-
// through message we are taking input from terminal and name is for variable name and type is for type of input like confirm, checkbox etc and validate is for validation of input
|
|
14
|
-
try {
|
|
15
|
-
const answer = await inquirer.prompt([
|
|
16
|
-
{
|
|
17
|
-
name: "projectName",
|
|
18
|
-
message: "Enter the Project (Folder) Name:",
|
|
19
|
-
validate: (input) => {
|
|
20
|
-
if (!input) return "Please enter a valid project name";
|
|
21
|
-
if (fs.existsSync(path.join(process.cwd(), input)))
|
|
22
|
-
return "Folder already exists";
|
|
23
|
-
return true;
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
type: "confirm",
|
|
28
|
-
name: "useMongo",
|
|
29
|
-
message: "Do you want MongoDB?",
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
type: "confirm",
|
|
33
|
-
name: "ENV",
|
|
34
|
-
message: "Do you want .env?",
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
type: "checkbox",
|
|
38
|
-
name: "dependencies",
|
|
39
|
-
message: "Select dependencies to install:",
|
|
40
|
-
choices: [
|
|
41
|
-
"express",
|
|
42
|
-
"nodemon",
|
|
43
|
-
"cors",
|
|
44
|
-
"bcryptjs",
|
|
45
|
-
"dotenv",
|
|
46
|
-
"jsonwebtoken",
|
|
47
|
-
"cookie-parser",
|
|
48
|
-
"cloudinary",
|
|
49
|
-
"multer",
|
|
50
|
-
],
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
type: "confirm",
|
|
54
|
-
name: "npmi",
|
|
55
|
-
message: "Do you want to install dependencies?",
|
|
56
|
-
},
|
|
57
|
-
]);
|
|
58
|
-
|
|
59
|
-
const projectPath = path.join(process.cwd(), answer.projectName);
|
|
60
|
-
|
|
61
|
-
// Create root folder
|
|
62
|
-
fs.mkdirSync(projectPath, { recursive: true });
|
|
63
|
-
|
|
64
|
-
// Folder structure
|
|
65
|
-
const folders = [
|
|
66
|
-
"controllers",
|
|
67
|
-
"routes",
|
|
68
|
-
"db",
|
|
69
|
-
"middlewares",
|
|
70
|
-
"models",
|
|
71
|
-
"utils",
|
|
72
|
-
"public",
|
|
73
|
-
];
|
|
74
|
-
|
|
75
|
-
folders.forEach((folder) => {
|
|
76
|
-
fs.mkdirSync(path.join(projectPath, folder), { recursive: true });
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// Initialize npm
|
|
80
|
-
execSync("npm init -y", { cwd: projectPath, stdio: "inherit" });
|
|
81
|
-
|
|
82
|
-
// Fix package.json
|
|
83
|
-
const pkgPath = path.join(projectPath, "package.json");
|
|
84
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
85
|
-
|
|
86
|
-
pkg.type = "module";
|
|
87
|
-
pkg.scripts = {
|
|
88
|
-
start: "node index.js",
|
|
89
|
-
dev: "nodemon index.js",
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
93
|
-
|
|
94
|
-
// ---------------- UTILS ----------------
|
|
95
|
-
fs.writeFileSync(
|
|
96
|
-
path.join(projectPath, "utils", "ApiError.js"),
|
|
97
|
-
`
|
|
98
|
-
class ApiError extends Error {
|
|
99
|
-
constructor(
|
|
100
|
-
statusCode,
|
|
101
|
-
message = "Something went wrong",
|
|
102
|
-
errors = [],
|
|
103
|
-
stack = ""
|
|
104
|
-
) {
|
|
105
|
-
super(message);
|
|
106
|
-
this.statusCode = statusCode;
|
|
107
|
-
this.data = null;
|
|
108
|
-
this.message = message;
|
|
109
|
-
this.success = false;
|
|
110
|
-
this.errors = errors;
|
|
111
|
-
|
|
112
|
-
if (stack) {
|
|
113
|
-
this.stack = stack;
|
|
114
|
-
} else {
|
|
115
|
-
Error.captureStackTrace(this, this.constructor);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export default ApiError;
|
|
121
|
-
`
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
fs.writeFileSync(
|
|
125
|
-
path.join(projectPath, "utils", "ApiResponse.js"),
|
|
126
|
-
`class ApiResponse {
|
|
127
|
-
constructor(statusCode, data, message = "Success") {
|
|
128
|
-
this.statusCode = statusCode;
|
|
129
|
-
this.data = data;
|
|
130
|
-
this.message = message;
|
|
131
|
-
this.success = statusCode < 400;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
// basically statusCode ka knowledge hona chiya aap ke pass
|
|
135
|
-
// Informational responses (100 – 199)
|
|
136
|
-
// Successful responses (200 – 299)
|
|
137
|
-
// Redirection messages (300 – 399)
|
|
138
|
-
// Client error responses (400 – 499)
|
|
139
|
-
// Server error responses (500 – 599)
|
|
140
|
-
|
|
141
|
-
export { ApiResponse };
|
|
142
|
-
`
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
fs.writeFileSync(
|
|
146
|
-
path.join(projectPath, "utils", "asyncHandler.js"),
|
|
147
|
-
`const asyncHandler = (requestHandler) => {
|
|
148
|
-
return (req, res, next) => {
|
|
149
|
-
Promise.resolve(requestHandler(req, res, next)).catch((error) =>
|
|
150
|
-
next(error)
|
|
151
|
-
);
|
|
152
|
-
};
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
export default asyncHandler;`
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
// ---------------- CORE FILES ----------------
|
|
159
|
-
const indexContent = `
|
|
160
|
-
import { app } from "./app.js";
|
|
161
|
-
${answer.useMongo ? `import connectDB from "./db/connect.js";` : ""}
|
|
162
|
-
${answer.ENV ? `import dotenv from "dotenv"; \n dotenv.config();` : ""}
|
|
163
|
-
|
|
164
|
-
const startServer = async () => {
|
|
165
|
-
try {
|
|
166
|
-
${answer.useMongo ? `await connectDB();` : ""}
|
|
167
|
-
app.on('error', (error) => {
|
|
168
|
-
console.log('app is facing error while connecting with db')
|
|
169
|
-
throw error
|
|
170
|
-
})
|
|
171
|
-
app.listen(process.env.PORT || 3000, () => {
|
|
172
|
-
console.log("Server running on port", process.env.PORT || 3000);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
} catch (error) {
|
|
176
|
-
console.error("Server failed to start", error);
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
startServer();
|
|
181
|
-
`;
|
|
182
|
-
|
|
183
|
-
fs.writeFileSync(path.join(projectPath, "index.js"), indexContent);
|
|
184
|
-
|
|
185
|
-
fs.writeFileSync(
|
|
186
|
-
path.join(projectPath, "app.js"),
|
|
187
|
-
`import express from "express";
|
|
188
|
-
${answer.dependencies.includes("cors") ? `import cors from "cors";` : ""}
|
|
189
|
-
${answer.dependencies.includes("cookie-parser") ? `import cookieParser from "cookie-parser";` : ""}
|
|
190
|
-
|
|
191
|
-
const app = express();
|
|
192
|
-
|
|
193
|
-
app.use(express.json());
|
|
194
|
-
app.use(express.urlencoded({ extended: true }));
|
|
195
|
-
app.use(express.static("public"));
|
|
196
|
-
|
|
197
|
-
${answer.dependencies.includes("cors") ? `
|
|
198
|
-
app.use(cors({
|
|
199
|
-
origin: process.env.CORS_ORIGIN || "*",
|
|
200
|
-
credentials: true
|
|
201
|
-
}));
|
|
202
|
-
` : ""}
|
|
203
|
-
|
|
204
|
-
${answer.dependencies.includes("cookie-parser") ? `app.use(cookieParser());` : ""}
|
|
205
|
-
|
|
206
|
-
// routes here
|
|
207
|
-
|
|
208
|
-
export { app };`
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
fs.writeFileSync(
|
|
212
|
-
path.join(projectPath, "constants.js"),
|
|
213
|
-
`export const DB_NAME = "your_db_name";`
|
|
214
|
-
);
|
|
215
|
-
|
|
216
|
-
// ---------------- MONGODB ----------------
|
|
217
|
-
let deps = [...answer.dependencies];
|
|
218
|
-
|
|
219
|
-
if (answer.useMongo) {
|
|
220
|
-
deps.push("mongoose");
|
|
221
|
-
|
|
222
|
-
fs.writeFileSync(
|
|
223
|
-
path.join(projectPath, "db", "connect.js"),
|
|
224
|
-
`import mongoose from "mongoose";
|
|
225
|
-
|
|
226
|
-
const connectDB = async () => {
|
|
227
|
-
try {
|
|
228
|
-
const conn = await mongoose.connect(process.env.MONGO_URI);
|
|
229
|
-
console.log("MongoDB connected:", conn.connection.host);
|
|
230
|
-
} catch (error) {
|
|
231
|
-
console.error("MongoDB connection FAILED", error);
|
|
232
|
-
process.exit(1);
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
export default connectDB;`
|
|
237
|
-
);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// ---------------- ENV ----------------
|
|
241
|
-
if (answer.ENV) {
|
|
242
|
-
fs.writeFileSync(
|
|
243
|
-
path.join(projectPath, ".env"),
|
|
244
|
-
`PORT=3000
|
|
245
|
-
MONGO_URI=your_mongodb_uri
|
|
246
|
-
|
|
247
|
-
ACCESS_TOKEN_SECRET=your_access_token
|
|
248
|
-
ACCESS_TOKEN_EXPIRY=2d
|
|
249
|
-
|
|
250
|
-
REFRESH_TOKEN_SECRET=your_refresh_token
|
|
251
|
-
REFRESH_TOKEN_EXPIRY=20d
|
|
252
|
-
|
|
253
|
-
CORS_ORIGIN=*`
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// ---------------- GITIGNORE ----------------
|
|
258
|
-
fs.writeFileSync(
|
|
259
|
-
path.join(projectPath, ".gitignore"),
|
|
260
|
-
`node_modules/
|
|
261
|
-
.env
|
|
262
|
-
dist/
|
|
263
|
-
coverage/
|
|
264
|
-
.DS_Store`
|
|
265
|
-
);
|
|
266
|
-
|
|
267
|
-
// ---------------- INSTALL DEPENDENCIES ----------------
|
|
268
|
-
const devDeps = [];
|
|
269
|
-
const normalDeps = [];
|
|
270
|
-
|
|
271
|
-
deps.forEach((dep) => {
|
|
272
|
-
if (dep === "nodemon") devDeps.push(dep);
|
|
273
|
-
else normalDeps.push(dep);
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
if (answer.npmi) {
|
|
277
|
-
if (normalDeps.length) {
|
|
278
|
-
execSync(`npm i ${normalDeps.join(" ")}`, {
|
|
279
|
-
cwd: projectPath,
|
|
280
|
-
stdio: "inherit",
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if (devDeps.length) {
|
|
285
|
-
execSync(`npm i -D ${devDeps.join(" ")}`, {
|
|
286
|
-
cwd: projectPath,
|
|
287
|
-
stdio: "inherit",
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
console.log(`\n${answer.projectName} project created successfully!\n`);
|
|
293
|
-
console.log("Happy coding! :)");
|
|
294
|
-
} catch (error) {
|
|
295
|
-
console.error("Error:", error.message);
|
|
296
|
-
process.exit(1);
|
|
297
|
-
}
|