@@ -16,6 +16,7 @@ const {
1616  String, 
1717  StringPrototypeEndsWith, 
1818  StringPrototypeIndexOf, 
19+   StringPrototypeLastIndexOf, 
1920  StringPrototypeReplace, 
2021  StringPrototypeSlice, 
2122  StringPrototypeSplit, 
@@ -59,6 +60,36 @@ const userConditions = getOptionValue('--conditions');
5960const  DEFAULT_CONDITIONS  =  ObjectFreeze ( [ 'node' ,  'import' ,  ...userConditions ] ) ; 
6061const  DEFAULT_CONDITIONS_SET  =  new  SafeSet ( DEFAULT_CONDITIONS ) ; 
6162
63+ const  pendingDeprecation  =  getOptionValue ( '--pending-deprecation' ) ; 
64+ const  emittedPackageWarnings  =  new  SafeSet ( ) ; 
65+ function  emitFolderMapDeprecation ( match ,  pjsonUrl ,  isExports ,  base )  { 
66+   const  pjsonPath  =  fileURLToPath ( pjsonUrl ) ; 
67+   if  ( ! pendingDeprecation )  { 
68+     const  nodeModulesIndex  =  StringPrototypeLastIndexOf ( pjsonPath , 
69+                                                         '/node_modules/' ) ; 
70+     if  ( nodeModulesIndex  !==  - 1 )  { 
71+       const  afterNodeModulesPath  =  StringPrototypeSlice ( pjsonPath , 
72+                                                         nodeModulesIndex  +  14 , 
73+                                                         - 13 ) ; 
74+       try  { 
75+         const  {  packageSubpath }  =  parsePackageName ( afterNodeModulesPath ) ; 
76+         if  ( packageSubpath  ===  '.' ) 
77+           return ; 
78+       }  catch  { } 
79+     } 
80+   } 
81+   if  ( emittedPackageWarnings . has ( pjsonPath  +  '|'  +  match ) ) 
82+     return ; 
83+   emittedPackageWarnings . add ( pjsonPath  +  '|'  +  match ) ; 
84+   process . emitWarning ( 
85+     `Use of deprecated folder mapping "${ match }  " in the ${ isExports  ? 
86+       '"exports"'  : '"imports"' }   field module resolution of the package at ${ 
87+       pjsonPath }  ${ base  ? ` imported from ${ fileURLToPath ( base ) }  `  : '' }  .\n`  + 
88+       `Update this package.json to use a subpath pattern like "${ match }  *".` , 
89+     'DeprecationWarning' , 
90+     'DEP0148' 
91+   ) ; 
92+ } 
6293
6394function  getConditionsSet ( conditions )  { 
6495  if  ( conditions  !==  undefined  &&  conditions  !==  DEFAULT_CONDITIONS )  { 
@@ -507,6 +538,8 @@ function packageExportsResolve(
507538                                          conditions ) ; 
508539    if  ( resolved  ===  null  ||  resolved  ===  undefined ) 
509540      throwExportsNotFound ( packageSubpath ,  packageJSONUrl ,  base ) ; 
541+     if  ( ! pattern ) 
542+       emitFolderMapDeprecation ( bestMatch ,  packageJSONUrl ,  true ,  base ) ; 
510543    return  {  resolved,  exact : pattern  } ; 
511544  } 
512545
@@ -556,8 +589,11 @@ function packageImportsResolve(name, base, conditions) {
556589          const  resolved  =  resolvePackageTarget ( 
557590            packageJSONUrl ,  target ,  subpath ,  bestMatch ,  base ,  pattern ,  true , 
558591            conditions ) ; 
559-           if  ( resolved  !==  null ) 
592+           if  ( resolved  !==  null )  { 
593+             if  ( ! pattern ) 
594+               emitFolderMapDeprecation ( bestMatch ,  packageJSONUrl ,  false ,  base ) ; 
560595            return  {  resolved,  exact : pattern  } ; 
596+           } 
561597        } 
562598      } 
563599    } 
@@ -570,13 +606,7 @@ function getPackageType(url) {
570606  return  packageConfig . type ; 
571607} 
572608
573- /** 
574-  * @param  {string } specifier 
575-  * @param  {URL } base 
576-  * @param  {Set<string> } conditions 
577-  * @returns  {URL } 
578-  */ 
579- function  packageResolve ( specifier ,  base ,  conditions )  { 
609+ function  parsePackageName ( specifier ,  base )  { 
580610  let  separatorIndex  =  StringPrototypeIndexOf ( specifier ,  '/' ) ; 
581611  let  validPackageName  =  true ; 
582612  let  isScoped  =  false ; 
@@ -610,6 +640,19 @@ function packageResolve(specifier, base, conditions) {
610640  const  packageSubpath  =  '.'  +  ( separatorIndex  ===  - 1  ? ''  :
611641    StringPrototypeSlice ( specifier ,  separatorIndex ) ) ; 
612642
643+   return  {  packageName,  packageSubpath,  isScoped } ; 
644+ } 
645+ 
646+ /** 
647+  * @param  {string } specifier 
648+  * @param  {URL } base 
649+  * @param  {Set<string> } conditions 
650+  * @returns  {URL } 
651+  */ 
652+ function  packageResolve ( specifier ,  base ,  conditions )  { 
653+   const  {  packageName,  packageSubpath,  isScoped }  = 
654+     parsePackageName ( specifier ,  base ) ; 
655+ 
613656  // ResolveSelf 
614657  const  packageConfig  =  getPackageScopeConfig ( base ) ; 
615658  if  ( packageConfig . exists )  { 
0 commit comments