@@ -463,6 +463,23 @@ const patternRegEx = /\*/g;
463463
464464function resolvePackageTargetString (
465465 target , subpath , match , packageJSONUrl , base , pattern , internal , conditions ) {
466+
467+ const composeResult = ( resolved ) => {
468+ let format ;
469+ try {
470+ format = getPackageType ( resolved ) ;
471+ } catch ( err ) {
472+ if ( err . code === 'ERR_INVALID_FILE_URL_PATH' ) {
473+ const invalidModuleErr = new ERR_INVALID_MODULE_SPECIFIER (
474+ resolved , 'must not include encoded "/" or "\\" characters' , base ) ;
475+ invalidModuleErr . cause = err ;
476+ throw invalidModuleErr ;
477+ }
478+ throw err ;
479+ }
480+ return { resolved, ...( format !== 'none' ) && { format } } ;
481+ } ;
482+
466483 if ( subpath !== '' && ! pattern && target [ target . length - 1 ] !== '/' )
467484 throwInvalidPackageTarget ( match , target , packageJSONUrl , internal , base ) ;
468485
@@ -478,7 +495,8 @@ function resolvePackageTargetString(
478495 const exportTarget = pattern ?
479496 RegExpPrototypeSymbolReplace ( patternRegEx , target , ( ) => subpath ) :
480497 target + subpath ;
481- return packageResolve ( exportTarget , packageJSONUrl , conditions ) ;
498+ return packageResolve (
499+ exportTarget , packageJSONUrl , conditions ) ;
482500 }
483501 }
484502 throwInvalidPackageTarget ( match , target , packageJSONUrl , internal , base ) ;
@@ -494,18 +512,21 @@ function resolvePackageTargetString(
494512 if ( ! StringPrototypeStartsWith ( resolvedPath , packagePath ) )
495513 throwInvalidPackageTarget ( match , target , packageJSONUrl , internal , base ) ;
496514
497- if ( subpath === '' ) return resolved ;
515+ if ( subpath === '' ) return composeResult ( resolved ) ;
498516
499517 if ( RegExpPrototypeTest ( invalidSegmentRegEx , subpath ) ) {
500518 const request = pattern ?
501519 StringPrototypeReplace ( match , '*' , ( ) => subpath ) : match + subpath ;
502520 throwInvalidSubpath ( request , packageJSONUrl , internal , base ) ;
503521 }
504522
505- if ( pattern )
506- return new URL ( RegExpPrototypeSymbolReplace ( patternRegEx , resolved . href ,
507- ( ) => subpath ) ) ;
508- return new URL ( subpath , resolved ) ;
523+ if ( pattern ) {
524+ return composeResult ( new URL ( RegExpPrototypeSymbolReplace ( patternRegEx ,
525+ resolved . href ,
526+ ( ) => subpath ) ) ) ;
527+ }
528+
529+ return composeResult ( new URL ( subpath , resolved ) ) ;
509530}
510531
511532/**
@@ -531,9 +552,9 @@ function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath,
531552 let lastException ;
532553 for ( let i = 0 ; i < target . length ; i ++ ) {
533554 const targetItem = target [ i ] ;
534- let resolved ;
555+ let resolveResult ;
535556 try {
536- resolved = resolvePackageTarget (
557+ resolveResult = resolvePackageTarget (
537558 packageJSONUrl , targetItem , subpath , packageSubpath , base , pattern ,
538559 internal , conditions ) ;
539560 } catch ( e ) {
@@ -542,13 +563,13 @@ function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath,
542563 continue ;
543564 throw e ;
544565 }
545- if ( resolved === undefined )
566+ if ( resolveResult === undefined )
546567 continue ;
547- if ( resolved === null ) {
568+ if ( resolveResult === null ) {
548569 lastException = null ;
549570 continue ;
550571 }
551- return resolved ;
572+ return resolveResult ;
552573 }
553574 if ( lastException === undefined || lastException === null )
554575 return lastException ;
@@ -567,12 +588,12 @@ function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath,
567588 const key = keys [ i ] ;
568589 if ( key === 'default' || conditions . has ( key ) ) {
569590 const conditionalTarget = target [ key ] ;
570- const resolved = resolvePackageTarget (
591+ const resolveResult = resolvePackageTarget (
571592 packageJSONUrl , conditionalTarget , subpath , packageSubpath , base ,
572593 pattern , internal , conditions ) ;
573- if ( resolved === undefined )
594+ if ( resolveResult === undefined )
574595 continue ;
575- return resolved ;
596+ return resolveResult ;
576597 }
577598 }
578599 return undefined ;
@@ -631,12 +652,15 @@ function packageExportsResolve(
631652 ! StringPrototypeIncludes ( packageSubpath , '*' ) &&
632653 ! StringPrototypeEndsWith ( packageSubpath , '/' ) ) {
633654 const target = exports [ packageSubpath ] ;
634- const resolved = resolvePackageTarget (
655+ const resolveResult = resolvePackageTarget (
635656 packageJSONUrl , target , '' , packageSubpath , base , false , false , conditions
636657 ) ;
637- if ( resolved === null || resolved === undefined )
658+
659+ if ( resolveResult == null ) {
638660 throwExportsNotFound ( packageSubpath , packageJSONUrl , base ) ;
639- return resolved ;
661+ }
662+
663+ return resolveResult ;
640664 }
641665
642666 let bestMatch = '' ;
@@ -672,12 +696,20 @@ function packageExportsResolve(
672696
673697 if ( bestMatch ) {
674698 const target = exports [ bestMatch ] ;
675- const resolved = resolvePackageTarget ( packageJSONUrl , target ,
676- bestMatchSubpath , bestMatch , base ,
677- true , false , conditions ) ;
678- if ( resolved === null || resolved === undefined )
699+ const resolveResult = resolvePackageTarget (
700+ packageJSONUrl ,
701+ target ,
702+ bestMatchSubpath ,
703+ bestMatch ,
704+ base ,
705+ true ,
706+ false ,
707+ conditions ) ;
708+
709+ if ( resolveResult == null ) {
679710 throwExportsNotFound ( packageSubpath , packageJSONUrl , base ) ;
680- return resolved ;
711+ }
712+ return resolveResult ;
681713 }
682714
683715 throwExportsNotFound ( packageSubpath , packageJSONUrl , base ) ;
@@ -717,11 +749,12 @@ function packageImportsResolve(name, base, conditions) {
717749 if ( imports ) {
718750 if ( ObjectPrototypeHasOwnProperty ( imports , name ) &&
719751 ! StringPrototypeIncludes ( name , '*' ) ) {
720- const resolved = resolvePackageTarget (
752+ const resolveResult = resolvePackageTarget (
721753 packageJSONUrl , imports [ name ] , '' , name , base , false , true , conditions
722754 ) ;
723- if ( resolved !== null && resolved !== undefined )
724- return resolved ;
755+ if ( resolveResult != null ) {
756+ return resolveResult . resolved ;
757+ }
725758 } else {
726759 let bestMatch = '' ;
727760 let bestMatchSubpath ;
@@ -747,11 +780,13 @@ function packageImportsResolve(name, base, conditions) {
747780
748781 if ( bestMatch ) {
749782 const target = imports [ bestMatch ] ;
750- const resolved = resolvePackageTarget ( packageJSONUrl , target ,
751- bestMatchSubpath , bestMatch ,
752- base , true , true , conditions ) ;
753- if ( resolved !== null && resolved !== undefined )
754- return resolved ;
783+ const resolveResult = resolvePackageTarget ( packageJSONUrl , target ,
784+ bestMatchSubpath ,
785+ bestMatch , base , true ,
786+ true , conditions ) ;
787+ if ( resolveResult != null ) {
788+ return resolveResult . resolved ;
789+ }
755790 }
756791 }
757792 }
@@ -810,11 +845,11 @@ function parsePackageName(specifier, base) {
810845 * @param {string } specifier
811846 * @param {string | URL | undefined } base
812847 * @param {Set<string> } conditions
813- * @returns {URL }
848+ * @returns {resolved: URL, format? : string }
814849 */
815850function packageResolve ( specifier , base , conditions ) {
816851 if ( NativeModule . canBeRequiredByUsers ( specifier ) )
817- return new URL ( 'node:' + specifier ) ;
852+ return { resolved : new URL ( 'node:' + specifier ) } ;
818853
819854 const { packageName, packageSubpath, isScoped } =
820855 parsePackageName ( specifier , base ) ;
@@ -826,8 +861,7 @@ function packageResolve(specifier, base, conditions) {
826861 if ( packageConfig . name === packageName &&
827862 packageConfig . exports !== undefined && packageConfig . exports !== null ) {
828863 return packageExportsResolve (
829- packageJSONUrl , packageSubpath , packageConfig , base , conditions
830- ) ;
864+ packageJSONUrl , packageSubpath , packageConfig , base , conditions ) ;
831865 }
832866 }
833867
@@ -849,13 +883,24 @@ function packageResolve(specifier, base, conditions) {
849883
850884 // Package match.
851885 const packageConfig = getPackageConfig ( packageJSONPath , specifier , base ) ;
852- if ( packageConfig . exports !== undefined && packageConfig . exports !== null )
886+ if ( packageConfig . exports !== undefined && packageConfig . exports !== null ) {
853887 return packageExportsResolve (
854- packageJSONUrl , packageSubpath , packageConfig , base , conditions
855- ) ;
856- if ( packageSubpath === '.' )
857- return legacyMainResolve ( packageJSONUrl , packageConfig , base ) ;
858- return new URL ( packageSubpath , packageJSONUrl ) ;
888+ packageJSONUrl , packageSubpath , packageConfig , base , conditions ) ;
889+ }
890+ if ( packageSubpath === '.' ) {
891+ return {
892+ resolved : legacyMainResolve (
893+ packageJSONUrl ,
894+ packageConfig ,
895+ base ) ,
896+ ...( packageConfig . type !== 'none' ) && { format : packageConfig . type }
897+ } ;
898+ }
899+
900+ return {
901+ resolved : new URL ( packageSubpath , packageJSONUrl ) ,
902+ ...( packageConfig . type !== 'none' ) && { format : packageConfig . type }
903+ } ;
859904 // Cross-platform root check.
860905 } while ( packageJSONPath . length !== lastPath . length ) ;
861906
@@ -893,12 +938,13 @@ function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) {
893938 * @param {string | URL | undefined } base
894939 * @param {Set<string> } conditions
895940 * @param {boolean } preserveSymlinks
896- * @returns {URL }
941+ * @returns {url: URL, format?: string }
897942 */
898943function moduleResolve ( specifier , base , conditions , preserveSymlinks ) {
899944 // Order swapped from spec for minor perf gain.
900945 // Ok since relative URLs cannot parse as URLs.
901946 let resolved ;
947+ let format ;
902948 if ( shouldBeTreatedAsRelativeOrAbsolutePath ( specifier ) ) {
903949 resolved = new URL ( specifier , base ) ;
904950 } else if ( specifier [ 0 ] === '#' ) {
@@ -907,12 +953,19 @@ function moduleResolve(specifier, base, conditions, preserveSymlinks) {
907953 try {
908954 resolved = new URL ( specifier ) ;
909955 } catch {
910- resolved = packageResolve ( specifier , base , conditions ) ;
956+ ( { resolved, format } = packageResolve ( specifier , base , conditions ) ) ;
911957 }
912958 }
913- if ( resolved . protocol !== 'file:' )
914- return resolved ;
915- return finalizeResolution ( resolved , base , preserveSymlinks ) ;
959+ if ( resolved . protocol !== 'file:' ) {
960+ return {
961+ url : resolved
962+ } ;
963+ }
964+
965+ return {
966+ url : finalizeResolution ( resolved , base , preserveSymlinks ) ,
967+ ...( format != null ) && { format }
968+ } ;
916969}
917970
918971/**
@@ -1001,9 +1054,15 @@ function defaultResolve(specifier, context = {}, defaultResolveUnused) {
10011054
10021055 conditions = getConditionsSet ( conditions ) ;
10031056 let url ;
1057+ let format ;
10041058 try {
1005- url = moduleResolve ( specifier , parentURL , conditions ,
1006- isMain ? preserveSymlinksMain : preserveSymlinks ) ;
1059+ ( { url, format } =
1060+ moduleResolve (
1061+ specifier ,
1062+ parentURL ,
1063+ conditions ,
1064+ isMain ? preserveSymlinksMain : preserveSymlinks
1065+ ) ) ;
10071066 } catch ( error ) {
10081067 // Try to give the user a hint of what would have been the
10091068 // resolved CommonJS module
@@ -1031,7 +1090,10 @@ function defaultResolve(specifier, context = {}, defaultResolveUnused) {
10311090 url . protocol !== 'node:' )
10321091 throw new ERR_UNSUPPORTED_ESM_URL_SCHEME ( url ) ;
10331092
1034- return { url : `${ url } ` } ;
1093+ return {
1094+ url : `${ url } ` ,
1095+ ...( format != null ) && { format }
1096+ } ;
10351097}
10361098
10371099module . exports = {
0 commit comments