Skip to content

Commit

Permalink
Merge pull request #1676 from embroider-build/reverse-exports-bug
Browse files Browse the repository at this point in the history
fix single asterisk replacement in reverse-exports
  • Loading branch information
mansona authored Nov 21, 2023
2 parents 9606cac + 77be472 commit d68fbec
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 18 deletions.
4 changes: 0 additions & 4 deletions packages/reverse-exports/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/minimatch": "^3.0.4"
},
"dependencies": {
"minimatch": "^3.0.4",
"resolve.exports": "^2.0.2"
}
}
21 changes: 15 additions & 6 deletions packages/reverse-exports/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { posix } from 'path';
import minimatch from 'minimatch';
import { exports as resolveExports } from 'resolve.exports';

type Exports = string | string[] | { [key: string]: Exports };
Expand Down Expand Up @@ -82,12 +81,9 @@ export default function reversePackageExports(
}

const maybeKeyValuePair = _findPathRecursively(exportsObj, candidate => {
// miminatch does not treat directories as full of content without glob
if (candidate.endsWith('/')) {
candidate += '**';
}
const regex = new RegExp(_prepareStringForRegex(candidate));

return minimatch(relativePath, candidate);
return regex.test(relativePath);
});

if (!maybeKeyValuePair) {
Expand All @@ -114,3 +110,16 @@ export default function reversePackageExports(

return resolvedPath.replace(/^./, name);
}

export function _prepareStringForRegex(input: string): string {
let result = input
.split('*')
.map(substr => substr.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&'))
.join('.*');

if (result.endsWith('/')) {
result += '.*';
}

return `^${result}$`;
}
33 changes: 32 additions & 1 deletion packages/reverse-exports/tests/reverse-exports.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import reversePackageExports, { _findPathRecursively } from '../src';
import reversePackageExports, { _findPathRecursively, _prepareStringForRegex } from '../src';

describe('reverse exports', function () {
it('exports is missing', function () {
Expand Down Expand Up @@ -140,6 +140,24 @@ describe('reverse exports', function () {
'You tried to reverse exports for the file `./foo.bar` in package `my-addon` but it does not match any of the exports rules defined in package.json. This means it should not be possible to access directly.'
);
});

it('conditional exports: using a single asterisk as glob for nested path', function () {
const packageJson = {
name: 'my-v2-addon',
exports: {
'.': './dist/index.js',
'./*': {
types: './dist/*.d.ts',
default: './dist/*.js',
},
'./addon-main.js': './addon-main.js',
},
};

expect(reversePackageExports(packageJson, './dist/_app_/components/welcome-page.js')).toBe(
'my-v2-addon/_app_/components/welcome-page'
);
});
});

describe('_findKeyRecursively', function () {
Expand Down Expand Up @@ -260,3 +278,16 @@ describe('_findKeyRecursively', function () {
expect(_findPathRecursively(exports, str => str === './missing-path.js')).toBe(undefined);
});
});

describe('_prepareStringForRegex', function () {
[
{ input: './foo', expected: '^\\.\\/foo$' },
{ input: './foo.js', expected: '^\\.\\/foo\\.js$' },
{ input: './foo/*.js', expected: '^\\.\\/foo\\/.*\\.js$' },
{ input: './foo/', expected: '^\\.\\/foo\\/.*$' },
].forEach(({ input, expected }) => {
it(input, function () {
expect(_prepareStringForRegex(input)).toStrictEqual(expected);
});
});
});
7 changes: 0 additions & 7 deletions pnpm-lock.yaml

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

0 comments on commit d68fbec

Please sign in to comment.