@stacksjs/bun-router 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/dist/auth.d.ts +134 -0
  2. package/dist/cache/lru-cache.d.ts +139 -0
  3. package/dist/cache/middleware-memoization.d.ts +151 -0
  4. package/dist/cache/route-cache-warmer.d.ts +161 -0
  5. package/dist/cache/sqlite-cache.d.ts +209 -0
  6. package/dist/cache/streaming-cache.d.ts +132 -0
  7. package/dist/cli/colors.d.ts +15 -0
  8. package/dist/cli/index.d.ts +10 -0
  9. package/dist/cli/middleware.d.ts +31 -0
  10. package/dist/cli/openapi.d.ts +17 -0
  11. package/dist/cli/router.d.ts +15 -0
  12. package/dist/cli/routes.d.ts +29 -0
  13. package/dist/cli/utils.d.ts +74 -0
  14. package/dist/cli.d.ts +1 -1
  15. package/dist/cli.js +1 -1
  16. package/dist/config.d.ts +7 -0
  17. package/dist/container/container.d.ts +273 -0
  18. package/dist/container/contextual-binding.d.ts +240 -0
  19. package/dist/container/decorators.d.ts +141 -0
  20. package/dist/container/service-provider.d.ts +285 -0
  21. package/dist/development/hot-reload.d.ts +187 -0
  22. package/dist/development/index.d.ts +167 -0
  23. package/dist/development/performance-profiler.d.ts +217 -0
  24. package/dist/development/route-debugger.d.ts +154 -0
  25. package/dist/development/route-inspector.d.ts +211 -0
  26. package/dist/development/typescript-utilities.d.ts +209 -0
  27. package/dist/docs.d.ts +11 -0
  28. package/dist/errors/circuit-breaker.d.ts +195 -0
  29. package/dist/errors/error-handler.d.ts +88 -0
  30. package/dist/errors/error-reporting.d.ts +144 -0
  31. package/dist/errors/exceptions.d.ts +184 -0
  32. package/dist/errors/graceful-degradation.d.ts +154 -0
  33. package/dist/errors/index.d.ts +9 -0
  34. package/dist/errors/router-errors.d.ts +110 -0
  35. package/dist/file-serving/static-files.d.ts +143 -0
  36. package/dist/index.d.ts +2 -0
  37. package/dist/index.js +319 -205
  38. package/dist/middleware/auth.d.ts +63 -0
  39. package/dist/middleware/content_security_policy.d.ts +53 -0
  40. package/dist/middleware/cors.d.ts +5 -0
  41. package/dist/middleware/csrf.d.ts +7 -0
  42. package/dist/middleware/ddos_protection.d.ts +39 -0
  43. package/dist/middleware/file_security.d.ts +26 -0
  44. package/dist/middleware/file_upload.d.ts +38 -0
  45. package/dist/middleware/helmet.d.ts +54 -0
  46. package/dist/middleware/index.d.ts +44 -0
  47. package/dist/middleware/input_validation.d.ts +45 -0
  48. package/dist/middleware/json_body.d.ts +4 -0
  49. package/dist/middleware/performance_alerting.d.ts +87 -0
  50. package/dist/middleware/performance_dashboard.d.ts +87 -0
  51. package/dist/middleware/performance_monitor.d.ts +209 -0
  52. package/dist/middleware/pipeline.d.ts +131 -0
  53. package/dist/middleware/rate_limit.d.ts +36 -0
  54. package/dist/middleware/request_id.d.ts +4 -0
  55. package/dist/middleware/request_signing.d.ts +153 -0
  56. package/dist/middleware/request_tracer.d.ts +72 -0
  57. package/dist/middleware/response_cache.d.ts +97 -0
  58. package/dist/middleware/security.d.ts +69 -0
  59. package/dist/middleware/security_suite.d.ts +46 -0
  60. package/dist/middleware/session.d.ts +23 -0
  61. package/dist/model-binding/index.d.ts +2 -0
  62. package/dist/model-binding/model-middleware.d.ts +118 -0
  63. package/dist/model-binding/model-registry.d.ts +164 -0
  64. package/dist/model-binding.d.ts +185 -0
  65. package/dist/model-resolver-factory.d.ts +31 -0
  66. package/dist/observability/correlation.d.ts +187 -0
  67. package/dist/observability/health-checks.d.ts +186 -0
  68. package/dist/observability/index.d.ts +60 -0
  69. package/dist/observability/integration.d.ts +147 -0
  70. package/dist/observability/metrics.d.ts +184 -0
  71. package/dist/observability/tracing.d.ts +187 -0
  72. package/dist/optimization/bun-utilities.d.ts +224 -0
  73. package/dist/query-builder-integration.d.ts +36 -0
  74. package/dist/request/context.d.ts +34 -0
  75. package/dist/request/enhanced-request.d.ts +213 -0
  76. package/dist/request/macros.d.ts +300 -0
  77. package/dist/response/macros.d.ts +245 -0
  78. package/dist/response/response-factory.d.ts +133 -0
  79. package/dist/router/api-routes.d.ts +5 -0
  80. package/dist/router/file-based-routing.d.ts +118 -0
  81. package/dist/router/file-streaming.d.ts +5 -0
  82. package/dist/router/fluent-router.d.ts +315 -0
  83. package/dist/router/fluent-routing.d.ts +271 -0
  84. package/dist/router/group-organization.d.ts +5 -0
  85. package/dist/router/handler-resolver.d.ts +24 -0
  86. package/dist/router/http-methods.d.ts +10 -0
  87. package/dist/router/index.d.ts +113 -0
  88. package/dist/router/middleware-groups.d.ts +94 -0
  89. package/dist/router/middleware-integration.d.ts +112 -0
  90. package/dist/router/middleware.d.ts +5 -0
  91. package/dist/router/model-binding.d.ts +5 -0
  92. package/dist/router/optimized-route-matching.d.ts +6 -0
  93. package/dist/router/route-building.d.ts +5 -0
  94. package/dist/router/route-compiler.d.ts +153 -0
  95. package/dist/router/route-matching.d.ts +5 -0
  96. package/dist/router/route-trie.d.ts +114 -0
  97. package/dist/router/router.d.ts +276 -0
  98. package/dist/router/server.d.ts +5 -0
  99. package/dist/router/validation-integration.d.ts +170 -0
  100. package/dist/router/view-rendering.d.ts +5 -0
  101. package/dist/router/websocket.d.ts +5 -0
  102. package/dist/routing/route-caching.d.ts +129 -0
  103. package/dist/routing/route-throttling.d.ts +150 -0
  104. package/dist/routing/subdomain-routing.d.ts +206 -0
  105. package/dist/session/database-store.d.ts +51 -0
  106. package/dist/session/file-store.d.ts +22 -0
  107. package/dist/session/index.d.ts +106 -0
  108. package/dist/session/memory-store.d.ts +21 -0
  109. package/dist/session/redis-store.d.ts +31 -0
  110. package/dist/streaming/index.d.ts +3 -0
  111. package/dist/streaming/sse-handler.d.ts +138 -0
  112. package/dist/streaming/stream-handler.d.ts +114 -0
  113. package/dist/testing/auth-testing.d.ts +156 -0
  114. package/dist/testing/file-upload-testing.d.ts +190 -0
  115. package/dist/testing/index.d.ts +10 -0
  116. package/dist/testing/middleware-testing.d.ts +138 -0
  117. package/dist/testing/model-binding-testing.d.ts +186 -0
  118. package/dist/testing/performance-testing.d.ts +235 -0
  119. package/dist/testing/test-client.d.ts +117 -0
  120. package/dist/testing/test-request.d.ts +85 -0
  121. package/dist/testing/test-response.d.ts +90 -0
  122. package/dist/testing/types.d.ts +207 -0
  123. package/dist/testing/websocket-testing.d.ts +227 -0
  124. package/dist/types/controller-types.d.ts +208 -0
  125. package/dist/types/core.d.ts +543 -0
  126. package/dist/types/middleware-types.d.ts +227 -0
  127. package/dist/types/request-response-augmentation.d.ts +261 -0
  128. package/dist/types/route-inference.d.ts +168 -0
  129. package/dist/types.d.ts +1776 -0
  130. package/dist/url.d.ts +56 -0
  131. package/dist/utils/index.d.ts +1 -0
  132. package/dist/utils/query-preservation.d.ts +48 -0
  133. package/dist/utils.d.ts +69 -0
  134. package/dist/validation/validator.d.ts +140 -0
  135. package/dist/websocket/clustering.d.ts +185 -0
  136. package/package.json +3 -2
  137. package/src/auth.ts +469 -0
  138. package/src/cache/lru-cache.ts +457 -0
  139. package/src/cache/middleware-memoization.ts +531 -0
  140. package/src/cache/route-cache-warmer.ts +486 -0
  141. package/src/cache/sqlite-cache.ts +783 -0
  142. package/src/cache/streaming-cache.ts +572 -0
  143. package/src/cli/colors.ts +29 -0
  144. package/src/cli/index.ts +287 -0
  145. package/src/cli/middleware.ts +291 -0
  146. package/src/cli/openapi.ts +407 -0
  147. package/src/cli/router.ts +188 -0
  148. package/src/cli/routes.ts +265 -0
  149. package/src/cli/utils.ts +531 -0
  150. package/src/cli.ts +5 -0
  151. package/src/config.ts +322 -0
  152. package/src/container/container.ts +740 -0
  153. package/src/container/contextual-binding.ts +603 -0
  154. package/src/container/decorators.ts +359 -0
  155. package/src/container/service-provider.ts +596 -0
  156. package/src/development/hot-reload.ts +673 -0
  157. package/src/development/index.ts +499 -0
  158. package/src/development/performance-profiler.ts +717 -0
  159. package/src/development/route-debugger.ts +527 -0
  160. package/src/development/route-inspector.ts +749 -0
  161. package/src/development/typescript-utilities.ts +678 -0
  162. package/src/docs.ts +397 -0
  163. package/src/errors/circuit-breaker.ts +732 -0
  164. package/src/errors/error-handler.ts +569 -0
  165. package/src/errors/error-reporting.ts +672 -0
  166. package/src/errors/exceptions.ts +536 -0
  167. package/src/errors/graceful-degradation.ts +621 -0
  168. package/src/errors/index.ts +21 -0
  169. package/src/errors/router-errors.ts +632 -0
  170. package/src/file-serving/static-files.ts +581 -0
  171. package/src/index.ts +14 -0
  172. package/src/middleware/auth.ts +219 -0
  173. package/src/middleware/content_security_policy.ts +215 -0
  174. package/src/middleware/cors.ts +74 -0
  175. package/src/middleware/csrf.ts +108 -0
  176. package/src/middleware/ddos_protection.ts +255 -0
  177. package/src/middleware/file_security.ts +191 -0
  178. package/src/middleware/file_upload.ts +264 -0
  179. package/src/middleware/helmet.ts +268 -0
  180. package/src/middleware/index.ts +117 -0
  181. package/src/middleware/input_validation.ts +449 -0
  182. package/src/middleware/json_body.ts +37 -0
  183. package/src/middleware/performance_alerting.ts +538 -0
  184. package/src/middleware/performance_dashboard.ts +661 -0
  185. package/src/middleware/performance_monitor.ts +943 -0
  186. package/src/middleware/pipeline.ts +489 -0
  187. package/src/middleware/rate_limit.ts +245 -0
  188. package/src/middleware/request_id.ts +36 -0
  189. package/src/middleware/request_signing.ts +636 -0
  190. package/src/middleware/request_tracer.ts +636 -0
  191. package/src/middleware/response_cache.ts +743 -0
  192. package/src/middleware/security.ts +482 -0
  193. package/src/middleware/security_suite.ts +257 -0
  194. package/src/middleware/session.ts +91 -0
  195. package/src/model-binding/index.ts +18 -0
  196. package/src/model-binding/model-middleware.ts +425 -0
  197. package/src/model-binding/model-registry.ts +550 -0
  198. package/src/model-binding.ts +370 -0
  199. package/src/model-resolver-factory.ts +106 -0
  200. package/src/observability/correlation.ts +691 -0
  201. package/src/observability/health-checks.ts +729 -0
  202. package/src/observability/index.ts +184 -0
  203. package/src/observability/integration.ts +548 -0
  204. package/src/observability/metrics.ts +753 -0
  205. package/src/observability/tracing.ts +638 -0
  206. package/src/optimization/bun-utilities.ts +778 -0
  207. package/src/query-builder-integration.ts +137 -0
  208. package/src/request/context.ts +62 -0
  209. package/src/request/enhanced-request.ts +857 -0
  210. package/src/request/macros.ts +688 -0
  211. package/src/response/macros.ts +612 -0
  212. package/src/response/response-factory.ts +588 -0
  213. package/src/router/api-routes.ts +243 -0
  214. package/src/router/file-based-routing.ts +670 -0
  215. package/src/router/file-streaming.ts +372 -0
  216. package/src/router/fluent-router.ts +927 -0
  217. package/src/router/fluent-routing.ts +797 -0
  218. package/src/router/group-organization.ts +213 -0
  219. package/src/router/handler-resolver.ts +291 -0
  220. package/src/router/http-methods.ts +377 -0
  221. package/src/router/index.ts +185 -0
  222. package/src/router/middleware-groups.ts +222 -0
  223. package/src/router/middleware-integration.ts +399 -0
  224. package/src/router/middleware.ts +231 -0
  225. package/src/router/model-binding.ts +215 -0
  226. package/src/router/optimized-route-matching.ts +253 -0
  227. package/src/router/route-building.ts +212 -0
  228. package/src/router/route-compiler.ts +702 -0
  229. package/src/router/route-matching.ts +349 -0
  230. package/src/router/route-trie.ts +464 -0
  231. package/src/router/router.ts +1508 -0
  232. package/src/router/server.ts +406 -0
  233. package/src/router/validation-integration.ts +443 -0
  234. package/src/router/view-rendering.ts +233 -0
  235. package/src/router/websocket.ts +100 -0
  236. package/src/routing/route-caching.ts +402 -0
  237. package/src/routing/route-throttling.ts +469 -0
  238. package/src/routing/subdomain-routing.ts +492 -0
  239. package/src/session/database-store.ts +109 -0
  240. package/src/session/file-store.ts +148 -0
  241. package/src/session/index.ts +244 -0
  242. package/src/session/memory-store.ts +88 -0
  243. package/src/session/redis-store.ts +93 -0
  244. package/src/streaming/index.ts +17 -0
  245. package/src/streaming/sse-handler.ts +482 -0
  246. package/src/streaming/stream-handler.ts +552 -0
  247. package/src/testing/auth-testing.ts +446 -0
  248. package/src/testing/file-upload-testing.ts +543 -0
  249. package/src/testing/index.ts +10 -0
  250. package/src/testing/middleware-testing.ts +322 -0
  251. package/src/testing/model-binding-testing.ts +645 -0
  252. package/src/testing/performance-testing.ts +738 -0
  253. package/src/testing/test-client.ts +310 -0
  254. package/src/testing/test-request.ts +315 -0
  255. package/src/testing/test-response.ts +332 -0
  256. package/src/testing/types.ts +224 -0
  257. package/src/testing/websocket-testing.ts +590 -0
  258. package/src/types/controller-types.ts +385 -0
  259. package/src/types/core.ts +683 -0
  260. package/src/types/middleware-types.ts +419 -0
  261. package/src/types/request-response-augmentation.ts +489 -0
  262. package/src/types/route-inference.ts +357 -0
  263. package/src/types.ts +2049 -0
  264. package/src/url.ts +126 -0
  265. package/src/utils/index.ts +1 -0
  266. package/src/utils/query-preservation.ts +201 -0
  267. package/src/utils.ts +327 -0
  268. package/src/validation/validator.ts +685 -0
  269. package/src/websocket/clustering.ts +762 -0
