create-express-mongo-ts 1.0.0

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 (54) hide show
  1. package/README.md +157 -0
  2. package/bin/cli.js +217 -0
  3. package/package.json +43 -0
  4. package/template/.dockerignore +2 -0
  5. package/template/.prettierignore +6 -0
  6. package/template/.prettierrc +8 -0
  7. package/template/Dockerfile +17 -0
  8. package/template/README.md +67 -0
  9. package/template/eslint.config.mts +34 -0
  10. package/template/jest.config.ts +201 -0
  11. package/template/keys/README.md +2 -0
  12. package/template/nodemon.json +5 -0
  13. package/template/package.json +65 -0
  14. package/template/src/app.ts +42 -0
  15. package/template/src/config.ts +31 -0
  16. package/template/src/core/ApiError.ts +118 -0
  17. package/template/src/core/ApiResponse.ts +140 -0
  18. package/template/src/core/asyncHandler.ts +15 -0
  19. package/template/src/core/authUtils.ts +68 -0
  20. package/template/src/core/jwtUtils.ts +96 -0
  21. package/template/src/core/logger.ts +48 -0
  22. package/template/src/core/utils.ts +12 -0
  23. package/template/src/database/index.ts +56 -0
  24. package/template/src/database/models/ApiKeys.ts +62 -0
  25. package/template/src/database/models/Keystore.ts +45 -0
  26. package/template/src/database/models/Role.ts +27 -0
  27. package/template/src/database/models/User.ts +64 -0
  28. package/template/src/database/repositories/ApiKeyRepo.ts +26 -0
  29. package/template/src/database/repositories/KeystoreRepo.ts +53 -0
  30. package/template/src/database/repositories/UserRepo.ts +63 -0
  31. package/template/src/helpers/generateApiKey.ts +23 -0
  32. package/template/src/helpers/validator.ts +38 -0
  33. package/template/src/index.ts +36 -0
  34. package/template/src/middlewares/authorize.middleware.ts +26 -0
  35. package/template/src/middlewares/error.middleware.ts +42 -0
  36. package/template/src/middlewares/permission.middleware.ts +20 -0
  37. package/template/src/middlewares/validator.middleware.ts +170 -0
  38. package/template/src/routes/auth/apiKey.ts +29 -0
  39. package/template/src/routes/auth/authentication.ts +45 -0
  40. package/template/src/routes/auth/index.ts +14 -0
  41. package/template/src/routes/auth/schema.ts +34 -0
  42. package/template/src/routes/auth/signin.ts +47 -0
  43. package/template/src/routes/auth/signout.ts +20 -0
  44. package/template/src/routes/auth/signup.ts +49 -0
  45. package/template/src/routes/auth/token.ts +68 -0
  46. package/template/src/routes/health/index.ts +14 -0
  47. package/template/src/routes/index.ts +19 -0
  48. package/template/src/types/ApiKey.ts +13 -0
  49. package/template/src/types/Keystore.ts +12 -0
  50. package/template/src/types/Role.ts +14 -0
  51. package/template/src/types/User.ts +16 -0
  52. package/template/src/types/app-requests.d.ts +22 -0
  53. package/template/src/types/permissions.ts +3 -0
  54. package/template/tsconfig.json +33 -0
