express-ts-api-starter 1.0.1

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.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +495 -0
  3. package/dist/app.d.ts +4 -0
  4. package/dist/app.d.ts.map +1 -0
  5. package/dist/app.js +42 -0
  6. package/dist/config/dbConfig.d.ts +3 -0
  7. package/dist/config/dbConfig.d.ts.map +1 -0
  8. package/dist/config/dbConfig.js +21 -0
  9. package/dist/config/emailConfig.d.ts +1 -0
  10. package/dist/config/emailConfig.d.ts.map +1 -0
  11. package/dist/config/emailConfig.js +1 -0
  12. package/dist/config/envConfig.d.ts +8 -0
  13. package/dist/config/envConfig.d.ts.map +1 -0
  14. package/dist/config/envConfig.js +22 -0
  15. package/dist/config/rateLimitConfig.d.ts +2 -0
  16. package/dist/config/rateLimitConfig.d.ts.map +1 -0
  17. package/dist/config/rateLimitConfig.js +9 -0
  18. package/dist/constants/index.d.ts +6 -0
  19. package/dist/constants/index.d.ts.map +1 -0
  20. package/dist/constants/index.js +9 -0
  21. package/dist/interfaces/userInterface.d.ts +11 -0
  22. package/dist/interfaces/userInterface.d.ts.map +1 -0
  23. package/dist/interfaces/userInterface.js +2 -0
  24. package/dist/messages/index.d.ts +25 -0
  25. package/dist/messages/index.d.ts.map +1 -0
  26. package/dist/messages/index.js +30 -0
  27. package/dist/middleware/auth.d.ts +9 -0
  28. package/dist/middleware/auth.d.ts.map +1 -0
  29. package/dist/middleware/auth.js +30 -0
  30. package/dist/middleware/errorMiddleware.d.ts +4 -0
  31. package/dist/middleware/errorMiddleware.d.ts.map +1 -0
  32. package/dist/middleware/errorMiddleware.js +15 -0
  33. package/dist/middleware/logMiddleware.d.ts +4 -0
  34. package/dist/middleware/logMiddleware.d.ts.map +1 -0
  35. package/dist/middleware/logMiddleware.js +29 -0
  36. package/dist/middleware/requestIdMiddleware.d.ts +3 -0
  37. package/dist/middleware/requestIdMiddleware.d.ts.map +1 -0
  38. package/dist/middleware/requestIdMiddleware.js +11 -0
  39. package/dist/middleware/uploadMiddleware.d.ts +3 -0
  40. package/dist/middleware/uploadMiddleware.d.ts.map +1 -0
  41. package/dist/middleware/uploadMiddleware.js +36 -0
  42. package/dist/middleware/validatorMiddleware.d.ts +3 -0
  43. package/dist/middleware/validatorMiddleware.d.ts.map +1 -0
  44. package/dist/middleware/validatorMiddleware.js +13 -0
  45. package/dist/models/UserModel.d.ts +9 -0
  46. package/dist/models/UserModel.d.ts.map +1 -0
  47. package/dist/models/UserModel.js +59 -0
  48. package/dist/modules/users/tests/userController.test.d.ts +2 -0
  49. package/dist/modules/users/tests/userController.test.d.ts.map +1 -0
  50. package/dist/modules/users/userController.d.ts +5 -0
  51. package/dist/modules/users/userController.d.ts.map +1 -0
  52. package/dist/modules/users/userController.js +90 -0
  53. package/dist/modules/users/userMessage.d.ts +11 -0
  54. package/dist/modules/users/userMessage.d.ts.map +1 -0
  55. package/dist/modules/users/userMessage.js +11 -0
  56. package/dist/modules/users/userService.d.ts +16 -0
  57. package/dist/modules/users/userService.d.ts.map +1 -0
  58. package/dist/modules/users/userService.js +67 -0
  59. package/dist/routes/index.d.ts +3 -0
  60. package/dist/routes/index.d.ts.map +1 -0
  61. package/dist/routes/index.js +11 -0
  62. package/dist/routes/usersRoute.d.ts +3 -0
  63. package/dist/routes/usersRoute.d.ts.map +1 -0
  64. package/dist/routes/usersRoute.js +11 -0
  65. package/dist/server.d.ts +2 -0
  66. package/dist/server.d.ts.map +1 -0
  67. package/dist/server.js +45 -0
  68. package/dist/types/index.d.ts +12 -0
  69. package/dist/types/index.d.ts.map +1 -0
  70. package/dist/types/index.js +2 -0
  71. package/dist/types/roleType.d.ts +2 -0
  72. package/dist/types/roleType.d.ts.map +1 -0
  73. package/dist/types/roleType.js +2 -0
  74. package/dist/types/userTypes.d.ts +20 -0
  75. package/dist/types/userTypes.d.ts.map +1 -0
  76. package/dist/types/userTypes.js +2 -0
  77. package/dist/utils/authFunction.d.ts +3 -0
  78. package/dist/utils/authFunction.d.ts.map +1 -0
  79. package/dist/utils/authFunction.js +50 -0
  80. package/dist/utils/responseUtil.d.ts +5 -0
  81. package/dist/utils/responseUtil.d.ts.map +1 -0
  82. package/dist/utils/responseUtil.js +27 -0
  83. package/dist/validators/index.d.ts +2 -0
  84. package/dist/validators/index.d.ts.map +1 -0
  85. package/dist/validators/index.js +17 -0
  86. package/dist/validators/userValidators.d.ts +3 -0
  87. package/dist/validators/userValidators.d.ts.map +1 -0
  88. package/dist/validators/userValidators.js +34 -0
  89. package/package.json +160 -0
