diff --git a/src/resolve.ts b/src/resolve.ts index 5647e1b..6f7ae7f 100644 --- a/src/resolve.ts +++ b/src/resolve.ts @@ -206,23 +206,25 @@ function _findSubpath(subpath: string, exports: PackageJson["exports"]) { return subpath; } - const flattenedExports = _flattenExports(exports); - const [foundPath] = - // eslint-disable-next-line @typescript-eslint/no-unused-vars - flattenedExports.find(([_, resolved]) => resolved === subpath) || []; - - return foundPath; + const _flatExports = _flattenExports(exports); + console.log(subpath, "in", _flatExports); + return _flatExports.find((p) => p.fsPath === subpath)?.subpath; } function _flattenExports( exports: Exclude, - path?: string, -) { + parentSubpath = "./", +): { subpath: string; fsPath: string; condition?: string }[] { return Object.entries(exports).flatMap(([key, value]) => { - const subpath = - path ?? (key.startsWith(".") ? key : "./"); /* key is export condition */ - return typeof value === "string" - ? [[subpath, value]] - : _flattenExports(value, subpath); + const [subpath, condition] = key.startsWith(".") + ? [key.slice(1), undefined] + : [undefined, key]; + const _subPath = joinURL(parentSubpath, subpath); + // eslint-disable-next-line unicorn/prefer-ternary + if (typeof value === "string") { + return [{ subpath: _subPath, fsPath: value, condition }]; + } else { + return _flattenExports(value, _subPath); + } }); } diff --git a/test/fixture/package/node_modules/subpaths/package.json b/test/fixture/package/node_modules/subpaths/package.json index ba1b90f..cf2e990 100644 --- a/test/fixture/package/node_modules/subpaths/package.json +++ b/test/fixture/package/node_modules/subpaths/package.json @@ -2,6 +2,11 @@ "name": "subpaths", "version": "1.0.0", "exports": { - "./subpath": "./lib/subpath.mjs" + ".": { + "default": "./dist/index.mjs" + }, + "./subpath": { + "default": "./dist/subpath.mjs" + } } } diff --git a/test/utils.test.ts b/test/utils.test.ts index 50b2dfc..cc493f9 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -108,36 +108,44 @@ describe("lookupNodeModuleSubpath", () => { const r = (p: string) => new URL(p, import.meta.url).toString(); const tests = [ + // Resolve with exports { - name: "resolves with exports field", - input: r("fixture/package/node_modules/subpaths/lib/subpath.mjs"), + name: "resolves with exports field (root)", + input: r("fixture/package/node_modules/subpaths/dist/index.mjs"), + output: "./", + }, + { + name: "resolves with exports field (subpath)", + input: r("fixture/package/node_modules/subpaths/dist/subpath.mjs"), output: "./subpath", }, { - name: "resolves with fallback subpath guess (non resolved module)", + name: "resolves with exports field (with conditions)", + input: r("fixture/package/node_modules/postgres/src/index.js"), + output: "./", + }, + // Fallbacks + { + name: "resolves with fallback (non resolved module)", input: r("fixture/package/node_modules/alien/lib/subpath.json5"), output: "./lib/subpath.json5", }, + { + name: "resolves with fallback subpath guess (non existing file)", + input: r("fixture/package/node_modules/subpaths/foo/bar.mjs"), + output: "./foo/bar.mjs", + }, + // Invalid { name: "ignores invalid paths", input: r("/foo/bar/lib/subpath.mjs"), output: undefined, }, - { - name: "resolves with fallback subpath guess (mjs)", - input: r("fixture/package/node_modules/subpaths/foo/bar.mjs"), - output: "./foo/bar.mjs", - }, { name: "resolves main export", input: r("fixture/package/node_modules/subpaths/"), output: "./", }, - { - name: "resolves main export (top level export conditions)", - input: r("fixture/package/node_modules/posgres/src/index.js"), - output: "./src/index.js", // TODO: Should be "./" - }, ]; for (const t of tests) {