package/README.md ADDED
@@ -0,0 +1,157 @@
1
+ # create-express-mongo
2
+
3
+ Create Express + MongoDB applications with TypeScript, authentication, and best practices out of the box.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/create-express-mongo.svg)](https://www.npmjs.com/package/create-express-mongo)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Quick Start
9
+
10
+ ```bash
11
+ npx create-express-mongo my-app
12
+ cd my-app
13
+ npm install
14
+ cp .env.example .env
15
+ npm run dev
16
+ ```
17
+
18
+ ## What's Included
19
+
20
+ This template provides a production-ready Express.js + MongoDB setup with:
21
+
22
+ ### 🔐 Authentication & Security
23
+ - JWT-based authentication (access & refresh tokens)
24
+ - API key management
25
+ - Role-based access control (RBAC)
26
+ - Password hashing with bcrypt
27
+ - Helmet.js security headers
28
+ - CORS configuration
29
+
30
+ ### 📁 Project Structure
31
+ ```
32
+ my-app/
33
+ ├── src/
34
+ │ ├── app.ts # Express app setup
35
+ │ ├── config.ts # Environment configuration
36
+ │ ├── index.ts # Application entry point
37
+ │ ├── core/ # Core utilities
38
+ │ │ ├── ApiError.ts # Custom error classes
39
+ │ │ ├── ApiResponse.ts # Standardized API responses
40
+ │ │ ├── asyncHandler.ts # Async error handling wrapper
41
+ │ │ ├── authUtils.ts # Authentication utilities
42
+ │ │ ├── jwtUtils.ts # JWT token utilities
43
+ │ │ ├── logger.ts # Winston logger setup
44
+ │ │ └── utils.ts # General utilities
45
+ │ ├── database/ # Database layer
46
+ │ │ ├── index.ts # MongoDB connection
47
+ │ │ ├── models/ # Mongoose models
48
+ │ │ └── repositories/ # Data access layer
49
+ │ ├── helpers/ # Helper functions
50
+ │ ├── middlewares/ # Express middlewares
51
+ │ ├── routes/ # API routes
52
+ │ └── types/ # TypeScript type definitions
53
+ ├── keys/ # RSA keys for JWT (generate your own)
54
+ ├── Dockerfile # Docker configuration
55
+ ├── tsconfig.json # TypeScript configuration
56
+ ├── jest.config.ts # Jest testing configuration
57
+ └── eslint.config.mts # ESLint configuration
58
+ ```
59
+
60
+ ### 🛠️ Tech Stack
61
+ - **Runtime**: Node.js 18+
62
+ - **Framework**: Express.js 5
63
+ - **Database**: MongoDB with Mongoose ODM
64
+ - **Language**: TypeScript
65
+ - **Validation**: Zod
66
+ - **Logging**: Winston with daily rotation
67
+ - **Testing**: Jest
68
+ - **Linting**: ESLint + Prettier
69
+
70
+ ## Available Scripts
71
+
72
+ | Command | Description |
73
+ |---------|-------------|
74
+ | `npm run dev` | Start development server with hot-reload |
75
+ | `npm run build` | Compile TypeScript to JavaScript |
76
+ | `npm start` | Build and run production server |
77
+ | `npm test` | Run test suite |
78
+ | `npm run lint` | Check code for linting errors |
79
+ | `npm run lint:fix` | Fix linting errors automatically |
80
+ | `npm run prettier:write` | Format code with Prettier |
81
+
82
+ ## Environment Variables
83
+
84
+ Create a `.env` file based on `.env.example`:
85
+
86
+ ```env
87
+ # Server Configuration
88
+ PORT=3000
89
+ NODE_ENV=development
90
+
91
+ # Database Configuration
92
+ DB_HOST=localhost
93
+ DB_PORT=27017
94
+ DB_NAME=myapp
95
+ DB_USER=
96
+ DB_PASSWORD=
97
+ DB_MIN_POOL_SIZE=2
98
+ DB_MAX_POOL_SIZE=5
99
+
100
+ # JWT Configuration
101
+ ACCESS_TOKEN_VALIDITY_SEC=3600
102
+ REFRESH_TOKEN_VALIDITY_SEC=86400
103
+ TOKEN_ISSUER=your-app
104
+ TOKEN_AUDIENCE=your-app
105
+
106
+ # CORS Configuration
107
+ ORIGIN_URL=*
108
+
109
+ # Logging
110
+ LOG_DIRECTORY=logs
111
+ ```
112
+
113
+ ## JWT Keys Setup
114
+
115
+ For production, generate RSA key pairs for JWT signing:
116
+
117
+ ```bash
118
+ # Navigate to keys directory
119
+ cd keys
120
+
121
+ # Generate private key
122
+ openssl genrsa -out private.pem 2048
123
+
124
+ # Generate public key
125
+ openssl rsa -in private.pem -pubout -out public.pem
126
+ ```
127
+
128
+ ## API Endpoints
129
+
130
+ ### Health Check
131
+ - `GET /health` - Server health status
132
+
133
+ ### Authentication
134
+ - `POST /auth/signup` - User registration
135
+ - `POST /auth/signin` - User login
136
+ - `POST /auth/signout` - User logout
137
+ - `POST /auth/token/refresh` - Refresh access token
138
+
139
+ ## Docker Support
140
+
141
+ Build and run with Docker:
142
+
143
+ ```bash
144
+ # Build image
145
+ docker build -t my-app .
146
+
147
+ # Run container
148
+ docker run -p 3000:3000 --env-file .env my-app
149
+ ```
150
+
151
+ ## Contributing
152
+
153
+ Contributions are welcome! Please feel free to submit a Pull Request.
154
+
155
+ ## License
156
+
157
+ MIT
package/bin/cli.js ADDED
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execSync } = require('child_process');
4
+ const path = require('path');
5
+ const fs = require('fs');
6
+
7
+ // Colors for console output
8
+ const colors = {
9
+ reset: '\x1b[0m',
10
+ bright: '\x1b[1m',
11
+ green: '\x1b[32m',
12
+ cyan: '\x1b[36m',
13
+ yellow: '\x1b[33m',
14
+ red: '\x1b[31m',
15
+ };
16
+
17
+ const log = {
18
+ info: (msg) => console.log(`${colors.cyan}ℹ${colors.reset} ${msg}`),
19
+ success: (msg) => console.log(`${colors.green}✔${colors.reset} ${msg}`),
20
+ warn: (msg) => console.log(`${colors.yellow}⚠${colors.reset} ${msg}`),
21
+ error: (msg) => console.log(`${colors.red}✖${colors.reset} ${msg}`),
22
+ };
23
+
24
+ // Get project name from command line arguments
25
+ const projectName = process.argv[2];
26
+
27
+ if (!projectName) {
28
+ log.error('Please specify the project directory:');
29
+ console.log(
30
+ ` ${colors.cyan}npx create-express-mongo${colors.reset} ${colors.green}<project-directory>${colors.reset}`,
31
+ );
32
+ console.log();
33
+ console.log('For example:');
34
+ console.log(
35
+ ` ${colors.cyan}npx create-express-mongo${colors.reset} ${colors.green}my-app${colors.reset}`,
36
+ );
37
+ process.exit(1);
38
+ }
39
+
40
+ const currentPath = process.cwd();
41
+ const projectPath = path.join(currentPath, projectName);
42
+ const templatePath = path.join(__dirname, '..', 'template');
43
+
44
+ // Check if directory already exists
45
+ if (fs.existsSync(projectPath)) {
46
+ log.error(
47
+ `The directory ${colors.green}${projectName}${colors.reset} already exists.`,
48
+ );
49
+ log.info(
50
+ 'Please choose a different project name or delete the existing directory.',
51
+ );
52
+ process.exit(1);
53
+ }
54
+
55
+ console.log();
56
+ console.log(
57
+ `${colors.bright}Creating a new Express + MongoDB app in ${colors.green}${projectPath}${colors.reset}`,
58
+ );
59
+ console.log();
60
+
61
+ // Create project directory
62
+ fs.mkdirSync(projectPath, { recursive: true });
63
+
64
+ // Function to copy directory recursively
65
+ function copyDir(src, dest) {
66
+ fs.mkdirSync(dest, { recursive: true });
67
+ const entries = fs.readdirSync(src, { withFileTypes: true });
68
+
69
+ for (const entry of entries) {
70
+ const srcPath = path.join(src, entry.name);
71
+ const destPath = path.join(dest, entry.name);
72
+
73
+ if (entry.isDirectory()) {
74
+ copyDir(srcPath, destPath);
75
+ } else {
76
+ fs.copyFileSync(srcPath, destPath);
77
+ }
78
+ }
79
+ }
80
+
81
+ try {
82
+ // Copy template files
83
+ log.info('Copying template files...');
84
+ copyDir(templatePath, projectPath);
85
+ log.success('Template files copied successfully.');
86
+
87
+ // Update package.json with project name
88
+ const packageJsonPath = path.join(projectPath, 'package.json');
89
+ if (fs.existsSync(packageJsonPath)) {
90
+ const packageJson = JSON.parse(
91
+ fs.readFileSync(packageJsonPath, 'utf8'),
92
+ );
93
+ packageJson.name = projectName;
94
+ packageJson.version = '1.0.0';
95
+ packageJson.description = `${projectName} - Express + MongoDB application`;
96
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
97
+ log.success('Updated package.json with project name.');
98
+ }
99
+
100
+ // Create .env.example file
101
+ const envExamplePath = path.join(projectPath, '.env.example');
102
+ if (!fs.existsSync(envExamplePath)) {
103
+ const envContent = `# Server Configuration
104
+ PORT=3000
105
+ NODE_ENV=development
106
+
107
+ # Database Configuration
108
+ DB_HOST=localhost
109
+ DB_PORT=27017
110
+ DB_NAME=${projectName}
111
+ DB_USER=
112
+ DB_PASSWORD=
113
+ DB_MIN_POOL_SIZE=2
114
+ DB_MAX_POOL_SIZE=5
115
+
116
+ # JWT Configuration
117
+ ACCESS_TOKEN_VALIDITY_SEC=3600
118
+ REFRESH_TOKEN_VALIDITY_SEC=86400
119
+
120
+ # CORS Configuration
121
+ CORS_URL=*
122
+
123
+ # Logging
124
+ LOG_DIR=logs
125
+ `;
126
+ fs.writeFileSync(envExamplePath, envContent);
127
+ log.success('Created .env.example file.');
128
+ }
129
+
130
+ // Initialize git repository
131
+ log.info('Initializing git repository...');
132
+ try {
133
+ execSync('git init', { cwd: projectPath, stdio: 'ignore' });
134
+
135
+ // Create .gitignore if it doesn't exist
136
+ const gitignorePath = path.join(projectPath, '.gitignore');
137
+ if (!fs.existsSync(gitignorePath)) {
138
+ const gitignoreContent = `# Dependencies
139
+ node_modules/
140
+
141
+ # Build output
142
+ dist/
143
+
144
+ # Environment files
145
+ .env
146
+ .env.local
147
+ .env.*.local
148
+
149
+ # Logs
150
+ logs/
151
+ *.log
152
+ npm-debug.log*
153
+
154
+ # IDE
155
+ .vscode/
156
+ .idea/
157
+
158
+ # OS files
159
+ .DS_Store
160
+ Thumbs.db
161
+
162
+ # Coverage
163
+ coverage/
164
+
165
+ # Keys (keep the folder structure but ignore actual keys)
166
+ keys/*.pem
167
+ keys/*.key
168
+
169
+ # TypeScript cache
170
+ *.tsbuildinfo
171
+ `;
172
+ fs.writeFileSync(gitignorePath, gitignoreContent);
173
+ }
174
+ log.success('Initialized git repository.');
175
+ } catch (error) {
176
+ log.warn(
177
+ 'Could not initialize git repository. Please initialize it manually.',
178
+ );
179
+ }
180
+
181
+ // Success message
182
+ console.log();
183
+ console.log(
184
+ `${colors.green}${colors.bright}Success!${colors.reset} Created ${colors.cyan}${projectName}${colors.reset} at ${colors.green}${projectPath}${colors.reset}`,
185
+ );
186
+ console.log();
187
+ console.log('Inside that directory, you can run several commands:');
188
+ console.log();
189
+ console.log(` ${colors.cyan}npm install${colors.reset}`);
190
+ console.log(' Installs all dependencies.');
191
+ console.log();
192
+ console.log(` ${colors.cyan}npm run dev${colors.reset}`);
193
+ console.log(' Starts the development server with hot-reload.');
194
+ console.log();
195
+ console.log(` ${colors.cyan}npm run build${colors.reset}`);
196
+ console.log(' Builds the app for production.');
197
+ console.log();
198
+ console.log(` ${colors.cyan}npm start${colors.reset}`);
199
+ console.log(' Builds and runs the production server.');
200
+ console.log();
201
+ console.log(` ${colors.cyan}npm test${colors.reset}`);
202
+ console.log(' Runs the test suite.');
203
+ console.log();
204
+ console.log('We suggest that you begin by typing:');
205
+ console.log();
206
+ console.log(` ${colors.cyan}cd${colors.reset} ${projectName}`);
207
+ console.log(` ${colors.cyan}npm install${colors.reset}`);
208
+ console.log(` ${colors.cyan}cp .env.example .env${colors.reset}`);
209
+ console.log(` ${colors.cyan}npm run dev${colors.reset}`);
210
+ console.log();
211
+ console.log(`${colors.bright}Happy coding!${colors.reset} 🚀`);
212
+ console.log();
213
+ } catch (error) {
214
+ log.error('An error occurred while creating the project:');
215
+ console.error(error);
216
+ process.exit(1);
217
+ }
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "create-express-mongo-ts",
3
+ "version": "1.0.0",
4
+ "description": "Create Express + MongoDB applications with TypeScript, authentication, and best practices out of the box",
5
+ "main": "bin/cli.js",
6
+ "bin": {
7
+ "create-express-mongo-ts": "./bin/cli.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "template"
12
+ ],
13
+ "scripts": {
14
+ "test": "echo \"No tests yet\""
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/sofikulsk02/express-mongobd-template.git"
19
+ },
20
+ "keywords": [
21
+ "express",
22
+ "mongodb",
23
+ "mongoose",
24
+ "typescript",
25
+ "template",
26
+ "boilerplate",
27
+ "rest-api",
28
+ "authentication",
29
+ "jwt",
30
+ "create-express-mongo",
31
+ "cli"
32
+ ],
33
+ "author": "sofikulsk02 <https://github.com/sofikulsk02>",
34
+ "license": "MIT",
35
+ "bugs": {
36
+ "url": "https://github.com/sofikulsk02/express-mongobd-template/issues"
37
+ },
38
+ "homepage": "https://github.com/sofikulsk02/express-mongobd-template#readme",
39
+ "type": "commonjs",
40
+ "engines": {
41
+ "node": ">=18.0.0"
42
+ }
43
+ }
@@ -0,0 +1,2 @@
1
+ dist
2
+ node_modules
@@ -0,0 +1,6 @@
1
+ build/
2
+ coverage/
3
+ keys/
4
+ logs/
5
+ node_modules/
6
+ *.md
@@ -0,0 +1,8 @@
1
+ {
2
+ "useTabs": false,
3
+ "semi": true,
4
+ "trailingComma": "all",
5
+ "singleQuote": true,
6
+ "printWidth": 80,
7
+ "tabWidth": 4
8
+ }
@@ -0,0 +1,17 @@
1
+ FROM node:22
2
+
3
+ USER node
4
+
5
+ RUN mkdir -p /home/node/app && chown -R node:node /home/node/app
6
+
7
+ WORKDIR /home/node/app
8
+
9
+ COPY --chown=node:node . .
10
+
11
+ RUN npm install
12
+
13
+ # container exposed network port number
14
+ EXPOSE 3000
15
+
16
+ # command to run within the container
17
+ CMD [ "npm", "start" ]
@@ -0,0 +1,67 @@
1
+ # Express + MongoDB Template
2
+
3
+ This is your new Express + MongoDB application. Follow the steps below to get started.
4
+
5
+ ## Getting Started
6
+
7
+ 1. **Install dependencies**
8
+ ```bash
9
+ npm install
10
+ ```
11
+
12
+ 2. **Set up environment variables**
13
+ ```bash
14
+ cp .env.example .env
15
+ ```
16
+ Then edit `.env` with your configuration.
17
+
18
+ 3. **Start MongoDB**
19
+ Make sure MongoDB is running locally or update the connection string in `.env`.
20
+
21
+ 4. **Run the development server**
22
+ ```bash
23
+ npm run dev
24
+ ```
25
+
26
+ 5. **Visit the health endpoint**
27
+ Open http://localhost:3000/health in your browser.
28
+
29
+ ## JWT Keys Setup (Required for Production)
30
+
31
+ Generate RSA key pairs for JWT token signing:
32
+
33
+ ```bash
34
+ cd keys
35
+ openssl genrsa -out private.pem 2048
36
+ openssl rsa -in private.pem -pubout -out public.pem
37
+ ```
38
+
39
+ ## Available Scripts
40
+
41
+ - `npm run dev` - Start development server with hot-reload
42
+ - `npm run build` - Compile TypeScript to JavaScript
43
+ - `npm start` - Build and run production server
44
+ - `npm test` - Run test suite
45
+ - `npm run lint` - Check code for linting errors
46
+ - `npm run lint:fix` - Fix linting errors automatically
47
+
48
+ ## Project Structure
49
+
50
+ ```
51
+ ├── src/
52
+ │ ├── app.ts # Express app setup
53
+ │ ├── config.ts # Environment configuration
54
+ │ ├── index.ts # Application entry point
55
+ │ ├── core/ # Core utilities (errors, responses, logging)
56
+ │ ├── database/ # Database connection and models
57
+ │ ├── helpers/ # Helper functions
58
+ │ ├── middlewares/ # Express middlewares
59
+ │ ├── routes/ # API routes
60
+ │ └── types/ # TypeScript type definitions
61
+ ├── keys/ # RSA keys for JWT
62
+ └── Dockerfile # Docker configuration
63
+ ```
64
+
65
+ ## Learn More
66
+
67
+ For more information, see the [create-express-mongo documentation](https://github.com/sofikulsk02/express-mongobd-template).
@@ -0,0 +1,34 @@
1
+ import tseslint from '@typescript-eslint/eslint-plugin';
2
+ import tsparser from '@typescript-eslint/parser';
3
+
4
+ export default [
5
+ {
6
+ files: ['**/*.ts'],
7
+ languageOptions: {
8
+ parser: tsparser,
9
+ parserOptions: {
10
+ project: './tsconfig.json',
11
+ },
12
+ },
13
+ plugins: {
14
+ '@typescript-eslint': tseslint,
15
+ },
16
+ rules: {
17
+ ...tseslint.configs.recommended.rules,
18
+ // Your custom rule overrides here
19
+ // "@typescript-eslint/explicit-function-return-type": "off",
20
+ "@typescript-eslint/no-unused-vars": [
21
+ "error",
22
+ {
23
+ "args": "all",
24
+ "argsIgnorePattern": "^_",
25
+ "caughtErrors": "all",
26
+ "caughtErrorsIgnorePattern": "^_",
27
+ "destructuredArrayIgnorePattern": "^_",
28
+ "varsIgnorePattern": "^_",
29
+ "ignoreRestSiblings": true
30
+ }
31
+ ]
32
+ },
33
+ },
34
+ ];