@naman_deep_singh/server-utils 1.0.8 → 1.2.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 +401 -11
- package/dist/{index.d.ts → cjs/index.d.ts} +1 -1
- package/dist/{index.js → cjs/index.js} +3 -1
- package/dist/{middleware.d.ts → cjs/middleware.d.ts} +2 -0
- package/dist/{middleware.js → cjs/middleware.js} +137 -10
- package/dist/{server.d.ts → cjs/server.d.ts} +1 -0
- package/dist/{server.js → cjs/server.js} +119 -4
- package/dist/{types.d.ts → cjs/types.d.ts} +17 -0
- 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 +39 -0
- package/dist/esm/middleware.js +327 -0
- package/dist/esm/periodic-health.d.ts +11 -0
- package/dist/esm/periodic-health.js +64 -0
- package/dist/esm/server.d.ts +70 -0
- package/dist/esm/server.js +386 -0
- package/dist/esm/shutdown.d.ts +5 -0
- package/dist/esm/shutdown.js +52 -0
- package/dist/esm/types.d.ts +87 -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 +39 -0
- package/dist/types/periodic-health.d.ts +11 -0
- package/dist/types/server.d.ts +70 -0
- package/dist/types/shutdown.d.ts +5 -0
- package/dist/types/types.d.ts +87 -0
- package/dist/types/utils.d.ts +3 -0
- package/package.json +26 -10
- package/src/health.ts +0 -47
- package/src/index.ts +0 -126
- package/src/middleware.ts +0 -275
- package/src/periodic-health.ts +0 -83
- 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/{periodic-health.d.ts → cjs/periodic-health.d.ts} +0 -0
- /package/dist/{periodic-health.js → cjs/periodic-health.js} +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.js → cjs/types.js} +0 -0
- /package/dist/{utils.d.ts → cjs/utils.d.ts} +0 -0
|
@@ -57,6 +57,7 @@ export declare class ExpressServer implements ServerInstance {
|
|
|
57
57
|
private healthMonitor?;
|
|
58
58
|
constructor(name?: string, version?: string, config?: ServerConfig);
|
|
59
59
|
private setupMiddleware;
|
|
60
|
+
private setupCacheAndSession;
|
|
60
61
|
private setupPeriodicHealthMonitoring;
|
|
61
62
|
start(): Promise<ServerInstance>;
|
|
62
63
|
stop(): Promise<void>;
|
|
@@ -9,6 +9,7 @@ const express_1 = __importDefault(require("express"));
|
|
|
9
9
|
const shutdown_1 = require("./shutdown");
|
|
10
10
|
const periodic_health_1 = require("./periodic-health");
|
|
11
11
|
const crypto_1 = __importDefault(require("crypto"));
|
|
12
|
+
const cache_1 = require("@naman_deep_singh/cache");
|
|
12
13
|
class ExpressServer {
|
|
13
14
|
constructor(name = 'Express Server', version = '1.0.0', config = {}) {
|
|
14
15
|
this.status = 'stopped';
|
|
@@ -28,8 +29,14 @@ class ExpressServer {
|
|
|
28
29
|
healthCheck: config.healthCheck ?? true,
|
|
29
30
|
gracefulShutdown: config.gracefulShutdown ?? true,
|
|
30
31
|
socketIO: config.socketIO,
|
|
31
|
-
periodicHealthCheck: config.periodicHealthCheck || { enabled: false }
|
|
32
|
+
periodicHealthCheck: config.periodicHealthCheck || { enabled: false },
|
|
33
|
+
cache: config.cache || { enabled: false },
|
|
34
|
+
session: config.session || { enabled: false }
|
|
32
35
|
};
|
|
36
|
+
// Initialize locals for cache/session
|
|
37
|
+
this.app.locals.cache = undefined;
|
|
38
|
+
this.app.locals.sessionStore = undefined;
|
|
39
|
+
this.app.locals.cacheDefaultTTL = config.cache?.defaultTTL;
|
|
33
40
|
// Apply middleware based on configuration
|
|
34
41
|
this.setupMiddleware();
|
|
35
42
|
// Setup periodic health monitoring
|
|
@@ -80,17 +87,104 @@ class ExpressServer {
|
|
|
80
87
|
// Add health check if enabled
|
|
81
88
|
if (this.config.healthCheck) {
|
|
82
89
|
const healthPath = typeof this.config.healthCheck === 'string' ? this.config.healthCheck : '/health';
|
|
83
|
-
this.app.get(healthPath, (req, res) => {
|
|
84
|
-
|
|
90
|
+
this.app.get(healthPath, async (req, res) => {
|
|
91
|
+
const base = {
|
|
85
92
|
status: 'healthy',
|
|
86
93
|
service: this.config.name,
|
|
87
94
|
version: this.config.version,
|
|
88
95
|
uptime: Date.now() - this.config.startTime.getTime(),
|
|
89
96
|
timestamp: new Date().toISOString()
|
|
90
|
-
}
|
|
97
|
+
};
|
|
98
|
+
// If cache is enabled, include its health
|
|
99
|
+
const cache = req.app.locals.cache;
|
|
100
|
+
if (cache && typeof cache.isAlive === 'function') {
|
|
101
|
+
try {
|
|
102
|
+
base.cache = await cache.isAlive();
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
base.cache = { isAlive: false, adapter: 'unknown', timestamp: new Date(), error: e.message };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
res.status(200).json(base);
|
|
91
109
|
});
|
|
92
110
|
}
|
|
93
111
|
}
|
|
112
|
+
async setupCacheAndSession(config, serverName) {
|
|
113
|
+
try {
|
|
114
|
+
// Initialize cache if enabled
|
|
115
|
+
if (config.cache && config.cache.enabled) {
|
|
116
|
+
try {
|
|
117
|
+
const provided = config.cache.options;
|
|
118
|
+
let cacheConfig = provided && typeof provided === 'object' ? provided : undefined;
|
|
119
|
+
if (!cacheConfig) {
|
|
120
|
+
cacheConfig = { adapter: config.cache.adapter || 'memory' };
|
|
121
|
+
}
|
|
122
|
+
console.log(`🔄 [${serverName}] Initializing cache adapter: ${config.cache.adapter || 'memory'}...`);
|
|
123
|
+
// Use createWithFallback to prefer primary and fall back to memory when configured
|
|
124
|
+
const cache = await cache_1.CacheFactory.createWithFallback({
|
|
125
|
+
...(cacheConfig || {}),
|
|
126
|
+
ttl: cacheConfig?.ttl ?? config.cache?.defaultTTL
|
|
127
|
+
});
|
|
128
|
+
this.app.locals.cache = cache;
|
|
129
|
+
this.cache = cache;
|
|
130
|
+
this.app.locals.cacheDefaultTTL = config.cache?.defaultTTL;
|
|
131
|
+
// attach per-request helper middleware
|
|
132
|
+
this.app.use((req, _res, next) => {
|
|
133
|
+
req.cache = cache;
|
|
134
|
+
next();
|
|
135
|
+
});
|
|
136
|
+
console.log(`✅ [${serverName}] Cache initialized successfully (adapter: ${(cacheConfig.adapter || 'memory')})`);
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
console.error(`❌ [${serverName}] Failed to initialize cache (fallback to memory if enabled):`, err instanceof Error ? err.message : err);
|
|
140
|
+
// Cache initialization error is critical but we continue to allow graceful fallback
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Initialize session if enabled
|
|
144
|
+
if (config.session && config.session.enabled) {
|
|
145
|
+
const cookieName = config.session.cookieName || `${serverName.replace(/\s+/g, '_').toLowerCase()}.sid`;
|
|
146
|
+
const ttl = config.session.ttl ?? 3600;
|
|
147
|
+
let cache = this.app.locals.cache;
|
|
148
|
+
if (!cache) {
|
|
149
|
+
// fallback to in-memory cache for session store
|
|
150
|
+
try {
|
|
151
|
+
cache = cache_1.CacheFactory.create({ adapter: 'memory' });
|
|
152
|
+
this.app.locals.cache = cache;
|
|
153
|
+
this.cache = cache;
|
|
154
|
+
console.log(`📝 [${serverName}] Session store using in-memory cache`);
|
|
155
|
+
}
|
|
156
|
+
catch (e) {
|
|
157
|
+
console.error(`❌ [${serverName}] Failed to create in-memory cache for sessions:`, e instanceof Error ? e.message : e);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
console.log(`📝 [${serverName}] Session store initialized with configured cache adapter`);
|
|
162
|
+
}
|
|
163
|
+
if (!cache) {
|
|
164
|
+
console.error(`❌ [${serverName}] CRITICAL: Session enabled but no cache available to store sessions. Session functionality will be unavailable.`);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
const store = new cache_1.SessionStore(cache, { ttl });
|
|
168
|
+
this.app.locals.sessionStore = store;
|
|
169
|
+
this.app.locals.sessionCookieName = cookieName;
|
|
170
|
+
this.sessionStore = store;
|
|
171
|
+
// attach session middleware globally so req.sessionStore is available
|
|
172
|
+
try {
|
|
173
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
174
|
+
const { useSession } = require('./middleware');
|
|
175
|
+
this.app.use(useSession(cookieName));
|
|
176
|
+
console.log(`✅ [${serverName}] Session middleware enabled (cookie: ${cookieName}, TTL: ${ttl}s)`);
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
console.error(`❌ [${serverName}] Session middleware not available:`, err instanceof Error ? err.message : err);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
console.error(`❌ [${serverName}] Error during cache/session setup:`, err instanceof Error ? err.message : err);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
94
188
|
setupPeriodicHealthMonitoring() {
|
|
95
189
|
if (this.config.periodicHealthCheck?.enabled) {
|
|
96
190
|
this.healthMonitor = new periodic_health_1.PeriodicHealthMonitor(this.config.periodicHealthCheck, this.config.name);
|
|
@@ -98,6 +192,8 @@ class ExpressServer {
|
|
|
98
192
|
}
|
|
99
193
|
async start() {
|
|
100
194
|
this.status = 'starting';
|
|
195
|
+
// Initialize cache and session before starting the server
|
|
196
|
+
await this.setupCacheAndSession(this.config, this.config.name);
|
|
101
197
|
return new Promise((resolve, reject) => {
|
|
102
198
|
try {
|
|
103
199
|
this.server = this.app.listen(this.config.port, () => {
|
|
@@ -111,6 +207,25 @@ class ExpressServer {
|
|
|
111
207
|
if (this.healthMonitor) {
|
|
112
208
|
this.healthMonitor.stop();
|
|
113
209
|
}
|
|
210
|
+
// Close cache and session store if present
|
|
211
|
+
try {
|
|
212
|
+
const cache = this.app.locals.cache;
|
|
213
|
+
if (cache && typeof cache.close === 'function') {
|
|
214
|
+
await cache.close();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch (e) {
|
|
218
|
+
console.warn(`${this.config.name}: Error closing cache`, e);
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
const store = this.app.locals.sessionStore;
|
|
222
|
+
if (store && typeof store.close === 'function') {
|
|
223
|
+
await store.close();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch (e) {
|
|
227
|
+
// SessionStore may not have close; ignore
|
|
228
|
+
}
|
|
114
229
|
}
|
|
115
230
|
});
|
|
116
231
|
}
|
|
@@ -22,6 +22,23 @@ export interface ServerConfig {
|
|
|
22
22
|
periodicHealthCheck?: PeriodicHealthCheckConfig;
|
|
23
23
|
name?: string;
|
|
24
24
|
version?: string;
|
|
25
|
+
cache?: {
|
|
26
|
+
enabled?: boolean;
|
|
27
|
+
adapter?: 'redis' | 'memcache' | 'memory';
|
|
28
|
+
options?: unknown;
|
|
29
|
+
defaultTTL?: number;
|
|
30
|
+
};
|
|
31
|
+
session?: {
|
|
32
|
+
enabled?: boolean;
|
|
33
|
+
cookieName?: string;
|
|
34
|
+
ttl?: number;
|
|
35
|
+
cookieOptions?: {
|
|
36
|
+
path?: string;
|
|
37
|
+
httpOnly?: boolean;
|
|
38
|
+
secure?: boolean;
|
|
39
|
+
sameSite?: 'lax' | 'strict' | 'none';
|
|
40
|
+
};
|
|
41
|
+
};
|
|
25
42
|
}
|
|
26
43
|
export interface PeriodicHealthCheckConfig {
|
|
27
44
|
enabled?: boolean;
|
|
@@ -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, cacheResponse, useSession, 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, cacheResponse, useSession } 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,39 @@
|
|
|
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;
|
|
38
|
+
export declare function cacheResponse(ttl?: number): express.RequestHandler;
|
|
39
|
+
export declare function useSession(cookieName?: string): express.RequestHandler;
|