exp-node-server 1.1.0 → 1.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 CHANGED
@@ -1,4 +1,4 @@
1
- # ⚡ Express + Mongoose + TypeScript Module Generator
1
+ # ⚡ Express Server CLI
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/exp-cli-gen.svg)](https://www.npmjs.com/package/exp-cli-gen)
4
4
  [![npm downloads](https://img.shields.io/npm/dw/exp-cli-gen.svg)](https://www.npmjs.com/package/exp-cli-gen)
@@ -14,167 +14,117 @@
14
14
 
15
15
  ## 🚀 Overview
16
16
 
17
- **exp-cli-gen** is a powerful **Express + TypeScript module generator** that uses **Mongoose** for database interaction.
18
- It automatically creates a complete module structure — including **models, controllers, services, routes, Zod validations, and Swagger documentation** — all in one command.
17
+ A powerful `Express + TypeScript CLI` that instantly generates scalable `backend` modules with `Mongoose `/ `Prisma`, `Zod` `validation`, and `Swagger` documentation.
19
18
 
20
- Ideal for developers who want to quickly scaffold modular Express APIs with clean architecture and ready-to-use integrations.
21
-
22
- ---
19
+ This tool helps developers quickly scaffold `clean`, `modular` `Express` APIs with minimal setup.
23
20
 
24
21
  ## ✨ Features
25
22
 
26
- - ⚙️ Generates full-featured Express + TypeScript modules
27
- - 🧩 Automatically integrates Mongoose models and Zod validations
28
- - 📘 Adds Swagger documentation automatically
29
- - 🚀 Clones and sets up a ready-to-run Express starter project
30
- - 🔁 Can add new modules anytime with a single command
31
- - 🧠 Skips redundant setup if the starter pack already exists
32
- - 💪 Built for scalability and maintainability
23
+ - ⚡ Generate complete `Express` + `TypeScript` modules
24
+ - 🧩 Built-in `Mongoose` / `Prisma` support
25
+ - 📘 Adds Swagger documentation automatically
26
+ - 📘 Automatic `Swagger` documentation
27
+ - 🔐 `Zod` validation ready
28
+ - 🏗️ `Modular` clean architecture
29
+ - 🚀 One command project setup
30
+ - 🔄 Add modules anytime
31
+ - 📦 Zero boilerplate setup
33
32
 
34
- ---
33
+ ## 📦 Quick Start
35
34
 
36
- ## 📦 Installation
35
+ Run directly using npx (recommended):
37
36
 
38
- Install globally:
39
-
40
- ```bash
41
- npm install -g exp-cli-gen
37
+ ```Bash
38
+ npx exp-node-server -c my-api
42
39
  ```
43
- Or run directly using npx (recommended):
44
40
 
45
- ```bash
46
- npx exp-cli-gen <module-name>
47
- ```
48
- ## Usage
49
- 🏗️ Generate your first module
41
+ This will:
50
42
 
51
- Run:
43
+ - Create an Express starter project
44
+ - Install dependencies
45
+ - Prepare the project for development
52
46
 
53
- ```bash
54
- npx exp-cli-gen test
55
- ```
56
- First run example:
47
+ ## 🧩 Generate a Module
57
48
 
58
- ```bash
59
- Need to install the following packages:
60
- exp-cli-gen@1.0.1
61
- Ok to proceed? (y)
49
+ Inside your project run:
62
50
 
63
- ⠋ No Express project found. Cloning starter pack...
64
- ✔ Starter project cloned!
51
+ ```bash
52
+ npx express-server-cli -g <module-name>
53
+ ```
65
54
 
66
- ✔ Git logs removed!
55
+ Example: `npx express-server-cli -g order`
67
56
 
68
- 📦 Installing dependencies...
57
+ Output:
69
58
 
70
- 🚀 Project setup complete.
71
- 🧩 Generating module: test...
72
- ✔ test.interface.ts created
73
- ✔ test.schema.ts created
74
- ✔ test.validation.ts created
75
- ✔ test.route.ts created
76
- ✔ test.controller.ts created
77
- ✔ test.service.ts created
78
- ✔ test.swagger.ts created
59
+ ```Bash
60
+ ✔ order.interface.ts created
61
+ ✔ order.schema.ts created
62
+ ✔ order.validation.ts created
63
+ ✔ order.route.ts created
64
+ ✔ order.controller.ts created
65
+ ✔ order.service.ts created
66
+ ✔ order.swagger.ts created
79
67
 
80
- 🔗 Route added to src/app/routes.ts
81
- 📘 Swagger doc added to src/swaggerOptions.ts
82
- ✨ Module 'test' created successfully!
68
+ 🔗 Route registered in routes.ts
69
+ 📘 Swagger docs registered
83
70
 
84
71
  ```
85
72
 
86
73
  ## 📁 Generated Module Structure
87
74
 
88
- Each generated module will contain the following files:
75
+ Each module follows a clean structure:
89
76
 
90
- ```pgsql
77
+ ```Bash
91
78
  src/app/modules/<module-name>/
92
- ├── <module-name>.interface.ts
93
- ├── <module-name>.schema.ts
94
- ├── <module-name>.validation.ts
95
- ├── <module-name>.route.ts
96
- ├── <module-name>.controller.ts
97
- ├── <module-name>.service.ts
98
- └── <module-name>.swagger.ts
99
- ```
100
-
101
- ## 🔄 Add More Modules
102
-
103
- Need another module? Just run:
104
-
105
- ```bash
106
- npx exp-cli-gen products
79
+ ├── <module>.interface.ts
80
+ ├── <module>.schema.ts
81
+ ├── <module>.validation.ts
82
+ ├── <module>.route.ts
83
+ ├── <module>.controller.ts
84
+ ├── <module>.service.ts
85
+ └── <module>.swagger.ts
107
86
  ```
108
87
 
109
- If the starter project already exists, it will skip cloning and directly add the new module.
88
+ ## ⚙️ Run the Project
110
89
 
111
- Example output:
112
90
  ```bash
113
- ℹ 📦 Starter folder already exists. Skipping clone.
114
- 📦 Dependencies already installed. Skipping npm install.
115
- 🧩 Generating module: products...
116
- ✔ products files created
117
- ✨ Module 'products' created successfully!
118
-
119
- src/app/modules/products/
120
- ├── products.interface.ts
121
- ├── products.schema.ts
122
- ├── products.validation.ts
123
- ├── products.route.ts
124
- ├── products.controller.ts
125
- ├── products.service.ts
126
- └── products.swagger.ts
127
- ```
128
-
129
- Then, refresh your Swagger docs at:
130
- ```bash
131
- http://localhost:5000/docs
91
+ npm run dev
132
92
  ```
133
93
 
134
- You’ll see your new routes automatically added.
135
-
136
- ---
137
-
138
- ## ⚙️ Configuration
94
+ Swagger docs available at:
139
95
 
140
- After setup, update your .env file following the .env.example file in the starter project.
141
-
142
- To start the server:
143
- ```bash
144
- npm run dev
145
- ```
146
- Open Swagger documentation at:
147
96
  ```bash
148
97
  http://localhost:5000/docs
149
98
  ```
150
99
 
151
- ---
152
100
  ## 🧠 Tech Stack
153
101
 
154
102
  - Express.js — Backend framework
155
103
  - TypeScript — Strongly typed JavaScript
156
- - Mongoose — MongoDB ORM
104
+ - Mongoose — MongoDB ODM
105
+ - Prisma — PostgreSQL ORM
157
106
  - Zod — Runtime schema validation
107
+ - JWT — Authentication
158
108
  - Swagger — API documentation
159
- - CLI (Node.js) — Command-line automation
160
109
 
161
- ---
162
- ## 🧩 Starter Pack Repository
110
+ ## 👨‍💻 Author
163
111
 
164
- This CLI uses the following base project as a starter:
112
+ ### Abumahid
165
113
 
166
- 👉 [mongo-server-stater-pack](https://github.com/abumahid/mongo-server-stater-pack.git)
114
+ GitHub
115
+ https://github.com/dev-abumahid
167
116
 
168
- ---
169
- ## 💬 Author
117
+ npm
118
+ https://www.npmjs.com/~dev_abumahid
170
119
 
171
- Abu Mahid
120
+ Portfolio
121
+ https://abumahid.me
172
122
 
173
- 🧠 [GitHub Profile](https://github.com/abumahid)
123
+ LinkedIn
124
+ https://linkedin.com/in/md-abu-mahid-islam
174
125
 
175
- 💼 [npm Profile](https://www.npmjs.com/~dev_abumahid)
126
+ ## ⭐ Support
176
127
 
177
- ---
178
- ### ⭐ Star this project
128
+ If you find this project helpful, consider giving it a ⭐ on `GitHub`.
179
129
 
180
- If you like this CLI, please give it a ⭐ on GitHub — it helps others discover it too! Thank you!
130
+ It helps the project grow and reach more developers.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "exp-node-server",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "exp-node-server": "./bin/cli.js"
@@ -24,7 +24,9 @@
24
24
  "nodejs",
25
25
  "api",
26
26
  "module-generator",
27
- "exp-cli-gen"
27
+ "exp-node-server",
28
+ "exp-node",
29
+ "server"
28
30
  ],
29
31
  "engines": {
30
32
  "node": ">=20.0.0"
@@ -1,4 +1,4 @@
1
- # ⚡ Express + Mongoose + TypeScript Module Generator
1
+ # ⚡ Express Server CLI
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/exp-cli-gen.svg)](https://www.npmjs.com/package/exp-cli-gen)
4
4
  [![npm downloads](https://img.shields.io/npm/dw/exp-cli-gen.svg)](https://www.npmjs.com/package/exp-cli-gen)
@@ -14,167 +14,117 @@
14
14
 
15
15
  ## 🚀 Overview
16
16
 
17
- **exp-cli-gen** is a powerful **Express + TypeScript module generator** that uses **Mongoose** for database interaction.
18
- It automatically creates a complete module structure — including **models, controllers, services, routes, Zod validations, and Swagger documentation** — all in one command.
17
+ A powerful `Express + TypeScript CLI` that instantly generates scalable `backend` modules with `Mongoose `/ `Prisma`, `Zod` `validation`, and `Swagger` documentation.
19
18
 
20
- Ideal for developers who want to quickly scaffold modular Express APIs with clean architecture and ready-to-use integrations.
21
-
22
- ---
19
+ This tool helps developers quickly scaffold `clean`, `modular` `Express` APIs with minimal setup.
23
20
 
24
21
  ## ✨ Features
25
22
 
26
- - ⚙️ Generates full-featured Express + TypeScript modules
27
- - 🧩 Automatically integrates Mongoose models and Zod validations
28
- - 📘 Adds Swagger documentation automatically
29
- - 🚀 Clones and sets up a ready-to-run Express starter project
30
- - 🔁 Can add new modules anytime with a single command
31
- - 🧠 Skips redundant setup if the starter pack already exists
32
- - 💪 Built for scalability and maintainability
23
+ - ⚡ Generate complete `Express` + `TypeScript` modules
24
+ - 🧩 Built-in `Mongoose` / `Prisma` support
25
+ - 📘 Adds Swagger documentation automatically
26
+ - 📘 Automatic `Swagger` documentation
27
+ - 🔐 `Zod` validation ready
28
+ - 🏗️ `Modular` clean architecture
29
+ - 🚀 One command project setup
30
+ - 🔄 Add modules anytime
31
+ - 📦 Zero boilerplate setup
33
32
 
34
- ---
33
+ ## 📦 Quick Start
35
34
 
36
- ## 📦 Installation
35
+ Run directly using npx (recommended):
37
36
 
38
- Install globally:
39
-
40
- ```bash
41
- npm install -g exp-cli-gen
37
+ ```Bash
38
+ npx exp-node-server -c my-api
42
39
  ```
43
- Or run directly using npx (recommended):
44
40
 
45
- ```bash
46
- npx exp-cli-gen <module-name>
47
- ```
48
- ## Usage
49
- 🏗️ Generate your first module
41
+ This will:
50
42
 
51
- Run:
43
+ - Create an Express starter project
44
+ - Install dependencies
45
+ - Prepare the project for development
52
46
 
53
- ```bash
54
- npx exp-cli-gen test
55
- ```
56
- First run example:
47
+ ## 🧩 Generate a Module
57
48
 
58
- ```bash
59
- Need to install the following packages:
60
- exp-cli-gen@1.0.1
61
- Ok to proceed? (y)
49
+ Inside your project run:
62
50
 
63
- ⠋ No Express project found. Cloning starter pack...
64
- ✔ Starter project cloned!
51
+ ```bash
52
+ npx express-server-cli -g <module-name>
53
+ ```
65
54
 
66
- ✔ Git logs removed!
55
+ Example: `npx express-server-cli -g order`
67
56
 
68
- 📦 Installing dependencies...
57
+ Output:
69
58
 
70
- 🚀 Project setup complete.
71
- 🧩 Generating module: test...
72
- ✔ test.interface.ts created
73
- ✔ test.schema.ts created
74
- ✔ test.validation.ts created
75
- ✔ test.route.ts created
76
- ✔ test.controller.ts created
77
- ✔ test.service.ts created
78
- ✔ test.swagger.ts created
59
+ ```Bash
60
+ ✔ order.interface.ts created
61
+ ✔ order.schema.ts created
62
+ ✔ order.validation.ts created
63
+ ✔ order.route.ts created
64
+ ✔ order.controller.ts created
65
+ ✔ order.service.ts created
66
+ ✔ order.swagger.ts created
79
67
 
80
- 🔗 Route added to src/app/routes.ts
81
- 📘 Swagger doc added to src/swaggerOptions.ts
82
- ✨ Module 'test' created successfully!
68
+ 🔗 Route registered in routes.ts
69
+ 📘 Swagger docs registered
83
70
 
84
71
  ```
85
72
 
86
73
  ## 📁 Generated Module Structure
87
74
 
88
- Each generated module will contain the following files:
75
+ Each module follows a clean structure:
89
76
 
90
- ```pgsql
77
+ ```Bash
91
78
  src/app/modules/<module-name>/
92
- ├── <module-name>.interface.ts
93
- ├── <module-name>.schema.ts
94
- ├── <module-name>.validation.ts
95
- ├── <module-name>.route.ts
96
- ├── <module-name>.controller.ts
97
- ├── <module-name>.service.ts
98
- └── <module-name>.swagger.ts
99
- ```
100
-
101
- ## 🔄 Add More Modules
102
-
103
- Need another module? Just run:
104
-
105
- ```bash
106
- npx exp-cli-gen products
79
+ ├── <module>.interface.ts
80
+ ├── <module>.schema.ts
81
+ ├── <module>.validation.ts
82
+ ├── <module>.route.ts
83
+ ├── <module>.controller.ts
84
+ ├── <module>.service.ts
85
+ └── <module>.swagger.ts
107
86
  ```
108
87
 
109
- If the starter project already exists, it will skip cloning and directly add the new module.
88
+ ## ⚙️ Run the Project
110
89
 
111
- Example output:
112
90
  ```bash
113
- ℹ 📦 Starter folder already exists. Skipping clone.
114
- 📦 Dependencies already installed. Skipping npm install.
115
- 🧩 Generating module: products...
116
- ✔ products files created
117
- ✨ Module 'products' created successfully!
118
-
119
- src/app/modules/products/
120
- ├── products.interface.ts
121
- ├── products.schema.ts
122
- ├── products.validation.ts
123
- ├── products.route.ts
124
- ├── products.controller.ts
125
- ├── products.service.ts
126
- └── products.swagger.ts
127
- ```
128
-
129
- Then, refresh your Swagger docs at:
130
- ```bash
131
- http://localhost:5000/docs
91
+ npm run dev
132
92
  ```
133
93
 
134
- You’ll see your new routes automatically added.
135
-
136
- ---
137
-
138
- ## ⚙️ Configuration
94
+ Swagger docs available at:
139
95
 
140
- After setup, update your .env file following the .env.example file in the starter project.
141
-
142
- To start the server:
143
- ```bash
144
- npm run dev
145
- ```
146
- Open Swagger documentation at:
147
96
  ```bash
148
97
  http://localhost:5000/docs
149
98
  ```
150
99
 
151
- ---
152
100
  ## 🧠 Tech Stack
153
101
 
154
102
  - Express.js — Backend framework
155
103
  - TypeScript — Strongly typed JavaScript
156
- - Mongoose — MongoDB ORM
104
+ - Mongoose — MongoDB ODM
105
+ - Prisma — PostgreSQL ORM
157
106
  - Zod — Runtime schema validation
107
+ - JWT — Authentication
158
108
  - Swagger — API documentation
159
- - CLI (Node.js) — Command-line automation
160
109
 
161
- ---
162
- ## 🧩 Starter Pack Repository
110
+ ## 👨‍💻 Author
163
111
 
164
- This CLI uses the following base project as a starter:
112
+ ### Abumahid
165
113
 
166
- 👉 [mongo-server-stater-pack](https://github.com/abumahid/mongo-server-stater-pack.git)
114
+ GitHub
115
+ https://github.com/dev-abumahid
167
116
 
168
- ---
169
- ## 💬 Author
117
+ npm
118
+ https://www.npmjs.com/~dev_abumahid
170
119
 
171
- Abu Mahid
120
+ Portfolio
121
+ https://abumahid.me
172
122
 
173
- 🧠 [GitHub Profile](https://github.com/abumahid)
123
+ LinkedIn
124
+ https://linkedin.com/in/md-abu-mahid-islam
174
125
 
175
- 💼 [npm Profile](https://www.npmjs.com/~dev_abumahid)
126
+ ## ⭐ Support
176
127
 
177
- ---
178
- ### ⭐ Star this project
128
+ If you find this project helpful, consider giving it a ⭐ on `GitHub`.
179
129
 
180
- If you like this CLI, please give it a ⭐ on GitHub — it helps others discover it too! Thank you!
130
+ It helps the project grow and reach more developers.
@@ -4,29 +4,29 @@ import manageResponse from "../../utils/manage_response";
4
4
  import { auth_services } from "./auth.service";
5
5
 
6
6
  const register_user = catchAsync(async (req, res) => {
7
- const result = await auth_services.register_user_into_db(req?.body)
7
+ const result = await auth_services.register_user_into_db(req?.body);
8
8
  manageResponse(res, {
9
9
  success: true,
10
10
  message: "Account created successful",
11
- statusCode: httpStatus.OK,
12
- data: result
13
- })
14
- })
11
+ statusCode: 200,
12
+ data: result,
13
+ });
14
+ });
15
15
 
16
16
  const login_user = catchAsync(async (req, res) => {
17
17
  const result = await auth_services.login_user_from_db(req.body);
18
18
 
19
- res.cookie('refreshToken', result.refreshToken, {
20
- secure: configs.env == 'production',
19
+ res.cookie("refreshToken", result.refreshToken, {
20
+ secure: configs.env == "production",
21
21
  httpOnly: true,
22
22
  });
23
23
  manageResponse(res, {
24
- statusCode: httpStatus.OK,
24
+ statusCode: 200,
25
25
  success: true,
26
- message: 'User is logged in successful !',
26
+ message: "User is logged in successful !",
27
27
  data: {
28
28
  accessToken: result.accessToken,
29
- role: result?.role
29
+ role: result?.role,
30
30
  },
31
31
  });
32
32
  });
@@ -35,9 +35,9 @@ const get_my_profile = catchAsync(async (req, res) => {
35
35
  const { email } = req.user!;
36
36
  const result = await auth_services.get_my_profile_from_db(email);
37
37
  manageResponse(res, {
38
- statusCode: httpStatus.OK,
38
+ statusCode: 200,
39
39
  success: true,
40
- message: 'User profile fetched successfully!',
40
+ message: "User profile fetched successfully!",
41
41
  data: result,
42
42
  });
43
43
  });
@@ -46,9 +46,9 @@ const refresh_token = catchAsync(async (req, res) => {
46
46
  const { refreshToken } = req.cookies;
47
47
  const result = await auth_services.refresh_token_from_db(refreshToken);
48
48
  manageResponse(res, {
49
- statusCode: httpStatus.OK,
49
+ statusCode: 200,
50
50
  success: true,
51
- message: 'Refresh token generated successfully!',
51
+ message: "Refresh token generated successfully!",
52
52
  data: result,
53
53
  });
54
54
  });
@@ -58,20 +58,20 @@ const change_password = catchAsync(async (req, res) => {
58
58
  const result = await auth_services.change_password_from_db(user!, req.body);
59
59
 
60
60
  manageResponse(res, {
61
- statusCode: httpStatus.OK,
61
+ statusCode: 200,
62
62
  success: true,
63
- message: 'Password changed successfully!',
63
+ message: "Password changed successfully!",
64
64
  data: result,
65
65
  });
66
66
  });
67
67
 
68
68
  const forget_password = catchAsync(async (req, res) => {
69
- const { email } = req?.body
69
+ const { email } = req?.body;
70
70
  await auth_services.forget_password_from_db(email);
71
71
  manageResponse(res, {
72
- statusCode: httpStatus.OK,
72
+ statusCode: 200,
73
73
  success: true,
74
- message: 'Reset password link sent to your email!',
74
+ message: "Reset password link sent to your email!",
75
75
  data: null,
76
76
  });
77
77
  });
@@ -84,33 +84,35 @@ const reset_password = catchAsync(async (req, res) => {
84
84
  newPassword,
85
85
  );
86
86
  manageResponse(res, {
87
- statusCode: httpStatus.OK,
87
+ statusCode: 200,
88
88
  success: true,
89
- message: 'Password reset successfully!',
89
+ message: "Password reset successfully!",
90
90
  data: result,
91
91
  });
92
92
  });
93
93
 
94
94
  const verified_account = catchAsync(async (req, res) => {
95
- const result = await auth_services.verified_account_into_db(req?.body?.token)
95
+ const result = await auth_services.verified_account_into_db(req?.body?.token);
96
96
 
97
97
  manageResponse(res, {
98
- statusCode: httpStatus.OK,
98
+ statusCode: 200,
99
99
  success: true,
100
100
  message: "Account Verification successful.",
101
- data: result
102
- })
103
- })
101
+ data: result,
102
+ });
103
+ });
104
104
 
