@naman_deep_singh/server-utils 1.2.0 → 1.3.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 +17 -58
- package/dist/cjs/middleware.js +9 -7
- package/dist/cjs/server.d.ts +2 -0
- package/dist/cjs/server.js +3 -5
- package/dist/cjs/shutdown.d.ts +1 -1
- package/dist/esm/middleware.js +9 -7
- package/dist/esm/server.d.ts +2 -0
- package/dist/esm/server.js +3 -5
- package/dist/esm/shutdown.d.ts +1 -1
- package/dist/types/server.d.ts +2 -0
- package/dist/types/shutdown.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @naman_deep_singh/server-utils
|
|
2
2
|
|
|
3
|
-
**Version:** 1.
|
|
3
|
+
**Version:** 1.3.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
|
|
@@ -184,52 +173,16 @@ server.app.use('/protected', requireAuth({
|
|
|
184
173
|
|
|
185
174
|
## Health Checks
|
|
186
175
|
|
|
176
|
+
|
|
187
177
|
### Basic Health Check
|
|
188
178
|
```typescript
|
|
189
|
-
import {
|
|
179
|
+
import { createHealthCheck } from '@naman_deep_singh/server-utils';
|
|
190
180
|
|
|
191
|
-
//
|
|
192
|
-
|
|
181
|
+
// The health check is automatically enabled when healthCheck is not false
|
|
182
|
+
// Health endpoint is available at /health by default
|
|
193
183
|
|
|
194
|
-
//
|
|
184
|
+
// If you need to customize or disable it:
|
|
195
185
|
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
186
|
```
|
|
234
187
|
|
|
235
188
|
## Server Management
|
|
@@ -332,6 +285,12 @@ import { Request, Response, NextFunction, Router, Application } from '@naman_dee
|
|
|
332
285
|
import type { RequestHandler, ErrorRequestHandler } from '@naman_deep_singh/server-utils';
|
|
333
286
|
|
|
334
287
|
// No need to install Express separately in your services
|
|
288
|
+
|
|
289
|
+
## TypeScript Notes
|
|
290
|
+
|
|
291
|
+
- 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.
|
|
292
|
+
- Middleware that attaches runtime props uses `unknown` internally and runtime guards — prefer the provided helpers rather than casting `req` to `any`.
|
|
293
|
+
|
|
335
294
|
```
|
|
336
295
|
|
|
337
296
|
## API Reference
|
package/dist/cjs/middleware.js
CHANGED
|
@@ -252,9 +252,9 @@ function cacheResponse(ttl) {
|
|
|
252
252
|
try {
|
|
253
253
|
if (req.method !== 'GET')
|
|
254
254
|
return next();
|
|
255
|
-
const cache = req.cache
|
|
255
|
+
const cache = (req.cache ?? req.app.locals.cache);
|
|
256
256
|
const defaultTTL = req.app.locals.cacheDefaultTTL;
|
|
257
|
-
if (!cache)
|
|
257
|
+
if (!cache || typeof cache.get !== 'function')
|
|
258
258
|
return next();
|
|
259
259
|
const key = `${req.originalUrl}`;
|
|
260
260
|
try {
|
|
@@ -272,15 +272,17 @@ function cacheResponse(ttl) {
|
|
|
272
272
|
res.json = (body) => {
|
|
273
273
|
try {
|
|
274
274
|
const expiry = ttl ?? defaultTTL;
|
|
275
|
-
if (expiry && cache) {
|
|
275
|
+
if (expiry && cache && typeof cache.set === 'function') {
|
|
276
276
|
cache.set(key, body, expiry).catch((err) => {
|
|
277
277
|
console.error(`[Cache] Failed to set key "${key}" with TTL ${expiry}:`, err);
|
|
278
278
|
});
|
|
279
279
|
}
|
|
280
280
|
else if (cache) {
|
|
281
|
-
cache.set
|
|
282
|
-
|
|
283
|
-
|
|
281
|
+
if (typeof cache.set === 'function') {
|
|
282
|
+
cache.set(key, body).catch((err) => {
|
|
283
|
+
console.error(`[Cache] Failed to set key "${key}":`, err);
|
|
284
|
+
});
|
|
285
|
+
}
|
|
284
286
|
}
|
|
285
287
|
}
|
|
286
288
|
catch (e) {
|
|
@@ -305,7 +307,7 @@ function useSession(cookieName) {
|
|
|
305
307
|
if (!store)
|
|
306
308
|
return next();
|
|
307
309
|
const name = cookieName || req.app.locals.sessionCookieName || 'sid';
|
|
308
|
-
let sid = req.cookies?.[name]
|
|
310
|
+
let sid = req.cookies?.[name];
|
|
309
311
|
if (!sid) {
|
|
310
312
|
const cookieHeader = req.headers.cookie;
|
|
311
313
|
if (cookieHeader) {
|
package/dist/cjs/server.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export declare class ExpressServer implements ServerInstance {
|
|
|
49
49
|
app: express.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?;
|
package/dist/cjs/server.js
CHANGED
|
@@ -114,17 +114,15 @@ class ExpressServer {
|
|
|
114
114
|
// Initialize cache if enabled
|
|
115
115
|
if (config.cache && config.cache.enabled) {
|
|
116
116
|
try {
|
|
117
|
-
const provided = config.cache
|
|
117
|
+
const provided = config.cache?.options;
|
|
118
118
|
let cacheConfig = provided && typeof provided === 'object' ? provided : undefined;
|
|
119
119
|
if (!cacheConfig) {
|
|
120
120
|
cacheConfig = { adapter: config.cache.adapter || 'memory' };
|
|
121
121
|
}
|
|
122
122
|
console.log(`🔄 [${serverName}] Initializing cache adapter: ${config.cache.adapter || 'memory'}...`);
|
|
123
123
|
// Use createWithFallback to prefer primary and fall back to memory when configured
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
ttl: cacheConfig?.ttl ?? config.cache?.defaultTTL
|
|
127
|
-
});
|
|
124
|
+
const cfg = { ...(cacheConfig || {}), ttl: cacheConfig?.ttl ?? config.cache?.defaultTTL };
|
|
125
|
+
const cache = await cache_1.CacheFactory.createWithFallback(cfg);
|
|
128
126
|
this.app.locals.cache = cache;
|
|
129
127
|
this.cache = cache;
|
|
130
128
|
this.app.locals.cacheDefaultTTL = config.cache?.defaultTTL;
|
package/dist/cjs/shutdown.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ import { Server } from 'http';
|
|
|
2
2
|
import { 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
|
-
export declare function startServerWithShutdown(app:
|
|
5
|
+
export declare function startServerWithShutdown(app: import('express').Application, port: number, shutdownConfig?: GracefulShutdownConfig, serverName?: string, serverVersion?: string): Server;
|
package/dist/esm/middleware.js
CHANGED
|
@@ -233,9 +233,9 @@ export function cacheResponse(ttl) {
|
|
|
233
233
|
try {
|
|
234
234
|
if (req.method !== 'GET')
|
|
235
235
|
return next();
|
|
236
|
-
const cache = req.cache
|
|
236
|
+
const cache = (req.cache ?? req.app.locals.cache);
|
|
237
237
|
const defaultTTL = req.app.locals.cacheDefaultTTL;
|
|
238
|
-
if (!cache)
|
|
238
|
+
if (!cache || typeof cache.get !== 'function')
|
|
239
239
|
return next();
|
|
240
240
|
const key = `${req.originalUrl}`;
|
|
241
241
|
try {
|
|
@@ -253,15 +253,17 @@ export function cacheResponse(ttl) {
|
|
|
253
253
|
res.json = (body) => {
|
|
254
254
|
try {
|
|
255
255
|
const expiry = ttl ?? defaultTTL;
|
|
256
|
-
if (expiry && cache) {
|
|
256
|
+
if (expiry && cache && typeof cache.set === 'function') {
|
|
257
257
|
cache.set(key, body, expiry).catch((err) => {
|
|
258
258
|
console.error(`[Cache] Failed to set key "${key}" with TTL ${expiry}:`, err);
|
|
259
259
|
});
|
|
260
260
|
}
|
|
261
261
|
else if (cache) {
|
|
262
|
-
cache.set
|
|
263
|
-
|
|
264
|
-
|
|
262
|
+
if (typeof cache.set === 'function') {
|
|
263
|
+
cache.set(key, body).catch((err) => {
|
|
264
|
+
console.error(`[Cache] Failed to set key "${key}":`, err);
|
|
265
|
+
});
|
|
266
|
+
}
|
|
265
267
|
}
|
|
266
268
|
}
|
|
267
269
|
catch (e) {
|
|
@@ -286,7 +288,7 @@ export function useSession(cookieName) {
|
|
|
286
288
|
if (!store)
|
|
287
289
|
return next();
|
|
288
290
|
const name = cookieName || req.app.locals.sessionCookieName || 'sid';
|
|
289
|
-
let sid = req.cookies?.[name]
|
|
291
|
+
let sid = req.cookies?.[name];
|
|
290
292
|
if (!sid) {
|
|
291
293
|
const cookieHeader = req.headers.cookie;
|
|
292
294
|
if (cookieHeader) {
|
package/dist/esm/server.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export declare class ExpressServer implements ServerInstance {
|
|
|
49
49
|
app: express.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?;
|
package/dist/esm/server.js
CHANGED
|
@@ -107,17 +107,15 @@ export class ExpressServer {
|
|
|
107
107
|
// Initialize cache if enabled
|
|
108
108
|
if (config.cache && config.cache.enabled) {
|
|
109
109
|
try {
|
|
110
|
-
const provided = config.cache
|
|
110
|
+
const provided = config.cache?.options;
|
|
111
111
|
let cacheConfig = provided && typeof provided === 'object' ? provided : undefined;
|
|
112
112
|
if (!cacheConfig) {
|
|
113
113
|
cacheConfig = { adapter: config.cache.adapter || 'memory' };
|
|
114
114
|
}
|
|
115
115
|
console.log(`🔄 [${serverName}] Initializing cache adapter: ${config.cache.adapter || 'memory'}...`);
|
|
116
116
|
// Use createWithFallback to prefer primary and fall back to memory when configured
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
ttl: cacheConfig?.ttl ?? config.cache?.defaultTTL
|
|
120
|
-
});
|
|
117
|
+
const cfg = { ...(cacheConfig || {}), ttl: cacheConfig?.ttl ?? config.cache?.defaultTTL };
|
|
118
|
+
const cache = await CacheFactory.createWithFallback(cfg);
|
|
121
119
|
this.app.locals.cache = cache;
|
|
122
120
|
this.cache = cache;
|
|
123
121
|
this.app.locals.cacheDefaultTTL = config.cache?.defaultTTL;
|
package/dist/esm/shutdown.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ import { Server } from 'http';
|
|
|
2
2
|
import { 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
|
-
export declare function startServerWithShutdown(app:
|
|
5
|
+
export declare function startServerWithShutdown(app: import('express').Application, port: number, shutdownConfig?: GracefulShutdownConfig, serverName?: string, serverVersion?: string): Server;
|
package/dist/types/server.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export declare class ExpressServer implements ServerInstance {
|
|
|
49
49
|
app: express.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?;
|
package/dist/types/shutdown.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ import { Server } from 'http';
|
|
|
2
2
|
import { 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
|
-
export declare function startServerWithShutdown(app:
|
|
5
|
+
export declare function startServerWithShutdown(app: import('express').Application, port: number, shutdownConfig?: GracefulShutdownConfig, serverName?: string, serverVersion?: string): Server;
|