@rollup/plugin-node-resolve 15.1.0 → 15.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/dist/cjs/index.js +340 -265
- package/dist/es/index.js +340 -265
- package/package.json +1 -1
- package/types/index.d.ts +8 -0
package/dist/cjs/index.js
CHANGED
@@ -12,7 +12,7 @@ var url = require('url');
|
|
12
12
|
var resolve = require('resolve');
|
13
13
|
var pluginutils = require('@rollup/pluginutils');
|
14
14
|
|
15
|
-
var version = "15.1
|
15
|
+
var version = "15.2.1";
|
16
16
|
var peerDependencies = {
|
17
17
|
rollup: "^2.78.0||^3.0.0"
|
18
18
|
};
|
@@ -21,18 +21,17 @@ util.promisify(fs.access);
|
|
21
21
|
const readFile$1 = util.promisify(fs.readFile);
|
22
22
|
const realpath = util.promisify(fs.realpath);
|
23
23
|
const stat = util.promisify(fs.stat);
|
24
|
-
|
25
24
|
async function fileExists(filePath) {
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
try {
|
26
|
+
const res = await stat(filePath);
|
27
|
+
return res.isFile();
|
28
|
+
}
|
29
|
+
catch {
|
30
|
+
return false;
|
31
|
+
}
|
32
32
|
}
|
33
|
-
|
34
33
|
async function resolveSymlink(path) {
|
35
|
-
|
34
|
+
return (await fileExists(path)) ? realpath(path) : path;
|
36
35
|
}
|
37
36
|
|
38
37
|
const onError = (error) => {
|
@@ -308,303 +307,372 @@ function normalizeInput(input) {
|
|
308
307
|
}
|
309
308
|
|
310
309
|
/* eslint-disable no-await-in-loop */
|
311
|
-
|
312
310
|
function isModuleDir(current, moduleDirs) {
|
313
|
-
|
311
|
+
return moduleDirs.some((dir) => current.endsWith(dir));
|
314
312
|
}
|
315
|
-
|
316
313
|
async function findPackageJson(base, moduleDirs) {
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
314
|
+
const { root } = path.parse(base);
|
315
|
+
let current = base;
|
316
|
+
while (current !== root && !isModuleDir(current, moduleDirs)) {
|
317
|
+
const pkgJsonPath = path.join(current, 'package.json');
|
318
|
+
if (await fileExists(pkgJsonPath)) {
|
319
|
+
const pkgJsonString = fs.readFileSync(pkgJsonPath, 'utf-8');
|
320
|
+
return { pkgJson: JSON.parse(pkgJsonString), pkgPath: current, pkgJsonPath };
|
321
|
+
}
|
322
|
+
current = path.resolve(current, '..');
|
325
323
|
}
|
326
|
-
|
327
|
-
}
|
328
|
-
return null;
|
324
|
+
return null;
|
329
325
|
}
|
330
|
-
|
331
326
|
function isUrl(str) {
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
327
|
+
try {
|
328
|
+
return !!new URL(str);
|
329
|
+
}
|
330
|
+
catch (_) {
|
331
|
+
return false;
|
332
|
+
}
|
337
333
|
}
|
338
|
-
|
334
|
+
/**
|
335
|
+
* Conditions is an export object where all keys are conditions like 'node' (aka do not with '.')
|
336
|
+
*/
|
339
337
|
function isConditions(exports) {
|
340
|
-
|
338
|
+
return typeof exports === 'object' && Object.keys(exports).every((k) => !k.startsWith('.'));
|
341
339
|
}
|
342
|
-
|
340
|
+
/**
|
341
|
+
* Mappings is an export object where all keys start with '.
|
342
|
+
*/
|
343
343
|
function isMappings(exports) {
|
344
|
-
|
344
|
+
return typeof exports === 'object' && !isConditions(exports);
|
345
345
|
}
|
346
|
-
|
346
|
+
/**
|
347
|
+
* Check for mixed exports, which are exports where some keys start with '.' and some do not
|
348
|
+
*/
|
347
349
|
function isMixedExports(exports) {
|
348
|
-
|
349
|
-
|
350
|
+
const keys = Object.keys(exports);
|
351
|
+
return keys.some((k) => k.startsWith('.')) && keys.some((k) => !k.startsWith('.'));
|
350
352
|
}
|
351
|
-
|
352
353
|
function createBaseErrorMsg(importSpecifier, importer) {
|
353
|
-
|
354
|
+
return `Could not resolve import "${importSpecifier}" in ${importer}`;
|
354
355
|
}
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
356
|
+
function createErrorMsg(context, reason, isImports) {
|
357
|
+
const { importSpecifier, importer, pkgJsonPath } = context;
|
358
|
+
const base = createBaseErrorMsg(importSpecifier, importer);
|
359
|
+
const field = isImports ? 'imports' : 'exports';
|
360
|
+
return `${base} using ${field} defined in ${pkgJsonPath}.${reason ? ` ${reason}` : ''}`;
|
361
|
+
}
|
362
|
+
class ResolveError extends Error {
|
361
363
|
}
|
362
|
-
|
363
|
-
class ResolveError extends Error {}
|
364
|
-
|
365
364
|
class InvalidConfigurationError extends ResolveError {
|
366
|
-
|
367
|
-
|
368
|
-
|
365
|
+
constructor(context, reason) {
|
366
|
+
super(createErrorMsg(context, `Invalid "exports" field. ${reason}`));
|
367
|
+
}
|
369
368
|
}
|
370
|
-
|
371
369
|
class InvalidModuleSpecifierError extends ResolveError {
|
372
|
-
|
373
|
-
|
374
|
-
|
370
|
+
constructor(context, isImports, reason) {
|
371
|
+
super(createErrorMsg(context, reason, isImports));
|
372
|
+
}
|
375
373
|
}
|
376
|
-
|
377
374
|
class InvalidPackageTargetError extends ResolveError {
|
378
|
-
|
379
|
-
|
380
|
-
|
375
|
+
constructor(context, reason) {
|
376
|
+
super(createErrorMsg(context, reason));
|
377
|
+
}
|
381
378
|
}
|
382
379
|
|
383
380
|
/* eslint-disable no-await-in-loop, no-undefined */
|
384
|
-
|
381
|
+
/**
|
382
|
+
* Check for invalid path segments
|
383
|
+
*/
|
385
384
|
function includesInvalidSegments(pathSegments, moduleDirs) {
|
386
|
-
|
387
|
-
.
|
388
|
-
.
|
389
|
-
.some((t) => ['.', '..', ...moduleDirs].includes(t));
|
385
|
+
const invalidSegments = ['', '.', '..', ...moduleDirs];
|
386
|
+
// contains any "", ".", "..", or "node_modules" segments, including percent encoded variants
|
387
|
+
return pathSegments.some((v) => invalidSegments.includes(v) || invalidSegments.includes(decodeURI(v)));
|
390
388
|
}
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
389
|
+
async function resolvePackageTarget(context, { target, patternMatch, isImports }) {
|
390
|
+
// If target is a String, then
|
391
|
+
if (typeof target === 'string') {
|
392
|
+
// If target does not start with "./", then
|
393
|
+
if (!target.startsWith('./')) {
|
394
|
+
// If isImports is false, or if target starts with "../" or "/", or if target is a valid URL, then
|
395
|
+
if (!isImports || ['/', '../'].some((p) => target.startsWith(p)) || isUrl(target)) {
|
396
|
+
// Throw an Invalid Package Target error.
|
397
|
+
throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
|
398
|
+
}
|
399
|
+
// If patternMatch is a String, then
|
400
|
+
if (typeof patternMatch === 'string') {
|
401
|
+
// Return PACKAGE_RESOLVE(target with every instance of "*" replaced by patternMatch, packageURL + "/")
|
402
|
+
const result = await context.resolveId(target.replace(/\*/g, patternMatch), context.pkgURL.href);
|
403
|
+
return result ? url.pathToFileURL(result.location).href : null;
|
404
|
+
}
|
405
|
+
// Return PACKAGE_RESOLVE(target, packageURL + "/").
|
406
|
+
const result = await context.resolveId(target, context.pkgURL.href);
|
407
|
+
return result ? url.pathToFileURL(result.location).href : null;
|
408
|
+
}
|
409
|
+
// TODO: Drop if we do not support Node <= 16 anymore
|
410
|
+
// This behavior was removed in Node 17 (deprecated in Node 14), see DEP0148
|
411
|
+
if (context.allowExportsFolderMapping) {
|
412
|
+
target = target.replace(/\/$/, '/*');
|
413
|
+
}
|
414
|
+
// If target split on "/" or "\"
|
415
|
+
{
|
416
|
+
const pathSegments = target.split(/\/|\\/);
|
417
|
+
// after the first "." segment
|
418
|
+
const firstDot = pathSegments.indexOf('.');
|
419
|
+
firstDot !== -1 && pathSegments.slice(firstDot);
|
420
|
+
if (firstDot !== -1 &&
|
421
|
+
firstDot < pathSegments.length - 1 &&
|
422
|
+
includesInvalidSegments(pathSegments.slice(firstDot + 1), context.moduleDirs)) {
|
423
|
+
throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
|
424
|
+
}
|
425
|
+
}
|
426
|
+
// Let resolvedTarget be the URL resolution of the concatenation of packageURL and target.
|
427
|
+
const resolvedTarget = new URL(target, context.pkgURL);
|
428
|
+
// Assert: resolvedTarget is contained in packageURL.
|
429
|
+
if (!resolvedTarget.href.startsWith(context.pkgURL.href)) {
|
430
|
+
throw new InvalidPackageTargetError(context, `Resolved to ${resolvedTarget.href} which is outside package ${context.pkgURL.href}`);
|
431
|
+
}
|
432
|
+
// If patternMatch is null, then
|
433
|
+
if (!patternMatch) {
|
434
|
+
// Return resolvedTarget.
|
435
|
+
return resolvedTarget;
|
436
|
+
}
|
437
|
+
// If patternMatch split on "/" or "\" contains invalid segments
|
438
|
+
if (includesInvalidSegments(patternMatch.split(/\/|\\/), context.moduleDirs)) {
|
439
|
+
// throw an Invalid Module Specifier error.
|
440
|
+
throw new InvalidModuleSpecifierError(context);
|
441
|
+
}
|
442
|
+
// Return the URL resolution of resolvedTarget with every instance of "*" replaced with patternMatch.
|
443
|
+
return resolvedTarget.href.replace(/\*/g, patternMatch);
|
396
444
|
}
|
397
|
-
|
398
|
-
if (
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
const result = await context.resolveId(
|
403
|
-
target.replace(/\*/g, subpath),
|
404
|
-
context.pkgURL.href
|
405
|
-
);
|
406
|
-
return result ? url.pathToFileURL(result.location).href : null;
|
445
|
+
// Otherwise, if target is an Array, then
|
446
|
+
if (Array.isArray(target)) {
|
447
|
+
// If _target.length is zero, return null.
|
448
|
+
if (target.length === 0) {
|
449
|
+
return null;
|
407
450
|
}
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
451
|
+
let lastError = null;
|
452
|
+
// For each item in target, do
|
453
|
+
for (const item of target) {
|
454
|
+
// Let resolved be the result of PACKAGE_TARGET_RESOLVE of the item
|
455
|
+
// continuing the loop on any Invalid Package Target error.
|
456
|
+
try {
|
457
|
+
const resolved = await resolvePackageTarget(context, {
|
458
|
+
target: item,
|
459
|
+
patternMatch,
|
460
|
+
isImports
|
461
|
+
});
|
462
|
+
// If resolved is undefined, continue the loop.
|
463
|
+
// Else Return resolved.
|
464
|
+
if (resolved !== undefined) {
|
465
|
+
return resolved;
|
466
|
+
}
|
467
|
+
}
|
468
|
+
catch (error) {
|
469
|
+
if (!(error instanceof InvalidPackageTargetError)) {
|
470
|
+
throw error;
|
471
|
+
}
|
472
|
+
else {
|
473
|
+
lastError = error;
|
474
|
+
}
|
475
|
+
}
|
476
|
+
}
|
477
|
+
// Return or throw the last fallback resolution null return or error
|
478
|
+
if (lastError) {
|
479
|
+
throw lastError;
|
480
|
+
}
|
481
|
+
return null;
|
413
482
|
}
|
414
|
-
|
415
|
-
if (
|
416
|
-
|
483
|
+
// Otherwise, if target is a non-null Object, then
|
484
|
+
if (target && typeof target === 'object') {
|
485
|
+
// For each property of target
|
486
|
+
for (const [key, value] of Object.entries(target)) {
|
487
|
+
// If exports contains any index property keys, as defined in ECMA-262 6.1.7 Array Index, throw an Invalid Package Configuration error.
|
488
|
+
// TODO: We do not check if the key is a number here...
|
489
|
+
// If key equals "default" or conditions contains an entry for the key, then
|
490
|
+
if (key === 'default' || context.conditions.includes(key)) {
|
491
|
+
// Let targetValue be the value of the property in target.
|
492
|
+
// Let resolved be the result of PACKAGE_TARGET_RESOLVE of the targetValue
|
493
|
+
const resolved = await resolvePackageTarget(context, {
|
494
|
+
target: value,
|
495
|
+
patternMatch,
|
496
|
+
isImports
|
497
|
+
});
|
498
|
+
// If resolved is equal to undefined, continue the loop.
|
499
|
+
// Return resolved.
|
500
|
+
if (resolved !== undefined) {
|
501
|
+
return resolved;
|
502
|
+
}
|
503
|
+
}
|
504
|
+
}
|
505
|
+
// Return undefined.
|
506
|
+
return undefined;
|
417
507
|
}
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
throw new InvalidPackageTargetError(
|
422
|
-
context,
|
423
|
-
`Resolved to ${resolvedTarget.href} which is outside package ${context.pkgURL.href}`
|
424
|
-
);
|
508
|
+
// Otherwise, if target is null, return null.
|
509
|
+
if (target === null) {
|
510
|
+
return null;
|
425
511
|
}
|
512
|
+
// Otherwise throw an Invalid Package Target error.
|
513
|
+
throw new InvalidPackageTargetError(context, `Invalid exports field.`);
|
514
|
+
}
|
426
515
|
|
427
|
-
|
428
|
-
|
516
|
+
/* eslint-disable no-await-in-loop */
|
517
|
+
/**
|
518
|
+
* Implementation of Node's `PATTERN_KEY_COMPARE` function
|
519
|
+
*/
|
520
|
+
function nodePatternKeyCompare(keyA, keyB) {
|
521
|
+
// Let baseLengthA be the index of "*" in keyA plus one, if keyA contains "*", or the length of keyA otherwise.
|
522
|
+
const baseLengthA = keyA.includes('*') ? keyA.indexOf('*') + 1 : keyA.length;
|
523
|
+
// Let baseLengthB be the index of "*" in keyB plus one, if keyB contains "*", or the length of keyB otherwise.
|
524
|
+
const baseLengthB = keyB.includes('*') ? keyB.indexOf('*') + 1 : keyB.length;
|
525
|
+
// if baseLengthA is greater, return -1, if lower 1
|
526
|
+
const rval = baseLengthB - baseLengthA;
|
527
|
+
if (rval !== 0)
|
528
|
+
return rval;
|
529
|
+
// If keyA does not contain "*", return 1.
|
530
|
+
if (!keyA.includes('*'))
|
531
|
+
return 1;
|
532
|
+
// If keyB does not contain "*", return -1.
|
533
|
+
if (!keyB.includes('*'))
|
534
|
+
return -1;
|
535
|
+
// If the length of keyA is greater than the length of keyB, return -1.
|
536
|
+
// If the length of keyB is greater than the length of keyA, return 1.
|
537
|
+
// Else Return 0.
|
538
|
+
return keyB.length - keyA.length;
|
539
|
+
}
|
540
|
+
async function resolvePackageImportsExports(context, { matchKey, matchObj, isImports }) {
|
541
|
+
// If matchKey is a key of matchObj and does not contain "*", then
|
542
|
+
if (!matchKey.includes('*') && matchKey in matchObj) {
|
543
|
+
// Let target be the value of matchObj[matchKey].
|
544
|
+
const target = matchObj[matchKey];
|
545
|
+
// Return the result of PACKAGE_TARGET_RESOLVE(packageURL, target, null, isImports, conditions).
|
546
|
+
const resolved = await resolvePackageTarget(context, { target, patternMatch: '', isImports });
|
547
|
+
return resolved;
|
429
548
|
}
|
430
|
-
|
431
|
-
|
432
|
-
|
549
|
+
// Let expansionKeys be the list of keys of matchObj containing only a single "*"
|
550
|
+
const expansionKeys = Object.keys(matchObj)
|
551
|
+
// Assert: ends with "/" or contains only a single "*".
|
552
|
+
.filter((k) => k.endsWith('/') || k.includes('*'))
|
553
|
+
// sorted by the sorting function PATTERN_KEY_COMPARE which orders in descending order of specificity.
|
554
|
+
.sort(nodePatternKeyCompare);
|
555
|
+
// For each key expansionKey in expansionKeys, do
|
556
|
+
for (const expansionKey of expansionKeys) {
|
557
|
+
const indexOfAsterisk = expansionKey.indexOf('*');
|
558
|
+
// Let patternBase be the substring of expansionKey up to but excluding the first "*" character.
|
559
|
+
const patternBase = indexOfAsterisk === -1 ? expansionKey : expansionKey.substring(0, indexOfAsterisk);
|
560
|
+
// If matchKey starts with but is not equal to patternBase, then
|
561
|
+
if (matchKey.startsWith(patternBase) && matchKey !== patternBase) {
|
562
|
+
// Let patternTrailer be the substring of expansionKey from the index after the first "*" character.
|
563
|
+
const patternTrailer = indexOfAsterisk !== -1 ? expansionKey.substring(indexOfAsterisk + 1) : '';
|
564
|
+
// If patternTrailer has zero length,
|
565
|
+
if (patternTrailer.length === 0 ||
|
566
|
+
// or if matchKey ends with patternTrailer and the length of matchKey is greater than or equal to the length of expansionKey, then
|
567
|
+
(matchKey.endsWith(patternTrailer) && matchKey.length >= expansionKey.length)) {
|
568
|
+
// Let target be the value of matchObj[expansionKey].
|
569
|
+
const target = matchObj[expansionKey];
|
570
|
+
// Let patternMatch be the substring of matchKey starting at the index of the length of patternBase up to the length
|
571
|
+
// of matchKey minus the length of patternTrailer.
|
572
|
+
const patternMatch = matchKey.substring(patternBase.length, matchKey.length - patternTrailer.length);
|
573
|
+
// Return the result of PACKAGE_TARGET_RESOLVE
|
574
|
+
const resolved = await resolvePackageTarget(context, {
|
575
|
+
target,
|
576
|
+
patternMatch,
|
577
|
+
isImports
|
578
|
+
});
|
579
|
+
return resolved;
|
580
|
+
}
|
581
|
+
}
|
433
582
|
}
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
if (Array.isArray(target)) {
|
438
|
-
let lastError;
|
439
|
-
for (const item of target) {
|
440
|
-
try {
|
441
|
-
const resolved = await resolvePackageTarget(context, {
|
442
|
-
target: item,
|
443
|
-
subpath,
|
444
|
-
pattern,
|
445
|
-
internal
|
446
|
-
});
|
583
|
+
throw new InvalidModuleSpecifierError(context, isImports);
|
584
|
+
}
|
447
585
|
|
448
|
-
|
449
|
-
|
450
|
-
|
586
|
+
/**
|
587
|
+
* Implementation of PACKAGE_EXPORTS_RESOLVE
|
588
|
+
*/
|
589
|
+
async function resolvePackageExports(context, subpath, exports) {
|
590
|
+
// If exports is an Object with both a key starting with "." and a key not starting with "."
|
591
|
+
if (isMixedExports(exports)) {
|
592
|
+
// throw an Invalid Package Configuration error.
|
593
|
+
throw new InvalidConfigurationError(context, 'All keys must either start with ./, or without one.');
|
594
|
+
}
|
595
|
+
// If subpath is equal to ".", then
|
596
|
+
if (subpath === '.') {
|
597
|
+
// Let mainExport be undefined.
|
598
|
+
let mainExport;
|
599
|
+
// If exports is a String or Array, or an Object containing no keys starting with ".", then
|
600
|
+
if (typeof exports === 'string' || Array.isArray(exports) || isConditions(exports)) {
|
601
|
+
// Set mainExport to exports
|
602
|
+
mainExport = exports;
|
603
|
+
// Otherwise if exports is an Object containing a "." property, then
|
451
604
|
}
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
} else {
|
456
|
-
lastError = error;
|
605
|
+
else if (isMappings(exports)) {
|
606
|
+
// Set mainExport to exports["."]
|
607
|
+
mainExport = exports['.'];
|
457
608
|
}
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
609
|
+
// If mainExport is not undefined, then
|
610
|
+
if (mainExport) {
|
611
|
+
// Let resolved be the result of PACKAGE_TARGET_RESOLVE with target = mainExport
|
612
|
+
const resolved = await resolvePackageTarget(context, {
|
613
|
+
target: mainExport,
|
614
|
+
patternMatch: '',
|
615
|
+
isImports: false
|
616
|
+
});
|
617
|
+
// If resolved is not null or undefined, return resolved.
|
618
|
+
if (resolved) {
|
619
|
+
return resolved;
|
620
|
+
}
|
621
|
+
}
|
622
|
+
// Otherwise, if exports is an Object and all keys of exports start with ".", then
|
463
623
|
}
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
const resolved = await resolvePackageTarget(context, {
|
471
|
-
target: value,
|
472
|
-
subpath,
|
473
|
-
pattern,
|
474
|
-
internal
|
624
|
+
else if (isMappings(exports)) {
|
625
|
+
// Let resolved be the result of PACKAGE_IMPORTS_EXPORTS_RESOLVE
|
626
|
+
const resolvedMatch = await resolvePackageImportsExports(context, {
|
627
|
+
matchKey: subpath,
|
628
|
+
matchObj: exports,
|
629
|
+
isImports: false
|
475
630
|
});
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
return resolved;
|
631
|
+
// If resolved is not null or undefined, return resolved.
|
632
|
+
if (resolvedMatch) {
|
633
|
+
return resolvedMatch;
|
480
634
|
}
|
481
|
-
}
|
482
635
|
}
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
if (target === null) {
|
487
|
-
return null;
|
488
|
-
}
|
489
|
-
|
490
|
-
throw new InvalidPackageTargetError(context, `Invalid exports field.`);
|
636
|
+
// Throw a Package Path Not Exported error.
|
637
|
+
throw new InvalidModuleSpecifierError(context);
|
491
638
|
}
|
492
639
|
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
const target = matchObj[matchKey];
|
498
|
-
const resolved = await resolvePackageTarget(context, { target, subpath: '', internal });
|
499
|
-
return resolved;
|
500
|
-
}
|
501
|
-
|
502
|
-
const expansionKeys = Object.keys(matchObj)
|
503
|
-
.filter((k) => k.endsWith('/') || k.endsWith('*'))
|
504
|
-
.sort((a, b) => b.length - a.length);
|
505
|
-
|
506
|
-
for (const expansionKey of expansionKeys) {
|
507
|
-
const prefix = expansionKey.substring(0, expansionKey.length - 1);
|
508
|
-
|
509
|
-
if (expansionKey.endsWith('*') && matchKey.startsWith(prefix)) {
|
510
|
-
const target = matchObj[expansionKey];
|
511
|
-
const subpath = matchKey.substring(expansionKey.length - 1);
|
512
|
-
const resolved = await resolvePackageTarget(context, {
|
513
|
-
target,
|
514
|
-
subpath,
|
515
|
-
pattern: true,
|
516
|
-
internal
|
517
|
-
});
|
518
|
-
return resolved;
|
640
|
+
async function resolvePackageImports({ importSpecifier, importer, moduleDirs, conditions, resolveId }) {
|
641
|
+
const result = await findPackageJson(importer, moduleDirs);
|
642
|
+
if (!result) {
|
643
|
+
throw new Error(`${createBaseErrorMsg(importSpecifier, importer)}. Could not find a parent package.json.`);
|
519
644
|
}
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
645
|
+
const { pkgPath, pkgJsonPath, pkgJson } = result;
|
646
|
+
const pkgURL = url.pathToFileURL(`${pkgPath}/`);
|
647
|
+
const context = {
|
648
|
+
importer,
|
649
|
+
importSpecifier,
|
650
|
+
moduleDirs,
|
651
|
+
pkgURL,
|
652
|
+
pkgJsonPath,
|
653
|
+
conditions,
|
654
|
+
resolveId
|
655
|
+
};
|
656
|
+
// Assert: specifier begins with "#".
|
657
|
+
if (!importSpecifier.startsWith('#')) {
|
658
|
+
throw new InvalidModuleSpecifierError(context, true, 'Invalid import specifier.');
|
527
659
|
}
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
async function resolvePackageExports(context, subpath, exports) {
|
534
|
-
if (isMixedExports(exports)) {
|
535
|
-
throw new InvalidConfigurationError(
|
536
|
-
context,
|
537
|
-
'All keys must either start with ./, or without one.'
|
538
|
-
);
|
539
|
-
}
|
540
|
-
|
541
|
-
if (subpath === '.') {
|
542
|
-
let mainExport;
|
543
|
-
// If exports is a String or Array, or an Object containing no keys starting with ".", then
|
544
|
-
if (typeof exports === 'string' || Array.isArray(exports) || isConditions(exports)) {
|
545
|
-
mainExport = exports;
|
546
|
-
} else if (isMappings(exports)) {
|
547
|
-
mainExport = exports['.'];
|
660
|
+
// If specifier is exactly equal to "#" or starts with "#/", then
|
661
|
+
if (importSpecifier === '#' || importSpecifier.startsWith('#/')) {
|
662
|
+
// Throw an Invalid Module Specifier error.
|
663
|
+
throw new InvalidModuleSpecifierError(context, true, 'Invalid import specifier.');
|
548
664
|
}
|
549
|
-
|
550
|
-
if (
|
551
|
-
|
552
|
-
if (resolved) {
|
553
|
-
return resolved;
|
554
|
-
}
|
665
|
+
const { imports } = pkgJson;
|
666
|
+
if (!imports) {
|
667
|
+
throw new InvalidModuleSpecifierError(context, true);
|
555
668
|
}
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
669
|
+
// Let packageURL be the result of LOOKUP_PACKAGE_SCOPE(parentURL).
|
670
|
+
// If packageURL is not null, then
|
671
|
+
return resolvePackageImportsExports(context, {
|
672
|
+
matchKey: importSpecifier,
|
673
|
+
matchObj: imports,
|
674
|
+
isImports: true
|
560
675
|
});
|
561
|
-
|
562
|
-
if (resolvedMatch) {
|
563
|
-
return resolvedMatch;
|
564
|
-
}
|
565
|
-
}
|
566
|
-
|
567
|
-
throw new InvalidModuleSpecifierError(context);
|
568
|
-
}
|
569
|
-
|
570
|
-
async function resolvePackageImports({
|
571
|
-
importSpecifier,
|
572
|
-
importer,
|
573
|
-
moduleDirs,
|
574
|
-
conditions,
|
575
|
-
resolveId
|
576
|
-
}) {
|
577
|
-
const result = await findPackageJson(importer, moduleDirs);
|
578
|
-
if (!result) {
|
579
|
-
throw new Error(createBaseErrorMsg('. Could not find a parent package.json.'));
|
580
|
-
}
|
581
|
-
|
582
|
-
const { pkgPath, pkgJsonPath, pkgJson } = result;
|
583
|
-
const pkgURL = url.pathToFileURL(`${pkgPath}/`);
|
584
|
-
const context = {
|
585
|
-
importer,
|
586
|
-
importSpecifier,
|
587
|
-
moduleDirs,
|
588
|
-
pkgURL,
|
589
|
-
pkgJsonPath,
|
590
|
-
conditions,
|
591
|
-
resolveId
|
592
|
-
};
|
593
|
-
|
594
|
-
const { imports } = pkgJson;
|
595
|
-
if (!imports) {
|
596
|
-
throw new InvalidModuleSpecifierError(context, true);
|
597
|
-
}
|
598
|
-
|
599
|
-
if (importSpecifier === '#' || importSpecifier.startsWith('#/')) {
|
600
|
-
throw new InvalidModuleSpecifierError(context, true, 'Invalid import specifier.');
|
601
|
-
}
|
602
|
-
|
603
|
-
return resolvePackageImportsExports(context, {
|
604
|
-
matchKey: importSpecifier,
|
605
|
-
matchObj: imports,
|
606
|
-
internal: true
|
607
|
-
});
|
608
676
|
}
|
609
677
|
|
610
678
|
const resolveImportPath = util.promisify(resolve);
|
@@ -709,7 +777,8 @@ async function resolveWithExportMap({
|
|
709
777
|
moduleDirectories,
|
710
778
|
modulePaths,
|
711
779
|
rootDir,
|
712
|
-
ignoreSideEffectsForRoot
|
780
|
+
ignoreSideEffectsForRoot,
|
781
|
+
allowExportsFolderMapping
|
713
782
|
}) {
|
714
783
|
if (importSpecifier.startsWith('#')) {
|
715
784
|
// this is a package internal import, resolve using package imports field
|
@@ -798,6 +867,7 @@ async function resolveWithExportMap({
|
|
798
867
|
moduleDirs: moduleDirectories,
|
799
868
|
pkgURL,
|
800
869
|
pkgJsonPath,
|
870
|
+
allowExportsFolderMapping,
|
801
871
|
conditions: exportConditions
|
802
872
|
};
|
803
873
|
const resolvedPackageExport = await resolvePackageExports(context, subpath, pkgJson.exports);
|
@@ -878,7 +948,8 @@ async function resolveImportSpecifiers({
|
|
878
948
|
moduleDirectories,
|
879
949
|
modulePaths,
|
880
950
|
rootDir,
|
881
|
-
ignoreSideEffectsForRoot
|
951
|
+
ignoreSideEffectsForRoot,
|
952
|
+
allowExportsFolderMapping
|
882
953
|
}) {
|
883
954
|
try {
|
884
955
|
const exportMapRes = await resolveWithExportMap({
|
@@ -894,7 +965,8 @@ async function resolveImportSpecifiers({
|
|
894
965
|
moduleDirectories,
|
895
966
|
modulePaths,
|
896
967
|
rootDir,
|
897
|
-
ignoreSideEffectsForRoot
|
968
|
+
ignoreSideEffectsForRoot,
|
969
|
+
allowExportsFolderMapping
|
898
970
|
});
|
899
971
|
if (exportMapRes) return exportMapRes;
|
900
972
|
} catch (error) {
|
@@ -981,7 +1053,9 @@ const defaults = {
|
|
981
1053
|
extensions: ['.mjs', '.js', '.json', '.node'],
|
982
1054
|
resolveOnly: [],
|
983
1055
|
moduleDirectories: ['node_modules'],
|
984
|
-
ignoreSideEffectsForRoot: false
|
1056
|
+
ignoreSideEffectsForRoot: false,
|
1057
|
+
// TODO: set to false in next major release or remove
|
1058
|
+
allowExportsFolderMapping: true
|
985
1059
|
};
|
986
1060
|
const DEFAULTS = deepFreeze(deepMerge({}, defaults));
|
987
1061
|
|
@@ -1127,7 +1201,8 @@ function nodeResolve(opts = {}) {
|
|
1127
1201
|
moduleDirectories,
|
1128
1202
|
modulePaths,
|
1129
1203
|
rootDir,
|
1130
|
-
ignoreSideEffectsForRoot
|
1204
|
+
ignoreSideEffectsForRoot,
|
1205
|
+
allowExportsFolderMapping: options.allowExportsFolderMapping
|
1131
1206
|
});
|
1132
1207
|
|
1133
1208
|
const importeeIsBuiltin = isBuiltinModule(importee);
|
@@ -1245,7 +1320,7 @@ function nodeResolve(opts = {}) {
|
|
1245
1320
|
// `moduleSideEffects` information.
|
1246
1321
|
const resolvedResolved = await this.resolve(resolved.id, importer, {
|
1247
1322
|
...resolveOptions,
|
1248
|
-
custom: { ...custom, 'node-resolve': { ...custom['node-resolve'], resolved } }
|
1323
|
+
custom: { ...custom, 'node-resolve': { ...custom['node-resolve'], resolved, importee } }
|
1249
1324
|
});
|
1250
1325
|
if (resolvedResolved) {
|
1251
1326
|
// Handle plugins that manually make the result external
|