Skip to content

Commit f184c18

Browse files
guybedfordBethGriggs
authored andcommitted
module: support pattern trailers for imports field
PR-URL: #40041 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com>
1 parent 703ca25 commit f184c18

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');
@@ -724,38 +723,49 @@ function packageImportsResolve(name, base, conditions) {
724723
packageJSONUrl = pathToFileURL(packageConfig.pjsonPath);
725724
const imports = packageConfig.imports;
726725
if (imports) {
727-
if (ObjectPrototypeHasOwnProperty(imports, name)) {
726+
if (ObjectPrototypeHasOwnProperty(imports, name) &&
727+
!StringPrototypeIncludes(name, '*') &&
728+
!StringPrototypeEndsWith(name, '/')) {
728729
const resolved = resolvePackageTarget(
729730
packageJSONUrl, imports[name], '', name, base, false, true, conditions
730731
);
731732
if (resolved !== null)
732733
return { resolved, exact: true };
733734
} else {
734735
let bestMatch = '';
736+
let bestMatchSubpath;
735737
const keys = ObjectGetOwnPropertyNames(imports);
736738
for (let i = 0; i < keys.length; i++) {
737739
const key = keys[i];
738-
if (key[key.length - 1] === '*' &&
740+
const patternIndex = StringPrototypeIndexOf(key, '*');
741+
if (patternIndex !== -1 &&
739742
StringPrototypeStartsWith(name,
740-
StringPrototypeSlice(key, 0, -1)) &&
741-
name.length >= key.length &&
742-
key.length > bestMatch.length) {
743-
bestMatch = key;
743+
StringPrototypeSlice(key, 0,
744+
patternIndex))) {
745+
const patternTrailer = StringPrototypeSlice(key, patternIndex + 1);
746+
if (name.length >= key.length &&
747+
StringPrototypeEndsWith(name, patternTrailer) &&
748+
patternKeyCompare(bestMatch, key) === 1 &&
749+
StringPrototypeLastIndexOf(key, '*') === patternIndex) {
750+
bestMatch = key;
751+
bestMatchSubpath = StringPrototypeSlice(
752+
name, patternIndex, name.length - patternTrailer.length);
753+
}
744754
} else if (key[key.length - 1] === '/' &&
745755
StringPrototypeStartsWith(name, key) &&
746-
key.length > bestMatch.length) {
756+
patternKeyCompare(bestMatch, key) === 1) {
747757
bestMatch = key;
758+
bestMatchSubpath = StringPrototypeSlice(name, key.length);
748759
}
749760
}
750761

751762
if (bestMatch) {
752763
const target = imports[bestMatch];
753-
const pattern = bestMatch[bestMatch.length - 1] === '*';
754-
const subpath = StringPrototypeSubstr(name, bestMatch.length -
755-
(pattern ? 1 : 0));
756-
const resolved = resolvePackageTarget(
757-
packageJSONUrl, target, subpath, bestMatch, base, pattern, true,
758-
conditions);
764+
const pattern = StringPrototypeIncludes(bestMatch, '*');
765+
const resolved = resolvePackageTarget(packageJSONUrl, target,
766+
bestMatchSubpath, bestMatch,
767+
base, pattern, true,
768+
conditions);
759769
if (resolved !== null) {
760770
if (!pattern)
761771
emitFolderMapDeprecation(bestMatch, packageJSONUrl, false, base);

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)