105
105
  const get_new_verification_link = catchAsync(async (req, res) => {
106
- const result = await auth_services.get_new_verification_link_from_db(req?.body?.email)
106
+ const result = await auth_services.get_new_verification_link_from_db(
107
+ req?.body?.email,
108
+ );
107
109
  manageResponse(res, {
108
- statusCode: httpStatus.OK,
110
+ statusCode: 200,
109
111
  success: true,
110
112
  message: "New Verification link is send on email.",
111
- data: result
112
- })
113
- })
113
+ data: result,
114
+ });
115
+ });
114
116
 
115
117
  export const auth_controllers = {
116
118
  register_user,
@@ -121,5 +123,5 @@ export const auth_controllers = {
121
123
  reset_password,
122
124
  forget_password,
123
125
  verified_account,
124
- get_new_verification_link
125
- }
126
+ get_new_verification_link,
127
+ };
@@ -1,64 +1,66 @@
1
- import { AppError } from "../../utils/app_error";
2
- import { TAccount, TLoginPayload, TRegisterPayload } from "./auth.interface";
3
- import { Account_Model } from "./auth.schema";
4
1
  import bcrypt from "bcrypt";
5
- import { TUser } from "../user/user.interface";
6
- import { User_Model } from "../user/user.schema";
2
+ import { JwtPayload, Secret } from "jsonwebtoken";
7
3
  import mongoose from "mongoose";
