4
4
ArrayIsArray,
5
5
JSONParse,
6
6
JSONStringify,
7
+ ObjectFreeze,
7
8
ObjectGetOwnPropertyNames,
8
9
ObjectPrototypeHasOwnProperty,
9
10
SafeMap,
11
+ SafeSet,
10
12
StringPrototypeEndsWith,
11
13
StringPrototypeIncludes,
12
14
StringPrototypeIndexOf,
@@ -35,6 +37,7 @@ const typeFlag = getOptionValue('--input-type');
35
37
const { URL , pathToFileURL, fileURLToPath } = require ( 'internal/url' ) ;
36
38
const {
37
39
ERR_INPUT_TYPE_NOT_ALLOWED ,
40
+ ERR_INVALID_ARG_VALUE ,
38
41
ERR_INVALID_MODULE_SPECIFIER ,
39
42
ERR_INVALID_PACKAGE_CONFIG ,
40
43
ERR_INVALID_PACKAGE_TARGET ,
@@ -43,6 +46,20 @@ const {
43
46
ERR_UNSUPPORTED_ESM_URL_SCHEME ,
44
47
} = require ( 'internal/errors' ) . codes ;
45
48
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
+
46
63
const realpathCache = new SafeMap ( ) ;
47
64
const packageJSONCache = new SafeMap ( ) ; /* string -> PackageConfig */
48
65
@@ -310,14 +327,18 @@ function resolveExportsTargetString(
310
327
return subpathResolved ;
311
328
}
312
329
313
- function isArrayIndex ( key /* string */ ) { /* -> boolean */
330
+ /**
331
+ * @param {string } key
332
+ * @returns {boolean }
333
+ */
334
+ function isArrayIndex ( key ) {
314
335
const keyNum = + key ;
315
336
if ( `${ keyNum } ` !== key ) return false ;
316
337
return keyNum >= 0 && keyNum < 0xFFFF_FFFF ;
317
338
}
318
339
319
340
function resolveExportsTarget (
320
- packageJSONUrl , target , subpath , packageSubpath , base ) {
341
+ packageJSONUrl , target , subpath , packageSubpath , base , conditions ) {
321
342
if ( typeof target === 'string' ) {
322
343
const resolved = resolveExportsTargetString (
323
344
target , subpath , packageSubpath , packageJSONUrl , base ) ;
@@ -332,7 +353,8 @@ function resolveExportsTarget(
332
353
let resolved ;
333
354
try {
334
355
resolved = resolveExportsTarget (
335
- packageJSONUrl , targetItem , subpath , packageSubpath , base ) ;
356
+ packageJSONUrl , targetItem , subpath , packageSubpath , base ,
357
+ conditions ) ;
336
358
} catch ( e ) {
337
359
lastException = e ;
338
360
if ( e . code === 'ERR_PACKAGE_PATH_NOT_EXPORTED' ||
@@ -357,11 +379,12 @@ function resolveExportsTarget(
357
379
}
358
380
for ( let i = 0 ; i < keys . length ; i ++ ) {
359
381
const key = keys [ i ] ;
360
- if ( key === 'node ' || key === 'import' || key === 'default' ) {
382
+ if ( key === 'default ' || conditions . has ( key ) ) {
361
383
const conditionalTarget = target [ key ] ;
362
384
try {
363
385
return resolveExportsTarget (
364
- packageJSONUrl , conditionalTarget , subpath , packageSubpath , base ) ;
386
+ packageJSONUrl , conditionalTarget , subpath , packageSubpath , base ,
387
+ conditions ) ;
365
388
} catch ( e ) {
366
389
if ( e . code === 'ERR_PACKAGE_PATH_NOT_EXPORTED' ) continue ;
367
390
throw e ;
@@ -397,16 +420,18 @@ function isConditionalExportsMainSugar(exports, packageJSONUrl, base) {
397
420
}
398
421
399
422
400
- function packageMainResolve ( packageJSONUrl , packageConfig , base ) {
423
+ function packageMainResolve ( packageJSONUrl , packageConfig , base , conditions ) {
401
424
if ( packageConfig . exists ) {
402
425
const exports = packageConfig . exports ;
403
426
if ( exports !== undefined ) {
404
427
if ( isConditionalExportsMainSugar ( exports , packageJSONUrl , base ) ) {
405
- return resolveExportsTarget ( packageJSONUrl , exports , '' , '' , base ) ;
428
+ return resolveExportsTarget ( packageJSONUrl , exports , '' , '' , base ,
429
+ conditions ) ;
406
430
} else if ( typeof exports === 'object' && exports !== null ) {
407
431
const target = exports [ '.' ] ;
408
432
if ( target !== undefined )
409
- return resolveExportsTarget ( packageJSONUrl , target , '' , '' , base ) ;
433
+ return resolveExportsTarget ( packageJSONUrl , target , '' , '' , base ,
434
+ conditions ) ;
410
435
}
411
436
412
437
throw new ERR_PACKAGE_PATH_NOT_EXPORTED ( packageJSONUrl , '.' ) ;
@@ -434,9 +459,16 @@ function packageMainResolve(packageJSONUrl, packageConfig, base) {
434
459
fileURLToPath ( new URL ( '.' , packageJSONUrl ) ) , fileURLToPath ( base ) ) ;
435
460
}
436
461
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
+ */
438
470
function packageExportsResolve (
439
- packageJSONUrl , packageSubpath , packageConfig , base ) /* -> URL */ {
471
+ packageJSONUrl , packageSubpath , packageConfig , base , conditions ) {
440
472
const exports = packageConfig . exports ;
441
473
if ( exports === undefined ||
442
474
isConditionalExportsMainSugar ( exports , packageJSONUrl , base ) ) {
@@ -447,7 +479,7 @@ function packageExportsResolve(
447
479
if ( ObjectPrototypeHasOwnProperty ( exports , packageSubpath ) ) {
448
480
const target = exports [ packageSubpath ] ;
449
481
const resolved = resolveExportsTarget (
450
- packageJSONUrl , target , '' , packageSubpath , base ) ;
482
+ packageJSONUrl , target , '' , packageSubpath , base , conditions ) ;
451
483
return finalizeResolution ( resolved , base ) ;
452
484
}
453
485
@@ -466,7 +498,7 @@ function packageExportsResolve(
466
498
const target = exports [ bestMatch ] ;
467
499
const subpath = StringPrototypeSubstr ( packageSubpath , bestMatch . length ) ;
468
500
const resolved = resolveExportsTarget (
469
- packageJSONUrl , target , subpath , packageSubpath , base ) ;
501
+ packageJSONUrl , target , subpath , packageSubpath , base , conditions ) ;
470
502
return finalizeResolution ( resolved , base ) ;
471
503
}
472
504
@@ -478,7 +510,13 @@ function getPackageType(url) {
478
510
return packageConfig . type ;
479
511
}
480
512
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 ) {
482
520
let separatorIndex = StringPrototypeIndexOf ( specifier , '/' ) ;
483
521
let validPackageName = true ;
484
522
let isScoped = false ;
@@ -530,10 +568,11 @@ function packageResolve(specifier /* string */, base /* URL */) { /* -> URL */
530
568
if ( packageSubpath === './' ) {
531
569
return new URL ( './' , packageJSONUrl ) ;
532
570
} else if ( packageSubpath === '' ) {
533
- return packageMainResolve ( packageJSONUrl , packageConfig , base ) ;
571
+ return packageMainResolve ( packageJSONUrl , packageConfig , base ,
572
+ conditions ) ;
534
573
} else {
535
574
return packageExportsResolve (
536
- packageJSONUrl , packageSubpath , packageConfig , base ) ;
575
+ packageJSONUrl , packageSubpath , packageConfig , base , conditions ) ;
537
576
}
538
577
}
539
578
}
@@ -559,10 +598,11 @@ function packageResolve(specifier /* string */, base /* URL */) { /* -> URL */
559
598
if ( packageSubpath === './' ) {
560
599
return new URL ( './' , packageJSONUrl ) ;
561
600
} else if ( packageSubpath === '' ) {
562
- return packageMainResolve ( packageJSONUrl , packageConfig , base ) ;
601
+ return packageMainResolve ( packageJSONUrl , packageConfig , base ,
602
+ conditions ) ;
563
603
} else if ( packageConfig . exports !== undefined ) {
564
604
return packageExportsResolve (
565
- packageJSONUrl , packageSubpath , packageConfig , base ) ;
605
+ packageJSONUrl , packageSubpath , packageConfig , base , conditions ) ;
566
606
} else {
567
607
return finalizeResolution (
568
608
new URL ( packageSubpath , packageJSONUrl ) , base ) ;
@@ -587,7 +627,13 @@ function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) {
587
627
return false ;
588
628
}
589
629
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 ) {
591
637
// Order swapped from spec for minor perf gain.
592
638
// Ok since relative URLs cannot parse as URLs.
593
639
let resolved ;
@@ -597,13 +643,14 @@ function moduleResolve(specifier /* string */, base /* URL */) { /* -> URL */
597
643
try {
598
644
resolved = new URL ( specifier ) ;
599
645
} catch {
600
- return packageResolve ( specifier , base ) ;
646
+ return packageResolve ( specifier , base , conditions ) ;
601
647
}
602
648
}
603
649
return finalizeResolution ( resolved , base ) ;
604
650
}
605
651
606
- function defaultResolve ( specifier , { parentURL } = { } , defaultResolveUnused ) {
652
+ function defaultResolve ( specifier , context = { } , defaultResolveUnused ) {
653
+ let { parentURL, conditions } = context ;
607
654
let parsed ;
608
655
try {
609
656
parsed = new URL ( specifier ) ;
@@ -641,7 +688,8 @@ function defaultResolve(specifier, { parentURL } = {}, defaultResolveUnused) {
641
688
throw new ERR_INPUT_TYPE_NOT_ALLOWED ( ) ;
642
689
}
643
690
644
- let url = moduleResolve ( specifier , new URL ( parentURL ) ) ;
691
+ conditions = getConditionsSet ( conditions ) ;
692
+ let url = moduleResolve ( specifier , parentURL , conditions ) ;
645
693
646
694
if ( isMain ? ! preserveSymlinksMain : ! preserveSymlinks ) {
647
695
const urlPath = fileURLToPath ( url ) ;
@@ -658,6 +706,7 @@ function defaultResolve(specifier, { parentURL } = {}, defaultResolveUnused) {
658
706
}
659
707
660
708
module . exports = {
709
+ DEFAULT_CONDITIONS ,
661
710
defaultResolve,
662
711
getPackageType
663
712
} ;
0 commit comments