From 1ae5886a98a072cbb2bf7446f53c20efed9474ec Mon Sep 17 00:00:00 2001 From: morgan-coded <256248948+morgan-coded@users.noreply.github.com> Date: Fri, 4 Sep 2026 21:21:01 -0500 Subject: [PATCH] fix: treat trailing-slash exports keys as wildcards A "./dir/" exports key is a folder mapping equivalent to "./dir/*", so mark it as a wildcard instead of resolving it as a literal subpath. --- .changeset/trailing-slash-wildcards.md | 5 ++++ .../core/src/internal/getEntrypointInfo.ts | 3 +- packages/core/test/getEntrypointInfo.test.ts | 29 +++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 .changeset/trailing-slash-wildcards.md diff --git a/.changeset/trailing-slash-wildcards.md b/.changeset/trailing-slash-wildcards.md new file mode 100644 index 0000000..1a2bfdf --- /dev/null +++ b/.changeset/trailing-slash-wildcards.md @@ -0,0 +1,5 @@ +--- +"@arethetypeswrong/core": patch +--- + +Treat trailing-slash `exports` keys as wildcard entrypoints. diff --git a/packages/core/src/internal/getEntrypointInfo.ts b/packages/core/src/internal/getEntrypointInfo.ts index 2c33be5..54ac696 100644 --- a/packages/core/src/internal/getEntrypointInfo.ts +++ b/packages/core/src/internal/getEntrypointInfo.ts @@ -160,7 +160,8 @@ function getEntrypointResolution( resolutionKind: ResolutionKind, entrypoint: string, ): EntrypointResolutionAnalysis { - if (entrypoint.includes("*")) { + // A trailing slash is the folder-mapping form of `./dir/*` + if (entrypoint.includes("*") || entrypoint.endsWith("/")) { return { name: entrypoint, resolutionKind, isWildcard: true }; } const moduleSpecifier = packageName + entrypoint.substring(1); // remove leading . before slash diff --git a/packages/core/test/getEntrypointInfo.test.ts b/packages/core/test/getEntrypointInfo.test.ts index 37abdac..3c03c07 100644 --- a/packages/core/test/getEntrypointInfo.test.ts +++ b/packages/core/test/getEntrypointInfo.test.ts @@ -34,4 +34,33 @@ describe("getEntrypointInfo", () => { assert("entrypoints" in result); assert.deepStrictEqual(Object.keys(result.entrypoints), ["./features/*.js", "./browser"]); }); + + test("treats trailing-slash exports keys as wildcards", async () => { + const result = await checkPackage( + createTestPackage({ + "es/index.d.ts": "export {};", + "es/index.js": "export {};", + "index.d.ts": "export {};", + "index.js": "export {};", + "package.json": JSON.stringify({ + name: "test", + version: "1.0.0", + exports: { + ".": "./index.js", + "./es/": "./es/", + "./es/*": "./es/*.js", + }, + }), + }), + ); + + assert("entrypoints" in result); + assert.deepStrictEqual(Object.keys(result.entrypoints), [".", "./es/", "./es/*"]); + assert(result.entrypoints["./es/"].isWildcard); + assert(Object.values(result.entrypoints["./es/"].resolutions).every((r) => r.isWildcard && !r.resolution)); + assert.deepStrictEqual( + result.problems.filter((p) => "entrypoint" in p && p.entrypoint === "./es/"), + [], + ); + }); });