8
- import { jwtHelpers } from "../../utils/JWT";
9
4
  import { configs } from "../../configs";
10
- import { JwtPayload, Secret } from "jsonwebtoken";
11
- import sendMail from "../../utils/mail_sender";
5
+ import { AppError } from "../../utils/app_error";
12
6
  import { isAccountExist } from "../../utils/isAccountExist";
7
+ import { jwtHelpers } from "../../utils/JWT";
8
+ import sendMail from "../../utils/mail_sender";
9
+ import { TUser } from "../user/user.interface";
10
+ import { User_Model } from "../user/user.schema";
11
+ import { TAccount, TLoginPayload, TRegisterPayload } from "./auth.interface";
12
+ import { Account_Model } from "./auth.schema";
13
13
  // register user
14
14
  const register_user_into_db = async (payload: TRegisterPayload) => {
15
- const session = await mongoose.startSession();
16
- session.startTransaction();
17
- try {
18
- // Check if the account already exists
19
- const isExistAccount = await Account_Model.findOne(
20
- { email: payload?.email },
21
- null,
22
- { session }
23
- );
24
- if (isExistAccount) {
25
- throw new AppError("Account already exist!!", httpStatus.BAD_REQUEST);
26
- }
27
-
28
- // Hash the password
29
- const hashPassword = bcrypt.hashSync(payload?.password, 10);
30
-
31
- // Create account
32
- const accountPayload: TAccount = {
33
- email: payload.email,
34
- password: hashPassword,
35
- lastPasswordChange: new Date()
36
- };
37
- const newAccount = await Account_Model.create([accountPayload], { session });
38
-
39
- // Create user
40
- const userPayload: TUser = {
41
- name: payload.name,
42
- accountId: newAccount[0]._id,
43
- };
44
- await User_Model.create([userPayload], { session });
45
- // make verified link
46
- const verifiedToken = jwtHelpers.generateToken(
47
- {
48
- email: payload?.email
49
- },
50
- configs.jwt.verified_token as Secret,
51
- '5m'
52
- );
53
- const verificationLink = `${configs.jwt.front_end_url}/verified?token=${verifiedToken}`;
54
- // Commit the transaction
55
- await session.commitTransaction();
56
- await sendMail({
57
- to: payload?.email,
58
- subject: "Thanks for creating account!",
59
- textBody: `New Account successfully created on ${new Date().toLocaleDateString()}`,
60
- name: payload?.name,
61
- htmlBody: `
15
+ const session = await mongoose.startSession();
16
+ session.startTransaction();
17
+ try {
18
+ // Check if the account already exists
19
+ const isExistAccount = await Account_Model.findOne(
20
+ { email: payload?.email },
21
+ null,
22
+ { session },
23
+ );
24
+ if (isExistAccount) {
25
+ throw new AppError("Account already exist!!", 409);
26
+ }
27
+
28
+ // Hash the password
29
+ const hashPassword = bcrypt.hashSync(payload?.password, 10);
30
+
31
+ // Create account
32
+ const accountPayload: TAccount = {
33
+ email: payload.email,
34
+ password: hashPassword,
35
+ lastPasswordChange: new Date(),
36
+ };
37
+ const newAccount = await Account_Model.create([accountPayload], {
38
+ session,
39
+ });
40
+
41
+ // Create user
42
+ const userPayload: TUser = {
43
+ name: payload.name,
44
+ accountId: newAccount[0]._id,
45
+ };
46
+ await User_Model.create([userPayload], { session });
47
+ // make verified link
48
+ const verifiedToken = jwtHelpers.generateToken(
49
+ {
50
+ email: payload?.email,
51
+ },
52
+ configs.jwt.verified_token as Secret,
53
+ "5m",
54
+ );
55
+ const verificationLink = `${configs.jwt.front_end_url}/verified?token=${verifiedToken}`;
56
+ // Commit the transaction
57
+ await session.commitTransaction();
58
+ await sendMail({
59
+ to: payload?.email,
60
+ subject: "Thanks for creating account!",
61
+ textBody: `New Account successfully created on ${new Date().toLocaleDateString()}`,
62
+ name: payload?.name,
63
+ htmlBody: `
62
64
  <p>Thanks for creating an account with us. We’re excited to have you on board! Click the button below to
63
65
  verify your email and activate your account:</p>
64
66
 
@@ -72,208 +74,224 @@ const register_user_into_db = async (payload: TRegisterPayload) => {
72
74
  </div>
73
75
 
74
76
  <p>If you did not create this account, please ignore this email.</p>
75
- `
76
- })
77
- return newAccount;
78
- } catch (error) {
79
- console.log(error)
80
- // Rollback the transaction
81
- await session.abortTransaction();
82
- throw error;
83
- } finally {
84
- session.endSession();
85
- }
77
+ `,
78
+ });
79
+ return newAccount;
80
+ } catch (error) {
81
+ console.log(error);
82
+ // Rollback the transaction
83
+ await session.abortTransaction();
84
+ throw error;
85
+ } finally {
86
+ session.endSession();
87
+ }
86
88
  };
87
89
 
88
-
89
90
  // login user
90
91
  const login_user_from_db = async (payload: TLoginPayload) => {
91
- // check account info
92
- const isExistAccount = await isAccountExist(payload?.email)
93
-
94
- const isPasswordMatch = await bcrypt.compare(
95
- payload.password,
96
- isExistAccount.password,
97
- );
98
- if (!isPasswordMatch) {
99
- throw new AppError('Invalid password', httpStatus.UNAUTHORIZED);
100
- }
101
- const accessToken = jwtHelpers.generateToken(
102
- {
103
- email: isExistAccount.email,
104
- role: isExistAccount.role,
105
- },
106
- configs.jwt.access_token as Secret,
107
- configs.jwt.access_expires as string,
108
- );
109
-
110
- const refreshToken = jwtHelpers.generateToken(
111
- {
112
- email: isExistAccount.email,
113
- role: isExistAccount.role,
114
- },
115
- configs.jwt.refresh_token as Secret,
116
- configs.jwt.refresh_expires as string,
117
- );
118
- return {
119
- accessToken: accessToken,
120
- refreshToken: refreshToken,
121
- role: isExistAccount.role
122
- };
123
-
124
- }
92
+ // check account info
93
+ const isExistAccount = await isAccountExist(payload?.email);
94
+
95
+ const isPasswordMatch = await bcrypt.compare(
96
+ payload.password,
97
+ isExistAccount.password,
98
+ );
99
+ if (!isPasswordMatch) {
100
+ throw new AppError("Invalid password", 401);
101
+ }
102
+ const accessToken = jwtHelpers.generateToken(
103
+ {
104
+ email: isExistAccount.email,
105
+ role: isExistAccount.role,
106
+ },
107
+ configs.jwt.access_token as Secret,
108
+ configs.jwt.access_expires as string,
109
+ );
110
+
111
+ const refreshToken = jwtHelpers.generateToken(
112
+ {
113
+ email: isExistAccount.email,
114
+ role: isExistAccount.role,
115
+ },
116
+ configs.jwt.refresh_token as Secret,
117
+ configs.jwt.refresh_expires as string,
118
+ );
119
+ return {
120
+ accessToken: accessToken,
121
+ refreshToken: refreshToken,
122
+ role: isExistAccount.role,
123
+ };
124
+ };
125
125
 
