Newer
Older
bugtrail / packages / shared / src / version.ts
/**
 * Semantic version comparison for x.y.z (optional -suffix) strings.
 * Used by the extension to decide whether the server has a newer overlay
 * module or an extension update is available.
 */

function parse(version: string): number[] {
  const core = version.trim().split("-")[0];
  return core.split(".").map((part) => Number.parseInt(part, 10) || 0);
}

/** -1 when a < b, 0 when equal, 1 when a > b. */
export function compareVersions(a: string, b: string): -1 | 0 | 1 {
  const pa = parse(a);
  const pb = parse(b);
  const len = Math.max(pa.length, pb.length);
  for (let i = 0; i < len; i++) {
    const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
    if (diff !== 0) return diff > 0 ? 1 : -1;
  }
  // same core numbers: a prerelease suffix sorts below the release
  const aPre = a.trim().includes("-");
  const bPre = b.trim().includes("-");
  if (aPre === bPre) return 0;
  return aPre ? -1 : 1;
}

/** True when remote is strictly newer than current. */
export function isVersionNewer(remote: string, current: string): boolean {
  return compareVersions(remote, current) > 0;
}