exp-node-server 1.1.2 → 1.1.6
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 +5 -9
- package/package.json +1 -1
- package/src/createProject.js +3 -0
- package/src/generateModule.js +54 -22
- package/src/utils/getProjectType.js +13 -0
- package/src/utils/{schemaGenerator.js → mongoose/schemaGenerator.js} +2 -2
- package/src/utils/prisma/prismaSchemaGenerator.js +10 -0
- package/src/utils/prisma/prismaServiceGenerator.js +47 -0
- package/templates/mongoose/.projectrc.json +3 -0
- package/templates/mongoose/package.json +0 -2
- package/templates/mongoose/readme.md +3 -7
- package/templates/mongoose/src/app/middlewares/request_validator.ts +2 -2
- package/templates/prisma/.env.example +20 -0
- package/templates/prisma/.projectrc.json +3 -0
- package/templates/prisma/Dockerfile +27 -0
- package/templates/prisma/docker-compose.yml +27 -0
- package/templates/prisma/dockerignore +0 -0
- package/templates/prisma/package.json +47 -0
- package/templates/prisma/prisma/schema/account.schema.prisma +19 -0
- package/templates/prisma/prisma/schema/profile.schema.prisma +8 -0
- package/templates/prisma/prisma/schema/schema.prisma +8 -0
- package/templates/prisma/prisma.config.ts +14 -0
- package/templates/prisma/readme.md +126 -0
- package/templates/prisma/src/app/configs/index.ts +26 -0
- package/templates/prisma/src/app/errors/zodError.ts +20 -0
- package/templates/prisma/src/app/lib/prisma.ts +10 -0
- package/templates/prisma/src/app/middlewares/auth.ts +30 -0
- package/templates/prisma/src/app/middlewares/global_error_handler.ts +51 -0
- package/templates/prisma/src/app/middlewares/not_found_api.ts +10 -0
- package/templates/prisma/src/app/middlewares/request_validator.ts +14 -0
- package/templates/prisma/src/app/middlewares/uploader.ts +16 -0
- package/templates/prisma/src/app/modules/account/account.controller.ts +116 -0
- package/templates/prisma/src/app/modules/account/account.route.ts +55 -0
- package/templates/prisma/src/app/modules/account/account.service.ts +402 -0
- package/templates/prisma/src/app/modules/account/account.swagger.ts +187 -0
- package/templates/prisma/src/app/modules/account/account.validation.ts +41 -0
- package/templates/prisma/src/app/modules/profile/profile.controller.ts +17 -0
- package/templates/prisma/src/app/modules/profile/profile.route.ts +22 -0
- package/templates/prisma/src/app/modules/profile/profile.service.ts +26 -0
- package/templates/prisma/src/app/modules/profile/profile.swagger.ts +34 -0
- package/templates/prisma/src/app/modules/profile/profile.validation.ts +8 -0
- package/templates/prisma/src/app/types/error.d.ts +10 -0
- package/templates/prisma/src/app/types/index.d.ts +12 -0
- package/templates/prisma/src/app/utils/JWT.ts +27 -0
- package/templates/prisma/src/app/utils/app_error.ts +12 -0
- package/templates/prisma/src/app/utils/catch_async.ts +13 -0
- package/templates/prisma/src/app/utils/cloudinary.ts +66 -0
- package/templates/prisma/src/app/utils/mail_sender.ts +102 -0
- package/templates/prisma/src/app/utils/manage_response.ts +24 -0
- package/templates/prisma/src/app/utils/otpGenerator.ts +29 -0
- package/templates/prisma/src/app.ts +42 -0
- package/templates/prisma/src/routes.ts +11 -0
- package/templates/prisma/src/server.ts +19 -0
- package/templates/prisma/src/swaggerOptions.ts +48 -0
- package/templates/prisma/tsconfig.json +23 -0
- /package/src/utils/{controllerGenerator.js → mongoose/controllerGenerator.js} +0 -0
- /package/src/utils/{routeGenerator.js → mongoose/routeGenerator.js} +0 -0
- /package/src/utils/{serviceGenerator.js → mongoose/serviceGenerator.js} +0 -0
- /package/src/utils/{swaggerGenerator.js → mongoose/swaggerGenerator.js} +0 -0
- /package/src/utils/{validationGenerator.js → mongoose/validationGenerator.js} +0 -0
package/README.md
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
# ⚡ Express Server CLI
|
|
2
2
|
|
|
3
|
-
[](https://github.com/abumahid/mongo-server-stater-pack/stargazers)
|
|
7
|
-
[](https://github.com/abumahid/mongo-server-stater-pack/issues)
|
|
8
|
-
[](https://github.com/abumahid/mongo-server-stater-pack/blob/main/LICENSE)
|
|
9
|
-
[](https://github.com/abumahid/mongo-server-stater-pack/commits/main)
|
|
3
|
+
[](https://www.npmjs.com/package/exp-node-server)
|
|
4
|
+
[](https://www.npmjs.com/package/exp-node-server)
|
|
5
|
+
[](https://www.npmjs.com/package/exp-node-server)
|
|
10
6
|
[](https://www.typescriptlang.org/)
|
|
11
7
|
[](https://nodejs.org/)
|
|
12
8
|
|
|
@@ -49,10 +45,10 @@ This will:
|
|
|
49
45
|
Inside your project run:
|
|
50
46
|
|
|
51
47
|
```bash
|
|
52
|
-
npx
|
|
48
|
+
npx exp-node-server -g <module-name>
|
|
53
49
|
```
|
|
54
50
|
|
|
55
|
-
Example: `npx
|
|
51
|
+
Example: `npx exp-node-server -g order`
|
|
56
52
|
|
|
57
53
|
Output:
|
|
58
54
|
|
package/package.json
CHANGED
package/src/createProject.js
CHANGED
|
@@ -49,6 +49,9 @@ export async function createProject(projectName) {
|
|
|
49
49
|
console.log(chalk.green(`\nNext steps:`));
|
|
50
50
|
console.log(chalk.cyan(`cd ${projectName}`));
|
|
51
51
|
console.log(chalk.cyan(`npm install`));
|
|
52
|
+
if (template === "prisma") {
|
|
53
|
+
console.log(chalk.cyan(`docker compose up -d`));
|
|
54
|
+
}
|
|
52
55
|
console.log(chalk.cyan(`npm run dev`));
|
|
53
56
|
|
|
54
57
|
} catch (err) {
|
package/src/generateModule.js
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { createDir, createFile } from "./utils.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { getProjectType } from './utils/getProjectType.js';
|
|
5
|
+
import { controllerGenerator } from "./utils/mongoose/controllerGenerator.js";
|
|
6
|
+
import { routeGenerator } from "./utils/mongoose/routeGenerator.js";
|
|
7
|
+
import { schemaGenerator } from "./utils/mongoose/schemaGenerator.js";
|
|
8
|
+
import { serviceGenerator } from "./utils/mongoose/serviceGenerator.js";
|
|
9
|
+
import { swaggerGenerator } from "./utils/mongoose/swaggerGenerator.js";
|
|
10
|
+
import { validationGenerator } from "./utils/mongoose/validationGenerator.js";
|
|
11
|
+
import { prismaSchemaGenerator } from "./utils/prisma/prismaSchemaGenerator.js";
|
|
12
|
+
import { prismaServiceGenerator } from "./utils/prisma/prismaServiceGenerator.js";
|
|
6
13
|
import { injectRoute } from "./utils/routeInjector.js";
|
|
7
|
-
import { schemaGenerator } from "./utils/schemaGenerator.js";
|
|
8
|
-
import { serviceGenerator } from "./utils/serviceGenerator.js";
|
|
9
|
-
import { swaggerGenerator } from "./utils/swaggerGenerator.js";
|
|
10
14
|
import { injectSwagger } from "./utils/swaggerInjector.js";
|
|
11
|
-
import { validationGenerator } from "./utils/validationGenerator.js";
|
|
12
15
|
|
|
13
16
|
export async function generateModule(name) {
|
|
14
17
|
|
|
18
|
+
const type = getProjectType();
|
|
19
|
+
|
|
15
20
|
const base = path.join(
|
|
16
21
|
process.cwd(),
|
|
17
22
|
"src/app/modules",
|
|
@@ -25,37 +30,64 @@ export async function generateModule(name) {
|
|
|
25
30
|
controllerGenerator(name)
|
|
26
31
|
);
|
|
27
32
|
|
|
28
|
-
createFile(
|
|
29
|
-
path.join(base, `${name}.service.ts`),
|
|
30
|
-
serviceGenerator(name)
|
|
31
|
-
);
|
|
32
|
-
|
|
33
33
|
createFile(
|
|
34
34
|
path.join(base, `${name}.route.ts`),
|
|
35
35
|
routeGenerator(name)
|
|
36
36
|
);
|
|
37
37
|
|
|
38
|
-
createFile(
|
|
39
|
-
path.join(base, `${name}.schema.ts`),
|
|
40
|
-
schemaGenerator(name)
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
createFile(
|
|
44
|
-
path.join(base, `${name}.interface.ts`),
|
|
45
|
-
`export type T_${name} = {
|
|
46
|
-
}`
|
|
47
|
-
);
|
|
48
|
-
|
|
49
38
|
createFile(
|
|
50
39
|
path.join(base, `${name}.validation.ts`),
|
|
51
40
|
validationGenerator(name)
|
|
52
41
|
);
|
|
42
|
+
|
|
53
43
|
createFile(
|
|
54
44
|
path.join(base, `${name}.swagger.ts`),
|
|
55
45
|
swaggerGenerator(name)
|
|
56
46
|
);
|
|
47
|
+
|
|
57
48
|
injectRoute(name);
|
|
58
49
|
injectSwagger(name);
|
|
59
50
|
|
|
51
|
+
//condition based generation
|
|
52
|
+
if (type === "mongoose") {
|
|
53
|
+
|
|
54
|
+
createFile(
|
|
55
|
+
path.join(base, `${name}.schema.ts`),
|
|
56
|
+
schemaGenerator(name)
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
createFile(
|
|
60
|
+
path.join(base, `${name}.interface.ts`),
|
|
61
|
+
`export type T_${name} = {}`
|
|
62
|
+
);
|
|
63
|
+
createFile(
|
|
64
|
+
path.join(base, `${name}.service.ts`),
|
|
65
|
+
serviceGenerator(name)
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
} else if (type === "prisma") {
|
|
69
|
+
|
|
70
|
+
// prisma schema file
|
|
71
|
+
const prismaDir = path.join(
|
|
72
|
+
process.cwd(),
|
|
73
|
+
"prisma/schema"
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
createFile(
|
|
77
|
+
path.join(prismaDir, `${name}.prisma`),
|
|
78
|
+
prismaSchemaGenerator(name)
|
|
79
|
+
);
|
|
80
|
+
createFile(
|
|
81
|
+
path.join(base, `${name}.service.ts`),
|
|
82
|
+
prismaServiceGenerator(name)
|
|
83
|
+
);
|
|
84
|
+
console.log(
|
|
85
|
+
chalk.blue("\n Run This Commands: \n")
|
|
86
|
+
);
|
|
87
|
+
console.log(
|
|
88
|
+
chalk.yellow(" npx prisma generate && npx prisma migrate dev\n")
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
60
92
|
console.log(chalk.green(`\nModule '${name}' created successfully`));
|
|
61
93
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
export function getProjectType() {
|
|
5
|
+
const configPath = path.join(process.cwd(), ".projectrc.json");
|
|
6
|
+
|
|
7
|
+
if (!fs.existsSync(configPath)) {
|
|
8
|
+
throw new Error("❌ .projectrc.json not found");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
12
|
+
return config.database;
|
|
13
|
+
}
|
|
@@ -3,9 +3,9 @@ export const schemaGenerator = (name) => {
|
|
|
3
3
|
import { Schema, model } from "mongoose";
|
|
4
4
|
import { T_${name} } from "./${name}.interface";
|
|
5
5
|
|
|
6
|
-
const schema = new Schema<T_${name}>({});
|
|
6
|
+
const schema = new Schema<T_${name}>({},{timestamps: true, versionKey: false});
|
|
7
7
|
|
|
8
8
|
export const ${name}_model = model("${name}", schema);
|
|
9
9
|
|
|
10
10
|
`
|
|
11
|
-
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const prismaServiceGenerator = (name) => {
|
|
2
|
+
return `
|
|
3
|
+
import { Request } from "express";
|
|
4
|
+
import { prisma } from "../../lib/prisma";
|
|
5
|
+
|
|
6
|
+
const get_all_${name}_from_db = async (req: Request) => {
|
|
7
|
+
// define your own login here
|
|
8
|
+
const result = await prisma.${name}.findMany();
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const get_single_${name}_from_db = async (req: Request) => {
|
|
13
|
+
// define your own login here
|
|
14
|
+
const { id } = req.params;
|
|
15
|
+
const result = await prisma.${name}.findUnique({where:{id}});
|
|
16
|
+
return result;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const create_${name}_into_db = async (req: Request) => {
|
|
20
|
+
// define your own login here
|
|
21
|
+
const result = await prisma.${name}.create({data:req.body});
|
|
22
|
+
return result;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const update_${name}_into_db = async (req: Request) => {
|
|
26
|
+
// define your own login here
|
|
27
|
+
const { id } = req.params;
|
|
28
|
+
const result = await prisma.${name}.update({where:{id},data:req.body});
|
|
29
|
+
return result;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const delete_${name}_from_db = async (req: Request) => {
|
|
33
|
+
// define your own login here
|
|
34
|
+
const { id } = req.params;
|
|
35
|
+
const result = await prisma.${name}.delete({where:{id}});
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const ${name}_service = {
|
|
40
|
+
get_all_${name}_from_db,
|
|
41
|
+
get_single_${name}_from_db,
|
|
42
|
+
create_${name}_into_db,
|
|
43
|
+
update_${name}_into_db,
|
|
44
|
+
delete_${name}_from_db,
|
|
45
|
+
};
|
|
46
|
+
`
|
|
47
|
+
}
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
"jsonwebtoken": "^9.0.2",
|
|
23
23
|
"multer": "^2.0.2",
|
|
24
24
|
"nodemailer": "^7.0.9",
|
|
25
|
-
"pg": "^8.17.2",
|
|
26
25
|
"swagger-jsdoc": "^6.2.8",
|
|
27
26
|
"swagger-ui-express": "^5.0.1",
|
|
28
27
|
"ts-node-dev": "^2.0.0",
|
|
@@ -38,7 +37,6 @@
|
|
|
38
37
|
"@types/multer": "^2.0.0",
|
|
39
38
|
"@types/node": "^24.10.9",
|
|
40
39
|
"@types/nodemailer": "^7.0.2",
|
|
41
|
-
"@types/pg": "^8.16.0",
|
|
42
40
|
"@types/swagger-jsdoc": "^6.0.4",
|
|
43
41
|
"@types/swagger-ui-express": "^4.1.8"
|
|
44
42
|
}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
# ⚡ Express Server CLI
|
|
2
2
|
|
|
3
|
-
[](https://github.com/abumahid/mongo-server-stater-pack/stargazers)
|
|
7
|
-
[](https://github.com/abumahid/mongo-server-stater-pack/issues)
|
|
8
|
-
[](https://github.com/abumahid/mongo-server-stater-pack/blob/main/LICENSE)
|
|
9
|
-
[](https://github.com/abumahid/mongo-server-stater-pack/commits/main)
|
|
3
|
+
[](https://www.npmjs.com/package/exp-node-server)
|
|
4
|
+
[](https://www.npmjs.com/package/exp-node-server)
|
|
5
|
+
[](https://www.npmjs.com/package/exp-node-server)
|
|
10
6
|
[](https://www.typescriptlang.org/)
|
|
11
7
|
[](https://nodejs.org/)
|
|
12
8
|
|
|
@@ -3,7 +3,7 @@ import { NextFunction, Request, Response } from 'express';
|
|
|
3
3
|
const RequestValidator = (schema: any) => {
|
|
4
4
|
return async (req: Request, res: Response, next: NextFunction) => {
|
|
5
5
|
try {
|
|
6
|
-
await schema.parseAsync(req.body);
|
|
6
|
+
req.body = await schema.parseAsync(req.body);
|
|
7
7
|
next();
|
|
8
8
|
} catch (err) {
|
|
9
9
|
next(err);
|
|
@@ -11,4 +11,4 @@ const RequestValidator = (schema: any) => {
|
|
|
11
11
|
};
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
export default RequestValidator;
|
|
14
|
+
export default RequestValidator;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
DATABASE_URL="postgresql://postgres:postgres123@localhost:5432/server_db?sslmode=disable"
|
|
2
|
+
|
|
3
|
+
NODE_ENV=development
|
|
4
|
+
PORT=5000
|
|
5
|
+
# JWT Configuration
|
|
6
|
+
ACCESS_TOKEN=
|
|
7
|
+
ACCESS_EXPIRES=
|
|
8
|
+
RESET_SECRET=
|
|
9
|
+
RESET_EXPIRES=
|
|
10
|
+
VERIFIED_TOKEN=
|
|
11
|
+
FRONT_END_URL=
|
|
12
|
+
|
|
13
|
+
# Email Configuration
|
|
14
|
+
APP_USER_EMAIL=
|
|
15
|
+
APP_PASSWORD=
|
|
16
|
+
|
|
17
|
+
# Cloudinary Configuration
|
|
18
|
+
CLOUD_NAME=
|
|
19
|
+
CLOUD_API_KEY=
|
|
20
|
+
CLOUD_API_SECRET=
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# ---------- BUILD STAGE ----------
|
|
2
|
+
FROM node:18-alpine AS builder
|
|
3
|
+
|
|
4
|
+
WORKDIR /app
|
|
5
|
+
|
|
6
|
+
COPY package*.json ./
|
|
7
|
+
RUN npm install
|
|
8
|
+
|
|
9
|
+
COPY . .
|
|
10
|
+
RUN npm run build
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# ---------- PRODUCTION STAGE ----------
|
|
14
|
+
FROM node:18-alpine
|
|
15
|
+
|
|
16
|
+
WORKDIR /app
|
|
17
|
+
|
|
18
|
+
COPY package*.json ./
|
|
19
|
+
RUN npm install && npm cache clean --force
|
|
20
|
+
|
|
21
|
+
COPY --from=builder /app/dist ./dist
|
|
22
|
+
|
|
23
|
+
RUN mkdir -p /app/uploads
|
|
24
|
+
|
|
25
|
+
EXPOSE 5000
|
|
26
|
+
|
|
27
|
+
CMD ["node", "dist/server.js"]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
version: "3.9"
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
postgres:
|
|
5
|
+
image: postgres:16-alpine
|
|
6
|
+
container_name: server_database
|
|
7
|
+
restart: always
|
|
8
|
+
|
|
9
|
+
environment:
|
|
10
|
+
POSTGRES_USER: postgres
|
|
11
|
+
POSTGRES_PASSWORD: postgres123
|
|
12
|
+
POSTGRES_DB: server_db
|
|
13
|
+
|
|
14
|
+
ports:
|
|
15
|
+
- "5432:5432"
|
|
16
|
+
|
|
17
|
+
volumes:
|
|
18
|
+
- postgres_data:/var/lib/postgresql/data
|
|
19
|
+
|
|
20
|
+
healthcheck:
|
|
21
|
+
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
22
|
+
interval: 5s
|
|
23
|
+
timeout: 5s
|
|
24
|
+
retries: 5
|
|
25
|
+
|
|
26
|
+
volumes:
|
|
27
|
+
postgres_data:
|
|
File without changes
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
8
|
+
"dev": "tsx watch src/server.ts",
|
|
9
|
+
"build": "tsc"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [],
|
|
12
|
+
"author": "",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@prisma/adapter-pg": "^7.5.0",
|
|
17
|
+
"@prisma/client": "^7.5.0",
|
|
18
|
+
"bcrypt": "^6.0.0",
|
|
19
|
+
"cloudinary": "^2.7.0",
|
|
20
|
+
"cookie-parser": "^1.4.7",
|
|
21
|
+
"cors": "^2.8.5",
|
|
22
|
+
"dotenv": "^17.3.1",
|
|
23
|
+
"express": "^5.1.0",
|
|
24
|
+
"jsonwebtoken": "^9.0.2",
|
|
25
|
+
"multer": "^2.0.2",
|
|
26
|
+
"nodemailer": "^7.0.9",
|
|
27
|
+
"pg": "^8.20.0",
|
|
28
|
+
"swagger-jsdoc": "^6.2.8",
|
|
29
|
+
"swagger-ui-express": "^5.0.1",
|
|
30
|
+
"zod": "^4.1.12"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/bcrypt": "^6.0.0",
|
|
34
|
+
"@types/cookie-parser": "^1.4.9",
|
|
35
|
+
"@types/cors": "^2.8.19",
|
|
36
|
+
"@types/express": "^5.0.3",
|
|
37
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
38
|
+
"@types/multer": "^2.0.0",
|
|
39
|
+
"@types/node": "^24.10.9",
|
|
40
|
+
"@types/nodemailer": "^7.0.2",
|
|
41
|
+
"@types/pg": "^8.20.0",
|
|
42
|
+
"@types/swagger-jsdoc": "^6.0.4",
|
|
43
|
+
"@types/swagger-ui-express": "^4.1.8",
|
|
44
|
+
"prisma": "^7.5.0",
|
|
45
|
+
"tsx": "^4.21.0"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
enum ROLE {
|
|
2
|
+
ADMIN
|
|
3
|
+
USER
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
model Account {
|
|
7
|
+
id String @id @default(uuid())
|
|
8
|
+
email String @unique
|
|
9
|
+
password String
|
|
10
|
+
role ROLE @default(USER)
|
|
11
|
+
lastOtp String?
|
|
12
|
+
lastOtpSendingTime DateTime?
|
|
13
|
+
isDeleted Boolean @default(false)
|
|
14
|
+
isAccountVerified Boolean @default(false)
|
|
15
|
+
createdAt DateTime @default(now())
|
|
16
|
+
updatedAt DateTime @default(now())
|
|
17
|
+
|
|
18
|
+
profile Profile?
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// This file was generated by Prisma, and assumes you have installed the following:
|
|
2
|
+
// npm install --save-dev prisma dotenv
|
|
3
|
+
import "dotenv/config";
|
|
4
|
+
import { defineConfig } from "prisma/config";
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
schema: "prisma/schema",
|
|
8
|
+
migrations: {
|
|
9
|
+
path: "prisma/migrations",
|
|
10
|
+
},
|
|
11
|
+
datasource: {
|
|
12
|
+
url: process.env["DATABASE_URL"],
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# ⚡ Express Server CLI
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/exp-node-server)
|
|
4
|
+
[](https://www.npmjs.com/package/exp-node-server)
|
|
5
|
+
[](https://www.npmjs.com/package/exp-node-server)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://nodejs.org/)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 🚀 Overview
|
|
12
|
+
|
|
13
|
+
A powerful `Express + TypeScript CLI` that instantly generates scalable `backend` modules with `Mongoose `/ `Prisma`, `Zod` `validation`, and `Swagger` documentation.
|
|
14
|
+
|
|
15
|
+
This tool helps developers quickly scaffold `clean`, `modular` `Express` APIs with minimal setup.
|
|
16
|
+
|
|
17
|
+
## ✨ Features
|
|
18
|
+
|
|
19
|
+
- ⚡ Generate complete `Express` + `TypeScript` modules
|
|
20
|
+
- 🧩 Built-in `Mongoose` / `Prisma` support
|
|
21
|
+
- 📘 Adds Swagger documentation automatically
|
|
22
|
+
- 📘 Automatic `Swagger` documentation
|
|
23
|
+
- 🔐 `Zod` validation ready
|
|
24
|
+
- 🏗️ `Modular` clean architecture
|
|
25
|
+
- 🚀 One command project setup
|
|
26
|
+
- 🔄 Add modules anytime
|
|
27
|
+
- 📦 Zero boilerplate setup
|
|
28
|
+
|
|
29
|
+
## 📦 Quick Start
|
|
30
|
+
|
|
31
|
+
Run directly using npx (recommended):
|
|
32
|
+
|
|
33
|
+
```Bash
|
|
34
|
+
npx exp-node-server -c my-api
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This will:
|
|
38
|
+
|
|
39
|
+
- Create an Express starter project
|
|
40
|
+
- Install dependencies
|
|
41
|
+
- Prepare the project for development
|
|
42
|
+
|
|
43
|
+
## 🧩 Generate a Module
|
|
44
|
+
|
|
45
|
+
Inside your project run:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx express-server-cli -g <module-name>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Example: `npx express-server-cli -g order`
|
|
52
|
+
|
|
53
|
+
Output:
|
|
54
|
+
|
|
55
|
+
```Bash
|
|
56
|
+
✔ order.interface.ts created
|
|
57
|
+
✔ order.schema.ts created
|
|
58
|
+
✔ order.validation.ts created
|
|
59
|
+
✔ order.route.ts created
|
|
60
|
+
✔ order.controller.ts created
|
|
61
|
+
✔ order.service.ts created
|
|
62
|
+
✔ order.swagger.ts created
|
|
63
|
+
|
|
64
|
+
🔗 Route registered in routes.ts
|
|
65
|
+
📘 Swagger docs registered
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 📁 Generated Module Structure
|
|
70
|
+
|
|
71
|
+
Each module follows a clean structure:
|
|
72
|
+
|
|
73
|
+
```Bash
|
|
74
|
+
src/app/modules/<module-name>/
|
|
75
|
+
├── <module>.interface.ts
|
|
76
|
+
├── <module>.schema.ts
|
|
77
|
+
├── <module>.validation.ts
|
|
78
|
+
├── <module>.route.ts
|
|
79
|
+
├── <module>.controller.ts
|
|
80
|
+
├── <module>.service.ts
|
|
81
|
+
└── <module>.swagger.ts
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## ⚙️ Run the Project
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm run dev
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Swagger docs available at:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
http://localhost:5000/docs
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 🧠 Tech Stack
|
|
97
|
+
|
|
98
|
+
- Express.js — Backend framework
|
|
99
|
+
- TypeScript — Strongly typed JavaScript
|
|
100
|
+
- Mongoose — MongoDB ODM
|
|
101
|
+
- Prisma — PostgreSQL ORM
|
|
102
|
+
- Zod — Runtime schema validation
|
|
103
|
+
- JWT — Authentication
|
|
104
|
+
- Swagger — API documentation
|
|
105
|
+
|
|
106
|
+
## 👨💻 Author
|
|
107
|
+
|
|
108
|
+
### Abumahid
|
|
109
|
+
|
|
110
|
+
GitHub
|
|
111
|
+
https://github.com/dev-abumahid
|
|
112
|
+
|
|
113
|
+
npm
|
|
114
|
+
https://www.npmjs.com/~dev_abumahid
|
|
115
|
+
|
|
116
|
+
Portfolio
|
|
117
|
+
https://abumahid.me
|
|
118
|
+
|
|
119
|
+
LinkedIn
|
|
120
|
+
https://linkedin.com/in/md-abu-mahid-islam
|
|
121
|
+
|
|
122
|
+
## ⭐ Support
|
|
123
|
+
|
|
124
|
+
If you find this project helpful, consider giving it a ⭐ on `GitHub`.
|
|
125
|
+
|
|
126
|
+
It helps the project grow and reach more developers.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
|
|
3
|
+
export const configs = {
|
|
4
|
+
port: process.env.PORT,
|
|
5
|
+
env: process.env.NODE_ENV,
|
|
6
|
+
db_url: process.env.DATABASE_URL,
|
|
7
|
+
jwt: {
|
|
8
|
+
access_token: process.env.ACCESS_TOKEN,
|
|
9
|
+
refresh_token: process.env.REFRESH_TOKEN,
|
|
10
|
+
access_expires: process.env.ACCESS_EXPIRES,
|
|
11
|
+
refresh_expires: process.env.REFRESH_EXPIRES,
|
|
12
|
+
reset_secret: process.env.RESET_SECRET,
|
|
13
|
+
reset_expires: process.env.RESET_EXPIRES,
|
|
14
|
+
front_end_url: process.env.FRONT_END_URL,
|
|
15
|
+
verified_token: process.env.VERIFIED_TOKEN,
|
|
16
|
+
},
|
|
17
|
+
email: {
|
|
18
|
+
app_email: process.env.APP_USER_EMAIL,
|
|
19
|
+
app_password: process.env.APP_PASSWORD,
|
|
20
|
+
},
|
|
21
|
+
cloudinary: {
|
|
22
|
+
cloud_name: process.env.CLOUD_NAME,
|
|
23
|
+
cloud_api_key: process.env.CLOUD_API_KEY,
|
|
24
|
+
cloud_api_secret: process.env.CLOUD_API_SECRET,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ZodError, ZodIssue } from 'zod'
|
|
2
|
+
import { TErrorSources, TGenericErrorResponse } from '../types/error'
|
|
3
|
+
|
|
4
|
+
const handleZodError = (err: ZodError): TGenericErrorResponse => {
|
|
5
|
+
const errorSources: TErrorSources = err.issues.map((issue: ZodIssue) => {
|
|
6
|
+
return {
|
|
7
|
+
path: issue?.path[issue.path.length - 1] as string,
|
|
8
|
+
message: issue.message
|
|
9
|
+
}
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
const statusCode = 400
|
|
13
|
+
return {
|
|
14
|
+
statusCode,
|
|
15
|
+
message: 'Validation Error',
|
|
16
|
+
errorSources
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default handleZodError
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PrismaPg } from "@prisma/adapter-pg";
|
|
2
|
+
import "dotenv/config";
|
|
3
|
+
import { PrismaClient } from "../../../prisma/generated/prisma/client";
|
|
4
|
+
|
|
5
|
+
const connectionString = `${process.env.DATABASE_URL}`;
|
|
6
|
+
|
|
7
|
+
const adapter = new PrismaPg({ connectionString });
|
|
8
|
+
const prisma = new PrismaClient({ adapter });
|
|
9
|
+
|
|
10
|
+
export { prisma };
|