@@ -100,11 +100,18 @@ type Handler<Req extends Schema, Context = unknown> = (
100100 ctx : Context
101101) => Promise < ResponseType >
102102
103+ export type QuerystringMatch = {
104+ key : string
105+ value : string | undefined
106+ }
107+
108+ export type RouteQuery = Record < string , string | undefined >
109+
103110type Route < S extends Schema , Context > = {
104111 method : HTTPMethod
105112 type ?: string
106113 path : string
107- querystringMatches : { key : string ; value : string } [ ]
114+ querystringMatches : QuerystringMatch [ ]
108115 headersMatches : string [ ]
109116 handler ?: Handler < S , Context >
110117 schema : S
@@ -241,7 +248,7 @@ export class Router<Context = unknown, S extends Schema = Schema> {
241248 this . registerRoute ( 'head' , url , options , handler as any )
242249 }
243250
244- parseQueryMatch ( query : string ) {
251+ parseQueryMatch ( query : string ) : QuerystringMatch {
245252 const [ key , value ] = query . split ( '=' )
246253 return { key, value }
247254 }
@@ -262,7 +269,7 @@ export class Router<Context = unknown, S extends Schema = Schema> {
262269
263270 matchRoute (
264271 route : Route < S , Context > ,
265- match : { query : Record < string , string > ; headers : Record < string , string > ; type ?: string }
272+ match : { query : RouteQuery ; headers : Record < string , string > ; type ?: string }
266273 ) {
267274 const isOfType = match . type ? match . type === route . type : route . type === undefined
268275
@@ -294,31 +301,46 @@ export class Router<Context = unknown, S extends Schema = Schema> {
294301 } )
295302 }
296303
297- protected matchQueryString (
298- matches : { key : string ; value : string } [ ] ,
299- received ?: Record < string , string >
300- ) {
301- const keys = Object . keys ( received || { } )
302- if ( keys . length === 0 || ! received ) {
303- return matches . find ( ( m ) => m . key === '*' )
304+ protected matchQueryString ( matches : QuerystringMatch [ ] , received ?: RouteQuery ) {
305+ let hasWildcard = false
306+ for ( const match of matches ) {
307+ if ( match . key === '*' ) {
308+ hasWildcard = true
309+ break
310+ }
304311 }
305312
306- const foundMatches = matches . every ( ( m ) => {
307- const key = Object . keys ( received ) . find ( ( k ) => k === m . key )
308- return (
309- ( m . key === key && m . value !== undefined && m . value === received [ m . key ] ) ||
310- ( m . key === key && m . value === undefined )
311- )
312- } )
313+ if ( ! received ) {
314+ return hasWildcard
315+ }
313316
314- if ( foundMatches ) {
315- return true
317+ let hasReceivedQuery = false
318+ for ( const key in received ) {
319+ if ( Object . prototype . hasOwnProperty . call ( received , key ) ) {
320+ hasReceivedQuery = true
321+ break
322+ }
316323 }
317324
318- if ( ! foundMatches && matches . find ( ( m ) => m . key === '*' ) ) {
319- return true
325+ if ( ! hasReceivedQuery ) {
326+ return hasWildcard
320327 }
321- return false
328+
329+ for ( const match of matches ) {
330+ if ( match . key === '*' ) {
331+ continue
332+ }
333+
334+ if ( ! Object . prototype . hasOwnProperty . call ( received , match . key ) ) {
335+ return hasWildcard
336+ }
337+
338+ if ( match . value !== undefined && match . value !== received [ match . key ] ) {
339+ return hasWildcard
340+ }
341+ }
342+
343+ return true
322344 }
323345}
324346
0 commit comments