@naman_deep_singh/server-utils 1.3.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 +19 -5
- package/dist/cjs/core/health.d.ts +5 -0
- package/dist/cjs/{health.js → core/health.js} +4 -4
- package/dist/cjs/{periodic-health.d.ts → core/periodic-health.d.ts} +1 -1
- package/dist/cjs/{periodic-health.js → core/periodic-health.js} +4 -4
- package/dist/{types → cjs/core}/server.d.ts +8 -7
- package/dist/cjs/{server.js → core/server.js} +70 -25
- package/dist/cjs/{shutdown.d.ts → core/shutdown.d.ts} +2 -2
- package/dist/cjs/{shutdown.js → core/shutdown.js} +2 -1
- package/dist/cjs/index.d.ts +14 -14
- 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 +58 -0
- package/dist/cjs/middleware/errorHandler.middleware.d.ts +2 -0
- package/dist/cjs/middleware/errorHandler.middleware.js +30 -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 +53 -0
- package/dist/cjs/middleware/validation.middleware.d.ts +11 -0
- package/dist/cjs/middleware/validation.middleware.js +67 -0
- package/dist/{esm/types.d.ts → cjs/types/index.d.ts} +1 -1
- package/dist/cjs/{utils.js → utils/utils.js} +2 -2
- package/dist/esm/core/health.d.ts +5 -0
- package/dist/esm/{health.js → core/health.js} +4 -4
- package/dist/esm/{periodic-health.d.ts → core/periodic-health.d.ts} +1 -1
- package/dist/esm/{periodic-health.js → core/periodic-health.js} +4 -4
- package/dist/esm/{server.d.ts → core/server.d.ts} +8 -7
- package/dist/esm/{server.js → core/server.js} +36 -24
- package/dist/esm/{shutdown.d.ts → core/shutdown.d.ts} +2 -2
- package/dist/esm/{shutdown.js → core/shutdown.js} +2 -1
- package/dist/esm/index.d.ts +14 -14
- package/dist/esm/index.js +12 -12
- 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 +55 -0
- package/dist/esm/middleware/errorHandler.middleware.d.ts +2 -0
- package/dist/esm/middleware/errorHandler.middleware.js +27 -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 +50 -0
- package/dist/esm/middleware/validation.middleware.d.ts +11 -0
- package/dist/esm/middleware/validation.middleware.js +64 -0
- package/dist/{types/types.d.ts → esm/types/index.d.ts} +1 -1
- package/dist/esm/{utils.js → utils/utils.js} +2 -2
- 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 +8 -7
- package/dist/types/{shutdown.d.ts → core/shutdown.d.ts} +2 -2
- package/dist/types/index.d.ts +14 -14
- 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/dist/{cjs/types.d.ts → types/types/index.d.ts} +1 -1
- package/package.json +4 -2
- package/dist/cjs/health.d.ts +0 -5
- package/dist/cjs/middleware.d.ts +0 -39
- package/dist/cjs/middleware.js +0 -348
- package/dist/esm/health.d.ts +0 -5
- package/dist/esm/middleware.d.ts +0 -39
- package/dist/esm/middleware.js +0 -329
- package/dist/types/health.d.ts +0 -5
- package/dist/types/middleware.d.ts +0 -39
- /package/dist/cjs/{types.js → types/index.js} +0 -0
- /package/dist/cjs/{utils.d.ts → utils/utils.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/types/{utils.d.ts → utils/utils.d.ts} +0 -0
|
@@ -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 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
|
+
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;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withLogging = withLogging;
|
|
4
|
+
exports.withErrorHandler = withErrorHandler;
|
|
5
|
+
exports.withRequestId = withRequestId;
|
|
6
|
+
exports.withValidation = withValidation;
|
|
7
|
+
exports.withRateLimit = withRateLimit;
|
|
8
|
+
exports.withAuth = withAuth;
|
|
9
|
+
exports.validateFields = validateFields;
|
|
10
|
+
exports.rateLimit = rateLimit;
|
|
11
|
+
exports.requireAuth = requireAuth;
|
|
12
|
+
const auth_middleware_1 = require("./auth.middleware");
|
|
13
|
+
const errorHandler_middleware_1 = require("./errorHandler.middleware");
|
|
14
|
+
const logging_middleware_1 = require("./logging.middleware");
|
|
15
|
+
const rateLimiter_middleware_1 = require("./rateLimiter.middleware");
|
|
16
|
+
const requestId_middleware_1 = require("./requestId.middleware");
|
|
17
|
+
const validation_middleware_1 = require("./validation.middleware");
|
|
18
|
+
// Plugin versions
|
|
19
|
+
function withLogging(format = 'simple') {
|
|
20
|
+
return (app) => {
|
|
21
|
+
app.use((0, logging_middleware_1.createLoggingMiddleware)(format));
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function withErrorHandler() {
|
|
25
|
+
return (app) => {
|
|
26
|
+
app.use((0, errorHandler_middleware_1.createErrorHandler)());
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function withRequestId() {
|
|
30
|
+
return (app) => {
|
|
31
|
+
app.use((0, requestId_middleware_1.createRequestIdMiddleware)());
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function withValidation(rules) {
|
|
35
|
+
return (app) => {
|
|
36
|
+
app.use((0, validation_middleware_1.createValidationMiddleware)(rules));
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function withRateLimit(config = {}) {
|
|
40
|
+
return (app) => {
|
|
41
|
+
app.use((0, rateLimiter_middleware_1.createRateLimitMiddleware)(config));
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function withAuth(config) {
|
|
45
|
+
return (app) => {
|
|
46
|
+
app.use((0, auth_middleware_1.createAuthMiddleware)(config));
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// Convenience functions for route-specific middleware
|
|
50
|
+
function validateFields(rules) {
|
|
51
|
+
return (0, validation_middleware_1.createValidationMiddleware)(rules);
|
|
52
|
+
}
|
|
53
|
+
function rateLimit(config = {}) {
|
|
54
|
+
return (0, rateLimiter_middleware_1.createRateLimitMiddleware)(config);
|
|
55
|
+
}
|
|
56
|
+
function requireAuth(config) {
|
|
57
|
+
return (0, auth_middleware_1.createAuthMiddleware)(config);
|
|
58
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Request, RequestHandler } from 'node_modules/@types/express';
|
|
2
|
+
export interface RateLimitConfig {
|
|
3
|
+
windowMs?: number;
|
|
4
|
+
maxRequests?: number;
|
|
5
|
+
message?: string;
|
|
6
|
+
keyGenerator?: (req: Request) => string;
|
|
7
|
+
}
|
|
8
|
+
export declare function createRateLimitMiddleware(config?: RateLimitConfig): RequestHandler;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRateLimitMiddleware = createRateLimitMiddleware;
|
|
4
|
+
const rateLimitStore = new Map();
|
|
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;
|
|
7
|
+
return (req, res, next) => {
|
|
8
|
+
const key = keyGenerator(req);
|
|
9
|
+
const now = Date.now();
|
|
10
|
+
const record = rateLimitStore.get(key);
|
|
11
|
+
if (!record || now > record.resetTime) {
|
|
12
|
+
rateLimitStore.set(key, {
|
|
13
|
+
count: 1,
|
|
14
|
+
resetTime: now + windowMs,
|
|
15
|
+
});
|
|
16
|
+
return next();
|
|
17
|
+
}
|
|
18
|
+
if (record.count >= maxRequests) {
|
|
19
|
+
return res.status(429).json({
|
|
20
|
+
success: false,
|
|
21
|
+
message,
|
|
22
|
+
data: undefined,
|
|
23
|
+
error: {
|
|
24
|
+
message,
|
|
25
|
+
details: {
|
|
26
|
+
retryAfter: Math.ceil((record.resetTime - now) / 1000),
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
meta: null,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
record.count++;
|
|
33
|
+
next();
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRequestIdMiddleware = createRequestIdMiddleware;
|
|
4
|
+
// Request ID middleware
|
|
5
|
+
function createRequestIdMiddleware() {
|
|
6
|
+
return (req, res, next) => {
|
|
7
|
+
const requestId = Math.random().toString(36).substring(2, 15);
|
|
8
|
+
req.requestId = requestId;
|
|
9
|
+
res.setHeader('X-Request-ID', requestId);
|
|
10
|
+
next();
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useSession = useSession;
|
|
4
|
+
// Session middleware helper (attaches sessionStore and helpers to req)
|
|
5
|
+
function useSession(cookieName) {
|
|
6
|
+
return async (req, res, next) => {
|
|
7
|
+
try {
|
|
8
|
+
const store = req.app.locals.sessionStore;
|
|
9
|
+
if (!store)
|
|
10
|
+
return next();
|
|
11
|
+
const name = cookieName || req.app.locals.sessionCookieName || 'sid';
|
|
12
|
+
let sid = req.cookies?.[name];
|
|
13
|
+
if (!sid) {
|
|
14
|
+
const cookieHeader = req.headers.cookie;
|
|
15
|
+
if (cookieHeader) {
|
|
16
|
+
const match = cookieHeader
|
|
17
|
+
.split(';')
|
|
18
|
+
.map((s) => s.trim())
|
|
19
|
+
.find((s) => s.startsWith(`${name}=`));
|
|
20
|
+
if (match)
|
|
21
|
+
sid = match.split('=')[1];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
req.sessionId = sid;
|
|
25
|
+
req.sessionStore = store;
|
|
26
|
+
req.getSession = async () => {
|
|
27
|
+
if (!sid)
|
|
28
|
+
return null;
|
|
29
|
+
try {
|
|
30
|
+
return await store.get(sid);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
console.error(`[Session] Failed to get session "${sid}":`, err);
|
|
34
|
+
throw err;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
req.createSession = async (id, data, ttl) => {
|
|
38
|
+
try {
|
|
39
|
+
return await store.create(id, data, ttl);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
console.error(`[Session] Failed to create session "${id}":`, err);
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
next();
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
console.error('[Session] Unexpected error in useSession middleware:', err);
|
|
50
|
+
next();
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RequestHandler } from 'node_modules/@types/express';
|
|
2
|
+
export interface ValidationRule {
|
|
3
|
+
field: string;
|
|
4
|
+
required?: boolean;
|
|
5
|
+
type?: 'string' | 'number' | 'email' | 'boolean';
|
|
6
|
+
minLength?: number;
|
|
7
|
+
maxLength?: number;
|
|
8
|
+
pattern?: RegExp;
|
|
9
|
+
custom?: (value: unknown) => boolean | string;
|
|
10
|
+
}
|
|
11
|
+
export declare function createValidationMiddleware(rules: ValidationRule[]): RequestHandler;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createValidationMiddleware = createValidationMiddleware;
|
|
4
|
+
const errors_utils_1 = require("@naman_deep_singh/errors-utils");
|
|
5
|
+
function createValidationMiddleware(rules) {
|
|
6
|
+
return (req, res, next) => {
|
|
7
|
+
const errors = [];
|
|
8
|
+
for (const rule of rules) {
|
|
9
|
+
const value = req.body[rule.field];
|
|
10
|
+
if (rule.required &&
|
|
11
|
+
(value === undefined || value === null || value === '')) {
|
|
12
|
+
errors.push(`${rule.field} is required`);
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (value === undefined || value === null)
|
|
16
|
+
continue;
|
|
17
|
+
if (rule.type) {
|
|
18
|
+
switch (rule.type) {
|
|
19
|
+
case 'email':
|
|
20
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
21
|
+
if (!emailRegex.test(value)) {
|
|
22
|
+
errors.push(`${rule.field} must be a valid email`);
|
|
23
|
+
}
|
|
24
|
+
break;
|
|
25
|
+
case 'string':
|
|
26
|
+
if (typeof value !== 'string') {
|
|
27
|
+
errors.push(`${rule.field} must be a string`);
|
|
28
|
+
}
|
|
29
|
+
break;
|
|
30
|
+
case 'number':
|
|
31
|
+
if (typeof value !== 'number' && isNaN(Number(value))) {
|
|
32
|
+
errors.push(`${rule.field} must be a number`);
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
case 'boolean':
|
|
36
|
+
if (typeof value !== 'boolean') {
|
|
37
|
+
errors.push(`${rule.field} must be a boolean`);
|
|
38
|
+
}
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (rule.minLength && value.length < rule.minLength) {
|
|
43
|
+
errors.push(`${rule.field} must be at least ${rule.minLength} characters`);
|
|
44
|
+
}
|
|
45
|
+
if (rule.maxLength && value.length > rule.maxLength) {
|
|
46
|
+
errors.push(`${rule.field} must be no more than ${rule.maxLength} characters`);
|
|
47
|
+
}
|
|
48
|
+
if (rule.pattern && !rule.pattern.test(value)) {
|
|
49
|
+
errors.push(`${rule.field} format is invalid`);
|
|
50
|
+
}
|
|
51
|
+
if (rule.custom) {
|
|
52
|
+
const result = rule.custom(value);
|
|
53
|
+
if (result !== true) {
|
|
54
|
+
errors.push(typeof result === 'string' ? result : `${rule.field} is invalid`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (errors.length > 0) {
|
|
59
|
+
// Use ValidationError from errors-utils and let error middleware handle response
|
|
60
|
+
const validationError = new errors_utils_1.ValidationError('Validation failed', {
|
|
61
|
+
validationErrors: errors,
|
|
62
|
+
});
|
|
63
|
+
return next(validationError);
|
|
64
|
+
}
|
|
65
|
+
next();
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -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[];
|
|
@@ -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
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Application, RequestHandler } from 'express';
|
|
2
|
+
import type { 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;
|
|
@@ -4,7 +4,7 @@ export function createHealthCheck(config = {}) {
|
|
|
4
4
|
try {
|
|
5
5
|
const checks = {
|
|
6
6
|
server: true,
|
|
7
|
-
timestamp: Date.now()
|
|
7
|
+
timestamp: Date.now(),
|
|
8
8
|
};
|
|
9
9
|
// Run custom health checks
|
|
10
10
|
for (const check of customChecks) {
|
|
@@ -15,16 +15,16 @@ export function createHealthCheck(config = {}) {
|
|
|
15
15
|
checks[check.name] = false;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
const isHealthy = Object.values(checks).every(status => status === true || typeof status === 'number');
|
|
18
|
+
const isHealthy = Object.values(checks).every((status) => status === true || typeof status === 'number');
|
|
19
19
|
res.status(isHealthy ? 200 : 503).json({
|
|
20
20
|
status: isHealthy ? 'healthy' : 'unhealthy',
|
|
21
|
-
checks
|
|
21
|
+
checks,
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
catch (error) {
|
|
25
25
|
res.status(503).json({
|
|
26
26
|
status: 'unhealthy',
|
|
27
|
-
error: 'Health check failed'
|
|
27
|
+
error: 'Health check failed',
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
};
|
|
@@ -9,7 +9,7 @@ export class PeriodicHealthMonitor {
|
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
11
|
const interval = this.config.interval || 30000;
|
|
12
|
-
this.config.services.forEach(service => {
|
|
12
|
+
this.config.services.forEach((service) => {
|
|
13
13
|
const intervalId = setInterval(async () => {
|
|
14
14
|
await this.checkServiceHealth(service);
|
|
15
15
|
}, interval);
|
|
@@ -18,7 +18,7 @@ export class PeriodicHealthMonitor {
|
|
|
18
18
|
console.log(`📊 ${this.serviceName}: Periodic health monitoring enabled (${interval}ms interval) for ${this.config.services.length} service(s)`);
|
|
19
19
|
}
|
|
20
20
|
stop() {
|
|
21
|
-
this.intervals.forEach(interval => clearInterval(interval));
|
|
21
|
+
this.intervals.forEach((interval) => clearInterval(interval));
|
|
22
22
|
this.intervals = [];
|
|
23
23
|
console.log(`🛑 ${this.serviceName}: Periodic health monitoring stopped`);
|
|
24
24
|
}
|
|
@@ -31,8 +31,8 @@ export class PeriodicHealthMonitor {
|
|
|
31
31
|
method: 'GET',
|
|
32
32
|
signal: controller.signal,
|
|
33
33
|
headers: {
|
|
34
|
-
'User-Agent': `${this.serviceName}-health-monitor
|
|
35
|
-
}
|
|
34
|
+
'User-Agent': `${this.serviceName}-health-monitor`,
|
|
35
|
+
},
|
|
36
36
|
});
|
|
37
37
|
clearTimeout(timeoutId);
|
|
38
38
|
if (response.ok) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Server } from 'http';
|
|
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>;
|
|
@@ -26,7 +27,7 @@ export interface ServerInstanceConfig extends Required<Omit<ServerConfig, 'socke
|
|
|
26
27
|
socketIO?: SocketIOConfig;
|
|
27
28
|
}
|
|
28
29
|
export interface ServerInstance {
|
|
29
|
-
app:
|
|
30
|
+
app: Application;
|
|
30
31
|
server?: Server;
|
|
31
32
|
config: ServerInstanceConfig;
|
|
32
33
|
start(): Promise<ServerInstance>;
|
|
@@ -46,11 +47,11 @@ export interface ServerInfo {
|
|
|
46
47
|
startTime: Date;
|
|
47
48
|
}
|
|
48
49
|
export declare class ExpressServer implements ServerInstance {
|
|
49
|
-
app:
|
|
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?;
|