fix: handle OR-range unions in subset() (#703)#854
Open
Conversation
owlstronaut
requested changes
May 5, 2026
| // No single dom range covers this sub range, but the union of | ||
| // multiple dom ranges might. Only attempt this when there are | ||
| // multiple OR branches in the dom. | ||
| if (dom.set.length > 1 && unionSubset(simpleSub, dom, options)) { |
Contributor
There was a problem hiding this comment.
This bypasses the prerelease-tuple admission rule that simpleSubset enforces above. So subset('>=1.0.0-pre', '<2.0.0 || >=1.0.0') will return true in non-includePrerelease mode
| ['>=1.0.0 <3.0.0', '1.0.0 || 2.0.0', false], // dom is all eq-sets | ||
| ['>=0.0.0', '<2.0.0 || >=1.0.0', true], // dom branch with -infinity lower | ||
| ['>=1.0.0 <10.0.0', '>=1.0.0 <3.0.0 || >=5.0.0 <7.0.0 || >=9.0.0', false], // gap | ||
| ['>=0.0.0-0', '* || >=1.0.0', true, { includePrerelease: true }], |
Contributor
There was a problem hiding this comment.
Adding negative tests here for the prerelease lower/upper bounds in non-includePrerelease mode would be great to make sure a regression doesn't happen.
| for (const simpleDom of dom.set) { | ||
| const b = extractBounds(simpleDom, options) | ||
| if (b) { | ||
| domIntervals.push(b) |
Contributor
There was a problem hiding this comment.
eq-only branches are dropped here, so a singleton like 2.0.0 can't bridge <2.0.0 and >2.0.0 in the union
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.
Summary
Fixes #703
subset('>=17.2.0', '^17.2.0 || >17')incorrectly returnsfalse.The root cause is that
subset()checks each OR-branch of the dom range independently. No single branch of^17.2.0 || >17covers>=17.2.0on its own, but their union does:Approach
When no single dom OR-branch covers a sub comparator set, fall back to an interval-sweep algorithm:
[lower, upper)bounds from the sub and every dom OR-branchKey details:
<18.0.0-0and>=18.0.0are treated as adjacent in non-prerelease mode (no release version exists between them)>5.0.0 <3.0.0) are detected and skipped*/ ANY bounds are handled as[-∞, +∞)domhas multiple OR-branchesTest plan
subset('>=17.2.0', '^17.2.0 || >17')now returnstrue*ranges, inclusive/exclusive bounds,includePrereleaseoption