@morojs/moro 1.8.10 → 1.8.12

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.
@@ -1,5 +1,7 @@
1
1
  import { ValidationSchema } from '../validation/schema-interface.js';
2
2
  import { HttpRequest, HttpResponse } from '../http/index.js';
3
+ import { type StaticBody, type StaticResponse } from './unified-router.js';
4
+ export type { StaticBody, StaticResponse };
3
5
  export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
4
6
  export type RouteHandler<T = any> = (req: HttpRequest, res: HttpResponse) => T | Promise<T>;
5
7
  export type Middleware = (req: HttpRequest, res: HttpResponse, next: () => void) => void | Promise<void>;
@@ -33,7 +35,8 @@ export interface MiddlewarePhases {
33
35
  export interface RouteSchema {
34
36
  method: HttpMethod;
35
37
  path: string;
36
- handler: RouteHandler;
38
+ /** A function, or the response body itself (see StaticBody / .handler()) */
39
+ handler: RouteHandler | StaticBody;
37
40
  validation?: ValidationConfig;
38
41
  auth?: AuthConfig;
39
42
  rateLimit?: RateLimitConfig;
@@ -41,6 +44,8 @@ export interface RouteSchema {
41
44
  middleware?: MiddlewarePhases;
42
45
  description?: string;
43
46
  tags?: string[];
47
+ /** Fixed reply of a literal handler; see StaticResponse */
48
+ static?: StaticResponse;
44
49
  }
45
50
  export declare const EXECUTION_PHASES: readonly ["security", "parsing", "rateLimit", "before", "auth", "validation", "transform", "cache", "after", "handler"];
46
51
  export type ExecutionPhase = (typeof EXECUTION_PHASES)[number];
@@ -66,7 +71,10 @@ export interface RouteBuilder {
66
71
  use(...middleware: Middleware[]): RouteBuilder;
67
72
  describe(description: string): RouteBuilder;
68
73
  tag(...tags: string[]): RouteBuilder;
69
- handler<T>(handler: RouteHandler<T>): void;
74
+ /** Terminal. A function handles the request; a string or Buffer IS the
75
+ * response body (as res.send would send it), and on a route with nothing
76
+ * else configured Moro's native engine answers it without calling JS. */
77
+ handler<T>(handler: RouteHandler<T> | StaticBody): void;
70
78
  }
71
79
  export interface CompiledRoute {
72
80
  schema: RouteSchema;
@@ -94,7 +102,7 @@ export declare class IntelligentRouteBuilder implements RouteBuilder {
94
102
  use(...middleware: Middleware[]): RouteBuilder;
95
103
  describe(description: string): RouteBuilder;
96
104
  tag(...tags: string[]): RouteBuilder;
97
- handler<T>(handler: RouteHandler<T>): void;
105
+ handler<T>(handler: RouteHandler<T> | StaticBody): void;
98
106
  }
99
107
  /**
100
108
  * Thin facade implementing CompiledRoute interface
@@ -3,7 +3,7 @@
3
3
  //
4
4
  // NOTE: This file exports types and thin facades to UnifiedRouter
5
5
  // All routing logic has been consolidated in unified-router.ts
6
- import { UnifiedRouter } from './unified-router.js';
6
+ import { UnifiedRouter, compileStaticRoute, } from './unified-router.js';
7
7
  export const EXECUTION_PHASES = [
8
8
  'security',
9
9
  'parsing',
@@ -137,13 +137,18 @@ export class IntelligentRouteBuilder {
137
137
  return this;
138
138
  }
139
139
  handler(handler) {
140
- if (!handler) {
141
- throw new Error('Handler is required');
140
+ if (typeof handler === 'function') {
141
+ // Avoid spread operator - add handler directly
142
+ this.schema.handler = handler;
143
+ // Delegate to UnifiedRouter
144
+ this.router.registerRoute(this.schema);
145
+ return;
142
146
  }
143
- // Avoid spread operator - add handler directly
144
- this.schema.handler = handler;
145
- // Delegate to UnifiedRouter
146
- this.router.registerRoute(this.schema);
147
+ if (typeof handler === 'string' || Buffer.isBuffer(handler)) {
148
+ this.router.registerRoute(compileStaticRoute(this.schema, handler));
149
+ return;
150
+ }
151
+ throw new Error('Handler is required: a function, or the response body as a string or Buffer');
147
152
  }
148
153
  }
149
154
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/routing/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Intelligent Routing System for Moro Framework\n// Schema-first with automatic middleware ordering and chainable API\n//\n// NOTE: This file exports types and thin facades to UnifiedRouter\n// All routing logic has been consolidated in unified-router.ts\n\nimport { ValidationSchema } from '../validation/schema-interface.js';\nimport { HttpRequest, HttpResponse } from '../http/index.js';\nimport { UnifiedRouter } from './unified-router.js';\n\n// ===== TYPE EXPORTS (Keep all - used by app code) =====\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 ValidationConfig {\n body?: ValidationSchema;\n query?: ValidationSchema;\n params?: ValidationSchema;\n headers?: ValidationSchema;\n}\n\nexport interface AuthConfig {\n roles?: string[];\n permissions?: string[];\n optional?: boolean;\n}\n\nexport interface RateLimitConfig {\n requests: number;\n window: number;\n skipSuccessfulRequests?: boolean;\n skipFailedRequests?: boolean;\n}\n\nexport interface CacheConfig {\n ttl: number;\n key?: string;\n tags?: string[];\n}\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;\n description?: string;\n tags?: string[];\n}\n\nexport const EXECUTION_PHASES = [\n 'security',\n 'parsing',\n 'rateLimit',\n 'before',\n 'auth',\n 'validation',\n 'transform',\n 'cache',\n 'after',\n 'handler',\n] as const;\n\nexport type ExecutionPhase = (typeof EXECUTION_PHASES)[number];\n\nexport interface ValidatedRequest<T = any> extends HttpRequest {\n validatedBody?: T;\n validatedQuery?: any;\n validatedParams?: any;\n validatedHeaders?: any;\n user?: any;\n}\n\n// ===== ROUTE BUILDER INTERFACE (Public API) =====\n\nexport interface RouteBuilder {\n validate(config: ValidationConfig): RouteBuilder;\n body<T>(schema: ValidationSchema<T>): RouteBuilder;\n query<T>(schema: ValidationSchema<T>): RouteBuilder;\n params<T>(schema: ValidationSchema<T>): RouteBuilder;\n headers<T>(schema: ValidationSchema<T>): RouteBuilder;\n auth(config: AuthConfig): RouteBuilder;\n rateLimit(config: RateLimitConfig): RouteBuilder;\n cache(config: CacheConfig): RouteBuilder;\n before(...middleware: Middleware[]): RouteBuilder;\n after(...middleware: Middleware[]): RouteBuilder;\n transform(...middleware: Middleware[]): RouteBuilder;\n use(...middleware: Middleware[]): RouteBuilder;\n describe(description: string): RouteBuilder;\n tag(...tags: string[]): RouteBuilder;\n handler<T>(handler: RouteHandler<T>): void;\n}\n\n// ===== COMPILED ROUTE INTERFACE (Public API) =====\n\nexport interface CompiledRoute {\n schema: RouteSchema;\n execute(req: HttpRequest, res: HttpResponse): Promise<void>;\n}\n\n// ===== FACADE IMPLEMENTATIONS (Delegate to UnifiedRouter) =====\n\n/**\n * Thin facade to UnifiedRouter.RouteBuilder\n * Maintains backward compatibility while using optimized implementation\n */\nexport class IntelligentRouteBuilder implements RouteBuilder {\n private schema: Partial<RouteSchema>;\n private router = UnifiedRouter.getInstance();\n\n constructor(method: HttpMethod, path: string) {\n this.schema = {\n method,\n path,\n middleware: {} as MiddlewarePhases,\n };\n }\n\n validate(config: ValidationConfig): RouteBuilder {\n // Avoid spread operator - 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>): RouteBuilder {\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>): RouteBuilder {\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>): RouteBuilder {\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>): RouteBuilder {\n if (!this.schema.validation) this.schema.validation = {};\n this.schema.validation.headers = schema;\n return this;\n }\n\n auth(config: AuthConfig): RouteBuilder {\n this.schema.auth = config;\n return this;\n }\n\n rateLimit(config: RateLimitConfig): RouteBuilder {\n this.schema.rateLimit = config;\n return this;\n }\n\n cache(config: CacheConfig): RouteBuilder {\n this.schema.cache = config;\n return this;\n }\n\n before(...middleware: Middleware[]): RouteBuilder {\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[]): RouteBuilder {\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[]): RouteBuilder {\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[]): RouteBuilder {\n return this.after(...middleware);\n }\n\n describe(description: string): RouteBuilder {\n this.schema.description = description;\n return this;\n }\n\n tag(...tags: string[]): RouteBuilder {\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 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\n // Delegate to UnifiedRouter\n this.router.registerRoute(this.schema as RouteSchema);\n }\n}\n\n/**\n * Thin facade implementing CompiledRoute interface\n * Just stores schema for documentation purposes\n */\nexport class ExecutableRoute implements CompiledRoute {\n constructor(public readonly schema: RouteSchema) {\n // Register with UnifiedRouter\n UnifiedRouter.getInstance().registerRoute(schema);\n }\n\n async execute(_req: HttpRequest, _res: HttpResponse): Promise<void> {\n // This is never called - UnifiedRouter handles execution\n // But we implement it for interface compatibility\n throw new Error(\n 'ExecutableRoute.execute() should not be called directly - routing handled by UnifiedRouter'\n );\n }\n}\n\n// ===== FACTORY FUNCTIONS (Backward Compatibility) =====\n\nexport function createRoute(method: HttpMethod, path: string): RouteBuilder {\n return new IntelligentRouteBuilder(method, path);\n}\n\nexport function defineRoute(schema: RouteSchema): CompiledRoute {\n return new ExecutableRoute(schema);\n}\n\n// ===== RE-EXPORTS FROM UNIFIED ROUTER =====\n\nexport { UnifiedRouter } from './unified-router.js';\nexport { RouteBuilder as UnifiedRouteBuilder } from './unified-router.js';\nexport { PathMatcher, type CompiledPath, type MatchResult } from './path-matcher.js';\nexport { ObjectPoolManager, getPoolManager } from '../pooling/object-pool-manager.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/routing/index.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,oEAAoE;AACpE,EAAE;AACF,kEAAkE;AAClE,+DAA+D;AAI/D,OAAO,EACL,aAAa,EACb,kBAAkB,GAInB,MAAM,qBAAqB,CAAC;AA8D7B,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,UAAU;IACV,SAAS;IACT,WAAW;IACX,QAAQ;IACR,MAAM;IACN,YAAY;IACZ,WAAW;IACX,OAAO;IACP,OAAO;IACP,SAAS;CACD,CAAC;AA0CX,iEAAiE;AAEjE;;;GAGG;AACH,MAAM,OAAO,uBAAuB;IAC1B,MAAM,CAAuB;IAC7B,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;IAE7C,YAAY,MAAkB,EAAE,IAAY;QAC1C,IAAI,CAAC,MAAM,GAAG;YACZ,MAAM;YACN,IAAI;YACJ,UAAU,EAAE,EAAsB;SACnC,CAAC;IACJ,CAAC;IAED,QAAQ,CAAC,MAAwB;QAC/B,oDAAoD;QACpD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;gBAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACzE,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;gBAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YAC5E,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;gBAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC/E,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;gBAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QACpF,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAI,MAA2B;QACjC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,GAAG,MAAM,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAI,MAA2B;QAClC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,MAAM,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAI,MAA2B;QACnC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAI,MAA2B;QACpC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,GAAG,MAAM,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,MAAkB;QACrB,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAC,MAAuB;QAC/B,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAmB;QACvB,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,GAAG,UAAwB;QAChC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAA8B,CAAC;QAC1D,gDAAgD;QAChD,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAe,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,GAAG,UAAwB;QAC/B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAA8B,CAAC;QAC1D,gDAAgD;QAChD,IAAI,CAAC,MAAM,CAAC,KAAK;YAAE,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC;QACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAe,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAC,GAAG,UAAwB;QACnC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAA8B,CAAC;QAC1D,gDAAgD;QAChD,IAAI,CAAC,MAAM,CAAC,SAAS;YAAE,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC;QAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAe,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,GAAG,CAAC,GAAG,UAAwB;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,CAAC;IACnC,CAAC;IAED,QAAQ,CAAC,WAAmB;QAC1B,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,GAAG,CAAC,GAAG,IAAc;QACnB,gDAAgD;QAChD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAW,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAI,OAAqC;QAC9C,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YAClC,+CAA+C;YAC/C,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;YAE9B,4BAA4B;YAC5B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAqB,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QACD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5D,IAAI,CAAC,MAAM,CAAC,aAAa,CACvB,kBAAkB,CAAC,IAAI,CAAC,MAAqC,EAAE,OAAO,CAAC,CACxE,CAAC;YACF,OAAO;QACT,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;IACjG,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,eAAe;IACE;IAA5B,YAA4B,MAAmB;QAAnB,WAAM,GAAN,MAAM,CAAa;QAC7C,8BAA8B;QAC9B,aAAa,CAAC,WAAW,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAiB,EAAE,IAAkB;QACjD,yDAAyD;QACzD,kDAAkD;QAClD,MAAM,IAAI,KAAK,CACb,4FAA4F,CAC7F,CAAC;IACJ,CAAC;CACF;AAED,yDAAyD;AAEzD,MAAM,UAAU,WAAW,CAAC,MAAkB,EAAE,IAAY;IAC1D,OAAO,IAAI,uBAAuB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAmB;IAC7C,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,6CAA6C;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAuC,MAAM,mBAAmB,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC","sourcesContent":["// Intelligent Routing System for Moro Framework\n// Schema-first with automatic middleware ordering and chainable API\n//\n// NOTE: This file exports types and thin facades to UnifiedRouter\n// All routing logic has been consolidated in unified-router.ts\n\nimport { ValidationSchema } from '../validation/schema-interface.js';\nimport { HttpRequest, HttpResponse } from '../http/index.js';\nimport {\n UnifiedRouter,\n compileStaticRoute,\n type RouteSchema as UnifiedRouteSchema,\n type StaticBody,\n type StaticResponse,\n} from './unified-router.js';\n\nexport type { StaticBody, StaticResponse };\n\n// ===== TYPE EXPORTS (Keep all - used by app code) =====\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 ValidationConfig {\n body?: ValidationSchema;\n query?: ValidationSchema;\n params?: ValidationSchema;\n headers?: ValidationSchema;\n}\n\nexport interface AuthConfig {\n roles?: string[];\n permissions?: string[];\n optional?: boolean;\n}\n\nexport interface RateLimitConfig {\n requests: number;\n window: number;\n skipSuccessfulRequests?: boolean;\n skipFailedRequests?: boolean;\n}\n\nexport interface CacheConfig {\n ttl: number;\n key?: string;\n tags?: string[];\n}\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 /** A function, or the response body itself (see StaticBody / .handler()) */\n handler: RouteHandler | StaticBody;\n validation?: ValidationConfig;\n auth?: AuthConfig;\n rateLimit?: RateLimitConfig;\n cache?: CacheConfig;\n middleware?: MiddlewarePhases;\n description?: string;\n tags?: string[];\n /** Fixed reply of a literal handler; see StaticResponse */\n static?: StaticResponse;\n}\n\nexport const EXECUTION_PHASES = [\n 'security',\n 'parsing',\n 'rateLimit',\n 'before',\n 'auth',\n 'validation',\n 'transform',\n 'cache',\n 'after',\n 'handler',\n] as const;\n\nexport type ExecutionPhase = (typeof EXECUTION_PHASES)[number];\n\nexport interface ValidatedRequest<T = any> extends HttpRequest {\n validatedBody?: T;\n validatedQuery?: any;\n validatedParams?: any;\n validatedHeaders?: any;\n user?: any;\n}\n\n// ===== ROUTE BUILDER INTERFACE (Public API) =====\n\nexport interface RouteBuilder {\n validate(config: ValidationConfig): RouteBuilder;\n body<T>(schema: ValidationSchema<T>): RouteBuilder;\n query<T>(schema: ValidationSchema<T>): RouteBuilder;\n params<T>(schema: ValidationSchema<T>): RouteBuilder;\n headers<T>(schema: ValidationSchema<T>): RouteBuilder;\n auth(config: AuthConfig): RouteBuilder;\n rateLimit(config: RateLimitConfig): RouteBuilder;\n cache(config: CacheConfig): RouteBuilder;\n before(...middleware: Middleware[]): RouteBuilder;\n after(...middleware: Middleware[]): RouteBuilder;\n transform(...middleware: Middleware[]): RouteBuilder;\n use(...middleware: Middleware[]): RouteBuilder;\n describe(description: string): RouteBuilder;\n tag(...tags: string[]): RouteBuilder;\n /** Terminal. A function handles the request; a string or Buffer IS the\n * response body (as res.send would send it), and on a route with nothing\n * else configured Moro's native engine answers it without calling JS. */\n handler<T>(handler: RouteHandler<T> | StaticBody): void;\n}\n\n// ===== COMPILED ROUTE INTERFACE (Public API) =====\n\nexport interface CompiledRoute {\n schema: RouteSchema;\n execute(req: HttpRequest, res: HttpResponse): Promise<void>;\n}\n\n// ===== FACADE IMPLEMENTATIONS (Delegate to UnifiedRouter) =====\n\n/**\n * Thin facade to UnifiedRouter.RouteBuilder\n * Maintains backward compatibility while using optimized implementation\n */\nexport class IntelligentRouteBuilder implements RouteBuilder {\n private schema: Partial<RouteSchema>;\n private router = UnifiedRouter.getInstance();\n\n constructor(method: HttpMethod, path: string) {\n this.schema = {\n method,\n path,\n middleware: {} as MiddlewarePhases,\n };\n }\n\n validate(config: ValidationConfig): RouteBuilder {\n // Avoid spread operator - 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>): RouteBuilder {\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>): RouteBuilder {\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>): RouteBuilder {\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>): RouteBuilder {\n if (!this.schema.validation) this.schema.validation = {};\n this.schema.validation.headers = schema;\n return this;\n }\n\n auth(config: AuthConfig): RouteBuilder {\n this.schema.auth = config;\n return this;\n }\n\n rateLimit(config: RateLimitConfig): RouteBuilder {\n this.schema.rateLimit = config;\n return this;\n }\n\n cache(config: CacheConfig): RouteBuilder {\n this.schema.cache = config;\n return this;\n }\n\n before(...middleware: Middleware[]): RouteBuilder {\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[]): RouteBuilder {\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[]): RouteBuilder {\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[]): RouteBuilder {\n return this.after(...middleware);\n }\n\n describe(description: string): RouteBuilder {\n this.schema.description = description;\n return this;\n }\n\n tag(...tags: string[]): RouteBuilder {\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 handler<T>(handler: RouteHandler<T> | StaticBody): void {\n if (typeof handler === 'function') {\n // Avoid spread operator - add handler directly\n this.schema.handler = handler;\n\n // Delegate to UnifiedRouter\n this.router.registerRoute(this.schema as RouteSchema);\n return;\n }\n if (typeof handler === 'string' || Buffer.isBuffer(handler)) {\n this.router.registerRoute(\n compileStaticRoute(this.schema as Partial<UnifiedRouteSchema>, handler)\n );\n return;\n }\n throw new Error('Handler is required: a function, or the response body as a string or Buffer');\n }\n}\n\n/**\n * Thin facade implementing CompiledRoute interface\n * Just stores schema for documentation purposes\n */\nexport class ExecutableRoute implements CompiledRoute {\n constructor(public readonly schema: RouteSchema) {\n // Register with UnifiedRouter\n UnifiedRouter.getInstance().registerRoute(schema);\n }\n\n async execute(_req: HttpRequest, _res: HttpResponse): Promise<void> {\n // This is never called - UnifiedRouter handles execution\n // But we implement it for interface compatibility\n throw new Error(\n 'ExecutableRoute.execute() should not be called directly - routing handled by UnifiedRouter'\n );\n }\n}\n\n// ===== FACTORY FUNCTIONS (Backward Compatibility) =====\n\nexport function createRoute(method: HttpMethod, path: string): RouteBuilder {\n return new IntelligentRouteBuilder(method, path);\n}\n\nexport function defineRoute(schema: RouteSchema): CompiledRoute {\n return new ExecutableRoute(schema);\n}\n\n// ===== RE-EXPORTS FROM UNIFIED ROUTER =====\n\nexport { UnifiedRouter } from './unified-router.js';\nexport { RouteBuilder as UnifiedRouteBuilder } from './unified-router.js';\nexport { PathMatcher, type CompiledPath, type MatchResult } from './path-matcher.js';\nexport { ObjectPoolManager, getPoolManager } from '../pooling/object-pool-manager.js';\n"]}
@@ -20,7 +20,8 @@ export interface MiddlewarePhases {
20
20
  export interface RouteSchema {
21
21
  method: HttpMethod;
22
22
  path: string;
23
- handler: RouteHandler;
23
+ /** A function, or the response body itself (see StaticBody) */
24
+ handler: RouteHandler | StaticBody;
24
25
  validation?: ValidationConfig;
25
26
  auth?: AuthConfig;
26
27
  rateLimit?: RateLimitConfig;
@@ -28,7 +29,31 @@ export interface RouteSchema {
28
29
  middleware?: MiddlewarePhases | Middleware[];
29
30
  description?: string;
30
31
  tags?: string[];
32
+ /** Fixed reply of a literal handler. A server that can answer it
33
+ * natively (MoroEngineServer on @morojs/engine >= 1.1.6) does so without
34
+ * calling into JS; every other server runs `handler`, which sends the
35
+ * same bytes. */
36
+ static?: StaticResponse;
31
37
  }
38
+ /** The reply a literal handler sends, in the engine's shape. */
39
+ export interface StaticResponse {
40
+ status: number;
41
+ /** [name, value, name, value, ...], or null for no headers at all */
42
+ headers: string[] | null;
43
+ body: string | Buffer | null;
44
+ }
45
+ /** What .handler() accepts in place of a function: the response body itself. */
46
+ export type StaticBody = string | Buffer;
47
+ /**
48
+ * A literal body in place of a handler: the route answers with exactly that
49
+ * body, as res.send(body) would (status 200, the implied content-type). When
50
+ * nothing else is configured on the route - no auth, validation, rate limit,
51
+ * cache or middleware, and a literal path - the schema also carries `static`,
52
+ * so a server that can answer it natively does so without calling into JS.
53
+ * Anything configured keeps the route on the normal pipeline, where the
54
+ * handler sends the same bytes after that configuration has run.
55
+ */
56
+ export declare function compileStaticRoute(schema: Partial<RouteSchema>, body: StaticBody): RouteSchema;
32
57
  export declare class RouteBuilder {
33
58
  private schema;
34
59
  private router;
@@ -47,7 +72,7 @@ export declare class RouteBuilder {
47
72
  use(...middleware: Middleware[]): this;
48
73
  describe(description: string): this;
49
74
  tag(...tags: string[]): this;
50
- handler<T>(handler: RouteHandler<T>): void;
75
+ handler<T>(handler: RouteHandler<T> | StaticBody): void;
51
76
  }
52
77
  export declare class UnifiedRouter {
53
78
  private static instance;
@@ -105,7 +130,7 @@ export declare class UnifiedRouter {
105
130
  /**
106
131
  * Direct API (for backward compatibility)
107
132
  */
108
- addRoute(method: HttpMethod, path: string, handler: RouteHandler, middleware?: Middleware[]): void;
133
+ addRoute(method: HttpMethod, path: string, handler: RouteHandler | StaticBody, middleware?: Middleware[]): void;
109
134
  /**
110
135
  * Find a matching route for the request - HYBRID OPTIMIZED
111
136
  * Returns boolean (sync) for fast-path routes, Promise<boolean> for others
@@ -13,6 +13,51 @@ const logger = createFrameworkLogger('UnifiedRouter');
13
13
  const rateLimitCore = new RateLimitCore();
14
14
  const cacheCore = new CacheCore();
15
15
  const validationCore = new ValidationCore();
16
+ // The content-type res.send() implies for a body it was given no header for:
17
+ // the same three cases MoroEngineServer's send() picks a template by, spelled
18
+ // out here so an engine-answered reply carries the bytes send() would have.
19
+ const STATIC_JSON_START = /^\s*[{[]/;
20
+ function impliedContentType(body) {
21
+ if (typeof body !== 'string')
22
+ return 'application/octet-stream';
23
+ return STATIC_JSON_START.test(body)
24
+ ? 'application/json; charset=utf-8'
25
+ : 'text/plain; charset=utf-8';
26
+ }
27
+ /**
28
+ * A literal body in place of a handler: the route answers with exactly that
29
+ * body, as res.send(body) would (status 200, the implied content-type). When
30
+ * nothing else is configured on the route - no auth, validation, rate limit,
31
+ * cache or middleware, and a literal path - the schema also carries `static`,
32
+ * so a server that can answer it natively does so without calling into JS.
33
+ * Anything configured keeps the route on the normal pipeline, where the
34
+ * handler sends the same bytes after that configuration has run.
35
+ */
36
+ export function compileStaticRoute(schema, body) {
37
+ schema.handler = (_req, res) => {
38
+ res.send(body);
39
+ };
40
+ const path = schema.path ?? '';
41
+ const mw = schema.middleware;
42
+ const hasMiddleware = Array.isArray(mw)
43
+ ? mw.length > 0
44
+ : mw !== undefined &&
45
+ Object.keys(mw).some(phase => {
46
+ const list = mw[phase];
47
+ return Array.isArray(list) && list.length > 0;
48
+ });
49
+ const bare = !path.includes(':') &&
50
+ !path.includes('*') &&
51
+ !schema.auth &&
52
+ !schema.validation &&
53
+ !schema.rateLimit &&
54
+ !schema.cache &&
55
+ !hasMiddleware;
56
+ if (bare) {
57
+ schema.static = { status: 200, headers: ['content-type', impliedContentType(body)], body };
58
+ }
59
+ return schema;
60
+ }
16
61
  // Canonical uppercase methods - lets dispatch skip toUpperCase for the
17
62
  // interned method strings every adapter hands over
18
63
  const UPPERCASE_METHODS = new Set(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS']);
@@ -143,14 +188,20 @@ export class RouteBuilder {
143
188
  }
144
189
  return this;
145
190
  }
146
- // Terminal method
191
+ // Terminal method: a function, or the response body itself (see
192
+ // compileStaticRoute for what a literal body means).
147
193
  handler(handler) {
148
- if (!handler) {
149
- throw new Error('Handler is required');
194
+ if (typeof handler === 'function') {
195
+ // Avoid spread operator - add handler directly
196
+ this.schema.handler = handler;
197
+ this.router.registerRoute(this.schema);
198
+ return;
150
199
  }
151
- // Avoid spread operator - add handler directly
152
- this.schema.handler = handler;
153
- this.router.registerRoute(this.schema);
200
+ if (typeof handler === 'string' || Buffer.isBuffer(handler)) {
201
+ this.router.registerRoute(compileStaticRoute(this.schema, handler));
202
+ return;
203
+ }
204
+ throw new Error('Handler is required: a function, or the response body as a string or Buffer');
154
205
  }
155
206
  }
156
207
  // ===== Unified Router =====
@@ -278,6 +329,20 @@ export class UnifiedRouter {
278
329
  * Register a route (internal method) - OPTIMIZED
279
330
  */
280
331
  registerRoute(schema) {
332
+ // A literal body in place of a handler (see compileStaticRoute). Every
333
+ // entry point lands here - the builder, app.get(path, body), route(schema)
334
+ // - so this is where the body becomes a handler and, on a bare route, a
335
+ // reply the native engine can answer itself.
336
+ if (typeof schema.handler !== 'function') {
337
+ const body = schema.handler;
338
+ if (typeof body !== 'string' && !Buffer.isBuffer(body)) {
339
+ throw new Error(`Handler for ${schema.method} ${schema.path} must be a function, ` +
340
+ 'or the response body as a string or Buffer');
341
+ }
342
+ compileStaticRoute(schema, body);
343
+ }
344
+ // From here on the handler is a function, whichever form was registered.
345
+ const registered = schema;
281
346
  // OPTIMIZATION: Skip PathMatcher.compile for better performance
282
347
  // Determine if static route (optimized check)
283
348
  const pathLen = schema.path.length;
@@ -296,9 +361,9 @@ export class UnifiedRouter {
296
361
  // OPTIMIZATION: Lazy auth middleware creation (only create when needed, not during registration)
297
362
  // This speeds up route registration significantly
298
363
  const route = {
299
- schema,
364
+ schema: registered,
300
365
  compiledPath: null, // Will be set lazily if needed
301
- handler: schema.handler,
366
+ handler: registered.handler,
302
367
  isFastPath,
303
368
  executionOrder,
304
369
  rateLimitConfig: schema.rateLimit,