@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,368 +0,0 @@
|
|
|
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
|
-
// eslint-disable-next-line pickier/no-unused-vars -- false positive: used on the next line
|
|
9
|
-
export function registerRouteMatching(RouterClass: typeof Router): void {
|
|
10
|
-
Object.defineProperties(RouterClass.prototype, {
|
|
11
|
-
/**
|
|
12
|
-
* Match a route based on the path, method, and domain
|
|
13
|
-
*/
|
|
14
|
-
matchRoute: {
|
|
15
|
-
value(path: string, method: HTTPMethod, domain?: string): MatchResult | undefined {
|
|
16
|
-
const url = new URL(path, 'http://localhost')
|
|
17
|
-
|
|
18
|
-
// Generate cache key
|
|
19
|
-
const cacheKey = `${domain || ''}:${method}:${url.pathname}`
|
|
20
|
-
|
|
21
|
-
// Check cache first
|
|
22
|
-
if (this.routeCache.has(cacheKey)) {
|
|
23
|
-
return this.routeCache.get(cacheKey)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Fast path for static routes
|
|
27
|
-
if (this.staticRoutes.has(method)) {
|
|
28
|
-
const staticRoute = this.staticRoutes.get(method)!.get(url.pathname)
|
|
29
|
-
if (staticRoute && (!domain || !staticRoute.domain || staticRoute.domain === domain)) {
|
|
30
|
-
const result = {
|
|
31
|
-
route: staticRoute,
|
|
32
|
-
params: {},
|
|
33
|
-
}
|
|
34
|
-
this.routeCache.set(cacheKey, result)
|
|
35
|
-
return result
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Get potential routes - either all routes or domain-specific routes
|
|
40
|
-
const potentialRoutes: Route[] = domain && this.domains[domain]
|
|
41
|
-
? this.domains[domain]
|
|
42
|
-
: this.routes
|
|
43
|
-
|
|
44
|
-
// Filter routes to only those matching the HTTP method
|
|
45
|
-
const methodRoutes = potentialRoutes.filter((route: Route) => route.method === method)
|
|
46
|
-
|
|
47
|
-
// First, try to find an exact match
|
|
48
|
-
for (const route of methodRoutes) {
|
|
49
|
-
if (route.path === url.pathname) {
|
|
50
|
-
const result = {
|
|
51
|
-
route,
|
|
52
|
-
params: {},
|
|
53
|
-
}
|
|
54
|
-
this.routeCache.set(cacheKey, result)
|
|
55
|
-
return result
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// If no exact match, try matching patterns
|
|
60
|
-
for (const route of methodRoutes) {
|
|
61
|
-
if (route.pattern) {
|
|
62
|
-
const match = route.pattern.exec(url)
|
|
63
|
-
if (match) {
|
|
64
|
-
const result = {
|
|
65
|
-
route,
|
|
66
|
-
params: match.pathname.groups,
|
|
67
|
-
}
|
|
68
|
-
this.routeCache.set(cacheKey, result)
|
|
69
|
-
return result
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// If still no match, try domain-specific * (wildcard) routes
|
|
75
|
-
if (domain && this.domains[domain]) {
|
|
76
|
-
const wildcardRoutes = this.domains[domain].filter((route: Route) =>
|
|
77
|
-
route.method === method && route.path.endsWith('*'),
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
for (const route of wildcardRoutes) {
|
|
81
|
-
const basePath = route.path.slice(0, -1) // Remove the '*'
|
|
82
|
-
if (url.pathname.startsWith(basePath)) {
|
|
83
|
-
const result = {
|
|
84
|
-
route,
|
|
85
|
-
params: {
|
|
86
|
-
wildcard: url.pathname.slice(basePath.length),
|
|
87
|
-
},
|
|
88
|
-
}
|
|
89
|
-
this.routeCache.set(cacheKey, result)
|
|
90
|
-
return result
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// If no match in domain-specific routes, try global wildcard routes
|
|
96
|
-
const globalWildcardRoutes = this.routes.filter((route: Route) =>
|
|
97
|
-
route.method === method && route.path.endsWith('*') && (!domain || !route.domain),
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
for (const route of globalWildcardRoutes) {
|
|
101
|
-
const basePath = route.path.slice(0, -1) // Remove the '*'
|
|
102
|
-
if (url.pathname.startsWith(basePath)) {
|
|
103
|
-
const result = {
|
|
104
|
-
route,
|
|
105
|
-
params: {
|
|
106
|
-
wildcard: url.pathname.slice(basePath.length),
|
|
107
|
-
},
|
|
108
|
-
}
|
|
109
|
-
this.routeCache.set(cacheKey, result)
|
|
110
|
-
return result
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// If no match for specific method, try HEAD for GET requests
|
|
115
|
-
if (method === 'HEAD') {
|
|
116
|
-
return this.matchRoute(path, 'GET', domain)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Try to match any OPTIONS requests to a generic options handler or to a matching route of another method
|
|
120
|
-
if (method === 'OPTIONS') {
|
|
121
|
-
// Check if we have a specific OPTIONS handler first
|
|
122
|
-
const optionsMatch = potentialRoutes.find((route: Route) =>
|
|
123
|
-
route.method === 'OPTIONS' && route.path === '*',
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
if (optionsMatch) {
|
|
127
|
-
const result = {
|
|
128
|
-
route: optionsMatch,
|
|
129
|
-
params: {},
|
|
130
|
-
}
|
|
131
|
-
this.routeCache.set(cacheKey, result)
|
|
132
|
-
return result
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Check if the path matches any route of another method
|
|
136
|
-
for (const otherMethod of ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']) {
|
|
137
|
-
const match = this.matchRoute(path, otherMethod as HTTPMethod, domain)
|
|
138
|
-
if (match) {
|
|
139
|
-
// We found a route that matches this path with another method,
|
|
140
|
-
// so this is a valid OPTIONS request
|
|
141
|
-
const result = {
|
|
142
|
-
route: {
|
|
143
|
-
...match.route,
|
|
144
|
-
method: 'OPTIONS',
|
|
145
|
-
handler: (_req: Request) => new Response(null, { status: 204 }),
|
|
146
|
-
},
|
|
147
|
-
params: match.params,
|
|
148
|
-
}
|
|
149
|
-
this.routeCache.set(cacheKey, result)
|
|
150
|
-
return result
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// No matching route found
|
|
156
|
-
return undefined
|
|
157
|
-
},
|
|
158
|
-
writable: true,
|
|
159
|
-
configurable: true,
|
|
160
|
-
},
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Match a domain pattern against a hostname
|
|
164
|
-
*/
|
|
165
|
-
matchDomain: {
|
|
166
|
-
value(pattern: string, hostname: string): boolean {
|
|
167
|
-
// Exact match
|
|
168
|
-
if (pattern === hostname) {
|
|
169
|
-
return true
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Wildcard subdomains (*.example.com)
|
|
173
|
-
if (pattern.startsWith('*.')) {
|
|
174
|
-
const domain = pattern.substring(2)
|
|
175
|
-
return hostname === domain || hostname.endsWith(`.${domain}`)
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Dynamic parameters ({subdomain}.example.com)
|
|
179
|
-
if (pattern.includes('{')) {
|
|
180
|
-
let regex: RegExp
|
|
181
|
-
if (!this.domainPatternCache.has(pattern)) {
|
|
182
|
-
const regexStr = pattern.replace(/\./g, '\\.').replace(/\{[^}]+\}/g, '([^.]+)')
|
|
183
|
-
regex = new RegExp(`^${regexStr}$`)
|
|
184
|
-
this.domainPatternCache.set(pattern, regex)
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
regex = this.domainPatternCache.get(pattern)!
|
|
188
|
-
}
|
|
189
|
-
return regex.test(hostname)
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return false
|
|
193
|
-
},
|
|
194
|
-
writable: true,
|
|
195
|
-
configurable: true,
|
|
196
|
-
},
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Extract domain parameters from a hostname
|
|
200
|
-
*/
|
|
201
|
-
extractDomainParams: {
|
|
202
|
-
value(pattern: string, hostname: string): Record<string, string> {
|
|
203
|
-
const params: Record<string, string> = {}
|
|
204
|
-
|
|
205
|
-
if (!pattern.includes('{')) {
|
|
206
|
-
return params
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const paramNames = pattern.match(/\{([^}]+)\}/g)?.map(p => p.substring(1, p.length - 1)) || []
|
|
210
|
-
const regex = pattern.replace(/\./g, '\\.').replace(/\{[^}]+\}/g, '([^.]+)')
|
|
211
|
-
const matches = hostname.match(new RegExp(`^${regex}$`))
|
|
212
|
-
|
|
213
|
-
if (matches && matches.length > 1) {
|
|
214
|
-
for (let i = 0; i < paramNames.length; i++) {
|
|
215
|
-
params[paramNames[i]] = matches[i + 1]
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return params
|
|
220
|
-
},
|
|
221
|
-
writable: true,
|
|
222
|
-
configurable: true,
|
|
223
|
-
},
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Apply pattern constraints to routes
|
|
227
|
-
*/
|
|
228
|
-
pattern: {
|
|
229
|
-
value(name: string, pattern: string): Router {
|
|
230
|
-
this.patterns.set(name, pattern)
|
|
231
|
-
return this
|
|
232
|
-
},
|
|
233
|
-
writable: true,
|
|
234
|
-
configurable: true,
|
|
235
|
-
},
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Apply constraints to route parameters
|
|
239
|
-
*/
|
|
240
|
-
where: {
|
|
241
|
-
value(params: Record<string, string>): Router {
|
|
242
|
-
// Apply to the most recently added route(s)
|
|
243
|
-
const lastRoute = this.routes[this.routes.length - 1]
|
|
244
|
-
if (lastRoute) {
|
|
245
|
-
// Update constraints
|
|
246
|
-
lastRoute.constraints = { ...(lastRoute.constraints || {}), ...params }
|
|
247
|
-
|
|
248
|
-
// Regenerate the route pattern with the new constraints
|
|
249
|
-
const routePath = lastRoute.path
|
|
250
|
-
const constraintsRecord = lastRoute.constraints && !Array.isArray(lastRoute.constraints)
|
|
251
|
-
? lastRoute.constraints as Record<string, string>
|
|
252
|
-
: undefined
|
|
253
|
-
|
|
254
|
-
// Recreate the pattern with the updated constraints
|
|
255
|
-
lastRoute.pattern = {
|
|
256
|
-
exec: (url: URL): { pathname: { groups: Record<string, string> } } | null => {
|
|
257
|
-
const params: Record<string, string> = {}
|
|
258
|
-
const isMatch = matchPath(routePath, url.pathname, params, constraintsRecord)
|
|
259
|
-
|
|
260
|
-
if (!isMatch) {
|
|
261
|
-
return null
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
return {
|
|
265
|
-
pathname: {
|
|
266
|
-
groups: params,
|
|
267
|
-
},
|
|
268
|
-
}
|
|
269
|
-
},
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Clear route cache when constraints are added
|
|
273
|
-
this.routeCache.clear()
|
|
274
|
-
|
|
275
|
-
// Force recompilation of the route in the trie
|
|
276
|
-
if (this.routeCompiler) {
|
|
277
|
-
// We need to completely rebuild the trie to ensure constraints are applied
|
|
278
|
-
// This is more reliable than trying to selectively update just one route
|
|
279
|
-
const allRoutes = [...this.routes]
|
|
280
|
-
this.routeCompiler.clear()
|
|
281
|
-
|
|
282
|
-
// Re-add all routes to ensure proper ordering and constraint application
|
|
283
|
-
for (const route of allRoutes) {
|
|
284
|
-
this.routeCompiler.addRoute(route)
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return this
|
|
290
|
-
},
|
|
291
|
-
writable: true,
|
|
292
|
-
configurable: true,
|
|
293
|
-
},
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Keep the most recently registered route on the fetch-handler
|
|
297
|
-
* matcher even when serving with `nativeRoutes: true`. Useful when a
|
|
298
|
-
* route must respect registration-order precedence against an
|
|
299
|
-
* overlapping pattern (Bun's native router resolves by specificity).
|
|
300
|
-
*/
|
|
301
|
-
withoutNativeDispatch: {
|
|
302
|
-
value(): Router {
|
|
303
|
-
const lastRoute = this.routes[this.routes.length - 1]
|
|
304
|
-
if (lastRoute) {
|
|
305
|
-
lastRoute.nativeDispatch = false
|
|
306
|
-
}
|
|
307
|
-
return this
|
|
308
|
-
},
|
|
309
|
-
writable: true,
|
|
310
|
-
configurable: true,
|
|
311
|
-
},
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Apply a numeric constraint to a parameter
|
|
315
|
-
*/
|
|
316
|
-
whereNumber: {
|
|
317
|
-
value(param: string): Router {
|
|
318
|
-
return this.where({ [param]: '\\d+' })
|
|
319
|
-
},
|
|
320
|
-
writable: true,
|
|
321
|
-
configurable: true,
|
|
322
|
-
},
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Apply an alphabetic constraint to a parameter
|
|
326
|
-
*/
|
|
327
|
-
whereAlpha: {
|
|
328
|
-
value(param: string): Router {
|
|
329
|
-
return this.where({ [param]: '[A-Za-z]+' })
|
|
330
|
-
},
|
|
331
|
-
writable: true,
|
|
332
|
-
configurable: true,
|
|
333
|
-
},
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Apply an alphanumeric constraint to a parameter
|
|
337
|
-
*/
|
|
338
|
-
whereAlphaNumeric: {
|
|
339
|
-
value(param: string): Router {
|
|
340
|
-
return this.where({ [param]: '[A-Za-z0-9]+' })
|
|
341
|
-
},
|
|
342
|
-
writable: true,
|
|
343
|
-
configurable: true,
|
|
344
|
-
},
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* Apply a UUID constraint to a parameter
|
|
348
|
-
*/
|
|
349
|
-
whereUuid: {
|
|
350
|
-
value(param: string): Router {
|
|
351
|
-
return this.where({ [param]: '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' })
|
|
352
|
-
},
|
|
353
|
-
writable: true,
|
|
354
|
-
configurable: true,
|
|
355
|
-
},
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Apply an "in array" constraint to a parameter
|
|
359
|
-
*/
|
|
360
|
-
whereIn: {
|
|
361
|
-
value(param: string, values: string[]): Router {
|
|
362
|
-
return this.where({ [param]: values.join('|') })
|
|
363
|
-
},
|
|
364
|
-
writable: true,
|
|
365
|
-
configurable: true,
|
|
366
|
-
},
|
|
367
|
-
})
|
|
368
|
-
}
|