package/dist/server.js ADDED
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const app_1 = __importDefault(require("./app"));
7
+ const envConfig_1 = require("./config/envConfig");
8
+ const messages_1 = require("./messages");
9
+ // Handle uncaught exceptions
10
+ process.on(messages_1.EUncaughtExceptionMessages.uncaughtException, (err) => {
11
+ console.error(messages_1.EUncaughtExceptionMessages.uncaughtExceptionMessage, err.message);
12
+ console.error(err.stack);
13
+ process.exit(1);
14
+ });
15
+ const PORT = envConfig_1.env.PORT;
16
+ const server = app_1.default.listen(PORT, () => {
17
+ console.info(`${messages_1.EServerStartMessages.serverStarted}`);
18
+ console.log(`${messages_1.EServerStartMessages.serverRunning}${PORT} ✅`);
19
+ });
20
+ // Handle unhandled promise rejections (async errors)
21
+ process.on(messages_1.EUnhandledRejectionMessages.unhandledRejection, (reason) => {
22
+ console.error(messages_1.EUnhandledRejectionMessages.unhandledRejectionMessage, reason);
23
+ gracefulShutdown();
24
+ });
25
+ // ===== Graceful Shutdown Handler =====
26
+ const gracefulShutdown = () => {
27
+ console.log(`\n${messages_1.EGracefulShutdownMessages.shutdownInitiated}`);
28
+ // Set a timeout for shutdown (30 seconds)
29
+ const shutdownTimeout = setTimeout(() => {
30
+ console.warn(messages_1.EGracefulShutdownMessages.shutdownTimeout);
31
+ process.exit(1);
32
+ }, 30000);
33
+ // Stop accepting new connections
34
+ server.close(() => {
35
+ console.log(messages_1.EGracefulShutdownMessages.serverClosed);
36
+ clearTimeout(shutdownTimeout);
37
+ console.log(messages_1.EGracefulShutdownMessages.connectionsClosed);
38
+ process.exit(0);
39
+ });
40
+ // Force exit after timeout
41
+ shutdownTimeout.unref();
42
+ };
43
+ // Handle termination signals for graceful shutdown
44
+ process.on("SIGTERM", gracefulShutdown);
45
+ process.on("SIGINT", gracefulShutdown);
@@ -0,0 +1,12 @@
1
+ import { Types } from "mongoose";
2
+ export type TGetAllQueryParams = {
3
+ search?: string;
4
+ sortBy?: string;
5
+ sortOrder?: string;
6
+ limit?: string;
7
+ offset?: string;
8
+ };
9
+ export type TGetOnePathParams = {
10
+ id: string | Types.ObjectId;
11
+ };
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC;CAC7B,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export type TRoles = "admin" | "manager" | "staff";
2
+ //# sourceMappingURL=roleType.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roleType.d.ts","sourceRoot":"","sources":["../../src/types/roleType.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,20 @@
1
+ export type TRoles = "admin" | "user";
2
+ export type TCreateUserBody = {
3
+ name: string;
4
+ email: string;
5
+ password: string;
6
+ role: TRoles;
7
+ phone: string;
8
+ };
9
+ export type TUser = {
10
+ name: string;
11
+ email: string;
12
+ password: string;
13
+ role: TRoles;
14
+ phone: string;
15
+ };
16
+ export type TUserLoginBody = {
17
+ email: string;
18
+ password: string;
19
+ };
20
+ //# sourceMappingURL=userTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userTypes.d.ts","sourceRoot":"","sources":["../../src/types/userTypes.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEtC,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ import { IUser } from "../interfaces/userInterface";
2
+ export declare const generateJWT: (user: IUser) => Promise<string>;
3
+ //# sourceMappingURL=authFunction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authFunction.d.ts","sourceRoot":"","sources":["../../src/utils/authFunction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAEpD,eAAO,MAAM,WAAW,GAAU,MAAM,KAAK,oBAU5C,CAAC"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.generateJWT = void 0;
37
+ const jwt = __importStar(require("jsonwebtoken"));
38
+ const envConfig_1 = require("../config/envConfig");
39
+ const generateJWT = async (user) => {
40
+ // JWT payload containing user information
41
+ const payload = {
42
+ userId: user._id,
43
+ role: user.role,
44
+ email: user.email,
45
+ };
46
+ // Generate and return the JWT
47
+ const token = await jwt.sign(payload, envConfig_1.env.JWT_SECRET, { expiresIn: "7d" });
48
+ return token;
49
+ };
50
+ exports.generateJWT = generateJWT;
@@ -0,0 +1,5 @@
1
+ import { Request, Response } from "express";
2
+ export declare const sendErrorResponse: (statusCode: number, req: Request, res: Response, error: any, errorMessage: string) => void;
3
+ export declare const sendSuccessResponse: <T>(statusCode: number, req: Request, res: Response, data: T, successMessage: string) => void;
4
+ export declare const sendValidationErrorResponse: <T>(statusCode: number, res: Response, validationData: T, errorMessage: string) => void;
5
+ //# sourceMappingURL=responseUtil.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responseUtil.d.ts","sourceRoot":"","sources":["../../src/utils/responseUtil.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,iBAAiB,GAC5B,YAAY,MAAM,EAClB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,OAAO,GAAG,EACV,cAAc,MAAM,KACnB,IAIF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,CAAC,EACnC,YAAY,MAAM,EAClB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,CAAC,EACP,gBAAgB,MAAM,KACrB,IAQF,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAI,CAAC,EAC3C,YAAY,MAAM,EAClB,KAAK,QAAQ,EACb,gBAAgB,CAAC,EACjB,cAAc,MAAM,KACnB,IAMF,CAAC"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendValidationErrorResponse = exports.sendSuccessResponse = exports.sendErrorResponse = void 0;
4
+ const sendErrorResponse = (statusCode, req, res, error, errorMessage) => {
5
+ const requestId = req.headers["x-request-id"];
6
+ const message = errorMessage || error?.message;
7
+ res.status(statusCode).json({ success: false, requestId, error: message });
8
+ };
9
+ exports.sendErrorResponse = sendErrorResponse;
10
+ const sendSuccessResponse = (statusCode, req, res, data, successMessage) => {
11
+ const requestId = req.headers["x-request-id"];
12
+ res.status(statusCode).json({
13
+ success: true,
14
+ requestId,
15
+ message: successMessage,
16
+ response: data,
17
+ });
18
+ };
19
+ exports.sendSuccessResponse = sendSuccessResponse;
20
+ const sendValidationErrorResponse = (statusCode, res, validationData, errorMessage) => {
21
+ res.status(statusCode).json({
22
+ success: false,
23
+ message: errorMessage,
24
+ response: validationData,
25
+ });
26
+ };
27
+ exports.sendValidationErrorResponse = sendValidationErrorResponse;
@@ -0,0 +1,2 @@
1
+ export * from "./userValidators";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./userValidators"), exports);
@@ -0,0 +1,3 @@
1
+ export declare const registerValidator: (((req: import("express").Request, res: import("express").Response, next: import("express").NextFunction) => any) | import("express-validator").ValidationChain)[];
2
+ export declare const loginValidator: (((req: import("express").Request, res: import("express").Response, next: import("express").NextFunction) => any) | import("express-validator").ValidationChain)[];
3
+ //# sourceMappingURL=userValidators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userValidators.d.ts","sourceRoot":"","sources":["../../src/validators/userValidators.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,oKAyB7B,CAAC;AAEF,eAAO,MAAM,cAAc,oKAO1B,CAAC"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loginValidator = exports.registerValidator = void 0;
4
+ const express_validator_1 = require("express-validator");
5
+ const validatorMiddleware_1 = require("../middleware/validatorMiddleware");
6
+ exports.registerValidator = [
7
+ (0, express_validator_1.body)("name")
8
+ .notEmpty()
9
+ .withMessage("Name is required")
10
+ .isLength({ min: 2 })
11
+ .withMessage("Name must be at least 2 characters"),
12
+ (0, express_validator_1.body)("email").isEmail().withMessage("A valid email is required"),
13
+ (0, express_validator_1.body)("password")
14
+ .isLength({ min: 6 })
15
+ .withMessage("Password must be at least 6 characters"),
16
+ (0, express_validator_1.body)("role")
17
+ .notEmpty()
18
+ .withMessage("Role is required")
19
+ .isIn(["admin", "user"])
20
+ .withMessage("Invalid role"),
21
+ (0, express_validator_1.body)("phone")
22
+ .notEmpty()
23
+ .withMessage("Phone number is required")
24
+ .isMobilePhone("en-IN")
25
+ .withMessage("Invalid phone number"),
26
+ validatorMiddleware_1.validatorFn,
27
+ ];
28
+ exports.loginValidator = [
29
+ (0, express_validator_1.body)("email").isEmail().withMessage("A valid email is required"),
30
+ (0, express_validator_1.body)("password")
31
+ .isLength({ min: 6 })
32
+ .withMessage("Password must be at least 6 characters long"),
33
+ validatorMiddleware_1.validatorFn,
34
+ ];
package/package.json ADDED
@@ -0,0 +1,160 @@
1
+ {
2
+ "name": "express-ts-api-starter",
3
+ "version": "1.0.1",
4
+ "description": "Production-ready Express.js + TypeScript boilerplate with MVC architecture, JWT auth, MongoDB, security, validation, and testing—build scalable REST APIs fast",
5
+ "main": "dist/server.js",
6
+ "types": "dist/server.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "!dist/**/*.test.js",
10
+ "!dist/**/*.spec.js",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "scripts": {
15
+ "dev": "node scripts/eslint-report.js && nodemon --exec ts-node src/server.ts",
16
+ "build": "tsc",
17
+ "start": "node dist/server.js",
18
+ "test": "jest",
19
+ "lint": "eslint --ext .ts,.js .",
20
+ "lint:fix": "eslint --ext .ts,.js . --fix",
21
+ "lint:report": "eslint --ext .ts,.js . --format json -o eslint-report.json && node scripts/eslint-report.js",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "keywords": [
25
+ "express",
26
+ "express.js",
27
+ "typescript",
28
+ "nodejs",
29
+ "node.js",
30
+ "boilerplate",
31
+ "starter",
32
+ "starter-template",
33
+ "template",
34
+ "scaffold",
35
+ "mvc",
36
+ "mvc-architecture",
37
+ "rest-api",
38
+ "rest",
39
+ "api",
40
+ "backend",
41
+ "backend-template",
42
+ "server",
43
+ "web-server",
44
+ "authentication",
45
+ "jwt",
46
+ "json-web-token",
47
+ "auth",
48
+ "mongodb",
49
+ "mongoose",
50
+ "database",
51
+ "nosql",
52
+ "security",
53
+ "helmet",
54
+ "cors",
55
+ "validation",
56
+ "input-validation",
57
+ "middleware",
58
+ "production-ready",
59
+ "production",
60
+ "scalable",
61
+ "enterprise",
62
+ "testing",
63
+ "jest",
64
+ "test",
65
+ "error-handling",
66
+ "logging",
67
+ "logger",
68
+ "bcryptjs",
69
+ "password-hashing",
70
+ "express-validator",
71
+ "api-development",
72
+ "rest-api-development",
73
+ "web-development",
74
+ "full-stack",
75
+ "typescript-boilerplate",
76
+ "express-boilerplate",
77
+ "nodejs-boilerplate",
78
+ "rate-limiting",
79
+ "file-upload",
80
+ "multer",
81
+ "graceful-shutdown",
82
+ "request-tracking",
83
+ "request-id",
84
+ "modular-architecture",
85
+ "feature-based",
86
+ "monolithic",
87
+ "service-pattern",
88
+ "functional-programming",
89
+ "async-await",
90
+ "promises",
91
+ "error-middleware",
92
+ "logging-middleware",
93
+ "auth-middleware",
94
+ "validation-middleware",
95
+ "http-server",
96
+ "node-server",
97
+ "api-server",
98
+ "base-project",
99
+ "starter-project",
100
+ "dev-tools",
101
+ "development-tools"
102
+ ],
103
+ "author": {
104
+ "name": "Nikhil Plavalappil Kuttan",
105
+ "email": "nikhil.pk.connect@gmail.com",
106
+ "url": "https://github.com/nikhilpktcr"
107
+ },
108
+ "license": "MIT",
109
+ "repository": {
110
+ "type": "git",
111
+ "url": "https://github.com/nikhilpktcr/express-ts-starter.git",
112
+ "directory": "."
113
+ },
114
+ "bugs": {
115
+ "url": "https://github.com/nikhilpktcr/express-ts-starter/issues",
116
+ "email": "nikhil.pk.connect@gmail.com"
117
+ },
118
+ "homepage": "https://github.com/nikhilpktcr/express-ts-starter#readme",
119
+ "dependencies": {
120
+ "bcryptjs": "^3.0.2",
121
+ "chalk": "^5.4.1",
122
+ "cors": "^2.8.5",
123
+ "dotenv": "^16.5.0",
124
+ "express": "^5.1.0",
125
+ "express-rate-limit": "^7.5.1",
126
+ "express-throttle": "^2.0.0",
127
+ "express-validator": "^7.2.1",
128
+ "helmet": "^8.1.0",
129
+ "http-status-codes": "^2.3.0",
130
+ "jsonwebtoken": "^9.0.2",
131
+ "mongoose": "^8.16.3",
132
+ "morgan": "^1.10.0",
133
+ "multer": "^2.0.1",
134
+ "uuid": "^11.1.0"
135
+ },
136
+ "devDependencies": {
137
+ "@eslint/js": "^9.31.0",
138
+ "@tsconfig/node20": "^20.1.6",
139
+ "@types/cors": "^2.8.19",
140
+ "@types/express": "^5.0.3",
141
+ "@types/jest": "^30.0.0",
142
+ "@types/jsonwebtoken": "^9.0.10",
143
+ "@types/morgan": "^1.9.10",
144
+ "@types/multer": "^2.0.0",
145
+ "@types/node": "^24.0.14",
146
+ "@typescript-eslint/eslint-plugin": "^8.37.0",
147
+ "@typescript-eslint/parser": "^8.37.0",
148
+ "eslint": "^9.31.0",
149
+ "eslint-config-prettier": "^10.1.5",
150
+ "eslint-plugin-import": "^2.32.0",
151
+ "globals": "^16.3.0",
152
+ "jest": "^30.0.4",
153
+ "nodemon": "^3.1.10",
154
+ "prettier": "^3.5.3",
155
+ "ts-jest": "^29.4.0",
156
+ "ts-node": "^10.9.2",
157
+ "typescript": "^5.8.3",
158
+ "typescript-eslint": "^8.37.0"
159
+ }
160
+ }