/** * Version comparison for plugin manifests. Versions are validated by the * manifest schema as `MAJOR.MINOR.PATCH`, so a numeric three-part compare is * exact — no pre-release/build metadata to reason about in v1. The install flow * (#71) uses this to accept an update only when the uploaded version is higher * than the installed one. */ /** Splits a validated `x.y.z` string into its three numeric parts. */ function parts(version: string): [number, number, number] { const [major = 0, minor = 0, patch = 0] = version.split('.').map((n) => Number.parseInt(n, 10)); return [major, minor, patch]; } /** Returns -1 if `a` < `b`, 1 if `a` > `b`, 0 if equal. */ export function compareVersions(a: string, b: string): -1 | 0 | 1 { const pa = parts(a); const pb = parts(b); for (let i = 0; i < 3; i += 1) { const left = pa[i] ?? 0; const right = pb[i] ?? 0; if (left < right) return -1; if (left > right) return 1; } return 0; } /** Whether `candidate` is a strictly higher version than `current`. */ export function isHigherVersion(candidate: string, current: string): boolean { return compareVersions(candidate, current) > 0; }