@asenajs/ergenecore 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +636 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/Ergenecore.d.ts +598 -0
- package/dist/lib/Ergenecore.js +1406 -0
- package/dist/lib/Ergenecore.js.map +1 -0
- package/dist/lib/ErgenecoreContextWrapper.d.ts +190 -0
- package/dist/lib/ErgenecoreContextWrapper.js +387 -0
- package/dist/lib/ErgenecoreContextWrapper.js.map +1 -0
- package/dist/lib/ErgenecoreWebsocketAdapter.d.ts +68 -0
- package/dist/lib/ErgenecoreWebsocketAdapter.js +233 -0
- package/dist/lib/ErgenecoreWebsocketAdapter.js.map +1 -0
- package/dist/lib/defaults/ConfigService.d.ts +39 -0
- package/dist/lib/defaults/ConfigService.js +30 -0
- package/dist/lib/defaults/ConfigService.js.map +1 -0
- package/dist/lib/defaults/MiddlewareService.d.ts +39 -0
- package/dist/lib/defaults/MiddlewareService.js +30 -0
- package/dist/lib/defaults/MiddlewareService.js.map +1 -0
- package/dist/lib/defaults/StaticServeService.d.ts +24 -0
- package/dist/lib/defaults/StaticServeService.js +23 -0
- package/dist/lib/defaults/StaticServeService.js.map +1 -0
- package/dist/lib/defaults/ValidationService.d.ts +35 -0
- package/dist/lib/defaults/ValidationService.js +34 -0
- package/dist/lib/defaults/ValidationService.js.map +1 -0
- package/dist/lib/defaults/index.d.ts +25 -0
- package/dist/lib/defaults/index.js +26 -0
- package/dist/lib/defaults/index.js.map +1 -0
- package/dist/lib/errors.d.ts +84 -0
- package/dist/lib/errors.js +108 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/index.d.ts +36 -0
- package/dist/lib/index.js +37 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/middlewares/CorsMiddleware.d.ts +147 -0
- package/dist/lib/middlewares/CorsMiddleware.js +163 -0
- package/dist/lib/middlewares/CorsMiddleware.js.map +1 -0
- package/dist/lib/middlewares/RateLimiterMiddleware.d.ts +330 -0
- package/dist/lib/middlewares/RateLimiterMiddleware.js +300 -0
- package/dist/lib/middlewares/RateLimiterMiddleware.js.map +1 -0
- package/dist/lib/types/Handler.d.ts +65 -0
- package/dist/lib/types/Handler.js +10 -0
- package/dist/lib/types/Handler.js.map +1 -0
- package/dist/lib/types/StaticServeExtras.d.ts +29 -0
- package/dist/lib/types/StaticServeExtras.js +2 -0
- package/dist/lib/types/StaticServeExtras.js.map +1 -0
- package/dist/lib/types/Validation.d.ts +7 -0
- package/dist/lib/types/Validation.js +2 -0
- package/dist/lib/types/Validation.js.map +1 -0
- package/dist/lib/types/index.d.ts +24 -0
- package/dist/lib/types/index.js +25 -0
- package/dist/lib/types/index.js.map +1 -0
- package/dist/lib/utils/factory.d.ts +121 -0
- package/dist/lib/utils/factory.js +144 -0
- package/dist/lib/utils/factory.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,598 @@
|
|
|
1
|
+
import type { WebsocketRouteParams } from '@asenajs/asena/adapter';
|
|
2
|
+
import { AsenaAdapter, type AsenaServeOptions, type BaseMiddleware, type ErrorHandler, type RouteParams } from '@asenajs/asena/adapter';
|
|
3
|
+
import { type ServerLogger } from '@asenajs/asena/logger';
|
|
4
|
+
import type { GlobalMiddlewareConfig } from '@asenajs/asena/server/config';
|
|
5
|
+
import { ErgenecoreWebsocketAdapter } from './ErgenecoreWebsocketAdapter';
|
|
6
|
+
import { type Context } from './ErgenecoreContextWrapper';
|
|
7
|
+
import type { Server } from 'bun';
|
|
8
|
+
import type { ValidationSchema, ValidationSchemaWithHook } from './types';
|
|
9
|
+
/**
|
|
10
|
+
* CoreAdapter - Native Bun adapter for Asenajs
|
|
11
|
+
*
|
|
12
|
+
* High-performance HTTP adapter using Bun's native APIs exclusively:
|
|
13
|
+
* - SIMD-accelerated routing
|
|
14
|
+
* - Native Request/Response
|
|
15
|
+
* - Zero framework overhead
|
|
16
|
+
* - Built-in parameter extraction
|
|
17
|
+
*/
|
|
18
|
+
export declare class Ergenecore extends AsenaAdapter<Context, ValidationSchemaWithHook | ValidationSchema> {
|
|
19
|
+
/**
|
|
20
|
+
* Adapter name
|
|
21
|
+
*/
|
|
22
|
+
name: string;
|
|
23
|
+
/**
|
|
24
|
+
* Server port (inherited from AsenaAdapter but needs override for initialization)
|
|
25
|
+
*/
|
|
26
|
+
protected port: number;
|
|
27
|
+
/**
|
|
28
|
+
* Server hostname
|
|
29
|
+
*/
|
|
30
|
+
private _hostname;
|
|
31
|
+
/**
|
|
32
|
+
* Bun server instance
|
|
33
|
+
*/
|
|
34
|
+
private server;
|
|
35
|
+
/**
|
|
36
|
+
* Route queue for deferred registration
|
|
37
|
+
* Routes are queued during initialization and built when server starts
|
|
38
|
+
*/
|
|
39
|
+
private routeQueue;
|
|
40
|
+
/**
|
|
41
|
+
* WebSocket route queue for deferred registration
|
|
42
|
+
* WebSocket routes are queued during initialization and built when server starts
|
|
43
|
+
*/
|
|
44
|
+
private wsRouteQueue;
|
|
45
|
+
/**
|
|
46
|
+
* Flag to track if routes have been built
|
|
47
|
+
*/
|
|
48
|
+
private routesBuilt;
|
|
49
|
+
/**
|
|
50
|
+
* Error handler function
|
|
51
|
+
*/
|
|
52
|
+
private errorHandler?;
|
|
53
|
+
/**
|
|
54
|
+
* Global middlewares with route configuration
|
|
55
|
+
* Structure: Array<{ middleware, config }>
|
|
56
|
+
* Config is optional - if not provided, middleware applies to all routes
|
|
57
|
+
*/
|
|
58
|
+
private globalMiddlewares;
|
|
59
|
+
private options;
|
|
60
|
+
/**
|
|
61
|
+
* Creates a new CoreAdapter instance
|
|
62
|
+
*
|
|
63
|
+
* @param logger - Server logger instance
|
|
64
|
+
* @param websocketAdapter - WebSocket adapter instance (optional)
|
|
65
|
+
*/
|
|
66
|
+
constructor(logger: ServerLogger, websocketAdapter?: ErgenecoreWebsocketAdapter);
|
|
67
|
+
/**
|
|
68
|
+
* Registers a WebSocket route (deferred registration)
|
|
69
|
+
*
|
|
70
|
+
* Routes are queued and will be built into Bun's native router format
|
|
71
|
+
* when the server starts. Supports middleware chain execution before
|
|
72
|
+
* WebSocket upgrade.
|
|
73
|
+
*
|
|
74
|
+
* @param params - WebSocket route parameters (path, middlewares, websocketService)
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* adapter.registerWebsocketRoute({
|
|
79
|
+
* path: '/chat',
|
|
80
|
+
* middlewares: [authMiddleware],
|
|
81
|
+
* websocketService: chatService
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
registerWebsocketRoute(params: WebsocketRouteParams<Context>): void;
|
|
86
|
+
/**
|
|
87
|
+
* Sets the server port
|
|
88
|
+
*
|
|
89
|
+
* @param port - Port number
|
|
90
|
+
*/
|
|
91
|
+
setPort(port: number): void;
|
|
92
|
+
/**
|
|
93
|
+
* Registers a global middleware with optional pattern matching
|
|
94
|
+
*
|
|
95
|
+
* @param middleware - Middleware instance
|
|
96
|
+
* @param config - Optional route configuration for pattern matching
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* // Old API (still supported) - applies to all routes
|
|
101
|
+
* adapter.use(loggerMiddleware);
|
|
102
|
+
*
|
|
103
|
+
* // New API with pattern matching - applies only to matching routes
|
|
104
|
+
* adapter.use(authMiddleware, {
|
|
105
|
+
* include: ['/api/*', '/admin/*'],
|
|
106
|
+
* exclude: ['/api/health']
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
use(middleware: BaseMiddleware<Context>, config?: GlobalMiddlewareConfig['routes']): void;
|
|
111
|
+
/**
|
|
112
|
+
* Registers a route (deferred registration)
|
|
113
|
+
*
|
|
114
|
+
* Routes are queued and will be built into Bun's native router format
|
|
115
|
+
* when the server starts.
|
|
116
|
+
*
|
|
117
|
+
* @param params - Route parameters
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* adapter.registerRoute({
|
|
122
|
+
* method: HttpMethod.GET,
|
|
123
|
+
* path: '/users/:id',
|
|
124
|
+
* middlewares: [],
|
|
125
|
+
* handler: async (ctx) => ctx.send({ id: ctx.getParam('id') })
|
|
126
|
+
* });
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
registerRoute(params: RouteParams<Context, ValidationSchemaWithHook>): void;
|
|
130
|
+
/**
|
|
131
|
+
* Starts the Bun server
|
|
132
|
+
*
|
|
133
|
+
* Builds routes from queue (HTTP + WebSocket) and starts Bun.serve() with native router.
|
|
134
|
+
*
|
|
135
|
+
* Process:
|
|
136
|
+
* 1. Build HTTP routes from route queue
|
|
137
|
+
* 2. Build WebSocket routes from WebSocket route queue
|
|
138
|
+
* 3. Check for path collisions (HTTP GET vs WebSocket GET)
|
|
139
|
+
* 4. Merge HTTP and WebSocket routes
|
|
140
|
+
* 5. Prepare WebSocket adapter
|
|
141
|
+
* 6. Start Bun server with merged routes
|
|
142
|
+
*
|
|
143
|
+
* @param port - Optional port to override default
|
|
144
|
+
* @returns Bun server instance
|
|
145
|
+
*/
|
|
146
|
+
start(port?: number): Server<any>;
|
|
147
|
+
/**
|
|
148
|
+
* Stops the server
|
|
149
|
+
*
|
|
150
|
+
* @param closeActiveConnections - Whether to close active connections
|
|
151
|
+
*/
|
|
152
|
+
stop(closeActiveConnections?: boolean): Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Sets the error handler
|
|
155
|
+
*
|
|
156
|
+
* @param errorHandler - Error handler function
|
|
157
|
+
*/
|
|
158
|
+
onError(errorHandler: ErrorHandler<Context>): void;
|
|
159
|
+
/**
|
|
160
|
+
* Sets serve options
|
|
161
|
+
*
|
|
162
|
+
* @param options - Serve options function
|
|
163
|
+
*/
|
|
164
|
+
serveOptions(options: () => Promise<AsenaServeOptions> | AsenaServeOptions): Promise<void>;
|
|
165
|
+
/**
|
|
166
|
+
* Builds Bun native router object from queued routes
|
|
167
|
+
*
|
|
168
|
+
* Optimizations applied:
|
|
169
|
+
* 1. Base path extraction - Groups routes by static base path
|
|
170
|
+
* 2. Common middleware detection - Identifies shared middlewares per group
|
|
171
|
+
* 3. Middleware deduplication - Reduces redundant middleware execution
|
|
172
|
+
*
|
|
173
|
+
* Converts Asena route format to Bun's native router format:
|
|
174
|
+
* ```typescript
|
|
175
|
+
* {
|
|
176
|
+
* "/users": {
|
|
177
|
+
* GET: (req) => Response,
|
|
178
|
+
* POST: (req) => Response
|
|
179
|
+
* },
|
|
180
|
+
* "/users/:id": {
|
|
181
|
+
* GET: (req) => Response
|
|
182
|
+
* }
|
|
183
|
+
* }
|
|
184
|
+
* ```
|
|
185
|
+
*
|
|
186
|
+
* @returns Bun router object
|
|
187
|
+
*/
|
|
188
|
+
private buildBunRoutes;
|
|
189
|
+
/**
|
|
190
|
+
* Builds WebSocket routes from queued WebSocket route registrations
|
|
191
|
+
*
|
|
192
|
+
* Converts Asena WebSocket route format to Bun's native router format
|
|
193
|
+
* with middleware chain support. Each WebSocket route creates a GET
|
|
194
|
+
* handler that executes middlewares before attempting WebSocket upgrade.
|
|
195
|
+
*
|
|
196
|
+
* @returns Bun router object for WebSocket routes
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* // Returns:
|
|
201
|
+
* {
|
|
202
|
+
* "/chat": {
|
|
203
|
+
* GET: (req) => Response | undefined // upgrade handler with middlewares
|
|
204
|
+
* }
|
|
205
|
+
* }
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
private buildWebSocketRoutes;
|
|
209
|
+
/**
|
|
210
|
+
* Executes middleware chain with recursive next() pattern
|
|
211
|
+
*
|
|
212
|
+
* Middlewares can control execution flow by:
|
|
213
|
+
* - Calling await next() to proceed to next middleware
|
|
214
|
+
* - Returning false to stop pipeline (403 response)
|
|
215
|
+
* - Returning Response to send custom response and stop pipeline
|
|
216
|
+
* - Throwing HttpException to send custom HTTP error response
|
|
217
|
+
* - Throwing error to trigger error handler
|
|
218
|
+
*
|
|
219
|
+
* @param context - Request context
|
|
220
|
+
* @param middlewares - Array of middlewares to execute
|
|
221
|
+
* @param index - Current middleware index (internal)
|
|
222
|
+
* @returns Promise<boolean | Response> - true to continue, false to stop with 403, Response to send custom response
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```typescript
|
|
226
|
+
* const result = await this.executeMiddlewares(context, globalMiddlewares);
|
|
227
|
+
* if (result === false) {
|
|
228
|
+
* return new Response('Forbidden', { status: 403 });
|
|
229
|
+
* }
|
|
230
|
+
* if (result instanceof Response) {
|
|
231
|
+
* return result;
|
|
232
|
+
* }
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
private executeMiddlewares;
|
|
236
|
+
/**
|
|
237
|
+
* Creates a WebSocket upgrade handler with middleware chain support
|
|
238
|
+
*
|
|
239
|
+
* The handler executes in the following order:
|
|
240
|
+
* 1. Create context wrapper
|
|
241
|
+
* 2. Execute global middlewares (pattern-filtered, if any return false, reject with 403)
|
|
242
|
+
* 3. Execute route-specific middlewares (if any return false, reject with 403)
|
|
243
|
+
* 4. Attempt WebSocket upgrade via server.upgrade()
|
|
244
|
+
* 5. Return undefined if upgrade successful, error response otherwise
|
|
245
|
+
*
|
|
246
|
+
* @param wsRoute - WebSocket route parameters
|
|
247
|
+
* @returns Bun-compatible WebSocket upgrade handler
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```typescript
|
|
251
|
+
* const handler = createWebSocketUpgradeHandler({
|
|
252
|
+
* path: '/chat',
|
|
253
|
+
* middlewares: [authMiddleware],
|
|
254
|
+
* websocketService: chatService
|
|
255
|
+
* });
|
|
256
|
+
* // handler(req) => Response | undefined
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
private createWebSocketUpgradeHandler;
|
|
260
|
+
/**
|
|
261
|
+
* Checks for path collisions between HTTP and WebSocket routes
|
|
262
|
+
*
|
|
263
|
+
* Validates that no HTTP GET route conflicts with a WebSocket route
|
|
264
|
+
* on the same path, as both use GET method for their handlers.
|
|
265
|
+
*
|
|
266
|
+
* @param httpRoutes - HTTP routes object from buildBunRoutes()
|
|
267
|
+
* @param wsRoutes - WebSocket routes object from buildWebSocketRoutes()
|
|
268
|
+
* @throws Error if collision detected
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* ```typescript
|
|
272
|
+
* checkPathCollisions(
|
|
273
|
+
* { "/api/data": { GET: handler1 } },
|
|
274
|
+
* { "/api/data": { GET: wsHandler } }
|
|
275
|
+
* );
|
|
276
|
+
* // Throws: Route collision detected at path "/api/data": Both HTTP and WebSocket routes define GET method
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
279
|
+
private checkPathCollisions;
|
|
280
|
+
/**
|
|
281
|
+
* Merges HTTP and WebSocket routes into a single router object
|
|
282
|
+
*
|
|
283
|
+
* Combines routes from buildBunRoutes() and buildWebSocketRoutes(),
|
|
284
|
+
* ensuring that methods on the same path are properly merged.
|
|
285
|
+
*
|
|
286
|
+
* @param httpRoutes - HTTP routes object
|
|
287
|
+
* @param wsRoutes - WebSocket routes object
|
|
288
|
+
* @returns Merged routes object
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```typescript
|
|
292
|
+
* mergeRoutes(
|
|
293
|
+
* { "/api": { POST: handler1, PUT: handler2 } },
|
|
294
|
+
* { "/api": { GET: wsHandler } }
|
|
295
|
+
* );
|
|
296
|
+
* // Returns: { "/api": { POST: handler1, PUT: handler2, GET: wsHandler } }
|
|
297
|
+
* ```
|
|
298
|
+
*/
|
|
299
|
+
private mergeRoutes;
|
|
300
|
+
/**
|
|
301
|
+
* Creates a fast path handler for simple routes
|
|
302
|
+
*
|
|
303
|
+
* This handler is optimized for routes without:
|
|
304
|
+
* - Middlewares (global or route-level)
|
|
305
|
+
* - Validators
|
|
306
|
+
* - Static file serving
|
|
307
|
+
*
|
|
308
|
+
* Benefits:
|
|
309
|
+
* - Minimal object allocation
|
|
310
|
+
* - No conditional checks
|
|
311
|
+
* - Direct handler execution
|
|
312
|
+
* - Reduced try-catch overhead
|
|
313
|
+
*
|
|
314
|
+
* @param route - Route parameters
|
|
315
|
+
* @returns Bun-compatible fast path handler
|
|
316
|
+
*/
|
|
317
|
+
private createFastPathHandler;
|
|
318
|
+
/**
|
|
319
|
+
* Creates a route handler function for Bun's router
|
|
320
|
+
*
|
|
321
|
+
* Wraps the Asena handler with:
|
|
322
|
+
* - CoreContextWrapper for context abstraction
|
|
323
|
+
* - Parameter injection from Bun's native parser
|
|
324
|
+
* - Global and route middlewares (pattern-filtered)
|
|
325
|
+
* - Error handling
|
|
326
|
+
*
|
|
327
|
+
* @param route - Route parameters
|
|
328
|
+
* @param _commonMiddlewares - Common middlewares for this route group (for future optimization)
|
|
329
|
+
* @returns Bun-compatible route handler
|
|
330
|
+
*/
|
|
331
|
+
private createRouteHandler;
|
|
332
|
+
/**
|
|
333
|
+
* Type guard to check if validation schema has hook format
|
|
334
|
+
*
|
|
335
|
+
* Discriminates between ValidationSchemaWithHook and plain ValidationSchema.
|
|
336
|
+
* Uses runtime check for 'schema' property to determine type.
|
|
337
|
+
*
|
|
338
|
+
* @param schema - Validation schema to check
|
|
339
|
+
* @returns true if schema is ValidationSchemaWithHook format
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* ```typescript
|
|
343
|
+
* if (isValidationSchemaWithHook(schema)) {
|
|
344
|
+
* // schema.schema and schema.hook are available
|
|
345
|
+
* } else {
|
|
346
|
+
* // schema is a plain Zod schema
|
|
347
|
+
* }
|
|
348
|
+
* ```
|
|
349
|
+
*/
|
|
350
|
+
private isValidationSchemaWithHook;
|
|
351
|
+
/**
|
|
352
|
+
* Validates request data using Zod schemas
|
|
353
|
+
*
|
|
354
|
+
* Checks each validation target (body, query, param, header) and runs
|
|
355
|
+
* the Zod schema validation. If validation fails and a hook is provided,
|
|
356
|
+
* the hook is called to generate a custom error response.
|
|
357
|
+
*
|
|
358
|
+
* Supports two validation formats:
|
|
359
|
+
* 1. Plain Zod schema: z.object({...})
|
|
360
|
+
* 2. Schema with hook: { schema: z.object({...}), hook?: (...) => {...} }
|
|
361
|
+
*
|
|
362
|
+
* @param context - Request context
|
|
363
|
+
* @param validator - Validator instance with schema definitions
|
|
364
|
+
* @returns Response if validation fails, null if passes
|
|
365
|
+
*/
|
|
366
|
+
private validateRequest;
|
|
367
|
+
/**
|
|
368
|
+
* Extracts data from request based on validation target
|
|
369
|
+
*
|
|
370
|
+
* @param context - Request context
|
|
371
|
+
* @param target - Validation target (body, query, param, header)
|
|
372
|
+
* @returns Data to be validated
|
|
373
|
+
*/
|
|
374
|
+
private extractValidationData;
|
|
375
|
+
/**
|
|
376
|
+
* Serves static files using Bun.file() API
|
|
377
|
+
*
|
|
378
|
+
* This method handles static file serving with the following features:
|
|
379
|
+
* - Path rewriting via rewriteRequestPath
|
|
380
|
+
* - Root directory resolution
|
|
381
|
+
* - File existence checking
|
|
382
|
+
* - onFound/onNotFound hooks
|
|
383
|
+
* - Automatic MIME type detection (via Bun.file())
|
|
384
|
+
*
|
|
385
|
+
* @param req - Native Bun Request object
|
|
386
|
+
* @param context - ErgenecoreContextWrapper instance
|
|
387
|
+
* @param staticServe - Static serve configuration from route
|
|
388
|
+
* @returns Response object if file found/not found, null if hooks override
|
|
389
|
+
*
|
|
390
|
+
* @example
|
|
391
|
+
* ```typescript
|
|
392
|
+
* const response = await this.serveStaticFile(req, context, {
|
|
393
|
+
* root: '/public',
|
|
394
|
+
* rewriteRequestPath: (path) => path.replace('/static', ''),
|
|
395
|
+
* onFound: { handler: async () => {}, override: false },
|
|
396
|
+
* onNotFound: { handler: async () => {}, override: false }
|
|
397
|
+
* });
|
|
398
|
+
* ```
|
|
399
|
+
*/
|
|
400
|
+
private serveStaticFile;
|
|
401
|
+
/**
|
|
402
|
+
* Builds response headers for static file serving
|
|
403
|
+
*
|
|
404
|
+
* Constructs headers with:
|
|
405
|
+
* - Content-Type (custom MIME or Bun default)
|
|
406
|
+
* - Cache-Control (if specified)
|
|
407
|
+
* - Custom headers (if specified)
|
|
408
|
+
*
|
|
409
|
+
* @param filePath - Resolved absolute file path
|
|
410
|
+
* @param extras - StaticServeExtras configuration
|
|
411
|
+
* @returns Headers object for Response
|
|
412
|
+
*
|
|
413
|
+
* @example
|
|
414
|
+
* ```typescript
|
|
415
|
+
* const headers = this.buildStaticFileHeaders('/app/public/style.css', {
|
|
416
|
+
* cacheControl: 'public, max-age=86400',
|
|
417
|
+
* headers: { 'X-Custom': 'value' },
|
|
418
|
+
* mimes: { '.css': 'text/css; charset=utf-8' }
|
|
419
|
+
* });
|
|
420
|
+
* // Returns: { 'Content-Type': 'text/css; charset=utf-8', 'Cache-Control': '...', 'X-Custom': 'value' }
|
|
421
|
+
* ```
|
|
422
|
+
*/
|
|
423
|
+
private buildStaticFileHeaders;
|
|
424
|
+
/**
|
|
425
|
+
* Extracts base path from a route path
|
|
426
|
+
*
|
|
427
|
+
* Removes dynamic segments (parameters and wildcards) from the path
|
|
428
|
+
* to find the static base path for grouping routes.
|
|
429
|
+
*
|
|
430
|
+
* @param path - Route path (e.g., "/api/users/:id")
|
|
431
|
+
* @returns Base path without dynamic segments (e.g., "/api/users")
|
|
432
|
+
*
|
|
433
|
+
* @example
|
|
434
|
+
* ```typescript
|
|
435
|
+
* extractBasePath('/api/users/:id') // => '/api/users'
|
|
436
|
+
* extractBasePath('/api/users/:id/posts/:postId') // => '/api/users'
|
|
437
|
+
* extractBasePath('/static/*') // => '/static'
|
|
438
|
+
* extractBasePath('/') // => '/'
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
private extractBasePath;
|
|
442
|
+
/**
|
|
443
|
+
* Extracts common middlewares across multiple routes
|
|
444
|
+
*
|
|
445
|
+
* Identifies middlewares that are present in ALL routes and can be
|
|
446
|
+
* moved to group level for optimization.
|
|
447
|
+
*
|
|
448
|
+
* @param routes - Array of routes to analyze
|
|
449
|
+
* @returns Array of common middleware instances
|
|
450
|
+
*
|
|
451
|
+
* @example
|
|
452
|
+
* ```typescript
|
|
453
|
+
* extractCommonMiddlewares([
|
|
454
|
+
* { middlewares: [auth, log, rate] },
|
|
455
|
+
* { middlewares: [auth, log] },
|
|
456
|
+
* { middlewares: [auth, log] }
|
|
457
|
+
* ]) // => [auth, log]
|
|
458
|
+
* ```
|
|
459
|
+
*/
|
|
460
|
+
private extractCommonMiddlewares;
|
|
461
|
+
/**
|
|
462
|
+
* Groups routes by their base path
|
|
463
|
+
*
|
|
464
|
+
* Creates a map of base paths to routes for optimization.
|
|
465
|
+
* Routes with the same base path will share common middlewares.
|
|
466
|
+
*
|
|
467
|
+
* @param routes - Array of routes to group
|
|
468
|
+
* @returns Map of base paths to route arrays
|
|
469
|
+
*
|
|
470
|
+
* @example
|
|
471
|
+
* ```typescript
|
|
472
|
+
* groupRoutesByBasePath([
|
|
473
|
+
* { path: '/api/users' },
|
|
474
|
+
* { path: '/api/users/:id' },
|
|
475
|
+
* { path: '/api/posts' }
|
|
476
|
+
* ])
|
|
477
|
+
* // => Map {
|
|
478
|
+
* // '/api/users' => [route1, route2],
|
|
479
|
+
* // '/api/posts' => [route3]
|
|
480
|
+
* // }
|
|
481
|
+
* ```
|
|
482
|
+
*/
|
|
483
|
+
private groupRoutesByBasePath;
|
|
484
|
+
get hostname(): any;
|
|
485
|
+
set hostname(value: any);
|
|
486
|
+
/**
|
|
487
|
+
* Groups HTTP routes by controller name
|
|
488
|
+
*
|
|
489
|
+
* Creates a map of controller names to their routes for organized logging.
|
|
490
|
+
* Each group contains the controller's base path and all its routes.
|
|
491
|
+
*
|
|
492
|
+
* @returns Map of controller names to route groups
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* ```typescript
|
|
496
|
+
* groupRoutesByController()
|
|
497
|
+
* // => Map {
|
|
498
|
+
* // 'UserController' => {
|
|
499
|
+
* // basePath: '/users',
|
|
500
|
+
* // routes: [{ method: 'GET', path: '/users' }, { method: 'POST', path: '/users' }]
|
|
501
|
+
* // }
|
|
502
|
+
* // }
|
|
503
|
+
* ```
|
|
504
|
+
*/
|
|
505
|
+
private groupRoutesByController;
|
|
506
|
+
/**
|
|
507
|
+
* Groups WebSocket routes by controller name
|
|
508
|
+
*
|
|
509
|
+
* Creates a map of controller names to their WebSocket routes for organized logging.
|
|
510
|
+
*
|
|
511
|
+
* @returns Map of controller names to WebSocket route groups
|
|
512
|
+
*
|
|
513
|
+
* @example
|
|
514
|
+
* ```typescript
|
|
515
|
+
* groupWebSocketRoutesByController()
|
|
516
|
+
* // => Map {
|
|
517
|
+
* // 'ChatController' => {
|
|
518
|
+
* // basePath: '/chat',
|
|
519
|
+
* // routes: [{ path: '/chat' }]
|
|
520
|
+
* // }
|
|
521
|
+
* // }
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
524
|
+
private groupWebSocketRoutesByController;
|
|
525
|
+
/**
|
|
526
|
+
* Filters global middlewares for a specific route path
|
|
527
|
+
*
|
|
528
|
+
* Uses pattern matching to determine which middlewares should apply to this path.
|
|
529
|
+
* Pattern matching happens ONCE during route building (deferred registration),
|
|
530
|
+
* not on every request, ensuring zero runtime overhead.
|
|
531
|
+
*
|
|
532
|
+
* @param path - Route path (e.g., '/api/users', '/users/:id')
|
|
533
|
+
* @returns Array of middlewares that should apply to this path
|
|
534
|
+
*
|
|
535
|
+
* @example
|
|
536
|
+
* ```typescript
|
|
537
|
+
* // Given:
|
|
538
|
+
* // - LoggerMiddleware (no config → applies to all routes)
|
|
539
|
+
* // - AuthMiddleware (include: ['/api/*'])
|
|
540
|
+
* // - RateLimitMiddleware (exclude: ['/health'])
|
|
541
|
+
*
|
|
542
|
+
* getGlobalMiddlewaresForPath('/api/users')
|
|
543
|
+
* // => [LoggerMiddleware, AuthMiddleware, RateLimitMiddleware]
|
|
544
|
+
*
|
|
545
|
+
* getGlobalMiddlewaresForPath('/health')
|
|
546
|
+
* // => [LoggerMiddleware, AuthMiddleware] (RateLimit excluded)
|
|
547
|
+
*
|
|
548
|
+
* getGlobalMiddlewaresForPath('/public/page')
|
|
549
|
+
* // => [LoggerMiddleware, RateLimitMiddleware] (Auth not included)
|
|
550
|
+
* ```
|
|
551
|
+
*/
|
|
552
|
+
private getGlobalMiddlewaresForPath;
|
|
553
|
+
/**
|
|
554
|
+
* Logs a summary of registered controllers
|
|
555
|
+
*
|
|
556
|
+
* Displays colored success messages for each controller with route counts.
|
|
557
|
+
* HTTP controllers show total HTTP routes, WebSocket-only controllers are
|
|
558
|
+
* displayed separately.
|
|
559
|
+
*
|
|
560
|
+
* @example
|
|
561
|
+
* Output format:
|
|
562
|
+
* ```
|
|
563
|
+
* ✓ Successfully registered CONTROLLER UserController (2 routes)
|
|
564
|
+
* ✓ Successfully registered WEBSOCKET ChatController (1 route)
|
|
565
|
+
* ```
|
|
566
|
+
*/
|
|
567
|
+
private logControllerSummary;
|
|
568
|
+
/**
|
|
569
|
+
* Builds controller-based log output with colors
|
|
570
|
+
*
|
|
571
|
+
* Creates a formatted string showing all routes grouped by controller,
|
|
572
|
+
* with HTTP controllers listed first, then WebSocket namespaces separately.
|
|
573
|
+
*
|
|
574
|
+
* Color scheme:
|
|
575
|
+
* - Controller name: blue
|
|
576
|
+
* - Base path: yellow
|
|
577
|
+
* - GET method: green
|
|
578
|
+
* - POST method: blue
|
|
579
|
+
* - PUT method: yellow
|
|
580
|
+
* - DELETE method: red
|
|
581
|
+
* - WS method: blue
|
|
582
|
+
*
|
|
583
|
+
* @returns Formatted log string with color codes
|
|
584
|
+
*
|
|
585
|
+
* @example
|
|
586
|
+
* Output format:
|
|
587
|
+
* ```
|
|
588
|
+
* UserController (/users):
|
|
589
|
+
* GET /users
|
|
590
|
+
* GET /users/:id
|
|
591
|
+
* POST /users
|
|
592
|
+
*
|
|
593
|
+
* ChatNamespace (chat):
|
|
594
|
+
* WS /chat
|
|
595
|
+
* ```
|
|
596
|
+
*/
|
|
597
|
+
private buildControllerBasedLog;
|
|
598
|
+
}
|