Skip to content

Commit 063ed71

Browse files
arhxamclaude
andauthored
feat(shared): support shorthand (major-only) versions in the semver helpers (#5027)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 34b15a9 commit 063ed71

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

packages/shared/src/semver.test.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { describe, expect, it } from "vite-plus/test";
22

3-
import { compareSemverVersions, normalizeSemverVersion, satisfiesSemverRange } from "./semver.ts";
3+
import {
4+
compareSemverVersions,
5+
normalizeSemverVersion,
6+
parseSemver,
7+
satisfiesSemverRange,
8+
} from "./semver.ts";
49

510
describe("semver helpers", () => {
611
it("matches supported range groups", () => {
@@ -18,6 +23,25 @@ describe("semver helpers", () => {
1823
expect(normalizeSemverVersion("2.1")).toBe("2.1.0");
1924
});
2025

26+
it("normalizes and parses shorthand major-only versions", () => {
27+
expect(normalizeSemverVersion("20")).toBe("20.0.0");
28+
expect(normalizeSemverVersion("v18")).toBe("v18.0.0");
29+
expect(normalizeSemverVersion("20-rc.1")).toBe("20.0.0-rc.1");
30+
expect(parseSemver("20")).toEqual({ major: 20, minor: 0, patch: 0, prerelease: [] });
31+
});
32+
33+
it("compares shorthand versions numerically instead of lexically", () => {
34+
// Regression: "20" vs "9" previously fell back to string comparison, which
35+
// ordered "20" before "9" ("2" < "9").
36+
expect(compareSemverVersions("20", "9")).toBeGreaterThan(0);
37+
expect(compareSemverVersions("18", "18.0.0")).toBe(0);
38+
});
39+
40+
it("still rejects non-numeric shorthand and keeps empty input empty", () => {
41+
expect(parseSemver("abc")).toBeNull();
42+
expect(normalizeSemverVersion("")).toBe("");
43+
});
44+
2145
it("compares prerelease versions before stable versions", () => {
2246
expect(compareSemverVersions("2.1.111-beta.1", "2.1.111")).toBeLessThan(0);
2347
});

packages/shared/src/semver.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ export function normalizeSemverVersion(version: string): string {
1717
}
1818
}
1919

20-
if (segments.length === 2) {
20+
// Pad shorthand versions ("20" or "20.1") up to three segments so major-only
21+
// and minor-only inputs parse and compare numerically. This matches
22+
// satisfiesSemverRange, which already treats a missing minor/patch as 0. The
23+
// length > 0 guard keeps empty/garbage input empty (parseSemver still
24+
// rejects it), and inputs with more than three segments are left untouched.
25+
while (segments.length > 0 && segments.length < 3) {
2126
segments.push("0");
2227
}
2328

0 commit comments

Comments
 (0)