express-genix 1.1.4 → 2.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 (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +204 -259
  3. package/index.js +229 -113
  4. package/lib/cleanup.js +41 -129
  5. package/lib/features.js +239 -0
  6. package/lib/generator.js +286 -204
  7. package/lib/utils.js +43 -91
  8. package/package.json +81 -63
  9. package/templates/cicd/github-actions.yml.ejs +70 -0
  10. package/templates/config/database.mongo.js.ejs +29 -33
  11. package/templates/config/database.postgres.js.ejs +41 -40
  12. package/templates/config/database.prisma.js.ejs +26 -0
  13. package/templates/config/redis.js.ejs +28 -0
  14. package/templates/config/schema.prisma.ejs +20 -0
  15. package/templates/config/swagger.js.ejs +30 -0
  16. package/templates/config/websocket.js.ejs +62 -0
  17. package/templates/controllers/authController.js.ejs +152 -129
  18. package/templates/controllers/exampleController.js.ejs +92 -152
  19. package/templates/controllers/userController.js.ejs +52 -60
  20. package/templates/core/Dockerfile.ejs +41 -31
  21. package/templates/core/README.md.ejs +191 -179
  22. package/templates/core/app.js.ejs +114 -64
  23. package/templates/core/docker-compose.yml.ejs +59 -47
  24. package/templates/core/dockerignore.ejs +7 -0
  25. package/templates/core/env.ejs +25 -19
  26. package/templates/core/env.example.ejs +26 -0
  27. package/templates/core/eslintrc.json.ejs +50 -20
  28. package/templates/core/gitignore.ejs +51 -51
  29. package/templates/core/healthcheck.js.ejs +24 -24
  30. package/templates/core/jest.config.js.ejs +19 -22
  31. package/templates/core/package.json.ejs +70 -33
  32. package/templates/core/prettierrc.json.ejs +11 -11
  33. package/templates/core/server.js.ejs +64 -48
  34. package/templates/core/tsconfig.json.ejs +19 -0
  35. package/templates/middleware/auth.js.ejs +80 -66
  36. package/templates/middleware/cache.js.ejs +67 -0
  37. package/templates/middleware/errorHandler.js.ejs +50 -46
  38. package/templates/middleware/requestId.js.ejs +9 -0
  39. package/templates/middleware/validation.js.ejs +109 -47
  40. package/templates/migrations/create-users.js.ejs +50 -0
  41. package/templates/migrations/seed-users.js.ejs +34 -0
  42. package/templates/migrations/sequelizerc.ejs +8 -0
  43. package/templates/models/User.mongo.js.ejs +29 -29
  44. package/templates/models/User.postgres.js.ejs +40 -40
  45. package/templates/models/index.mongo.js.ejs +7 -7
  46. package/templates/models/index.postgres.js.ejs +11 -11
  47. package/templates/routes/authRoutes.js.ejs +222 -13
  48. package/templates/routes/exampleRoutes.js.ejs +100 -12
  49. package/templates/routes/index.js.ejs +34 -24
  50. package/templates/routes/userRoutes.js.ejs +78 -15
  51. package/templates/services/authService.js.ejs +111 -35
  52. package/templates/services/exampleService.js.ejs +112 -112
  53. package/templates/services/userService.mongodb.js.ejs +33 -33
  54. package/templates/services/userService.postgres.js.ejs +30 -30
  55. package/templates/services/userService.prisma.js.ejs +36 -0
  56. package/templates/tests/auth.test.js.ejs +83 -66
  57. package/templates/tests/example.test.js.ejs +109 -112
  58. package/templates/tests/setup.js.ejs +11 -11
  59. package/templates/tests/users.test.js.ejs +42 -42
  60. package/templates/utils/envValidator.js.ejs +23 -0
  61. package/templates/utils/errors.js.ejs +12 -12
  62. package/templates/utils/logger.js.ejs +37 -28
  63. package/templates/utils/response.js.ejs +28 -0
  64. package/templates/utils/validators.js.ejs +34 -34
  65. package/templates/config/swagger.json.ejs +0 -194
  66. package/templates/core/index.js.ejs +0 -24
@@ -1,32 +1,42 @@
1
- # templates/core/Dockerfile.ejs
2
- FROM node:20-alpine
3
-
4
- # Set working directory
5
- WORKDIR /app
6
-
7
- # Copy package files
8
- COPY package*.json ./
9
-
10
- # Install dependencies
11
- RUN npm ci --only=production && npm cache clean --force
12
-
13
- # Copy application code
14
- COPY . .
15
-
16
- # Create non-root user
17
- RUN addgroup -g 1001 -S nodejs
18
- RUN adduser -S nodeuser -u 1001
19
-
20
- # Change ownership of app directory
21
- RUN chown -R nodeuser:nodejs /app
22
- USER nodeuser
23
-
24
- # Expose port
25
- EXPOSE 3000
26
-
27
- # Health check
28
- HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
29
- CMD node healthcheck.js
30
-
31
- # Start application
1
+ FROM node:20-alpine
2
+
3
+ # Set working directory
4
+ WORKDIR /app
5
+
6
+ # Copy package files
7
+ COPY package*.json ./
8
+ <% if (isPrisma) { %>
9
+ # Copy Prisma schema for generation
10
+ COPY prisma ./prisma/
11
+ <% } %>
12
+ # Install dependencies
13
+ RUN npm ci --only=production && npm cache clean --force
14
+ <% if (isPrisma) { %>
15
+ # Generate Prisma client
16
+ RUN npx prisma generate
17
+ <% } %><% if (isTypescript) { %>
18
+ # Copy source and build
19
+ COPY tsconfig.json ./
20
+ COPY src ./src/
21
+ RUN npx tsc
22
+ <% } else { %>
23
+ # Copy application code
24
+ COPY . .
25
+ <% } %>
26
+ # Create non-root user
27
+ RUN addgroup -g 1001 -S nodejs
28
+ RUN adduser -S nodeuser -u 1001
29
+
30
+ # Change ownership of app directory
31
+ RUN chown -R nodeuser:nodejs /app
32
+ USER nodeuser
33
+
34
+ # Expose port
35
+ EXPOSE 3000
36
+
37
+ # Health check
38
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
39
+ CMD node healthcheck.js
40
+
41
+ # Start application
32
42
  CMD ["npm", "start"]
@@ -1,179 +1,191 @@
1
- # <%= projectName %>
2
-
3
- A production-grade Express.js boilerplate<% if (hasDatabase) { %> with JWT authentication, <%= db %> support<% } %>, rate-limiting, security middleware, logging, API documentation, testing, and more.
4
-
5
- ## Features
6
-
7
- <% if (hasDatabase) { %>- **Authentication**: JWT-based authentication with refresh tokens
8
- - **Database**: <%= db === 'mongodb' ? 'MongoDB with Mongoose' : 'PostgreSQL with Sequelize' %>
9
- - **User Management**: Complete user registration, login, profile management<% } else { %>- **No Database**: Perfect for microservices, proxy servers, or computational APIs
10
- - **Example API**: CRUD operations with in-memory storage (easily replaceable)<% } %>
11
- - **Security**: Helmet, CORS, rate limiting
12
- - **Logging**: Morgan HTTP request logger with custom logging utilities
13
- - **API Documentation**: Swagger UI
14
- - **Testing**: Jest and Supertest
15
- - **Code Quality**: ESLint with Airbnb configuration, Prettier formatting
16
- - **Deployment**: Docker support with clustering
17
- - **Project Structure**: Clean, modular Express.js architecture
18
-
19
- ## Project Structure
20
-
21
- ```
22
- ├── src/
23
- │ ├── config/ # Configuration files (swagger<% if (hasDatabase) { %>, database<% } %>)
24
- │ ├── controllers/ # Request handlers and business logic orchestration<% if (hasDatabase) { %>
25
- │ ├── middleware/ # Custom middleware (auth, validation, errors)<% } else { %>
26
- │ ├── middleware/ # Custom middleware (errors)<% } %>
27
- <% if (hasDatabase) { %>│ ├── models/ # Database models<% } %>
28
- │ ├── routes/ # API endpoint definitions
29
- │ ├── services/ # Business logic layer
30
- │ ├── utils/ # Utility functions and helpers
31
- │ ├── app.js # Express app configuration
32
- └── server.js # Server setup and clustering
33
- ├── tests/ # Test files
34
- ├── .env # Environment variables
35
- ├── .gitignore # Git ignore rules
36
- ├── package.json # Dependencies and scripts
37
- └── README.md # Project documentation
38
- ```
39
-
40
- ## Setup
41
-
42
- 1. **Install Dependencies**
43
- ```bash
44
- npm install
45
- ```
46
-
47
- 2. **Environment Configuration**
48
- - Copy `.env` and configure your environment variables<% if (hasDatabase) { %>
49
- - Update database connection settings
50
- - Change JWT secrets for production<% } %>
51
-
52
- <% if (hasDatabase) { %>3. **Database Setup**<% if (db === 'mongodb') { %>
53
- - Ensure MongoDB is running locally or update MONGO_URI
54
- - Database will be created automatically<% } else if (db === 'postgresql') { %>
55
- - Ensure PostgreSQL is running locally
56
- - Create a database matching your DATABASE_URL
57
- - Run migrations if needed<% } %>
58
-
59
- 4.<% } else { %>3.<% } %> **Start Development Server**
60
- ```bash
61
- npm run dev
62
- ```
63
-
64
- <% if (hasDatabase) { %>5.<% } else { %>4.<% } %> **Production**
65
- ```bash
66
- npm start
67
- ```
68
-
69
- ## Available Scripts
70
-
71
- - `npm run dev` - Start development server with nodemon
72
- - `npm start` - Start production server with clustering
73
- - `npm test` - Run tests with coverage
74
- - `npm run lint` - Run ESLint
75
- - `npm run lint:fix` - Fix ESLint issues automatically
76
- - `npm run format` - Format code with Prettier
77
- - `npm run format:check` - Check code formatting
78
-
79
- ## API Documentation
80
-
81
- Visit `http://localhost:3000/api-docs` for interactive Swagger documentation.
82
-
83
- ## API Endpoints
84
-
85
- <% if (hasDatabase) { %>### Authentication
86
- - `POST /api/auth/register` - Register new user
87
- - `POST /api/auth/login` - User login
88
- - `POST /api/auth/refresh` - Refresh access token
89
- - `POST /api/auth/logout` - User logout
90
-
91
- ### Users
92
- - `GET /api/users/profile` - Get user profile (protected)
93
- - `PUT /api/users/profile` - Update user profile (protected)
94
- - `DELETE /api/users/profile` - Delete user profile (protected)<% } else { %>### Examples
95
- - `GET /api/examples` - Get all examples (with pagination)
96
- - `GET /api/examples/:id` - Get example by ID
97
- - `POST /api/examples` - Create new example
98
- - `PUT /api/examples/:id` - Update example
99
- - `DELETE /api/examples/:id` - Delete example<% } %>
100
-
101
- ### Health Check
102
- - `GET /health` - Application health status
103
-
104
- ## Environment Variables
105
-
106
- | Variable | Description | Default |
107
- |----------|-------------|---------|
108
- | NODE_ENV | Environment mode | development |
109
- | PORT | Server port | 3000 |<% if (hasDatabase) { %>
110
- | JWT_SECRET | JWT signing secret | - |
111
- | JWT_REFRESH_SECRET | Refresh token secret | - |
112
- | JWT_EXPIRE | Access token expiry | 15m |
113
- | JWT_REFRESH_EXPIRE | Refresh token expiry | 7d |
114
- | <%= db === 'mongodb' ? 'MONGO_URI' : 'DATABASE_URL' %> | Database connection | - |<% } %>
115
- | RATE_LIMIT_WINDOW_MS | Rate limit window | 900000 |
116
- | RATE_LIMIT_MAX | Max requests per window | 100 |
117
-
118
- ## Testing
119
-
120
- ```bash
121
- # Run all tests
122
- npm test
123
-
124
- # Run tests with coverage
125
- npm run test
126
-
127
- # Run tests in watch mode
128
- npm run test:watch
129
- ```
130
-
131
- ## Deployment
132
-
133
- ### Docker
134
-
135
- 1. **Build Image**
136
- ```bash
137
- docker build -t <%= projectName %> .
138
- ```
139
-
140
- 2. **Run Container**
141
- ```bash
142
- docker run -p 3000:3000 --env-file .env <%= projectName %>
143
- ```
144
-
145
- 3. **Docker Compose**
146
- ```bash
147
- docker-compose up
148
- ```
149
-
150
- ## Security Features
151
-
152
- - **Helmet**: Sets various HTTP headers for security
153
- - **CORS**: Configurable cross-origin resource sharing
154
- - **Rate Limiting**: Prevents abuse and DDoS attacks<% if (hasDatabase) { %>
155
- - **JWT**: Stateless authentication with refresh tokens
156
- - **Password Hashing**: bcrypt for secure password storage
157
- - **Input Validation**: Request validation middleware<% } %>
158
-
159
- <% if (!hasDatabase) { %>## Extending the Application
160
-
161
- This boilerplate is designed for APIs that don't require database persistence. You can easily:
162
-
163
- - Add database support by integrating MongoDB or PostgreSQL
164
- - Replace in-memory storage with external services (Redis, etc.)
165
- - Add authentication by integrating with OAuth providers
166
- - Build microservices by adding service-to-service communication
167
-
168
- <% } %>## Contributing
169
-
170
- 1. Fork the repository
171
- 2. Create a feature branch
172
- 3. Make your changes
173
- 4. Add tests for new functionality
174
- 5. Ensure all tests pass
175
- 6. Submit a pull request
176
-
177
- ## License
178
-
179
- MIT License - see LICENSE file for details
1
+ # <%= projectName %>
2
+
3
+ A production-grade Express.js application generated by [express-genix](https://www.npmjs.com/package/express-genix).
4
+
5
+ ## Features
6
+
7
+ <% if (isTypescript) { %>- **TypeScript**: Full type safety with TypeScript
8
+ <% } %><% if (hasAuth) { %>- **Authentication**: JWT-based auth with access & refresh tokens, token blacklist logout
9
+ - **User Management**: Registration, login, profile CRUD
10
+ <% } %><% if (hasDatabase) { %>- **Database**: <%= db === 'mongodb' ? 'MongoDB with Mongoose' : (isPrisma ? 'PostgreSQL with Prisma ORM' : 'PostgreSQL with Sequelize') %>
11
+ <% } else { %>- **No Database**: Lightweight API with in-memory storage (easily replaceable)
12
+ <% } %><% if (hasRateLimit) { %>- **Rate Limiting**: Configurable request throttling
13
+ <% } %><% if (hasSwagger) { %>- **API Documentation**: Swagger UI with swagger-jsdoc annotations
14
+ <% } %><% if (hasRequestId) { %>- **Request ID**: Correlation ID tracking per request
15
+ <% } %>- **Security**: Helmet, CORS, input sanitization
16
+ - **Logging**: <%= logger === 'pino' ? 'Pino (fast, structured)' : 'Winston (feature-rich)' %> with Morgan HTTP logger
17
+ - **Testing**: Jest + Supertest with coverage
18
+ - **Code Quality**: ESLint (Airbnb) + Prettier
19
+ <% if (hasDocker) { %>- **Docker**: Multi-stage Dockerfile + docker-compose
20
+ <% } %><% if (hasCicd) { %>- **CI/CD**: GitHub Actions workflow
21
+ <% } %>- **Production**: Clustering, graceful shutdown, environment validation
22
+
23
+ ## Project Structure
24
+
25
+ ```
26
+ <%= projectName %>/
27
+ ├── src/
28
+ │ ├── config/ # Database, Swagger configuration
29
+ │ ├── controllers/ # Route handlers
30
+ │ ├── middleware/ # Auth, validation, error handling<% if (hasDatabase && !isPrisma) { %>
31
+ │ ├── models/ # Database models<% } %>
32
+ ├── routes/ # API route definitions
33
+ ├── services/ # Business logic
34
+ ├── utils/ # Helpers (logger, errors, response, validators)
35
+ ├── app.<%= isTypescript ? 'ts' : 'js' %> # Express app setup
36
+ │ └── server.<%= isTypescript ? 'ts' : 'js' %> # Server + clustering
37
+ ├── tests/ # Test suites<% if (isPrisma) { %>
38
+ ├── prisma/
39
+ │ └── schema.prisma # Prisma schema<% } %><% if (hasCicd) { %>
40
+ ├── .github/workflows/ # CI/CD pipeline<% } %>
41
+ ├── .env # Environment variables (do not commit)
42
+ ├── .env.example # Environment template
43
+ └── package.json
44
+ ```
45
+
46
+ ## Getting Started
47
+
48
+ ### Prerequisites
49
+
50
+ - Node.js >= 18
51
+ - npm >= 9<% if (db === 'mongodb') { %>
52
+ - MongoDB (local or cloud)<% } else if (hasDatabase) { %>
53
+ - PostgreSQL 15+<% } %>
54
+
55
+ ### Installation
56
+
57
+ ```bash
58
+ npm install
59
+ ```
60
+ <% if (isPrisma) { %>
61
+ ### Database Setup
62
+
63
+ ```bash
64
+ # Generate Prisma client
65
+ npx prisma generate
66
+
67
+ # Run migrations
68
+ npx prisma migrate dev --name init
69
+
70
+ # Open Prisma Studio (optional)
71
+ npx prisma studio
72
+ ```
73
+ <% } else if (db === 'mongodb') { %>
74
+ ### Database Setup
75
+
76
+ Ensure MongoDB is running locally or update `MONGO_URI` in `.env`.
77
+ <% } else if (db === 'postgresql') { %>
78
+ ### Database Setup
79
+
80
+ Create a PostgreSQL database and update `DATABASE_URL` in `.env`. The schema syncs automatically in development.
81
+ <% } %>
82
+ ### Environment
83
+
84
+ Copy `.env.example` to `.env` and update values for your environment:
85
+
86
+ ```bash
87
+ cp .env.example .env
88
+ ```
89
+ <% if (hasAuth) { %>
90
+ > **Important**: Change `JWT_SECRET` and `JWT_REFRESH_SECRET` before deploying.
91
+ <% } %>
92
+ ### Development
93
+
94
+ ```bash
95
+ npm run dev
96
+ ```
97
+
98
+ ### Production
99
+
100
+ ```bash
101
+ npm start
102
+ ```
103
+
104
+ ## Available Scripts
105
+
106
+ | Script | Description |
107
+ |--------|-------------|
108
+ | `npm run dev` | Development server with auto-reload |
109
+ | `npm start` | Production server with clustering |
110
+ | `npm test` | Run tests with coverage |
111
+ | `npm run lint` | Check for linting errors |
112
+ | `npm run lint:fix` | Auto-fix linting errors |
113
+ | `npm run format` | Format code with Prettier |
114
+ | `npm run format:check` | Check formatting |<% if (isTypescript) { %>
115
+ | `npm run build` | Compile TypeScript |<% } %><% if (isPrisma) { %>
116
+ | `npx prisma studio` | Open Prisma Studio |
117
+ | `npx prisma migrate dev` | Run database migrations |<% } %>
118
+ <% if (hasSwagger) { %>
119
+ ## API Documentation
120
+
121
+ Interactive docs available at [http://localhost:3000/api-docs](http://localhost:3000/api-docs)
122
+ <% } %>
123
+ ## API Endpoints
124
+
125
+ <% if (hasAuth) { %>### Authentication
126
+
127
+ | Method | Endpoint | Description |
128
+ |--------|----------|-------------|
129
+ | POST | `/api/auth/register` | Register a new user |
130
+ | POST | `/api/auth/login` | Login and receive tokens |
131
+ | POST | `/api/auth/refresh` | Refresh access token |
132
+ | POST | `/api/auth/logout` | Logout (blacklist token) |
133
+
134
+ ### Users (protected)
135
+
136
+ | Method | Endpoint | Description |
137
+ |--------|----------|-------------|
138
+ | GET | `/api/users/profile` | Get current user profile |
139
+ | PUT | `/api/users/profile` | Update profile |
140
+ | DELETE | `/api/users/profile` | Delete account |
141
+ <% } else { %>### Examples
142
+
143
+ | Method | Endpoint | Description |
144
+ |--------|----------|-------------|
145
+ | GET | `/api/examples` | List all (paginated) |
146
+ | GET | `/api/examples/:id` | Get by ID |
147
+ | POST | `/api/examples` | Create |
148
+ | PUT | `/api/examples/:id` | Update |
149
+ | DELETE | `/api/examples/:id` | Delete |
150
+ <% } %>
151
+ ### Health
152
+
153
+ | Method | Endpoint | Description |
154
+ |--------|----------|-------------|
155
+ | GET | `/health` | Health check |
156
+
157
+ ## Environment Variables
158
+
159
+ | Variable | Description | Default |
160
+ |----------|-------------|---------|
161
+ | `NODE_ENV` | Environment | `development` |
162
+ | `PORT` | Server port | `3000` |<% if (hasAuth) { %>
163
+ | `JWT_SECRET` | Access token secret | *(required)* |
164
+ | `JWT_REFRESH_SECRET` | Refresh token secret | *(required)* |
165
+ | `JWT_EXPIRE` | Access token TTL | `15m` |
166
+ | `JWT_REFRESH_EXPIRE` | Refresh token TTL | `7d` |<% } %><% if (db === 'mongodb') { %>
167
+ | `MONGO_URI` | MongoDB connection string | *(required)* |<% } else if (hasDatabase) { %>
168
+ | `DATABASE_URL` | PostgreSQL connection string | *(required)* |<% } %><% if (hasRateLimit) { %>
169
+ | `RATE_LIMIT_WINDOW_MS` | Rate limit window (ms) | `900000` |
170
+ | `RATE_LIMIT_MAX` | Max requests per window | `100` |<% } %>
171
+ <% if (hasDocker) { %>
172
+ ## Docker
173
+
174
+ ```bash
175
+ # Build and run with docker-compose
176
+ docker-compose up --build
177
+
178
+ # Or build manually
179
+ docker build -t <%= projectName %> .
180
+ docker run -p 3000:3000 --env-file .env <%= projectName %>
181
+ ```
182
+ <% } %>
183
+ ## Testing
184
+
185
+ ```bash
186
+ npm test
187
+ ```
188
+
189
+ ## License
190
+
191
+ MIT
@@ -1,65 +1,115 @@
1
- const express = require('express');
2
- const cors = require('cors');
3
- const helmet = require('helmet');
4
- const morgan = require('morgan');
5
- const rateLimit = require('express-rate-limit');
6
- const swaggerUi = require('swagger-ui-express');
7
- const dotenv = require('dotenv');
8
-
9
- const routes = require('./routes');
10
- const errorHandler = require('./middleware/errorHandler');
11
- const swaggerConfig = require('./config/swagger.json');
12
-
13
- // Load environment variables
14
- dotenv.config();
15
-
16
- const app = express();
17
-
18
- // Security middleware
19
- app.use(helmet());
20
- app.use(cors());
21
-
22
- // Logging
23
- app.use(morgan('dev'));
24
-
25
- // Body parsing middleware
26
- app.use(express.json({ limit: '10mb' }));
27
- app.use(express.urlencoded({ extended: true }));
28
-
29
- // Rate limiting
30
- const limiter = rateLimit({
31
- windowMs: 15 * 60 * 1000, // 15 minutes
32
- max: 100, // Limit each IP to 100 requests per windowMs
33
- message: 'Too many requests from this IP, please try again later.',
34
- });
35
- app.use(limiter);
36
-
37
- // Health check endpoint
38
- app.get('/health', (req, res) => {
39
- res.status(200).json({
40
- status: 'OK',
41
- timestamp: new Date().toISOString(),
42
- uptime: process.uptime(),<% if (hasDatabase) { %>
43
- database: '<%= db %>'<% } else { %>
44
- database: 'none'<% } %>,
45
- });
46
- });
47
-
48
- // API documentation
49
- app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerConfig));
50
-
51
- // API routes
52
- app.use('/api', routes);
53
-
54
- // 404 handler
55
- app.use('*', (req, res) => {
56
- res.status(404).json({
57
- error: 'Route not found',
58
- path: req.originalUrl,
59
- });
60
- });
61
-
62
- // Error handling middleware (should be last)
63
- app.use(errorHandler);
64
-
1
+ const express = require('express');
2
+ const cors = require('cors');
3
+ const helmet = require('helmet');
4
+ const morgan = require('morgan');
5
+ <% if (hasRateLimit) { %>const rateLimit = require('express-rate-limit');<% } %>
6
+ <% if (hasSwagger) { %>const swaggerUi = require('swagger-ui-express');
7
+ const swaggerSpec = require('./config/swagger');<% } %>
8
+ <% if (hasRequestId) { %>const { requestId } = require('./middleware/requestId');<% } %>
9
+ const routes = require('./routes');
10
+ const errorHandler = require('./middleware/errorHandler');
11
+ <% if (hasDatabase || hasAuth) { %>const { validateEnv } = require('./utils/envValidator');
12
+
13
+ validateEnv();<% } %>
14
+
15
+ const app = express();
16
+
17
+ // Security middleware
18
+ app.use(helmet());
19
+ app.use(cors({
20
+ origin: process.env.CORS_ORIGIN || '*',
21
+ methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
22
+ allowedHeaders: ['Content-Type', 'Authorization'],
23
+ }));
24
+ <% if (hasRequestId) { %>
25
+ // Request ID tracking
26
+ app.use(requestId);<% } %>
27
+
28
+ // Logging
29
+ app.use(morgan(process.env.NODE_ENV === 'production' ? 'combined' : 'dev'));
30
+
31
+ // Body parsing
32
+ app.use(express.json({ limit: '10mb' }));
33
+ app.use(express.urlencoded({ extended: true }));
34
+ <% if (hasRateLimit) { %>
35
+ // Rate limiting
36
+ const limiter = rateLimit({
37
+ windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS, 10) || 15 * 60 * 1000,
38
+ max: parseInt(process.env.RATE_LIMIT_MAX, 10) || 100,
39
+ standardHeaders: true,
40
+ legacyHeaders: false,
41
+ message: { success: false, error: 'Too many requests, please try again later.' },
42
+ });
43
+ app.use(limiter);<% } %>
44
+
45
+ // Health check
46
+ app.get('/health', async (req, res) => {
47
+ const health = {
48
+ status: 'OK',
49
+ timestamp: new Date().toISOString(),
50
+ uptime: process.uptime(),
51
+ memoryUsage: Math.round(process.memoryUsage().rss / 1024 / 1024) + ' MB',
52
+ };
53
+
54
+ const checks = {};
55
+ <% if (db === 'mongodb') { %>
56
+ try {
57
+ const mongoose = require('mongoose');
58
+ checks.database = mongoose.connection.readyState === 1 ? 'connected' : 'disconnected';
59
+ } catch {
60
+ checks.database = 'error';
61
+ }
62
+ <% } else if (db === 'postgresql') { %>
63
+ try {
64
+ const { sequelize } = require('./models');
65
+ await sequelize.authenticate();
66
+ checks.database = 'connected';
67
+ } catch {
68
+ checks.database = 'disconnected';
69
+ }
70
+ <% } else if (isPrisma) { %>
71
+ try {
72
+ const { prisma } = require('./config/database');
73
+ await prisma.$queryRaw\`SELECT 1\`;
74
+ checks.database = 'connected';
75
+ } catch {
76
+ checks.database = 'disconnected';
77
+ }
78
+ <% } %><% if (hasRedis) { %>
79
+ try {
80
+ const { redis } = require('./config/redis');
81
+ await redis.ping();
82
+ checks.redis = 'connected';
83
+ } catch {
84
+ checks.redis = 'disconnected';
85
+ }
86
+ <% } %>
87
+ const allHealthy = Object.values(checks).every((v) => v === 'connected');
88
+ const statusCode = Object.keys(checks).length === 0 || allHealthy ? 200 : 503;
89
+ health.status = statusCode === 200 ? 'OK' : 'DEGRADED';
90
+ health.checks = checks;
91
+
92
+ res.status(statusCode).json({ success: statusCode === 200, data: health });
93
+ });
94
+ <% if (hasSwagger) { %>
95
+ // API documentation
96
+ app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec, {
97
+ customCss: '.swagger-ui .topbar { display: none }',
98
+ }));<% } %>
99
+
100
+ // API routes
101
+ app.use('/api', routes);
102
+
103
+ // 404 handler
104
+ app.use('*', (req, res) => {
105
+ res.status(404).json({
106
+ success: false,
107
+ error: 'Route not found',
108
+ path: req.originalUrl,
109
+ });
110
+ });
111
+
112
+ // Error handler (must be last)
113
+ app.use(errorHandler);
114
+
65
115
  module.exports = app;