@stacksjs/bun-router 0.0.12 → 0.0.14
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/CHANGELOG.md +770 -0
- package/README.md +584 -261
- package/package.json +43 -48
- package/bin/cli.ts +0 -9
- package/dist/auth.d.ts +0 -134
- package/dist/cache/lru-cache.d.ts +0 -139
- package/dist/cache/middleware-memoization.d.ts +0 -151
- package/dist/cache/route-cache-warmer.d.ts +0 -161
- package/dist/cache/sqlite-cache.d.ts +0 -209
- package/dist/cache/streaming-cache.d.ts +0 -132
- package/dist/chunk-1mvtv6jw.js +0 -13012
- package/dist/cli/colors.d.ts +0 -15
- package/dist/cli/index.d.ts +0 -10
- package/dist/cli/middleware.d.ts +0 -31
- package/dist/cli/openapi.d.ts +0 -17
- package/dist/cli/router.d.ts +0 -15
- package/dist/cli/routes.d.ts +0 -29
- package/dist/cli/utils.d.ts +0 -74
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -3195
- package/dist/config.d.ts +0 -7
- package/dist/container/container.d.ts +0 -273
- package/dist/container/contextual-binding.d.ts +0 -240
- package/dist/container/decorators.d.ts +0 -141
- package/dist/container/service-provider.d.ts +0 -285
- package/dist/development/hot-reload.d.ts +0 -187
- package/dist/development/index.d.ts +0 -167
- package/dist/development/performance-profiler.d.ts +0 -217
- package/dist/development/route-debugger.d.ts +0 -154
- package/dist/development/route-inspector.d.ts +0 -211
- package/dist/development/typescript-utilities.d.ts +0 -209
- package/dist/docs.d.ts +0 -11
- package/dist/errors/circuit-breaker.d.ts +0 -195
- package/dist/errors/error-handler.d.ts +0 -88
- package/dist/errors/error-reporting.d.ts +0 -144
- package/dist/errors/exceptions.d.ts +0 -184
- package/dist/errors/graceful-degradation.d.ts +0 -154
- package/dist/errors/index.d.ts +0 -9
- package/dist/errors/router-errors.d.ts +0 -110
- package/dist/file-serving/static-files.d.ts +0 -143
- package/dist/index.d.ts +0 -14
- package/dist/index.js +0 -13933
- package/dist/middleware/auth.d.ts +0 -63
- package/dist/middleware/content_security_policy.d.ts +0 -53
- package/dist/middleware/cors.d.ts +0 -5
- package/dist/middleware/csrf.d.ts +0 -7
- package/dist/middleware/ddos_protection.d.ts +0 -39
- package/dist/middleware/file_security.d.ts +0 -26
- package/dist/middleware/file_upload.d.ts +0 -38
- package/dist/middleware/helmet.d.ts +0 -54
- package/dist/middleware/index.d.ts +0 -44
- package/dist/middleware/input_validation.d.ts +0 -45
- package/dist/middleware/json_body.d.ts +0 -4
- package/dist/middleware/performance_alerting.d.ts +0 -87
- package/dist/middleware/performance_dashboard.d.ts +0 -87
- package/dist/middleware/performance_monitor.d.ts +0 -209
- package/dist/middleware/pipeline.d.ts +0 -131
- package/dist/middleware/rate_limit.d.ts +0 -36
- package/dist/middleware/request_id.d.ts +0 -4
- package/dist/middleware/request_signing.d.ts +0 -153
- package/dist/middleware/request_tracer.d.ts +0 -72
- package/dist/middleware/response_cache.d.ts +0 -97
- package/dist/middleware/security.d.ts +0 -69
- package/dist/middleware/security_suite.d.ts +0 -46
- package/dist/middleware/session.d.ts +0 -23
- package/dist/model-binding/index.d.ts +0 -2
- package/dist/model-binding/model-middleware.d.ts +0 -118
- package/dist/model-binding/model-registry.d.ts +0 -164
- package/dist/model-binding.d.ts +0 -185
- package/dist/model-resolver-factory.d.ts +0 -31
- package/dist/observability/correlation.d.ts +0 -187
- package/dist/observability/health-checks.d.ts +0 -186
- package/dist/observability/index.d.ts +0 -60
- package/dist/observability/integration.d.ts +0 -147
- package/dist/observability/metrics.d.ts +0 -184
- package/dist/observability/tracing.d.ts +0 -187
- package/dist/optimization/bun-utilities.d.ts +0 -224
- package/dist/query-builder-integration.d.ts +0 -36
- package/dist/request/context.d.ts +0 -34
- package/dist/request/enhanced-request.d.ts +0 -213
- package/dist/request/macros.d.ts +0 -300
- package/dist/response/macros.d.ts +0 -245
- package/dist/response/response-factory.d.ts +0 -133
- package/dist/router/api-routes.d.ts +0 -5
- package/dist/router/file-based-routing.d.ts +0 -118
- package/dist/router/file-streaming.d.ts +0 -5
- package/dist/router/fluent-router.d.ts +0 -315
- package/dist/router/fluent-routing.d.ts +0 -271
- package/dist/router/group-organization.d.ts +0 -5
- package/dist/router/handler-resolver.d.ts +0 -24
- package/dist/router/http-methods.d.ts +0 -10
- package/dist/router/index.d.ts +0 -114
- package/dist/router/middleware-groups.d.ts +0 -94
- package/dist/router/middleware-integration.d.ts +0 -112
- package/dist/router/middleware.d.ts +0 -5
- package/dist/router/model-binding.d.ts +0 -5
- package/dist/router/optimized-route-matching.d.ts +0 -6
- package/dist/router/route-building.d.ts +0 -5
- package/dist/router/route-compiler.d.ts +0 -153
- package/dist/router/route-matching.d.ts +0 -5
- package/dist/router/route-trie.d.ts +0 -114
- package/dist/router/router.d.ts +0 -294
- package/dist/router/server.d.ts +0 -5
- package/dist/router/validation-integration.d.ts +0 -170
- package/dist/router/view-rendering.d.ts +0 -5
- package/dist/router/websocket.d.ts +0 -5
- package/dist/routing/route-caching.d.ts +0 -129
- package/dist/routing/route-throttling.d.ts +0 -150
- package/dist/routing/subdomain-routing.d.ts +0 -206
- package/dist/session/database-store.d.ts +0 -51
- package/dist/session/file-store.d.ts +0 -22
- package/dist/session/index.d.ts +0 -106
- package/dist/session/memory-store.d.ts +0 -21
- package/dist/session/redis-store.d.ts +0 -31
- package/dist/streaming/index.d.ts +0 -3
- package/dist/streaming/sse-handler.d.ts +0 -138
- package/dist/streaming/stream-handler.d.ts +0 -114
- package/dist/testing/auth-testing.d.ts +0 -156
- package/dist/testing/file-upload-testing.d.ts +0 -190
- package/dist/testing/index.d.ts +0 -10
- package/dist/testing/middleware-testing.d.ts +0 -138
- package/dist/testing/model-binding-testing.d.ts +0 -186
- package/dist/testing/performance-testing.d.ts +0 -235
- package/dist/testing/test-client.d.ts +0 -117
- package/dist/testing/test-request.d.ts +0 -85
- package/dist/testing/test-response.d.ts +0 -90
- package/dist/testing/types.d.ts +0 -207
- package/dist/testing/websocket-testing.d.ts +0 -227
- package/dist/types/controller-types.d.ts +0 -208
- package/dist/types/core.d.ts +0 -543
- package/dist/types/middleware-types.d.ts +0 -227
- package/dist/types/request-response-augmentation.d.ts +0 -261
- package/dist/types/route-inference.d.ts +0 -168
- package/dist/types.d.ts +0 -1782
- package/dist/url.d.ts +0 -56
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/query-preservation.d.ts +0 -48
- package/dist/utils.d.ts +0 -69
- package/dist/validation/validator.d.ts +0 -140
- package/dist/websocket/clustering.d.ts +0 -185
- package/src/auth.ts +0 -469
- package/src/cache/lru-cache.ts +0 -457
- package/src/cache/middleware-memoization.ts +0 -531
- package/src/cache/route-cache-warmer.ts +0 -486
- package/src/cache/sqlite-cache.ts +0 -783
- package/src/cache/streaming-cache.ts +0 -572
- package/src/cli/colors.ts +0 -29
- package/src/cli/index.ts +0 -287
- package/src/cli/middleware.ts +0 -291
- package/src/cli/openapi.ts +0 -407
- package/src/cli/router.ts +0 -188
- package/src/cli/routes.ts +0 -265
- package/src/cli/utils.ts +0 -531
- package/src/cli.ts +0 -5
- package/src/config.ts +0 -322
- package/src/container/container.ts +0 -740
- package/src/container/contextual-binding.ts +0 -603
- package/src/container/decorators.ts +0 -359
- package/src/container/service-provider.ts +0 -596
- package/src/development/hot-reload.ts +0 -673
- package/src/development/index.ts +0 -499
- package/src/development/performance-profiler.ts +0 -717
- package/src/development/route-debugger.ts +0 -527
- package/src/development/route-inspector.ts +0 -749
- package/src/development/typescript-utilities.ts +0 -682
- package/src/docs.ts +0 -397
- package/src/errors/circuit-breaker.ts +0 -732
- package/src/errors/error-handler.ts +0 -569
- package/src/errors/error-reporting.ts +0 -672
- package/src/errors/exceptions.ts +0 -536
- package/src/errors/graceful-degradation.ts +0 -621
- package/src/errors/index.ts +0 -21
- package/src/errors/router-errors.ts +0 -632
- package/src/file-serving/static-files.ts +0 -581
- package/src/index.ts +0 -14
- package/src/middleware/auth.ts +0 -219
- package/src/middleware/content_security_policy.ts +0 -215
- package/src/middleware/cors.ts +0 -74
- package/src/middleware/csrf.ts +0 -108
- package/src/middleware/ddos_protection.ts +0 -255
- package/src/middleware/file_security.ts +0 -191
- package/src/middleware/file_upload.ts +0 -264
- package/src/middleware/helmet.ts +0 -268
- package/src/middleware/index.ts +0 -117
- package/src/middleware/input_validation.ts +0 -449
- package/src/middleware/json_body.ts +0 -37
- package/src/middleware/performance_alerting.ts +0 -538
- package/src/middleware/performance_dashboard.ts +0 -661
- package/src/middleware/performance_monitor.ts +0 -943
- package/src/middleware/pipeline.ts +0 -489
- package/src/middleware/rate_limit.ts +0 -245
- package/src/middleware/request_id.ts +0 -36
- package/src/middleware/request_signing.ts +0 -636
- package/src/middleware/request_tracer.ts +0 -636
- package/src/middleware/response_cache.ts +0 -743
- package/src/middleware/security.ts +0 -482
- package/src/middleware/security_suite.ts +0 -257
- package/src/middleware/session.ts +0 -91
- package/src/model-binding/index.ts +0 -18
- package/src/model-binding/model-middleware.ts +0 -425
- package/src/model-binding/model-registry.ts +0 -550
- package/src/model-binding.ts +0 -370
- package/src/model-resolver-factory.ts +0 -106
- package/src/observability/correlation.ts +0 -691
- package/src/observability/health-checks.ts +0 -729
- package/src/observability/index.ts +0 -184
- package/src/observability/integration.ts +0 -548
- package/src/observability/metrics.ts +0 -753
- package/src/observability/tracing.ts +0 -638
- package/src/optimization/bun-utilities.ts +0 -778
- package/src/query-builder-integration.ts +0 -137
- package/src/request/context.ts +0 -62
- package/src/request/enhanced-request.ts +0 -857
- package/src/request/macros.ts +0 -688
- package/src/response/macros.ts +0 -612
- package/src/response/response-factory.ts +0 -596
- package/src/router/api-routes.ts +0 -243
- package/src/router/file-based-routing.ts +0 -670
- package/src/router/file-streaming.ts +0 -372
- package/src/router/fluent-router.ts +0 -927
- package/src/router/fluent-routing.ts +0 -797
- package/src/router/group-organization.ts +0 -213
- package/src/router/handler-resolver.ts +0 -291
- package/src/router/http-methods.ts +0 -377
- package/src/router/index.ts +0 -187
- package/src/router/middleware-groups.ts +0 -222
- package/src/router/middleware-integration.ts +0 -399
- package/src/router/middleware.ts +0 -231
- package/src/router/model-binding.ts +0 -215
- package/src/router/optimized-route-matching.ts +0 -253
- package/src/router/route-building.ts +0 -212
- package/src/router/route-compiler.ts +0 -702
- package/src/router/route-matching.ts +0 -349
- package/src/router/route-trie.ts +0 -464
- package/src/router/router.ts +0 -1581
- package/src/router/server.ts +0 -462
- package/src/router/validation-integration.ts +0 -443
- package/src/router/view-rendering.ts +0 -233
- package/src/router/websocket.ts +0 -100
- package/src/routing/route-caching.ts +0 -402
- package/src/routing/route-throttling.ts +0 -469
- package/src/routing/subdomain-routing.ts +0 -492
- package/src/session/database-store.ts +0 -109
- package/src/session/file-store.ts +0 -148
- package/src/session/index.ts +0 -244
- package/src/session/memory-store.ts +0 -88
- package/src/session/redis-store.ts +0 -93
- package/src/streaming/index.ts +0 -17
- package/src/streaming/sse-handler.ts +0 -482
- package/src/streaming/stream-handler.ts +0 -552
- package/src/testing/auth-testing.ts +0 -446
- package/src/testing/file-upload-testing.ts +0 -543
- package/src/testing/index.ts +0 -10
- package/src/testing/middleware-testing.ts +0 -322
- package/src/testing/model-binding-testing.ts +0 -645
- package/src/testing/performance-testing.ts +0 -738
- package/src/testing/test-client.ts +0 -310
- package/src/testing/test-request.ts +0 -315
- package/src/testing/test-response.ts +0 -332
- package/src/testing/types.ts +0 -224
- package/src/testing/websocket-testing.ts +0 -590
- package/src/types/controller-types.ts +0 -385
- package/src/types/core.ts +0 -683
- package/src/types/middleware-types.ts +0 -419
- package/src/types/request-response-augmentation.ts +0 -489
- package/src/types/route-inference.ts +0 -357
- package/src/types.ts +0 -2055
- package/src/url.ts +0 -126
- package/src/utils/index.ts +0 -1
- package/src/utils/query-preservation.ts +0 -201
- package/src/utils.ts +0 -327
- package/src/validation/validator.ts +0 -685
- package/src/websocket/clustering.ts +0 -762
|
@@ -1,527 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Development Tools - Route Debugging
|
|
3
|
-
*
|
|
4
|
-
* Comprehensive route debugging with detailed logging and inspection
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { EnhancedRequest } from '../types'
|
|
8
|
-
import process from 'node:process'
|
|
9
|
-
|
|
10
|
-
export interface RouteDebugConfig {
|
|
11
|
-
enabled?: boolean
|
|
12
|
-
logLevel?: 'debug' | 'info' | 'warn' | 'error'
|
|
13
|
-
includeHeaders?: boolean
|
|
14
|
-
includeBody?: boolean
|
|
15
|
-
includeParams?: boolean
|
|
16
|
-
includeQuery?: boolean
|
|
17
|
-
includeTimings?: boolean
|
|
18
|
-
maxBodySize?: number
|
|
19
|
-
colorOutput?: boolean
|
|
20
|
-
outputFormat?: 'console' | 'json' | 'structured'
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface RouteMatchAttempt {
|
|
24
|
-
pattern: string
|
|
25
|
-
method: string
|
|
26
|
-
matched: boolean
|
|
27
|
-
reason?: string
|
|
28
|
-
params?: Record<string, string>
|
|
29
|
-
score?: number
|
|
30
|
-
timing: number
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface RouteDebugInfo {
|
|
34
|
-
requestId: string
|
|
35
|
-
timestamp: number
|
|
36
|
-
method: string
|
|
37
|
-
url: string
|
|
38
|
-
path: string
|
|
39
|
-
headers?: Record<string, string>
|
|
40
|
-
query?: Record<string, string>
|
|
41
|
-
params?: Record<string, string>
|
|
42
|
-
body?: any
|
|
43
|
-
matchAttempts: RouteMatchAttempt[]
|
|
44
|
-
finalMatch?: {
|
|
45
|
-
pattern: string
|
|
46
|
-
handler: string
|
|
47
|
-
middleware: string[]
|
|
48
|
-
params: Record<string, string>
|
|
49
|
-
}
|
|
50
|
-
timings: {
|
|
51
|
-
routeMatching: number
|
|
52
|
-
middlewareExecution: number
|
|
53
|
-
handlerExecution: number
|
|
54
|
-
total: number
|
|
55
|
-
}
|
|
56
|
-
performance: {
|
|
57
|
-
memoryUsage: NodeJS.MemoryUsage
|
|
58
|
-
cpuTime: number
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Route debugger for development
|
|
64
|
-
*/
|
|
65
|
-
export class RouteDebugger {
|
|
66
|
-
private config: RouteDebugConfig
|
|
67
|
-
private debugSessions = new Map<string, RouteDebugInfo>()
|
|
68
|
-
private routePatterns = new Map<string, { pattern: string, method: string, handler: (...args: any[]) => any, middleware: ((...args: any[]) => any)[] }>()
|
|
69
|
-
|
|
70
|
-
constructor(config: RouteDebugConfig = {}) {
|
|
71
|
-
this.config = {
|
|
72
|
-
enabled: true,
|
|
73
|
-
logLevel: 'debug',
|
|
74
|
-
includeHeaders: true,
|
|
75
|
-
includeBody: true,
|
|
76
|
-
includeParams: true,
|
|
77
|
-
includeQuery: true,
|
|
78
|
-
includeTimings: true,
|
|
79
|
-
maxBodySize: 1024 * 10, // 10KB
|
|
80
|
-
colorOutput: true,
|
|
81
|
-
outputFormat: 'console',
|
|
82
|
-
...config,
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Start debugging a request
|
|
88
|
-
*/
|
|
89
|
-
startDebugging(req: EnhancedRequest): string {
|
|
90
|
-
if (!this.config.enabled)
|
|
91
|
-
return ''
|
|
92
|
-
|
|
93
|
-
const requestId = this.generateRequestId()
|
|
94
|
-
const _startTime = performance.now()
|
|
95
|
-
|
|
96
|
-
const debugInfo: RouteDebugInfo = {
|
|
97
|
-
requestId,
|
|
98
|
-
timestamp: Date.now(),
|
|
99
|
-
method: req.method,
|
|
100
|
-
url: req.url,
|
|
101
|
-
path: new URL(req.url).pathname,
|
|
102
|
-
matchAttempts: [],
|
|
103
|
-
timings: {
|
|
104
|
-
routeMatching: 0,
|
|
105
|
-
middlewareExecution: 0,
|
|
106
|
-
handlerExecution: 0,
|
|
107
|
-
total: 0,
|
|
108
|
-
},
|
|
109
|
-
performance: {
|
|
110
|
-
memoryUsage: process.memoryUsage(),
|
|
111
|
-
cpuTime: process.cpuUsage().user,
|
|
112
|
-
},
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Include optional data based on config
|
|
116
|
-
if (this.config.includeHeaders) {
|
|
117
|
-
debugInfo.headers = Object.fromEntries(req.headers.entries())
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (this.config.includeQuery) {
|
|
121
|
-
const url = new URL(req.url)
|
|
122
|
-
debugInfo.query = Object.fromEntries(url.searchParams.entries())
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (this.config.includeParams && (req as any).params) {
|
|
126
|
-
debugInfo.params = (req as any).params
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (this.config.includeBody && req.body) {
|
|
130
|
-
this.captureRequestBody(req, debugInfo)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
this.debugSessions.set(requestId, debugInfo)
|
|
134
|
-
|
|
135
|
-
this.log('info', `🔍 Starting route debugging for ${req.method} ${debugInfo.path}`, {
|
|
136
|
-
requestId,
|
|
137
|
-
timestamp: new Date(debugInfo.timestamp).toISOString(),
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
return requestId
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Record route match attempt
|
|
145
|
-
*/
|
|
146
|
-
recordMatchAttempt(
|
|
147
|
-
requestId: string,
|
|
148
|
-
pattern: string,
|
|
149
|
-
method: string,
|
|
150
|
-
matched: boolean,
|
|
151
|
-
reason?: string,
|
|
152
|
-
params?: Record<string, string>,
|
|
153
|
-
): void {
|
|
154
|
-
if (!this.config.enabled || !requestId)
|
|
155
|
-
return
|
|
156
|
-
|
|
157
|
-
const debugInfo = this.debugSessions.get(requestId)
|
|
158
|
-
if (!debugInfo)
|
|
159
|
-
return
|
|
160
|
-
|
|
161
|
-
const timing = performance.now()
|
|
162
|
-
|
|
163
|
-
const attempt: RouteMatchAttempt = {
|
|
164
|
-
pattern,
|
|
165
|
-
method,
|
|
166
|
-
matched,
|
|
167
|
-
reason,
|
|
168
|
-
params,
|
|
169
|
-
timing,
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
debugInfo.matchAttempts.push(attempt)
|
|
173
|
-
|
|
174
|
-
const status = matched ? '✅' : '❌'
|
|
175
|
-
const reasonText = reason ? ` (${reason})` : ''
|
|
176
|
-
|
|
177
|
-
this.log('debug', `${status} Route match: ${method} ${pattern}${reasonText}`, {
|
|
178
|
-
requestId,
|
|
179
|
-
pattern,
|
|
180
|
-
method,
|
|
181
|
-
matched,
|
|
182
|
-
reason,
|
|
183
|
-
params,
|
|
184
|
-
})
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Record final route match
|
|
189
|
-
*/
|
|
190
|
-
recordFinalMatch(
|
|
191
|
-
requestId: string,
|
|
192
|
-
pattern: string,
|
|
193
|
-
handler: (..._args: any[]) => any,
|
|
194
|
-
middleware: ((..._args: any[]) => any)[],
|
|
195
|
-
params: Record<string, string>,
|
|
196
|
-
): void {
|
|
197
|
-
if (!this.config.enabled || !requestId)
|
|
198
|
-
return
|
|
199
|
-
|
|
200
|
-
const debugInfo = this.debugSessions.get(requestId)
|
|
201
|
-
if (!debugInfo)
|
|
202
|
-
return
|
|
203
|
-
|
|
204
|
-
debugInfo.finalMatch = {
|
|
205
|
-
pattern,
|
|
206
|
-
handler: handler.name || 'anonymous',
|
|
207
|
-
middleware: middleware.map(m => m.name || 'anonymous'),
|
|
208
|
-
params,
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
this.log('info', `🎯 Final route match: ${pattern}`, {
|
|
212
|
-
requestId,
|
|
213
|
-
pattern,
|
|
214
|
-
handler: debugInfo.finalMatch.handler,
|
|
215
|
-
middleware: debugInfo.finalMatch.middleware,
|
|
216
|
-
params,
|
|
217
|
-
})
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Record timing information
|
|
222
|
-
*/
|
|
223
|
-
recordTiming(requestId: string, phase: keyof RouteDebugInfo['timings'], duration: number): void {
|
|
224
|
-
if (!this.config.enabled || !requestId)
|
|
225
|
-
return
|
|
226
|
-
|
|
227
|
-
const debugInfo = this.debugSessions.get(requestId)
|
|
228
|
-
if (!debugInfo)
|
|
229
|
-
return
|
|
230
|
-
|
|
231
|
-
debugInfo.timings[phase] = duration
|
|
232
|
-
|
|
233
|
-
if (this.config.includeTimings) {
|
|
234
|
-
this.log('debug', `⏱️ ${phase}: ${duration.toFixed(2)}ms`, {
|
|
235
|
-
requestId,
|
|
236
|
-
phase,
|
|
237
|
-
duration,
|
|
238
|
-
})
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Finish debugging session
|
|
244
|
-
*/
|
|
245
|
-
finishDebugging(requestId: string, response?: Response): RouteDebugInfo | null {
|
|
246
|
-
if (!this.config.enabled || !requestId)
|
|
247
|
-
return null
|
|
248
|
-
|
|
249
|
-
const debugInfo = this.debugSessions.get(requestId)
|
|
250
|
-
if (!debugInfo)
|
|
251
|
-
return null
|
|
252
|
-
|
|
253
|
-
// Calculate total time
|
|
254
|
-
debugInfo.timings.total = Object.values(debugInfo.timings)
|
|
255
|
-
.filter(t => t > 0)
|
|
256
|
-
.reduce((sum, t) => sum + t, 0)
|
|
257
|
-
|
|
258
|
-
// Update performance metrics
|
|
259
|
-
const endMemory = process.memoryUsage()
|
|
260
|
-
const endCpuTime = process.cpuUsage().user
|
|
261
|
-
|
|
262
|
-
debugInfo.performance = {
|
|
263
|
-
memoryUsage: {
|
|
264
|
-
rss: endMemory.rss - debugInfo.performance.memoryUsage.rss,
|
|
265
|
-
heapTotal: endMemory.heapTotal - debugInfo.performance.memoryUsage.heapTotal,
|
|
266
|
-
heapUsed: endMemory.heapUsed - debugInfo.performance.memoryUsage.heapUsed,
|
|
267
|
-
external: endMemory.external - debugInfo.performance.memoryUsage.external,
|
|
268
|
-
arrayBuffers: endMemory.arrayBuffers - debugInfo.performance.memoryUsage.arrayBuffers,
|
|
269
|
-
},
|
|
270
|
-
cpuTime: endCpuTime - debugInfo.performance.cpuTime,
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Log summary
|
|
274
|
-
this.logSummary(debugInfo, response)
|
|
275
|
-
|
|
276
|
-
// Clean up session
|
|
277
|
-
this.debugSessions.delete(requestId)
|
|
278
|
-
|
|
279
|
-
return debugInfo
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Register route pattern for debugging
|
|
284
|
-
*/
|
|
285
|
-
registerRoute(method: string, pattern: string, handler: (...args: any[]) => any, middleware: ((...args: any[]) => any)[] = []): void {
|
|
286
|
-
const key = `${method}:${pattern}`
|
|
287
|
-
this.routePatterns.set(key, { pattern, method, handler, middleware })
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Get all registered routes
|
|
292
|
-
*/
|
|
293
|
-
getRegisteredRoutes(): Array<{ method: string, pattern: string, handler: string, middleware: string[] }> {
|
|
294
|
-
return Array.from(this.routePatterns.values()).map(route => ({
|
|
295
|
-
method: route.method,
|
|
296
|
-
pattern: route.pattern,
|
|
297
|
-
handler: route.handler.name || 'anonymous',
|
|
298
|
-
middleware: route.middleware.map(m => m.name || 'anonymous'),
|
|
299
|
-
}))
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Get debug session
|
|
304
|
-
*/
|
|
305
|
-
getDebugSession(requestId: string): RouteDebugInfo | undefined {
|
|
306
|
-
return this.debugSessions.get(requestId)
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Clear all debug sessions
|
|
311
|
-
*/
|
|
312
|
-
clearSessions(): void {
|
|
313
|
-
this.debugSessions.clear()
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* Generate unique request ID
|
|
318
|
-
*/
|
|
319
|
-
private generateRequestId(): string {
|
|
320
|
-
return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Capture request body safely
|
|
325
|
-
*/
|
|
326
|
-
private async captureRequestBody(req: EnhancedRequest, debugInfo: RouteDebugInfo): Promise<void> {
|
|
327
|
-
try {
|
|
328
|
-
if (req.headers.get('content-type')?.includes('application/json')) {
|
|
329
|
-
const text = await req.text()
|
|
330
|
-
if (text.length <= (this.config.maxBodySize || 1024 * 10)) {
|
|
331
|
-
debugInfo.body = JSON.parse(text)
|
|
332
|
-
}
|
|
333
|
-
else {
|
|
334
|
-
debugInfo.body = `[Body too large: ${text.length} bytes]`
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
else if (req.headers.get('content-type')?.includes('application/x-www-form-urlencoded')) {
|
|
338
|
-
const formData = await req.formData()
|
|
339
|
-
debugInfo.body = Object.fromEntries((formData as any).entries())
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
catch (error) {
|
|
343
|
-
debugInfo.body = `[Error reading body: ${error instanceof Error ? error.message : String(error)}]`
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* Log debug message
|
|
349
|
-
*/
|
|
350
|
-
private log(level: string, message: string, data?: any): void {
|
|
351
|
-
if (!this.shouldLog(level))
|
|
352
|
-
return
|
|
353
|
-
|
|
354
|
-
const timestamp = new Date().toISOString()
|
|
355
|
-
|
|
356
|
-
switch (this.config.outputFormat) {
|
|
357
|
-
case 'json':
|
|
358
|
-
console.log(JSON.stringify({ timestamp, level, message, data }))
|
|
359
|
-
break
|
|
360
|
-
|
|
361
|
-
case 'structured':
|
|
362
|
-
console.log(`[${timestamp}] [${level.toUpperCase()}] ${message}`)
|
|
363
|
-
if (data)
|
|
364
|
-
console.log(' Data:', JSON.stringify(data, null, 2))
|
|
365
|
-
break
|
|
366
|
-
|
|
367
|
-
default: // console
|
|
368
|
-
if (this.config.colorOutput) {
|
|
369
|
-
const colors = {
|
|
370
|
-
debug: '\x1B[36m', // cyan
|
|
371
|
-
info: '\x1B[32m', // green
|
|
372
|
-
warn: '\x1B[33m', // yellow
|
|
373
|
-
error: '\x1B[31m', // red
|
|
374
|
-
}
|
|
375
|
-
const reset = '\x1B[0m'
|
|
376
|
-
const color = colors[level as keyof typeof colors] || ''
|
|
377
|
-
console.log(`${color}[ROUTE-DEBUG]${reset} ${message}`)
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
380
|
-
console.log(`[ROUTE-DEBUG] ${message}`)
|
|
381
|
-
}
|
|
382
|
-
if (data && level !== 'debug') {
|
|
383
|
-
console.log(' ', data)
|
|
384
|
-
}
|
|
385
|
-
break
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* Log debugging summary
|
|
391
|
-
*/
|
|
392
|
-
private logSummary(debugInfo: RouteDebugInfo, response?: Response): void {
|
|
393
|
-
const { timings, matchAttempts, finalMatch } = debugInfo
|
|
394
|
-
|
|
395
|
-
this.log('info', `📊 Route debugging summary for ${debugInfo.method} ${debugInfo.path}`, {
|
|
396
|
-
requestId: debugInfo.requestId,
|
|
397
|
-
totalTime: `${timings.total.toFixed(2)}ms`,
|
|
398
|
-
matchAttempts: matchAttempts.length,
|
|
399
|
-
successfulMatch: !!finalMatch,
|
|
400
|
-
responseStatus: response?.status,
|
|
401
|
-
memoryDelta: `${(debugInfo.performance.memoryUsage.heapUsed / 1024 / 1024).toFixed(2)}MB`,
|
|
402
|
-
cpuTime: `${(debugInfo.performance.cpuTime / 1000).toFixed(2)}ms`,
|
|
403
|
-
})
|
|
404
|
-
|
|
405
|
-
// Log failed matches if any
|
|
406
|
-
const failedMatches = matchAttempts.filter(attempt => !attempt.matched)
|
|
407
|
-
if (failedMatches.length > 0) {
|
|
408
|
-
this.log('warn', `❌ ${failedMatches.length} failed route matches:`, failedMatches.map(attempt => `${attempt.method} ${attempt.pattern} (${attempt.reason})`),
|
|
409
|
-
)
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// Log performance warnings
|
|
413
|
-
if (timings.total > 1000) {
|
|
414
|
-
this.log('warn', `⚠️ Slow request detected: ${timings.total.toFixed(2)}ms`)
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
if (debugInfo.performance.memoryUsage.heapUsed > 50 * 1024 * 1024) { // 50MB
|
|
418
|
-
this.log('warn', `⚠️ High memory usage: ${(debugInfo.performance.memoryUsage.heapUsed / 1024 / 1024).toFixed(2)}MB`)
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* Check if should log at level
|
|
424
|
-
*/
|
|
425
|
-
private shouldLog(level: string): boolean {
|
|
426
|
-
const levels = { debug: 0, info: 1, warn: 2, error: 3 }
|
|
427
|
-
const currentLevel = levels[this.config.logLevel as keyof typeof levels] || 0
|
|
428
|
-
const messageLevel = levels[level as keyof typeof levels] || 0
|
|
429
|
-
return messageLevel >= currentLevel
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* Global route debugger instance
|
|
435
|
-
*/
|
|
436
|
-
let globalDebugger: RouteDebugger | null = null
|
|
437
|
-
|
|
438
|
-
/**
|
|
439
|
-
* Initialize global route debugger
|
|
440
|
-
*/
|
|
441
|
-
export function initializeRouteDebugger(config?: RouteDebugConfig): RouteDebugger {
|
|
442
|
-
globalDebugger = new RouteDebugger(config)
|
|
443
|
-
return globalDebugger
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* Get global route debugger
|
|
448
|
-
*/
|
|
449
|
-
export function getRouteDebugger(): RouteDebugger | null {
|
|
450
|
-
return globalDebugger
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
/**
|
|
454
|
-
* Route debugging middleware factory
|
|
455
|
-
*/
|
|
456
|
-
export function createRouteDebugMiddleware(config?: RouteDebugConfig) {
|
|
457
|
-
const routeDebugger = globalDebugger || new RouteDebugger(config)
|
|
458
|
-
|
|
459
|
-
return async (req: EnhancedRequest, next: () => Promise<Response>): Promise<Response> => {
|
|
460
|
-
const requestId = routeDebugger.startDebugging(req)
|
|
461
|
-
|
|
462
|
-
// Add debugger to request for route matching
|
|
463
|
-
;(req as any).debugger = routeDebugger
|
|
464
|
-
;(req as any).debugRequestId = requestId
|
|
465
|
-
|
|
466
|
-
const startTime = performance.now()
|
|
467
|
-
|
|
468
|
-
try {
|
|
469
|
-
const response = await next()
|
|
470
|
-
|
|
471
|
-
const endTime = performance.now()
|
|
472
|
-
routeDebugger.recordTiming(requestId, 'total', endTime - startTime)
|
|
473
|
-
|
|
474
|
-
routeDebugger.finishDebugging(requestId, response)
|
|
475
|
-
|
|
476
|
-
return response
|
|
477
|
-
}
|
|
478
|
-
catch (error) {
|
|
479
|
-
const endTime = performance.now()
|
|
480
|
-
routeDebugger.recordTiming(requestId, 'total', endTime - startTime)
|
|
481
|
-
|
|
482
|
-
routeDebugger.finishDebugging(requestId)
|
|
483
|
-
throw error
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
* Route debugging helpers
|
|
490
|
-
*/
|
|
491
|
-
export const RouteDebugHelpers = {
|
|
492
|
-
/**
|
|
493
|
-
* Record route match attempt from request context
|
|
494
|
-
*/
|
|
495
|
-
recordMatch: (req: EnhancedRequest, pattern: string, method: string, matched: boolean, reason?: string, params?: Record<string, string>): void => {
|
|
496
|
-
const routeDebugger = (req as any).debugger as RouteDebugger
|
|
497
|
-
const requestId = (req as any).debugRequestId as string
|
|
498
|
-
|
|
499
|
-
if (routeDebugger && requestId) {
|
|
500
|
-
routeDebugger.recordMatchAttempt(requestId, pattern, method, matched, reason, params)
|
|
501
|
-
}
|
|
502
|
-
},
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* Record final match from request context
|
|
506
|
-
*/
|
|
507
|
-
recordFinalMatch: (req: EnhancedRequest, pattern: string, handler: (...args: any[]) => any, middleware: ((...args: any[]) => any)[], params: Record<string, string>): void => {
|
|
508
|
-
const routeDebugger = (req as any).debugger as RouteDebugger
|
|
509
|
-
const requestId = (req as any).debugRequestId as string
|
|
510
|
-
|
|
511
|
-
if (routeDebugger && requestId) {
|
|
512
|
-
routeDebugger.recordFinalMatch(requestId, pattern, handler, middleware, params)
|
|
513
|
-
}
|
|
514
|
-
},
|
|
515
|
-
|
|
516
|
-
/**
|
|
517
|
-
* Record timing from request context
|
|
518
|
-
*/
|
|
519
|
-
recordTiming: (req: EnhancedRequest, phase: keyof RouteDebugInfo['timings'], duration: number): void => {
|
|
520
|
-
const routeDebugger = (req as any).debugger as RouteDebugger
|
|
521
|
-
const requestId = (req as any).debugRequestId as string
|
|
522
|
-
|
|
523
|
-
if (routeDebugger && requestId) {
|
|
524
|
-
routeDebugger.recordTiming(requestId, phase, duration)
|
|
525
|
-
}
|
|
526
|
-
},
|
|
527
|
-
}
|