Spaces:
Build error
Build error
| /** | |
| * Industrial Standard: Middleware Suite | |
| * | |
| * Includes: | |
| * - Request logging | |
| * - Response caching | |
| * - Error handling | |
| * - Performance monitoring | |
| * - Security headers | |
| */ | |
| /** | |
| * Simple in-memory cache for frequently accessed data | |
| * In production, use Redis for distributed caching | |
| */ | |
| class CacheManager { | |
| private cache = new Map<string, { data: unknown; expiresAt: number }>(); | |
| set(key: string, data: unknown, ttlSeconds: number = 300): void { | |
| const expiresAt = Date.now() + ttlSeconds * 1000; | |
| this.cache.set(key, { data, expiresAt }); | |
| } | |
| get(key: string): unknown | null { | |
| const entry = this.cache.get(key); | |
| if (!entry) return null; | |
| if (Date.now() > entry.expiresAt) { | |
| this.cache.delete(key); | |
| return null; | |
| } | |
| return entry.data; | |
| } | |
| clear(): void { | |
| this.cache.clear(); | |
| } | |
| delete(key: string): void { | |
| this.cache.delete(key); | |
| } | |
| } | |
| export const cacheManager = new CacheManager(); | |
| /** | |
| * Request logger with performance tracking | |
| */ | |
| export function createRequestLogger() { | |
| return (req: any, res: any, next: any) => { | |
| const startTime = Date.now(); | |
| const { method, url, ip } = req; | |
| // Log request | |
| console.log(`[${new Date().toISOString()}] ${method} ${url} from ${ip}`); | |
| // Capture response | |
| const originalSend = res.send; | |
| res.send = function (data: any) { | |
| const duration = Date.now() - startTime; | |
| const statusCode = res.statusCode; | |
| console.log( | |
| `[${new Date().toISOString()}] ${method} ${url} ${statusCode} ${duration}ms` | |
| ); | |
| return originalSend.call(this, data); | |
| }; | |
| next(); | |
| }; | |
| } | |
| /** | |
| * Error handler middleware | |
| */ | |
| export function createErrorHandler() { | |
| return (err: any, req: any, res: any, next: any) => { | |
| console.error("[ERROR]", err); | |
| const statusCode = err.statusCode || 500; | |
| const message = err.message || "Internal Server Error"; | |
| res.status(statusCode).json({ | |
| success: false, | |
| error: message, | |
| ...(process.env.NODE_ENV === "development" && { stack: err.stack }), | |
| }); | |
| }; | |
| } | |
| /** | |
| * Security headers middleware | |
| */ | |
| export function createSecurityHeaders() { | |
| return (req: any, res: any, next: any) => { | |
| res.setHeader("X-Content-Type-Options", "nosniff"); | |
| res.setHeader("X-Frame-Options", "DENY"); | |
| res.setHeader("X-XSS-Protection", "1; mode=block"); | |
| res.setHeader("Strict-Transport-Security", "max-age=31536000"); | |
| res.setHeader( | |
| "Content-Security-Policy", | |
| "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" | |
| ); | |
| next(); | |
| }; | |
| } | |
| /** | |
| * Performance monitoring | |
| */ | |
| export class PerformanceMonitor { | |
| private metrics = new Map<string, number[]>(); | |
| record(operation: string, duration: number): void { | |
| if (!this.metrics.has(operation)) { | |
| this.metrics.set(operation, []); | |
| } | |
| this.metrics.get(operation)!.push(duration); | |
| } | |
| getStats(operation: string): { | |
| count: number; | |
| avg: number; | |
| min: number; | |
| max: number; | |
| } | null { | |
| const durations = this.metrics.get(operation); | |
| if (!durations || durations.length === 0) return null; | |
| const count = durations.length; | |
| const avg = durations.reduce((a, b) => a + b, 0) / count; | |
| const min = Math.min(...durations); | |
| const max = Math.max(...durations); | |
| return { count, avg, min, max }; | |
| } | |
| getAllStats(): Record< | |
| string, | |
| { count: number; avg: number; min: number; max: number } | |
| > { | |
| const stats: Record< | |
| string, | |
| { count: number; avg: number; min: number; max: number } | |
| > = {}; | |
| this.metrics.forEach((durations, operation) => { | |
| if (durations.length > 0) { | |
| const count = durations.length; | |
| const avg = durations.reduce((a: number, b: number) => a + b, 0) / count; | |
| const min = Math.min(...durations); | |
| const max = Math.max(...durations); | |
| stats[operation] = { count, avg, min, max }; | |
| } | |
| }); | |
| return stats; | |
| } | |
| clear(): void { | |
| this.metrics.clear(); | |
| } | |
| } | |
| export const performanceMonitor = new PerformanceMonitor(); | |
| /** | |
| * Health check endpoint data | |
| */ | |
| export interface HealthStatus { | |
| status: "healthy" | "degraded" | "unhealthy"; | |
| timestamp: string; | |
| uptime: number; | |
| database: "connected" | "disconnected"; | |
| cache: "active" | "inactive"; | |
| memoryUsage: number; | |
| requestsPerMinute: number; | |
| } | |
| export function getHealthStatus(): HealthStatus { | |
| const uptime = process.uptime(); | |
| const memoryUsage = process.memoryUsage().heapUsed / 1024 / 1024; // MB | |
| return { | |
| status: memoryUsage > 500 ? "degraded" : "healthy", | |
| timestamp: new Date().toISOString(), | |
| uptime, | |
| database: "connected", // Would check actual DB connection | |
| cache: "active", | |
| memoryUsage: Math.round(memoryUsage), | |
| requestsPerMinute: 0, // Would track actual requests | |
| }; | |
| } | |