@@ -15,7 +15,9 @@ const {
15
15
SafeSet,
16
16
String,
17
17
StringPrototypeEndsWith,
18
+ StringPrototypeIncludes,
18
19
StringPrototypeIndexOf,
20
+ StringPrototypeLastIndexOf,
19
21
StringPrototypeReplace,
20
22
StringPrototypeSlice,
21
23
StringPrototypeSplit,
@@ -114,7 +116,7 @@ function emitLegacyIndexDeprecation(url, packageJSONUrl, base, main) {
114
116
`Package ${ pkgPath } has a "main" field set to ${ JSONStringify ( main ) } , ` +
115
117
`excluding the full filename and extension to the resolved file at "${
116
118
StringPrototypeSlice ( path , pkgPath . length ) } ", imported from ${
117
- basePath } .\n Automatic extension resolution of the "main" field is` +
119
+ basePath } .\n Automatic extension resolution of the "main" field is ` +
118
120
'deprecated for ES modules.' ,
119
121
'DeprecationWarning' ,
120
122
'DEP0151'
@@ -607,7 +609,9 @@ function packageExportsResolve(
607
609
if ( isConditionalExportsMainSugar ( exports , packageJSONUrl , base ) )
608
610
exports = { '.' : exports } ;
609
611
610
- if ( ObjectPrototypeHasOwnProperty ( exports , packageSubpath ) ) {
612
+ if ( ObjectPrototypeHasOwnProperty ( exports , packageSubpath ) &&
613
+ ! StringPrototypeIncludes ( packageSubpath , '*' ) &&
614
+ ! StringPrototypeEndsWith ( packageSubpath , '/' ) ) {
611
615
const target = exports [ packageSubpath ] ;
612
616
const resolved = resolvePackageTarget (
613
617
packageJSONUrl , target , '' , packageSubpath , base , false , false , conditions
@@ -618,30 +622,38 @@ function packageExportsResolve(
618
622
}
619
623
620
624
let bestMatch = '' ;
625
+ let bestMatchSubpath ;
621
626
const keys = ObjectGetOwnPropertyNames ( exports ) ;
622
627
for ( let i = 0 ; i < keys . length ; i ++ ) {
623
628
const key = keys [ i ] ;
624
- if ( key [ key . length - 1 ] === '*' &&
629
+ const patternIndex = StringPrototypeIndexOf ( key , '*' ) ;
630
+ if ( patternIndex !== - 1 &&
625
631
StringPrototypeStartsWith ( packageSubpath ,
626
- StringPrototypeSlice ( key , 0 , - 1 ) ) &&
627
- packageSubpath . length >= key . length &&
628
- key . length > bestMatch . length ) {
629
- bestMatch = key ;
632
+ StringPrototypeSlice ( key , 0 , patternIndex ) ) ) {
633
+ const patternTrailer = StringPrototypeSlice ( key , patternIndex + 1 ) ;
634
+ if ( packageSubpath . length >= key . length &&
635
+ StringPrototypeEndsWith ( packageSubpath , patternTrailer ) &&
636
+ patternKeyCompare ( bestMatch , key ) === 1 &&
637
+ StringPrototypeLastIndexOf ( key , '*' ) === patternIndex ) {
638
+ bestMatch = key ;
639
+ bestMatchSubpath = StringPrototypeSlice (
640
+ packageSubpath , patternIndex ,
641
+ packageSubpath . length - patternTrailer . length ) ;
642
+ }
630
643
} else if ( key [ key . length - 1 ] === '/' &&
631
644
StringPrototypeStartsWith ( packageSubpath , key ) &&
632
- key . length > bestMatch . length ) {
645
+ patternKeyCompare ( bestMatch , key ) === 1 ) {
633
646
bestMatch = key ;
647
+ bestMatchSubpath = StringPrototypeSlice ( packageSubpath , key . length ) ;
634
648
}
635
649
}
636
650
637
651
if ( bestMatch ) {
638
652
const target = exports [ bestMatch ] ;
639
- const pattern = bestMatch [ bestMatch . length - 1 ] === '*' ;
640
- const subpath = StringPrototypeSubstr ( packageSubpath , bestMatch . length -
641
- ( pattern ? 1 : 0 ) ) ;
642
- const resolved = resolvePackageTarget ( packageJSONUrl , target , subpath ,
643
- bestMatch , base , pattern , false ,
644
- conditions ) ;
653
+ const pattern = StringPrototypeIncludes ( bestMatch , '*' ) ;
654
+ const resolved = resolvePackageTarget ( packageJSONUrl , target ,
655
+ bestMatchSubpath , bestMatch , base ,
656
+ pattern , false , conditions ) ;
645
657
if ( resolved === null || resolved === undefined )
646
658
throwExportsNotFound ( packageSubpath , packageJSONUrl , base ) ;
647
659
if ( ! pattern )
@@ -652,6 +664,20 @@ function packageExportsResolve(
652
664
throwExportsNotFound ( packageSubpath , packageJSONUrl , base ) ;
653
665
}
654
666
667
+ function patternKeyCompare ( a , b ) {
668
+ const aPatternIndex = StringPrototypeIndexOf ( a , '*' ) ;
669
+ const bPatternIndex = StringPrototypeIndexOf ( b , '*' ) ;
670
+ const baseLenA = aPatternIndex === - 1 ? a . length : aPatternIndex + 1 ;
671
+ const baseLenB = bPatternIndex === - 1 ? b . length : bPatternIndex + 1 ;
672
+ if ( baseLenA > baseLenB ) return - 1 ;
673
+ if ( baseLenB > baseLenA ) return 1 ;
674
+ if ( aPatternIndex === - 1 ) return 1 ;
675
+ if ( bPatternIndex === - 1 ) return - 1 ;
676
+ if ( a . length > b . length ) return - 1 ;
677
+ if ( b . length > a . length ) return 1 ;
678
+ return 0 ;
679
+ }
680
+
655
681
/**
656
682
* @param {string } name
657
683
* @param {string | URL | undefined } base
0 commit comments