@@ -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,
@@ -502,7 +504,9 @@ function packageExportsResolve(
502
504
if ( isConditionalExportsMainSugar ( exports , packageJSONUrl , base ) )
503
505
exports = { '.' : exports } ;
504
506
505
- if ( ObjectPrototypeHasOwnProperty ( exports , packageSubpath ) ) {
507
+ if ( ObjectPrototypeHasOwnProperty ( exports , packageSubpath ) &&
508
+ ! StringPrototypeIncludes ( packageSubpath , '*' ) &&
509
+ ! StringPrototypeEndsWith ( packageSubpath , '/' ) ) {
506
510
const target = exports [ packageSubpath ] ;
507
511
const resolved = resolvePackageTarget (
508
512
packageJSONUrl , target , '' , packageSubpath , base , false , false , conditions
@@ -513,30 +517,38 @@ function packageExportsResolve(
513
517
}
514
518
515
519
let bestMatch = '' ;
520
+ let bestMatchSubpath ;
516
521
const keys = ObjectGetOwnPropertyNames ( exports ) ;
517
522
for ( let i = 0 ; i < keys . length ; i ++ ) {
518
523
const key = keys [ i ] ;
519
- if ( key [ key . length - 1 ] === '*' &&
524
+ const patternIndex = StringPrototypeIndexOf ( key , '*' ) ;
525
+ if ( patternIndex !== - 1 &&
520
526
StringPrototypeStartsWith ( packageSubpath ,
521
- StringPrototypeSlice ( key , 0 , - 1 ) ) &&
522
- packageSubpath . length >= key . length &&
523
- key . length > bestMatch . length ) {
524
- bestMatch = key ;
527
+ StringPrototypeSlice ( key , 0 , patternIndex ) ) ) {
528
+ const patternTrailer = StringPrototypeSlice ( key , patternIndex + 1 ) ;
529
+ if ( packageSubpath . length >= key . length &&
530
+ StringPrototypeEndsWith ( packageSubpath , patternTrailer ) &&
531
+ patternKeyCompare ( bestMatch , key ) === 1 &&
532
+ StringPrototypeLastIndexOf ( key , '*' ) === patternIndex ) {
533
+ bestMatch = key ;
534
+ bestMatchSubpath = StringPrototypeSlice (
535
+ packageSubpath , patternIndex ,
536
+ packageSubpath . length - patternTrailer . length ) ;
537
+ }
525
538
} else if ( key [ key . length - 1 ] === '/' &&
526
539
StringPrototypeStartsWith ( packageSubpath , key ) &&
527
- key . length > bestMatch . length ) {
540
+ patternKeyCompare ( bestMatch , key ) === 1 ) {
528
541
bestMatch = key ;
542
+ bestMatchSubpath = StringPrototypeSlice ( packageSubpath , key . length ) ;
529
543
}
530
544
}
531
545
532
546
if ( bestMatch ) {
533
547
const target = exports [ bestMatch ] ;
534
- const pattern = bestMatch [ bestMatch . length - 1 ] === '*' ;
535
- const subpath = StringPrototypeSubstr ( packageSubpath , bestMatch . length -
536
- ( pattern ? 1 : 0 ) ) ;
537
- const resolved = resolvePackageTarget ( packageJSONUrl , target , subpath ,
538
- bestMatch , base , pattern , false ,
539
- conditions ) ;
548
+ const pattern = StringPrototypeIncludes ( bestMatch , '*' ) ;
549
+ const resolved = resolvePackageTarget ( packageJSONUrl , target ,
550
+ bestMatchSubpath , bestMatch , base ,
551
+ pattern , false , conditions ) ;
540
552
if ( resolved === null || resolved === undefined )
541
553
throwExportsNotFound ( packageSubpath , packageJSONUrl , base ) ;
542
554
return { resolved, exact : pattern } ;
@@ -545,6 +557,20 @@ function packageExportsResolve(
545
557
throwExportsNotFound ( packageSubpath , packageJSONUrl , base ) ;
546
558
}
547
559
560
+ function patternKeyCompare ( a , b ) {
561
+ const aPatternIndex = StringPrototypeIndexOf ( a , '*' ) ;
562
+ const bPatternIndex = StringPrototypeIndexOf ( b , '*' ) ;
563
+ const baseLenA = aPatternIndex === - 1 ? a . length : aPatternIndex + 1 ;
564
+ const baseLenB = bPatternIndex === - 1 ? b . length : bPatternIndex + 1 ;
565
+ if ( baseLenA > baseLenB ) return - 1 ;
566
+ if ( baseLenB > baseLenA ) return 1 ;
567
+ if ( aPatternIndex === - 1 ) return 1 ;
568
+ if ( bPatternIndex === - 1 ) return - 1 ;
569
+ if ( a . length > b . length ) return - 1 ;
570
+ if ( b . length > a . length ) return 1 ;
571
+ return 0 ;
572
+ }
573
+
548
574
function packageImportsResolve ( name , base , conditions ) {
549
575
if ( name === '#' || StringPrototypeStartsWith ( name , '#/' ) ) {
550
576
const reason = 'is not a valid internal imports specifier name' ;
0 commit comments