Skip to content

Commit

Permalink
test: more
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Apr 18, 2023
1 parent b848e43 commit 05659b7
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 20 deletions.
72 changes: 55 additions & 17 deletions lib/util/entrypoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Conditional mapping nested in another conditional mapping is called nested mappi
const slashCode = "/".charCodeAt(0);
const dotCode = ".".charCodeAt(0);
const hashCode = "#".charCodeAt(0);
const patternRegEx = /\*/g;

/**
* @param {ExportsField} exportsField the exports field
Expand Down Expand Up @@ -118,7 +119,7 @@ function createFieldProcessor(field, assertRequest, assertTarget) {

if (match === null) return [];

const [mapping, remainingRequest, subpathMapping] = match;
const [mapping, remainingRequest, isSubpathMapping, isPattern] = match;

/** @type {DirectMapping|null} */
let direct = null;
Expand All @@ -137,7 +138,8 @@ function createFieldProcessor(field, assertRequest, assertTarget) {

return directMapping(
remainingRequest,
subpathMapping,
isPattern,
isSubpathMapping,
direct,
conditionNames,
assertTarget
Expand Down Expand Up @@ -256,7 +258,7 @@ function patternKeyCompare(a, b) {
* Trying to match request to field
* @param {string} request request
* @param {ExportsField | ImportsField} field exports or import field
* @returns {[MappingValue, string, boolean]|null} match or null, number is negative and one less when it's a folder mapping, number is request.length + 1 for direct mappings
* @returns {[MappingValue, string, boolean, boolean]|null} match or null, number is negative and one less when it's a folder mapping, number is request.length + 1 for direct mappings
*/
function findMatch(request, field) {
if (
Expand All @@ -265,10 +267,10 @@ function findMatch(request, field) {
!request.endsWith("/")
) {
const target = field[request];
const isDirectory =
const isSubpathMapping =
typeof target === "string" ? target.endsWith("/") : false;

return [target, "", isDirectory];
return [target, "", isSubpathMapping, false];
}

let bestMatch = "";
Expand Down Expand Up @@ -319,9 +321,15 @@ function findMatch(request, field) {
if (bestMatch === "") return null;

const target = field[bestMatch];
const pattern = bestMatch.endsWith("/");

return [target, /** @type {string} */ (bestMatchSubpath), pattern];
const isSubpathMapping = bestMatch.endsWith("/");
const isPattern = bestMatch.includes("*");

return [
target,
/** @type {string} */ (bestMatchSubpath),
isSubpathMapping,
isPattern
];
}

/**
Expand All @@ -336,15 +344,17 @@ function isConditionalMapping(mapping) {

/**
* @param {string|undefined} remainingRequest remaining request when folder mapping, undefined for file mappings
* @param {boolean} subpathMapping true, for subpath mappings
* @param {boolean} isPattern true, if mapping is a pattern (contains "*")
* @param {boolean} isSubpathMapping true, for subpath mappings
* @param {DirectMapping|null} mappingTarget direct export
* @param {Set<string>} conditionNames condition names
* @param {(d: string, f: boolean) => void} assert asserting direct value
* @returns {string[]} mapping result
*/
function directMapping(
remainingRequest,
subpathMapping,
isPattern,
isSubpathMapping,
mappingTarget,
conditionNames,
assert
Expand All @@ -353,7 +363,13 @@ function directMapping(

if (typeof mappingTarget === "string") {
return [
targetMapping(remainingRequest, subpathMapping, mappingTarget, assert)
targetMapping(
remainingRequest,
isPattern,
isSubpathMapping,
mappingTarget,
assert
)
];
}

Expand All @@ -362,7 +378,13 @@ function directMapping(
for (const exp of mappingTarget) {
if (typeof exp === "string") {
targets.push(
targetMapping(remainingRequest, subpathMapping, exp, assert)
targetMapping(
remainingRequest,
isPattern,
isSubpathMapping,
exp,
assert
)
);
continue;
}
Expand All @@ -371,7 +393,8 @@ function directMapping(
if (!mapping) continue;
const innerExports = directMapping(
remainingRequest,
subpathMapping,
isPattern,
isSubpathMapping,
mapping,
conditionNames,
assert
Expand All @@ -386,28 +409,43 @@ function directMapping(

/**
* @param {string|undefined} remainingRequest remaining request when folder mapping, undefined for file mappings
* @param {boolean} subpathMapping true, for subpath mappings
* @param {boolean} isPattern true, if mapping is a pattern (contains "*")
* @param {boolean} isSubpathMapping true, for subpath mappings
* @param {string} mappingTarget direct export
* @param {(d: string, f: boolean) => void} assert asserting direct value
* @returns {string} mapping result
*/
function targetMapping(
remainingRequest,
subpathMapping,
isPattern,
isSubpathMapping,
mappingTarget,
assert
) {
if (remainingRequest === undefined) {
assert(mappingTarget, false);

return mappingTarget;
}
if (subpathMapping) {

if (isSubpathMapping) {
assert(mappingTarget, true);

return mappingTarget + remainingRequest;
}

assert(mappingTarget, false);

return mappingTarget.replace(/\*/g, remainingRequest.replace(/\$/g, "$$"));
let result = mappingTarget;

if (isPattern) {
result = result.replace(
patternRegEx,
remainingRequest.replace(/\$/g, "$$")
);
}

return result;
}

/**
Expand Down
148 changes: 146 additions & 2 deletions test/exportsField.js
Original file line number Diff line number Diff line change
Expand Up @@ -2000,7 +2000,7 @@ describe("Process exports field", function exportsField() {
},
{
name: "wildcard pattern #5",
expect: ["./browser/index.js"], // default condition used
expect: ["./browser/index.js"],
suite: [
{
"./lib/*": {
Expand All @@ -2017,7 +2017,7 @@ describe("Process exports field", function exportsField() {
},
{
name: "wildcard pattern #5",
expect: ["./browser/index.js"], // default condition used
expect: ["./browser/index.js"],
suite: [
{
"./lib/*": {
Expand All @@ -2031,6 +2031,134 @@ describe("Process exports field", function exportsField() {
"./lib/index.js",
["browser"]
]
},
{
name: "wildcard pattern #6",
expect: ["./browser/foo/bar.js"],
suite: [
{
"./lib/*/bar.js": {
browser: ["./browser/*/bar.js"]
},
"./dist/*/bar.js": {
node: "./*.js",
default: "./browser/*.js"
}
},
"./lib/foo/bar.js",
["browser"]
]
},
{
name: "wildcard pattern #6",
expect: ["./browser/foo.js"],
suite: [
{
"./lib/*/bar.js": {
browser: ["./browser/*/bar.js"]
},
"./dist/*/bar.js": {
node: "./*.js",
default: "./browser/*.js"
}
},
"./dist/foo/bar.js",
["browser"]
]
},
{
name: "wildcard pattern #7",
expect: ["./browser/foo/default.js"],
suite: [
{
"./lib/*/bar.js": {
browser: ["./browser/*/bar.js"]
},
"./dist/*/bar.js": {
node: "./*.js",
default: "./browser/*/default.js"
}
},
"./dist/foo/bar.js",
["default"]
]
},
{
name: "wildcard pattern #8",
expect: ["./A/b/b/b.js"],
suite: [
{
"./a/*/c.js": "./A/*/*/*.js"
},
"./a/b/c.js",
[]
]
},
{
name: "wildcard pattern #9",
expect: ["./A/b/b/b.js", "./B/b/b/b.js"],
suite: [
{
"./a/*/c.js": ["./A/*/*/*.js", "./B/*/*/*.js"]
},
"./a/b/c.js",
[]
]
},
{
name: "wildcard pattern #10",
expect: ["./A/b/b/b.js"],
suite: [
{
"./a/foo-*/c.js": "./A/*/*/*.js"
},
"./a/foo-b/c.js",
[]
]
},
{
name: "wildcard pattern #11",
expect: ["./A/b/b/b.js"],
suite: [
{
"./a/*-foo/c.js": "./A/*/*/*.js"
},
"./a/b-foo/c.js",
[]
]
},
{
name: "wildcard pattern #12",
expect: ["./A/b/b/b.js"],
suite: [
{
"./a/foo-*-foo/c.js": "./A/*/*/*.js"
},
"./a/foo-b-foo/c.js",
[]
]
},
{
name: "wildcard pattern #13",
expect: ["./A/b/c/d.js"],
suite: [
{
"./a/foo-*-foo/c.js": "./A/b/c/d.js"
},
"./a/foo-b-foo/c.js",
[]
]
},
{
name: "wildcard pattern #13",
expect: ["./A/b/c/*.js"],
suite: [
{
"./a/foo-foo/c.js": "./A/b/c/*.js"
},
"./a/foo-foo/c.js",
[]
]
}
];

Expand Down Expand Up @@ -2696,6 +2824,22 @@ describe("ExportsFieldPlugin", () => {
});
});

it("should resolve with wildcard pattern #9", done => {
const fixture = path.resolve(
__dirname,
"./fixtures/imports-exports-wildcard/"
);

resolver.resolve({}, fixture, "m/middle-5/f$/$", {}, (err, result) => {
if (err) return done(err);
if (!result) throw new Error("No result");
result.should.equal(
path.resolve(fixture, "./node_modules/m/src/middle-5/f$/$.js")
);
done();
});
});

it("should throw error if target is 'null'", done => {
const fixture = path.resolve(
__dirname,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file.
Empty file.

0 comments on commit 05659b7

Please sign in to comment.