@@ -297,7 +297,7 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
297
297
if ( asterisk ) {
298
298
tokens . push ( {
299
299
name : String ( key ++ ) ,
300
- pattern : `${ negate ( escape ( delimiter ) ) } *` ,
300
+ pattern : `${ negate ( delimiter ) } *` ,
301
301
modifier : "*" ,
302
302
separator : delimiter ,
303
303
} ) ;
@@ -590,7 +590,6 @@ function tokensToRegexp(data: TokenData, options: PathOptions) {
590
590
* Convert a token into a regexp string (re-used for path validation).
591
591
*/
592
592
function toRegExpSource ( data : TokenData , keys : Key [ ] ) : string [ ] {
593
- const delim = escape ( data . delimiter ) ;
594
593
const sources = Array ( data . tokens . length ) ;
595
594
let backtrack = "" ;
596
595
@@ -600,7 +599,8 @@ function toRegExpSource(data: TokenData, keys: Key[]): string[] {
600
599
const token = data . tokens [ i ] ;
601
600
602
601
if ( typeof token === "string" ) {
603
- sources [ i ] = backtrack = escape ( token ) ;
602
+ backtrack = token ;
603
+ sources [ i ] = escape ( token ) ;
604
604
continue ;
605
605
}
606
606
@@ -615,39 +615,65 @@ function toRegExpSource(data: TokenData, keys: Key[]): string[] {
615
615
const post = escape ( suffix ) ;
616
616
617
617
if ( token . name ) {
618
- let pattern = token . pattern || "" ;
619
-
618
+ backtrack = suffix || backtrack ;
620
619
keys . unshift ( token ) ;
621
620
622
621
if ( isRepeat ( token ) ) {
623
- const mod = modifier === "*" ? "?" : "" ;
624
- const sep = escape ( separator ) ;
625
-
626
- if ( ! sep ) {
622
+ if ( ! separator ) {
627
623
throw new TypeError (
628
624
`Missing separator for "${ token . name } ": ${ DEBUG_URL } ` ,
629
625
) ;
630
626
}
631
627
632
- pattern ||= `${ negate ( delim , sep , post || backtrack ) } +` ;
633
- sources [ i ] =
634
- `(?:${ pre } ((?:${ pattern } )(?:${ sep } (?:${ pattern } ))*)${ post } )${ mod } ` ;
628
+ const mod = modifier === "*" ? "?" : "" ;
629
+ const sep = escape ( separator ) ;
630
+ const pattern =
631
+ token . pattern || `${ negate ( data . delimiter , separator , backtrack ) } +` ;
632
+
633
+ sources [ i ] = wrap (
634
+ pre ,
635
+ `(?:${ pattern } )(?:${ sep } (?:${ pattern } ))*` ,
636
+ post ,
637
+ mod ,
638
+ ) ;
635
639
} else {
636
- pattern ||= `${ negate ( delim , post || backtrack ) } +` ;
637
- sources [ i ] = `(?:${ pre } (${ pattern } )${ post } )${ modifier } ` ;
640
+ sources [ i ] = wrap (
641
+ pre ,
642
+ token . pattern || `${ negate ( data . delimiter , backtrack ) } +` ,
643
+ post ,
644
+ modifier ,
645
+ ) ;
638
646
}
639
647
640
- backtrack = pre || pattern ;
648
+ backtrack = prefix ;
641
649
} else {
642
650
sources [ i ] = `(?:${ pre } ${ post } )${ modifier } ` ;
643
- backtrack = `${ pre } ${ post } ` ;
651
+ backtrack = `${ prefix } ${ suffix } ` ;
644
652
}
645
653
}
646
654
647
655
return sources ;
648
656
}
649
657
650
658
function negate ( ...args : string [ ] ) {
651
- const values = Array . from ( new Set ( args ) ) . filter ( Boolean ) ;
652
- return `(?:(?!${ values . join ( "|" ) } ).)` ;
659
+ const values = args . sort ( ) . filter ( ( value , index , array ) => {
660
+ for ( let i = 0 ; i < index ; i ++ ) {
661
+ const v = array [ i ] ;
662
+ if ( v . length && value . startsWith ( v ) ) return false ;
663
+ }
664
+ return value . length > 0 ;
665
+ } ) ;
666
+
667
+ const isSimple = values . every ( ( value ) => value . length === 1 ) ;
668
+ if ( isSimple ) return `[^${ escape ( values . join ( "" ) ) } ]` ;
669
+
670
+ return `(?:(?!${ values . map ( escape ) . join ( "|" ) } ).)` ;
671
+ }
672
+
673
+ function wrap ( pre : string , pattern : string , post : string , modifier : string ) {
674
+ if ( pre || post ) {
675
+ return `(?:${ pre } (${ pattern } )${ post } )${ modifier } ` ;
676
+ }
677
+
678
+ return `(${ pattern } )${ modifier } ` ;
653
679
}
0 commit comments