create-enterprise-backend 0.1.0 โ 0.1.2
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 +165 -0
- package/core/install.js +4 -1
- package/core/run.js +22 -27
- package/core/scaffold.js +42 -14
- package/package.json +16 -3
- package/templates/express/mongo/.env.example +3 -0
- package/templates/fastify/mongo/.env.example +3 -0
- package/templates/fastify/supabase/.env.example +4 -0
package/README.md
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# ๐ Create Enterprise Backend
|
|
2
|
+
|
|
3
|
+
Create Enterprise Backend is a modern CLI tool to scaffold production-ready backend applications using Express or Fastify with MongoDB or Supabase, following enterprise best practices.
|
|
4
|
+
|
|
5
|
+
โก Zero setup. Secure defaults. Scalable structure.
|
|
6
|
+
|
|
7
|
+
## โจ Features
|
|
8
|
+
|
|
9
|
+
### ๐ Frameworks
|
|
10
|
+
- Express
|
|
11
|
+
- Fastify
|
|
12
|
+
|
|
13
|
+
### ๐ Databases
|
|
14
|
+
- MongoDB (Mongoose)
|
|
15
|
+
- Supabase (Postgres + Auth)
|
|
16
|
+
|
|
17
|
+
### ๐ Authentication Ready
|
|
18
|
+
- JWT-based auth
|
|
19
|
+
- Auth guards & middleware
|
|
20
|
+
- Safe handling when DB/env is missing
|
|
21
|
+
|
|
22
|
+
### ๐งฑ Enterprise Architecture
|
|
23
|
+
- Modular structure
|
|
24
|
+
- Controllers / Services / Routes
|
|
25
|
+
- Centralized error handling
|
|
26
|
+
- Environment-based config
|
|
27
|
+
|
|
28
|
+
### ๐ Developer Experience
|
|
29
|
+
- Nodemon preconfigured
|
|
30
|
+
- Clean logging
|
|
31
|
+
- Safe defaults (no crash if DB not configured)
|
|
32
|
+
|
|
33
|
+
## ๐ฆ Installation & Usage
|
|
34
|
+
|
|
35
|
+
You don't need to install anything globally.
|
|
36
|
+
|
|
37
|
+
**Create a new backend project**
|
|
38
|
+
```bash
|
|
39
|
+
npx create-enterprise-backend my-backend
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**or inside the current folder:**
|
|
43
|
+
```bash
|
|
44
|
+
npx create-enterprise-backend .
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## ๐งญ Interactive Setup
|
|
48
|
+
|
|
49
|
+
The CLI will guide you through:
|
|
50
|
+
- Framework selection (Express / Fastify)
|
|
51
|
+
- Database selection (MongoDB / Supabase)
|
|
52
|
+
- Dependency installation (Install now or later)
|
|
53
|
+
|
|
54
|
+
## ๐ Project Structure (Example)
|
|
55
|
+
```
|
|
56
|
+
src/
|
|
57
|
+
โโโ app.js
|
|
58
|
+
โโโ server.js
|
|
59
|
+
โโโ routes.js
|
|
60
|
+
โโโ config/
|
|
61
|
+
โ โโโ env.js
|
|
62
|
+
โ โโโ db.js # Mongo
|
|
63
|
+
โ โโโ supabase.js # Supabase
|
|
64
|
+
โโโ modules/
|
|
65
|
+
โ โโโ auth/
|
|
66
|
+
โ โโโ auth.controller.js
|
|
67
|
+
โ โโโ auth.routes.js
|
|
68
|
+
โ โโโ auth.service.js
|
|
69
|
+
โ โโโ auth.schema.js
|
|
70
|
+
โ โโโ user.model.js
|
|
71
|
+
โโโ middlewares/
|
|
72
|
+
โโโ services/
|
|
73
|
+
โโโ utils/
|
|
74
|
+
โโโ error-handler.js
|
|
75
|
+
โโโ jwt-guard.js
|
|
76
|
+
โโโ db-guard.js
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## โถ๏ธ Running the Server
|
|
80
|
+
```bash
|
|
81
|
+
npm run dev
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Output example:**
|
|
85
|
+
```
|
|
86
|
+
โ ๏ธ Supabase public client disabled (missing env vars)
|
|
87
|
+
โ ๏ธ Supabase admin client disabled (missing env vars)
|
|
88
|
+
๐ Server running at http://localhost:5000
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
This is intentional and safe โ the app won't crash if env vars are missing.
|
|
92
|
+
|
|
93
|
+
## ๐ Environment Variables
|
|
94
|
+
|
|
95
|
+
### MongoDB
|
|
96
|
+
```
|
|
97
|
+
PORT=5000
|
|
98
|
+
MONGO_URI=mongodb://localhost:27017/myapp
|
|
99
|
+
JWT_SECRET=supersecret
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Supabase
|
|
103
|
+
```
|
|
104
|
+
PORT=5000
|
|
105
|
+
SUPABASE_URL=https://xxxx.supabase.co
|
|
106
|
+
SUPABASE_ANON_KEY=public-key
|
|
107
|
+
SUPABASE_SERVICE_ROLE_KEY=service-role-key
|
|
108
|
+
JWT_SECRET=supersecret
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## ๐ก Database Safety (Enterprise Behavior)
|
|
112
|
+
|
|
113
|
+
- If DB is not connected, DB-dependent routes are automatically blocked
|
|
114
|
+
- The server never crashes due to missing DB or env variables
|
|
115
|
+
- Clear warnings are logged instead
|
|
116
|
+
|
|
117
|
+
## ๐งช Health Check
|
|
118
|
+
```
|
|
119
|
+
GET /health
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Response:**
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"status": "ok"
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## ๐ Node Version
|
|
130
|
+
- Node.js โฅ 18
|
|
131
|
+
|
|
132
|
+
## ๐ง Philosophy
|
|
133
|
+
|
|
134
|
+
This tool is built for:
|
|
135
|
+
- SaaS backends
|
|
136
|
+
- Admin dashboards
|
|
137
|
+
- APIs at scale
|
|
138
|
+
- Teams that care about structure & safety
|
|
139
|
+
|
|
140
|
+
It's meant to be extended, not locked.
|
|
141
|
+
|
|
142
|
+
## ๐ฃ Roadmap
|
|
143
|
+
- PostgreSQL & MySQL templates
|
|
144
|
+
- Docker & CI templates
|
|
145
|
+
- CLI flags (--yes, --framework, --db)
|
|
146
|
+
- Prisma / Drizzle support
|
|
147
|
+
- RBAC & multi-tenant auth
|
|
148
|
+
|
|
149
|
+
## ๐ค Contributing
|
|
150
|
+
|
|
151
|
+
Contributions are welcome!
|
|
152
|
+
- Fork the repo
|
|
153
|
+
- Create a feature branch
|
|
154
|
+
- Submit a PR
|
|
155
|
+
|
|
156
|
+
## ๐ License
|
|
157
|
+
|
|
158
|
+
MIT ยฉ Imad Hussain Khan
|
|
159
|
+
|
|
160
|
+
## โญ Support
|
|
161
|
+
|
|
162
|
+
If this tool helped you:
|
|
163
|
+
- โญ Star the repo
|
|
164
|
+
- ๐ Report issues
|
|
165
|
+
- ๐ก Suggest features
|
package/core/install.js
CHANGED
package/core/run.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
-
import fs from "fs";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
3
|
import prompts from "prompts";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import { generateProject } from "./scaffold.js";
|
|
@@ -16,8 +16,7 @@ export async function run() {
|
|
|
16
16
|
type: projectNameArg ? null : "text",
|
|
17
17
|
name: "projectName",
|
|
18
18
|
message: "Project name?",
|
|
19
|
-
validate: (
|
|
20
|
-
v?.trim()?.length ? true : "Project name is required"
|
|
19
|
+
validate: v => v?.trim()?.length ? true : "Project name is required"
|
|
21
20
|
},
|
|
22
21
|
{
|
|
23
22
|
type: "select",
|
|
@@ -34,7 +33,7 @@ export async function run() {
|
|
|
34
33
|
message: "Select database",
|
|
35
34
|
choices: [
|
|
36
35
|
{ title: "MongoDB", value: "mongo" },
|
|
37
|
-
{ title: "Supabase", value: "supabase" }
|
|
36
|
+
{ title: "Supabase", value: "supabase" }
|
|
38
37
|
]
|
|
39
38
|
},
|
|
40
39
|
{
|
|
@@ -55,41 +54,37 @@ export async function run() {
|
|
|
55
54
|
);
|
|
56
55
|
|
|
57
56
|
const projectName = (projectNameArg || answers.projectName).trim();
|
|
58
|
-
const { framework, database } = answers;
|
|
59
57
|
|
|
60
|
-
const
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
// โ
Validate template exists
|
|
67
|
-
if (!fs.existsSync(templatePath)) {
|
|
68
|
-
console.log(
|
|
69
|
-
chalk.red(
|
|
70
|
-
`\nโ Template not found for: ${framework} + ${database}\n`
|
|
71
|
-
)
|
|
72
|
-
);
|
|
73
|
-
process.exit(1);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const targetDir = path.join(process.cwd(), projectName);
|
|
58
|
+
const targetDir =
|
|
59
|
+
projectName === "." || projectName === "./"
|
|
60
|
+
? process.cwd()
|
|
61
|
+
: path.join(process.cwd(), projectName);
|
|
77
62
|
|
|
78
63
|
console.log(chalk.gray("\n๐ฆ Generating project..."));
|
|
64
|
+
|
|
79
65
|
await generateProject({
|
|
80
|
-
framework,
|
|
81
|
-
database,
|
|
66
|
+
framework: answers.framework,
|
|
67
|
+
database: answers.database,
|
|
82
68
|
targetDir,
|
|
83
69
|
projectName
|
|
84
70
|
});
|
|
85
71
|
|
|
72
|
+
// ๐ SAFETY CHECK
|
|
73
|
+
const pkgPath = path.join(targetDir, "package.json");
|
|
74
|
+
if (!(await fs.pathExists(pkgPath))) {
|
|
75
|
+
throw new Error("package.json not found. Scaffolding failed.");
|
|
76
|
+
}
|
|
77
|
+
|
|
86
78
|
if (answers.install) {
|
|
87
79
|
console.log(chalk.gray("\n๐ฅ Installing dependencies..."));
|
|
88
80
|
await installDeps({ targetDir });
|
|
89
81
|
}
|
|
90
82
|
|
|
91
83
|
console.log(chalk.green.bold("\nโ
Done!\n"));
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
);
|
|
84
|
+
|
|
85
|
+
if (projectName !== "." && projectName !== "./") {
|
|
86
|
+
console.log(`Next steps:\n cd ${projectName}\n npm run dev\n`);
|
|
87
|
+
} else {
|
|
88
|
+
console.log(`Next steps:\n npm run dev\n`);
|
|
89
|
+
}
|
|
95
90
|
}
|
package/core/scaffold.js
CHANGED
|
@@ -7,29 +7,57 @@ function getPackageRoot() {
|
|
|
7
7
|
return path.resolve(path.dirname(__filename), "..");
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const DB_MAP = {
|
|
11
|
+
mongo: "mongo",
|
|
12
|
+
supabase: "supabase"
|
|
13
|
+
};
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
export async function generateProject({
|
|
16
|
+
framework,
|
|
17
|
+
database,
|
|
18
|
+
targetDir,
|
|
19
|
+
projectName
|
|
20
|
+
}) {
|
|
21
|
+
const root = getPackageRoot();
|
|
22
|
+
const dbFolder = DB_MAP[database];
|
|
14
23
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
throw new Error(`Template not found: ${framework}/${database}`);
|
|
24
|
+
if (!dbFolder) {
|
|
25
|
+
throw new Error(`Unsupported database: ${database}`);
|
|
18
26
|
}
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
const templateDir = path.join(root, "templates", framework, dbFolder);
|
|
29
|
+
|
|
30
|
+
if (!(await fs.pathExists(templateDir))) {
|
|
31
|
+
throw new Error(`Template not found: ${framework}/${dbFolder}`);
|
|
22
32
|
}
|
|
23
33
|
|
|
34
|
+
const isCurrentDir = projectName === "." || projectName === "./";
|
|
35
|
+
|
|
24
36
|
await fs.ensureDir(targetDir);
|
|
25
|
-
await fs.copy(templateDir, targetDir, {
|
|
26
|
-
overwrite: false,
|
|
27
|
-
errorOnExist: true
|
|
28
|
-
});
|
|
29
37
|
|
|
30
|
-
//
|
|
38
|
+
// ๐ EMPTY DIRECTORY CHECK (CRITICAL)
|
|
39
|
+
if (isCurrentDir) {
|
|
40
|
+
const entries = await fs.readdir(targetDir);
|
|
41
|
+
const allowed = [".git", ".gitignore", ".DS_Store"];
|
|
42
|
+
|
|
43
|
+
const unsafe = entries.filter(e => !allowed.includes(e));
|
|
44
|
+
if (unsafe.length > 0) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
"Current directory is not empty. Please use an empty folder."
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
} else {
|
|
50
|
+
if ((await fs.pathExists(targetDir)) && (await fs.readdir(targetDir)).length) {
|
|
51
|
+
throw new Error(`Target folder already exists: ${projectName}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// โ
SAFE COPY
|
|
56
|
+
await fs.copy(templateDir, targetDir);
|
|
57
|
+
|
|
58
|
+
// Rename package.json only when not using "."
|
|
31
59
|
const pkgPath = path.join(targetDir, "package.json");
|
|
32
|
-
if (await fs.pathExists(pkgPath)) {
|
|
60
|
+
if (!isCurrentDir && (await fs.pathExists(pkgPath))) {
|
|
33
61
|
const pkg = await fs.readJson(pkgPath);
|
|
34
62
|
pkg.name = projectName;
|
|
35
63
|
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
package/package.json
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-enterprise-backend",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Enterprise backend scaffolder (Express/Fastify + Mongo/Supabase)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"create-enterprise-backend": "./bin/cli.js"
|
|
8
8
|
},
|
|
9
|
-
"files": [
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"core",
|
|
12
|
+
"templates",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
10
15
|
"keywords": [
|
|
11
16
|
"cli",
|
|
12
17
|
"scaffold",
|
|
@@ -24,5 +29,13 @@
|
|
|
24
29
|
"chalk": "^5.3.0",
|
|
25
30
|
"fs-extra": "^11.2.0",
|
|
26
31
|
"prompts": "^2.4.2"
|
|
27
|
-
}
|
|
32
|
+
},
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/ImaadDev/create-enterprise-backend"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/ImaadDev/create-enterprise-backend/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/ImaadDev/create-enterprise-backend#README"
|
|
28
41
|
}
|