@naman_deep_singh/server-utils 1.0.7 → 1.1.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.
- package/README.md +147 -7
- package/dist/{index.d.ts → cjs/index.d.ts} +2 -3
- package/dist/{index.js → cjs/index.js} +1 -3
- package/dist/{middleware.js → cjs/middleware.js} +37 -10
- package/dist/{periodic-health.d.ts → cjs/periodic-health.d.ts} +0 -1
- package/dist/{periodic-health.js → cjs/periodic-health.js} +0 -4
- package/dist/{server.js → cjs/server.js} +1 -1
- package/dist/{utils.js → cjs/utils.js} +14 -8
- package/dist/esm/health.d.ts +5 -0
- package/dist/esm/health.js +40 -0
- package/dist/esm/index.d.ts +46 -0
- package/dist/esm/index.js +58 -0
- package/dist/esm/middleware.d.ts +37 -0
- package/dist/esm/middleware.js +229 -0
- package/dist/esm/periodic-health.d.ts +11 -0
- package/dist/esm/periodic-health.js +64 -0
- package/dist/esm/server.d.ts +69 -0
- package/dist/esm/server.js +271 -0
- package/dist/esm/shutdown.d.ts +5 -0
- package/dist/esm/shutdown.js +52 -0
- package/dist/esm/types.d.ts +70 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/utils.d.ts +3 -0
- package/dist/esm/utils.js +38 -0
- package/dist/types/health.d.ts +5 -0
- package/dist/types/index.d.ts +46 -0
- package/dist/types/middleware.d.ts +37 -0
- package/dist/types/periodic-health.d.ts +11 -0
- package/dist/types/server.d.ts +69 -0
- package/dist/types/shutdown.d.ts +5 -0
- package/dist/types/types.d.ts +70 -0
- package/dist/types/utils.d.ts +3 -0
- package/package.json +22 -7
- package/src/health.ts +0 -47
- package/src/index.ts +0 -127
- package/src/middleware.ts +0 -275
- package/src/periodic-health.ts +0 -87
- package/src/server.ts +0 -412
- package/src/shutdown.ts +0 -69
- package/src/types.ts +0 -80
- package/src/utils.ts +0 -34
- package/tsconfig.json +0 -21
- /package/dist/{health.d.ts → cjs/health.d.ts} +0 -0
- /package/dist/{health.js → cjs/health.js} +0 -0
- /package/dist/{middleware.d.ts → cjs/middleware.d.ts} +0 -0
- /package/dist/{server.d.ts → cjs/server.d.ts} +0 -0
- /package/dist/{shutdown.d.ts → cjs/shutdown.d.ts} +0 -0
- /package/dist/{shutdown.js → cjs/shutdown.js} +0 -0
- /package/dist/{types.d.ts → cjs/types.d.ts} +0 -0
- /package/dist/{types.js → cjs/types.js} +0 -0
- /package/dist/{utils.d.ts → cjs/utils.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @naman_deep_singh/server-utils
|
|
2
2
|
|
|
3
|
+
**Version:** 1.1.0
|
|
4
|
+
|
|
3
5
|
Extensible server utilities for Express.js microservices with multi-protocol support and TypeScript.
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
@@ -180,9 +182,24 @@ server.app.use('/protected', requireAuth({
|
|
|
180
182
|
|
|
181
183
|
## Health Checks
|
|
182
184
|
|
|
185
|
+
### Basic Health Check
|
|
183
186
|
```typescript
|
|
184
|
-
import { addHealthCheck } from '@naman_deep_singh/server-utils';
|
|
187
|
+
import { addHealthCheck, createHealthCheck, withHealthCheck } from '@naman_deep_singh/server-utils';
|
|
188
|
+
|
|
189
|
+
// Method 1: Direct addition
|
|
190
|
+
addHealthCheck(server.app, '/health');
|
|
191
|
+
|
|
192
|
+
// Method 2: As middleware
|
|
193
|
+
server.app.get('/health', createHealthCheck());
|
|
194
|
+
|
|
195
|
+
// Method 3: As plugin
|
|
196
|
+
const server = createServerWithPlugins('My API', '1.0.0', [
|
|
197
|
+
withHealthCheck('/health')
|
|
198
|
+
]);
|
|
199
|
+
```
|
|
185
200
|
|
|
201
|
+
### Advanced Health Checks
|
|
202
|
+
```typescript
|
|
186
203
|
addHealthCheck(server.app, '/health', {
|
|
187
204
|
customChecks: [
|
|
188
205
|
{
|
|
@@ -200,6 +217,17 @@ addHealthCheck(server.app, '/health', {
|
|
|
200
217
|
}
|
|
201
218
|
]
|
|
202
219
|
});
|
|
220
|
+
|
|
221
|
+
// Response format:
|
|
222
|
+
// {
|
|
223
|
+
// "status": "healthy",
|
|
224
|
+
// "checks": {
|
|
225
|
+
// "server": true,
|
|
226
|
+
// "timestamp": 1640995200000,
|
|
227
|
+
// "database": true,
|
|
228
|
+
// "redis": false
|
|
229
|
+
// }
|
|
230
|
+
// }
|
|
203
231
|
```
|
|
204
232
|
|
|
205
233
|
## Server Management
|
|
@@ -246,12 +274,78 @@ interface ServerConfig {
|
|
|
246
274
|
}
|
|
247
275
|
```
|
|
248
276
|
|
|
277
|
+
## Environment Utilities
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
import { getEnv, getEnvNumber, getEnvBoolean } from '@naman_deep_singh/server-utils';
|
|
281
|
+
|
|
282
|
+
// Get string environment variable
|
|
283
|
+
const dbUrl = getEnv('DATABASE_URL'); // Throws if missing
|
|
284
|
+
const dbUrl = getEnv('DATABASE_URL', 'localhost'); // With default
|
|
285
|
+
|
|
286
|
+
// Get number environment variable
|
|
287
|
+
const port = getEnvNumber('PORT', 3000);
|
|
288
|
+
const maxConnections = getEnvNumber('MAX_CONNECTIONS'); // Throws if missing
|
|
289
|
+
|
|
290
|
+
// Get boolean environment variable
|
|
291
|
+
const enableLogging = getEnvBoolean('ENABLE_LOGGING', true);
|
|
292
|
+
const isProduction = getEnvBoolean('NODE_ENV'); // Must be 'true' or 'false'
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Periodic Health Monitoring
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
import { PeriodicHealthMonitor } from '@naman_deep_singh/server-utils';
|
|
299
|
+
|
|
300
|
+
const server = createServer('My API', '1.0.0', {
|
|
301
|
+
periodicHealthCheck: {
|
|
302
|
+
enabled: true,
|
|
303
|
+
interval: 30000, // 30 seconds
|
|
304
|
+
services: [
|
|
305
|
+
{
|
|
306
|
+
name: 'database',
|
|
307
|
+
url: 'http://localhost:5432/health',
|
|
308
|
+
timeout: 5000
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: 'redis',
|
|
312
|
+
url: 'http://localhost:6379/ping'
|
|
313
|
+
}
|
|
314
|
+
]
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// Manual health check
|
|
319
|
+
const monitor = new PeriodicHealthMonitor(config, 'My Service');
|
|
320
|
+
monitor.start();
|
|
321
|
+
const status = await monitor.getHealthStatus();
|
|
322
|
+
console.log(status); // { database: true, redis: false }
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Express Re-exports
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
// Import Express types and classes directly from server-utils
|
|
329
|
+
import { Request, Response, NextFunction, Router, Application } from '@naman_deep_singh/server-utils';
|
|
330
|
+
import type { RequestHandler, ErrorRequestHandler } from '@naman_deep_singh/server-utils';
|
|
331
|
+
|
|
332
|
+
// No need to install Express separately in your services
|
|
333
|
+
```
|
|
334
|
+
|
|
249
335
|
## API Reference
|
|
250
336
|
|
|
251
337
|
### Core Functions
|
|
252
338
|
- `createServer(name?, version?, config?)` - Create server instance
|
|
253
339
|
- `ExpressServer` - Server class for advanced usage
|
|
254
340
|
|
|
341
|
+
### Environment Utilities
|
|
342
|
+
- `getEnv(key, defaultValue?)` - Get string environment variable
|
|
343
|
+
- `getEnvNumber(key, defaultValue?)` - Get number environment variable
|
|
344
|
+
- `getEnvBoolean(key, defaultValue?)` - Get boolean environment variable
|
|
345
|
+
|
|
346
|
+
### Health Monitoring
|
|
347
|
+
- `PeriodicHealthMonitor` - Automated service health checking
|
|
348
|
+
|
|
255
349
|
### Middleware Functions
|
|
256
350
|
- `createLoggingMiddleware(format?)` - Request logging
|
|
257
351
|
- `createErrorHandler()` - Error handling
|
|
@@ -260,8 +354,10 @@ interface ServerConfig {
|
|
|
260
354
|
- `createAuthMiddleware(config)` - Authentication
|
|
261
355
|
|
|
262
356
|
### Health & Monitoring
|
|
263
|
-
- `createHealthCheck(config?)` -
|
|
357
|
+
- `createHealthCheck(config?)` - Create health check middleware
|
|
358
|
+
- `withHealthCheck(path?, config?)` - Health check plugin
|
|
264
359
|
- `addHealthCheck(app, path?, config?)` - Add health check to app
|
|
360
|
+
- `PeriodicHealthMonitor` - Automated service health checking
|
|
265
361
|
|
|
266
362
|
### Graceful Shutdown
|
|
267
363
|
- `createGracefulShutdown(server, config?)` - Setup graceful shutdown
|
|
@@ -270,12 +366,56 @@ interface ServerConfig {
|
|
|
270
366
|
## Dependencies
|
|
271
367
|
|
|
272
368
|
### Required
|
|
273
|
-
- **express** - Web framework
|
|
274
|
-
- **cors** - CORS middleware
|
|
275
|
-
- **helmet** - Security middleware
|
|
276
|
-
- **cookie-parser** - Cookie parsing
|
|
369
|
+
- **express** - Web framework (v5.1.0+)
|
|
277
370
|
|
|
278
371
|
### Optional (for specific features)
|
|
372
|
+
- **cors** - CORS middleware (if using CORS)
|
|
373
|
+
- **helmet** - Security middleware (if using Helmet)
|
|
374
|
+
- **cookie-parser** - Cookie parsing (if using cookies)
|
|
279
375
|
- **@grpc/grpc-js** - For gRPC support
|
|
280
376
|
- **jayson** - For JSON-RPC support
|
|
281
|
-
- **socket.io** - For WebSocket support
|
|
377
|
+
- **socket.io** - For WebSocket support
|
|
378
|
+
|
|
379
|
+
## Response Format
|
|
380
|
+
|
|
381
|
+
All middleware responses follow the consistent format:
|
|
382
|
+
|
|
383
|
+
```json
|
|
384
|
+
{
|
|
385
|
+
"success": true/false,
|
|
386
|
+
"message": "Operation message",
|
|
387
|
+
"data": {...} | undefined,
|
|
388
|
+
"error": {
|
|
389
|
+
"message": "Error message",
|
|
390
|
+
"details": {...}
|
|
391
|
+
} | null,
|
|
392
|
+
"meta": {...} | null
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Integration with @naman_deep_singh/response-utils
|
|
397
|
+
|
|
398
|
+
For advanced error handling, use with `@naman_deep_singh/errors-utils`:
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
import { expressErrorHandler } from '@naman_deep_singh/errors-utils';
|
|
402
|
+
|
|
403
|
+
// Replace basic error handler with advanced one
|
|
404
|
+
server.app.use(expressErrorHandler);
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Integration with @naman_deep_singh/response-utils
|
|
408
|
+
|
|
409
|
+
For consistent API responses, use with `@naman_deep_singh/response-utils`:
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
import { responderMiddleware } from '@naman_deep_singh/response-utils';
|
|
413
|
+
|
|
414
|
+
server.app.use(responderMiddleware());
|
|
415
|
+
|
|
416
|
+
// Now use responder in routes
|
|
417
|
+
server.app.get('/users', (req, res) => {
|
|
418
|
+
const responder = (res as any).responder();
|
|
419
|
+
return responder.okAndSend({ users: [] });
|
|
420
|
+
});
|
|
421
|
+
```
|
|
@@ -6,14 +6,14 @@ export { createHealthCheck, withHealthCheck, addHealthCheck } from './health';
|
|
|
6
6
|
export { createGracefulShutdown, withGracefulShutdown, startServerWithShutdown } from './shutdown';
|
|
7
7
|
export { createLoggingMiddleware, createErrorHandler, createRequestIdMiddleware, createValidationMiddleware, createRateLimitMiddleware, createAuthMiddleware, withLogging, withErrorHandler, withRequestId, withValidation, withRateLimit, withAuth, validateFields, rateLimit, requireAuth, type ValidationRule, type RateLimitConfig, type AuthConfig } from './middleware';
|
|
8
8
|
export { getEnv, getEnvNumber, getEnvBoolean } from './utils';
|
|
9
|
-
export { PeriodicHealthMonitor
|
|
9
|
+
export { PeriodicHealthMonitor } from './periodic-health';
|
|
10
10
|
export type { ServerConfig, HealthCheckConfig, HealthCheck, GracefulShutdownConfig, ServerPlugin, SocketIOConfig, SocketInstance, PeriodicHealthCheckConfig, HealthCheckService } from './types';
|
|
11
11
|
import { ExpressServer, createServer } from './server';
|
|
12
12
|
import { createHealthCheck, withHealthCheck, addHealthCheck } from './health';
|
|
13
13
|
import { createGracefulShutdown, withGracefulShutdown, startServerWithShutdown } from './shutdown';
|
|
14
14
|
import { createLoggingMiddleware, createErrorHandler, createRequestIdMiddleware, createValidationMiddleware, createRateLimitMiddleware, createAuthMiddleware, withLogging, withErrorHandler, withRequestId, withValidation, withRateLimit, withAuth, validateFields, rateLimit, requireAuth } from './middleware';
|
|
15
15
|
import { getEnv, getEnvNumber, getEnvBoolean } from './utils';
|
|
16
|
-
import { PeriodicHealthMonitor
|
|
16
|
+
import { PeriodicHealthMonitor } from './periodic-health';
|
|
17
17
|
declare const ServerUtils: {
|
|
18
18
|
createServer: typeof createServer;
|
|
19
19
|
ExpressServer: typeof ExpressServer;
|
|
@@ -42,6 +42,5 @@ declare const ServerUtils: {
|
|
|
42
42
|
getEnvNumber: typeof getEnvNumber;
|
|
43
43
|
getEnvBoolean: typeof getEnvBoolean;
|
|
44
44
|
PeriodicHealthMonitor: typeof PeriodicHealthMonitor;
|
|
45
|
-
createPeriodicHealthMonitor: typeof createPeriodicHealthMonitor;
|
|
46
45
|
};
|
|
47
46
|
export default ServerUtils;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.PeriodicHealthMonitor = exports.getEnvBoolean = exports.getEnvNumber = exports.getEnv = exports.requireAuth = exports.rateLimit = exports.validateFields = exports.withAuth = exports.withRateLimit = exports.withValidation = exports.withRequestId = exports.withErrorHandler = exports.withLogging = exports.createAuthMiddleware = exports.createRateLimitMiddleware = exports.createValidationMiddleware = exports.createRequestIdMiddleware = exports.createErrorHandler = exports.createLoggingMiddleware = exports.startServerWithShutdown = exports.withGracefulShutdown = exports.createGracefulShutdown = exports.addHealthCheck = exports.withHealthCheck = exports.createHealthCheck = exports.Router = exports.createServer = exports.ExpressServer = void 0;
|
|
4
4
|
// Core server utilities
|
|
5
5
|
var server_1 = require("./server");
|
|
6
6
|
Object.defineProperty(exports, "ExpressServer", { enumerable: true, get: function () { return server_1.ExpressServer; } });
|
|
@@ -43,7 +43,6 @@ Object.defineProperty(exports, "getEnvBoolean", { enumerable: true, get: functio
|
|
|
43
43
|
// Periodic health monitoring
|
|
44
44
|
var periodic_health_1 = require("./periodic-health");
|
|
45
45
|
Object.defineProperty(exports, "PeriodicHealthMonitor", { enumerable: true, get: function () { return periodic_health_1.PeriodicHealthMonitor; } });
|
|
46
|
-
Object.defineProperty(exports, "createPeriodicHealthMonitor", { enumerable: true, get: function () { return periodic_health_1.createPeriodicHealthMonitor; } });
|
|
47
46
|
// Import all exports for default export
|
|
48
47
|
const server_2 = require("./server");
|
|
49
48
|
const health_2 = require("./health");
|
|
@@ -86,6 +85,5 @@ const ServerUtils = {
|
|
|
86
85
|
getEnvBoolean: utils_2.getEnvBoolean,
|
|
87
86
|
// Periodic Health Monitoring
|
|
88
87
|
PeriodicHealthMonitor: periodic_health_2.PeriodicHealthMonitor,
|
|
89
|
-
createPeriodicHealthMonitor: periodic_health_2.createPeriodicHealthMonitor
|
|
90
88
|
};
|
|
91
89
|
exports.default = ServerUtils;
|
|
@@ -45,9 +45,14 @@ function createErrorHandler() {
|
|
|
45
45
|
? 'Internal Server Error'
|
|
46
46
|
: errorObj.message || 'Unknown error';
|
|
47
47
|
res.status(status).json({
|
|
48
|
-
|
|
48
|
+
success: false,
|
|
49
49
|
message,
|
|
50
|
-
|
|
50
|
+
data: undefined,
|
|
51
|
+
error: {
|
|
52
|
+
message,
|
|
53
|
+
...(process.env.NODE_ENV !== 'production' && { details: { stack: errorObj.stack } })
|
|
54
|
+
},
|
|
55
|
+
meta: null
|
|
51
56
|
});
|
|
52
57
|
};
|
|
53
58
|
}
|
|
@@ -114,9 +119,14 @@ function createValidationMiddleware(rules) {
|
|
|
114
119
|
}
|
|
115
120
|
if (errors.length > 0) {
|
|
116
121
|
return res.status(400).json({
|
|
117
|
-
|
|
122
|
+
success: false,
|
|
118
123
|
message: 'Validation failed',
|
|
119
|
-
|
|
124
|
+
data: undefined,
|
|
125
|
+
error: {
|
|
126
|
+
message: 'Validation failed',
|
|
127
|
+
details: errors
|
|
128
|
+
},
|
|
129
|
+
meta: null
|
|
120
130
|
});
|
|
121
131
|
}
|
|
122
132
|
next();
|
|
@@ -138,9 +148,16 @@ function createRateLimitMiddleware(config = {}) {
|
|
|
138
148
|
}
|
|
139
149
|
if (record.count >= maxRequests) {
|
|
140
150
|
return res.status(429).json({
|
|
141
|
-
|
|
151
|
+
success: false,
|
|
142
152
|
message,
|
|
143
|
-
|
|
153
|
+
data: undefined,
|
|
154
|
+
error: {
|
|
155
|
+
message,
|
|
156
|
+
details: {
|
|
157
|
+
retryAfter: Math.ceil((record.resetTime - now) / 1000)
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
meta: null
|
|
144
161
|
});
|
|
145
162
|
}
|
|
146
163
|
record.count++;
|
|
@@ -160,8 +177,13 @@ function createAuthMiddleware(config) {
|
|
|
160
177
|
const token = tokenExtractor(req);
|
|
161
178
|
if (!token) {
|
|
162
179
|
return res.status(401).json({
|
|
163
|
-
|
|
164
|
-
message: unauthorizedMessage
|
|
180
|
+
success: false,
|
|
181
|
+
message: unauthorizedMessage,
|
|
182
|
+
data: undefined,
|
|
183
|
+
error: {
|
|
184
|
+
message: unauthorizedMessage
|
|
185
|
+
},
|
|
186
|
+
meta: null
|
|
165
187
|
});
|
|
166
188
|
}
|
|
167
189
|
const user = await tokenValidator(token);
|
|
@@ -170,8 +192,13 @@ function createAuthMiddleware(config) {
|
|
|
170
192
|
}
|
|
171
193
|
catch (error) {
|
|
172
194
|
return res.status(401).json({
|
|
173
|
-
|
|
174
|
-
message: unauthorizedMessage
|
|
195
|
+
success: false,
|
|
196
|
+
message: unauthorizedMessage,
|
|
197
|
+
data: undefined,
|
|
198
|
+
error: {
|
|
199
|
+
message: unauthorizedMessage
|
|
200
|
+
},
|
|
201
|
+
meta: null
|
|
175
202
|
});
|
|
176
203
|
}
|
|
177
204
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PeriodicHealthMonitor = void 0;
|
|
4
|
-
exports.createPeriodicHealthMonitor = createPeriodicHealthMonitor;
|
|
5
4
|
class PeriodicHealthMonitor {
|
|
6
5
|
constructor(config, serviceName) {
|
|
7
6
|
this.intervals = [];
|
|
@@ -67,6 +66,3 @@ class PeriodicHealthMonitor {
|
|
|
67
66
|
}
|
|
68
67
|
}
|
|
69
68
|
exports.PeriodicHealthMonitor = PeriodicHealthMonitor;
|
|
70
|
-
function createPeriodicHealthMonitor(config, serviceName) {
|
|
71
|
-
return new PeriodicHealthMonitor(config, serviceName);
|
|
72
|
-
}
|
|
@@ -93,7 +93,7 @@ class ExpressServer {
|
|
|
93
93
|
}
|
|
94
94
|
setupPeriodicHealthMonitoring() {
|
|
95
95
|
if (this.config.periodicHealthCheck?.enabled) {
|
|
96
|
-
this.healthMonitor =
|
|
96
|
+
this.healthMonitor = new periodic_health_1.PeriodicHealthMonitor(this.config.periodicHealthCheck, this.config.name);
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
async start() {
|
|
@@ -3,13 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getEnv = getEnv;
|
|
4
4
|
exports.getEnvNumber = getEnvNumber;
|
|
5
5
|
exports.getEnvBoolean = getEnvBoolean;
|
|
6
|
-
// Environment utilities
|
|
7
6
|
function getEnv(key, defaultValue) {
|
|
8
7
|
const value = process.env[key];
|
|
9
|
-
if (value === undefined
|
|
10
|
-
|
|
8
|
+
if (value === undefined) {
|
|
9
|
+
if (defaultValue === undefined) {
|
|
10
|
+
throw new Error(`Environment variable ${key} is required`);
|
|
11
|
+
}
|
|
12
|
+
return defaultValue;
|
|
11
13
|
}
|
|
12
|
-
return value
|
|
14
|
+
return value; // empty string allowed
|
|
13
15
|
}
|
|
14
16
|
function getEnvNumber(key, defaultValue) {
|
|
15
17
|
const value = process.env[key];
|
|
@@ -19,9 +21,9 @@ function getEnvNumber(key, defaultValue) {
|
|
|
19
21
|
}
|
|
20
22
|
return defaultValue;
|
|
21
23
|
}
|
|
22
|
-
const parsed =
|
|
23
|
-
if (isNaN(parsed)) {
|
|
24
|
-
throw new Error(`Environment variable ${key} must be a number`);
|
|
24
|
+
const parsed = Number(value);
|
|
25
|
+
if (Number.isNaN(parsed)) {
|
|
26
|
+
throw new Error(`Environment variable ${key} must be a valid number`);
|
|
25
27
|
}
|
|
26
28
|
return parsed;
|
|
27
29
|
}
|
|
@@ -33,5 +35,9 @@ function getEnvBoolean(key, defaultValue) {
|
|
|
33
35
|
}
|
|
34
36
|
return defaultValue;
|
|
35
37
|
}
|
|
36
|
-
|
|
38
|
+
const normalized = value.toLowerCase();
|
|
39
|
+
if (normalized !== "true" && normalized !== "false") {
|
|
40
|
+
throw new Error(`Environment variable ${key} must be 'true' or 'false'`);
|
|
41
|
+
}
|
|
42
|
+
return normalized === "true";
|
|
37
43
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { HealthCheckConfig, ServerPlugin } from './types';
|
|
3
|
+
export declare function createHealthCheck(config?: HealthCheckConfig): express.RequestHandler;
|
|
4
|
+
export declare function withHealthCheck(path?: string, config?: HealthCheckConfig): ServerPlugin;
|
|
5
|
+
export declare function addHealthCheck(app: express.Application, path?: string, config?: HealthCheckConfig): void;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export function createHealthCheck(config = {}) {
|
|
2
|
+
const { customChecks = [] } = config;
|
|
3
|
+
return async (req, res) => {
|
|
4
|
+
try {
|
|
5
|
+
const checks = {
|
|
6
|
+
server: true,
|
|
7
|
+
timestamp: Date.now()
|
|
8
|
+
};
|
|
9
|
+
// Run custom health checks
|
|
10
|
+
for (const check of customChecks) {
|
|
11
|
+
try {
|
|
12
|
+
checks[check.name] = await check.check();
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
checks[check.name] = false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const isHealthy = Object.values(checks).every(status => status === true || typeof status === 'number');
|
|
19
|
+
res.status(isHealthy ? 200 : 503).json({
|
|
20
|
+
status: isHealthy ? 'healthy' : 'unhealthy',
|
|
21
|
+
checks
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
res.status(503).json({
|
|
26
|
+
status: 'unhealthy',
|
|
27
|
+
error: 'Health check failed'
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function withHealthCheck(path = '/health', config = {}) {
|
|
33
|
+
return (app) => {
|
|
34
|
+
app.get(path, createHealthCheck(config));
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// Convenience function for direct use
|
|
38
|
+
export function addHealthCheck(app, path = '/health', config = {}) {
|
|
39
|
+
app.get(path, createHealthCheck(config));
|
|
40
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export { ExpressServer, createServer } from './server';
|
|
2
|
+
export type { ServerInstance, ServerInfo, GrpcService, RpcMethod, WebhookConfig } from './server';
|
|
3
|
+
export { Request, Response, NextFunction, Router, Application } from 'express';
|
|
4
|
+
export type { RequestHandler, ErrorRequestHandler } from 'express';
|
|
5
|
+
export { createHealthCheck, withHealthCheck, addHealthCheck } from './health';
|
|
6
|
+
export { createGracefulShutdown, withGracefulShutdown, startServerWithShutdown } from './shutdown';
|
|
7
|
+
export { createLoggingMiddleware, createErrorHandler, createRequestIdMiddleware, createValidationMiddleware, createRateLimitMiddleware, createAuthMiddleware, withLogging, withErrorHandler, withRequestId, withValidation, withRateLimit, withAuth, validateFields, rateLimit, requireAuth, type ValidationRule, type RateLimitConfig, type AuthConfig } from './middleware';
|
|
8
|
+
export { getEnv, getEnvNumber, getEnvBoolean } from './utils';
|
|
9
|
+
export { PeriodicHealthMonitor } from './periodic-health';
|
|
10
|
+
export type { ServerConfig, HealthCheckConfig, HealthCheck, GracefulShutdownConfig, ServerPlugin, SocketIOConfig, SocketInstance, PeriodicHealthCheckConfig, HealthCheckService } from './types';
|
|
11
|
+
import { ExpressServer, createServer } from './server';
|
|
12
|
+
import { createHealthCheck, withHealthCheck, addHealthCheck } from './health';
|
|
13
|
+
import { createGracefulShutdown, withGracefulShutdown, startServerWithShutdown } from './shutdown';
|
|
14
|
+
import { createLoggingMiddleware, createErrorHandler, createRequestIdMiddleware, createValidationMiddleware, createRateLimitMiddleware, createAuthMiddleware, withLogging, withErrorHandler, withRequestId, withValidation, withRateLimit, withAuth, validateFields, rateLimit, requireAuth } from './middleware';
|
|
15
|
+
import { getEnv, getEnvNumber, getEnvBoolean } from './utils';
|
|
16
|
+
import { PeriodicHealthMonitor } from './periodic-health';
|
|
17
|
+
declare const ServerUtils: {
|
|
18
|
+
createServer: typeof createServer;
|
|
19
|
+
ExpressServer: typeof ExpressServer;
|
|
20
|
+
createHealthCheck: typeof createHealthCheck;
|
|
21
|
+
withHealthCheck: typeof withHealthCheck;
|
|
22
|
+
addHealthCheck: typeof addHealthCheck;
|
|
23
|
+
createGracefulShutdown: typeof createGracefulShutdown;
|
|
24
|
+
withGracefulShutdown: typeof withGracefulShutdown;
|
|
25
|
+
startServerWithShutdown: typeof startServerWithShutdown;
|
|
26
|
+
createLoggingMiddleware: typeof createLoggingMiddleware;
|
|
27
|
+
createErrorHandler: typeof createErrorHandler;
|
|
28
|
+
createRequestIdMiddleware: typeof createRequestIdMiddleware;
|
|
29
|
+
createValidationMiddleware: typeof createValidationMiddleware;
|
|
30
|
+
createRateLimitMiddleware: typeof createRateLimitMiddleware;
|
|
31
|
+
createAuthMiddleware: typeof createAuthMiddleware;
|
|
32
|
+
withLogging: typeof withLogging;
|
|
33
|
+
withErrorHandler: typeof withErrorHandler;
|
|
34
|
+
withRequestId: typeof withRequestId;
|
|
35
|
+
withValidation: typeof withValidation;
|
|
36
|
+
withRateLimit: typeof withRateLimit;
|
|
37
|
+
withAuth: typeof withAuth;
|
|
38
|
+
validateFields: typeof validateFields;
|
|
39
|
+
rateLimit: typeof rateLimit;
|
|
40
|
+
requireAuth: typeof requireAuth;
|
|
41
|
+
getEnv: typeof getEnv;
|
|
42
|
+
getEnvNumber: typeof getEnvNumber;
|
|
43
|
+
getEnvBoolean: typeof getEnvBoolean;
|
|
44
|
+
PeriodicHealthMonitor: typeof PeriodicHealthMonitor;
|
|
45
|
+
};
|
|
46
|
+
export default ServerUtils;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Core server utilities
|
|
2
|
+
export { ExpressServer, createServer } from './server';
|
|
3
|
+
// Express re-exports (to avoid direct Express dependency in services)
|
|
4
|
+
export { Router } from 'express';
|
|
5
|
+
// Health check utilities
|
|
6
|
+
export { createHealthCheck, withHealthCheck, addHealthCheck } from './health';
|
|
7
|
+
// Graceful shutdown utilities
|
|
8
|
+
export { createGracefulShutdown, withGracefulShutdown, startServerWithShutdown } from './shutdown';
|
|
9
|
+
// Middleware utilities
|
|
10
|
+
export { createLoggingMiddleware, createErrorHandler, createRequestIdMiddleware, createValidationMiddleware, createRateLimitMiddleware, createAuthMiddleware, withLogging, withErrorHandler, withRequestId, withValidation, withRateLimit, withAuth, validateFields, rateLimit, requireAuth } from './middleware';
|
|
11
|
+
// Utility functions
|
|
12
|
+
export { getEnv, getEnvNumber, getEnvBoolean } from './utils';
|
|
13
|
+
// Periodic health monitoring
|
|
14
|
+
export { PeriodicHealthMonitor } from './periodic-health';
|
|
15
|
+
// Import all exports for default export
|
|
16
|
+
import { ExpressServer, createServer } from './server';
|
|
17
|
+
import { createHealthCheck, withHealthCheck, addHealthCheck } from './health';
|
|
18
|
+
import { createGracefulShutdown, withGracefulShutdown, startServerWithShutdown } from './shutdown';
|
|
19
|
+
import { createLoggingMiddleware, createErrorHandler, createRequestIdMiddleware, createValidationMiddleware, createRateLimitMiddleware, createAuthMiddleware, withLogging, withErrorHandler, withRequestId, withValidation, withRateLimit, withAuth, validateFields, rateLimit, requireAuth } from './middleware';
|
|
20
|
+
import { getEnv, getEnvNumber, getEnvBoolean } from './utils';
|
|
21
|
+
import { PeriodicHealthMonitor } from './periodic-health';
|
|
22
|
+
// Default export for namespace usage
|
|
23
|
+
const ServerUtils = {
|
|
24
|
+
// Server creation
|
|
25
|
+
createServer,
|
|
26
|
+
ExpressServer,
|
|
27
|
+
// Health checks
|
|
28
|
+
createHealthCheck,
|
|
29
|
+
withHealthCheck,
|
|
30
|
+
addHealthCheck,
|
|
31
|
+
// Graceful shutdown
|
|
32
|
+
createGracefulShutdown,
|
|
33
|
+
withGracefulShutdown,
|
|
34
|
+
startServerWithShutdown,
|
|
35
|
+
// Middleware
|
|
36
|
+
createLoggingMiddleware,
|
|
37
|
+
createErrorHandler,
|
|
38
|
+
createRequestIdMiddleware,
|
|
39
|
+
createValidationMiddleware,
|
|
40
|
+
createRateLimitMiddleware,
|
|
41
|
+
createAuthMiddleware,
|
|
42
|
+
withLogging,
|
|
43
|
+
withErrorHandler,
|
|
44
|
+
withRequestId,
|
|
45
|
+
withValidation,
|
|
46
|
+
withRateLimit,
|
|
47
|
+
withAuth,
|
|
48
|
+
validateFields,
|
|
49
|
+
rateLimit,
|
|
50
|
+
requireAuth,
|
|
51
|
+
// Utils
|
|
52
|
+
getEnv,
|
|
53
|
+
getEnvNumber,
|
|
54
|
+
getEnvBoolean,
|
|
55
|
+
// Periodic Health Monitoring
|
|
56
|
+
PeriodicHealthMonitor,
|
|
57
|
+
};
|
|
58
|
+
export default ServerUtils;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { ServerPlugin } from './types';
|
|
3
|
+
export declare function createLoggingMiddleware(format?: 'simple' | 'detailed'): express.RequestHandler;
|
|
4
|
+
export declare function createErrorHandler(): express.ErrorRequestHandler;
|
|
5
|
+
export declare function createRequestIdMiddleware(): express.RequestHandler;
|
|
6
|
+
export interface ValidationRule {
|
|
7
|
+
field: string;
|
|
8
|
+
required?: boolean;
|
|
9
|
+
type?: 'string' | 'number' | 'email' | 'boolean';
|
|
10
|
+
minLength?: number;
|
|
11
|
+
maxLength?: number;
|
|
12
|
+
pattern?: RegExp;
|
|
13
|
+
custom?: (value: unknown) => boolean | string;
|
|
14
|
+
}
|
|
15
|
+
export declare function createValidationMiddleware(rules: ValidationRule[]): express.RequestHandler;
|
|
16
|
+
export interface RateLimitConfig {
|
|
17
|
+
windowMs?: number;
|
|
18
|
+
maxRequests?: number;
|
|
19
|
+
message?: string;
|
|
20
|
+
keyGenerator?: (req: express.Request) => string;
|
|
21
|
+
}
|
|
22
|
+
export declare function createRateLimitMiddleware(config?: RateLimitConfig): express.RequestHandler;
|
|
23
|
+
export interface AuthConfig {
|
|
24
|
+
tokenExtractor?: (req: express.Request) => string | null;
|
|
25
|
+
tokenValidator?: (token: string) => Promise<unknown> | unknown;
|
|
26
|
+
unauthorizedMessage?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function createAuthMiddleware(config: AuthConfig): express.RequestHandler;
|
|
29
|
+
export declare function withLogging(format?: 'simple' | 'detailed'): ServerPlugin;
|
|
30
|
+
export declare function withErrorHandler(): ServerPlugin;
|
|
31
|
+
export declare function withRequestId(): ServerPlugin;
|
|
32
|
+
export declare function withValidation(rules: ValidationRule[]): ServerPlugin;
|
|
33
|
+
export declare function withRateLimit(config?: RateLimitConfig): ServerPlugin;
|
|
34
|
+
export declare function withAuth(config: AuthConfig): ServerPlugin;
|
|
35
|
+
export declare function validateFields(rules: ValidationRule[]): express.RequestHandler;
|
|
36
|
+
export declare function rateLimit(config?: RateLimitConfig): express.RequestHandler;
|
|
37
|
+
export declare function requireAuth(config: AuthConfig): express.RequestHandler;
|