Skip to content

Commit ec3bd72

Browse files
guybedforddanielleadams
authored andcommitted
module: support pattern trailers for imports field
PR-URL: nodejs#40041 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Geoffrey Booth <[email protected]>
1 parent c589e50 commit ec3bd72

File tree

3 files changed

+27
-14
lines changed

3 files changed

+27
-14
lines changed

lib/internal/modules/esm/resolve.js

+24-14
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ const {
2222
StringPrototypeSlice,
2323
StringPrototypeSplit,
2424
StringPrototypeStartsWith,
25-
StringPrototypeSubstr,
2625
} = primordials;
2726
const internalFS = require('internal/fs/utils');
2827
const { NativeModule } = require('internal/bootstrap/loaders');
@@ -582,38 +581,49 @@ function packageImportsResolve(name, base, conditions) {
582581
packageJSONUrl = pathToFileURL(packageConfig.pjsonPath);
583582
const imports = packageConfig.imports;
584583
if (imports) {
585-
if (ObjectPrototypeHasOwnProperty(imports, name)) {
584+
if (ObjectPrototypeHasOwnProperty(imports, name) &&
585+
!StringPrototypeIncludes(name, '*') &&
586+
!StringPrototypeEndsWith(name, '/')) {
586587
const resolved = resolvePackageTarget(
587588
packageJSONUrl, imports[name], '', name, base, false, true, conditions
588589
);
589590
if (resolved !== null)
590591
return { resolved, exact: true };
591592
} else {
592593
let bestMatch = '';
594+
let bestMatchSubpath;
593595
const keys = ObjectGetOwnPropertyNames(imports);
594596
for (let i = 0; i < keys.length; i++) {
595597
const key = keys[i];
596-
if (key[key.length - 1] === '*' &&
598+
const patternIndex = StringPrototypeIndexOf(key, '*');
599+
if (patternIndex !== -1 &&
597600
StringPrototypeStartsWith(name,
598-
StringPrototypeSlice(key, 0, -1)) &&
599-
name.length >= key.length &&
600-
key.length > bestMatch.length) {
601-
bestMatch = key;
601+
StringPrototypeSlice(key, 0,
602+
patternIndex))) {
603+
const patternTrailer = StringPrototypeSlice(key, patternIndex + 1);
604+
if (name.length >= key.length &&
605+
StringPrototypeEndsWith(name, patternTrailer) &&
606+
patternKeyCompare(bestMatch, key) === 1 &&
607+
StringPrototypeLastIndexOf(key, '*') === patternIndex) {
608+
bestMatch = key;
609+
bestMatchSubpath = StringPrototypeSlice(
610+
name, patternIndex, name.length - patternTrailer.length);
611+
}
602612
} else if (key[key.length - 1] === '/' &&
603613
StringPrototypeStartsWith(name, key) &&
604-
key.length > bestMatch.length) {
614+
patternKeyCompare(bestMatch, key) === 1) {
605615
bestMatch = key;
616+
bestMatchSubpath = StringPrototypeSlice(name, key.length);
606617
}
607618
}
608619

609620
if (bestMatch) {
610621
const target = imports[bestMatch];
611-
const pattern = bestMatch[bestMatch.length - 1] === '*';
612-
const subpath = StringPrototypeSubstr(name, bestMatch.length -
613-
(pattern ? 1 : 0));
614-
const resolved = resolvePackageTarget(
615-
packageJSONUrl, target, subpath, bestMatch, base, pattern, true,
616-
conditions);
622+
const pattern = StringPrototypeIncludes(bestMatch, '*');
623+
const resolved = resolvePackageTarget(packageJSONUrl, target,
624+
bestMatchSubpath, bestMatch,
625+
base, pattern, true,
626+
conditions);
617627
if (resolved !== null)
618628
return { resolved, exact: pattern };
619629
}

test/es-module/test-esm-imports.mjs

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ const { requireImport, importImport } = importer;
2020
['#external', { default: 'asdf' }],
2121
// External subpath imports
2222
['#external/subpath/asdf.js', { default: 'asdf' }],
23+
// Trailing pattern imports
24+
['#subpath/asdf.asdf', { default: 'test' }],
2325
]);
2426

2527
for (const [validSpecifier, expected] of internalImports) {

test/fixtures/es-modules/pkgimports/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"require": "./requirebranch.js"
77
},
88
"#subpath/*": "./sub/*",
9+
"#subpath/*.asdf": "./test.js",
910
"#external": "pkgexports/valid-cjs",
1011
"#external/subpath/*": "pkgexports/sub/*",
1112
"#external/invalidsubpath/": "pkgexports/sub",

0 commit comments

Comments
 (0)