@stacksjs/bun-router 0.0.17 → 0.0.18
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/dist/cli.js +1 -1
- package/dist/container/service-provider.d.ts +3 -3
- package/dist/development/performance-profiler.d.ts +3 -3
- package/dist/development/route-debugger.d.ts +1 -1
- package/dist/development/route-inspector.d.ts +2 -2
- package/dist/observability/integration.d.ts +1 -1
- package/dist/response/macros.d.ts +1 -1
- package/dist/router/index.d.ts +7 -7
- package/dist/router/router.d.ts +0 -32
- package/dist/testing/performance-testing.d.ts +2 -2
- package/dist/testing/test-client.d.ts +1 -1
- package/dist/testing/websocket-testing.d.ts +1 -1
- package/package.json +2 -3
- package/src/auth.ts +0 -489
- 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 -786
- package/src/container/contextual-binding.ts +0 -606
- package/src/container/decorators.ts +0 -368
- package/src/container/index.ts +0 -49
- 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 -733
- 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 -623
- package/src/errors/index.ts +0 -21
- package/src/errors/router-errors.ts +0 -632
- package/src/file-serving/static-files.ts +0 -718
- package/src/index.ts +0 -66
- package/src/middleware/auth.ts +0 -220
- package/src/middleware/content_security_policy.ts +0 -215
- package/src/middleware/cors.ts +0 -142
- package/src/middleware/csrf.ts +0 -166
- package/src/middleware/ddos_protection.ts +0 -279
- package/src/middleware/file_security.ts +0 -191
- package/src/middleware/file_upload.ts +0 -275
- package/src/middleware/helmet.ts +0 -268
- package/src/middleware/index.ts +0 -117
- package/src/middleware/input_validation.ts +0 -453
- package/src/middleware/json_body.ts +0 -37
- package/src/middleware/performance_alerting.ts +0 -540
- package/src/middleware/performance_dashboard.ts +0 -661
- package/src/middleware/performance_monitor.ts +0 -945
- package/src/middleware/pipeline.ts +0 -489
- package/src/middleware/rate_limit.ts +0 -251
- package/src/middleware/request_id.ts +0 -36
- package/src/middleware/request_signing.ts +0 -638
- package/src/middleware/request_tracer.ts +0 -653
- package/src/middleware/response_cache.ts +0 -778
- 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 -109
- package/src/request/enhanced-request.ts +0 -876
- package/src/request/macros.ts +0 -822
- package/src/response/macros.ts +0 -665
- package/src/response/response-factory.ts +0 -596
- package/src/router/api-routes.ts +0 -243
- package/src/router/file-based-routing.ts +0 -697
- package/src/router/file-streaming.ts +0 -383
- package/src/router/fluent-routing.ts +0 -866
- package/src/router/group-organization.ts +0 -229
- package/src/router/handler-resolver.ts +0 -327
- package/src/router/http-methods.ts +0 -407
- package/src/router/index.ts +0 -193
- package/src/router/middleware-groups.ts +0 -222
- package/src/router/middleware-integration.ts +0 -399
- package/src/router/middleware.ts +0 -234
- package/src/router/model-binding.ts +0 -215
- package/src/router/optimized-route-matching.ts +0 -302
- package/src/router/route-building.ts +0 -221
- package/src/router/route-compiler.ts +0 -691
- package/src/router/route-matching.ts +0 -368
- package/src/router/route-trie.ts +0 -450
- package/src/router/router.ts +0 -1616
- package/src/router/server.ts +0 -684
- package/src/router/validation-integration.ts +0 -449
- 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 -448
- 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 -422
- package/src/types/request-response-augmentation.ts +0 -489
- package/src/types/route-inference.ts +0 -372
- package/src/types.ts +0 -2123
- package/src/url.ts +0 -131
- package/src/utils/index.ts +0 -1
- package/src/utils/query-preservation.ts +0 -201
- package/src/utils.ts +0 -395
- package/src/validation/validator.ts +0 -688
- package/src/websocket/clustering.ts +0 -769
|
@@ -1,407 +0,0 @@
|
|
|
1
|
-
import type { ActionHandler, EnhancedRequest, MiddlewareHandler, Route } from '../types'
|
|
2
|
-
import type { Router } from './router'
|
|
3
|
-
import { registerNamedRoute } from '../url'
|
|
4
|
-
import { extractParamNames, joinPaths, matchPath } from '../utils'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* HTTP methods extension for Router class
|
|
8
|
-
* Uses a class extension pattern instead of prototype manipulation
|
|
9
|
-
*/
|
|
10
|
-
export function registerHttpMethods(RouterClass: typeof Router): void {
|
|
11
|
-
// Extend the Router class with HTTP methods
|
|
12
|
-
Object.defineProperties(RouterClass.prototype, {
|
|
13
|
-
// Add a route to the router
|
|
14
|
-
addRoute: {
|
|
15
|
-
value(
|
|
16
|
-
method: string,
|
|
17
|
-
path: string,
|
|
18
|
-
handler: ActionHandler,
|
|
19
|
-
type?: 'api' | 'web',
|
|
20
|
-
name?: string,
|
|
21
|
-
middleware?: (string | MiddlewareHandler)[],
|
|
22
|
-
): Router {
|
|
23
|
-
// Apply current group settings if in a group
|
|
24
|
-
let routePath = path
|
|
25
|
-
let routeMiddleware: MiddlewareHandler[] = []
|
|
26
|
-
const routeType = type || 'web'
|
|
27
|
-
|
|
28
|
-
if (this.currentGroup) {
|
|
29
|
-
// Apply prefix if it exists
|
|
30
|
-
if (this.currentGroup.prefix) {
|
|
31
|
-
routePath = joinPaths(this.currentGroup.prefix, path)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Apply middleware if it exists
|
|
35
|
-
if (this.currentGroup.middleware && this.currentGroup.middleware.length > 0) {
|
|
36
|
-
routeMiddleware = [...this.currentGroup.middleware] as MiddlewareHandler[]
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Apply route-specific middleware if provided
|
|
41
|
-
if (middleware && middleware.length > 0) {
|
|
42
|
-
for (const middlewareItem of middleware) {
|
|
43
|
-
const resolved = this.resolveMiddleware(middlewareItem)
|
|
44
|
-
if (resolved) {
|
|
45
|
-
routeMiddleware.push(resolved)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Apply API/Web path prefixes
|
|
51
|
-
if (routeType === 'api' && this.config.apiPrefix) {
|
|
52
|
-
routePath = joinPaths(this.config.apiPrefix, routePath)
|
|
53
|
-
}
|
|
54
|
-
else if (routeType === 'web' && this.config.webPrefix) {
|
|
55
|
-
routePath = joinPaths(this.config.webPrefix, routePath)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Apply domain if in a domain group
|
|
59
|
-
let domain: string | undefined
|
|
60
|
-
if (this.currentDomain) {
|
|
61
|
-
domain = this.currentDomain
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Create the route
|
|
65
|
-
const route: Route = {
|
|
66
|
-
method: method.toUpperCase(),
|
|
67
|
-
path: routePath,
|
|
68
|
-
handler,
|
|
69
|
-
domain,
|
|
70
|
-
params: {},
|
|
71
|
-
middleware: routeMiddleware,
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Apply constraints from patterns map
|
|
75
|
-
const paramNames = extractParamNames(routePath)
|
|
76
|
-
const constraints: Record<string, string> = {}
|
|
77
|
-
|
|
78
|
-
paramNames.forEach((param: string) => {
|
|
79
|
-
// Remove optional marker for constraint lookup
|
|
80
|
-
const baseParam = param.replace('?', '')
|
|
81
|
-
if (this.patterns.has(baseParam)) {
|
|
82
|
-
constraints[baseParam] = this.patterns.get(baseParam)!
|
|
83
|
-
}
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
if (Object.keys(constraints).length > 0) {
|
|
87
|
-
route.constraints = constraints
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Add pattern property for route matching
|
|
91
|
-
route.pattern = {
|
|
92
|
-
exec: (url: URL): { pathname: { groups: Record<string, string> } } | null => {
|
|
93
|
-
const params: Record<string, string> = {}
|
|
94
|
-
// Pass constraints directly to matchPath for more efficient matching
|
|
95
|
-
const constraintsRecord = route.constraints && !Array.isArray(route.constraints)
|
|
96
|
-
? route.constraints as Record<string, string>
|
|
97
|
-
: undefined
|
|
98
|
-
|
|
99
|
-
const isMatch = matchPath(routePath, url.pathname, params, constraintsRecord)
|
|
100
|
-
|
|
101
|
-
if (!isMatch) {
|
|
102
|
-
return null
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return {
|
|
106
|
-
pathname: {
|
|
107
|
-
groups: params,
|
|
108
|
-
},
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// If handler is a Response object, register it for Bun's native static dispatch.
|
|
114
|
-
// Static responses bypass the fetch handler entirely for zero-allocation serving.
|
|
115
|
-
if (handler instanceof Response) {
|
|
116
|
-
this.staticResponses.set(routePath, handler)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Add to the appropriate collection
|
|
120
|
-
if (domain) {
|
|
121
|
-
if (!this.domains[domain]) {
|
|
122
|
-
this.domains[domain] = []
|
|
123
|
-
}
|
|
124
|
-
this.domains[domain].push(route)
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
this.routes.push(route)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Add to static routes map for fast lookup if it's a static route.
|
|
131
|
-
// First registration wins — if a route is already registered (e.g., by user code),
|
|
132
|
-
// the framework default is skipped so users can override any route.
|
|
133
|
-
if (!routePath.includes('{') && !routePath.includes('*')) {
|
|
134
|
-
if (!this.staticRoutes.has(method.toUpperCase())) {
|
|
135
|
-
this.staticRoutes.set(method.toUpperCase(), new Map())
|
|
136
|
-
}
|
|
137
|
-
const methodMap = this.staticRoutes.get(method.toUpperCase())!
|
|
138
|
-
if (!methodMap.has(routePath)) {
|
|
139
|
-
methodMap.set(routePath, route)
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Add to named routes if name is provided
|
|
144
|
-
if (name) {
|
|
145
|
-
route.name = name
|
|
146
|
-
this.namedRoutes.set(name, route)
|
|
147
|
-
registerNamedRoute(name, route.path)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Add to optimized route compiler if available. Domain-scoped routes
|
|
151
|
-
// stay out of the shared trie — its cache is keyed by method+path
|
|
152
|
-
// only, so a domain route in the trie could be served to the wrong
|
|
153
|
-
// host. They are matched by the domain-aware fallback instead.
|
|
154
|
-
if (this.addRouteToCompiler && !domain) {
|
|
155
|
-
this.addRouteToCompiler(route)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Clear route caches when new routes are added
|
|
159
|
-
this.routeCache.clear()
|
|
160
|
-
this._allowedMethodsCache?.clear()
|
|
161
|
-
|
|
162
|
-
return this
|
|
163
|
-
},
|
|
164
|
-
writable: true,
|
|
165
|
-
configurable: true,
|
|
166
|
-
},
|
|
167
|
-
|
|
168
|
-
// HTTP GET method
|
|
169
|
-
get: {
|
|
170
|
-
value(
|
|
171
|
-
path: string,
|
|
172
|
-
handler: ActionHandler,
|
|
173
|
-
type?: 'api' | 'web',
|
|
174
|
-
name?: string,
|
|
175
|
-
middleware?: (string | MiddlewareHandler)[],
|
|
176
|
-
): Router {
|
|
177
|
-
return this.addRoute('GET', path, handler, type, name, middleware)
|
|
178
|
-
},
|
|
179
|
-
writable: true,
|
|
180
|
-
configurable: true,
|
|
181
|
-
},
|
|
182
|
-
|
|
183
|
-
// HTTP POST method
|
|
184
|
-
post: {
|
|
185
|
-
value(
|
|
186
|
-
path: string,
|
|
187
|
-
handler: ActionHandler,
|
|
188
|
-
type?: 'api' | 'web',
|
|
189
|
-
name?: string,
|
|
190
|
-
middleware?: (string | MiddlewareHandler)[],
|
|
191
|
-
): Router {
|
|
192
|
-
return this.addRoute('POST', path, handler, type, name, middleware)
|
|
193
|
-
},
|
|
194
|
-
writable: true,
|
|
195
|
-
configurable: true,
|
|
196
|
-
},
|
|
197
|
-
|
|
198
|
-
// HTTP PUT method
|
|
199
|
-
put: {
|
|
200
|
-
value(
|
|
201
|
-
path: string,
|
|
202
|
-
handler: ActionHandler,
|
|
203
|
-
type?: 'api' | 'web',
|
|
204
|
-
name?: string,
|
|
205
|
-
middleware?: (string | MiddlewareHandler)[],
|
|
206
|
-
): Router {
|
|
207
|
-
return this.addRoute('PUT', path, handler, type, name, middleware)
|
|
208
|
-
},
|
|
209
|
-
writable: true,
|
|
210
|
-
configurable: true,
|
|
211
|
-
},
|
|
212
|
-
|
|
213
|
-
// HTTP PATCH method
|
|
214
|
-
patch: {
|
|
215
|
-
value(
|
|
216
|
-
path: string,
|
|
217
|
-
handler: ActionHandler,
|
|
218
|
-
type?: 'api' | 'web',
|
|
219
|
-
name?: string,
|
|
220
|
-
middleware?: (string | MiddlewareHandler)[],
|
|
221
|
-
): Router {
|
|
222
|
-
return this.addRoute('PATCH', path, handler, type, name, middleware)
|
|
223
|
-
},
|
|
224
|
-
writable: true,
|
|
225
|
-
configurable: true,
|
|
226
|
-
},
|
|
227
|
-
|
|
228
|
-
// HTTP DELETE method
|
|
229
|
-
delete: {
|
|
230
|
-
value(
|
|
231
|
-
path: string,
|
|
232
|
-
handler: ActionHandler,
|
|
233
|
-
type?: 'api' | 'web',
|
|
234
|
-
name?: string,
|
|
235
|
-
middleware?: (string | MiddlewareHandler)[],
|
|
236
|
-
): Router {
|
|
237
|
-
return this.addRoute('DELETE', path, handler, type, name, middleware)
|
|
238
|
-
},
|
|
239
|
-
writable: true,
|
|
240
|
-
configurable: true,
|
|
241
|
-
},
|
|
242
|
-
|
|
243
|
-
// HTTP OPTIONS method
|
|
244
|
-
options: {
|
|
245
|
-
value(
|
|
246
|
-
path: string,
|
|
247
|
-
handler: ActionHandler,
|
|
248
|
-
type?: 'api' | 'web',
|
|
249
|
-
name?: string,
|
|
250
|
-
middleware?: (string | MiddlewareHandler)[],
|
|
251
|
-
): Router {
|
|
252
|
-
return this.addRoute('OPTIONS', path, handler, type, name, middleware)
|
|
253
|
-
},
|
|
254
|
-
writable: true,
|
|
255
|
-
configurable: true,
|
|
256
|
-
},
|
|
257
|
-
|
|
258
|
-
// HTTP HEAD method. Note: GET routes already answer HEAD requests
|
|
259
|
-
// automatically — register an explicit HEAD route only when the HEAD
|
|
260
|
-
// behavior must differ from GET.
|
|
261
|
-
head: {
|
|
262
|
-
value(
|
|
263
|
-
path: string,
|
|
264
|
-
handler: ActionHandler,
|
|
265
|
-
type?: 'api' | 'web',
|
|
266
|
-
name?: string,
|
|
267
|
-
middleware?: (string | MiddlewareHandler)[],
|
|
268
|
-
): Router {
|
|
269
|
-
return this.addRoute('HEAD', path, handler, type, name, middleware)
|
|
270
|
-
},
|
|
271
|
-
writable: true,
|
|
272
|
-
configurable: true,
|
|
273
|
-
},
|
|
274
|
-
|
|
275
|
-
// Register a route that responds to multiple HTTP methods
|
|
276
|
-
match: {
|
|
277
|
-
value(
|
|
278
|
-
methods: string[],
|
|
279
|
-
path: string,
|
|
280
|
-
handler: ActionHandler,
|
|
281
|
-
type?: 'api' | 'web',
|
|
282
|
-
name?: string,
|
|
283
|
-
middleware?: (string | MiddlewareHandler)[],
|
|
284
|
-
): Router {
|
|
285
|
-
for (const method of methods) {
|
|
286
|
-
this.addRoute(method, path, handler, type, name, middleware)
|
|
287
|
-
}
|
|
288
|
-
return this
|
|
289
|
-
},
|
|
290
|
-
writable: true,
|
|
291
|
-
configurable: true,
|
|
292
|
-
},
|
|
293
|
-
|
|
294
|
-
// Register a route that responds to ANY HTTP method
|
|
295
|
-
any: {
|
|
296
|
-
value(
|
|
297
|
-
path: string,
|
|
298
|
-
handler: ActionHandler,
|
|
299
|
-
type?: 'api' | 'web',
|
|
300
|
-
name?: string,
|
|
301
|
-
middleware?: (string | MiddlewareHandler)[],
|
|
302
|
-
): Router {
|
|
303
|
-
const methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD']
|
|
304
|
-
return this.match(methods, path, handler, type, name, middleware)
|
|
305
|
-
},
|
|
306
|
-
writable: true,
|
|
307
|
-
configurable: true,
|
|
308
|
-
},
|
|
309
|
-
|
|
310
|
-
// Register a fallback handler for unmatched routes
|
|
311
|
-
fallback: {
|
|
312
|
-
value(handler: ActionHandler): Router {
|
|
313
|
-
this.fallbackHandler = handler
|
|
314
|
-
return this
|
|
315
|
-
},
|
|
316
|
-
writable: true,
|
|
317
|
-
configurable: true,
|
|
318
|
-
},
|
|
319
|
-
|
|
320
|
-
// Generate a URL for a named route
|
|
321
|
-
route: {
|
|
322
|
-
value(name: string, params: Record<string, string> = {}): string {
|
|
323
|
-
const route = this.namedRoutes.get(name)
|
|
324
|
-
if (!route) {
|
|
325
|
-
throw new Error(`Route with name "${name}" not found`)
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
let url = route.path
|
|
329
|
-
// Replace path parameters
|
|
330
|
-
for (const [param, value] of Object.entries(params)) {
|
|
331
|
-
url = url.replace(`{${param}}`, encodeURIComponent(value))
|
|
332
|
-
url = url.replace(`{${param}?}`, encodeURIComponent(value))
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// Drop unfilled optional placeholders and tidy up the slashes
|
|
336
|
-
// they leave behind (`/posts/{page?}` → `/posts`)
|
|
337
|
-
if (url.includes('{')) {
|
|
338
|
-
url = url.replace(/\{[^}]+\?\}/g, '').replace(/\/{2,}/g, '/')
|
|
339
|
-
if (url.length > 1 && url.endsWith('/')) {
|
|
340
|
-
url = url.slice(0, -1)
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
return url
|
|
345
|
-
},
|
|
346
|
-
writable: true,
|
|
347
|
-
configurable: true,
|
|
348
|
-
},
|
|
349
|
-
|
|
350
|
-
// Register an error handler
|
|
351
|
-
onError: {
|
|
352
|
-
value(handler: (error: Error) => Response | Promise<Response>): Router {
|
|
353
|
-
this.errorHandler = handler
|
|
354
|
-
return this
|
|
355
|
-
},
|
|
356
|
-
writable: true,
|
|
357
|
-
configurable: true,
|
|
358
|
-
},
|
|
359
|
-
})
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* Register redirect methods on the Router class
|
|
364
|
-
*/
|
|
365
|
-
export function registerRedirectMethods(RouterClass: typeof Router): void {
|
|
366
|
-
Object.defineProperties(RouterClass.prototype, {
|
|
367
|
-
redirect: {
|
|
368
|
-
value(url: string, status: 301 | 302 | 303 | 307 | 308 = 302): Response {
|
|
369
|
-
const headers = new Headers()
|
|
370
|
-
headers.set('Location', url)
|
|
371
|
-
return new Response(null, {
|
|
372
|
-
status,
|
|
373
|
-
headers,
|
|
374
|
-
})
|
|
375
|
-
},
|
|
376
|
-
writable: true,
|
|
377
|
-
configurable: true,
|
|
378
|
-
},
|
|
379
|
-
|
|
380
|
-
permanentRedirect: {
|
|
381
|
-
value(url: string): Response {
|
|
382
|
-
return this.redirect(url, 301)
|
|
383
|
-
},
|
|
384
|
-
writable: true,
|
|
385
|
-
configurable: true,
|
|
386
|
-
},
|
|
387
|
-
|
|
388
|
-
redirectRoute: {
|
|
389
|
-
value(from: string, to: string, status: 301 | 302 | 303 | 307 | 308 = 302): Router {
|
|
390
|
-
this.get(from, (_req: EnhancedRequest) => {
|
|
391
|
-
return this.redirect(to, status)
|
|
392
|
-
})
|
|
393
|
-
return this
|
|
394
|
-
},
|
|
395
|
-
writable: true,
|
|
396
|
-
configurable: true,
|
|
397
|
-
},
|
|
398
|
-
|
|
399
|
-
permanentRedirectRoute: {
|
|
400
|
-
value(from: string, to: string): Router {
|
|
401
|
-
return this.redirectRoute(from, to, 301)
|
|
402
|
-
},
|
|
403
|
-
writable: true,
|
|
404
|
-
configurable: true,
|
|
405
|
-
},
|
|
406
|
-
})
|
|
407
|
-
}
|
package/src/router/index.ts
DELETED
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
import type { ActionHandler, Route } from '../types'
|
|
2
|
-
import { Dependencies, globalMiddlewarePipeline, MiddlewareFactory, MiddlewarePipeline, SkipConditions } from '../middleware/pipeline'
|
|
3
|
-
import { registerApiRoutes } from './api-routes'
|
|
4
|
-
import { registerFileBasedRouting } from './file-based-routing'
|
|
5
|
-
import { registerFileStreaming } from './file-streaming'
|
|
6
|
-
import { FluentRouteBuilder, FluentRouter, RouteFactory, router, RouterUtils } from './fluent-routing'
|
|
7
|
-
import { registerGroupOrganization } from './group-organization'
|
|
8
|
-
import { registerHttpMethods, registerRedirectMethods } from './http-methods'
|
|
9
|
-
import { registerMiddlewareHandling } from './middleware'
|
|
10
|
-
import { registerModelBinding } from './model-binding'
|
|
11
|
-
import { registerOptimizedRouteMatching } from './optimized-route-matching'
|
|
12
|
-
import { registerRouteBuilding } from './route-building'
|
|
13
|
-
import { registerRouteMatching } from './route-matching'
|
|
14
|
-
import { Router } from './router'
|
|
15
|
-
import { registerServerHandling } from './server'
|
|
16
|
-
import { registerViewRendering } from './view-rendering'
|
|
17
|
-
import { registerWebSocketHandling } from './websocket'
|
|
18
|
-
import '../types' // Import types for type augmentation
|
|
19
|
-
|
|
20
|
-
// Register all the extensions to the Router class
|
|
21
|
-
registerHttpMethods(Router)
|
|
22
|
-
registerRedirectMethods(Router)
|
|
23
|
-
registerRouteMatching(Router)
|
|
24
|
-
registerOptimizedRouteMatching(Router) // Override with optimized version
|
|
25
|
-
registerMiddlewareHandling(Router)
|
|
26
|
-
registerViewRendering(Router)
|
|
27
|
-
registerWebSocketHandling(Router)
|
|
28
|
-
registerFileStreaming(Router)
|
|
29
|
-
registerGroupOrganization(Router)
|
|
30
|
-
registerServerHandling(Router)
|
|
31
|
-
registerRouteBuilding(Router)
|
|
32
|
-
registerModelBinding(Router)
|
|
33
|
-
registerFileBasedRouting(Router)
|
|
34
|
-
registerApiRoutes(Router)
|
|
35
|
-
|
|
36
|
-
// Export the Router class, the standalone request-enhancement helper, and
|
|
37
|
-
// fluent routing features.
|
|
38
|
-
export { Router }
|
|
39
|
-
export { applyRequestEnhancements } from './router'
|
|
40
|
-
|
|
41
|
-
// Type augmentation for Laravel-style methods
|
|
42
|
-
declare module './router' {
|
|
43
|
-
interface Router {
|
|
44
|
-
// Laravel-style streaming methods
|
|
45
|
-
stream: (
|
|
46
|
-
callback: () => Generator<string | Uint8Array, void, unknown> | AsyncGenerator<string | Uint8Array, void, unknown>,
|
|
47
|
-
status?: number,
|
|
48
|
-
headers?: Record<string, string>
|
|
49
|
-
) => Response
|
|
50
|
-
|
|
51
|
-
streamJson: <T>(
|
|
52
|
-
data: Record<string, Iterable<T> | AsyncIterable<T>>,
|
|
53
|
-
status?: number,
|
|
54
|
-
headers?: Record<string, string>
|
|
55
|
-
) => Response
|
|
56
|
-
|
|
57
|
-
eventStream: <_T = any>(
|
|
58
|
-
callback: () => Generator<{ data: any, event?: string, id?: string, retry?: number }, void, unknown> | AsyncGenerator<{ data: any, event?: string, id?: string, retry?: number }, void, unknown>,
|
|
59
|
-
headers?: Record<string, string>
|
|
60
|
-
) => Response
|
|
61
|
-
|
|
62
|
-
streamDownload: (
|
|
63
|
-
callback: () => Generator<string | Uint8Array, void, unknown> | AsyncGenerator<string | Uint8Array, void, unknown>,
|
|
64
|
-
filename: string,
|
|
65
|
-
headers?: Record<string, string>
|
|
66
|
-
) => Response
|
|
67
|
-
|
|
68
|
-
streamFile: (
|
|
69
|
-
filePath: string,
|
|
70
|
-
request: any,
|
|
71
|
-
options?: {
|
|
72
|
-
contentType?: string
|
|
73
|
-
enableRanges?: boolean
|
|
74
|
-
chunkSize?: number
|
|
75
|
-
}
|
|
76
|
-
) => Promise<Response>
|
|
77
|
-
|
|
78
|
-
streamFileWithRanges: (filePath: string, req: any) => Promise<Response>
|
|
79
|
-
|
|
80
|
-
streamResponse: (
|
|
81
|
-
generator: () => AsyncGenerator<string | Uint8Array, void, unknown>,
|
|
82
|
-
options?: { headers?: Record<string, string>, status?: number }
|
|
83
|
-
) => Response
|
|
84
|
-
|
|
85
|
-
transformStream: (
|
|
86
|
-
transformer: (chunk: string | Uint8Array) => string | Uint8Array | Promise<string | Uint8Array>,
|
|
87
|
-
options?: { headers?: Record<string, string>, status?: number }
|
|
88
|
-
) => (req: Request) => Response
|
|
89
|
-
|
|
90
|
-
// Laravel-style model binding methods
|
|
91
|
-
model: <T>(
|
|
92
|
-
key: string,
|
|
93
|
-
modelClass: string | ((_value: string) => Promise<T | null>),
|
|
94
|
-
callback?: (model: T | null) => Response | null
|
|
95
|
-
) => Router
|
|
96
|
-
|
|
97
|
-
implicitBinding: () => any
|
|
98
|
-
|
|
99
|
-
missing: (callback: (req: any) => Response) => any
|
|
100
|
-
|
|
101
|
-
scopedBindings: (bindings: Record<string, string>) => any
|
|
102
|
-
|
|
103
|
-
clearModelCache: (modelName?: string) => Router
|
|
104
|
-
|
|
105
|
-
getModelStats: () => {
|
|
106
|
-
totalEntries: number
|
|
107
|
-
validEntries: number
|
|
108
|
-
expiredEntries: number
|
|
109
|
-
models: number
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
readonly modelRegistry: {
|
|
113
|
-
has: (name: string) => boolean
|
|
114
|
-
register: <_T>(name: string, config: any) => void
|
|
115
|
-
resolve: <_T>(modelName: string, params: Record<string, string>, req?: any) => Promise<any>
|
|
116
|
-
createErrorResponse: (modelName: string, result: any, params: Record<string, string>) => Response
|
|
117
|
-
clearCache: (modelName: string, params?: Record<string, string>) => void
|
|
118
|
-
clearAllCache: () => void
|
|
119
|
-
getCacheStats: () => any
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Optimized route matching methods
|
|
123
|
-
matchRoute: (path: string, method: string, domain?: string) => { route: Route, params: Record<string, string> } | undefined
|
|
124
|
-
getAllowedMethods: (path: string, domain?: string) => string[]
|
|
125
|
-
clearRouteCache: () => void
|
|
126
|
-
getCacheStats: () => any
|
|
127
|
-
getRouteStats: () => any
|
|
128
|
-
warmRouteCache: (commonPaths: Array<{ path: string, method: string }>) => void
|
|
129
|
-
getRoutesByMethod: () => any
|
|
130
|
-
getRouteConflicts: () => any
|
|
131
|
-
rebuildRouteCompiler: () => void
|
|
132
|
-
optimizeRoutes: (usageStats?: Record<string, number>) => void
|
|
133
|
-
addRouteToCompiler: (route: Route) => void
|
|
134
|
-
initializeRouteCompiler: () => void
|
|
135
|
-
|
|
136
|
-
// Health check method
|
|
137
|
-
health: () => Router
|
|
138
|
-
|
|
139
|
-
// View rendering methods
|
|
140
|
-
renderView: (view: string, data?: Record<string, any>, options?: { layout?: string }) => Promise<string>
|
|
141
|
-
view: (path: string, view: string, data?: Record<string, any>, options?: { layout?: string, status?: number, headers?: Record<string, string> }) => Router
|
|
142
|
-
|
|
143
|
-
// Keep the most recently registered route off the native route table
|
|
144
|
-
withoutNativeDispatch: () => Router
|
|
145
|
-
|
|
146
|
-
// Route constraint methods
|
|
147
|
-
where: ((_param: string, _pattern: string | RegExp) => Router) & ((constraints: Record<string, string | RegExp>) => Router)
|
|
148
|
-
whereNumber: (param: string) => Router
|
|
149
|
-
whereAlpha: (param: string) => Router
|
|
150
|
-
whereAlphaNumeric: (param: string) => Router
|
|
151
|
-
whereUuid: (param: string) => Router
|
|
152
|
-
whereIn: (param: string, values: string[]) => Router
|
|
153
|
-
|
|
154
|
-
// Domain routing
|
|
155
|
-
domain: (domain: string, callback: () => void) => Router
|
|
156
|
-
|
|
157
|
-
// RESTful resource routing
|
|
158
|
-
resource: (name: string, handlers: {
|
|
159
|
-
index?: ActionHandler
|
|
160
|
-
show?: ActionHandler
|
|
161
|
-
store?: ActionHandler
|
|
162
|
-
update?: ActionHandler
|
|
163
|
-
destroy?: ActionHandler
|
|
164
|
-
create?: ActionHandler
|
|
165
|
-
edit?: ActionHandler
|
|
166
|
-
}) => Router
|
|
167
|
-
|
|
168
|
-
// HTTP HEAD method (GET routes already answer HEAD automatically)
|
|
169
|
-
head: (path: string, handler: ActionHandler, type?: 'api' | 'web', name?: string, middleware?: any[]) => Router
|
|
170
|
-
|
|
171
|
-
// Redirect and utility methods
|
|
172
|
-
onError: (handler: (error: Error) => Response | Promise<Response>) => Router
|
|
173
|
-
redirect: (url: string, status?: 301 | 302 | 303 | 307 | 308) => Response
|
|
174
|
-
permanentRedirect: (url: string) => Response
|
|
175
|
-
fallback: (handler: ActionHandler) => Router
|
|
176
|
-
route: (name: string, params?: Record<string, string>) => string
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
export { Dependencies, FluentRouteBuilder, FluentRouter, globalMiddlewarePipeline, MiddlewareFactory, MiddlewarePipeline, RouteFactory, router, RouterUtils, SkipConditions }
|
|
180
|
-
|
|
181
|
-
// Export routing features
|
|
182
|
-
export * from '../routing/route-caching'
|
|
183
|
-
export * from '../routing/route-throttling'
|
|
184
|
-
export * from '../routing/subdomain-routing'
|
|
185
|
-
|
|
186
|
-
// Export handler resolution utilities
|
|
187
|
-
export { createHandlerResolver, resolveHandler, wrapResponse } from './handler-resolver'
|
|
188
|
-
|
|
189
|
-
// Export validation integration
|
|
190
|
-
export * from './validation-integration'
|
|
191
|
-
|
|
192
|
-
// Export file-based routing
|
|
193
|
-
export type { DiscoveredRoute, FileBasedRoutingConfig } from './file-based-routing'
|