126
126
  const get_my_profile_from_db = async (email: string) => {
127
- const isExistAccount = await isAccountExist(email)
128
- const accountProfile = await User_Model.findOne({ accountId: isExistAccount._id })
129
- isExistAccount.password = ""
130
- return {
131
- account: isExistAccount,
132
- profile: accountProfile
133
- };
127
+ const isExistAccount = await isAccountExist(email);
128
+ const accountProfile = await User_Model.findOne({
129
+ accountId: isExistAccount._id,
130
+ });
131
+ isExistAccount.password = "";
132
+ return {
133
+ account: isExistAccount,
134
+ profile: accountProfile,
135
+ };
134
136
  };
135
137
 
136
138
  const refresh_token_from_db = async (token: string) => {
137
- let decodedData;
138
- try {
139
- decodedData = jwtHelpers.verifyToken(
140
- token,
141
- configs.jwt.refresh_token as Secret,
142
- );
143
- } catch (err) {
144
- throw new Error('You are not authorized!');
145
- }
146
-
147
- const userData = await Account_Model.findOne({ email: decodedData.email, status: "ACTIVE", isDeleted: false })
148
-
149
- const accessToken = jwtHelpers.generateToken(
150
- {
151
- email: userData!.email,
152
- role: userData!.role,
153
- },
154
- configs.jwt.access_token as Secret,
155
- configs.jwt.access_expires as string,
139
+ let decodedData;
140
+ try {
141
+ decodedData = jwtHelpers.verifyToken(
142
+ token,
143
+ configs.jwt.refresh_token as Secret,
156
144
  );
145
+ } catch (err) {
146
+ throw new Error("You are not authorized!");
147
+ }
148
+
149
+ const userData = await Account_Model.findOne({
150
+ email: decodedData.email,
151
+ status: "ACTIVE",
152
+ isDeleted: false,
153
+ });
154
+
155
+ const accessToken = jwtHelpers.generateToken(
156
+ {
157
+ email: userData!.email,
158
+ role: userData!.role,
159
+ },
160
+ configs.jwt.access_token as Secret,
161
+ configs.jwt.access_expires as string,
162
+ );
157
163
 
158
- return accessToken;
164
+ return accessToken;
159
165
  };
160
166
 
161
167
  const change_password_from_db = async (
162
- user: JwtPayload,
163
- payload: {
164
- oldPassword: string;
165
- newPassword: string;
166
- },
168
+ user: JwtPayload,
169
+ payload: {
170
+ oldPassword: string;
171
+ newPassword: string;
172
+ },
167
173
  ) => {
168
- const isExistAccount = await isAccountExist(user?.email)
169
-
170
- const isCorrectPassword: boolean = await bcrypt.compare(
171
- payload.oldPassword,
172
- isExistAccount.password,
173
- );
174
-
175
- if (!isCorrectPassword) {
176
- throw new AppError('Old password is incorrect', httpStatus.UNAUTHORIZED);
177
- }
178
-
179
- const hashedPassword: string = await bcrypt.hash(payload.newPassword, 10);
180
- await Account_Model.findOneAndUpdate({ email: isExistAccount.email }, {
181
- password: hashedPassword,
182
- lastPasswordChange: Date()
183
- })
184
- return 'Password changed successful.';
174
+ const isExistAccount = await isAccountExist(user?.email);
175
+
176
+ const isCorrectPassword: boolean = await bcrypt.compare(
177
+ payload.oldPassword,
178
+ isExistAccount.password,
179
+ );
180
+
181
+ if (!isCorrectPassword) {
182
+ throw new AppError("Old password is incorrect", 401);
183
+ }
184
+
185
+ const hashedPassword: string = await bcrypt.hash(payload.newPassword, 10);
186
+ await Account_Model.findOneAndUpdate(
187
+ { email: isExistAccount.email },
188
+ {
189
+ password: hashedPassword,
190
+ lastPasswordChange: Date(),
191
+ },
192
+ );
193
+ return "Password changed successful.";
185
194
  };
186
195
 
187
196
  const forget_password_from_db = async (email: string) => {
188
- const isAccountExists = await isAccountExist(email)
189
- const resetToken = jwtHelpers.generateToken(
190
- {
191
- email: isAccountExists.email,
192
- role: isAccountExists.role,
193
- },
194
- configs.jwt.reset_secret as Secret,
195
- configs.jwt.reset_expires as string,
196
- );
197
+ const isAccountExists = await isAccountExist(email);
198
+ const resetToken = jwtHelpers.generateToken(
199
+ {
200
+ email: isAccountExists.email,
201
+ role: isAccountExists.role,
202
+ },
203
+ configs.jwt.reset_secret as Secret,
204
+ configs.jwt.reset_expires as string,
205
+ );
197
206
 
198
- const resetPasswordLink = `${configs.jwt.front_end_url}/reset?token=${resetToken}&email=${isAccountExists.email}`;
199
- const emailTemplate = `<p>Click the link below to reset your password:</p><a href="${resetPasswordLink}">Reset Password</a>`;
207
+ const resetPasswordLink = `${configs.jwt.front_end_url}/reset?token=${resetToken}&email=${isAccountExists.email}`;
208
+ const emailTemplate = `<p>Click the link below to reset your password:</p><a href="${resetPasswordLink}">Reset Password</a>`;
200
209
 
201
- await sendMail({
202
- to: email,
203
- subject: "Password reset successful!",
204
- textBody: "Your password is successfully reset.",
205
- htmlBody: emailTemplate
206
- });
210
+ await sendMail({
211
+ to: email,
212
+ subject: "Password reset successful!",
213
+ textBody: "Your password is successfully reset.",
214
+ htmlBody: emailTemplate,
215
+ });
207
216
 
208
- return 'Check your email for reset link';
217
+ return "Check your email for reset link";
209
218
  };
210
219
 
211
220
  const reset_password_into_db = async (
212
- token: string,
213
- email: string,
214
- newPassword: string,
221
+ token: string,
222
+ email: string,
223
+ newPassword: string,
215
224
  ) => {
216
- let decodedData: JwtPayload;
217
- try {
218
- decodedData = jwtHelpers.verifyToken(
219
- token,
220
- configs.jwt.reset_secret as Secret,
221
- );
222
- } catch (err) {
223
- throw new AppError(
224
- 'Your reset link is expire. Submit new link request!!',
225
- httpStatus.UNAUTHORIZED,
226
- );
227
- }
225
+ let decodedData: JwtPayload;
226
+ try {
227
+ decodedData = jwtHelpers.verifyToken(
228
+ token,
229
+ configs.jwt.reset_secret as Secret,
230
+ );
231
+ } catch (err) {
232
+ throw new AppError(
233
+ "Your reset link is expire. Submit new link request!!",
234
+ 403,
235
+ );
236
+ }
228
237
 
229
- const isAccountExists = await isAccountExist(email)
238
+ const isAccountExists = await isAccountExist(email);
230
239
 
231
- const hashedPassword: string = await bcrypt.hash(newPassword, 10);
240
+ const hashedPassword: string = await bcrypt.hash(newPassword, 10);
232
241
 
233
- await Account_Model.findOneAndUpdate({ email: isAccountExists.email }, {
234
- password: hashedPassword,
235
- lastPasswordChange: Date()
236
- })
237
- return 'Password reset successfully!';
242
+ await Account_Model.findOneAndUpdate(
243
+ { email: isAccountExists.email },
244
+ {
245
+ password: hashedPassword,
246
+ lastPasswordChange: Date(),
247
+ },
248
+ );
249
+ return "Password reset successfully!";
238
250
  };
239
251
 
240
252
  const verified_account_into_db = async (token: string) => {
241
- try {
242
- const { email } = jwtHelpers.verifyToken(token, configs.jwt.verified_token as string)
243
- // check account is already verified or blocked
244
- const isExistAccount = await Account_Model.findOne({ email })
245
- // check account
246
- if (!isExistAccount) {
247
- throw new AppError("Account not found!!", httpStatus.NOT_FOUND)
248
- }
249
- if (isExistAccount.isDeleted) {
250
- throw new AppError("Account deleted !!", httpStatus.BAD_REQUEST)
251
- }
252
- const result = await Account_Model.findOneAndUpdate({ email }, { isVerified: true }, { new: true })
253
-
254
- return result
255
- } catch (error) {
256
- throw new AppError("Invalid or Expired token!!!", httpStatus.BAD_REQUEST)
253
+ try {
254
+ const { email } = jwtHelpers.verifyToken(
255
+ token,
256
+ configs.jwt.verified_token as string,
257
+ );
258
+ // check account is already verified or blocked
259
+ const isExistAccount = await Account_Model.findOne({ email });
260
+ // check account
261
+ if (!isExistAccount) {
262
+ throw new AppError("Account not found!!", 404);
263
+ }
264
+ if (isExistAccount.isDeleted) {
265
+ throw new AppError("Account deleted !!", 403);
257
266
  }
267
+ const result = await Account_Model.findOneAndUpdate(
268
+ { email },
269
+ { isVerified: true },
270
+ { new: true },
271
+ );
258
272
 
259
- }
273
+ return result;
274
+ } catch (error) {
275
+ throw new AppError("Invalid or Expired token!!!", 403);
276
+ }
277
+ };
260
278
 
261
279
  const get_new_verification_link_from_db = async (email: string) => {
262
- const isExistAccount = await isAccountExist(email)
280
+ const isExistAccount = await isAccountExist(email);
263
281
 
264
- const verifiedToken = jwtHelpers.generateToken(
265
- {
266
- email
267
- },
268
- configs.jwt.verified_token as Secret,
269
- '5m'
270
- );
271
- const verificationLink = `${configs.jwt.front_end_url}/verified?token=${verifiedToken}`;
272
- await sendMail({
273
- to: email,
274
- subject: "New Verification link",
275
- textBody: `New Account verification link is successfully created on ${new Date().toLocaleDateString()}`,
276
- htmlBody: `
282
+ const verifiedToken = jwtHelpers.generateToken(
283
+ {
284
+ email,
285
+ },
286
+ configs.jwt.verified_token as Secret,
287
+ "5m",
288
+ );
289
+ const verificationLink = `${configs.jwt.front_end_url}/verified?token=${verifiedToken}`;
290
+ await sendMail({
291
+ to: email,
292
+ subject: "New Verification link",
293
+ textBody: `New Account verification link is successfully created on ${new Date().toLocaleDateString()}`,
294
+ htmlBody: `
277
295
  <p>Thanks for creating an account with us. We’re excited to have you on board! Click the button below to
278
296
  verify your email and activate your account:</p>
279
297
 
@@ -287,20 +305,20 @@ const get_new_verification_link_from_db = async (email: string) => {
287
305
  </div>
288
306
 
289
307
  <p>If you did not create this account, please ignore this email.</p>
290
- `
291
- })
308
+ `,
309
+ });
292
310
 
293
- return null
294
- }
311
+ return null;
312
+ };
295
313
 
296
314
  export const auth_services = {
297
- register_user_into_db,
298
- login_user_from_db,
299
- get_my_profile_from_db,
300
- refresh_token_from_db,
301
- change_password_from_db,
302
- forget_password_from_db,
303
- reset_password_into_db,
304
- verified_account_into_db,
305
- get_new_verification_link_from_db
306
- }
315
+ register_user_into_db,
316
+ login_user_from_db,
317
+ get_my_profile_from_db,
318
+ refresh_token_from_db,
319
+ change_password_from_db,
320
+ forget_password_from_db,
321
+ reset_password_into_db,
322
+ verified_account_into_db,
323
+ get_new_verification_link_from_db,
324
+ };