44 ArrayIsArray,
55 JSONParse,
66 JSONStringify,
7+ ObjectFreeze,
78 ObjectGetOwnPropertyNames,
89 ObjectPrototypeHasOwnProperty,
910 SafeMap,
11+ SafeSet,
1012 StringPrototypeEndsWith,
1113 StringPrototypeIncludes,
1214 StringPrototypeIndexOf,
@@ -35,6 +37,7 @@ const typeFlag = getOptionValue('--input-type');
3537const { URL , pathToFileURL, fileURLToPath } = require ( 'internal/url' ) ;
3638const {
3739 ERR_INPUT_TYPE_NOT_ALLOWED ,
40+ ERR_INVALID_ARG_VALUE ,
3841 ERR_INVALID_MODULE_SPECIFIER ,
3942 ERR_INVALID_PACKAGE_CONFIG ,
4043 ERR_INVALID_PACKAGE_TARGET ,
@@ -43,6 +46,20 @@ const {
4346 ERR_UNSUPPORTED_ESM_URL_SCHEME ,
4447} = require ( 'internal/errors' ) . codes ;
4548
49+ const DEFAULT_CONDITIONS = ObjectFreeze ( [ 'node' , 'import' ] ) ;
50+ const DEFAULT_CONDITIONS_SET = new SafeSet ( DEFAULT_CONDITIONS ) ;
51+
52+ function getConditionsSet ( conditions ) {
53+ if ( conditions !== undefined && conditions !== DEFAULT_CONDITIONS ) {
54+ if ( ! ArrayIsArray ( conditions ) ) {
55+ throw new ERR_INVALID_ARG_VALUE ( 'conditions' , conditions ,
56+ 'expected an array' ) ;
57+ }
58+ return new SafeSet ( conditions ) ;
59+ }
60+ return DEFAULT_CONDITIONS_SET ;
61+ }
62+
4663const realpathCache = new SafeMap ( ) ;
4764const packageJSONCache = new SafeMap ( ) ; /* string -> PackageConfig */
4865
@@ -310,14 +327,18 @@ function resolveExportsTargetString(
310327 return subpathResolved ;
311328}
312329
313- function isArrayIndex ( key /* string */ ) { /* -> boolean */
330+ /**
331+ * @param {string } key
332+ * @returns {boolean }
333+ */
334+ function isArrayIndex ( key ) {
314335 const keyNum = + key ;
315336 if ( `${ keyNum } ` !== key ) return false ;
316337 return keyNum >= 0 && keyNum < 0xFFFF_FFFF ;
317338}
318339
319340function resolveExportsTarget (
320- packageJSONUrl , target , subpath , packageSubpath , base ) {
341+ packageJSONUrl , target , subpath , packageSubpath , base , conditions ) {
321342 if ( typeof target === 'string' ) {
322343 const resolved = resolveExportsTargetString (
323344 target , subpath , packageSubpath , packageJSONUrl , base ) ;
@@ -332,7 +353,8 @@ function resolveExportsTarget(
332353 let resolved ;
333354 try {
334355 resolved = resolveExportsTarget (
335- packageJSONUrl , targetItem , subpath , packageSubpath , base ) ;
356+ packageJSONUrl , targetItem , subpath , packageSubpath , base ,
357+ conditions ) ;
336358 } catch ( e ) {
337359 lastException = e ;
338360 if ( e . code === 'ERR_PACKAGE_PATH_NOT_EXPORTED' ||
@@ -357,11 +379,12 @@ function resolveExportsTarget(
357379 }
358380 for ( let i = 0 ; i < keys . length ; i ++ ) {
359381 const key = keys [ i ] ;
360- if ( key === 'node ' || key === 'import' || key === 'default' ) {
382+ if ( key === 'default ' || conditions . has ( key ) ) {
361383 const conditionalTarget = target [ key ] ;
362384 try {
363385 return resolveExportsTarget (
364- packageJSONUrl , conditionalTarget , subpath , packageSubpath , base ) ;
386+ packageJSONUrl , conditionalTarget , subpath , packageSubpath , base ,
387+ conditions ) ;
365388 } catch ( e ) {
366389 if ( e . code === 'ERR_PACKAGE_PATH_NOT_EXPORTED' ) continue ;
367390 throw e ;
@@ -397,16 +420,18 @@ function isConditionalExportsMainSugar(exports, packageJSONUrl, base) {
397420}
398421
399422
400- function packageMainResolve ( packageJSONUrl , packageConfig , base ) {
423+ function packageMainResolve ( packageJSONUrl , packageConfig , base , conditions ) {
401424 if ( packageConfig . exists ) {
402425 const exports = packageConfig . exports ;
403426 if ( exports !== undefined ) {
404427 if ( isConditionalExportsMainSugar ( exports , packageJSONUrl , base ) ) {
405- return resolveExportsTarget ( packageJSONUrl , exports , '' , '' , base ) ;
428+ return resolveExportsTarget ( packageJSONUrl , exports , '' , '' , base ,
429+ conditions ) ;
406430 } else if ( typeof exports === 'object' && exports !== null ) {
407431 const target = exports [ '.' ] ;
408432 if ( target !== undefined )
409- return resolveExportsTarget ( packageJSONUrl , target , '' , '' , base ) ;
433+ return resolveExportsTarget ( packageJSONUrl , target , '' , '' , base ,
434+ conditions ) ;
410435 }
411436
412437 throw new ERR_PACKAGE_PATH_NOT_EXPORTED ( packageJSONUrl , '.' ) ;
@@ -434,9 +459,16 @@ function packageMainResolve(packageJSONUrl, packageConfig, base) {
434459 fileURLToPath ( new URL ( '.' , packageJSONUrl ) ) , fileURLToPath ( base ) ) ;
435460}
436461
437-
462+ /**
463+ * @param {URL } packageJSONUrl
464+ * @param {string } packageSubpath
465+ * @param {object } packageConfig
466+ * @param {string } base
467+ * @param {Set<string> } conditions
468+ * @returns {URL }
469+ */
438470function packageExportsResolve (
439- packageJSONUrl , packageSubpath , packageConfig , base ) /* -> URL */ {
471+ packageJSONUrl , packageSubpath , packageConfig , base , conditions ) {
440472 const exports = packageConfig . exports ;
441473 if ( exports === undefined ||
442474 isConditionalExportsMainSugar ( exports , packageJSONUrl , base ) ) {
@@ -447,7 +479,7 @@ function packageExportsResolve(
447479 if ( ObjectPrototypeHasOwnProperty ( exports , packageSubpath ) ) {
448480 const target = exports [ packageSubpath ] ;
449481 const resolved = resolveExportsTarget (
450- packageJSONUrl , target , '' , packageSubpath , base ) ;
482+ packageJSONUrl , target , '' , packageSubpath , base , conditions ) ;
451483 return finalizeResolution ( resolved , base ) ;
452484 }
453485
@@ -466,7 +498,7 @@ function packageExportsResolve(
466498 const target = exports [ bestMatch ] ;
467499 const subpath = StringPrototypeSubstr ( packageSubpath , bestMatch . length ) ;
468500 const resolved = resolveExportsTarget (
469- packageJSONUrl , target , subpath , packageSubpath , base ) ;
501+ packageJSONUrl , target , subpath , packageSubpath , base , conditions ) ;
470502 return finalizeResolution ( resolved , base ) ;
471503 }
472504
@@ -478,7 +510,13 @@ function getPackageType(url) {
478510 return packageConfig . type ;
479511}
480512
481- function packageResolve ( specifier /* string */ , base /* URL */ ) { /* -> URL */
513+ /**
514+ * @param {string } specifier
515+ * @param {URL } base
516+ * @param {Set<string> } conditions
517+ * @returns {URL }
518+ */
519+ function packageResolve ( specifier , base , conditions ) {
482520 let separatorIndex = StringPrototypeIndexOf ( specifier , '/' ) ;
483521 let validPackageName = true ;
484522 let isScoped = false ;
@@ -530,10 +568,11 @@ function packageResolve(specifier /* string */, base /* URL */) { /* -> URL */
530568 if ( packageSubpath === './' ) {
531569 return new URL ( './' , packageJSONUrl ) ;
532570 } else if ( packageSubpath === '' ) {
533- return packageMainResolve ( packageJSONUrl , packageConfig , base ) ;
571+ return packageMainResolve ( packageJSONUrl , packageConfig , base ,
572+ conditions ) ;
534573 } else {
535574 return packageExportsResolve (
536- packageJSONUrl , packageSubpath , packageConfig , base ) ;
575+ packageJSONUrl , packageSubpath , packageConfig , base , conditions ) ;
537576 }
538577 }
539578 }
@@ -559,10 +598,11 @@ function packageResolve(specifier /* string */, base /* URL */) { /* -> URL */
559598 if ( packageSubpath === './' ) {
560599 return new URL ( './' , packageJSONUrl ) ;
561600 } else if ( packageSubpath === '' ) {
562- return packageMainResolve ( packageJSONUrl , packageConfig , base ) ;
601+ return packageMainResolve ( packageJSONUrl , packageConfig , base ,
602+ conditions ) ;
563603 } else if ( packageConfig . exports !== undefined ) {
564604 return packageExportsResolve (
565- packageJSONUrl , packageSubpath , packageConfig , base ) ;
605+ packageJSONUrl , packageSubpath , packageConfig , base , conditions ) ;
566606 } else {
567607 return finalizeResolution (
568608 new URL ( packageSubpath , packageJSONUrl ) , base ) ;
@@ -587,7 +627,13 @@ function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) {
587627 return false ;
588628}
589629
590- function moduleResolve ( specifier /* string */ , base /* URL */ ) { /* -> URL */
630+ /**
631+ * @param {string } specifier
632+ * @param {URL } base
633+ * @param {Set<string> } conditions
634+ * @returns {URL }
635+ */
636+ function moduleResolve ( specifier , base , conditions ) {
591637 // Order swapped from spec for minor perf gain.
592638 // Ok since relative URLs cannot parse as URLs.
593639 let resolved ;
@@ -597,13 +643,14 @@ function moduleResolve(specifier /* string */, base /* URL */) { /* -> URL */
597643 try {
598644 resolved = new URL ( specifier ) ;
599645 } catch {
600- return packageResolve ( specifier , base ) ;
646+ return packageResolve ( specifier , base , conditions ) ;
601647 }
602648 }
603649 return finalizeResolution ( resolved , base ) ;
604650}
605651
606- function defaultResolve ( specifier , { parentURL } = { } , defaultResolveUnused ) {
652+ function defaultResolve ( specifier , context = { } , defaultResolveUnused ) {
653+ let { parentURL, conditions } = context ;
607654 let parsed ;
608655 try {
609656 parsed = new URL ( specifier ) ;
@@ -641,7 +688,8 @@ function defaultResolve(specifier, { parentURL } = {}, defaultResolveUnused) {
641688 throw new ERR_INPUT_TYPE_NOT_ALLOWED ( ) ;
642689 }
643690
644- let url = moduleResolve ( specifier , new URL ( parentURL ) ) ;
691+ conditions = getConditionsSet ( conditions ) ;
692+ let url = moduleResolve ( specifier , parentURL , conditions ) ;
645693
646694 if ( isMain ? ! preserveSymlinksMain : ! preserveSymlinks ) {
647695 const urlPath = fileURLToPath ( url ) ;
@@ -658,6 +706,7 @@ function defaultResolve(specifier, { parentURL } = {}, defaultResolveUnused) {
658706}
659707
660708module . exports = {
709+ DEFAULT_CONDITIONS ,
661710 defaultResolve,
662711 getPackageType
663712} ;
0 commit comments