@@ -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