@naman_deep_singh/server-utils 1.2.0 → 1.4.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 +35 -62
- package/dist/cjs/core/health.d.ts +5 -0
- package/dist/cjs/{periodic-health.d.ts → core/periodic-health.d.ts} +1 -1
- package/dist/{types → cjs/core}/server.d.ts +6 -4
- package/dist/cjs/{server.js → core/server.js} +43 -12
- package/dist/cjs/core/shutdown.d.ts +5 -0
- package/dist/cjs/index.d.ts +11 -11
- package/dist/cjs/index.js +10 -10
- package/dist/cjs/middleware/auth.middleware.d.ts +7 -0
- package/dist/cjs/middleware/auth.middleware.js +41 -0
- package/dist/cjs/middleware/cache.middleware.d.ts +2 -0
- package/dist/cjs/middleware/cache.middleware.js +56 -0
- package/dist/cjs/middleware/errorHandler.middleware.d.ts +2 -0
- package/dist/cjs/middleware/errorHandler.middleware.js +28 -0
- package/dist/cjs/middleware/index.d.ts +10 -0
- package/dist/cjs/middleware/index.js +40 -0
- package/dist/cjs/middleware/logging.middleware.d.ts +2 -0
- package/dist/cjs/middleware/logging.middleware.js +19 -0
- package/dist/cjs/middleware/plugins.middleware.d.ts +14 -0
- package/dist/cjs/middleware/plugins.middleware.js +58 -0
- package/dist/cjs/middleware/rateLimiter.middleware.d.ts +8 -0
- package/dist/cjs/middleware/rateLimiter.middleware.js +35 -0
- package/dist/cjs/middleware/requestId.middleware.d.ts +2 -0
- package/dist/cjs/middleware/requestId.middleware.js +12 -0
- package/dist/cjs/middleware/session.middleware.d.ts +2 -0
- package/dist/cjs/middleware/session.middleware.js +50 -0
- package/dist/cjs/middleware/validation.middleware.d.ts +11 -0
- package/dist/cjs/middleware/validation.middleware.js +66 -0
- package/dist/esm/core/health.d.ts +5 -0
- package/dist/esm/{periodic-health.d.ts → core/periodic-health.d.ts} +1 -1
- package/dist/esm/{server.d.ts → core/server.d.ts} +6 -4
- package/dist/esm/{server.js → core/server.js} +10 -12
- package/dist/esm/core/shutdown.d.ts +5 -0
- package/dist/esm/index.d.ts +11 -11
- package/dist/esm/index.js +10 -10
- package/dist/esm/middleware/auth.middleware.d.ts +7 -0
- package/dist/esm/middleware/auth.middleware.js +38 -0
- package/dist/esm/middleware/cache.middleware.d.ts +2 -0
- package/dist/esm/middleware/cache.middleware.js +53 -0
- package/dist/esm/middleware/errorHandler.middleware.d.ts +2 -0
- package/dist/esm/middleware/errorHandler.middleware.js +25 -0
- package/dist/esm/middleware/index.d.ts +10 -0
- package/dist/esm/middleware/index.js +20 -0
- package/dist/esm/middleware/logging.middleware.d.ts +2 -0
- package/dist/esm/middleware/logging.middleware.js +16 -0
- package/dist/esm/middleware/plugins.middleware.d.ts +14 -0
- package/dist/esm/middleware/plugins.middleware.js +47 -0
- package/dist/esm/middleware/rateLimiter.middleware.d.ts +8 -0
- package/dist/esm/middleware/rateLimiter.middleware.js +32 -0
- package/dist/esm/middleware/requestId.middleware.d.ts +2 -0
- package/dist/esm/middleware/requestId.middleware.js +9 -0
- package/dist/esm/middleware/session.middleware.d.ts +2 -0
- package/dist/esm/middleware/session.middleware.js +47 -0
- package/dist/esm/middleware/validation.middleware.d.ts +11 -0
- package/dist/esm/middleware/validation.middleware.js +63 -0
- package/dist/types/core/health.d.ts +5 -0
- package/dist/types/{periodic-health.d.ts → core/periodic-health.d.ts} +1 -1
- package/dist/{cjs → types/core}/server.d.ts +6 -4
- package/dist/types/core/shutdown.d.ts +5 -0
- package/dist/types/index.d.ts +11 -11
- package/dist/types/middleware/auth.middleware.d.ts +7 -0
- package/dist/types/middleware/cache.middleware.d.ts +2 -0
- package/dist/types/middleware/errorHandler.middleware.d.ts +2 -0
- package/dist/types/middleware/index.d.ts +10 -0
- package/dist/types/middleware/logging.middleware.d.ts +2 -0
- package/dist/types/middleware/plugins.middleware.d.ts +14 -0
- package/dist/types/middleware/rateLimiter.middleware.d.ts +8 -0
- package/dist/types/middleware/requestId.middleware.d.ts +2 -0
- package/dist/types/middleware/session.middleware.d.ts +2 -0
- package/dist/types/middleware/validation.middleware.d.ts +11 -0
- package/package.json +3 -1
- package/dist/cjs/health.d.ts +0 -5
- package/dist/cjs/middleware.d.ts +0 -39
- package/dist/cjs/middleware.js +0 -346
- package/dist/cjs/shutdown.d.ts +0 -5
- package/dist/esm/health.d.ts +0 -5
- package/dist/esm/middleware.d.ts +0 -39
- package/dist/esm/middleware.js +0 -327
- package/dist/esm/shutdown.d.ts +0 -5
- package/dist/types/health.d.ts +0 -5
- package/dist/types/middleware.d.ts +0 -39
- package/dist/types/shutdown.d.ts +0 -5
- /package/dist/cjs/{health.js → core/health.js} +0 -0
- /package/dist/cjs/{periodic-health.js → core/periodic-health.js} +0 -0
- /package/dist/cjs/{shutdown.js → core/shutdown.js} +0 -0
- /package/dist/cjs/{types.d.ts → types/index.d.ts} +0 -0
- /package/dist/cjs/{types.js → types/index.js} +0 -0
- /package/dist/cjs/{utils.d.ts → utils/utils.d.ts} +0 -0
- /package/dist/cjs/{utils.js → utils/utils.js} +0 -0
- /package/dist/esm/{health.js → core/health.js} +0 -0
- /package/dist/esm/{periodic-health.js → core/periodic-health.js} +0 -0
- /package/dist/esm/{shutdown.js → core/shutdown.js} +0 -0
- /package/dist/esm/{types.d.ts → types/index.d.ts} +0 -0
- /package/dist/esm/{types.js → types/index.js} +0 -0
- /package/dist/esm/{utils.d.ts → utils/utils.d.ts} +0 -0
- /package/dist/esm/{utils.js → utils/utils.js} +0 -0
- /package/dist/types/{types.d.ts → types/index.d.ts} +0 -0
- /package/dist/types/{utils.d.ts → utils/utils.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @naman_deep_singh/server-utils
|
|
2
2
|
|
|
3
|
-
**Version:** 1.
|
|
3
|
+
**Version:** 1.4.0 (with integrated cache & session support)
|
|
4
4
|
|
|
5
5
|
Extensible server utilities for Express.js microservices with multi-protocol support, integrated caching, session management, and TypeScript.
|
|
6
6
|
|
|
@@ -19,13 +19,13 @@ npm install @naman_deep_singh/server-utils
|
|
|
19
19
|
- ✅ **Graceful shutdown** handling with cache/session cleanup
|
|
20
20
|
- ✅ **Health checks** with custom checks and cache health integration
|
|
21
21
|
- ✅ **TypeScript support** with full type safety
|
|
22
|
-
|
|
23
|
-
- ✅ **Plugin architecture** for extensibility
|
|
22
|
+
|
|
24
23
|
- ✅ **Built-in middleware** - logging, validation, rate limiting, auth, caching, sessions
|
|
25
24
|
|
|
25
|
+
|
|
26
26
|
## Quick Start
|
|
27
27
|
|
|
28
|
-
###
|
|
28
|
+
### Basic Usage
|
|
29
29
|
```typescript
|
|
30
30
|
import { createServer } from '@naman_deep_singh/server-utils';
|
|
31
31
|
|
|
@@ -44,13 +44,6 @@ server.app.get('/users', (req, res) => {
|
|
|
44
44
|
await server.start();
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
### Namespace Import
|
|
48
|
-
```typescript
|
|
49
|
-
import ServerUtils from '@naman_deep_singh/server-utils';
|
|
50
|
-
|
|
51
|
-
const server = ServerUtils.createServer('My API', '1.0.0');
|
|
52
|
-
```
|
|
53
|
-
|
|
54
47
|
## Multi-Protocol Support
|
|
55
48
|
|
|
56
49
|
### HTTP + Express Routes
|
|
@@ -131,17 +124,13 @@ server.addWebhook({
|
|
|
131
124
|
|
|
132
125
|
## Built-in Middleware
|
|
133
126
|
|
|
127
|
+
|
|
134
128
|
### Logging Middleware
|
|
135
129
|
```typescript
|
|
136
|
-
import { createLoggingMiddleware
|
|
130
|
+
import { createLoggingMiddleware } from '@naman_deep_singh/server-utils';
|
|
137
131
|
|
|
138
132
|
// Direct usage
|
|
139
133
|
server.app.use(createLoggingMiddleware('detailed'));
|
|
140
|
-
|
|
141
|
-
// Plugin usage
|
|
142
|
-
const server = createServerWithPlugins('My API', '1.0.0', [
|
|
143
|
-
withLogging('detailed')
|
|
144
|
-
]);
|
|
145
134
|
```
|
|
146
135
|
|
|
147
136
|
### Validation Middleware
|
|
@@ -169,67 +158,45 @@ server.app.use('/api', rateLimit({
|
|
|
169
158
|
}));
|
|
170
159
|
```
|
|
171
160
|
|
|
161
|
+
|
|
172
162
|
### Authentication Middleware
|
|
173
163
|
```typescript
|
|
174
164
|
import { requireAuth } from '@naman_deep_singh/server-utils';
|
|
175
165
|
|
|
176
166
|
server.app.use('/protected', requireAuth({
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
167
|
+
secret: process.env.JWT_SECRET!,
|
|
168
|
+
unauthorizedMessage: 'Invalid or expired token'
|
|
169
|
+
}));
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Advanced Configuration:**
|
|
173
|
+
```typescript
|
|
174
|
+
import { createAuthMiddleware } from '@naman_deep_singh/server-utils';
|
|
175
|
+
|
|
176
|
+
server.app.use('/api', createAuthMiddleware({
|
|
177
|
+
secret: process.env.JWT_SECRET!,
|
|
178
|
+
unauthorizedMessage: 'Access denied',
|
|
179
|
+
tokenExtractor: (req) => {
|
|
180
|
+
// Custom token extraction logic
|
|
181
|
+
// By default, uses sophisticated extractToken from @naman_deep_singh/security
|
|
182
|
+
// that checks Authorization headers, cookies, query params, and body
|
|
183
|
+
return req.headers.authorization?.substring(7);
|
|
181
184
|
}
|
|
182
185
|
}));
|
|
183
186
|
```
|
|
184
187
|
|
|
185
188
|
## Health Checks
|
|
186
189
|
|
|
190
|
+
|
|
187
191
|
### Basic Health Check
|
|
188
192
|
```typescript
|
|
189
|
-
import {
|
|
193
|
+
import { createHealthCheck } from '@naman_deep_singh/server-utils';
|
|
190
194
|
|
|
191
|
-
//
|
|
192
|
-
|
|
195
|
+
// The health check is automatically enabled when healthCheck is not false
|
|
196
|
+
// Health endpoint is available at /health by default
|
|
193
197
|
|
|
194
|
-
//
|
|
198
|
+
// If you need to customize or disable it:
|
|
195
199
|
server.app.get('/health', createHealthCheck());
|
|
196
|
-
|
|
197
|
-
// Method 3: As plugin
|
|
198
|
-
const server = createServerWithPlugins('My API', '1.0.0', [
|
|
199
|
-
withHealthCheck('/health')
|
|
200
|
-
]);
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### Advanced Health Checks
|
|
204
|
-
```typescript
|
|
205
|
-
addHealthCheck(server.app, '/health', {
|
|
206
|
-
customChecks: [
|
|
207
|
-
{
|
|
208
|
-
name: 'database',
|
|
209
|
-
check: async () => {
|
|
210
|
-
// Check database connection
|
|
211
|
-
return await db.ping();
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
name: 'redis',
|
|
216
|
-
check: async () => {
|
|
217
|
-
return await redis.ping() === 'PONG';
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
]
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
// Response format:
|
|
224
|
-
// {
|
|
225
|
-
// "status": "healthy",
|
|
226
|
-
// "checks": {
|
|
227
|
-
// "server": true,
|
|
228
|
-
// "timestamp": 1640995200000,
|
|
229
|
-
// "database": true,
|
|
230
|
-
// "redis": false
|
|
231
|
-
// }
|
|
232
|
-
// }
|
|
233
200
|
```
|
|
234
201
|
|
|
235
202
|
## Server Management
|
|
@@ -332,6 +299,12 @@ import { Request, Response, NextFunction, Router, Application } from '@naman_dee
|
|
|
332
299
|
import type { RequestHandler, ErrorRequestHandler } from '@naman_deep_singh/server-utils';
|
|
333
300
|
|
|
334
301
|
// No need to install Express separately in your services
|
|
302
|
+
|
|
303
|
+
## TypeScript Notes
|
|
304
|
+
|
|
305
|
+
- This package includes TypeScript augmentations for Express `Request` and `Application` that expose runtime helpers used by the middleware (for example `req.cache`, `req.sessionStore`, `req.getSession`, and `req.createSession`). Installing and importing `@naman_deep_singh/server-utils` in your project will surface these types automatically.
|
|
306
|
+
- Middleware that attaches runtime props uses `unknown` internally and runtime guards — prefer the provided helpers rather than casting `req` to `any`.
|
|
307
|
+
|
|
335
308
|
```
|
|
336
309
|
|
|
337
310
|
## API Reference
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Application, RequestHandler } from 'express';
|
|
2
|
+
import { HealthCheckConfig, ServerPlugin } from '../types';
|
|
3
|
+
export declare function createHealthCheck(config?: HealthCheckConfig): RequestHandler;
|
|
4
|
+
export declare function withHealthCheck(path?: string, config?: HealthCheckConfig): ServerPlugin;
|
|
5
|
+
export declare function addHealthCheck(app: Application, path?: string, config?: HealthCheckConfig): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
1
|
import { Server } from 'http';
|
|
3
|
-
import {
|
|
2
|
+
import { Application } from 'express';
|
|
3
|
+
import { ServerConfig, SocketIOConfig } from '../types';
|
|
4
4
|
export interface GrpcService {
|
|
5
5
|
service: Record<string, unknown>;
|
|
6
6
|
implementation: Record<string, (...args: unknown[]) => unknown>;
|
|
@@ -26,7 +26,7 @@ export interface ServerInstanceConfig extends Required<Omit<ServerConfig, 'socke
|
|
|
26
26
|
socketIO?: SocketIOConfig;
|
|
27
27
|
}
|
|
28
28
|
export interface ServerInstance {
|
|
29
|
-
app:
|
|
29
|
+
app: Application;
|
|
30
30
|
server?: Server;
|
|
31
31
|
config: ServerInstanceConfig;
|
|
32
32
|
start(): Promise<ServerInstance>;
|
|
@@ -46,9 +46,11 @@ export interface ServerInfo {
|
|
|
46
46
|
startTime: Date;
|
|
47
47
|
}
|
|
48
48
|
export declare class ExpressServer implements ServerInstance {
|
|
49
|
-
app:
|
|
49
|
+
app: Application;
|
|
50
50
|
server?: Server;
|
|
51
51
|
config: ServerInstanceConfig;
|
|
52
|
+
cache?: import('@naman_deep_singh/cache').ICache<unknown>;
|
|
53
|
+
sessionStore?: import('@naman_deep_singh/cache').SessionStore | undefined;
|
|
52
54
|
private status;
|
|
53
55
|
private grpcServices;
|
|
54
56
|
private grpcServer?;
|
|
@@ -1,15 +1,48 @@
|
|
|
1
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
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
5
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
39
|
exports.ExpressServer = void 0;
|
|
7
40
|
exports.createServer = createServer;
|
|
8
|
-
const express_1 =
|
|
9
|
-
const shutdown_1 = require("./shutdown");
|
|
10
|
-
const periodic_health_1 = require("./periodic-health");
|
|
11
|
-
const crypto_1 = __importDefault(require("crypto"));
|
|
41
|
+
const express_1 = __importStar(require("express"));
|
|
12
42
|
const cache_1 = require("@naman_deep_singh/cache");
|
|
43
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
44
|
+
const periodic_health_1 = require("./periodic-health");
|
|
45
|
+
const shutdown_1 = require("./shutdown");
|
|
13
46
|
class ExpressServer {
|
|
14
47
|
constructor(name = 'Express Server', version = '1.0.0', config = {}) {
|
|
15
48
|
this.status = 'stopped';
|
|
@@ -66,7 +99,7 @@ class ExpressServer {
|
|
|
66
99
|
}
|
|
67
100
|
// Apply JSON parser if enabled
|
|
68
101
|
if (this.config.json) {
|
|
69
|
-
this.app.use(express_1.
|
|
102
|
+
this.app.use((0, express_1.json)());
|
|
70
103
|
}
|
|
71
104
|
// Apply cookie parser if enabled
|
|
72
105
|
if (this.config.cookieParser) {
|
|
@@ -114,17 +147,15 @@ class ExpressServer {
|
|
|
114
147
|
// Initialize cache if enabled
|
|
115
148
|
if (config.cache && config.cache.enabled) {
|
|
116
149
|
try {
|
|
117
|
-
const provided = config.cache
|
|
150
|
+
const provided = config.cache?.options;
|
|
118
151
|
let cacheConfig = provided && typeof provided === 'object' ? provided : undefined;
|
|
119
152
|
if (!cacheConfig) {
|
|
120
153
|
cacheConfig = { adapter: config.cache.adapter || 'memory' };
|
|
121
154
|
}
|
|
122
155
|
console.log(`🔄 [${serverName}] Initializing cache adapter: ${config.cache.adapter || 'memory'}...`);
|
|
123
156
|
// Use createWithFallback to prefer primary and fall back to memory when configured
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
ttl: cacheConfig?.ttl ?? config.cache?.defaultTTL
|
|
127
|
-
});
|
|
157
|
+
const cfg = { ...(cacheConfig || {}), ttl: cacheConfig?.ttl ?? config.cache?.defaultTTL };
|
|
158
|
+
const cache = await cache_1.CacheFactory.createWithFallback(cfg);
|
|
128
159
|
this.app.locals.cache = cache;
|
|
129
160
|
this.cache = cache;
|
|
130
161
|
this.app.locals.cacheDefaultTTL = config.cache?.defaultTTL;
|
|
@@ -171,7 +202,7 @@ class ExpressServer {
|
|
|
171
202
|
// attach session middleware globally so req.sessionStore is available
|
|
172
203
|
try {
|
|
173
204
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
174
|
-
const { useSession } = require('
|
|
205
|
+
const { useSession } = require('../middleware/middleware');
|
|
175
206
|
this.app.use(useSession(cookieName));
|
|
176
207
|
console.log(`✅ [${serverName}] Session middleware enabled (cookie: ${cookieName}, TTL: ${ttl}s)`);
|
|
177
208
|
}
|
|
@@ -315,7 +346,7 @@ class ExpressServer {
|
|
|
315
346
|
}
|
|
316
347
|
}
|
|
317
348
|
addWebhook(config) {
|
|
318
|
-
this.app.post(config.path, express_1.
|
|
349
|
+
this.app.post(config.path, (0, express_1.raw)({ type: 'application/json' }), async (req, res) => {
|
|
319
350
|
try {
|
|
320
351
|
// Verify signature if secret provided
|
|
321
352
|
if (config.secret) {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Server } from 'http';
|
|
2
|
+
import { GracefulShutdownConfig, ServerPlugin } from '../types';
|
|
3
|
+
export declare function createGracefulShutdown(server: Server, config?: GracefulShutdownConfig): void;
|
|
4
|
+
export declare function withGracefulShutdown(config?: GracefulShutdownConfig): ServerPlugin;
|
|
5
|
+
export declare function startServerWithShutdown(app: import('express').Application, port: number, shutdownConfig?: GracefulShutdownConfig, serverName?: string, serverVersion?: string): Server;
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
export { ExpressServer, createServer } from './server';
|
|
2
|
-
export type { ServerInstance, ServerInfo, GrpcService, RpcMethod, WebhookConfig } from './server';
|
|
1
|
+
export { ExpressServer, createServer } from './core/server';
|
|
2
|
+
export type { ServerInstance, ServerInfo, GrpcService, RpcMethod, WebhookConfig } from './core/server';
|
|
3
3
|
export { Request, Response, NextFunction, Router, Application } from 'express';
|
|
4
4
|
export type { RequestHandler, ErrorRequestHandler } from 'express';
|
|
5
|
-
export { createHealthCheck, withHealthCheck, addHealthCheck } from './health';
|
|
6
|
-
export { createGracefulShutdown, withGracefulShutdown, startServerWithShutdown } from './shutdown';
|
|
5
|
+
export { createHealthCheck, withHealthCheck, addHealthCheck } from './core/health';
|
|
6
|
+
export { createGracefulShutdown, withGracefulShutdown, startServerWithShutdown } from './core/shutdown';
|
|
7
7
|
export { createLoggingMiddleware, createErrorHandler, createRequestIdMiddleware, createValidationMiddleware, createRateLimitMiddleware, createAuthMiddleware, withLogging, withErrorHandler, withRequestId, withValidation, withRateLimit, withAuth, validateFields, rateLimit, requireAuth, cacheResponse, useSession, type ValidationRule, type RateLimitConfig, type AuthConfig } from './middleware';
|
|
8
|
-
export { getEnv, getEnvNumber, getEnvBoolean } from './utils';
|
|
9
|
-
export { PeriodicHealthMonitor } from './periodic-health';
|
|
8
|
+
export { getEnv, getEnvNumber, getEnvBoolean } from './utils/utils';
|
|
9
|
+
export { PeriodicHealthMonitor } from './core/periodic-health';
|
|
10
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';
|
|
11
|
+
import { ExpressServer, createServer } from './core/server';
|
|
12
|
+
import { createHealthCheck, withHealthCheck, addHealthCheck } from './core/health';
|
|
13
|
+
import { createGracefulShutdown, withGracefulShutdown, startServerWithShutdown } from './core/shutdown';
|
|
14
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';
|
|
15
|
+
import { getEnv, getEnvNumber, getEnvBoolean } from './utils/utils';
|
|
16
|
+
import { PeriodicHealthMonitor } from './core/periodic-health';
|
|
17
17
|
declare const ServerUtils: {
|
|
18
18
|
createServer: typeof createServer;
|
|
19
19
|
ExpressServer: typeof ExpressServer;
|
package/dist/cjs/index.js
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PeriodicHealthMonitor = exports.getEnvBoolean = exports.getEnvNumber = exports.getEnv = exports.useSession = exports.cacheResponse = 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
|
-
var server_1 = require("./server");
|
|
5
|
+
var server_1 = require("./core/server");
|
|
6
6
|
Object.defineProperty(exports, "ExpressServer", { enumerable: true, get: function () { return server_1.ExpressServer; } });
|
|
7
7
|
Object.defineProperty(exports, "createServer", { enumerable: true, get: function () { return server_1.createServer; } });
|
|
8
8
|
// Express re-exports (to avoid direct Express dependency in services)
|
|
9
9
|
var express_1 = require("express");
|
|
10
10
|
Object.defineProperty(exports, "Router", { enumerable: true, get: function () { return express_1.Router; } });
|
|
11
11
|
// Health check utilities
|
|
12
|
-
var health_1 = require("./health");
|
|
12
|
+
var health_1 = require("./core/health");
|
|
13
13
|
Object.defineProperty(exports, "createHealthCheck", { enumerable: true, get: function () { return health_1.createHealthCheck; } });
|
|
14
14
|
Object.defineProperty(exports, "withHealthCheck", { enumerable: true, get: function () { return health_1.withHealthCheck; } });
|
|
15
15
|
Object.defineProperty(exports, "addHealthCheck", { enumerable: true, get: function () { return health_1.addHealthCheck; } });
|
|
16
16
|
// Graceful shutdown utilities
|
|
17
|
-
var shutdown_1 = require("./shutdown");
|
|
17
|
+
var shutdown_1 = require("./core/shutdown");
|
|
18
18
|
Object.defineProperty(exports, "createGracefulShutdown", { enumerable: true, get: function () { return shutdown_1.createGracefulShutdown; } });
|
|
19
19
|
Object.defineProperty(exports, "withGracefulShutdown", { enumerable: true, get: function () { return shutdown_1.withGracefulShutdown; } });
|
|
20
20
|
Object.defineProperty(exports, "startServerWithShutdown", { enumerable: true, get: function () { return shutdown_1.startServerWithShutdown; } });
|
|
@@ -38,20 +38,20 @@ Object.defineProperty(exports, "requireAuth", { enumerable: true, get: function
|
|
|
38
38
|
Object.defineProperty(exports, "cacheResponse", { enumerable: true, get: function () { return middleware_1.cacheResponse; } });
|
|
39
39
|
Object.defineProperty(exports, "useSession", { enumerable: true, get: function () { return middleware_1.useSession; } });
|
|
40
40
|
// Utility functions
|
|
41
|
-
var utils_1 = require("./utils");
|
|
41
|
+
var utils_1 = require("./utils/utils");
|
|
42
42
|
Object.defineProperty(exports, "getEnv", { enumerable: true, get: function () { return utils_1.getEnv; } });
|
|
43
43
|
Object.defineProperty(exports, "getEnvNumber", { enumerable: true, get: function () { return utils_1.getEnvNumber; } });
|
|
44
44
|
Object.defineProperty(exports, "getEnvBoolean", { enumerable: true, get: function () { return utils_1.getEnvBoolean; } });
|
|
45
45
|
// Periodic health monitoring
|
|
46
|
-
var periodic_health_1 = require("./periodic-health");
|
|
46
|
+
var periodic_health_1 = require("./core/periodic-health");
|
|
47
47
|
Object.defineProperty(exports, "PeriodicHealthMonitor", { enumerable: true, get: function () { return periodic_health_1.PeriodicHealthMonitor; } });
|
|
48
48
|
// Import all exports for default export
|
|
49
|
-
const server_2 = require("./server");
|
|
50
|
-
const health_2 = require("./health");
|
|
51
|
-
const shutdown_2 = require("./shutdown");
|
|
49
|
+
const server_2 = require("./core/server");
|
|
50
|
+
const health_2 = require("./core/health");
|
|
51
|
+
const shutdown_2 = require("./core/shutdown");
|
|
52
52
|
const middleware_2 = require("./middleware");
|
|
53
|
-
const utils_2 = require("./utils");
|
|
54
|
-
const periodic_health_2 = require("./periodic-health");
|
|
53
|
+
const utils_2 = require("./utils/utils");
|
|
54
|
+
const periodic_health_2 = require("./core/periodic-health");
|
|
55
55
|
// Default export for namespace usage
|
|
56
56
|
const ServerUtils = {
|
|
57
57
|
// Server creation
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Request, RequestHandler } from "node_modules/@types/express";
|
|
2
|
+
export interface AuthConfig {
|
|
3
|
+
secret: string;
|
|
4
|
+
unauthorizedMessage?: string;
|
|
5
|
+
tokenExtractor?: (req: Request) => string | null;
|
|
6
|
+
}
|
|
7
|
+
export declare function createAuthMiddleware(config: AuthConfig): RequestHandler;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAuthMiddleware = createAuthMiddleware;
|
|
4
|
+
const security_1 = require("@naman_deep_singh/security");
|
|
5
|
+
const errors_utils_1 = require("@naman_deep_singh/errors-utils");
|
|
6
|
+
function createAuthMiddleware(config) {
|
|
7
|
+
const { secret, unauthorizedMessage = 'Unauthorized access', tokenExtractor = (req) => (0, security_1.extractToken)({
|
|
8
|
+
header: req.headers.authorization || undefined,
|
|
9
|
+
cookies: req.cookies,
|
|
10
|
+
query: req.query,
|
|
11
|
+
body: req.body
|
|
12
|
+
}) } = config;
|
|
13
|
+
return async (req, res, next) => {
|
|
14
|
+
try {
|
|
15
|
+
// Extract token from request
|
|
16
|
+
const token = tokenExtractor(req);
|
|
17
|
+
if (!token) {
|
|
18
|
+
const error = new errors_utils_1.UnauthorizedError(unauthorizedMessage, {
|
|
19
|
+
reason: 'No token provided'
|
|
20
|
+
});
|
|
21
|
+
return next(error);
|
|
22
|
+
}
|
|
23
|
+
// Use safe verify token from security package
|
|
24
|
+
const result = (0, security_1.safeVerifyToken)(token, secret);
|
|
25
|
+
if (!result.valid) {
|
|
26
|
+
const error = new errors_utils_1.UnauthorizedError(unauthorizedMessage, {
|
|
27
|
+
reason: 'Invalid or expired token',
|
|
28
|
+
originalError: result.error?.message
|
|
29
|
+
});
|
|
30
|
+
return next(error);
|
|
31
|
+
}
|
|
32
|
+
// Attach the verified payload as user
|
|
33
|
+
req.user = result.payload;
|
|
34
|
+
next();
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
const unauthorizedError = new errors_utils_1.UnauthorizedError(unauthorizedMessage, error instanceof Error ? { originalError: error.message } : error);
|
|
38
|
+
return next(unauthorizedError);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cacheResponse = cacheResponse;
|
|
4
|
+
// Cache response middleware (per-route opt-in)
|
|
5
|
+
function cacheResponse(ttl) {
|
|
6
|
+
return async (req, res, next) => {
|
|
7
|
+
try {
|
|
8
|
+
if (req.method !== 'GET')
|
|
9
|
+
return next();
|
|
10
|
+
const cache = (req.cache ?? req.app.locals.cache);
|
|
11
|
+
const defaultTTL = req.app.locals.cacheDefaultTTL;
|
|
12
|
+
if (!cache || typeof cache.get !== 'function')
|
|
13
|
+
return next();
|
|
14
|
+
const key = `${req.originalUrl}`;
|
|
15
|
+
try {
|
|
16
|
+
const cached = await cache.get(key);
|
|
17
|
+
if (cached !== null && cached !== undefined) {
|
|
18
|
+
res.setHeader('X-Cache', 'HIT');
|
|
19
|
+
return res.json(cached);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch (cacheErr) {
|
|
23
|
+
console.error(`[Cache] Failed to retrieve key "${key}":`, cacheErr);
|
|
24
|
+
// Continue without cache hit
|
|
25
|
+
}
|
|
26
|
+
const originalJson = res.json.bind(res);
|
|
27
|
+
res.json = (body) => {
|
|
28
|
+
try {
|
|
29
|
+
const expiry = ttl ?? defaultTTL;
|
|
30
|
+
if (expiry && cache && typeof cache.set === 'function') {
|
|
31
|
+
cache.set(key, body, expiry).catch((err) => {
|
|
32
|
+
console.error(`[Cache] Failed to set key "${key}" with TTL ${expiry}:`, err);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
else if (cache) {
|
|
36
|
+
if (typeof cache.set === 'function') {
|
|
37
|
+
cache.set(key, body).catch((err) => {
|
|
38
|
+
console.error(`[Cache] Failed to set key "${key}":`, err);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
console.error(`[Cache] Error during cache.set operation:`, e);
|
|
45
|
+
}
|
|
46
|
+
res.setHeader('X-Cache', 'MISS');
|
|
47
|
+
return originalJson(body);
|
|
48
|
+
};
|
|
49
|
+
next();
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
console.error('[Cache] Unexpected error in cacheResponse middleware:', err);
|
|
53
|
+
next();
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createErrorHandler = createErrorHandler;
|
|
4
|
+
// Error handling middleware
|
|
5
|
+
function createErrorHandler() {
|
|
6
|
+
return (err, req, res, next) => {
|
|
7
|
+
console.error('Error:', err);
|
|
8
|
+
if (res.headersSent) {
|
|
9
|
+
return next(err);
|
|
10
|
+
}
|
|
11
|
+
// Type guard for error objects
|
|
12
|
+
const errorObj = err;
|
|
13
|
+
const status = errorObj.status || errorObj.statusCode || 500;
|
|
14
|
+
const message = process.env.NODE_ENV === 'production'
|
|
15
|
+
? 'Internal Server Error'
|
|
16
|
+
: errorObj.message || 'Unknown error';
|
|
17
|
+
res.status(status).json({
|
|
18
|
+
success: false,
|
|
19
|
+
message,
|
|
20
|
+
data: undefined,
|
|
21
|
+
error: {
|
|
22
|
+
message,
|
|
23
|
+
...(process.env.NODE_ENV !== 'production' && { details: { stack: errorObj.stack } })
|
|
24
|
+
},
|
|
25
|
+
meta: null
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { AuthConfig, createAuthMiddleware } from './auth.middleware';
|
|
2
|
+
export { cacheResponse } from './cache.middleware';
|
|
3
|
+
export { createErrorHandler } from './errorHandler.middleware';
|
|
4
|
+
export { createLoggingMiddleware } from './logging.middleware';
|
|
5
|
+
export { RateLimitConfig, createRateLimitMiddleware } from './rateLimiter.middleware';
|
|
6
|
+
export { createRequestIdMiddleware } from './requestId.middleware';
|
|
7
|
+
export { useSession } from './session.middleware';
|
|
8
|
+
export { ValidationRule, createValidationMiddleware } from './validation.middleware';
|
|
9
|
+
export { withLogging, withErrorHandler, withRequestId, withValidation, withRateLimit, withAuth } from './plugins.middleware';
|
|
10
|
+
export { validateFields, rateLimit, requireAuth } from './plugins.middleware';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.requireAuth = exports.rateLimit = exports.validateFields = exports.withAuth = exports.withRateLimit = exports.withValidation = exports.withRequestId = exports.withErrorHandler = exports.withLogging = exports.createValidationMiddleware = exports.useSession = exports.createRequestIdMiddleware = exports.createRateLimitMiddleware = exports.createLoggingMiddleware = exports.createErrorHandler = exports.cacheResponse = exports.createAuthMiddleware = void 0;
|
|
4
|
+
// Authentication Middleware
|
|
5
|
+
var auth_middleware_1 = require("./auth.middleware");
|
|
6
|
+
Object.defineProperty(exports, "createAuthMiddleware", { enumerable: true, get: function () { return auth_middleware_1.createAuthMiddleware; } });
|
|
7
|
+
// Cache Middleware
|
|
8
|
+
var cache_middleware_1 = require("./cache.middleware");
|
|
9
|
+
Object.defineProperty(exports, "cacheResponse", { enumerable: true, get: function () { return cache_middleware_1.cacheResponse; } });
|
|
10
|
+
// Error Handler Middleware
|
|
11
|
+
var errorHandler_middleware_1 = require("./errorHandler.middleware");
|
|
12
|
+
Object.defineProperty(exports, "createErrorHandler", { enumerable: true, get: function () { return errorHandler_middleware_1.createErrorHandler; } });
|
|
13
|
+
// Logging Middleware
|
|
14
|
+
var logging_middleware_1 = require("./logging.middleware");
|
|
15
|
+
Object.defineProperty(exports, "createLoggingMiddleware", { enumerable: true, get: function () { return logging_middleware_1.createLoggingMiddleware; } });
|
|
16
|
+
// Rate Limiter Middleware
|
|
17
|
+
var rateLimiter_middleware_1 = require("./rateLimiter.middleware");
|
|
18
|
+
Object.defineProperty(exports, "createRateLimitMiddleware", { enumerable: true, get: function () { return rateLimiter_middleware_1.createRateLimitMiddleware; } });
|
|
19
|
+
// Request ID Middleware
|
|
20
|
+
var requestId_middleware_1 = require("./requestId.middleware");
|
|
21
|
+
Object.defineProperty(exports, "createRequestIdMiddleware", { enumerable: true, get: function () { return requestId_middleware_1.createRequestIdMiddleware; } });
|
|
22
|
+
// Session Middleware
|
|
23
|
+
var session_middleware_1 = require("./session.middleware");
|
|
24
|
+
Object.defineProperty(exports, "useSession", { enumerable: true, get: function () { return session_middleware_1.useSession; } });
|
|
25
|
+
// Validation Middleware
|
|
26
|
+
var validation_middleware_1 = require("./validation.middleware");
|
|
27
|
+
Object.defineProperty(exports, "createValidationMiddleware", { enumerable: true, get: function () { return validation_middleware_1.createValidationMiddleware; } });
|
|
28
|
+
// Plugin middleware functions (for application-level middleware)
|
|
29
|
+
var plugins_middleware_1 = require("./plugins.middleware");
|
|
30
|
+
Object.defineProperty(exports, "withLogging", { enumerable: true, get: function () { return plugins_middleware_1.withLogging; } });
|
|
31
|
+
Object.defineProperty(exports, "withErrorHandler", { enumerable: true, get: function () { return plugins_middleware_1.withErrorHandler; } });
|
|
32
|
+
Object.defineProperty(exports, "withRequestId", { enumerable: true, get: function () { return plugins_middleware_1.withRequestId; } });
|
|
33
|
+
Object.defineProperty(exports, "withValidation", { enumerable: true, get: function () { return plugins_middleware_1.withValidation; } });
|
|
34
|
+
Object.defineProperty(exports, "withRateLimit", { enumerable: true, get: function () { return plugins_middleware_1.withRateLimit; } });
|
|
35
|
+
Object.defineProperty(exports, "withAuth", { enumerable: true, get: function () { return plugins_middleware_1.withAuth; } });
|
|
36
|
+
// Convenience middleware functions (for route-level middleware)
|
|
37
|
+
var plugins_middleware_2 = require("./plugins.middleware");
|
|
38
|
+
Object.defineProperty(exports, "validateFields", { enumerable: true, get: function () { return plugins_middleware_2.validateFields; } });
|
|
39
|
+
Object.defineProperty(exports, "rateLimit", { enumerable: true, get: function () { return plugins_middleware_2.rateLimit; } });
|
|
40
|
+
Object.defineProperty(exports, "requireAuth", { enumerable: true, get: function () { return plugins_middleware_2.requireAuth; } });
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createLoggingMiddleware = createLoggingMiddleware;
|
|
4
|
+
// Logging middleware
|
|
5
|
+
function createLoggingMiddleware(format = 'simple') {
|
|
6
|
+
return (req, res, next) => {
|
|
7
|
+
const start = Date.now();
|
|
8
|
+
res.on('finish', () => {
|
|
9
|
+
const duration = Date.now() - start;
|
|
10
|
+
if (format === 'detailed') {
|
|
11
|
+
console.log(`${req.method} ${req.url} - ${res.statusCode} - ${duration}ms - ${req.ip}`);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
console.log(`${req.method} ${req.url} - ${res.statusCode}`);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
next();
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RequestHandler } from 'express';
|
|
2
|
+
import { ServerPlugin } from '../types';
|
|
3
|
+
import { ValidationRule } from './validation.middleware';
|
|
4
|
+
import { RateLimitConfig } from './rateLimiter.middleware';
|
|
5
|
+
import { AuthConfig } from './auth.middleware';
|
|
6
|
+
export declare function withLogging(format?: 'simple' | 'detailed'): ServerPlugin;
|
|
7
|
+
export declare function withErrorHandler(): ServerPlugin;
|
|
8
|
+
export declare function withRequestId(): ServerPlugin;
|
|
9
|
+
export declare function withValidation(rules: ValidationRule[]): ServerPlugin;
|
|
10
|
+
export declare function withRateLimit(config?: RateLimitConfig): ServerPlugin;
|
|
11
|
+
export declare function withAuth(config: AuthConfig): ServerPlugin;
|
|
12
|
+
export declare function validateFields(rules: ValidationRule[]): RequestHandler;
|
|
13
|
+
export declare function rateLimit(config?: RateLimitConfig): RequestHandler;
|
|
14
|
+
export declare function requireAuth(config: AuthConfig): RequestHandler;
|