Files
kandev/apps/cli/src/version.ts
T

58 lines
1.6 KiB
TypeScript

/**
* Centralized version parsing and comparison for the CLI.
*
* Version format: optional "v" prefix + dot-separated numeric segments.
* Examples: "v1.2", "0.3.0", "v2.0.1", "1"
*/
export type ParsedVersion = {
raw: string;
segments: number[];
};
/**
* Parse a version string into numeric segments.
* Strips leading "v" prefix if present.
*
* "v1.2.3" -> { raw: "v1.2.3", segments: [1, 2, 3] }
* "0.3" -> { raw: "0.3", segments: [0, 3] }
* "bad" -> { raw: "bad", segments: [] }
*/
export function parseVersion(version: string): ParsedVersion {
const cleaned = String(version).replace(/^v/, "");
const parts = cleaned.split(".");
const segments: number[] = [];
for (const part of parts) {
const n = parseInt(part, 10);
if (Number.isNaN(n)) return { raw: version, segments: [] };
segments.push(n);
}
return { raw: version, segments };
}
/**
* Compare two version strings.
* Returns 1 if a > b, -1 if a < b, 0 if equal.
* Missing segments are treated as 0 (e.g. "1.0" == "1.0.0").
*/
export function compareVersions(a: string, b: string): number {
const pa = parseVersion(a).segments;
const pb = parseVersion(b).segments;
const len = Math.max(pa.length, pb.length);
for (let i = 0; i < len; i++) {
const av = pa[i] ?? 0;
const bv = pb[i] ?? 0;
if (av > bv) return 1;
if (av < bv) return -1;
}
return 0;
}
/**
* Sort version strings in descending order (newest first).
* Non-parseable strings sort to the end.
*/
export function sortVersionsDesc(versions: string[]): string[] {
return [...versions].sort((a, b) => compareVersions(b, a));
}