@@ -79,24 +79,40 @@ export interface CompileOptions extends ParseOptions {
79
79
encode ?: Encode ;
80
80
}
81
81
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
+
82
97
/**
83
98
* Tokenizer results.
84
99
*/
85
100
interface 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 ;
96
102
index : number ;
97
103
value : string ;
98
104
}
99
105
106
+ const SIMPLE_TOKENS : Record < string , TokenType > = {
107
+ "!" : "!" ,
108
+ ";" : ";" ,
109
+ "*" : "*" ,
110
+ "+" : "+" ,
111
+ "?" : "?" ,
112
+ "{" : "{" ,
113
+ "}" : "}" ,
114
+ } ;
115
+
100
116
/**
101
117
* Tokenize input string.
102
118
*/
@@ -107,29 +123,15 @@ function lexer(str: string) {
107
123
108
124
while ( i < chars . length ) {
109
125
const char = chars [ i ] ;
126
+ const type = SIMPLE_TOKENS [ char ] ;
110
127
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 } ) ;
118
130
continue ;
119
131
}
120
132
121
133
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 ++ ] } ) ;
133
135
continue ;
134
136
}
135
137
@@ -220,13 +222,15 @@ class Iter {
220
222
text ( ) : string {
221
223
let result = "" ;
222
224
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" ) ) ) {
226
226
result += value ;
227
227
}
228
228
return result ;
229
229
}
230
+
231
+ modifier ( ) : string | undefined {
232
+ return this . tryConsume ( "?" ) || this . tryConsume ( "*" ) || this . tryConsume ( "+" ) ;
233
+ }
230
234
}
231
235
232
236
/**
@@ -258,9 +262,8 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
258
262
const char = it . tryConsume ( "CHAR" ) ;
259
263
const name = it . tryConsume ( "NAME" ) ;
260
264
const pattern = it . tryConsume ( "PATTERN" ) ;
261
- const modifier = it . tryConsume ( "MODIFIER" ) ;
262
265
263
- if ( name || pattern || modifier ) {
266
+ if ( name || pattern ) {
264
267
let prefix = char || "" ;
265
268
266
269
if ( ! prefixes . includes ( prefix ) ) {
@@ -277,17 +280,17 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
277
280
toKey (
278
281
encodePath ,
279
282
delimiter ,
280
- name || key ++ ,
283
+ name || String ( key ++ ) ,
281
284
pattern || defaultPattern ,
282
285
prefix ,
283
286
"" ,
284
- modifier ,
287
+ it . modifier ( ) ,
285
288
) ,
286
289
) ;
287
290
continue ;
288
291
}
289
292
290
- const value = char || it . tryConsume ( "ESCAPED_CHAR " ) ;
293
+ const value = char || it . tryConsume ( "ESCAPED " ) ;
291
294
if ( value ) {
292
295
path += value ;
293
296
continue ;
@@ -298,26 +301,24 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
298
301
path = "" ;
299
302
}
300
303
301
- const open = it . tryConsume ( "OPEN " ) ;
304
+ const open = it . tryConsume ( "{ " ) ;
302
305
if ( open ) {
303
306
const prefix = it . text ( ) ;
304
307
const name = it . tryConsume ( "NAME" ) ;
305
308
const pattern = it . tryConsume ( "PATTERN" ) ;
306
309
const suffix = it . text ( ) ;
307
310
308
- it . consume ( "CLOSE" ) ;
309
-
310
- const modifier = it . tryConsume ( "MODIFIER" ) ;
311
+ it . consume ( "}" ) ;
311
312
312
313
tokens . push (
313
314
toKey (
314
315
encodePath ,
315
316
delimiter ,
316
- name || ( pattern ? key ++ : "" ) ,
317
+ name || ( pattern ? String ( key ++ ) : "" ) ,
317
318
name && ! pattern ? defaultPattern : pattern || "" ,
318
319
prefix ,
319
320
suffix ,
320
- modifier ,
321
+ it . modifier ( ) ,
321
322
) ,
322
323
) ;
323
324
continue ;
@@ -333,7 +334,7 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
333
334
function toKey (
334
335
encode : Encode ,
335
336
delimiter : string ,
336
- name : string | number ,
337
+ name : string ,
337
338
pattern = "" ,
338
339
inputPrefix = "" ,
339
340
inputSuffix = "" ,
@@ -586,7 +587,7 @@ function flags(options: { sensitive?: boolean }) {
586
587
* A key is a capture group in the regex.
587
588
*/
588
589
export interface Key {
589
- name : string | number ;
590
+ name : string ;
590
591
prefix : string ;
591
592
suffix : string ;
592
593
pattern : string ;
@@ -609,7 +610,7 @@ function regexpToRegexp(path: RegExp, keys: Key[]): RegExp {
609
610
for ( const execResult of path . source . matchAll ( GROUPS_RE ) ) {
610
611
keys . push ( {
611
612
// Use parenthesized substring match if available, index otherwise.
612
- name : execResult [ 1 ] || index ++ ,
613
+ name : execResult [ 1 ] || String ( index ++ ) ,
613
614
prefix : "" ,
614
615
suffix : "" ,
615
616
modifier : "" ,
@@ -664,7 +665,7 @@ function tokensToRegexp(
664
665
if ( typeof token === "string" ) {
665
666
pattern += stringify ( token ) ;
666
667
} else {
667
- if ( token . pattern ) keys . push ( token ) ;
668
+ if ( token . name ) keys . push ( token ) ;
668
669
pattern += keyToRegexp ( token , stringify ) ;
669
670
}
670
671
}
@@ -685,7 +686,7 @@ function keyToRegexp(key: Key, stringify: Encode): string {
685
686
const prefix = stringify ( key . prefix ) ;
686
687
const suffix = stringify ( key . suffix ) ;
687
688
688
- if ( key . pattern ) {
689
+ if ( key . name ) {
689
690
if ( key . separator ) {
690
691
const mod = key . modifier === "*" ? "?" : "" ;
691
692
const split = stringify ( key . separator ) ;
0 commit comments