@@ -560,7 +560,56 @@ func (a expansionKeysArray) Len() int { return len(a) }
560
560
func (a expansionKeysArray ) Swap (i int , j int ) { a [i ], a [j ] = a [j ], a [i ] }
561
561
562
562
func (a expansionKeysArray ) Less (i int , j int ) bool {
563
- return len (a [i ].key ) > len (a [j ].key )
563
+ // Assert: keyA ends with "/" or contains only a single "*".
564
+ // Assert: keyB ends with "/" or contains only a single "*".
565
+ keyA := a [i ].key
566
+ keyB := a [j ].key
567
+
568
+ // Let baseLengthA be the index of "*" in keyA plus one, if keyA contains "*", or the length of keyA otherwise.
569
+ // Let baseLengthB be the index of "*" in keyB plus one, if keyB contains "*", or the length of keyB otherwise.
570
+ starA := strings .IndexByte (keyA , '*' )
571
+ starB := strings .IndexByte (keyB , '*' )
572
+ var baseLengthA int
573
+ var baseLengthB int
574
+ if starA >= 0 {
575
+ baseLengthA = starA
576
+ } else {
577
+ baseLengthA = len (keyA )
578
+ }
579
+ if starB >= 0 {
580
+ baseLengthB = starB
581
+ } else {
582
+ baseLengthB = len (keyB )
583
+ }
584
+
585
+ // If baseLengthA is greater than baseLengthB, return -1.
586
+ // If baseLengthB is greater than baseLengthA, return 1.
587
+ if baseLengthA > baseLengthB {
588
+ return true
589
+ }
590
+ if baseLengthB > baseLengthA {
591
+ return false
592
+ }
593
+
594
+ // If keyA does not contain "*", return 1.
595
+ // If keyB does not contain "*", return -1.
596
+ if starA < 0 {
597
+ return false
598
+ }
599
+ if starB < 0 {
600
+ return true
601
+ }
602
+
603
+ // If the length of keyA is greater than the length of keyB, return -1.
604
+ // If the length of keyB is greater than the length of keyA, return 1.
605
+ if len (keyA ) > len (keyB ) {
606
+ return true
607
+ }
608
+ if len (keyB ) > len (keyA ) {
609
+ return false
610
+ }
611
+
612
+ return false
564
613
}
565
614
566
615
func (entry pjEntry ) valueForKey (key string ) (pjEntry , bool ) {
@@ -638,15 +687,16 @@ func parseImportsExportsMap(source logger.Source, log logger.Log, json js_ast.Ex
638
687
value : visit (property .ValueOrNil ),
639
688
}
640
689
641
- if strings .HasSuffix (key , "/" ) || strings .HasSuffix (key , "*" ) {
690
+ if strings .HasSuffix (key , "/" ) || strings .IndexByte (key , '*' ) >= 0 {
642
691
expansionKeys = append (expansionKeys , entry )
643
692
}
644
693
645
694
mapData [i ] = entry
646
695
}
647
696
648
- // Let expansionKeys be the list of keys of matchObj ending in "/" or "*",
649
- // sorted by length descending.
697
+ // Let expansionKeys be the list of keys of matchObj either ending in "/"
698
+ // or containing only a single "*", sorted by the sorting function
699
+ // PATTERN_KEY_COMPARE which orders in descending order of specificity.
650
700
sort .Stable (expansionKeys )
651
701
652
702
return pjEntry {
@@ -860,7 +910,8 @@ func (r resolverQuery) esmPackageImportsExportsResolve(
860
910
r .debugLogs .addNote (fmt .Sprintf ("Checking object path map for %q" , matchKey ))
861
911
}
862
912
863
- if ! strings .HasSuffix (matchKey , "*" ) {
913
+ // If matchKey is a key of matchObj and does not end in "/" or contain "*", then
914
+ if ! strings .HasSuffix (matchKey , "/" ) && strings .IndexByte (matchKey , '*' ) < 0 {
864
915
if target , ok := matchObj .valueForKey (matchKey ); ok {
865
916
if r .debugLogs != nil {
866
917
r .debugLogs .addNote (fmt .Sprintf ("Found exact match for %q" , matchKey ))
@@ -870,31 +921,46 @@ func (r resolverQuery) esmPackageImportsExportsResolve(
870
921
}
871
922
872
923
for _ , expansion := range matchObj .expansionKeys {
873
- // If expansionKey ends in "*" and matchKey starts with but is not equal to
874
- // the substring of expansionKey excluding the last "*" character
875
- if strings .HasSuffix (expansion .key , "*" ) {
876
- if substr := expansion .key [:len (expansion .key )- 1 ]; strings .HasPrefix (matchKey , substr ) && matchKey != substr {
924
+ // If expansionKey contains "*", set patternBase to the substring of
925
+ // expansionKey up to but excluding the first "*" character
926
+ if star := strings .IndexByte (expansion .key , '*' ); star >= 0 {
927
+ patternBase := expansion .key [:star ]
928
+
929
+ // If patternBase is not null and matchKey starts with but is not equal
930
+ // to patternBase, then
931
+ if strings .HasPrefix (matchKey , patternBase ) {
932
+ // Let patternTrailer be the substring of expansionKey from the index
933
+ // after the first "*" character.
934
+ patternTrailer := expansion .key [star + 1 :]
935
+
936
+ // If patternTrailer has zero length, or if matchKey ends with
937
+ // patternTrailer and the length of matchKey is greater than or
938
+ // equal to the length of expansionKey, then
939
+ if patternTrailer == "" || (strings .HasSuffix (matchKey , patternTrailer ) && len (matchKey ) >= len (expansion .key )) {
940
+ target := expansion .value
941
+ subpath := matchKey [len (patternBase ) : len (matchKey )- len (patternTrailer )]
942
+ if r .debugLogs != nil {
943
+ r .debugLogs .addNote (fmt .Sprintf ("The key %q matched with %q left over" , expansion .key , subpath ))
944
+ }
945
+ return r .esmPackageTargetResolve (packageURL , target , subpath , true , isImports , conditions )
946
+ }
947
+ }
948
+ } else {
949
+ // Otherwise if patternBase is null and matchKey starts with
950
+ // expansionKey, then
951
+ if strings .HasPrefix (matchKey , expansion .key ) {
877
952
target := expansion .value
878
- subpath := matchKey [len (expansion .key )- 1 :]
953
+ subpath := matchKey [len (expansion .key ):]
879
954
if r .debugLogs != nil {
880
955
r .debugLogs .addNote (fmt .Sprintf ("The key %q matched with %q left over" , expansion .key , subpath ))
881
956
}
882
- return r .esmPackageTargetResolve (packageURL , target , subpath , true , isImports , conditions )
883
- }
884
- }
885
-
886
- if strings .HasPrefix (matchKey , expansion .key ) {
887
- target := expansion .value
888
- subpath := matchKey [len (expansion .key ):]
889
- if r .debugLogs != nil {
890
- r .debugLogs .addNote (fmt .Sprintf ("The key %q matched with %q left over" , expansion .key , subpath ))
891
- }
892
- result , status , debug := r .esmPackageTargetResolve (packageURL , target , subpath , false , isImports , conditions )
893
- if status == pjStatusExact || status == pjStatusExactEndsWithStar {
894
- // Return the object { resolved, exact: false }.
895
- status = pjStatusInexact
957
+ result , status , debug := r .esmPackageTargetResolve (packageURL , target , subpath , false , isImports , conditions )
958
+ if status == pjStatusExact || status == pjStatusExactEndsWithStar {
959
+ // Return the object { resolved, exact: false }.
960
+ status = pjStatusInexact
961
+ }
962
+ return result , status , debug
896
963
}
897
- return result , status , debug
898
964
}
899
965
900
966
if r .debugLogs != nil {
0 commit comments