|
4 | 4 | // Newer versions sort before older ones; pre-release < rc < release. |
5 | 5 |
|
6 | 6 | interface ParsedVersion { |
7 | | - major: number; |
8 | | - minor: number; |
9 | | - patch: number; |
10 | | - preRelease: 'pre' | 'rc' | null; |
11 | | - preNumber: number; |
| 7 | + major: number; |
| 8 | + minor: number; |
| 9 | + patch: number; |
| 10 | + preRelease: 'pre' | 'rc' | null; |
| 11 | + preNumber: number; |
12 | 12 | } |
13 | 13 |
|
14 | 14 | const VERSION_RE = /^(\d+)\.(\d+)(?:\.(\d+))?(?:-(pre|rc)(\d+))?$/; |
15 | 15 |
|
16 | 16 | function toInt(value: string | undefined): number { |
17 | | - if (!value) return 0; |
18 | | - const n = parseInt(value, 10); |
19 | | - return Number.isNaN(n) ? 0 : n; |
| 17 | + if (!value) return 0; |
| 18 | + const n = parseInt(value, 10); |
| 19 | + return Number.isNaN(n) ? 0 : n; |
20 | 20 | } |
21 | 21 |
|
22 | 22 | function parseVersion(version: string): ParsedVersion { |
23 | | - const match = version.match(VERSION_RE); |
24 | | - if (!match) return { major: 0, minor: 0, patch: 0, preRelease: null, preNumber: 0 }; |
25 | | - return { |
26 | | - major: toInt(match[1]), |
27 | | - minor: toInt(match[2]), |
28 | | - patch: toInt(match[3]), |
29 | | - preRelease: (match[4] as 'pre' | 'rc' | undefined) ?? null, |
30 | | - preNumber: toInt(match[5]), |
31 | | - }; |
| 23 | + const match = version.match(VERSION_RE); |
| 24 | + if (!match) return { major: 0, minor: 0, patch: 0, preRelease: null, preNumber: 0 }; |
| 25 | + return { |
| 26 | + major: toInt(match[1]), |
| 27 | + minor: toInt(match[2]), |
| 28 | + patch: toInt(match[3]), |
| 29 | + preRelease: (match[4] as 'pre' | 'rc' | undefined) ?? null, |
| 30 | + preNumber: toInt(match[5]), |
| 31 | + }; |
32 | 32 | } |
33 | 33 |
|
34 | 34 | function compareVersions(a: string, b: string): number { |
35 | | - const vA = parseVersion(a); |
36 | | - const vB = parseVersion(b); |
37 | | - if (vA.major !== vB.major) return vB.major - vA.major; |
38 | | - if (vA.minor !== vB.minor) return vB.minor - vA.minor; |
39 | | - if (vA.patch !== vB.patch) return vB.patch - vA.patch; |
40 | | - if (vA.preRelease === null && vB.preRelease !== null) return -1; |
41 | | - if (vA.preRelease !== null && vB.preRelease === null) return 1; |
42 | | - if (vA.preRelease !== vB.preRelease) { |
43 | | - if (vA.preRelease === 'rc' && vB.preRelease === 'pre') return -1; |
44 | | - if (vA.preRelease === 'pre' && vB.preRelease === 'rc') return 1; |
45 | | - } |
46 | | - return vB.preNumber - vA.preNumber; |
| 35 | + const vA = parseVersion(a); |
| 36 | + const vB = parseVersion(b); |
| 37 | + if (vA.major !== vB.major) return vB.major - vA.major; |
| 38 | + if (vA.minor !== vB.minor) return vB.minor - vA.minor; |
| 39 | + if (vA.patch !== vB.patch) return vB.patch - vA.patch; |
| 40 | + if (vA.preRelease === null && vB.preRelease !== null) return -1; |
| 41 | + if (vA.preRelease !== null && vB.preRelease === null) return 1; |
| 42 | + if (vA.preRelease !== vB.preRelease) { |
| 43 | + if (vA.preRelease === 'rc' && vB.preRelease === 'pre') return -1; |
| 44 | + if (vA.preRelease === 'pre' && vB.preRelease === 'rc') return 1; |
| 45 | + } |
| 46 | + return vB.preNumber - vA.preNumber; |
47 | 47 | } |
48 | 48 |
|
49 | 49 | // Group key: `major.minor`. For 1.20.1 → "1.20"; for 26.1.2 → "26.1". |
50 | 50 | // 26.1 and 26.1.2 land in the same group; 26.2 is its own group. |
51 | 51 | export function groupVersions(versionKeys: string[]): Record<string, string[]> { |
52 | | - const sorted = [...versionKeys].sort(compareVersions); |
53 | | - const groups: Record<string, string[]> = {}; |
54 | | - for (const version of sorted) { |
55 | | - const { major, minor } = parseVersion(version); |
56 | | - const key = `${major}.${minor}`; |
57 | | - if (!groups[key]) groups[key] = []; |
58 | | - groups[key].push(version); |
59 | | - } |
60 | | - return groups; |
| 52 | + const sorted = [...versionKeys].sort(compareVersions); |
| 53 | + const groups: Record<string, string[]> = {}; |
| 54 | + for (const version of sorted) { |
| 55 | + const { major, minor } = parseVersion(version); |
| 56 | + const key = `${major}.${minor}`; |
| 57 | + if (!groups[key]) groups[key] = []; |
| 58 | + groups[key].push(version); |
| 59 | + } |
| 60 | + return groups; |
61 | 61 | } |
0 commit comments