also looking at this
refactor: one update-type classifier, with the edge cases decided instead of accidental
#1439
4 files
+108
-116
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | import type { VersionRange } from '../types' |
| 2 | 2 | import { semver } from 'bun' |
| 3 | import { getUpdateType } from '../utils/helpers' | |
| 3 | 4 | |
| 4 | 5 | export class VersionResolver { |
| 5 | 6 | /** |
| @@ -43,33 +44,15 @@ export class VersionResolver { | ||
| 43 | 44 | } |
| 44 | 45 | |
| 45 | 46 | /** |
| 46 | * Determine update type between two versions | |
| 47 | * Determine update type between two versions. | |
| 48 | * | |
| 49 | * Delegates to the canonical classifier in `utils/helpers`. This class | |
| 50 | * used to carry its own variant, which disagreed with the live scan path | |
| 51 | * on exactly the awkward inputs: 'v2.0.0' read as no change (the v was | |
| 52 | * never stripped) and 'latest' read as a fabricated major. | |
| 47 | 53 | */ |
| 48 | 54 | static getUpdateType(fromVersion: string, toVersion: string): 'major' | 'minor' | 'patch' { |
| 49 | // Strip leading semver range operators. Do NOT strip `@` — scoped npm package | |
| 50 | // names start with `@` (e.g. @scope/pkg), so stripping it here would corrupt | |
| 51 | // any caller that accidentally passed a full spec instead of a version. | |
| 52 | const cleanFrom = fromVersion.replace(/^[\^~>=<]+/, '') | |
| 53 | const cleanTo = toVersion.replace(/^[\^~>=<]+/, '') | |
| 54 | ||
| 55 | const fromParts = cleanFrom.split('.').map((part) => { | |
| 56 | const num = Number(part) | |
| 57 | return Number.isNaN(num) ? 0 : num | |
| 58 | }) | |
| 59 | const toParts = cleanTo.split('.').map((part) => { | |
| 60 | const num = Number(part) | |
| 61 | return Number.isNaN(num) ? 0 : num | |
| 62 | }) | |
| 63 | ||
| 64 | // Ensure we have at least major.minor.patch structure | |
| 65 | while (fromParts.length < 3) fromParts.push(0) | |
| 66 | while (toParts.length < 3) toParts.push(0) | |
| 67 | ||
| 68 | if (toParts[0] > fromParts[0]) | |
| 69 | return 'major' | |
| 70 | if (toParts[0] === fromParts[0] && toParts[1] > fromParts[1]) | |
| 71 | return 'minor' | |
| 72 | return 'patch' | |
| 55 | return getUpdateType(fromVersion, toVersion) | |
| 73 | 56 | } |
| 74 | 57 | |
| 75 | 58 | /** |