diff --git a/tasks/generate-redirects.ts b/tasks/generate-redirects.ts index caaaead7..cc3fae32 100644 --- a/tasks/generate-redirects.ts +++ b/tasks/generate-redirects.ts @@ -21,7 +21,33 @@ const flags = parseArgs(Deno.args, { default: { symlinks: false }, }); -const latestRelease = Object.values(versions).slice(-1)[0]; +// "latest" resolves to the most stable release available, never a nightly. +// Nightlies use x-wildcard slugs (e.g. "4.x-nightly") which coerce to an +// inflated placeholder semver (4.99.0-nightly) that would otherwise outrank +// real releases like "4.0.0-alpha.1". Prefer real releases by semver and +// only fall back to nightlies when no real release exists. +const latestRelease = selectLatestRelease(Object.values(versions)); + +function selectLatestRelease( + versionArtifacts: { version: string; cid: string }[], +): { version: string; cid: string } { + const real: { version: string; cid: string; semver: SemVer }[] = []; + const nightlies: { version: string; cid: string; semver: SemVer }[] = []; + + for (const artifact of versionArtifacts) { + const coerced = tryCoerceVersion(artifact.version); + if (!coerced) continue; + const parsed = parseSemver(coerced); + const isTrackAlias = !canParseSemver(artifact.version); + if (isTrackAlias) nightlies.push({ ...artifact, semver: parsed }); + else real.push({ ...artifact, semver: parsed }); + } + + const pool = real.length ? real : nightlies; + return pool.reduce((best, current) => + greaterThan(current.semver, best.semver) ? current : best + ); +} //////////////////////////////////////////// // GENERATE TREES