Skip to content

Commit

Permalink
feat: empty subpath pattern matches
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <unicornware@flexdevelopment.llc>
  • Loading branch information
unicornware committed Nov 9, 2024
1 parent ca57108 commit b5bfc6d
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 34 deletions.
3 changes: 3 additions & 0 deletions __fixtures__/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../tsconfig"
}
10 changes: 10 additions & 0 deletions __fixtures__/tsconfig.json.d.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { TSConfig as Tsconfig } from '@flex-development/tsconfig-utils'

/**
* TypeScript configuration.
*
* @const {Tsconfig} tsconfig
*/
declare const tsconfig: Tsconfig

export default tsconfig
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
},
"imports": {
"#build/*": "./build/*.mts",
"#fixtures/tsconfig*.json": {
"types": "./__fixtures__/tsconfig.json.d.mts",
"default": "./__fixtures__/tsconfig*.json"
},
"#fixtures/*": "./__fixtures__/*.mts",
"#interfaces/*": {
"mlly": "./src/interfaces/*.mts",
Expand Down
3 changes: 0 additions & 3 deletions src/internal/invalid-subpath.mts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
} from '@flex-development/errnode'
import type { ModuleId } from '@flex-development/mlly'
import { fileURLToPath } from '@flex-development/pathe'
import { ok } from 'devlop'

/**
* Create an {@linkcode ERR_INVALID_MODULE_SPECIFIER} error for an invalid
Expand Down Expand Up @@ -41,8 +40,6 @@ function invalidSubpath(
isImports?: boolean | null | undefined,
parent?: ModuleId | null | undefined
): ErrInvalidModuleSpecifier {
ok(patternMatch, 'expected `patternMatch`')

return new ERR_INVALID_MODULE_SPECIFIER(
subpath.replace(chars.asterisk, () => patternMatch),
`request is not a valid match in pattern "${subpath}" for the ` +
Expand Down
11 changes: 9 additions & 2 deletions src/lib/__snapshots__/pattern-match.snap
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`unit:lib/patternMatch > should return \`PatternMatch\` if subpath pattern match is found (0) 1`] = `
[
"#fixtures/tsconfig*.json",
"",
]
`;

exports[`unit:lib/patternMatch > should return \`PatternMatch\` if subpath pattern match is found (1) 1`] = `
[
"#lib/*",
"pattern-match",
]
`;

exports[`unit:lib/patternMatch > should return \`PatternMatch\` if subpath pattern match is found (1) 1`] = `
exports[`unit:lib/patternMatch > should return \`PatternMatch\` if subpath pattern match is found (2) 1`] = `
[
"./lib/*.js",
"a",
]
`;

exports[`unit:lib/patternMatch > should return \`PatternMatch\` if subpath pattern match is found (2) 1`] = `
exports[`unit:lib/patternMatch > should return \`PatternMatch\` if subpath pattern match is found (3) 1`] = `
[
"./package.json",
null,
Expand Down
42 changes: 22 additions & 20 deletions src/lib/__snapshots__/resolver.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,52 @@

exports[`unit:lib/resolver > legacyMainResolve > should throw if main entry point is not found 1`] = `Cannot find package '\${process.cwd()}/__fixtures__/node_modules/@flex-development/mlly/' imported from \${process.cwd()}/__fixtures__/parent.mts`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (0) 1`] = `"node:fs/promises"`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (0) 1`] = `file://\${process.cwd()}/__fixtures__/tsconfig.json`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (1) 1`] = `file://\${process.cwd()}/src/internal/fs.browser.mts`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (1) 1`] = `"node:fs/promises"`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (2) 1`] = `"node:path/posix"`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (2) 1`] = `file://\${process.cwd()}/src/internal/fs.browser.mts`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (3) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/subpath-imports/internal/path/windows.browser.mjs`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (3) 1`] = `"node:path/posix"`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (4) 1`] = `file://\${process.cwd()}/src/lib/resolver.mts`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (4) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/subpath-imports/internal/path/windows.browser.mjs`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (5) 1`] = `file://\${process.cwd()}/src/lib/resolver.mts`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (6) 1`] = `file://\${process.cwd()}/node_modules/@flex-development/mkbuild/dist/index.mjs`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (6) 1`] = `file://\${process.cwd()}/src/lib/resolver.mts`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (7) 1`] = `"node:fs"`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (7) 1`] = `file://\${process.cwd()}/node_modules/@flex-development/mkbuild/dist/index.mjs`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (8) 1`] = `"node:fs/promises"`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (8) 1`] = `"node:fs"`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (9) 1`] = `"node:url"`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (9) 1`] = `"node:fs/promises"`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (10) 1`] = `file://\${process.cwd()}/node_modules/vitest/dist/index.js`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (10) 1`] = `"node:url"`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (11) 1`] = `file://\${process.cwd()}/src/lib/index.mts`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (11) 1`] = `file://\${process.cwd()}/node_modules/vitest/dist/index.js`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (12) 1`] = `file://\${process.cwd()}/node_modules/@flex-development/errnode/dist/index.mjs`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (12) 1`] = `file://\${process.cwd()}/src/lib/index.mts`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (13) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/exports-sugar/index.mjs`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (13) 1`] = `file://\${process.cwd()}/node_modules/@flex-development/errnode/dist/index.mjs`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (14) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/exports-sugar-a/index.mjs`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (14) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/exports-sugar/index.mjs`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (15) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/legacy-main-1/a.js`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (15) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/exports-sugar-a/index.mjs`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (16) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/legacy-main-1/index.js`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (16) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/legacy-main-1/a.js`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (17) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/legacy-main-2/index.json`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (17) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/legacy-main-1/index.js`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (18) 1`] = `file://\${process.cwd()}/package.json`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (18) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/legacy-main-2/index.json`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (19) 1`] = `file://\${process.cwd()}/src/index.mts`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (19) 1`] = `file://\${process.cwd()}/package.json`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (20) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/subpath-exports/lib/a.js`;
exports[`unit:lib/resolver > moduleResolve > should return resolved URL (20) 1`] = `file://\${process.cwd()}/src/index.mts`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (21) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/subpath-exports/lib/a.js`;

exports[`unit:lib/resolver > moduleResolve > should return resolved URL (22) 1`] = `file://\${process.cwd()}/__fixtures__/node_modules/subpath-exports/lib/a.js`;

exports[`unit:lib/resolver > moduleResolve > should throw if \`specifier\` contains encoded separators 1`] = `Invalid module '/lib%2futils.mjs' must not include encoded "/" or "\\" characters imported from \${process.cwd()}/src/lib/__tests__/resolver.spec.mts`;

exports[`unit:lib/resolver > moduleResolve > should throw if \`specifier\` resolves to a directory 1`] = `Directory import '\${process.cwd()}/src/' is not supported resolving ES modules imported from \${process.cwd()}/src/lib/__tests__/resolver.spec.mts`;
Expand Down
1 change: 1 addition & 0 deletions src/lib/__tests__/pattern-match.spec.mts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import pkg from '@flex-development/mlly/package.json'

describe('unit:lib/patternMatch', () => {
it.each<Parameters<typeof testSubject>>([
['#fixtures/tsconfig.json', pkg.imports],
['#lib/pattern-match', pkg.imports],
['./lib/a.js', subpathExports.exports],
['./package.json', pkg.exports]
Expand Down
18 changes: 12 additions & 6 deletions src/lib/__tests__/resolver.spec.mts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ describe('unit:lib/resolver', () => {

describe('moduleResolve', () => {
it.each<Parameters<(typeof testSubject)['moduleResolve']>>([
['#fixtures/tsconfig.json', import.meta.url],
['#internal/fs', import.meta.url, fixtureConditions],
['#internal/fs', import.meta.url, ['browser', ...fixtureConditions]],
[
Expand Down Expand Up @@ -94,11 +95,16 @@ describe('unit:lib/resolver', () => {
fs
) => {
// Arrange
const expected: URL = baseline.moduleResolve(
specifier,
new URL(parent),
new Set(conditions ?? defaultConditions)
)
let expected: URL | null = null

// `import-meta-resolve` does not support empty pattern matches.
if (specifier !== '#fixtures/tsconfig.json') {
expected = baseline.moduleResolve(
specifier,
new URL(parent),
new Set(conditions ?? defaultConditions)
)
}

// Act
const result = await testSubject.moduleResolve(
Expand All @@ -111,7 +117,7 @@ describe('unit:lib/resolver', () => {
)

// Expect
expect(result).to.eql(expected)
expect(result).to.eql(expected ?? result)
expect(result).toMatchSnapshot()
})

Expand Down
5 changes: 4 additions & 1 deletion src/lib/pattern-match.mts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ function patternMatch(
!patternTrailer.length ||
(
matchKey.endsWith(patternTrailer) &&
matchKey.length >= expansionKey.length
(
matchKey.length >= expansionKey.length ||
matchKey === patternBase + patternTrailer
)
)
) {
return [
Expand Down
4 changes: 2 additions & 2 deletions src/lib/resolver.mts
Original file line number Diff line number Diff line change
Expand Up @@ -973,8 +973,8 @@ async function packageTargetResolve(
}

// replace `chars.asterisk` in `resolved` with `patternMatch`
if (patternMatch) {
if (checkInvalidSegments(patternMatch)) {
if (typeof patternMatch === 'string') {
if (patternMatch && checkInvalidSegments(patternMatch)) {
throw invalidSubpath(
subpath,
patternMatch,
Expand Down

0 comments on commit b5bfc6d

Please sign in to comment.