fix: match wildcard imports keys with a trailer - #57
Merged
Merged
Conversation
📝 WalkthroughWalkthroughThe imports resolver now matches wildcard keys using the actual ChangesWildcard imports resolution
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #57 +/- ##
==========================================
+ Coverage 65.26% 65.61% +0.34%
==========================================
Files 6 6
Lines 858 858
Branches 305 305
==========================================
+ Hits 560 563 +3
Misses 236 236
+ Partials 62 59 -3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
pi0
approved these changes
Jul 27, 2026
`packageImportsResolve` computed the pattern base as `key.slice(0, -1)`
instead of `key.slice(0, patternIndex)`. For a key like `#*.js` this
tested `name.startsWith("#*.")`, which never matches, so the key was
skipped.
Usually that meant resolution threw, but when a less specific key also
matched the specifier it silently resolved the wrong file: given
`#feat*.js` and `#feat*`, `#featx.js` should pick the former, yet the
former was skipped and the latter won by default.
Keys without a trailer (`#/*`) were unaffected, which hid the bug, and
`packageExportsResolve` already used the correct base.
Aligns with the Node.js upstream implementation.
Fixes #56
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #56.
Problem
packageImportsResolvecomputed the wildcard pattern base askey.slice(0, -1)instead ofkey.slice(0, patternIndex). For a key like#*.jsthis testedname.startsWith("#*."), which never matches, so the key was skipped.Usually that meant resolution threw — but when a less specific key also matched, it silently resolved the wrong file. Given
#feat*.jsand#feat*,patternKeyCompareshould pick the former for#featx.js; instead the former was skipped and the latter won by default.Keys without a trailer (
#/*) were unaffected —slice(0, -1)andslice(0, patternIndex)coincide there — which is why this went unnoticed.packageExportsResolvealready used the correct base, soexportsandimportsdisagreed within the same file.Changes
src/internal/resolve.ts— one-line fix, aligning with the Node.js upstream implementation.test/resolve-imports-exports.test.ts— regression tests for a bare wildcard-with-trailer key, a nested one, and the wrong-winner case above (both targets exist on disk, so it pins key selection rather than mere existence), plus a negative test that#.jsstill does not match#*.js.The three positive tests fail on the parent commit and pass with the fix. Because
key.slice(0, patternIndex)is always a prefix ofkey.slice(0, -1), the new predicate is a strict superset of the old one — it can only add matches, never remove them.Verification
Full suite passes (84 passed, 1 skipped), as do
tsc --noEmit,oxlint, andoxfmt --check.The fixture in
test/fixture/imports-pkgwas also checked against real Node (createRequire().resolve, v24.18.0) to confirm the expectations are Node's actual answers and that the added keys don't disturb the pre-existing cases:#internal/marker.jsruntime/internal/marker.js#lib/deep/thing.jslib/deep/thing.js#featx.jsfeat-js/x.js#.jsERR_PACKAGE_IMPORT_NOT_DEFINED#/util.jssrc/util.js(unchanged)#internalinternal.js(unchanged)🤖 Generated with Claude Code