@naman_deep_singh/server-utils 1.4.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cjs/core/health.d.ts +2 -2
- package/dist/cjs/core/health.js +4 -4
- package/dist/cjs/core/periodic-health.d.ts +1 -1
- package/dist/cjs/core/periodic-health.js +4 -4
- package/dist/cjs/core/server.d.ts +6 -5
- package/dist/cjs/core/server.js +34 -22
- package/dist/cjs/core/shutdown.d.ts +2 -2
- package/dist/cjs/core/shutdown.js +2 -1
- package/dist/cjs/index.d.ts +11 -11
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/middleware/auth.middleware.d.ts +1 -1
- package/dist/cjs/middleware/auth.middleware.js +5 -5
- package/dist/cjs/middleware/cache.middleware.d.ts +1 -1
- package/dist/cjs/middleware/cache.middleware.js +2 -0
- package/dist/cjs/middleware/errorHandler.middleware.d.ts +1 -1
- package/dist/cjs/middleware/errorHandler.middleware.js +4 -2
- package/dist/cjs/middleware/index.d.ts +4 -4
- package/dist/cjs/middleware/logging.middleware.d.ts +1 -1
- package/dist/cjs/middleware/plugins.middleware.d.ts +5 -5
- package/dist/cjs/middleware/plugins.middleware.js +3 -3
- package/dist/cjs/middleware/rateLimiter.middleware.d.ts +1 -1
- package/dist/cjs/middleware/rateLimiter.middleware.js +5 -5
- package/dist/cjs/middleware/requestId.middleware.d.ts +1 -1
- package/dist/cjs/middleware/session.middleware.d.ts +1 -1
- package/dist/cjs/middleware/session.middleware.js +4 -1
- package/dist/cjs/middleware/validation.middleware.d.ts +1 -1
- package/dist/cjs/middleware/validation.middleware.js +3 -2
- package/dist/cjs/types/index.d.ts +1 -1
- package/dist/cjs/utils/utils.js +2 -2
- package/dist/esm/core/health.d.ts +2 -2
- package/dist/esm/core/health.js +4 -4
- package/dist/esm/core/periodic-health.d.ts +1 -1
- package/dist/esm/core/periodic-health.js +4 -4
- package/dist/esm/core/server.d.ts +6 -5
- package/dist/esm/core/server.js +33 -21
- package/dist/esm/core/shutdown.d.ts +2 -2
- package/dist/esm/core/shutdown.js +2 -1
- package/dist/esm/index.d.ts +11 -11
- package/dist/esm/index.js +9 -9
- package/dist/esm/middleware/auth.middleware.d.ts +1 -1
- package/dist/esm/middleware/auth.middleware.js +6 -6
- package/dist/esm/middleware/cache.middleware.d.ts +1 -1
- package/dist/esm/middleware/cache.middleware.js +2 -0
- package/dist/esm/middleware/errorHandler.middleware.d.ts +1 -1
- package/dist/esm/middleware/errorHandler.middleware.js +4 -2
- package/dist/esm/middleware/index.d.ts +4 -4
- package/dist/esm/middleware/index.js +4 -4
- package/dist/esm/middleware/logging.middleware.d.ts +1 -1
- package/dist/esm/middleware/plugins.middleware.d.ts +5 -5
- package/dist/esm/middleware/plugins.middleware.js +3 -3
- package/dist/esm/middleware/rateLimiter.middleware.d.ts +1 -1
- package/dist/esm/middleware/rateLimiter.middleware.js +5 -5
- package/dist/esm/middleware/requestId.middleware.d.ts +1 -1
- package/dist/esm/middleware/session.middleware.d.ts +1 -1
- package/dist/esm/middleware/session.middleware.js +4 -1
- package/dist/esm/middleware/validation.middleware.d.ts +1 -1
- package/dist/esm/middleware/validation.middleware.js +4 -3
- package/dist/esm/types/index.d.ts +1 -1
- package/dist/esm/utils/utils.js +2 -2
- package/dist/types/core/health.d.ts +2 -2
- package/dist/types/core/periodic-health.d.ts +1 -1
- package/dist/types/core/server.d.ts +6 -5
- package/dist/types/core/shutdown.d.ts +2 -2
- package/dist/types/index.d.ts +11 -11
- package/dist/types/middleware/auth.middleware.d.ts +1 -1
- package/dist/types/middleware/cache.middleware.d.ts +1 -1
- package/dist/types/middleware/errorHandler.middleware.d.ts +1 -1
- package/dist/types/middleware/index.d.ts +4 -4
- package/dist/types/middleware/logging.middleware.d.ts +1 -1
- package/dist/types/middleware/plugins.middleware.d.ts +5 -5
- package/dist/types/middleware/rateLimiter.middleware.d.ts +1 -1
- package/dist/types/middleware/requestId.middleware.d.ts +1 -1
- package/dist/types/middleware/session.middleware.d.ts +1 -1
- package/dist/types/middleware/validation.middleware.d.ts +1 -1
- package/dist/types/types/index.d.ts +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @naman_deep_singh/server-utils
|
|
2
2
|
|
|
3
|
-
**Version:** 1.4.
|
|
3
|
+
**Version:** 1.4.1 (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
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Application, RequestHandler } from 'express';
|
|
2
|
-
import { HealthCheckConfig, ServerPlugin } from '../types';
|
|
1
|
+
import type { Application, RequestHandler } from 'express';
|
|
2
|
+
import type { HealthCheckConfig, ServerPlugin } from '../types';
|
|
3
3
|
export declare function createHealthCheck(config?: HealthCheckConfig): RequestHandler;
|
|
4
4
|
export declare function withHealthCheck(path?: string, config?: HealthCheckConfig): ServerPlugin;
|
|
5
5
|
export declare function addHealthCheck(app: Application, path?: string, config?: HealthCheckConfig): void;
|
package/dist/cjs/core/health.js
CHANGED
|
@@ -9,7 +9,7 @@ function createHealthCheck(config = {}) {
|
|
|
9
9
|
try {
|
|
10
10
|
const checks = {
|
|
11
11
|
server: true,
|
|
12
|
-
timestamp: Date.now()
|
|
12
|
+
timestamp: Date.now(),
|
|
13
13
|
};
|
|
14
14
|
// Run custom health checks
|
|
15
15
|
for (const check of customChecks) {
|
|
@@ -20,16 +20,16 @@ function createHealthCheck(config = {}) {
|
|
|
20
20
|
checks[check.name] = false;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
const isHealthy = Object.values(checks).every(status => status === true || typeof status === 'number');
|
|
23
|
+
const isHealthy = Object.values(checks).every((status) => status === true || typeof status === 'number');
|
|
24
24
|
res.status(isHealthy ? 200 : 503).json({
|
|
25
25
|
status: isHealthy ? 'healthy' : 'unhealthy',
|
|
26
|
-
checks
|
|
26
|
+
checks,
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
catch (error) {
|
|
30
30
|
res.status(503).json({
|
|
31
31
|
status: 'unhealthy',
|
|
32
|
-
error: 'Health check failed'
|
|
32
|
+
error: 'Health check failed',
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
};
|
|
@@ -12,7 +12,7 @@ class PeriodicHealthMonitor {
|
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
14
|
const interval = this.config.interval || 30000;
|
|
15
|
-
this.config.services.forEach(service => {
|
|
15
|
+
this.config.services.forEach((service) => {
|
|
16
16
|
const intervalId = setInterval(async () => {
|
|
17
17
|
await this.checkServiceHealth(service);
|
|
18
18
|
}, interval);
|
|
@@ -21,7 +21,7 @@ class PeriodicHealthMonitor {
|
|
|
21
21
|
console.log(`📊 ${this.serviceName}: Periodic health monitoring enabled (${interval}ms interval) for ${this.config.services.length} service(s)`);
|
|
22
22
|
}
|
|
23
23
|
stop() {
|
|
24
|
-
this.intervals.forEach(interval => clearInterval(interval));
|
|
24
|
+
this.intervals.forEach((interval) => clearInterval(interval));
|
|
25
25
|
this.intervals = [];
|
|
26
26
|
console.log(`🛑 ${this.serviceName}: Periodic health monitoring stopped`);
|
|
27
27
|
}
|
|
@@ -34,8 +34,8 @@ class PeriodicHealthMonitor {
|
|
|
34
34
|
method: 'GET',
|
|
35
35
|
signal: controller.signal,
|
|
36
36
|
headers: {
|
|
37
|
-
'User-Agent': `${this.serviceName}-health-monitor
|
|
38
|
-
}
|
|
37
|
+
'User-Agent': `${this.serviceName}-health-monitor`,
|
|
38
|
+
},
|
|
39
39
|
});
|
|
40
40
|
clearTimeout(timeoutId);
|
|
41
41
|
if (response.ok) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { ICache, SessionStore } from '@naman_deep_singh/cache';
|
|
2
|
+
import type { Server } from 'http';
|
|
3
|
+
import type { Application } from 'express';
|
|
4
|
+
import type { ServerConfig, SocketIOConfig } from '../types';
|
|
4
5
|
export interface GrpcService {
|
|
5
6
|
service: Record<string, unknown>;
|
|
6
7
|
implementation: Record<string, (...args: unknown[]) => unknown>;
|
|
@@ -49,8 +50,8 @@ export declare class ExpressServer implements ServerInstance {
|
|
|
49
50
|
app: Application;
|
|
50
51
|
server?: Server;
|
|
51
52
|
config: ServerInstanceConfig;
|
|
52
|
-
cache?:
|
|
53
|
-
sessionStore?:
|
|
53
|
+
cache?: ICache<unknown>;
|
|
54
|
+
sessionStore?: SessionStore | undefined;
|
|
54
55
|
private status;
|
|
55
56
|
private grpcServices;
|
|
56
57
|
private grpcServer?;
|
package/dist/cjs/core/server.js
CHANGED
|
@@ -38,11 +38,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.ExpressServer = void 0;
|
|
40
40
|
exports.createServer = createServer;
|
|
41
|
-
const express_1 = __importStar(require("express"));
|
|
42
|
-
const cache_1 = require("@naman_deep_singh/cache");
|
|
43
41
|
const crypto_1 = __importDefault(require("crypto"));
|
|
42
|
+
const cache_1 = require("@naman_deep_singh/cache");
|
|
43
|
+
const express_1 = __importStar(require("express"));
|
|
44
44
|
const periodic_health_1 = require("./periodic-health");
|
|
45
45
|
const shutdown_1 = require("./shutdown");
|
|
46
|
+
const middleware_1 = require("../middleware");
|
|
46
47
|
class ExpressServer {
|
|
47
48
|
constructor(name = 'Express Server', version = '1.0.0', config = {}) {
|
|
48
49
|
this.status = 'stopped';
|
|
@@ -64,7 +65,7 @@ class ExpressServer {
|
|
|
64
65
|
socketIO: config.socketIO,
|
|
65
66
|
periodicHealthCheck: config.periodicHealthCheck || { enabled: false },
|
|
66
67
|
cache: config.cache || { enabled: false },
|
|
67
|
-
session: config.session || { enabled: false }
|
|
68
|
+
session: config.session || { enabled: false },
|
|
68
69
|
};
|
|
69
70
|
// Initialize locals for cache/session
|
|
70
71
|
this.app.locals.cache = undefined;
|
|
@@ -112,21 +113,24 @@ class ExpressServer {
|
|
|
112
113
|
}
|
|
113
114
|
}
|
|
114
115
|
// Apply custom middleware
|
|
115
|
-
if (this.config.customMiddleware &&
|
|
116
|
-
this.config.customMiddleware.
|
|
116
|
+
if (this.config.customMiddleware &&
|
|
117
|
+
this.config.customMiddleware.length > 0) {
|
|
118
|
+
this.config.customMiddleware.forEach((middleware) => {
|
|
117
119
|
this.app.use(middleware);
|
|
118
120
|
});
|
|
119
121
|
}
|
|
120
122
|
// Add health check if enabled
|
|
121
123
|
if (this.config.healthCheck) {
|
|
122
|
-
const healthPath = typeof this.config.healthCheck === 'string'
|
|
124
|
+
const healthPath = typeof this.config.healthCheck === 'string'
|
|
125
|
+
? this.config.healthCheck
|
|
126
|
+
: '/health';
|
|
123
127
|
this.app.get(healthPath, async (req, res) => {
|
|
124
128
|
const base = {
|
|
125
129
|
status: 'healthy',
|
|
126
130
|
service: this.config.name,
|
|
127
131
|
version: this.config.version,
|
|
128
132
|
uptime: Date.now() - this.config.startTime.getTime(),
|
|
129
|
-
timestamp: new Date().toISOString()
|
|
133
|
+
timestamp: new Date().toISOString(),
|
|
130
134
|
};
|
|
131
135
|
// If cache is enabled, include its health
|
|
132
136
|
const cache = req.app.locals.cache;
|
|
@@ -135,7 +139,12 @@ class ExpressServer {
|
|
|
135
139
|
base.cache = await cache.isAlive();
|
|
136
140
|
}
|
|
137
141
|
catch (e) {
|
|
138
|
-
base.cache = {
|
|
142
|
+
base.cache = {
|
|
143
|
+
isAlive: false,
|
|
144
|
+
adapter: 'unknown',
|
|
145
|
+
timestamp: new Date(),
|
|
146
|
+
error: e.message,
|
|
147
|
+
};
|
|
139
148
|
}
|
|
140
149
|
}
|
|
141
150
|
res.status(200).json(base);
|
|
@@ -154,7 +163,11 @@ class ExpressServer {
|
|
|
154
163
|
}
|
|
155
164
|
console.log(`🔄 [${serverName}] Initializing cache adapter: ${config.cache.adapter || 'memory'}...`);
|
|
156
165
|
// Use createWithFallback to prefer primary and fall back to memory when configured
|
|
157
|
-
const cfg = {
|
|
166
|
+
const cfg = {
|
|
167
|
+
...(cacheConfig || {}),
|
|
168
|
+
ttl: cacheConfig?.ttl ??
|
|
169
|
+
config.cache?.defaultTTL,
|
|
170
|
+
};
|
|
158
171
|
const cache = await cache_1.CacheFactory.createWithFallback(cfg);
|
|
159
172
|
this.app.locals.cache = cache;
|
|
160
173
|
this.cache = cache;
|
|
@@ -164,7 +177,7 @@ class ExpressServer {
|
|
|
164
177
|
req.cache = cache;
|
|
165
178
|
next();
|
|
166
179
|
});
|
|
167
|
-
console.log(`✅ [${serverName}] Cache initialized successfully (adapter: ${
|
|
180
|
+
console.log(`✅ [${serverName}] Cache initialized successfully (adapter: ${cacheConfig.adapter || 'memory'})`);
|
|
168
181
|
}
|
|
169
182
|
catch (err) {
|
|
170
183
|
console.error(`❌ [${serverName}] Failed to initialize cache (fallback to memory if enabled):`, err instanceof Error ? err.message : err);
|
|
@@ -173,7 +186,8 @@ class ExpressServer {
|
|
|
173
186
|
}
|
|
174
187
|
// Initialize session if enabled
|
|
175
188
|
if (config.session && config.session.enabled) {
|
|
176
|
-
const cookieName = config.session.cookieName ||
|
|
189
|
+
const cookieName = config.session.cookieName ||
|
|
190
|
+
`${serverName.replace(/\s+/g, '_').toLowerCase()}.sid`;
|
|
177
191
|
const ttl = config.session.ttl ?? 3600;
|
|
178
192
|
let cache = this.app.locals.cache;
|
|
179
193
|
if (!cache) {
|
|
@@ -201,9 +215,7 @@ class ExpressServer {
|
|
|
201
215
|
this.sessionStore = store;
|
|
202
216
|
// attach session middleware globally so req.sessionStore is available
|
|
203
217
|
try {
|
|
204
|
-
|
|
205
|
-
const { useSession } = require('../middleware/middleware');
|
|
206
|
-
this.app.use(useSession(cookieName));
|
|
218
|
+
this.app.use((0, middleware_1.useSession)(cookieName));
|
|
207
219
|
console.log(`✅ [${serverName}] Session middleware enabled (cookie: ${cookieName}, TTL: ${ttl}s)`);
|
|
208
220
|
}
|
|
209
221
|
catch (err) {
|
|
@@ -257,7 +269,7 @@ class ExpressServer {
|
|
|
257
269
|
catch (e) {
|
|
258
270
|
// SessionStore may not have close; ignore
|
|
259
271
|
}
|
|
260
|
-
}
|
|
272
|
+
},
|
|
261
273
|
});
|
|
262
274
|
}
|
|
263
275
|
// Start periodic health monitoring after server is running
|
|
@@ -307,7 +319,7 @@ class ExpressServer {
|
|
|
307
319
|
port: this.config.port,
|
|
308
320
|
uptime: Date.now() - this.config.startTime.getTime(),
|
|
309
321
|
status: this.status,
|
|
310
|
-
startTime: this.config.startTime
|
|
322
|
+
startTime: this.config.startTime,
|
|
311
323
|
};
|
|
312
324
|
}
|
|
313
325
|
addGrpcService(service, implementation, port = 50051) {
|
|
@@ -315,7 +327,6 @@ class ExpressServer {
|
|
|
315
327
|
// Lazy load gRPC to avoid dependency issues
|
|
316
328
|
if (!this.grpcServer) {
|
|
317
329
|
try {
|
|
318
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
319
330
|
const grpc = require('@grpc/grpc-js');
|
|
320
331
|
this.grpcServer = new grpc.Server();
|
|
321
332
|
// Add all services
|
|
@@ -335,7 +346,6 @@ class ExpressServer {
|
|
|
335
346
|
addRpcMethods(methods, path = '/rpc') {
|
|
336
347
|
Object.assign(this.rpcMethods, methods);
|
|
337
348
|
try {
|
|
338
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
339
349
|
const jayson = require('jayson');
|
|
340
350
|
const rpcServer = jayson.server(this.rpcMethods);
|
|
341
351
|
this.app.use(path, rpcServer.middleware());
|
|
@@ -350,13 +360,16 @@ class ExpressServer {
|
|
|
350
360
|
try {
|
|
351
361
|
// Verify signature if secret provided
|
|
352
362
|
if (config.secret) {
|
|
353
|
-
const signature = req.headers['x-hub-signature-256'] ||
|
|
363
|
+
const signature = req.headers['x-hub-signature-256'] ||
|
|
364
|
+
req.headers['x-signature-256'];
|
|
354
365
|
if (signature) {
|
|
355
366
|
const expectedSignature = crypto_1.default
|
|
356
367
|
.createHmac('sha256', config.secret)
|
|
357
368
|
.update(req.body)
|
|
358
369
|
.digest('hex');
|
|
359
|
-
const providedSignature = Array.isArray(signature)
|
|
370
|
+
const providedSignature = Array.isArray(signature)
|
|
371
|
+
? signature[0]
|
|
372
|
+
: signature;
|
|
360
373
|
if (!providedSignature.includes(expectedSignature)) {
|
|
361
374
|
return res.status(401).json({ error: 'Invalid signature' });
|
|
362
375
|
}
|
|
@@ -380,7 +393,6 @@ class ExpressServer {
|
|
|
380
393
|
throw new Error(`${this.config.name}: Server must be started before adding Socket.IO`);
|
|
381
394
|
}
|
|
382
395
|
try {
|
|
383
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
384
396
|
const { Server } = require('socket.io');
|
|
385
397
|
// Configure CORS
|
|
386
398
|
const corsConfig = config.cors === true
|
|
@@ -389,7 +401,7 @@ class ExpressServer {
|
|
|
389
401
|
// Create Socket.IO server
|
|
390
402
|
const io = new Server(this.server, {
|
|
391
403
|
cors: config.cors ? corsConfig : undefined,
|
|
392
|
-
path: config.path || '/socket.io'
|
|
404
|
+
path: config.path || '/socket.io',
|
|
393
405
|
});
|
|
394
406
|
// Store reference for cleanup
|
|
395
407
|
this.socketIO = io;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Server } from 'http';
|
|
2
|
-
import { GracefulShutdownConfig, ServerPlugin } from '../types';
|
|
1
|
+
import type { Server } from 'http';
|
|
2
|
+
import type { GracefulShutdownConfig, ServerPlugin } from '../types';
|
|
3
3
|
export declare function createGracefulShutdown(server: Server, config?: GracefulShutdownConfig): void;
|
|
4
4
|
export declare function withGracefulShutdown(config?: GracefulShutdownConfig): ServerPlugin;
|
|
5
5
|
export declare function startServerWithShutdown(app: import('express').Application, port: number, shutdownConfig?: GracefulShutdownConfig, serverName?: string, serverVersion?: string): Server;
|
|
@@ -37,6 +37,7 @@ function withGracefulShutdown(config = {}) {
|
|
|
37
37
|
return (app, serverConfig) => {
|
|
38
38
|
// This plugin needs to be applied after server.listen()
|
|
39
39
|
// Store config for later use
|
|
40
|
+
;
|
|
40
41
|
app.__gracefulShutdownConfig = config;
|
|
41
42
|
};
|
|
42
43
|
}
|
|
@@ -50,7 +51,7 @@ function startServerWithShutdown(app, port, shutdownConfig = {}, serverName, ser
|
|
|
50
51
|
const enhancedConfig = {
|
|
51
52
|
...config,
|
|
52
53
|
serverName,
|
|
53
|
-
serverVersion
|
|
54
|
+
serverVersion,
|
|
54
55
|
};
|
|
55
56
|
createGracefulShutdown(server, enhancedConfig);
|
|
56
57
|
return server;
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
export { ExpressServer, createServer } from './core/server';
|
|
2
|
-
export type { ServerInstance, ServerInfo, GrpcService, RpcMethod, WebhookConfig } 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 './core/health';
|
|
6
|
-
export { createGracefulShutdown, withGracefulShutdown, startServerWithShutdown } from './core/shutdown';
|
|
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/utils';
|
|
5
|
+
export { createHealthCheck, withHealthCheck, addHealthCheck, } from './core/health';
|
|
6
|
+
export { createGracefulShutdown, withGracefulShutdown, startServerWithShutdown, } from './core/shutdown';
|
|
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/utils';
|
|
9
9
|
export { PeriodicHealthMonitor } from './core/periodic-health';
|
|
10
|
-
export type { ServerConfig, HealthCheckConfig, HealthCheck, GracefulShutdownConfig, ServerPlugin, SocketIOConfig, SocketInstance, PeriodicHealthCheckConfig, HealthCheckService } from './types';
|
|
11
|
-
import {
|
|
12
|
-
import { createHealthCheck, withHealthCheck, addHealthCheck } from './core/health';
|
|
13
|
-
import { createGracefulShutdown, withGracefulShutdown, startServerWithShutdown } from './core/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/utils';
|
|
10
|
+
export type { ServerConfig, HealthCheckConfig, HealthCheck, GracefulShutdownConfig, ServerPlugin, SocketIOConfig, SocketInstance, PeriodicHealthCheckConfig, HealthCheckService, } from './types';
|
|
11
|
+
import { addHealthCheck, createHealthCheck, withHealthCheck } from './core/health';
|
|
16
12
|
import { PeriodicHealthMonitor } from './core/periodic-health';
|
|
13
|
+
import { ExpressServer, createServer } from './core/server';
|
|
14
|
+
import { createGracefulShutdown, startServerWithShutdown, withGracefulShutdown } from './core/shutdown';
|
|
15
|
+
import { createAuthMiddleware, createErrorHandler, createLoggingMiddleware, createRateLimitMiddleware, createRequestIdMiddleware, createValidationMiddleware, rateLimit, requireAuth, validateFields, withAuth, withErrorHandler, withLogging, withRateLimit, withRequestId, withValidation } from './middleware';
|
|
16
|
+
import { getEnv, getEnvBoolean, getEnvNumber } from './utils/utils';
|
|
17
17
|
declare const ServerUtils: {
|
|
18
18
|
createServer: typeof createServer;
|
|
19
19
|
ExpressServer: typeof ExpressServer;
|
package/dist/cjs/index.js
CHANGED
|
@@ -45,13 +45,13 @@ Object.defineProperty(exports, "getEnvBoolean", { enumerable: true, get: functio
|
|
|
45
45
|
// Periodic health monitoring
|
|
46
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
|
+
const health_2 = require("./core/health");
|
|
49
|
+
const periodic_health_2 = require("./core/periodic-health");
|
|
48
50
|
// Import all exports for default export
|
|
49
51
|
const server_2 = require("./core/server");
|
|
50
|
-
const health_2 = require("./core/health");
|
|
51
52
|
const shutdown_2 = require("./core/shutdown");
|
|
52
53
|
const middleware_2 = require("./middleware");
|
|
53
54
|
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
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createAuthMiddleware = createAuthMiddleware;
|
|
4
|
-
const security_1 = require("@naman_deep_singh/security");
|
|
5
4
|
const errors_utils_1 = require("@naman_deep_singh/errors-utils");
|
|
5
|
+
const security_1 = require("@naman_deep_singh/security");
|
|
6
6
|
function createAuthMiddleware(config) {
|
|
7
7
|
const { secret, unauthorizedMessage = 'Unauthorized access', tokenExtractor = (req) => (0, security_1.extractToken)({
|
|
8
8
|
header: req.headers.authorization || undefined,
|
|
9
9
|
cookies: req.cookies,
|
|
10
10
|
query: req.query,
|
|
11
|
-
body: req.body
|
|
12
|
-
}) } = config;
|
|
11
|
+
body: req.body,
|
|
12
|
+
}), } = config;
|
|
13
13
|
return async (req, res, next) => {
|
|
14
14
|
try {
|
|
15
15
|
// Extract token from request
|
|
16
16
|
const token = tokenExtractor(req);
|
|
17
17
|
if (!token) {
|
|
18
18
|
const error = new errors_utils_1.UnauthorizedError(unauthorizedMessage, {
|
|
19
|
-
reason: 'No token provided'
|
|
19
|
+
reason: 'No token provided',
|
|
20
20
|
});
|
|
21
21
|
return next(error);
|
|
22
22
|
}
|
|
@@ -25,7 +25,7 @@ function createAuthMiddleware(config) {
|
|
|
25
25
|
if (!result.valid) {
|
|
26
26
|
const error = new errors_utils_1.UnauthorizedError(unauthorizedMessage, {
|
|
27
27
|
reason: 'Invalid or expired token',
|
|
28
|
-
originalError: result.error?.message
|
|
28
|
+
originalError: result.error?.message,
|
|
29
29
|
});
|
|
30
30
|
return next(error);
|
|
31
31
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RequestHandler } from
|
|
1
|
+
import type { RequestHandler } from 'node_modules/@types/express';
|
|
2
2
|
export declare function cacheResponse(ttl?: number): RequestHandler;
|
|
@@ -28,12 +28,14 @@ function cacheResponse(ttl) {
|
|
|
28
28
|
try {
|
|
29
29
|
const expiry = ttl ?? defaultTTL;
|
|
30
30
|
if (expiry && cache && typeof cache.set === 'function') {
|
|
31
|
+
;
|
|
31
32
|
cache.set(key, body, expiry).catch((err) => {
|
|
32
33
|
console.error(`[Cache] Failed to set key "${key}" with TTL ${expiry}:`, err);
|
|
33
34
|
});
|
|
34
35
|
}
|
|
35
36
|
else if (cache) {
|
|
36
37
|
if (typeof cache.set === 'function') {
|
|
38
|
+
;
|
|
37
39
|
cache.set(key, body).catch((err) => {
|
|
38
40
|
console.error(`[Cache] Failed to set key "${key}":`, err);
|
|
39
41
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ErrorRequestHandler } from
|
|
1
|
+
import type { ErrorRequestHandler } from 'node_modules/@types/express';
|
|
2
2
|
export declare function createErrorHandler(): ErrorRequestHandler;
|
|
@@ -20,9 +20,11 @@ function createErrorHandler() {
|
|
|
20
20
|
data: undefined,
|
|
21
21
|
error: {
|
|
22
22
|
message,
|
|
23
|
-
...(process.env.NODE_ENV !== 'production' && {
|
|
23
|
+
...(process.env.NODE_ENV !== 'production' && {
|
|
24
|
+
details: { stack: errorObj.stack },
|
|
25
|
+
}),
|
|
24
26
|
},
|
|
25
|
-
meta: null
|
|
27
|
+
meta: null,
|
|
26
28
|
});
|
|
27
29
|
};
|
|
28
30
|
}
|
|
@@ -2,9 +2,9 @@ export { AuthConfig, createAuthMiddleware } from './auth.middleware';
|
|
|
2
2
|
export { cacheResponse } from './cache.middleware';
|
|
3
3
|
export { createErrorHandler } from './errorHandler.middleware';
|
|
4
4
|
export { createLoggingMiddleware } from './logging.middleware';
|
|
5
|
-
export { RateLimitConfig, createRateLimitMiddleware } from './rateLimiter.middleware';
|
|
5
|
+
export { RateLimitConfig, createRateLimitMiddleware, } from './rateLimiter.middleware';
|
|
6
6
|
export { createRequestIdMiddleware } from './requestId.middleware';
|
|
7
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';
|
|
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';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RequestHandler } from
|
|
1
|
+
import type { RequestHandler } from 'node_modules/@types/express';
|
|
2
2
|
export declare function createLoggingMiddleware(format?: 'simple' | 'detailed'): RequestHandler;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { RequestHandler } from 'express';
|
|
2
|
-
import { ServerPlugin } from '../types';
|
|
3
|
-
import {
|
|
4
|
-
import { RateLimitConfig } from './rateLimiter.middleware';
|
|
5
|
-
import {
|
|
1
|
+
import type { RequestHandler } from 'express';
|
|
2
|
+
import type { ServerPlugin } from '../types';
|
|
3
|
+
import type { AuthConfig } from './auth.middleware';
|
|
4
|
+
import type { RateLimitConfig } from './rateLimiter.middleware';
|
|
5
|
+
import type { ValidationRule } from './validation.middleware';
|
|
6
6
|
export declare function withLogging(format?: 'simple' | 'detailed'): ServerPlugin;
|
|
7
7
|
export declare function withErrorHandler(): ServerPlugin;
|
|
8
8
|
export declare function withRequestId(): ServerPlugin;
|
|
@@ -9,12 +9,12 @@ exports.withAuth = withAuth;
|
|
|
9
9
|
exports.validateFields = validateFields;
|
|
10
10
|
exports.rateLimit = rateLimit;
|
|
11
11
|
exports.requireAuth = requireAuth;
|
|
12
|
-
const
|
|
12
|
+
const auth_middleware_1 = require("./auth.middleware");
|
|
13
13
|
const errorHandler_middleware_1 = require("./errorHandler.middleware");
|
|
14
|
+
const logging_middleware_1 = require("./logging.middleware");
|
|
15
|
+
const rateLimiter_middleware_1 = require("./rateLimiter.middleware");
|
|
14
16
|
const requestId_middleware_1 = require("./requestId.middleware");
|
|
15
17
|
const validation_middleware_1 = require("./validation.middleware");
|
|
16
|
-
const rateLimiter_middleware_1 = require("./rateLimiter.middleware");
|
|
17
|
-
const auth_middleware_1 = require("./auth.middleware");
|
|
18
18
|
// Plugin versions
|
|
19
19
|
function withLogging(format = 'simple') {
|
|
20
20
|
return (app) => {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createRateLimitMiddleware = createRateLimitMiddleware;
|
|
4
4
|
const rateLimitStore = new Map();
|
|
5
5
|
function createRateLimitMiddleware(config = {}) {
|
|
6
|
-
const { windowMs = 15 * 60 * 1000, maxRequests = 100, message = 'Too many requests, please try again later', keyGenerator = (req) => req.ip || 'unknown' } = config;
|
|
6
|
+
const { windowMs = 15 * 60 * 1000, maxRequests = 100, message = 'Too many requests, please try again later', keyGenerator = (req) => req.ip || 'unknown', } = config;
|
|
7
7
|
return (req, res, next) => {
|
|
8
8
|
const key = keyGenerator(req);
|
|
9
9
|
const now = Date.now();
|
|
@@ -11,7 +11,7 @@ function createRateLimitMiddleware(config = {}) {
|
|
|
11
11
|
if (!record || now > record.resetTime) {
|
|
12
12
|
rateLimitStore.set(key, {
|
|
13
13
|
count: 1,
|
|
14
|
-
resetTime: now + windowMs
|
|
14
|
+
resetTime: now + windowMs,
|
|
15
15
|
});
|
|
16
16
|
return next();
|
|
17
17
|
}
|
|
@@ -23,10 +23,10 @@ function createRateLimitMiddleware(config = {}) {
|
|
|
23
23
|
error: {
|
|
24
24
|
message,
|
|
25
25
|
details: {
|
|
26
|
-
retryAfter: Math.ceil((record.resetTime - now) / 1000)
|
|
27
|
-
}
|
|
26
|
+
retryAfter: Math.ceil((record.resetTime - now) / 1000),
|
|
27
|
+
},
|
|
28
28
|
},
|
|
29
|
-
meta: null
|
|
29
|
+
meta: null,
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
32
|
record.count++;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RequestHandler } from
|
|
1
|
+
import type { RequestHandler } from 'node_modules/@types/express';
|
|
2
2
|
export declare function createRequestIdMiddleware(): RequestHandler;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RequestHandler } from
|
|
1
|
+
import type { RequestHandler } from 'node_modules/@types/express';
|
|
2
2
|
export declare function useSession(cookieName?: string): RequestHandler;
|
|
@@ -13,7 +13,10 @@ function useSession(cookieName) {
|
|
|
13
13
|
if (!sid) {
|
|
14
14
|
const cookieHeader = req.headers.cookie;
|
|
15
15
|
if (cookieHeader) {
|
|
16
|
-
const match = cookieHeader
|
|
16
|
+
const match = cookieHeader
|
|
17
|
+
.split(';')
|
|
18
|
+
.map((s) => s.trim())
|
|
19
|
+
.find((s) => s.startsWith(`${name}=`));
|
|
17
20
|
if (match)
|
|
18
21
|
sid = match.split('=')[1];
|
|
19
22
|
}
|
|
@@ -7,7 +7,8 @@ function createValidationMiddleware(rules) {
|
|
|
7
7
|
const errors = [];
|
|
8
8
|
for (const rule of rules) {
|
|
9
9
|
const value = req.body[rule.field];
|
|
10
|
-
if (rule.required &&
|
|
10
|
+
if (rule.required &&
|
|
11
|
+
(value === undefined || value === null || value === '')) {
|
|
11
12
|
errors.push(`${rule.field} is required`);
|
|
12
13
|
continue;
|
|
13
14
|
}
|
|
@@ -57,7 +58,7 @@ function createValidationMiddleware(rules) {
|
|
|
57
58
|
if (errors.length > 0) {
|
|
58
59
|
// Use ValidationError from errors-utils and let error middleware handle response
|
|
59
60
|
const validationError = new errors_utils_1.ValidationError('Validation failed', {
|
|
60
|
-
validationErrors: errors
|
|
61
|
+
validationErrors: errors,
|
|
61
62
|
});
|
|
62
63
|
return next(validationError);
|
|
63
64
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import express from 'express';
|
|
1
|
+
import type express from 'express';
|
|
2
2
|
export interface CorsOptions {
|
|
3
3
|
origin?: string | string[] | boolean | RegExp | ((origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) => void);
|
|
4
4
|
methods?: string | string[];
|
package/dist/cjs/utils/utils.js
CHANGED
|
@@ -36,8 +36,8 @@ function getEnvBoolean(key, defaultValue) {
|
|
|
36
36
|
return defaultValue;
|
|
37
37
|
}
|
|
38
38
|
const normalized = value.toLowerCase();
|
|
39
|
-
if (normalized !==
|
|
39
|
+
if (normalized !== 'true' && normalized !== 'false') {
|
|
40
40
|
throw new Error(`Environment variable ${key} must be 'true' or 'false'`);
|
|
41
41
|
}
|
|
42
|
-
return normalized ===
|
|
42
|
+
return normalized === 'true';
|
|
43
43
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Application, RequestHandler } from 'express';
|
|
2
|
-
import { HealthCheckConfig, ServerPlugin } from '../types';
|
|
1
|
+
import type { Application, RequestHandler } from 'express';
|
|
2
|
+
import type { HealthCheckConfig, ServerPlugin } from '../types';
|
|
3
3
|
export declare function createHealthCheck(config?: HealthCheckConfig): RequestHandler;
|
|
4
4
|
export declare function withHealthCheck(path?: string, config?: HealthCheckConfig): ServerPlugin;
|
|
5
5
|
export declare function addHealthCheck(app: Application, path?: string, config?: HealthCheckConfig): void;
|