@@ -0,0 +1,349 @@
1
+ import type { HTTPMethod, MatchResult, Route } from '../types'
2
+ import type { Router } from './router'
3
+ import { matchPath } from '../utils'
4
+
5
+ /**
6
+ * Route matching extension for Router class
7
+ */
8
+ export function registerRouteMatching(RouterClass: typeof Router): void {
9
+ Object.defineProperties(RouterClass.prototype, {
10
+ /**
11
+ * Match a route based on the path, method, and domain
12
+ */
13
+ matchRoute: {
14
+ value(path: string, method: HTTPMethod, domain?: string): MatchResult | undefined {
15
+ const url = new URL(path, 'http://localhost')
16
+
17
+ // Generate cache key
18
+ const cacheKey = `${domain || ''}:${method}:${url.pathname}`
19
+
20
+ // Check cache first
21
+ if (this.routeCache.has(cacheKey)) {
22
+ return this.routeCache.get(cacheKey)
23
+ }
24
+
25
+ // Fast path for static routes
26
+ if (this.staticRoutes.has(method)) {
27
+ const staticRoute = this.staticRoutes.get(method)!.get(url.pathname)
28
+ if (staticRoute && (!domain || !staticRoute.domain || staticRoute.domain === domain)) {
29
+ const result = {
30
+ route: staticRoute,
31
+ params: {},
32
+ }
33
+ this.routeCache.set(cacheKey, result)
34
+ return result
35
+ }
36
+ }
37
+
38
+ // Get potential routes - either all routes or domain-specific routes
39
+ const potentialRoutes: Route[] = domain && this.domains[domain]
40
+ ? this.domains[domain]
41
+ : this.routes
42
+
43
+ // Filter routes to only those matching the HTTP method
44
+ const methodRoutes = potentialRoutes.filter((route: Route) => route.method === method)
45
+
46
+ // First, try to find an exact match
47
+ for (const route of methodRoutes) {
48
+ if (route.path === url.pathname) {
49
+ const result = {
50
+ route,
51
+ params: {},
52
+ }
53
+ this.routeCache.set(cacheKey, result)
54
+ return result
55
+ }
56
+ }
57
+
58
+ // If no exact match, try matching patterns
59
+ for (const route of methodRoutes) {
60
+ if (route.pattern) {
61
+ const match = route.pattern.exec(url)
62
+ if (match) {
63
+ const result = {
64
+ route,
65
+ params: match.pathname.groups,
66
+ }
67
+ this.routeCache.set(cacheKey, result)
68
+ return result
69
+ }
70
+ }
71
+ }
72
+
73
+ // If still no match, try domain-specific * (wildcard) routes
74
+ if (domain && this.domains[domain]) {
75
+ const wildcardRoutes = this.domains[domain].filter((route: Route) =>
76
+ route.method === method && route.path.endsWith('*'),
77
+ )
78
+
79
+ for (const route of wildcardRoutes) {
80
+ const basePath = route.path.slice(0, -1) // Remove the '*'
81
+ if (url.pathname.startsWith(basePath)) {
82
+ const result = {
83
+ route,
84
+ params: {
85
+ wildcard: url.pathname.slice(basePath.length),
86
+ },
87
+ }
88
+ this.routeCache.set(cacheKey, result)
89
+ return result
90
+ }
91
+ }
92
+ }
93
+
94
+ // If no match in domain-specific routes, try global wildcard routes
95
+ const globalWildcardRoutes = this.routes.filter((route: Route) =>
96
+ route.method === method && route.path.endsWith('*') && (!domain || !route.domain),
97
+ )
98
+
99
+ for (const route of globalWildcardRoutes) {
100
+ const basePath = route.path.slice(0, -1) // Remove the '*'
101
+ if (url.pathname.startsWith(basePath)) {
102
+ const result = {
103
+ route,
104
+ params: {
105
+ wildcard: url.pathname.slice(basePath.length),
106
+ },
107
+ }
108
+ this.routeCache.set(cacheKey, result)
109
+ return result
110
+ }
111
+ }
112
+
113
+ // If no match for specific method, try HEAD for GET requests
114
+ if (method === 'HEAD') {
115
+ return this.matchRoute(path, 'GET', domain)
116
+ }
117
+
118
+ // Try to match any OPTIONS requests to a generic options handler or to a matching route of another method
119
+ if (method === 'OPTIONS') {
120
+ // Check if we have a specific OPTIONS handler first
121
+ const optionsMatch = potentialRoutes.find((route: Route) =>
122
+ route.method === 'OPTIONS' && route.path === '*',
123
+ )
124
+
125
+ if (optionsMatch) {
126
+ const result = {
127
+ route: optionsMatch,
128
+ params: {},
129
+ }
130
+ this.routeCache.set(cacheKey, result)
131
+ return result
132
+ }
133
+
134
+ // Check if the path matches any route of another method
135
+ for (const otherMethod of ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']) {
136
+ const match = this.matchRoute(path, otherMethod as HTTPMethod, domain)
137
+ if (match) {
138
+ // We found a route that matches this path with another method,
139
+ // so this is a valid OPTIONS request
140
+ const result = {
141
+ route: {
142
+ ...match.route,
143
+ method: 'OPTIONS',
144
+ handler: (_req: Request) => new Response(null, { status: 204 }),
145
+ },
146
+ params: match.params,
147
+ }
148
+ this.routeCache.set(cacheKey, result)
149
+ return result
150
+ }
151
+ }
152
+ }
153
+
154
+ // No matching route found
155
+ return undefined
156
+ },
157
+ writable: true,
158
+ configurable: true,
159
+ },
160
+
161
+ /**
162
+ * Match a domain pattern against a hostname
163
+ */
164
+ matchDomain: {
165
+ value(pattern: string, hostname: string): boolean {
166
+ // Exact match
167
+ if (pattern === hostname) {
168
+ return true
169
+ }
170
+
171
+ // Wildcard subdomains (*.example.com)
172
+ if (pattern.startsWith('*.')) {
173
+ const domain = pattern.substring(2)
174
+ return hostname === domain || hostname.endsWith(`.${domain}`)
175
+ }
176
+
177
+ // Dynamic parameters ({subdomain}.example.com)
178
+ if (pattern.includes('{')) {
179
+ let regex: RegExp
180
+ if (!this.domainPatternCache.has(pattern)) {
181
+ const regexStr = pattern.replace(/\./g, '\\.').replace(/\{[^}]+\}/g, '([^.]+)')
182
+ regex = new RegExp(`^${regexStr}$`)
183
+ this.domainPatternCache.set(pattern, regex)
184
+ }
185
+ else {
186
+ regex = this.domainPatternCache.get(pattern)!
187
+ }
188
+ return regex.test(hostname)
189
+ }
190
+
191
+ return false
192
+ },
193
+ writable: true,
194
+ configurable: true,
195
+ },
196
+
197
+ /**
198
+ * Extract domain parameters from a hostname
199
+ */
200
+ extractDomainParams: {
201
+ value(pattern: string, hostname: string): Record<string, string> {
202
+ const params: Record<string, string> = {}
203
+
204
+ if (!pattern.includes('{')) {
205
+ return params
206
+ }
207
+
208
+ const paramNames = pattern.match(/\{([^}]+)\}/g)?.map(p => p.substring(1, p.length - 1)) || []
209
+ const regex = pattern.replace(/\./g, '\\.').replace(/\{[^}]+\}/g, '([^.]+)')
210
+ const matches = hostname.match(new RegExp(`^${regex}$`))
211
+
212
+ if (matches && matches.length > 1) {
213
+ for (let i = 0; i < paramNames.length; i++) {
214
+ params[paramNames[i]] = matches[i + 1]
215
+ }
216
+ }
217
+
218
+ return params
219
+ },
220
+ writable: true,
221
+ configurable: true,
222
+ },
223
+
224
+ /**
225
+ * Apply pattern constraints to routes
226
+ */
227
+ pattern: {
228
+ value(name: string, pattern: string): Router {
229
+ this.patterns.set(name, pattern)
230
+ return this
231
+ },
232
+ writable: true,
233
+ configurable: true,
234
+ },
235
+
236
+ /**
237
+ * Apply constraints to route parameters
238
+ */
239
+ where: {
240
+ value(params: Record<string, string>): Router {
241
+ // Apply to the most recently added route(s)
242
+ const lastRoute = this.routes[this.routes.length - 1]
243
+ if (lastRoute) {
244
+ // Update constraints
245
+ lastRoute.constraints = { ...(lastRoute.constraints || {}), ...params }
246
+
247
+ // Regenerate the route pattern with the new constraints
248
+ const routePath = lastRoute.path
249
+ const constraintsRecord = lastRoute.constraints && !Array.isArray(lastRoute.constraints)
250
+ ? lastRoute.constraints as Record<string, string>
251
+ : undefined
252
+
253
+ // Recreate the pattern with the updated constraints
254
+ lastRoute.pattern = {
255
+ exec: (url: URL): { pathname: { groups: Record<string, string> } } | null => {
256
+ const params: Record<string, string> = {}
257
+ const isMatch = matchPath(routePath, url.pathname, params, constraintsRecord)
258
+
259
+ if (!isMatch) {
260
+ return null
261
+ }
262
+
263
+ return {
264
+ pathname: {
265
+ groups: params,
266
+ },
267
+ }
268
+ },
269
+ }
270
+
271
+ // Clear route cache when constraints are added
272
+ this.routeCache.clear()
273
+
274
+ // Force recompilation of the route in the trie
275
+ if (this.routeCompiler) {
276
+ // We need to completely rebuild the trie to ensure constraints are applied
277
+ // This is more reliable than trying to selectively update just one route
278
+ const allRoutes = [...this.routes]
279
+ this.routeCompiler.clear()
280
+
281
+ // Re-add all routes to ensure proper ordering and constraint application
282
+ for (const route of allRoutes) {
283
+ this.routeCompiler.addRoute(route)
284
+ }
285
+ }
286
+ }
287
+
288
+ return this
289
+ },
290
+ writable: true,
291
+ configurable: true,
292
+ },
293
+
294
+ /**
295
+ * Apply a numeric constraint to a parameter
296
+ */
297
+ whereNumber: {
298
+ value(param: string): Router {
299
+ return this.where({ [param]: '\\d+' })
300
+ },
301
+ writable: true,
302
+ configurable: true,
303
+ },
304
+
305
+ /**
306
+ * Apply an alphabetic constraint to a parameter
307
+ */
308
+ whereAlpha: {
309
+ value(param: string): Router {
310
+ return this.where({ [param]: '[A-Za-z]+' })
311
+ },
312
+ writable: true,
313
+ configurable: true,
314
+ },
315
+
316
+ /**
317
+ * Apply an alphanumeric constraint to a parameter
318
+ */
319
+ whereAlphaNumeric: {
320
+ value(param: string): Router {
321
+ return this.where({ [param]: '[A-Za-z0-9]+' })
322
+ },
323
+ writable: true,
324
+ configurable: true,
325
+ },
326
+
327
+ /**
328
+ * Apply a UUID constraint to a parameter
329
+ */
330
+ whereUuid: {
331
+ value(param: string): Router {
332
+ return this.where({ [param]: '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' })
333
+ },
334
+ writable: true,
335
+ configurable: true,
336
+ },
337
+
338
+ /**
339
+ * Apply an "in array" constraint to a parameter
340
+ */
341
+ whereIn: {
342
+ value(param: string, values: string[]): Router {
343
+ return this.where({ [param]: values.join('|') })
344
+ },
345
+ writable: true,
346
+ configurable: true,
347
+ },
348
+ })
349
+ }