@@ -79,24 +79,40 @@ export interface CompileOptions extends ParseOptions {
7979 encode ?: Encode ;
8080}
8181
82+ type TokenType =
83+ | "{"
84+ | "}"
85+ | "*"
86+ | "+"
87+ | "?"
88+ | "NAME"
89+ | "PATTERN"
90+ | "CHAR"
91+ | "ESCAPED"
92+ | "END"
93+ // Reserved for use.
94+ | "!"
95+ | ";" ;
96+
8297/**
8398 * Tokenizer results.
8499 */
85100interface LexToken {
86- type :
87- | "OPEN"
88- | "CLOSE"
89- | "PATTERN"
90- | "NAME"
91- | "CHAR"
92- | "ESCAPED_CHAR"
93- | "MODIFIER"
94- | "RESERVED"
95- | "END" ;
101+ type : TokenType ;
96102 index : number ;
97103 value : string ;
98104}
99105
106+ const SIMPLE_TOKENS : Record < string , TokenType > = {
107+ "!" : "!" ,
108+ ";" : ";" ,
109+ "*" : "*" ,
110+ "+" : "+" ,
111+ "?" : "?" ,
112+ "{" : "{" ,
113+ "}" : "}" ,
114+ } ;
115+
100116/**
101117 * Tokenize input string.
102118 */
@@ -107,29 +123,15 @@ function lexer(str: string) {
107123
108124 while ( i < chars . length ) {
109125 const char = chars [ i ] ;
126+ const type = SIMPLE_TOKENS [ char ] ;
110127
111- if ( char === "!" || char === ";" || char === "|" ) {
112- tokens . push ( { type : "RESERVED" , index : i , value : chars [ i ++ ] } ) ;
113- continue ;
114- }
115-
116- if ( char === "*" || char === "+" || char === "?" ) {
117- tokens . push ( { type : "MODIFIER" , index : i , value : chars [ i ++ ] } ) ;
128+ if ( type ) {
129+ tokens . push ( { type, index : i ++ , value : char } ) ;
118130 continue ;
119131 }
120132
121133 if ( char === "\\" ) {
122- tokens . push ( { type : "ESCAPED_CHAR" , index : i ++ , value : chars [ i ++ ] } ) ;
123- continue ;
124- }
125-
126- if ( char === "{" ) {
127- tokens . push ( { type : "OPEN" , index : i , value : chars [ i ++ ] } ) ;
128- continue ;
129- }
130-
131- if ( char === "}" ) {
132- tokens . push ( { type : "CLOSE" , index : i , value : chars [ i ++ ] } ) ;
134+ tokens . push ( { type : "ESCAPED" , index : i ++ , value : chars [ i ++ ] } ) ;
133135 continue ;
134136 }
135137
@@ -220,13 +222,15 @@ class Iter {
220222 text ( ) : string {
221223 let result = "" ;
222224 let value : string | undefined ;
223- while (
224- ( value = this . tryConsume ( "CHAR" ) || this . tryConsume ( "ESCAPED_CHAR" ) )
225- ) {
225+ while ( ( value = this . tryConsume ( "CHAR" ) || this . tryConsume ( "ESCAPED" ) ) ) {
226226 result += value ;
227227 }
228228 return result ;
229229 }
230+
231+ modifier ( ) : string | undefined {
232+ return this . tryConsume ( "?" ) || this . tryConsume ( "*" ) || this . tryConsume ( "+" ) ;
233+ }
230234}
231235
232236/**
@@ -258,9 +262,8 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
258262 const char = it . tryConsume ( "CHAR" ) ;
259263 const name = it . tryConsume ( "NAME" ) ;
260264 const pattern = it . tryConsume ( "PATTERN" ) ;
261- const modifier = it . tryConsume ( "MODIFIER" ) ;
262265
263- if ( name || pattern || modifier ) {
266+ if ( name || pattern ) {
264267 let prefix = char || "" ;
265268
266269 if ( ! prefixes . includes ( prefix ) ) {
@@ -277,17 +280,17 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
277280 toKey (
278281 encodePath ,
279282 delimiter ,
280- name || key ++ ,
283+ name || String ( key ++ ) ,
281284 pattern || defaultPattern ,
282285 prefix ,
283286 "" ,
284- modifier ,
287+ it . modifier ( ) ,
285288 ) ,
286289 ) ;
287290 continue ;
288291 }
289292
290- const value = char || it . tryConsume ( "ESCAPED_CHAR " ) ;
293+ const value = char || it . tryConsume ( "ESCAPED " ) ;
291294 if ( value ) {
292295 path += value ;
293296 continue ;
@@ -298,26 +301,24 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
298301 path = "" ;
299302 }
300303
301- const open = it . tryConsume ( "OPEN " ) ;
304+ const open = it . tryConsume ( "{ " ) ;
302305 if ( open ) {
303306 const prefix = it . text ( ) ;
304307 const name = it . tryConsume ( "NAME" ) ;
305308 const pattern = it . tryConsume ( "PATTERN" ) ;
306309 const suffix = it . text ( ) ;
307310
308- it . consume ( "CLOSE" ) ;
309-
310- const modifier = it . tryConsume ( "MODIFIER" ) ;
311+ it . consume ( "}" ) ;
311312
312313 tokens . push (
313314 toKey (
314315 encodePath ,
315316 delimiter ,
316- name || ( pattern ? key ++ : "" ) ,
317+ name || ( pattern ? String ( key ++ ) : "" ) ,
317318 name && ! pattern ? defaultPattern : pattern || "" ,
318319 prefix ,
319320 suffix ,
320- modifier ,
321+ it . modifier ( ) ,
321322 ) ,
322323 ) ;
323324 continue ;
@@ -333,7 +334,7 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
333334function toKey (
334335 encode : Encode ,
335336 delimiter : string ,
336- name : string | number ,
337+ name : string ,
337338 pattern = "" ,
338339 inputPrefix = "" ,
339340 inputSuffix = "" ,
@@ -586,7 +587,7 @@ function flags(options: { sensitive?: boolean }) {
586587 * A key is a capture group in the regex.
587588 */
588589export interface Key {
589- name : string | number ;
590+ name : string ;
590591 prefix : string ;
591592 suffix : string ;
592593 pattern : string ;
@@ -609,7 +610,7 @@ function regexpToRegexp(path: RegExp, keys: Key[]): RegExp {
609610 for ( const execResult of path . source . matchAll ( GROUPS_RE ) ) {
610611 keys . push ( {
611612 // Use parenthesized substring match if available, index otherwise.
612- name : execResult [ 1 ] || index ++ ,
613+ name : execResult [ 1 ] || String ( index ++ ) ,
613614 prefix : "" ,
614615 suffix : "" ,
615616 modifier : "" ,
@@ -664,7 +665,7 @@ function tokensToRegexp(
664665 if ( typeof token === "string" ) {
665666 pattern += stringify ( token ) ;
666667 } else {
667- if ( token . pattern ) keys . push ( token ) ;
668+ if ( token . name ) keys . push ( token ) ;
668669 pattern += keyToRegexp ( token , stringify ) ;
669670 }
670671 }
@@ -685,7 +686,7 @@ function keyToRegexp(key: Key, stringify: Encode): string {
685686 const prefix = stringify ( key . prefix ) ;
686687 const suffix = stringify ( key . suffix ) ;
687688
688- if ( key . pattern ) {
689+ if ( key . name ) {
689690 if ( key . separator ) {
690691 const mod = key . modifier === "*" ? "?" : "" ;
691692 const split = stringify ( key . separator ) ;
0 commit comments