@@ -211,14 +211,6 @@ export class UriTemplate {
211211 }
212212
213213 if ( part . operator === '?' || part . operator === '&' ) {
214- for ( let i = 0 ; i < part . names . length ; i ++ ) {
215- const name = part . names [ i ] ! ;
216- const prefix = i === 0 ? '\\' + part . operator : '&' ;
217- patterns . push ( {
218- pattern : prefix + this . escapeRegExp ( name ) + '=([^&]+)' ,
219- name
220- } ) ;
221- }
222214 return patterns ;
223215 }
224216
@@ -227,7 +219,7 @@ export class UriTemplate {
227219
228220 switch ( part . operator ) {
229221 case '' : {
230- pattern = part . exploded ? '([^/,]+(?:,[^/,]+)*)' : '([^/,]+)' ;
222+ pattern = part . exploded ? '([^/?# ,]+(?:,[^/?# ,]+)*)' : '([^/?# ,]+)' ;
231223 break ;
232224 }
233225 case '+' :
@@ -256,10 +248,18 @@ export class UriTemplate {
256248 UriTemplate . validateLength ( uri , MAX_TEMPLATE_LENGTH , 'URI' ) ;
257249 let pattern = '^' ;
258250 const names : Array < { name : string ; exploded : boolean } > = [ ] ;
251+ const queryNames : Array < { name : string ; exploded : boolean } > = [ ] ;
259252
260253 for ( const part of this . parts ) {
261254 if ( typeof part === 'string' ) {
262255 pattern += this . escapeRegExp ( part ) ;
256+ } else if ( part . operator === '?' || part . operator === '&' ) {
257+ for ( const name of part . names ) {
258+ UriTemplate . validateLength ( name , MAX_VARIABLE_LENGTH , 'Variable name' ) ;
259+ queryNames . push ( { name, exploded : part . exploded } ) ;
260+ }
261+
262+ pattern += part . operator === '?' ? String . raw `(?:\?[^#]*)?` : '(?:&[^#]*)?' ;
263263 } else {
264264 const patterns = this . partToRegExp ( part ) ;
265265 for ( const { pattern : partPattern , name } of patterns ) {
@@ -285,6 +285,22 @@ export class UriTemplate {
285285 result [ cleanName ] = exploded && value . includes ( ',' ) ? value . split ( ',' ) : value ;
286286 }
287287
288+ if ( queryNames . length > 0 ) {
289+ const queryStart = uri . indexOf ( '?' ) ;
290+ if ( queryStart !== - 1 ) {
291+ const queryEnd = uri . indexOf ( '#' , queryStart ) ;
292+ const query = uri . slice ( queryStart + 1 , queryEnd === - 1 ? undefined : queryEnd ) ;
293+ const params = new URLSearchParams ( query ) ;
294+
295+ for ( const { name, exploded } of queryNames ) {
296+ const value = params . get ( name ) ;
297+ if ( value !== null ) {
298+ result [ name ] = exploded && value . includes ( ',' ) ? value . split ( ',' ) : value ;
299+ }
300+ }
301+ }
302+ }
303+
288304 return result ;
289305 }
290306}
0 commit comments