@morojs/moro 1.8.5 → 1.8.6

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 CHANGED
@@ -8,9 +8,9 @@
8
8
 
9
9
  [![npm version](https://badge.fury.io/js/@morojs%2Fmoro.svg)](https://badge.fury.io/js/@morojs%2Fmoro)
10
10
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
11
- [![Node.js Version](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen)](https://nodejs.org/)
11
+ [![Node.js Version](https://img.shields.io/badge/node-%3E%3D20.0.0-brightgreen)](https://nodejs.org/)
12
12
 
13
- [**Website**](https://morojs.com) • [**Documentation**](https://morojs.com/docs) • [**Quick Start**](https://morojs.com/docs/getting-started) • [**Discord**](https://morojs.com/discord)
13
+ [**Website**](https://morojs.com) • [**Documentation**](https://morojs.com/docs) • [**Quick Start**](https://morojs.com/docs/quick-start) • [**Discord**](https://morojs.com/discord)
14
14
 
15
15
  </div>
16
16
 
@@ -18,12 +18,12 @@
18
18
 
19
19
  ## Why MoroJS?
20
20
 
21
- Build high-performance APIs with intelligent routing that automatically orders middleware execution. Deploy anywhere: Node.js, Vercel Edge, AWS Lambda, or Cloudflare Workers - same code, zero configuration.
21
+ Build high-performance APIs with intelligent routing: declare what a route needs and MoroJS runs it in the optimal, security-first order every time — rate limiting sheds floods before auth, auth gates the cache. Middleware ordering stops being something you can get wrong. Deploy anywhere: Node.js, Vercel Edge, AWS Lambda, or Cloudflare Workers - same code, zero configuration.
22
22
 
23
23
  **Key Features:**
24
24
 
25
25
  - **Native C++ Engine** - ~102k req/s real-world through the full framework, 572k pipelined, on a single thread
26
- - **Intelligent Routing** - Automatic middleware ordering, no configuration needed
26
+ - **Intelligent Routing** - Declare auth, validation, rate limits and caching in any order; they always execute in the optimal, security-first one
27
27
  - **Enterprise Auth** - Built-in Better Auth with OAuth & RBAC
28
28
  - **Universal Validation** - Works with Zod, Joi, Yup, or Class Validator
29
29
  - **Message Queues** - Production-ready queues (Bull, RabbitMQ, SQS, Kafka)
@@ -53,6 +53,7 @@ import { createApp, z } from '@morojs/moro';
53
53
  const app = await createApp();
54
54
 
55
55
  // Intelligent routing - order doesn't matter!
56
+ // (rate limit -> auth -> validation -> cache -> handler)
56
57
  app
57
58
  .post('/users')
58
59
  .body(
@@ -196,7 +197,7 @@ Check out [working examples](https://github.com/Moro-JS/examples) for:
196
197
 
197
198
  ## Why Choose MoroJS?
198
199
 
199
- **vs Express** - Intelligent middleware ordering eliminates configuration complexity and race conditions
200
+ **vs Express** - Intelligent security-first middleware pipeline eliminates ordering bugs and configuration complexity
200
201
 
201
202
  **vs Fastify** - ~1.5x the throughput out of the box (Moro's native engine), plus multi-runtime deployment without adapters
202
203
 
@@ -216,6 +217,6 @@ MIT © [Moro Framework Team](https://morojs.com)
216
217
 
217
218
  **Ready to build high-performance APIs?**
218
219
 
219
- [Get Started](https://morojs.com/docs/getting-started) • [GitHub](https://github.com/Moro-JS/moro) • [npm](https://www.npmjs.com/package/@morojs/moro) • [Discord](https://morojs.com/discord)
220
+ [Get Started](https://morojs.com/docs/quick-start) • [GitHub](https://github.com/Moro-JS/moro) • [npm](https://www.npmjs.com/package/@morojs/moro) • [Discord](https://morojs.com/discord)
220
221
 
221
222
  </div>
@@ -27,6 +27,7 @@ export interface JobExecutorOptions {
27
27
  circuitBreakerThreshold?: number;
28
28
  circuitBreakerResetTimeout?: number;
29
29
  enableMemoryMonitoring?: boolean;
30
+ /** Heap ceiling in MB. Defaults to 90% of the process's V8 heap limit. */
30
31
  memoryThreshold?: number;
31
32
  }
32
33
  export interface JobFunction {
@@ -1,7 +1,29 @@
1
1
  // Production-grade Job Executor
2
2
  // Handles job execution with retry logic, timeout, circuit breaker, and memory monitoring
3
3
  import { EventEmitter } from 'events';
4
+ import { getHeapStatistics } from 'v8';
4
5
  import { CircuitBreaker } from '../utilities/circuit-breaker.js';
6
+ /**
7
+ * Default memory ceiling for job execution, in MB.
8
+ *
9
+ * Derived from the process's actual V8 heap limit rather than a fixed number.
10
+ * A hardcoded default (previously 512MB) is meaningless in isolation: 64-bit
11
+ * Node defaults to a ~4GB heap, so 512MB is only ~12% of what the process may
12
+ * legitimately use. Every job would refuse to run once the process crossed
13
+ * that line — and because heap usage rarely falls back, the failure was
14
+ * permanent rather than transient.
15
+ *
16
+ * 90% of the heap limit is the point where allocation pressure is real and
17
+ * refusing new work is the right call. An explicit `memoryThreshold` option
18
+ * still wins, so existing configuration is unaffected.
19
+ */
20
+ function defaultMemoryThresholdMB() {
21
+ const limitMB = getHeapStatistics().heap_size_limit / 1024 / 1024;
22
+ // No floor: V8's own minimum heap is ~256MB, so any absolute floor would
23
+ // meet or exceed the limit in a memory-constrained container and disable
24
+ // the guard entirely. A percentage of the real limit is correct at any size.
25
+ return Math.round(limitMB * 0.9);
26
+ }
5
27
  // Reference to global AbortController
6
28
  const AbortControllerClass = globalThis.AbortController;
7
29
  /**
@@ -34,7 +56,7 @@ export class JobExecutor extends EventEmitter {
34
56
  circuitBreakerThreshold: options.circuitBreakerThreshold ?? 5,
35
57
  circuitBreakerResetTimeout: options.circuitBreakerResetTimeout ?? 60000,
36
58
  enableMemoryMonitoring: options.enableMemoryMonitoring ?? true,
37
- memoryThreshold: options.memoryThreshold ?? 512, // 512MB default
59
+ memoryThreshold: options.memoryThreshold ?? defaultMemoryThresholdMB(),
38
60
  };
39
61
  this.logger.debug('JobExecutor initialized', 'JobExecutor', { options: this.options });
40
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"job-executor.js","sourceRoot":"","sources":["../../../src/core/jobs/job-executor.ts"],"names":[],"mappings":"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","sourcesContent":["// Production-grade Job Executor\n// Handles job execution with retry logic, timeout, circuit breaker, and memory monitoring\n\nimport { EventEmitter } from 'events';\nimport { Logger } from '../../types/logger.js';\nimport { CircuitBreaker } from '../utilities/circuit-breaker.js';\n\n// Type definitions for native Node.js AbortController (available in Node.js 15+)\ntype AbortSignal = {\n readonly aborted: boolean;\n addEventListener(type: 'abort', listener: () => void, options?: { once: boolean }): void;\n removeEventListener(type: 'abort', listener: () => void): void;\n};\n\ntype AbortController = {\n readonly signal: AbortSignal;\n abort(): void;\n};\n\n// Access global AbortController through globalThis\ndeclare global {\n interface GlobalThis {\n AbortController: new () => AbortController;\n }\n}\n\n// Reference to global AbortController\nconst AbortControllerClass = globalThis.AbortController;\n\nexport interface JobExecutorOptions {\n maxRetries?: number;\n retryDelay?: number;\n retryBackoff?: 'linear' | 'exponential';\n retryBackoffMultiplier?: number;\n maxRetryDelay?: number;\n timeout?: number;\n enableCircuitBreaker?: boolean;\n circuitBreakerThreshold?: number;\n circuitBreakerResetTimeout?: number;\n enableMemoryMonitoring?: boolean;\n memoryThreshold?: number; // MB\n}\n\nexport interface JobFunction {\n (...args: any[]): Promise<any> | any;\n}\n\nexport interface ExecutionContext {\n jobId: string;\n executionId: string;\n attempt: number;\n startTime: Date;\n metadata?: Record<string, any>;\n}\n\nexport interface ExecutionResult {\n success: boolean;\n value?: any;\n error?: Error | undefined;\n attempts: number;\n duration: number;\n memoryUsed?: number;\n circuitBreakerTripped?: boolean;\n timedOut?: boolean;\n}\n\n/**\n * JobExecutor - Executes jobs with production-grade resilience\n * Features:\n * - Configurable retry with exponential backoff + jitter\n * - Timeout enforcement\n * - Circuit breaker integration\n * - Memory leak detection\n * - Graceful cancellation\n */\nexport class JobExecutor extends EventEmitter {\n private options: Required<JobExecutorOptions>;\n private logger: Logger;\n private circuitBreakers = new Map<string, CircuitBreaker>();\n private activeExecutions = new Map<string, AbortController>();\n private isShuttingDown = false;\n\n constructor(logger: Logger, options: JobExecutorOptions = {}) {\n super();\n this.logger = logger;\n\n // Set defaults\n this.options = {\n maxRetries: options.maxRetries ?? 3,\n retryDelay: options.retryDelay ?? 1000,\n retryBackoff: options.retryBackoff ?? 'exponential',\n retryBackoffMultiplier: options.retryBackoffMultiplier ?? 2,\n maxRetryDelay: options.maxRetryDelay ?? 60000,\n timeout: options.timeout ?? 300000, // 5 minutes default\n enableCircuitBreaker: options.enableCircuitBreaker ?? true,\n circuitBreakerThreshold: options.circuitBreakerThreshold ?? 5,\n circuitBreakerResetTimeout: options.circuitBreakerResetTimeout ?? 60000,\n enableMemoryMonitoring: options.enableMemoryMonitoring ?? true,\n memoryThreshold: options.memoryThreshold ?? 512, // 512MB default\n };\n\n this.logger.debug('JobExecutor initialized', 'JobExecutor', { options: this.options });\n }\n\n /**\n * Execute a job with full resilience features\n *\n * @param jobId - Unique job identifier\n * @param executionId - Unique execution identifier\n * @param jobFn - The job function to execute\n * @param context - Execution context\n * @param optionOverrides - Per-execution option overrides (merged on top of constructor defaults)\n */\n public async execute(\n jobId: string,\n executionId: string,\n jobFn: JobFunction,\n context?: ExecutionContext,\n optionOverrides?: Partial<JobExecutorOptions>\n ): Promise<ExecutionResult> {\n if (this.isShuttingDown) {\n throw new Error('JobExecutor is shutting down');\n }\n\n // Merge per-execution overrides with constructor defaults\n const opts = optionOverrides ? { ...this.options, ...optionOverrides } : this.options;\n\n const ctx: ExecutionContext = context || {\n jobId,\n executionId,\n attempt: 1,\n startTime: new Date(),\n };\n\n const startTime = Date.now();\n const abortController = new AbortControllerClass();\n this.activeExecutions.set(executionId, abortController);\n\n let lastError: Error | undefined;\n let attempts = 0;\n let circuitBreakerTripped = false;\n let timedOut = false;\n\n try {\n // Check memory before execution\n if (opts.enableMemoryMonitoring) {\n await this.checkMemoryUsage(jobId);\n }\n\n // Execute with retries\n while (attempts <= opts.maxRetries) {\n attempts++;\n ctx.attempt = attempts;\n\n try {\n // Check circuit breaker\n if (opts.enableCircuitBreaker) {\n const breaker = this.getCircuitBreaker(jobId);\n\n if (breaker.isOpen()) {\n circuitBreakerTripped = true;\n throw new Error(`Circuit breaker open for job ${jobId}`);\n }\n }\n\n // Execute with timeout\n const result = await this.executeWithTimeout(\n jobFn,\n ctx,\n abortController.signal,\n opts.timeout\n );\n\n // Success - record in circuit breaker\n if (opts.enableCircuitBreaker) {\n const breaker = this.getCircuitBreaker(jobId);\n breaker.recordSuccess();\n }\n\n const duration = Date.now() - startTime;\n const memoryUsed = this.getMemoryUsage();\n\n this.logger.debug(`Job executed successfully: ${jobId}`, 'JobExecutor', {\n executionId,\n attempts,\n duration,\n memoryUsed,\n });\n\n this.emit('execution:success', {\n jobId,\n executionId,\n attempts,\n duration,\n memoryUsed,\n });\n\n return {\n success: true,\n value: result,\n attempts,\n duration,\n memoryUsed,\n circuitBreakerTripped: false,\n timedOut: false,\n };\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Check if it's a timeout\n if (lastError.name === 'TimeoutError' || lastError.message.includes('timeout')) {\n timedOut = true;\n }\n\n // Record failure in circuit breaker\n if (opts.enableCircuitBreaker && !circuitBreakerTripped) {\n const breaker = this.getCircuitBreaker(jobId);\n breaker.recordFailure();\n }\n\n this.logger.warn(\n `Job execution failed: ${jobId} (attempt ${attempts}/${opts.maxRetries + 1})`,\n 'JobExecutor',\n {\n executionId,\n error: lastError.message,\n timedOut,\n circuitBreakerTripped,\n }\n );\n\n this.emit('execution:retry', {\n jobId,\n executionId,\n attempt: attempts,\n maxAttempts: opts.maxRetries + 1,\n error: lastError,\n timedOut,\n });\n\n // Don't retry if circuit breaker tripped or shutting down\n if (circuitBreakerTripped || this.isShuttingDown) {\n break;\n }\n\n // Calculate retry delay with backoff and jitter\n if (attempts <= opts.maxRetries) {\n const delay = this.calculateRetryDelay(attempts, opts);\n await this.sleep(delay);\n }\n }\n }\n\n // All retries exhausted\n const duration = Date.now() - startTime;\n\n this.logger.error(\n `Job execution failed after ${attempts} attempts: ${jobId}`,\n 'JobExecutor',\n {\n executionId,\n error: lastError?.message,\n timedOut,\n circuitBreakerTripped,\n }\n );\n\n this.emit('execution:failed', {\n jobId,\n executionId,\n attempts,\n duration,\n error: lastError,\n timedOut,\n circuitBreakerTripped,\n });\n\n return {\n success: false,\n error: lastError,\n attempts,\n duration,\n circuitBreakerTripped,\n timedOut,\n };\n } finally {\n this.activeExecutions.delete(executionId);\n\n // Force GC if memory threshold exceeded\n if (opts.enableMemoryMonitoring) {\n const memUsage = process.memoryUsage();\n const heapUsedMB = memUsage.heapUsed / 1024 / 1024;\n\n if (heapUsedMB > opts.memoryThreshold * 0.9 && globalThis.gc) {\n this.logger.warn('High memory usage detected, triggering GC', 'JobExecutor', {\n heapUsedMB: Math.round(heapUsedMB),\n threshold: opts.memoryThreshold,\n });\n globalThis.gc();\n }\n }\n }\n }\n\n /**\n * Execute job function with timeout\n */\n private async executeWithTimeout(\n jobFn: JobFunction,\n context: ExecutionContext,\n signal: AbortSignal,\n timeout?: number\n ): Promise<any> {\n const effectiveTimeout = timeout ?? this.options.timeout;\n return new Promise((resolve, reject) => {\n // Setup timeout\n const timeoutId = setTimeout(() => {\n const error = new Error(`Job execution timeout after ${effectiveTimeout}ms`);\n error.name = 'TimeoutError';\n reject(error);\n }, effectiveTimeout);\n\n // Don't keep process alive for job execution timeout\n timeoutId.unref();\n\n // Setup abort handler\n const abortHandler = () => {\n clearTimeout(timeoutId);\n reject(new Error('Job execution cancelled'));\n };\n\n if (signal.aborted) {\n clearTimeout(timeoutId);\n reject(new Error('Job execution cancelled'));\n return;\n }\n\n signal.addEventListener('abort', abortHandler, { once: true });\n\n // Execute job\n Promise.resolve()\n .then(() => jobFn(context))\n .then(result => {\n clearTimeout(timeoutId);\n signal.removeEventListener('abort', abortHandler);\n resolve(result);\n })\n .catch(error => {\n clearTimeout(timeoutId);\n signal.removeEventListener('abort', abortHandler);\n reject(error);\n });\n });\n }\n\n /**\n * Calculate retry delay with backoff and jitter\n */\n private calculateRetryDelay(\n attempt: number,\n opts?: Pick<\n Required<JobExecutorOptions>,\n 'retryBackoff' | 'retryDelay' | 'retryBackoffMultiplier' | 'maxRetryDelay'\n >\n ): number {\n const effectiveOpts = opts ?? this.options;\n let delay: number;\n\n if (effectiveOpts.retryBackoff === 'exponential') {\n delay =\n effectiveOpts.retryDelay * Math.pow(effectiveOpts.retryBackoffMultiplier, attempt - 1);\n } else {\n delay = effectiveOpts.retryDelay * attempt;\n }\n\n // Cap at max delay\n delay = Math.min(delay, effectiveOpts.maxRetryDelay);\n\n // Add jitter (±20%)\n const jitter = delay * 0.2 * (Math.random() * 2 - 1);\n delay = Math.max(0, delay + jitter);\n\n return Math.floor(delay);\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => {\n const timer = setTimeout(resolve, ms);\n timer.unref(); // Don't keep process alive\n });\n }\n\n /**\n * Get or create circuit breaker for job\n */\n private getCircuitBreaker(jobId: string): CircuitBreaker {\n let breaker = this.circuitBreakers.get(jobId);\n\n if (!breaker) {\n breaker = new CircuitBreaker({\n failureThreshold: this.options.circuitBreakerThreshold,\n resetTimeout: this.options.circuitBreakerResetTimeout,\n });\n\n // Log circuit breaker state changes\n breaker.on('open', () => {\n this.logger.error(`Circuit breaker opened for job: ${jobId}`);\n this.emit('circuit-breaker:open', { jobId });\n });\n\n breaker.on('halfOpen', () => {\n this.logger.info(`Circuit breaker half-open for job: ${jobId}`);\n this.emit('circuit-breaker:half-open', { jobId });\n });\n\n breaker.on('closed', () => {\n this.logger.info(`Circuit breaker closed for job: ${jobId}`);\n this.emit('circuit-breaker:closed', { jobId });\n });\n\n this.circuitBreakers.set(jobId, breaker);\n }\n\n return breaker;\n }\n\n /**\n * Check memory usage before execution\n */\n private async checkMemoryUsage(jobId: string): Promise<void> {\n const memUsage = process.memoryUsage();\n const heapUsedMB = memUsage.heapUsed / 1024 / 1024;\n\n if (heapUsedMB > this.options.memoryThreshold) {\n const error = `Memory threshold exceeded: ${Math.round(heapUsedMB)}MB / ${this.options.memoryThreshold}MB`;\n this.logger.error(error, 'JobExecutor', { jobId });\n\n this.emit('memory:threshold-exceeded', {\n jobId,\n heapUsedMB,\n threshold: this.options.memoryThreshold,\n });\n\n // Try to force GC if available\n if (globalThis.gc) {\n this.logger.warn('Forcing garbage collection', 'JobExecutor', { jobId });\n globalThis.gc();\n\n // Check again after GC\n const newMemUsage = process.memoryUsage();\n const newHeapUsedMB = newMemUsage.heapUsed / 1024 / 1024;\n\n if (newHeapUsedMB > this.options.memoryThreshold) {\n throw new Error(error);\n }\n\n this.logger.info('Memory recovered after GC', 'JobExecutor', {\n before: Math.round(heapUsedMB),\n after: Math.round(newHeapUsedMB),\n });\n } else {\n throw new Error(error);\n }\n }\n }\n\n /**\n * Get current memory usage in MB\n */\n private getMemoryUsage(): number {\n const memUsage = process.memoryUsage();\n return Math.round(memUsage.heapUsed / 1024 / 1024);\n }\n\n /**\n * Cancel a running execution\n */\n public cancelExecution(executionId: string): boolean {\n const controller = this.activeExecutions.get(executionId);\n if (!controller) {\n return false;\n }\n\n controller.abort();\n this.logger.info(`Execution cancelled: ${executionId}`);\n this.emit('execution:cancelled', { executionId });\n\n return true;\n }\n\n /**\n * Cancel all running executions\n */\n public cancelAllExecutions(): void {\n const executionIds = Array.from(this.activeExecutions.keys());\n\n this.logger.info(`Cancelling ${executionIds.length} running executions`);\n\n for (const executionId of executionIds) {\n this.cancelExecution(executionId);\n }\n }\n\n /**\n * Get active execution count\n */\n public getActiveExecutionCount(): number {\n return this.activeExecutions.size;\n }\n\n /**\n * Get circuit breaker status for job\n */\n public getCircuitBreakerStatus(jobId: string): {\n exists: boolean;\n state?: string;\n failures?: number;\n threshold?: number;\n } {\n const breaker = this.circuitBreakers.get(jobId);\n\n if (!breaker) {\n return { exists: false };\n }\n\n return {\n exists: true,\n state: breaker.getState().toLowerCase(),\n failures: breaker.getFailures(),\n threshold: this.options.circuitBreakerThreshold,\n };\n }\n\n /**\n * Reset circuit breaker for job\n */\n public resetCircuitBreaker(jobId: string): boolean {\n const breaker = this.circuitBreakers.get(jobId);\n if (!breaker) {\n return false;\n }\n\n breaker.reset();\n this.logger.info(`Circuit breaker reset for job: ${jobId}`);\n return true;\n }\n\n /**\n * Update executor options at runtime\n */\n public updateOptions(options: Partial<JobExecutorOptions>): void {\n Object.assign(this.options, options);\n this.logger.info('JobExecutor options updated', 'JobExecutor', { options });\n }\n\n /**\n * Get current options\n */\n public getOptions(): Required<JobExecutorOptions> {\n return { ...this.options };\n }\n\n /**\n * Shutdown and cleanup\n */\n public async shutdown(gracePeriod: number = 30000): Promise<void> {\n this.logger.info('JobExecutor shutting down...', 'JobExecutor', {\n activeExecutions: this.activeExecutions.size,\n gracePeriod,\n });\n\n this.isShuttingDown = true;\n\n // Wait for active executions to complete or grace period to expire\n const startTime = Date.now();\n\n while (this.activeExecutions.size > 0 && Date.now() - startTime < gracePeriod) {\n this.logger.debug(`Waiting for ${this.activeExecutions.size} active executions to complete`);\n await this.sleep(1000);\n }\n\n // Force cancel remaining executions\n if (this.activeExecutions.size > 0) {\n this.logger.warn(`Force cancelling ${this.activeExecutions.size} remaining executions`);\n this.cancelAllExecutions();\n }\n\n // Cleanup state\n this.circuitBreakers.clear();\n this.activeExecutions.clear();\n\n this.removeAllListeners();\n this.logger.info('JobExecutor shutdown complete');\n }\n}\n"]}
1
+ {"version":3,"file":"job-executor.js","sourceRoot":"","sources":["../../../src/core/jobs/job-executor.ts"],"names":[],"mappings":"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","sourcesContent":["// Production-grade Job Executor\n// Handles job execution with retry logic, timeout, circuit breaker, and memory monitoring\n\nimport { EventEmitter } from 'events';\nimport { getHeapStatistics } from 'v8';\nimport { Logger } from '../../types/logger.js';\nimport { CircuitBreaker } from '../utilities/circuit-breaker.js';\n\n/**\n * Default memory ceiling for job execution, in MB.\n *\n * Derived from the process's actual V8 heap limit rather than a fixed number.\n * A hardcoded default (previously 512MB) is meaningless in isolation: 64-bit\n * Node defaults to a ~4GB heap, so 512MB is only ~12% of what the process may\n * legitimately use. Every job would refuse to run once the process crossed\n * that line — and because heap usage rarely falls back, the failure was\n * permanent rather than transient.\n *\n * 90% of the heap limit is the point where allocation pressure is real and\n * refusing new work is the right call. An explicit `memoryThreshold` option\n * still wins, so existing configuration is unaffected.\n */\nfunction defaultMemoryThresholdMB(): number {\n const limitMB = getHeapStatistics().heap_size_limit / 1024 / 1024;\n // No floor: V8's own minimum heap is ~256MB, so any absolute floor would\n // meet or exceed the limit in a memory-constrained container and disable\n // the guard entirely. A percentage of the real limit is correct at any size.\n return Math.round(limitMB * 0.9);\n}\n\n// Type definitions for native Node.js AbortController (available in Node.js 15+)\ntype AbortSignal = {\n readonly aborted: boolean;\n addEventListener(type: 'abort', listener: () => void, options?: { once: boolean }): void;\n removeEventListener(type: 'abort', listener: () => void): void;\n};\n\ntype AbortController = {\n readonly signal: AbortSignal;\n abort(): void;\n};\n\n// Access global AbortController through globalThis\ndeclare global {\n interface GlobalThis {\n AbortController: new () => AbortController;\n }\n}\n\n// Reference to global AbortController\nconst AbortControllerClass = globalThis.AbortController;\n\nexport interface JobExecutorOptions {\n maxRetries?: number;\n retryDelay?: number;\n retryBackoff?: 'linear' | 'exponential';\n retryBackoffMultiplier?: number;\n maxRetryDelay?: number;\n timeout?: number;\n enableCircuitBreaker?: boolean;\n circuitBreakerThreshold?: number;\n circuitBreakerResetTimeout?: number;\n enableMemoryMonitoring?: boolean;\n /** Heap ceiling in MB. Defaults to 90% of the process's V8 heap limit. */\n memoryThreshold?: number;\n}\n\nexport interface JobFunction {\n (...args: any[]): Promise<any> | any;\n}\n\nexport interface ExecutionContext {\n jobId: string;\n executionId: string;\n attempt: number;\n startTime: Date;\n metadata?: Record<string, any>;\n}\n\nexport interface ExecutionResult {\n success: boolean;\n value?: any;\n error?: Error | undefined;\n attempts: number;\n duration: number;\n memoryUsed?: number;\n circuitBreakerTripped?: boolean;\n timedOut?: boolean;\n}\n\n/**\n * JobExecutor - Executes jobs with production-grade resilience\n * Features:\n * - Configurable retry with exponential backoff + jitter\n * - Timeout enforcement\n * - Circuit breaker integration\n * - Memory leak detection\n * - Graceful cancellation\n */\nexport class JobExecutor extends EventEmitter {\n private options: Required<JobExecutorOptions>;\n private logger: Logger;\n private circuitBreakers = new Map<string, CircuitBreaker>();\n private activeExecutions = new Map<string, AbortController>();\n private isShuttingDown = false;\n\n constructor(logger: Logger, options: JobExecutorOptions = {}) {\n super();\n this.logger = logger;\n\n // Set defaults\n this.options = {\n maxRetries: options.maxRetries ?? 3,\n retryDelay: options.retryDelay ?? 1000,\n retryBackoff: options.retryBackoff ?? 'exponential',\n retryBackoffMultiplier: options.retryBackoffMultiplier ?? 2,\n maxRetryDelay: options.maxRetryDelay ?? 60000,\n timeout: options.timeout ?? 300000, // 5 minutes default\n enableCircuitBreaker: options.enableCircuitBreaker ?? true,\n circuitBreakerThreshold: options.circuitBreakerThreshold ?? 5,\n circuitBreakerResetTimeout: options.circuitBreakerResetTimeout ?? 60000,\n enableMemoryMonitoring: options.enableMemoryMonitoring ?? true,\n memoryThreshold: options.memoryThreshold ?? defaultMemoryThresholdMB(),\n };\n\n this.logger.debug('JobExecutor initialized', 'JobExecutor', { options: this.options });\n }\n\n /**\n * Execute a job with full resilience features\n *\n * @param jobId - Unique job identifier\n * @param executionId - Unique execution identifier\n * @param jobFn - The job function to execute\n * @param context - Execution context\n * @param optionOverrides - Per-execution option overrides (merged on top of constructor defaults)\n */\n public async execute(\n jobId: string,\n executionId: string,\n jobFn: JobFunction,\n context?: ExecutionContext,\n optionOverrides?: Partial<JobExecutorOptions>\n ): Promise<ExecutionResult> {\n if (this.isShuttingDown) {\n throw new Error('JobExecutor is shutting down');\n }\n\n // Merge per-execution overrides with constructor defaults\n const opts = optionOverrides ? { ...this.options, ...optionOverrides } : this.options;\n\n const ctx: ExecutionContext = context || {\n jobId,\n executionId,\n attempt: 1,\n startTime: new Date(),\n };\n\n const startTime = Date.now();\n const abortController = new AbortControllerClass();\n this.activeExecutions.set(executionId, abortController);\n\n let lastError: Error | undefined;\n let attempts = 0;\n let circuitBreakerTripped = false;\n let timedOut = false;\n\n try {\n // Check memory before execution\n if (opts.enableMemoryMonitoring) {\n await this.checkMemoryUsage(jobId);\n }\n\n // Execute with retries\n while (attempts <= opts.maxRetries) {\n attempts++;\n ctx.attempt = attempts;\n\n try {\n // Check circuit breaker\n if (opts.enableCircuitBreaker) {\n const breaker = this.getCircuitBreaker(jobId);\n\n if (breaker.isOpen()) {\n circuitBreakerTripped = true;\n throw new Error(`Circuit breaker open for job ${jobId}`);\n }\n }\n\n // Execute with timeout\n const result = await this.executeWithTimeout(\n jobFn,\n ctx,\n abortController.signal,\n opts.timeout\n );\n\n // Success - record in circuit breaker\n if (opts.enableCircuitBreaker) {\n const breaker = this.getCircuitBreaker(jobId);\n breaker.recordSuccess();\n }\n\n const duration = Date.now() - startTime;\n const memoryUsed = this.getMemoryUsage();\n\n this.logger.debug(`Job executed successfully: ${jobId}`, 'JobExecutor', {\n executionId,\n attempts,\n duration,\n memoryUsed,\n });\n\n this.emit('execution:success', {\n jobId,\n executionId,\n attempts,\n duration,\n memoryUsed,\n });\n\n return {\n success: true,\n value: result,\n attempts,\n duration,\n memoryUsed,\n circuitBreakerTripped: false,\n timedOut: false,\n };\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Check if it's a timeout\n if (lastError.name === 'TimeoutError' || lastError.message.includes('timeout')) {\n timedOut = true;\n }\n\n // Record failure in circuit breaker\n if (opts.enableCircuitBreaker && !circuitBreakerTripped) {\n const breaker = this.getCircuitBreaker(jobId);\n breaker.recordFailure();\n }\n\n this.logger.warn(\n `Job execution failed: ${jobId} (attempt ${attempts}/${opts.maxRetries + 1})`,\n 'JobExecutor',\n {\n executionId,\n error: lastError.message,\n timedOut,\n circuitBreakerTripped,\n }\n );\n\n this.emit('execution:retry', {\n jobId,\n executionId,\n attempt: attempts,\n maxAttempts: opts.maxRetries + 1,\n error: lastError,\n timedOut,\n });\n\n // Don't retry if circuit breaker tripped or shutting down\n if (circuitBreakerTripped || this.isShuttingDown) {\n break;\n }\n\n // Calculate retry delay with backoff and jitter\n if (attempts <= opts.maxRetries) {\n const delay = this.calculateRetryDelay(attempts, opts);\n await this.sleep(delay);\n }\n }\n }\n\n // All retries exhausted\n const duration = Date.now() - startTime;\n\n this.logger.error(\n `Job execution failed after ${attempts} attempts: ${jobId}`,\n 'JobExecutor',\n {\n executionId,\n error: lastError?.message,\n timedOut,\n circuitBreakerTripped,\n }\n );\n\n this.emit('execution:failed', {\n jobId,\n executionId,\n attempts,\n duration,\n error: lastError,\n timedOut,\n circuitBreakerTripped,\n });\n\n return {\n success: false,\n error: lastError,\n attempts,\n duration,\n circuitBreakerTripped,\n timedOut,\n };\n } finally {\n this.activeExecutions.delete(executionId);\n\n // Force GC if memory threshold exceeded\n if (opts.enableMemoryMonitoring) {\n const memUsage = process.memoryUsage();\n const heapUsedMB = memUsage.heapUsed / 1024 / 1024;\n\n if (heapUsedMB > opts.memoryThreshold * 0.9 && globalThis.gc) {\n this.logger.warn('High memory usage detected, triggering GC', 'JobExecutor', {\n heapUsedMB: Math.round(heapUsedMB),\n threshold: opts.memoryThreshold,\n });\n globalThis.gc();\n }\n }\n }\n }\n\n /**\n * Execute job function with timeout\n */\n private async executeWithTimeout(\n jobFn: JobFunction,\n context: ExecutionContext,\n signal: AbortSignal,\n timeout?: number\n ): Promise<any> {\n const effectiveTimeout = timeout ?? this.options.timeout;\n return new Promise((resolve, reject) => {\n // Setup timeout\n const timeoutId = setTimeout(() => {\n const error = new Error(`Job execution timeout after ${effectiveTimeout}ms`);\n error.name = 'TimeoutError';\n reject(error);\n }, effectiveTimeout);\n\n // Don't keep process alive for job execution timeout\n timeoutId.unref();\n\n // Setup abort handler\n const abortHandler = () => {\n clearTimeout(timeoutId);\n reject(new Error('Job execution cancelled'));\n };\n\n if (signal.aborted) {\n clearTimeout(timeoutId);\n reject(new Error('Job execution cancelled'));\n return;\n }\n\n signal.addEventListener('abort', abortHandler, { once: true });\n\n // Execute job\n Promise.resolve()\n .then(() => jobFn(context))\n .then(result => {\n clearTimeout(timeoutId);\n signal.removeEventListener('abort', abortHandler);\n resolve(result);\n })\n .catch(error => {\n clearTimeout(timeoutId);\n signal.removeEventListener('abort', abortHandler);\n reject(error);\n });\n });\n }\n\n /**\n * Calculate retry delay with backoff and jitter\n */\n private calculateRetryDelay(\n attempt: number,\n opts?: Pick<\n Required<JobExecutorOptions>,\n 'retryBackoff' | 'retryDelay' | 'retryBackoffMultiplier' | 'maxRetryDelay'\n >\n ): number {\n const effectiveOpts = opts ?? this.options;\n let delay: number;\n\n if (effectiveOpts.retryBackoff === 'exponential') {\n delay =\n effectiveOpts.retryDelay * Math.pow(effectiveOpts.retryBackoffMultiplier, attempt - 1);\n } else {\n delay = effectiveOpts.retryDelay * attempt;\n }\n\n // Cap at max delay\n delay = Math.min(delay, effectiveOpts.maxRetryDelay);\n\n // Add jitter (±20%)\n const jitter = delay * 0.2 * (Math.random() * 2 - 1);\n delay = Math.max(0, delay + jitter);\n\n return Math.floor(delay);\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => {\n const timer = setTimeout(resolve, ms);\n timer.unref(); // Don't keep process alive\n });\n }\n\n /**\n * Get or create circuit breaker for job\n */\n private getCircuitBreaker(jobId: string): CircuitBreaker {\n let breaker = this.circuitBreakers.get(jobId);\n\n if (!breaker) {\n breaker = new CircuitBreaker({\n failureThreshold: this.options.circuitBreakerThreshold,\n resetTimeout: this.options.circuitBreakerResetTimeout,\n });\n\n // Log circuit breaker state changes\n breaker.on('open', () => {\n this.logger.error(`Circuit breaker opened for job: ${jobId}`);\n this.emit('circuit-breaker:open', { jobId });\n });\n\n breaker.on('halfOpen', () => {\n this.logger.info(`Circuit breaker half-open for job: ${jobId}`);\n this.emit('circuit-breaker:half-open', { jobId });\n });\n\n breaker.on('closed', () => {\n this.logger.info(`Circuit breaker closed for job: ${jobId}`);\n this.emit('circuit-breaker:closed', { jobId });\n });\n\n this.circuitBreakers.set(jobId, breaker);\n }\n\n return breaker;\n }\n\n /**\n * Check memory usage before execution\n */\n private async checkMemoryUsage(jobId: string): Promise<void> {\n const memUsage = process.memoryUsage();\n const heapUsedMB = memUsage.heapUsed / 1024 / 1024;\n\n if (heapUsedMB > this.options.memoryThreshold) {\n const error = `Memory threshold exceeded: ${Math.round(heapUsedMB)}MB / ${this.options.memoryThreshold}MB`;\n this.logger.error(error, 'JobExecutor', { jobId });\n\n this.emit('memory:threshold-exceeded', {\n jobId,\n heapUsedMB,\n threshold: this.options.memoryThreshold,\n });\n\n // Try to force GC if available\n if (globalThis.gc) {\n this.logger.warn('Forcing garbage collection', 'JobExecutor', { jobId });\n globalThis.gc();\n\n // Check again after GC\n const newMemUsage = process.memoryUsage();\n const newHeapUsedMB = newMemUsage.heapUsed / 1024 / 1024;\n\n if (newHeapUsedMB > this.options.memoryThreshold) {\n throw new Error(error);\n }\n\n this.logger.info('Memory recovered after GC', 'JobExecutor', {\n before: Math.round(heapUsedMB),\n after: Math.round(newHeapUsedMB),\n });\n } else {\n throw new Error(error);\n }\n }\n }\n\n /**\n * Get current memory usage in MB\n */\n private getMemoryUsage(): number {\n const memUsage = process.memoryUsage();\n return Math.round(memUsage.heapUsed / 1024 / 1024);\n }\n\n /**\n * Cancel a running execution\n */\n public cancelExecution(executionId: string): boolean {\n const controller = this.activeExecutions.get(executionId);\n if (!controller) {\n return false;\n }\n\n controller.abort();\n this.logger.info(`Execution cancelled: ${executionId}`);\n this.emit('execution:cancelled', { executionId });\n\n return true;\n }\n\n /**\n * Cancel all running executions\n */\n public cancelAllExecutions(): void {\n const executionIds = Array.from(this.activeExecutions.keys());\n\n this.logger.info(`Cancelling ${executionIds.length} running executions`);\n\n for (const executionId of executionIds) {\n this.cancelExecution(executionId);\n }\n }\n\n /**\n * Get active execution count\n */\n public getActiveExecutionCount(): number {\n return this.activeExecutions.size;\n }\n\n /**\n * Get circuit breaker status for job\n */\n public getCircuitBreakerStatus(jobId: string): {\n exists: boolean;\n state?: string;\n failures?: number;\n threshold?: number;\n } {\n const breaker = this.circuitBreakers.get(jobId);\n\n if (!breaker) {\n return { exists: false };\n }\n\n return {\n exists: true,\n state: breaker.getState().toLowerCase(),\n failures: breaker.getFailures(),\n threshold: this.options.circuitBreakerThreshold,\n };\n }\n\n /**\n * Reset circuit breaker for job\n */\n public resetCircuitBreaker(jobId: string): boolean {\n const breaker = this.circuitBreakers.get(jobId);\n if (!breaker) {\n return false;\n }\n\n breaker.reset();\n this.logger.info(`Circuit breaker reset for job: ${jobId}`);\n return true;\n }\n\n /**\n * Update executor options at runtime\n */\n public updateOptions(options: Partial<JobExecutorOptions>): void {\n Object.assign(this.options, options);\n this.logger.info('JobExecutor options updated', 'JobExecutor', { options });\n }\n\n /**\n * Get current options\n */\n public getOptions(): Required<JobExecutorOptions> {\n return { ...this.options };\n }\n\n /**\n * Shutdown and cleanup\n */\n public async shutdown(gracePeriod: number = 30000): Promise<void> {\n this.logger.info('JobExecutor shutting down...', 'JobExecutor', {\n activeExecutions: this.activeExecutions.size,\n gracePeriod,\n });\n\n this.isShuttingDown = true;\n\n // Wait for active executions to complete or grace period to expire\n const startTime = Date.now();\n\n while (this.activeExecutions.size > 0 && Date.now() - startTime < gracePeriod) {\n this.logger.debug(`Waiting for ${this.activeExecutions.size} active executions to complete`);\n await this.sleep(1000);\n }\n\n // Force cancel remaining executions\n if (this.activeExecutions.size > 0) {\n this.logger.warn(`Force cancelling ${this.activeExecutions.size} remaining executions`);\n this.cancelAllExecutions();\n }\n\n // Cleanup state\n this.circuitBreakers.clear();\n this.activeExecutions.clear();\n\n this.removeAllListeners();\n this.logger.info('JobExecutor shutdown complete');\n }\n}\n"]}
@@ -5,7 +5,17 @@ export function requireAuth(options = {}) {
5
5
  return async (req, res, next) => {
6
6
  const auth = req.auth;
7
7
  if (!auth) {
8
- throw new Error('Auth middleware must be installed before using requireAuth');
8
+ // Server misconfiguration, not a client error. Throwing here surfaced as
9
+ // a generic "Internal server error" with no hint at the cause, which is
10
+ // a miserable first-run experience for anyone who declares .auth() on a
11
+ // route but forgets to install the middleware.
12
+ return res.status(500).json({
13
+ success: false,
14
+ error: 'Auth middleware not installed',
15
+ message: 'This route requires authentication, but no auth middleware is installed. ' +
16
+ 'Add `app.use(auth({ ... }))` during setup before using .auth() on a route ' +
17
+ 'or requireAuth() directly.',
18
+ });
9
19
  }
10
20
  // Check if already authenticated and should redirect
11
21
  if (auth.isAuthenticated && options.redirectOnAuth) {
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/auth/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["// Auth Helper Middleware and Utilities\nimport { AuthRequest } from '../../../../types/auth.js';\n\nexport interface AuthGuardOptions {\n redirectTo?: string;\n redirectOnAuth?: string; // Redirect if already authenticated\n authorize?: (user: any) => boolean | Promise<boolean>;\n roles?: string[];\n permissions?: string[];\n allowUnauthenticated?: boolean;\n onUnauthorized?: (req: any, res: any) => void;\n onForbidden?: (req: any, res: any) => void;\n}\n\nexport interface AuthRouteOptions {\n requireAuth?: boolean;\n roles?: string[];\n permissions?: string[];\n redirectTo?: string;\n}\n\n/**\n * Auth Guard Middleware - Protects routes with authentication and authorization\n */\nexport function requireAuth(options: AuthGuardOptions = {}) {\n return async (req: any, res: any, next: any) => {\n const auth: AuthRequest = req.auth;\n\n if (!auth) {\n throw new Error('Auth middleware must be installed before using requireAuth');\n }\n\n // Check if already authenticated and should redirect\n if (auth.isAuthenticated && options.redirectOnAuth) {\n return res.redirect(options.redirectOnAuth);\n }\n\n // Check authentication requirement\n if (!options.allowUnauthenticated && !auth.isAuthenticated) {\n if (options.onUnauthorized) {\n return options.onUnauthorized(req, res);\n }\n\n if (options.redirectTo) {\n return res.redirect(`${options.redirectTo}?callbackUrl=${encodeURIComponent(req.url)}`);\n }\n\n return res.status(401).json({\n error: 'Authentication required',\n message: 'You must be logged in to access this resource',\n signInUrl: '/api/auth/signin',\n });\n }\n\n // Skip further checks if not authenticated but allowed\n if (!auth.isAuthenticated && options.allowUnauthenticated) {\n return next();\n }\n\n const user = auth.user;\n\n // Check roles if specified\n if (options.roles && options.roles.length > 0) {\n const userRoles = user?.roles || [];\n const hasRole = options.roles.some(role => userRoles.includes(role));\n\n if (!hasRole) {\n if (options.onForbidden) {\n return options.onForbidden(req, res);\n }\n\n return res.status(403).json({\n error: 'Insufficient permissions',\n message: `Required roles: ${options.roles.join(', ')}`,\n userRoles,\n });\n }\n }\n\n // Check permissions if specified\n if (options.permissions && options.permissions.length > 0) {\n const userPermissions = user?.permissions || [];\n const hasPermission = options.permissions.every(permission =>\n userPermissions.includes(permission)\n );\n\n if (!hasPermission) {\n if (options.onForbidden) {\n return options.onForbidden(req, res);\n }\n\n return res.status(403).json({\n error: 'Insufficient permissions',\n message: `Required permissions: ${options.permissions.join(', ')}`,\n userPermissions,\n });\n }\n }\n\n // Custom authorization function\n if (options.authorize) {\n try {\n const authorized = await options.authorize(user);\n\n if (!authorized) {\n if (options.onForbidden) {\n return options.onForbidden(req, res);\n }\n\n return res.status(403).json({\n error: 'Access denied',\n message: 'Custom authorization check failed',\n });\n }\n } catch {\n return res.status(500).json({\n error: 'Authorization error',\n message: 'Failed to verify authorization',\n });\n }\n }\n\n // All checks passed\n next();\n };\n}\n\n/**\n * Role-based access control middleware\n */\nexport function requireRole(\n role: string | string[],\n options: Omit<AuthGuardOptions, 'roles'> = {}\n) {\n const roles = Array.isArray(role) ? role : [role];\n return requireAuth({ ...options, roles });\n}\n\n/**\n * Permission-based access control middleware\n */\nexport function requirePermission(\n permission: string | string[],\n options: Omit<AuthGuardOptions, 'permissions'> = {}\n) {\n const permissions = Array.isArray(permission) ? permission : [permission];\n return requireAuth({ ...options, permissions });\n}\n\n/**\n * Admin-only access middleware\n */\nexport function requireAdmin(options: Omit<AuthGuardOptions, 'roles'> = {}) {\n return requireRole('admin', options);\n}\n\n/**\n * Guest-only middleware (redirect if authenticated)\n */\nexport function guestOnly(redirectTo = '/dashboard') {\n return requireAuth({\n allowUnauthenticated: true,\n redirectOnAuth: redirectTo,\n });\n}\n\n/**\n * Optional auth middleware (allows both authenticated and unauthenticated)\n */\nexport function optionalAuth() {\n return requireAuth({\n allowUnauthenticated: true,\n });\n}\n\n/**\n * Route-level auth decorator\n */\nexport function withAuth(options: AuthRouteOptions = {}) {\n return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (req: any, res: any, next: any) {\n if (options.requireAuth !== false) {\n const authMiddleware = requireAuth({\n ...(options.roles !== undefined ? { roles: options.roles } : {}),\n ...(options.redirectTo !== undefined ? { redirectTo: options.redirectTo } : {}),\n });\n\n await new Promise<void>((resolve, reject) => {\n void authMiddleware(req, res, (error: any) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n\n return originalMethod.call(this, req, res, next);\n };\n\n return descriptor;\n };\n}\n\n/**\n * Auth utilities for manual checks in route handlers\n */\nexport const authUtils = {\n /**\n * Check if user is authenticated\n */\n isAuthenticated(req: any): boolean {\n return req.auth?.isAuthenticated || false;\n },\n\n /**\n * Get current user\n */\n getUser(req: any) {\n return req.auth?.user || null;\n },\n\n /**\n * Check if user has role\n */\n hasRole(req: any, role: string | string[]): boolean {\n const user = this.getUser(req);\n if (!user?.roles) return false;\n\n const roles = Array.isArray(role) ? role : [role];\n return roles.some(r => user.roles.includes(r));\n },\n\n /**\n * Check if user has permission\n */\n hasPermission(req: any, permission: string | string[]): boolean {\n const user = this.getUser(req);\n if (!user?.permissions) return false;\n\n const permissions = Array.isArray(permission) ? permission : [permission];\n return permissions.every(p => user.permissions.includes(p));\n },\n\n /**\n * Check if user is admin\n */\n isAdmin(req: any): boolean {\n return this.hasRole(req, 'admin');\n },\n\n /**\n * Get user ID\n */\n getUserId(req: any): string | null {\n return this.getUser(req)?.id || null;\n },\n\n /**\n * Force authentication check and redirect if needed\n */\n ensureAuth(req: any, res: any, redirectTo = '/api/auth/signin'): boolean {\n if (!this.isAuthenticated(req)) {\n res.redirect(`${redirectTo}?callbackUrl=${encodeURIComponent(req.url)}`);\n return false;\n }\n return true;\n },\n\n /**\n * Create auth response for API endpoints\n */\n createAuthResponse(req: any) {\n const auth = req.auth;\n\n return {\n isAuthenticated: auth?.isAuthenticated || false,\n user: auth?.user || null,\n session: auth?.session || null,\n timestamp: new Date().toISOString(),\n };\n },\n};\n\n/**\n * API Response helpers for auth endpoints\n */\nexport const authResponses = {\n unauthorized: (res: any, message = 'Authentication required') => {\n return res.status(401).json({\n error: 'Unauthorized',\n message,\n code: 'AUTH_REQUIRED',\n signInUrl: '/api/auth/signin',\n });\n },\n\n forbidden: (res: any, message = 'Insufficient permissions') => {\n return res.status(403).json({\n error: 'Forbidden',\n message,\n code: 'INSUFFICIENT_PERMISSIONS',\n });\n },\n\n authSuccess: (res: any, user: any, message = 'Authentication successful') => {\n return res.json({\n success: true,\n message,\n user: {\n id: user.id,\n name: user.name,\n email: user.email,\n roles: user.roles || [],\n permissions: user.permissions || [],\n },\n });\n },\n\n authError: (res: any, error: string, message = 'Authentication failed') => {\n return res.status(400).json({\n error,\n message,\n code: 'AUTH_ERROR',\n });\n },\n};\n\n/**\n * Higher-order function to create protected route handlers\n */\nexport function protectedRoute(\n handler: (req: any, res: any, next?: any) => any,\n options: AuthGuardOptions = {}\n) {\n return async (req: any, res: any, next: any) => {\n const authMiddleware = requireAuth(options);\n\n return new Promise<void>((resolve, reject) => {\n void authMiddleware(req, res, (error: any) => {\n if (error) {\n reject(error);\n } else {\n Promise.resolve(handler(req, res, next))\n .then(() => resolve())\n .catch(reject);\n }\n });\n });\n };\n}\n\n/**\n * Session management helpers\n */\nexport const sessionHelpers = {\n /**\n * Store data in session\n */\n async setSessionData(req: any, key: string, value: any) {\n if (req.session) {\n req.session[key] = value;\n await req.session.save();\n }\n },\n\n /**\n * Get data from session\n */\n getSessionData(req: any, key: string) {\n return req.session?.[key] || null;\n },\n\n /**\n * Remove data from session\n */\n async removeSessionData(req: any, key: string) {\n if (req.session && key in req.session.data) {\n delete req.session.data[key];\n await req.session.save();\n }\n },\n\n /**\n * Clear entire session\n */\n async clearSession(req: any) {\n if (req.session) {\n await req.session.destroy();\n }\n },\n\n /**\n * Regenerate session ID\n */\n async regenerateSession(req: any) {\n if (req.session) {\n return await req.session.regenerate();\n }\n },\n};\n"]}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/auth/helpers.ts"],"names":[],"mappings":"AAqBA;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,UAA4B,EAAE;IACxD,OAAO,KAAK,EAAE,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;QAC7C,MAAM,IAAI,GAAgB,GAAG,CAAC,IAAI,CAAC;QAEnC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,yEAAyE;YACzE,wEAAwE;YACxE,wEAAwE;YACxE,+CAA+C;YAC/C,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,+BAA+B;gBACtC,OAAO,EACL,2EAA2E;oBAC3E,4EAA4E;oBAC5E,4BAA4B;aAC/B,CAAC,CAAC;QACL,CAAC;QAED,qDAAqD;QACrD,IAAI,IAAI,CAAC,eAAe,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;YACnD,OAAO,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC9C,CAAC;QAED,mCAAmC;QACnC,IAAI,CAAC,OAAO,CAAC,oBAAoB,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC3D,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;gBAC3B,OAAO,OAAO,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC1C,CAAC;YAED,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;gBACvB,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,UAAU,gBAAgB,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1F,CAAC;YAED,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,KAAK,EAAE,yBAAyB;gBAChC,OAAO,EAAE,+CAA+C;gBACxD,SAAS,EAAE,kBAAkB;aAC9B,CAAC,CAAC;QACL,CAAC;QAED,uDAAuD;QACvD,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;YAC1D,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAEvB,2BAA2B;QAC3B,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,SAAS,GAAG,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YACpC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAErE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;oBACxB,OAAO,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBACvC,CAAC;gBAED,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,KAAK,EAAE,0BAA0B;oBACjC,OAAO,EAAE,mBAAmB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;oBACtD,SAAS;iBACV,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,iCAAiC;QACjC,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1D,MAAM,eAAe,GAAG,IAAI,EAAE,WAAW,IAAI,EAAE,CAAC;YAChD,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAC3D,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC,CACrC,CAAC;YAEF,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;oBACxB,OAAO,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBACvC,CAAC;gBAED,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,KAAK,EAAE,0BAA0B;oBACjC,OAAO,EAAE,yBAAyB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;oBAClE,eAAe;iBAChB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,gCAAgC;QAChC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBAEjD,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;wBACxB,OAAO,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;oBACvC,CAAC;oBAED,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;wBAC1B,KAAK,EAAE,eAAe;wBACtB,OAAO,EAAE,mCAAmC;qBAC7C,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,KAAK,EAAE,qBAAqB;oBAC5B,OAAO,EAAE,gCAAgC;iBAC1C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,oBAAoB;QACpB,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,IAAuB,EACvB,UAA2C,EAAE;IAE7C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,WAAW,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAA6B,EAC7B,UAAiD,EAAE;IAEnD,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAC1E,OAAO,WAAW,CAAC,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,UAA2C,EAAE;IACxE,OAAO,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,UAAU,GAAG,YAAY;IACjD,OAAO,WAAW,CAAC;QACjB,oBAAoB,EAAE,IAAI;QAC1B,cAAc,EAAE,UAAU;KAC3B,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,WAAW,CAAC;QACjB,oBAAoB,EAAE,IAAI;KAC3B,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,UAA4B,EAAE;IACrD,OAAO,UAAU,MAAW,EAAE,WAAmB,EAAE,UAA8B;QAC/E,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QAExC,UAAU,CAAC,KAAK,GAAG,KAAK,WAAW,GAAQ,EAAE,GAAQ,EAAE,IAAS;YAC9D,IAAI,OAAO,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;gBAClC,MAAM,cAAc,GAAG,WAAW,CAAC;oBACjC,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAChE,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAChF,CAAC,CAAC;gBAEH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBAC1C,KAAK,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,KAAU,EAAE,EAAE;wBAC3C,IAAI,KAAK;4BAAE,MAAM,CAAC,KAAK,CAAC,CAAC;;4BACpB,OAAO,EAAE,CAAC;oBACjB,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC;YAED,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACnD,CAAC,CAAC;QAEF,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB;;OAEG;IACH,eAAe,CAAC,GAAQ;QACtB,OAAO,GAAG,CAAC,IAAI,EAAE,eAAe,IAAI,KAAK,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,GAAQ;QACd,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,GAAQ,EAAE,IAAuB;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI,EAAE,KAAK;YAAE,OAAO,KAAK,CAAC;QAE/B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,GAAQ,EAAE,UAA6B;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI,EAAE,WAAW;YAAE,OAAO,KAAK,CAAC;QAErC,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAC1E,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,GAAQ;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,GAAQ;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,GAAQ,EAAE,GAAQ,EAAE,UAAU,GAAG,kBAAkB;QAC5D,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,GAAG,CAAC,QAAQ,CAAC,GAAG,UAAU,gBAAgB,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACzE,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,GAAQ;QACzB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QAEtB,OAAO;YACL,eAAe,EAAE,IAAI,EAAE,eAAe,IAAI,KAAK;YAC/C,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI;YACxB,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,IAAI;YAC9B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;IACJ,CAAC;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,YAAY,EAAE,CAAC,GAAQ,EAAE,OAAO,GAAG,yBAAyB,EAAE,EAAE;QAC9D,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,cAAc;YACrB,OAAO;YACP,IAAI,EAAE,eAAe;YACrB,SAAS,EAAE,kBAAkB;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,SAAS,EAAE,CAAC,GAAQ,EAAE,OAAO,GAAG,0BAA0B,EAAE,EAAE;QAC5D,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,WAAW;YAClB,OAAO;YACP,IAAI,EAAE,0BAA0B;SACjC,CAAC,CAAC;IACL,CAAC;IAED,WAAW,EAAE,CAAC,GAAQ,EAAE,IAAS,EAAE,OAAO,GAAG,2BAA2B,EAAE,EAAE;QAC1E,OAAO,GAAG,CAAC,IAAI,CAAC;YACd,OAAO,EAAE,IAAI;YACb,OAAO;YACP,IAAI,EAAE;gBACJ,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE;gBACvB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;aACpC;SACF,CAAC,CAAC;IACL,CAAC;IAED,SAAS,EAAE,CAAC,GAAQ,EAAE,KAAa,EAAE,OAAO,GAAG,uBAAuB,EAAE,EAAE;QACxE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK;YACL,OAAO;YACP,IAAI,EAAE,YAAY;SACnB,CAAC,CAAC;IACL,CAAC;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAgD,EAChD,UAA4B,EAAE;IAE9B,OAAO,KAAK,EAAE,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;QAC7C,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAE5C,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,KAAK,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,KAAU,EAAE,EAAE;gBAC3C,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChB,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;yBACrC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;yBACrB,KAAK,CAAC,MAAM,CAAC,CAAC;gBACnB,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,GAAQ,EAAE,GAAW,EAAE,KAAU;QACpD,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACzB,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,GAAQ,EAAE,GAAW;QAClC,OAAO,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CAAC,GAAQ,EAAE,GAAW;QAC3C,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC3C,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,GAAQ;QACzB,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CAAC,GAAQ;QAC9B,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACxC,CAAC;IACH,CAAC;CACF,CAAC","sourcesContent":["// Auth Helper Middleware and Utilities\nimport { AuthRequest } from '../../../../types/auth.js';\n\nexport interface AuthGuardOptions {\n redirectTo?: string;\n redirectOnAuth?: string; // Redirect if already authenticated\n authorize?: (user: any) => boolean | Promise<boolean>;\n roles?: string[];\n permissions?: string[];\n allowUnauthenticated?: boolean;\n onUnauthorized?: (req: any, res: any) => void;\n onForbidden?: (req: any, res: any) => void;\n}\n\nexport interface AuthRouteOptions {\n requireAuth?: boolean;\n roles?: string[];\n permissions?: string[];\n redirectTo?: string;\n}\n\n/**\n * Auth Guard Middleware - Protects routes with authentication and authorization\n */\nexport function requireAuth(options: AuthGuardOptions = {}) {\n return async (req: any, res: any, next: any) => {\n const auth: AuthRequest = req.auth;\n\n if (!auth) {\n // Server misconfiguration, not a client error. Throwing here surfaced as\n // a generic \"Internal server error\" with no hint at the cause, which is\n // a miserable first-run experience for anyone who declares .auth() on a\n // route but forgets to install the middleware.\n return res.status(500).json({\n success: false,\n error: 'Auth middleware not installed',\n message:\n 'This route requires authentication, but no auth middleware is installed. ' +\n 'Add `app.use(auth({ ... }))` during setup before using .auth() on a route ' +\n 'or requireAuth() directly.',\n });\n }\n\n // Check if already authenticated and should redirect\n if (auth.isAuthenticated && options.redirectOnAuth) {\n return res.redirect(options.redirectOnAuth);\n }\n\n // Check authentication requirement\n if (!options.allowUnauthenticated && !auth.isAuthenticated) {\n if (options.onUnauthorized) {\n return options.onUnauthorized(req, res);\n }\n\n if (options.redirectTo) {\n return res.redirect(`${options.redirectTo}?callbackUrl=${encodeURIComponent(req.url)}`);\n }\n\n return res.status(401).json({\n error: 'Authentication required',\n message: 'You must be logged in to access this resource',\n signInUrl: '/api/auth/signin',\n });\n }\n\n // Skip further checks if not authenticated but allowed\n if (!auth.isAuthenticated && options.allowUnauthenticated) {\n return next();\n }\n\n const user = auth.user;\n\n // Check roles if specified\n if (options.roles && options.roles.length > 0) {\n const userRoles = user?.roles || [];\n const hasRole = options.roles.some(role => userRoles.includes(role));\n\n if (!hasRole) {\n if (options.onForbidden) {\n return options.onForbidden(req, res);\n }\n\n return res.status(403).json({\n error: 'Insufficient permissions',\n message: `Required roles: ${options.roles.join(', ')}`,\n userRoles,\n });\n }\n }\n\n // Check permissions if specified\n if (options.permissions && options.permissions.length > 0) {\n const userPermissions = user?.permissions || [];\n const hasPermission = options.permissions.every(permission =>\n userPermissions.includes(permission)\n );\n\n if (!hasPermission) {\n if (options.onForbidden) {\n return options.onForbidden(req, res);\n }\n\n return res.status(403).json({\n error: 'Insufficient permissions',\n message: `Required permissions: ${options.permissions.join(', ')}`,\n userPermissions,\n });\n }\n }\n\n // Custom authorization function\n if (options.authorize) {\n try {\n const authorized = await options.authorize(user);\n\n if (!authorized) {\n if (options.onForbidden) {\n return options.onForbidden(req, res);\n }\n\n return res.status(403).json({\n error: 'Access denied',\n message: 'Custom authorization check failed',\n });\n }\n } catch {\n return res.status(500).json({\n error: 'Authorization error',\n message: 'Failed to verify authorization',\n });\n }\n }\n\n // All checks passed\n next();\n };\n}\n\n/**\n * Role-based access control middleware\n */\nexport function requireRole(\n role: string | string[],\n options: Omit<AuthGuardOptions, 'roles'> = {}\n) {\n const roles = Array.isArray(role) ? role : [role];\n return requireAuth({ ...options, roles });\n}\n\n/**\n * Permission-based access control middleware\n */\nexport function requirePermission(\n permission: string | string[],\n options: Omit<AuthGuardOptions, 'permissions'> = {}\n) {\n const permissions = Array.isArray(permission) ? permission : [permission];\n return requireAuth({ ...options, permissions });\n}\n\n/**\n * Admin-only access middleware\n */\nexport function requireAdmin(options: Omit<AuthGuardOptions, 'roles'> = {}) {\n return requireRole('admin', options);\n}\n\n/**\n * Guest-only middleware (redirect if authenticated)\n */\nexport function guestOnly(redirectTo = '/dashboard') {\n return requireAuth({\n allowUnauthenticated: true,\n redirectOnAuth: redirectTo,\n });\n}\n\n/**\n * Optional auth middleware (allows both authenticated and unauthenticated)\n */\nexport function optionalAuth() {\n return requireAuth({\n allowUnauthenticated: true,\n });\n}\n\n/**\n * Route-level auth decorator\n */\nexport function withAuth(options: AuthRouteOptions = {}) {\n return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (req: any, res: any, next: any) {\n if (options.requireAuth !== false) {\n const authMiddleware = requireAuth({\n ...(options.roles !== undefined ? { roles: options.roles } : {}),\n ...(options.redirectTo !== undefined ? { redirectTo: options.redirectTo } : {}),\n });\n\n await new Promise<void>((resolve, reject) => {\n void authMiddleware(req, res, (error: any) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n\n return originalMethod.call(this, req, res, next);\n };\n\n return descriptor;\n };\n}\n\n/**\n * Auth utilities for manual checks in route handlers\n */\nexport const authUtils = {\n /**\n * Check if user is authenticated\n */\n isAuthenticated(req: any): boolean {\n return req.auth?.isAuthenticated || false;\n },\n\n /**\n * Get current user\n */\n getUser(req: any) {\n return req.auth?.user || null;\n },\n\n /**\n * Check if user has role\n */\n hasRole(req: any, role: string | string[]): boolean {\n const user = this.getUser(req);\n if (!user?.roles) return false;\n\n const roles = Array.isArray(role) ? role : [role];\n return roles.some(r => user.roles.includes(r));\n },\n\n /**\n * Check if user has permission\n */\n hasPermission(req: any, permission: string | string[]): boolean {\n const user = this.getUser(req);\n if (!user?.permissions) return false;\n\n const permissions = Array.isArray(permission) ? permission : [permission];\n return permissions.every(p => user.permissions.includes(p));\n },\n\n /**\n * Check if user is admin\n */\n isAdmin(req: any): boolean {\n return this.hasRole(req, 'admin');\n },\n\n /**\n * Get user ID\n */\n getUserId(req: any): string | null {\n return this.getUser(req)?.id || null;\n },\n\n /**\n * Force authentication check and redirect if needed\n */\n ensureAuth(req: any, res: any, redirectTo = '/api/auth/signin'): boolean {\n if (!this.isAuthenticated(req)) {\n res.redirect(`${redirectTo}?callbackUrl=${encodeURIComponent(req.url)}`);\n return false;\n }\n return true;\n },\n\n /**\n * Create auth response for API endpoints\n */\n createAuthResponse(req: any) {\n const auth = req.auth;\n\n return {\n isAuthenticated: auth?.isAuthenticated || false,\n user: auth?.user || null,\n session: auth?.session || null,\n timestamp: new Date().toISOString(),\n };\n },\n};\n\n/**\n * API Response helpers for auth endpoints\n */\nexport const authResponses = {\n unauthorized: (res: any, message = 'Authentication required') => {\n return res.status(401).json({\n error: 'Unauthorized',\n message,\n code: 'AUTH_REQUIRED',\n signInUrl: '/api/auth/signin',\n });\n },\n\n forbidden: (res: any, message = 'Insufficient permissions') => {\n return res.status(403).json({\n error: 'Forbidden',\n message,\n code: 'INSUFFICIENT_PERMISSIONS',\n });\n },\n\n authSuccess: (res: any, user: any, message = 'Authentication successful') => {\n return res.json({\n success: true,\n message,\n user: {\n id: user.id,\n name: user.name,\n email: user.email,\n roles: user.roles || [],\n permissions: user.permissions || [],\n },\n });\n },\n\n authError: (res: any, error: string, message = 'Authentication failed') => {\n return res.status(400).json({\n error,\n message,\n code: 'AUTH_ERROR',\n });\n },\n};\n\n/**\n * Higher-order function to create protected route handlers\n */\nexport function protectedRoute(\n handler: (req: any, res: any, next?: any) => any,\n options: AuthGuardOptions = {}\n) {\n return async (req: any, res: any, next: any) => {\n const authMiddleware = requireAuth(options);\n\n return new Promise<void>((resolve, reject) => {\n void authMiddleware(req, res, (error: any) => {\n if (error) {\n reject(error);\n } else {\n Promise.resolve(handler(req, res, next))\n .then(() => resolve())\n .catch(reject);\n }\n });\n });\n };\n}\n\n/**\n * Session management helpers\n */\nexport const sessionHelpers = {\n /**\n * Store data in session\n */\n async setSessionData(req: any, key: string, value: any) {\n if (req.session) {\n req.session[key] = value;\n await req.session.save();\n }\n },\n\n /**\n * Get data from session\n */\n getSessionData(req: any, key: string) {\n return req.session?.[key] || null;\n },\n\n /**\n * Remove data from session\n */\n async removeSessionData(req: any, key: string) {\n if (req.session && key in req.session.data) {\n delete req.session.data[key];\n await req.session.save();\n }\n },\n\n /**\n * Clear entire session\n */\n async clearSession(req: any) {\n if (req.session) {\n await req.session.destroy();\n }\n },\n\n /**\n * Regenerate session ID\n */\n async regenerateSession(req: any) {\n if (req.session) {\n return await req.session.regenerate();\n }\n },\n};\n"]}
@@ -40,6 +40,11 @@ export class RouteBuilder {
40
40
  this.schema.validation.params = config.params;
41
41
  if (config.headers !== undefined)
42
42
  this.schema.validation.headers = config.headers;
43
+ // Without this, `.body(schema).validate({ onValidationError })` silently
44
+ // dropped the handler and fell back to the default 400 response.
45
+ if (config.onValidationError !== undefined) {
46
+ this.schema.validation.onValidationError = config.onValidationError;
47
+ }
43
48
  }
44
49
  return this;
45
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"unified-router.js","sourceRoot":"","sources":["../../../src/core/routing/unified-router.ts"],"names":[],"mappings":"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","sourcesContent":["// Unified Router - Consolidates Intelligent Router and Core Router\n// Combines best features from both systems with zero breaking changes\n\nimport { PathMatcher, CompiledPath } from './path-matcher.js';\nimport { ObjectPoolManager } from '../pooling/object-pool-manager.js';\nimport { createFrameworkLogger } from '../logger/index.js';\nimport { HttpRequest, HttpResponse } from '../../types/http.js';\nimport { RateLimitCore, type RateLimitConfig } from '../middleware/built-in/rate-limit/index.js';\nimport { CacheCore, type CacheConfig } from '../middleware/built-in/cache/index.js';\nimport { ValidationCore, type ValidationConfig } from '../middleware/built-in/validation/index.js';\nimport { requireAuth } from '../middleware/built-in/auth/helpers.js';\nimport { ValidationSchema } from '../validation/schema-interface.js';\nimport { MethodRadixRouter } from './radix-tree.js';\n\nconst logger = createFrameworkLogger('UnifiedRouter');\n\n// Shared Core instances for route-based features\nconst rateLimitCore = new RateLimitCore();\nconst cacheCore = new CacheCore();\nconst validationCore = new ValidationCore();\n\n// ===== Types =====\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';\nexport type RouteHandler<T = any> = (req: HttpRequest, res: HttpResponse) => T | Promise<T>;\nexport type Middleware = (\n req: HttpRequest,\n res: HttpResponse,\n next: () => void\n) => void | Promise<void>;\n\nexport interface AuthConfig {\n roles?: string[];\n permissions?: string[];\n optional?: boolean;\n}\n\n// Re-export config types from built-in middleware for convenience\nexport type { RateLimitConfig, CacheConfig, ValidationConfig };\n\nexport interface MiddlewarePhases {\n before?: Middleware[];\n after?: Middleware[];\n transform?: Middleware[];\n}\n\nexport interface RouteSchema {\n method: HttpMethod;\n path: string;\n handler: RouteHandler;\n validation?: ValidationConfig;\n auth?: AuthConfig;\n rateLimit?: RateLimitConfig;\n cache?: CacheConfig;\n middleware?: MiddlewarePhases | Middleware[];\n description?: string;\n tags?: string[];\n}\n\n// Internal route representation\ninterface InternalRoute {\n schema: RouteSchema;\n compiledPath: CompiledPath;\n isFastPath: boolean; // No middleware, auth, validation, rate limiting\n executionOrder: string[]; // Ordered list of execution phases\n // Route-specific configs (not middleware)\n rateLimitConfig?: RateLimitConfig;\n cacheConfig?: CacheConfig;\n authMiddleware?: Middleware; // Auth keeps middleware since it's using requireAuth helper\n validationConfig?: ValidationConfig;\n}\n\n// ===== Route Builder (Chainable API) =====\n\nexport class RouteBuilder {\n private schema: Partial<RouteSchema>;\n private router: UnifiedRouter;\n\n constructor(method: HttpMethod, path: string, router: UnifiedRouter) {\n this.schema = {\n method,\n path,\n middleware: {} as MiddlewarePhases,\n };\n this.router = router;\n }\n\n // Validation methods\n validate(config: ValidationConfig): this {\n // Avoid spread operator and Object.assign - manually merge properties\n if (!this.schema.validation) {\n this.schema.validation = config;\n } else {\n if (config.body !== undefined) this.schema.validation.body = config.body;\n if (config.query !== undefined) this.schema.validation.query = config.query;\n if (config.params !== undefined) this.schema.validation.params = config.params;\n if (config.headers !== undefined) this.schema.validation.headers = config.headers;\n }\n return this;\n }\n\n body<T>(schema: ValidationSchema<T>): this {\n if (!this.schema.validation) this.schema.validation = {};\n this.schema.validation.body = schema;\n return this;\n }\n\n query<T>(schema: ValidationSchema<T>): this {\n if (!this.schema.validation) this.schema.validation = {};\n this.schema.validation.query = schema;\n return this;\n }\n\n params<T>(schema: ValidationSchema<T>): this {\n if (!this.schema.validation) this.schema.validation = {};\n this.schema.validation.params = schema;\n return this;\n }\n\n headers<T>(schema: ValidationSchema<T>): this {\n if (!this.schema.validation) this.schema.validation = {};\n this.schema.validation.headers = schema;\n return this;\n }\n\n // Security methods\n auth(config: AuthConfig): this {\n this.schema.auth = config;\n return this;\n }\n\n rateLimit(config: RateLimitConfig): this {\n this.schema.rateLimit = config;\n return this;\n }\n\n // Caching\n cache(config: CacheConfig): this {\n this.schema.cache = config;\n return this;\n }\n\n // Custom middleware\n before(...middleware: Middleware[]): this {\n if (!this.schema.middleware) this.schema.middleware = {};\n const phases = this.schema.middleware as MiddlewarePhases;\n // Avoid spread, use push for better performance\n if (!phases.before) phases.before = [];\n for (let i = 0; i < middleware.length; i++) {\n phases.before.push(middleware[i] as Middleware);\n }\n return this;\n }\n\n after(...middleware: Middleware[]): this {\n if (!this.schema.middleware) this.schema.middleware = {};\n const phases = this.schema.middleware as MiddlewarePhases;\n // Avoid spread, use push for better performance\n if (!phases.after) phases.after = [];\n for (let i = 0; i < middleware.length; i++) {\n phases.after.push(middleware[i] as Middleware);\n }\n return this;\n }\n\n transform(...middleware: Middleware[]): this {\n if (!this.schema.middleware) this.schema.middleware = {};\n const phases = this.schema.middleware as MiddlewarePhases;\n // Avoid spread, use push for better performance\n if (!phases.transform) phases.transform = [];\n for (let i = 0; i < middleware.length; i++) {\n phases.transform.push(middleware[i] as Middleware);\n }\n return this;\n }\n\n use(...middleware: Middleware[]): this {\n return this.after(...middleware);\n }\n\n // Metadata\n describe(description: string): this {\n this.schema.description = description;\n return this;\n }\n\n tag(...tags: string[]): this {\n // Avoid spread, use push for better performance\n if (!this.schema.tags) this.schema.tags = [];\n for (let i = 0; i < tags.length; i++) {\n this.schema.tags.push(tags[i] as string);\n }\n return this;\n }\n\n // Terminal method\n handler<T>(handler: RouteHandler<T>): void {\n if (!handler) {\n throw new Error('Handler is required');\n }\n\n // Avoid spread operator - add handler directly\n this.schema.handler = handler;\n this.router.registerRoute(this.schema as RouteSchema);\n }\n}\n\n// ===== Unified Router =====\n\nexport class UnifiedRouter {\n private static instance: UnifiedRouter | null = null;\n\n private readonly poolManager = ObjectPoolManager.getInstance();\n\n // Route storage optimized for different access patterns\n // OPTIMIZATION: Separate maps per method for faster lookup (no string concat needed)\n private staticRoutesByMethod = {\n GET: new Map<string, InternalRoute>(),\n POST: new Map<string, InternalRoute>(),\n PUT: new Map<string, InternalRoute>(),\n DELETE: new Map<string, InternalRoute>(),\n PATCH: new Map<string, InternalRoute>(),\n HEAD: new Map<string, InternalRoute>(),\n OPTIONS: new Map<string, InternalRoute>(),\n };\n private dynamicRoutesBySegments = new Map<number, InternalRoute[]>(); // Grouped by segment count\n private fastPathRoutes = new Set<InternalRoute>(); // Routes with no middleware\n private allRoutes: InternalRoute[] = []; // For iteration/inspection\n\n // NEW: Radix tree for fast dynamic route matching\n private radixRouter = new MethodRadixRouter();\n\n // Statistics\n private stats = {\n totalRoutes: 0,\n staticRoutes: 0,\n dynamicRoutes: 0,\n fastPathRoutes: 0,\n requestCount: 0,\n fastPathHits: 0,\n staticHits: 0,\n dynamicHits: 0,\n cacheHits: 0,\n radixHits: 0,\n };\n\n constructor() {\n logger.debug('UnifiedRouter initialized', 'Initialization');\n }\n\n // User-registered global error handler (set via Moro.setErrorHandler)\n private errorHandler?: (err: any, req: HttpRequest, res: HttpResponse) => any | Promise<any>;\n\n // Lifecycle hook manager (set via Moro) so 'error' hooks observe handler\n // errors — the router swallows them here, so the server-level error\n // boundary never sees them.\n private hookManager?: any;\n\n setErrorHandler(fn: (err: any, req: HttpRequest, res: HttpResponse) => any | Promise<any>): void {\n this.errorHandler = fn;\n }\n\n setHookManager(hookManager: any): void {\n this.hookManager = hookManager;\n }\n\n // Invoke the registered error handler (if any). Returns true if it produced a response.\n private async invokeErrorHandler(\n err: any,\n req: HttpRequest,\n res: HttpResponse\n ): Promise<boolean> {\n // Error hooks are observational: fire-and-forget so a slow or throwing\n // observer can never delay or alter the error response.\n if (\n this.hookManager &&\n (this.hookManager.hasHooks === undefined || this.hookManager.hasHooks('error'))\n ) {\n void Promise.resolve(\n this.hookManager.execute('error', { request: req, response: res, error: err })\n ).catch((hookError: any) =>\n logger.error('Error hook error', 'Hooks', {\n error: hookError instanceof Error ? hookError.message : String(hookError),\n })\n );\n }\n\n if (!this.errorHandler || res.headersSent) return false;\n try {\n const result = this.errorHandler(err, req, res);\n if (result && typeof (result as any).then === 'function') {\n await result;\n }\n return res.headersSent;\n } catch (handlerErr) {\n logger.error('Error handler itself threw', 'Execution', {\n error: handlerErr instanceof Error ? handlerErr.message : String(handlerErr),\n });\n return false;\n }\n }\n\n /**\n * Get singleton instance (optional - can still create new instances)\n */\n static getInstance(): UnifiedRouter {\n if (!this.instance) {\n this.instance = new UnifiedRouter();\n logger.info(`UnifiedRouter initialized (PID: ${process.pid})`, 'Router');\n }\n return this.instance;\n }\n\n /**\n * Reset singleton (useful for testing)\n */\n static reset(): void {\n if (this.instance) {\n this.instance.clearAllRoutes();\n }\n this.instance = null;\n }\n\n /**\n * Clear all routes (useful for testing)\n */\n clearAllRoutes(): void {\n this.staticRoutesByMethod.GET.clear();\n this.staticRoutesByMethod.POST.clear();\n this.staticRoutesByMethod.PUT.clear();\n this.staticRoutesByMethod.DELETE.clear();\n this.staticRoutesByMethod.PATCH.clear();\n this.staticRoutesByMethod.HEAD.clear();\n this.staticRoutesByMethod.OPTIONS.clear();\n this.dynamicRoutesBySegments.clear();\n this.fastPathRoutes.clear();\n this.allRoutes = [];\n this.radixRouter.clear();\n this.stats = {\n totalRoutes: 0,\n staticRoutes: 0,\n dynamicRoutes: 0,\n fastPathRoutes: 0,\n requestCount: 0,\n fastPathHits: 0,\n staticHits: 0,\n dynamicHits: 0,\n cacheHits: 0,\n radixHits: 0,\n };\n logger.debug('UnifiedRouter routes cleared', 'Reset');\n }\n\n // ===== Route Registration =====\n\n /**\n * Register a route (internal method) - OPTIMIZED\n */\n registerRoute(schema: RouteSchema): void {\n // OPTIMIZATION: Skip PathMatcher.compile for better performance\n // Determine if static route (optimized check)\n const pathLen = schema.path.length;\n let hasParams = false;\n for (let i = 0; i < pathLen; i++) {\n if (schema.path.charCodeAt(i) === 58) {\n // ':' character\n hasParams = true;\n break;\n }\n }\n\n const isStatic = !hasParams;\n const isFastPath = this.isFastPathRoute(schema);\n\n // OPTIMIZATION: Lazy execution order building (only when needed)\n const executionOrder = isFastPath ? [] : this.buildExecutionOrder(schema);\n\n // OPTIMIZATION: Lazy auth middleware creation (only create when needed, not during registration)\n // This speeds up route registration significantly\n const route: InternalRoute = {\n schema,\n compiledPath: null as any, // Will be set lazily if needed\n isFastPath,\n executionOrder,\n rateLimitConfig: schema.rateLimit,\n cacheConfig: schema.cache,\n authMiddleware: undefined, // Will be created lazily on first request\n validationConfig: schema.validation,\n } as any;\n\n // Store in appropriate structures\n if (isStatic) {\n const methodMap = this.staticRoutesByMethod[schema.method as HttpMethod];\n if (methodMap) {\n methodMap.set(schema.path, route);\n }\n this.stats.staticRoutes++;\n\n // DON'T add static routes to radix tree - Map is faster\n } else {\n // Add ONLY dynamic routes to radix tree (primary lookup for dynamic routes)\n this.radixRouter.addRoute(schema.method, schema.path, route);\n\n // Keep segment-based grouping for backward compatibility\n const segments = this.countSegmentsFast(schema.path);\n let routes = this.dynamicRoutesBySegments.get(segments);\n if (!routes) {\n routes = [];\n this.dynamicRoutesBySegments.set(segments, routes);\n }\n routes.push(route);\n this.stats.dynamicRoutes++;\n }\n\n if (isFastPath) {\n this.fastPathRoutes.add(route);\n this.stats.fastPathRoutes++;\n }\n\n this.allRoutes.push(route);\n this.stats.totalRoutes++;\n\n // OPTIMIZATION: Skip logging in production for performance\n // Most routes are registered once at startup, so this isn't a hot path\n // But reducing allocations still helps\n }\n\n /**\n * Fast segment counting without allocations\n */\n private countSegmentsFast(path: string): number {\n let count = 0;\n let inSegment = false;\n const len = path.length;\n\n for (let i = 0; i < len; i++) {\n const char = path.charCodeAt(i);\n if (char === 47) {\n // '/' character\n inSegment = false;\n } else if (!inSegment) {\n inSegment = true;\n count++;\n }\n }\n\n return count;\n }\n\n /**\n * Compile specialized param extractor for common cases\n */\n private compileParamExtractor(\n compiledPath: CompiledPath\n ): (matches: RegExpMatchArray) => Record<string, string> {\n const paramNames = compiledPath.paramNames;\n const paramCount = paramNames.length;\n\n // Specialized extractors for common cases\n if (paramCount === 0) {\n return () => ({}); // No allocation needed\n } else if (paramCount === 1) {\n const name = paramNames[0] as string;\n return matches => ({ [name]: matches[1] as string });\n } else if (paramCount === 2) {\n const name1 = paramNames[0] as string;\n const name2 = paramNames[1] as string;\n return matches => ({ [name1]: matches[1] as string, [name2]: matches[2] as string });\n } else if (paramCount === 3) {\n const name1 = paramNames[0] as string;\n const name2 = paramNames[1] as string;\n const name3 = paramNames[2] as string;\n return matches => ({\n [name1]: matches[1] as string,\n [name2]: matches[2] as string,\n [name3]: matches[3] as string,\n });\n } else {\n // Generic path for 4+ params\n return matches => {\n const params: Record<string, string> = {};\n for (let i = 0; i < paramCount; i++) {\n params[paramNames[i] as string] = matches[i + 1] as string;\n }\n return params;\n };\n }\n }\n\n /**\n * Chainable API methods\n */\n get(path: string): RouteBuilder {\n return new RouteBuilder('GET', path, this);\n }\n\n post(path: string): RouteBuilder {\n return new RouteBuilder('POST', path, this);\n }\n\n put(path: string): RouteBuilder {\n return new RouteBuilder('PUT', path, this);\n }\n\n delete(path: string): RouteBuilder {\n return new RouteBuilder('DELETE', path, this);\n }\n\n patch(path: string): RouteBuilder {\n return new RouteBuilder('PATCH', path, this);\n }\n\n head(path: string): RouteBuilder {\n return new RouteBuilder('HEAD', path, this);\n }\n\n options(path: string): RouteBuilder {\n return new RouteBuilder('OPTIONS', path, this);\n }\n\n /**\n * Schema-first route registration\n */\n route(schema: RouteSchema): void {\n this.registerRoute(schema);\n }\n\n /**\n * Direct API (for backward compatibility)\n */\n addRoute(\n method: HttpMethod,\n path: string,\n handler: RouteHandler,\n middleware: Middleware[] = []\n ): void {\n this.registerRoute({\n method,\n path,\n handler,\n middleware,\n });\n }\n\n // ===== Route Matching =====\n\n /**\n * Find a matching route for the request - HYBRID OPTIMIZED\n * Returns boolean (sync) for fast-path routes, Promise<boolean> for others\n */\n handleRequest(req: HttpRequest, res: HttpResponse): Promise<boolean> | boolean {\n this.stats.requestCount++;\n\n const method = req.method?.toUpperCase() as HttpMethod;\n const path = req.path;\n\n // FAST PATH 1: Try static route Map lookup first (fastest possible - no string concat)\n const methodMap = this.staticRoutesByMethod[method];\n if (methodMap) {\n const staticRoute = methodMap.get(path);\n\n if (staticRoute) {\n // OPTIMIZATION: Reuse empty params object to avoid allocation\n if (!req.params) {\n req.params = {};\n }\n\n // Fast-path execution (no middleware)\n if (staticRoute.isFastPath) {\n try {\n const result = staticRoute.schema.handler(req, res);\n\n if (result && typeof (result as any).then === 'function') {\n return (result as Promise<any>)\n .then(actualResult => {\n if (actualResult !== undefined && !res.headersSent) {\n res.json(actualResult);\n }\n return true;\n })\n .catch(async err => {\n const handled = await this.invokeErrorHandler(err, req, res);\n if (!handled && !res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n return true;\n });\n } else {\n if (result !== undefined && !res.headersSent) {\n res.json(result);\n }\n return true;\n }\n } catch (err) {\n return (async () => {\n const handled = await this.invokeErrorHandler(err, req, res);\n if (!handled && !res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n return true;\n })();\n }\n }\n\n // Non-fast-path static route\n return (async () => {\n await this.executeRoute(staticRoute, req, res, { params: {} });\n return true;\n })();\n }\n }\n\n // FAST PATH 2: Try radix tree for dynamic routes\n const radixResult = this.radixRouter.findRoute(method, path);\n if (radixResult) {\n const route = radixResult.handler as InternalRoute;\n req.params = radixResult.params;\n\n // Fast-path dynamic routes (no middleware)\n if (route.isFastPath) {\n try {\n const result = route.schema.handler(req, res);\n\n if (result && typeof (result as any).then === 'function') {\n return (result as Promise<any>)\n .then(actualResult => {\n if (actualResult !== undefined && !res.headersSent) {\n res.json(actualResult);\n }\n return true;\n })\n .catch(async err => {\n const handled = await this.invokeErrorHandler(err, req, res);\n if (!handled && !res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n return true;\n });\n } else {\n if (result !== undefined && !res.headersSent) {\n res.json(result);\n }\n return true;\n }\n } catch (err) {\n return (async () => {\n const handled = await this.invokeErrorHandler(err, req, res);\n if (!handled && !res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n return true;\n })();\n }\n }\n\n // Non-fast-path dynamic routes (with middleware)\n return (async () => {\n await this.executeRoute(route, req, res, { params: radixResult.params });\n return true;\n })();\n }\n\n // No route found\n return false;\n }\n\n // ===== Route Execution =====\n\n private async executeRoute(\n route: InternalRoute,\n req: HttpRequest,\n res: HttpResponse,\n matchResult: { params: Record<string, string> }\n ): Promise<void> {\n // The matcher already built a fresh params object - use it directly.\n // (No pooling: handlers may retain req past the response, so recycling\n // the object would alias params across requests.)\n req.params = matchResult.params;\n\n try {\n // Performance: Skip empty executionOrder array iteration\n // Most routes have empty or very short executionOrder\n if (route.executionOrder.length > 0) {\n // Execute middleware phases in order\n for (const phase of route.executionOrder) {\n if (res.headersSent) break;\n await this.executePhase(phase, route, req, res);\n }\n }\n\n // Execute handler\n if (!res.headersSent) {\n const result = await route.schema.handler(req, res);\n if (result !== undefined && !res.headersSent) {\n await res.json(result);\n }\n } else {\n // Headers already sent by middleware (e.g., cache hit, validation error, rate limit, auth)\n // This is expected behavior, not an error\n logger.debug('Handler skipped - response already sent by middleware', 'Execution');\n }\n } catch (error) {\n logger.error('Route execution error', 'Execution', {\n error: error instanceof Error ? error.message : String(error),\n route: `${route.schema.method} ${route.schema.path}`,\n });\n\n const handled = await this.invokeErrorHandler(error, req, res);\n if (!handled && !res.headersSent) {\n res.status(500).json({\n success: false,\n error: 'Internal server error',\n requestId: req.requestId,\n });\n }\n }\n }\n\n private async executePhase(\n phase: string,\n route: InternalRoute,\n req: HttpRequest,\n res: HttpResponse\n ): Promise<void> {\n const schema = route.schema;\n const middleware = schema.middleware;\n\n switch (phase) {\n case 'before': {\n // Performance: Early exit if no middleware present (fast path)\n if (!middleware || !('before' in middleware)) break;\n const beforeMw = (middleware as MiddlewarePhases).before;\n if (!beforeMw || beforeMw.length === 0) break;\n\n const beforeLen = beforeMw.length;\n for (let i = 0; i < beforeLen; i++) {\n await this.executeMiddleware(beforeMw[i] as Middleware, req, res);\n if (res.headersSent) return;\n }\n break;\n }\n\n case 'rateLimit':\n // Use Core directly for route-based rate limiting\n if (route.rateLimitConfig) {\n await rateLimitCore.checkLimit(req, res, route.rateLimitConfig);\n }\n break;\n\n case 'auth':\n // Auth uses middleware (from requireAuth helper) - created lazily\n if (schema.auth) {\n if (!route.authMiddleware) {\n route.authMiddleware = requireAuth({\n ...(schema.auth.roles !== undefined && { roles: schema.auth.roles }),\n ...(schema.auth.permissions !== undefined && {\n permissions: schema.auth.permissions,\n }),\n ...(schema.auth.optional !== undefined && {\n allowUnauthenticated: schema.auth.optional,\n }),\n });\n }\n await this.executeMiddleware(route.authMiddleware, req, res);\n }\n break;\n\n case 'validation':\n // Use Core directly for route-based validation\n if (route.validationConfig) {\n const isValid = await validationCore.validate(req, res, route.validationConfig);\n if (!isValid) {\n return; // Validation failed, response already sent\n }\n }\n break;\n\n case 'transform': {\n // Performance: Early exit if no middleware present (fast path)\n if (!middleware || !('transform' in middleware)) break;\n const transformMw = (middleware as MiddlewarePhases).transform;\n if (!transformMw || transformMw.length === 0) break;\n\n const transformLen = transformMw.length;\n for (let i = 0; i < transformLen; i++) {\n await this.executeMiddleware(transformMw[i] as Middleware, req, res);\n if (res.headersSent) return;\n }\n break;\n }\n\n case 'cache':\n // Use Core directly for route-based caching\n if (route.cacheConfig) {\n const cached = await cacheCore.tryGet(req, res, route.cacheConfig);\n if (cached) {\n return; // Cache hit, response already sent\n }\n }\n break;\n\n case 'after': {\n // Performance: Early exit if no middleware present (fast path)\n if (!middleware || !('after' in middleware)) break;\n const afterMw = (middleware as MiddlewarePhases).after;\n if (!afterMw || afterMw.length === 0) break;\n\n const afterLen = afterMw.length;\n for (let i = 0; i < afterLen; i++) {\n await this.executeMiddleware(afterMw[i] as Middleware, req, res);\n if (res.headersSent) return;\n }\n break;\n }\n\n case 'middleware': {\n // Handle array-style middleware (backward compatibility)\n // Performance: Early exit if no middleware present (fast path)\n if (!middleware || !Array.isArray(middleware) || middleware.length === 0) break;\n\n const middlewareLen = middleware.length;\n for (let i = 0; i < middlewareLen; i++) {\n await this.executeMiddleware(middleware[i] as Middleware, req, res);\n if (res.headersSent) return;\n }\n break;\n }\n }\n }\n\n private async executeMiddleware(\n middleware: Middleware,\n req: HttpRequest,\n res: HttpResponse\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n let resolved = false;\n\n const next = () => {\n if (!resolved) {\n resolved = true;\n resolve();\n }\n };\n\n try {\n const result = middleware(req, res, next);\n // Duck typing faster than instanceof\n if (result && typeof result.then === 'function') {\n result.then(() => !resolved && next()).catch(reject);\n } else if (!resolved) {\n next();\n }\n } catch (error) {\n if (!resolved) {\n resolved = true;\n reject(error);\n }\n }\n });\n }\n\n // ===== Helper Methods =====\n\n private isFastPathRoute(schema: RouteSchema): boolean {\n const middleware = schema.middleware;\n const hasMiddleware =\n (middleware && Array.isArray(middleware) && middleware.length > 0) ||\n (middleware &&\n typeof middleware === 'object' &&\n ((middleware as MiddlewarePhases).before?.length ||\n (middleware as MiddlewarePhases).after?.length ||\n (middleware as MiddlewarePhases).transform?.length));\n\n return (\n !schema.auth && !schema.validation && !schema.rateLimit && !schema.cache && !hasMiddleware\n );\n }\n\n private buildExecutionOrder(schema: RouteSchema): string[] {\n const order: string[] = [];\n const middleware = schema.middleware;\n\n // Phase-based middleware\n if (middleware && 'before' in middleware && middleware.before?.length) {\n order.push('before');\n }\n\n if (schema.rateLimit) order.push('rateLimit');\n if (schema.auth) order.push('auth');\n if (schema.validation) order.push('validation');\n\n if (middleware && 'transform' in middleware && middleware.transform?.length) {\n order.push('transform');\n }\n\n if (schema.cache) order.push('cache');\n\n if (middleware && 'after' in middleware && middleware.after?.length) {\n order.push('after');\n }\n\n // Array-style middleware (backward compatibility)\n if (middleware && Array.isArray(middleware) && middleware.length > 0) {\n order.push('middleware');\n }\n\n return order;\n }\n\n // ===== Inspection Methods =====\n\n getAllRoutes(): RouteSchema[] {\n return this.allRoutes.map(r => r.schema);\n }\n\n /**\n * Fast-path routes (no middleware/auth/validation/rateLimit/cache) in a shape\n * suitable for registering directly on a native server router (e.g. uWS).\n */\n getNativeFastPathRoutes(): Array<{\n method: string;\n path: string;\n paramNames: string[] | null;\n handler: (req: HttpRequest, res: HttpResponse) => any;\n }> {\n const result: Array<{\n method: string;\n path: string;\n paramNames: string[] | null;\n handler: (req: HttpRequest, res: HttpResponse) => any;\n }> = [];\n for (const route of this.allRoutes) {\n if (!route.isFastPath) continue;\n const path = route.schema.path;\n let paramNames: string[] | null = null;\n if (path.indexOf(':') !== -1) {\n paramNames = [];\n for (const seg of path.split('/')) {\n if (seg.charCodeAt(0) === 58) paramNames.push(seg.slice(1));\n }\n }\n result.push({\n method: route.schema.method,\n path,\n paramNames,\n handler: route.schema.handler,\n });\n }\n return result;\n }\n\n /**\n * Public wrapper around the registered error handler so native fast paths\n * share the exact same error semantics as router-dispatched routes.\n * Returns true if the handler produced a response.\n */\n handleRouteError(err: any, req: HttpRequest, res: HttpResponse): Promise<boolean> {\n return this.invokeErrorHandler(err, req, res);\n }\n\n getRouteCount(): number {\n return this.stats.totalRoutes;\n }\n\n getStats() {\n // Manually build object instead of spread operator\n return {\n totalRoutes: this.stats.totalRoutes,\n staticRoutes: this.stats.staticRoutes,\n dynamicRoutes: this.stats.dynamicRoutes,\n fastPathRoutes: this.stats.fastPathRoutes,\n requestCount: this.stats.requestCount,\n fastPathHits: this.stats.fastPathHits,\n staticHits: this.stats.staticHits,\n dynamicHits: this.stats.dynamicHits,\n cacheHits: this.stats.cacheHits,\n radixHits: this.stats.radixHits,\n poolManager: this.poolManager.getPerformanceSummary(),\n pathMatcher: PathMatcher.getStats(),\n };\n }\n\n logPerformanceStats(): void {\n const stats = this.getStats();\n logger.info('UnifiedRouter Performance', 'Stats', {\n totalRoutes: stats.totalRoutes,\n staticRoutes: stats.staticRoutes,\n dynamicRoutes: stats.dynamicRoutes,\n fastPathRoutes: stats.fastPathRoutes,\n requests: stats.requestCount,\n poolManager: {\n routeCacheHitRate: stats.poolManager.routeCacheHitRate.toFixed(1) + '%',\n responseCacheHitRate: stats.poolManager.responseCacheHitRate.toFixed(1) + '%',\n paramPoolUtilization: stats.poolManager.paramPoolUtilization.toFixed(1) + '%',\n totalMemoryKB: stats.poolManager.totalMemoryKB.toFixed(1) + ' KB',\n },\n });\n }\n}\n"]}
1
+ {"version":3,"file":"unified-router.js","sourceRoot":"","sources":["../../../src/core/routing/unified-router.ts"],"names":[],"mappings":"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","sourcesContent":["// Unified Router - Consolidates Intelligent Router and Core Router\n// Combines best features from both systems with zero breaking changes\n\nimport { PathMatcher, CompiledPath } from './path-matcher.js';\nimport { ObjectPoolManager } from '../pooling/object-pool-manager.js';\nimport { createFrameworkLogger } from '../logger/index.js';\nimport { HttpRequest, HttpResponse } from '../../types/http.js';\nimport { RateLimitCore, type RateLimitConfig } from '../middleware/built-in/rate-limit/index.js';\nimport { CacheCore, type CacheConfig } from '../middleware/built-in/cache/index.js';\nimport { ValidationCore, type ValidationConfig } from '../middleware/built-in/validation/index.js';\nimport { requireAuth } from '../middleware/built-in/auth/helpers.js';\nimport { ValidationSchema } from '../validation/schema-interface.js';\nimport { MethodRadixRouter } from './radix-tree.js';\n\nconst logger = createFrameworkLogger('UnifiedRouter');\n\n// Shared Core instances for route-based features\nconst rateLimitCore = new RateLimitCore();\nconst cacheCore = new CacheCore();\nconst validationCore = new ValidationCore();\n\n// ===== Types =====\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';\nexport type RouteHandler<T = any> = (req: HttpRequest, res: HttpResponse) => T | Promise<T>;\nexport type Middleware = (\n req: HttpRequest,\n res: HttpResponse,\n next: () => void\n) => void | Promise<void>;\n\nexport interface AuthConfig {\n roles?: string[];\n permissions?: string[];\n optional?: boolean;\n}\n\n// Re-export config types from built-in middleware for convenience\nexport type { RateLimitConfig, CacheConfig, ValidationConfig };\n\nexport interface MiddlewarePhases {\n before?: Middleware[];\n after?: Middleware[];\n transform?: Middleware[];\n}\n\nexport interface RouteSchema {\n method: HttpMethod;\n path: string;\n handler: RouteHandler;\n validation?: ValidationConfig;\n auth?: AuthConfig;\n rateLimit?: RateLimitConfig;\n cache?: CacheConfig;\n middleware?: MiddlewarePhases | Middleware[];\n description?: string;\n tags?: string[];\n}\n\n// Internal route representation\ninterface InternalRoute {\n schema: RouteSchema;\n compiledPath: CompiledPath;\n isFastPath: boolean; // No middleware, auth, validation, rate limiting\n executionOrder: string[]; // Ordered list of execution phases\n // Route-specific configs (not middleware)\n rateLimitConfig?: RateLimitConfig;\n cacheConfig?: CacheConfig;\n authMiddleware?: Middleware; // Auth keeps middleware since it's using requireAuth helper\n validationConfig?: ValidationConfig;\n}\n\n// ===== Route Builder (Chainable API) =====\n\nexport class RouteBuilder {\n private schema: Partial<RouteSchema>;\n private router: UnifiedRouter;\n\n constructor(method: HttpMethod, path: string, router: UnifiedRouter) {\n this.schema = {\n method,\n path,\n middleware: {} as MiddlewarePhases,\n };\n this.router = router;\n }\n\n // Validation methods\n validate(config: ValidationConfig): this {\n // Avoid spread operator and Object.assign - manually merge properties\n if (!this.schema.validation) {\n this.schema.validation = config;\n } else {\n if (config.body !== undefined) this.schema.validation.body = config.body;\n if (config.query !== undefined) this.schema.validation.query = config.query;\n if (config.params !== undefined) this.schema.validation.params = config.params;\n if (config.headers !== undefined) this.schema.validation.headers = config.headers;\n // Without this, `.body(schema).validate({ onValidationError })` silently\n // dropped the handler and fell back to the default 400 response.\n if (config.onValidationError !== undefined) {\n this.schema.validation.onValidationError = config.onValidationError;\n }\n }\n return this;\n }\n\n body<T>(schema: ValidationSchema<T>): this {\n if (!this.schema.validation) this.schema.validation = {};\n this.schema.validation.body = schema;\n return this;\n }\n\n query<T>(schema: ValidationSchema<T>): this {\n if (!this.schema.validation) this.schema.validation = {};\n this.schema.validation.query = schema;\n return this;\n }\n\n params<T>(schema: ValidationSchema<T>): this {\n if (!this.schema.validation) this.schema.validation = {};\n this.schema.validation.params = schema;\n return this;\n }\n\n headers<T>(schema: ValidationSchema<T>): this {\n if (!this.schema.validation) this.schema.validation = {};\n this.schema.validation.headers = schema;\n return this;\n }\n\n // Security methods\n auth(config: AuthConfig): this {\n this.schema.auth = config;\n return this;\n }\n\n rateLimit(config: RateLimitConfig): this {\n this.schema.rateLimit = config;\n return this;\n }\n\n // Caching\n cache(config: CacheConfig): this {\n this.schema.cache = config;\n return this;\n }\n\n // Custom middleware\n before(...middleware: Middleware[]): this {\n if (!this.schema.middleware) this.schema.middleware = {};\n const phases = this.schema.middleware as MiddlewarePhases;\n // Avoid spread, use push for better performance\n if (!phases.before) phases.before = [];\n for (let i = 0; i < middleware.length; i++) {\n phases.before.push(middleware[i] as Middleware);\n }\n return this;\n }\n\n after(...middleware: Middleware[]): this {\n if (!this.schema.middleware) this.schema.middleware = {};\n const phases = this.schema.middleware as MiddlewarePhases;\n // Avoid spread, use push for better performance\n if (!phases.after) phases.after = [];\n for (let i = 0; i < middleware.length; i++) {\n phases.after.push(middleware[i] as Middleware);\n }\n return this;\n }\n\n transform(...middleware: Middleware[]): this {\n if (!this.schema.middleware) this.schema.middleware = {};\n const phases = this.schema.middleware as MiddlewarePhases;\n // Avoid spread, use push for better performance\n if (!phases.transform) phases.transform = [];\n for (let i = 0; i < middleware.length; i++) {\n phases.transform.push(middleware[i] as Middleware);\n }\n return this;\n }\n\n use(...middleware: Middleware[]): this {\n return this.after(...middleware);\n }\n\n // Metadata\n describe(description: string): this {\n this.schema.description = description;\n return this;\n }\n\n tag(...tags: string[]): this {\n // Avoid spread, use push for better performance\n if (!this.schema.tags) this.schema.tags = [];\n for (let i = 0; i < tags.length; i++) {\n this.schema.tags.push(tags[i] as string);\n }\n return this;\n }\n\n // Terminal method\n handler<T>(handler: RouteHandler<T>): void {\n if (!handler) {\n throw new Error('Handler is required');\n }\n\n // Avoid spread operator - add handler directly\n this.schema.handler = handler;\n this.router.registerRoute(this.schema as RouteSchema);\n }\n}\n\n// ===== Unified Router =====\n\nexport class UnifiedRouter {\n private static instance: UnifiedRouter | null = null;\n\n private readonly poolManager = ObjectPoolManager.getInstance();\n\n // Route storage optimized for different access patterns\n // OPTIMIZATION: Separate maps per method for faster lookup (no string concat needed)\n private staticRoutesByMethod = {\n GET: new Map<string, InternalRoute>(),\n POST: new Map<string, InternalRoute>(),\n PUT: new Map<string, InternalRoute>(),\n DELETE: new Map<string, InternalRoute>(),\n PATCH: new Map<string, InternalRoute>(),\n HEAD: new Map<string, InternalRoute>(),\n OPTIONS: new Map<string, InternalRoute>(),\n };\n private dynamicRoutesBySegments = new Map<number, InternalRoute[]>(); // Grouped by segment count\n private fastPathRoutes = new Set<InternalRoute>(); // Routes with no middleware\n private allRoutes: InternalRoute[] = []; // For iteration/inspection\n\n // NEW: Radix tree for fast dynamic route matching\n private radixRouter = new MethodRadixRouter();\n\n // Statistics\n private stats = {\n totalRoutes: 0,\n staticRoutes: 0,\n dynamicRoutes: 0,\n fastPathRoutes: 0,\n requestCount: 0,\n fastPathHits: 0,\n staticHits: 0,\n dynamicHits: 0,\n cacheHits: 0,\n radixHits: 0,\n };\n\n constructor() {\n logger.debug('UnifiedRouter initialized', 'Initialization');\n }\n\n // User-registered global error handler (set via Moro.setErrorHandler)\n private errorHandler?: (err: any, req: HttpRequest, res: HttpResponse) => any | Promise<any>;\n\n // Lifecycle hook manager (set via Moro) so 'error' hooks observe handler\n // errors — the router swallows them here, so the server-level error\n // boundary never sees them.\n private hookManager?: any;\n\n setErrorHandler(fn: (err: any, req: HttpRequest, res: HttpResponse) => any | Promise<any>): void {\n this.errorHandler = fn;\n }\n\n setHookManager(hookManager: any): void {\n this.hookManager = hookManager;\n }\n\n // Invoke the registered error handler (if any). Returns true if it produced a response.\n private async invokeErrorHandler(\n err: any,\n req: HttpRequest,\n res: HttpResponse\n ): Promise<boolean> {\n // Error hooks are observational: fire-and-forget so a slow or throwing\n // observer can never delay or alter the error response.\n if (\n this.hookManager &&\n (this.hookManager.hasHooks === undefined || this.hookManager.hasHooks('error'))\n ) {\n void Promise.resolve(\n this.hookManager.execute('error', { request: req, response: res, error: err })\n ).catch((hookError: any) =>\n logger.error('Error hook error', 'Hooks', {\n error: hookError instanceof Error ? hookError.message : String(hookError),\n })\n );\n }\n\n if (!this.errorHandler || res.headersSent) return false;\n try {\n const result = this.errorHandler(err, req, res);\n if (result && typeof (result as any).then === 'function') {\n await result;\n }\n return res.headersSent;\n } catch (handlerErr) {\n logger.error('Error handler itself threw', 'Execution', {\n error: handlerErr instanceof Error ? handlerErr.message : String(handlerErr),\n });\n return false;\n }\n }\n\n /**\n * Get singleton instance (optional - can still create new instances)\n */\n static getInstance(): UnifiedRouter {\n if (!this.instance) {\n this.instance = new UnifiedRouter();\n logger.info(`UnifiedRouter initialized (PID: ${process.pid})`, 'Router');\n }\n return this.instance;\n }\n\n /**\n * Reset singleton (useful for testing)\n */\n static reset(): void {\n if (this.instance) {\n this.instance.clearAllRoutes();\n }\n this.instance = null;\n }\n\n /**\n * Clear all routes (useful for testing)\n */\n clearAllRoutes(): void {\n this.staticRoutesByMethod.GET.clear();\n this.staticRoutesByMethod.POST.clear();\n this.staticRoutesByMethod.PUT.clear();\n this.staticRoutesByMethod.DELETE.clear();\n this.staticRoutesByMethod.PATCH.clear();\n this.staticRoutesByMethod.HEAD.clear();\n this.staticRoutesByMethod.OPTIONS.clear();\n this.dynamicRoutesBySegments.clear();\n this.fastPathRoutes.clear();\n this.allRoutes = [];\n this.radixRouter.clear();\n this.stats = {\n totalRoutes: 0,\n staticRoutes: 0,\n dynamicRoutes: 0,\n fastPathRoutes: 0,\n requestCount: 0,\n fastPathHits: 0,\n staticHits: 0,\n dynamicHits: 0,\n cacheHits: 0,\n radixHits: 0,\n };\n logger.debug('UnifiedRouter routes cleared', 'Reset');\n }\n\n // ===== Route Registration =====\n\n /**\n * Register a route (internal method) - OPTIMIZED\n */\n registerRoute(schema: RouteSchema): void {\n // OPTIMIZATION: Skip PathMatcher.compile for better performance\n // Determine if static route (optimized check)\n const pathLen = schema.path.length;\n let hasParams = false;\n for (let i = 0; i < pathLen; i++) {\n if (schema.path.charCodeAt(i) === 58) {\n // ':' character\n hasParams = true;\n break;\n }\n }\n\n const isStatic = !hasParams;\n const isFastPath = this.isFastPathRoute(schema);\n\n // OPTIMIZATION: Lazy execution order building (only when needed)\n const executionOrder = isFastPath ? [] : this.buildExecutionOrder(schema);\n\n // OPTIMIZATION: Lazy auth middleware creation (only create when needed, not during registration)\n // This speeds up route registration significantly\n const route: InternalRoute = {\n schema,\n compiledPath: null as any, // Will be set lazily if needed\n isFastPath,\n executionOrder,\n rateLimitConfig: schema.rateLimit,\n cacheConfig: schema.cache,\n authMiddleware: undefined, // Will be created lazily on first request\n validationConfig: schema.validation,\n } as any;\n\n // Store in appropriate structures\n if (isStatic) {\n const methodMap = this.staticRoutesByMethod[schema.method as HttpMethod];\n if (methodMap) {\n methodMap.set(schema.path, route);\n }\n this.stats.staticRoutes++;\n\n // DON'T add static routes to radix tree - Map is faster\n } else {\n // Add ONLY dynamic routes to radix tree (primary lookup for dynamic routes)\n this.radixRouter.addRoute(schema.method, schema.path, route);\n\n // Keep segment-based grouping for backward compatibility\n const segments = this.countSegmentsFast(schema.path);\n let routes = this.dynamicRoutesBySegments.get(segments);\n if (!routes) {\n routes = [];\n this.dynamicRoutesBySegments.set(segments, routes);\n }\n routes.push(route);\n this.stats.dynamicRoutes++;\n }\n\n if (isFastPath) {\n this.fastPathRoutes.add(route);\n this.stats.fastPathRoutes++;\n }\n\n this.allRoutes.push(route);\n this.stats.totalRoutes++;\n\n // OPTIMIZATION: Skip logging in production for performance\n // Most routes are registered once at startup, so this isn't a hot path\n // But reducing allocations still helps\n }\n\n /**\n * Fast segment counting without allocations\n */\n private countSegmentsFast(path: string): number {\n let count = 0;\n let inSegment = false;\n const len = path.length;\n\n for (let i = 0; i < len; i++) {\n const char = path.charCodeAt(i);\n if (char === 47) {\n // '/' character\n inSegment = false;\n } else if (!inSegment) {\n inSegment = true;\n count++;\n }\n }\n\n return count;\n }\n\n /**\n * Compile specialized param extractor for common cases\n */\n private compileParamExtractor(\n compiledPath: CompiledPath\n ): (matches: RegExpMatchArray) => Record<string, string> {\n const paramNames = compiledPath.paramNames;\n const paramCount = paramNames.length;\n\n // Specialized extractors for common cases\n if (paramCount === 0) {\n return () => ({}); // No allocation needed\n } else if (paramCount === 1) {\n const name = paramNames[0] as string;\n return matches => ({ [name]: matches[1] as string });\n } else if (paramCount === 2) {\n const name1 = paramNames[0] as string;\n const name2 = paramNames[1] as string;\n return matches => ({ [name1]: matches[1] as string, [name2]: matches[2] as string });\n } else if (paramCount === 3) {\n const name1 = paramNames[0] as string;\n const name2 = paramNames[1] as string;\n const name3 = paramNames[2] as string;\n return matches => ({\n [name1]: matches[1] as string,\n [name2]: matches[2] as string,\n [name3]: matches[3] as string,\n });\n } else {\n // Generic path for 4+ params\n return matches => {\n const params: Record<string, string> = {};\n for (let i = 0; i < paramCount; i++) {\n params[paramNames[i] as string] = matches[i + 1] as string;\n }\n return params;\n };\n }\n }\n\n /**\n * Chainable API methods\n */\n get(path: string): RouteBuilder {\n return new RouteBuilder('GET', path, this);\n }\n\n post(path: string): RouteBuilder {\n return new RouteBuilder('POST', path, this);\n }\n\n put(path: string): RouteBuilder {\n return new RouteBuilder('PUT', path, this);\n }\n\n delete(path: string): RouteBuilder {\n return new RouteBuilder('DELETE', path, this);\n }\n\n patch(path: string): RouteBuilder {\n return new RouteBuilder('PATCH', path, this);\n }\n\n head(path: string): RouteBuilder {\n return new RouteBuilder('HEAD', path, this);\n }\n\n options(path: string): RouteBuilder {\n return new RouteBuilder('OPTIONS', path, this);\n }\n\n /**\n * Schema-first route registration\n */\n route(schema: RouteSchema): void {\n this.registerRoute(schema);\n }\n\n /**\n * Direct API (for backward compatibility)\n */\n addRoute(\n method: HttpMethod,\n path: string,\n handler: RouteHandler,\n middleware: Middleware[] = []\n ): void {\n this.registerRoute({\n method,\n path,\n handler,\n middleware,\n });\n }\n\n // ===== Route Matching =====\n\n /**\n * Find a matching route for the request - HYBRID OPTIMIZED\n * Returns boolean (sync) for fast-path routes, Promise<boolean> for others\n */\n handleRequest(req: HttpRequest, res: HttpResponse): Promise<boolean> | boolean {\n this.stats.requestCount++;\n\n const method = req.method?.toUpperCase() as HttpMethod;\n const path = req.path;\n\n // FAST PATH 1: Try static route Map lookup first (fastest possible - no string concat)\n const methodMap = this.staticRoutesByMethod[method];\n if (methodMap) {\n const staticRoute = methodMap.get(path);\n\n if (staticRoute) {\n // OPTIMIZATION: Reuse empty params object to avoid allocation\n if (!req.params) {\n req.params = {};\n }\n\n // Fast-path execution (no middleware)\n if (staticRoute.isFastPath) {\n try {\n const result = staticRoute.schema.handler(req, res);\n\n if (result && typeof (result as any).then === 'function') {\n return (result as Promise<any>)\n .then(actualResult => {\n if (actualResult !== undefined && !res.headersSent) {\n res.json(actualResult);\n }\n return true;\n })\n .catch(async err => {\n const handled = await this.invokeErrorHandler(err, req, res);\n if (!handled && !res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n return true;\n });\n } else {\n if (result !== undefined && !res.headersSent) {\n res.json(result);\n }\n return true;\n }\n } catch (err) {\n return (async () => {\n const handled = await this.invokeErrorHandler(err, req, res);\n if (!handled && !res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n return true;\n })();\n }\n }\n\n // Non-fast-path static route\n return (async () => {\n await this.executeRoute(staticRoute, req, res, { params: {} });\n return true;\n })();\n }\n }\n\n // FAST PATH 2: Try radix tree for dynamic routes\n const radixResult = this.radixRouter.findRoute(method, path);\n if (radixResult) {\n const route = radixResult.handler as InternalRoute;\n req.params = radixResult.params;\n\n // Fast-path dynamic routes (no middleware)\n if (route.isFastPath) {\n try {\n const result = route.schema.handler(req, res);\n\n if (result && typeof (result as any).then === 'function') {\n return (result as Promise<any>)\n .then(actualResult => {\n if (actualResult !== undefined && !res.headersSent) {\n res.json(actualResult);\n }\n return true;\n })\n .catch(async err => {\n const handled = await this.invokeErrorHandler(err, req, res);\n if (!handled && !res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n return true;\n });\n } else {\n if (result !== undefined && !res.headersSent) {\n res.json(result);\n }\n return true;\n }\n } catch (err) {\n return (async () => {\n const handled = await this.invokeErrorHandler(err, req, res);\n if (!handled && !res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n return true;\n })();\n }\n }\n\n // Non-fast-path dynamic routes (with middleware)\n return (async () => {\n await this.executeRoute(route, req, res, { params: radixResult.params });\n return true;\n })();\n }\n\n // No route found\n return false;\n }\n\n // ===== Route Execution =====\n\n private async executeRoute(\n route: InternalRoute,\n req: HttpRequest,\n res: HttpResponse,\n matchResult: { params: Record<string, string> }\n ): Promise<void> {\n // The matcher already built a fresh params object - use it directly.\n // (No pooling: handlers may retain req past the response, so recycling\n // the object would alias params across requests.)\n req.params = matchResult.params;\n\n try {\n // Performance: Skip empty executionOrder array iteration\n // Most routes have empty or very short executionOrder\n if (route.executionOrder.length > 0) {\n // Execute middleware phases in order\n for (const phase of route.executionOrder) {\n if (res.headersSent) break;\n await this.executePhase(phase, route, req, res);\n }\n }\n\n // Execute handler\n if (!res.headersSent) {\n const result = await route.schema.handler(req, res);\n if (result !== undefined && !res.headersSent) {\n await res.json(result);\n }\n } else {\n // Headers already sent by middleware (e.g., cache hit, validation error, rate limit, auth)\n // This is expected behavior, not an error\n logger.debug('Handler skipped - response already sent by middleware', 'Execution');\n }\n } catch (error) {\n logger.error('Route execution error', 'Execution', {\n error: error instanceof Error ? error.message : String(error),\n route: `${route.schema.method} ${route.schema.path}`,\n });\n\n const handled = await this.invokeErrorHandler(error, req, res);\n if (!handled && !res.headersSent) {\n res.status(500).json({\n success: false,\n error: 'Internal server error',\n requestId: req.requestId,\n });\n }\n }\n }\n\n private async executePhase(\n phase: string,\n route: InternalRoute,\n req: HttpRequest,\n res: HttpResponse\n ): Promise<void> {\n const schema = route.schema;\n const middleware = schema.middleware;\n\n switch (phase) {\n case 'before': {\n // Performance: Early exit if no middleware present (fast path)\n if (!middleware || !('before' in middleware)) break;\n const beforeMw = (middleware as MiddlewarePhases).before;\n if (!beforeMw || beforeMw.length === 0) break;\n\n const beforeLen = beforeMw.length;\n for (let i = 0; i < beforeLen; i++) {\n await this.executeMiddleware(beforeMw[i] as Middleware, req, res);\n if (res.headersSent) return;\n }\n break;\n }\n\n case 'rateLimit':\n // Use Core directly for route-based rate limiting\n if (route.rateLimitConfig) {\n await rateLimitCore.checkLimit(req, res, route.rateLimitConfig);\n }\n break;\n\n case 'auth':\n // Auth uses middleware (from requireAuth helper) - created lazily\n if (schema.auth) {\n if (!route.authMiddleware) {\n route.authMiddleware = requireAuth({\n ...(schema.auth.roles !== undefined && { roles: schema.auth.roles }),\n ...(schema.auth.permissions !== undefined && {\n permissions: schema.auth.permissions,\n }),\n ...(schema.auth.optional !== undefined && {\n allowUnauthenticated: schema.auth.optional,\n }),\n });\n }\n await this.executeMiddleware(route.authMiddleware, req, res);\n }\n break;\n\n case 'validation':\n // Use Core directly for route-based validation\n if (route.validationConfig) {\n const isValid = await validationCore.validate(req, res, route.validationConfig);\n if (!isValid) {\n return; // Validation failed, response already sent\n }\n }\n break;\n\n case 'transform': {\n // Performance: Early exit if no middleware present (fast path)\n if (!middleware || !('transform' in middleware)) break;\n const transformMw = (middleware as MiddlewarePhases).transform;\n if (!transformMw || transformMw.length === 0) break;\n\n const transformLen = transformMw.length;\n for (let i = 0; i < transformLen; i++) {\n await this.executeMiddleware(transformMw[i] as Middleware, req, res);\n if (res.headersSent) return;\n }\n break;\n }\n\n case 'cache':\n // Use Core directly for route-based caching\n if (route.cacheConfig) {\n const cached = await cacheCore.tryGet(req, res, route.cacheConfig);\n if (cached) {\n return; // Cache hit, response already sent\n }\n }\n break;\n\n case 'after': {\n // Performance: Early exit if no middleware present (fast path)\n if (!middleware || !('after' in middleware)) break;\n const afterMw = (middleware as MiddlewarePhases).after;\n if (!afterMw || afterMw.length === 0) break;\n\n const afterLen = afterMw.length;\n for (let i = 0; i < afterLen; i++) {\n await this.executeMiddleware(afterMw[i] as Middleware, req, res);\n if (res.headersSent) return;\n }\n break;\n }\n\n case 'middleware': {\n // Handle array-style middleware (backward compatibility)\n // Performance: Early exit if no middleware present (fast path)\n if (!middleware || !Array.isArray(middleware) || middleware.length === 0) break;\n\n const middlewareLen = middleware.length;\n for (let i = 0; i < middlewareLen; i++) {\n await this.executeMiddleware(middleware[i] as Middleware, req, res);\n if (res.headersSent) return;\n }\n break;\n }\n }\n }\n\n private async executeMiddleware(\n middleware: Middleware,\n req: HttpRequest,\n res: HttpResponse\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n let resolved = false;\n\n const next = () => {\n if (!resolved) {\n resolved = true;\n resolve();\n }\n };\n\n try {\n const result = middleware(req, res, next);\n // Duck typing faster than instanceof\n if (result && typeof result.then === 'function') {\n result.then(() => !resolved && next()).catch(reject);\n } else if (!resolved) {\n next();\n }\n } catch (error) {\n if (!resolved) {\n resolved = true;\n reject(error);\n }\n }\n });\n }\n\n // ===== Helper Methods =====\n\n private isFastPathRoute(schema: RouteSchema): boolean {\n const middleware = schema.middleware;\n const hasMiddleware =\n (middleware && Array.isArray(middleware) && middleware.length > 0) ||\n (middleware &&\n typeof middleware === 'object' &&\n ((middleware as MiddlewarePhases).before?.length ||\n (middleware as MiddlewarePhases).after?.length ||\n (middleware as MiddlewarePhases).transform?.length));\n\n return (\n !schema.auth && !schema.validation && !schema.rateLimit && !schema.cache && !hasMiddleware\n );\n }\n\n private buildExecutionOrder(schema: RouteSchema): string[] {\n const order: string[] = [];\n const middleware = schema.middleware;\n\n // Phase-based middleware\n if (middleware && 'before' in middleware && middleware.before?.length) {\n order.push('before');\n }\n\n if (schema.rateLimit) order.push('rateLimit');\n if (schema.auth) order.push('auth');\n if (schema.validation) order.push('validation');\n\n if (middleware && 'transform' in middleware && middleware.transform?.length) {\n order.push('transform');\n }\n\n if (schema.cache) order.push('cache');\n\n if (middleware && 'after' in middleware && middleware.after?.length) {\n order.push('after');\n }\n\n // Array-style middleware (backward compatibility)\n if (middleware && Array.isArray(middleware) && middleware.length > 0) {\n order.push('middleware');\n }\n\n return order;\n }\n\n // ===== Inspection Methods =====\n\n getAllRoutes(): RouteSchema[] {\n return this.allRoutes.map(r => r.schema);\n }\n\n /**\n * Fast-path routes (no middleware/auth/validation/rateLimit/cache) in a shape\n * suitable for registering directly on a native server router (e.g. uWS).\n */\n getNativeFastPathRoutes(): Array<{\n method: string;\n path: string;\n paramNames: string[] | null;\n handler: (req: HttpRequest, res: HttpResponse) => any;\n }> {\n const result: Array<{\n method: string;\n path: string;\n paramNames: string[] | null;\n handler: (req: HttpRequest, res: HttpResponse) => any;\n }> = [];\n for (const route of this.allRoutes) {\n if (!route.isFastPath) continue;\n const path = route.schema.path;\n let paramNames: string[] | null = null;\n if (path.indexOf(':') !== -1) {\n paramNames = [];\n for (const seg of path.split('/')) {\n if (seg.charCodeAt(0) === 58) paramNames.push(seg.slice(1));\n }\n }\n result.push({\n method: route.schema.method,\n path,\n paramNames,\n handler: route.schema.handler,\n });\n }\n return result;\n }\n\n /**\n * Public wrapper around the registered error handler so native fast paths\n * share the exact same error semantics as router-dispatched routes.\n * Returns true if the handler produced a response.\n */\n handleRouteError(err: any, req: HttpRequest, res: HttpResponse): Promise<boolean> {\n return this.invokeErrorHandler(err, req, res);\n }\n\n getRouteCount(): number {\n return this.stats.totalRoutes;\n }\n\n getStats() {\n // Manually build object instead of spread operator\n return {\n totalRoutes: this.stats.totalRoutes,\n staticRoutes: this.stats.staticRoutes,\n dynamicRoutes: this.stats.dynamicRoutes,\n fastPathRoutes: this.stats.fastPathRoutes,\n requestCount: this.stats.requestCount,\n fastPathHits: this.stats.fastPathHits,\n staticHits: this.stats.staticHits,\n dynamicHits: this.stats.dynamicHits,\n cacheHits: this.stats.cacheHits,\n radixHits: this.stats.radixHits,\n poolManager: this.poolManager.getPerformanceSummary(),\n pathMatcher: PathMatcher.getStats(),\n };\n }\n\n logPerformanceStats(): void {\n const stats = this.getStats();\n logger.info('UnifiedRouter Performance', 'Stats', {\n totalRoutes: stats.totalRoutes,\n staticRoutes: stats.staticRoutes,\n dynamicRoutes: stats.dynamicRoutes,\n fastPathRoutes: stats.fastPathRoutes,\n requests: stats.requestCount,\n poolManager: {\n routeCacheHitRate: stats.poolManager.routeCacheHitRate.toFixed(1) + '%',\n responseCacheHitRate: stats.poolManager.responseCacheHitRate.toFixed(1) + '%',\n paramPoolUtilization: stats.poolManager.paramPoolUtilization.toFixed(1) + '%',\n totalMemoryKB: stats.poolManager.totalMemoryKB.toFixed(1) + ' KB',\n },\n });\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morojs/moro",
3
- "version": "1.8.5",
3
+ "version": "1.8.6",
4
4
  "description": "High-performance Node.js framework with intelligent routing, automatic middleware ordering, enterprise authentication (Better Auth), type-safe validation, and functional architecture",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -34,6 +34,8 @@
34
34
  "test:force": "jest --forceExit",
35
35
  "test:all": "npm run test:unit && npm run test:integration && npm run test:e2e",
36
36
  "test:dist": "npm run build && node scripts/validate-dist.mjs",
37
+ "test:fuzz": "jest --testPathPatterns=fuzz --detectOpenHandles",
38
+ "test:fuzz:deep": "MORO_FUZZ_RUNS=200000 jest --testPathPatterns=fuzz --testTimeout=600000",
37
39
  "test:package": "npm run build && node scripts/validate-package.mjs",
38
40
  "lint": "eslint src --ext .ts --max-warnings 0",
39
41
  "lint:fix": "eslint src --ext .ts --fix",