Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 15 additions & 22 deletions src/registries/cargo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ import type {
} from "./types.ts";
import {
filterByPrefix,
findLatestPrerelease,
findLatestStable,
isPrerelease,
resolveLatestVersions,
sortVersionsDescending,
} from "../utils/version.ts";
import { versionCache } from "../utils/cache.ts";
Expand Down Expand Up @@ -102,43 +101,37 @@ export class CargoClient implements RegistryClient {
}
}

// Find latest stable version
let latestStable = findLatestStable(versions);
const resolved = resolveLatestVersions(versions, {
includePrerelease: options?.includePrerelease,
fallbackStable: !options?.versionPrefix
? (data.crate.max_stable_version || data.crate.max_version)
: undefined,
});

// Fall back to max_stable_version if available
if (!latestStable && !options?.versionPrefix) {
latestStable = data.crate.max_stable_version || data.crate.max_version;
}

if (!latestStable) {
if (!resolved) {
throw new Error(
`No stable version found for '${packageName}'${
`No version found for '${packageName}'${
options?.versionPrefix
? ` with prefix '${options.versionPrefix}'`
: ""
}`,
);
}

const versionData = data.versions.find((v) => v.num === latestStable);
const versionData = data.versions.find((v) =>
v.num === resolved.latestStable
);
const publishedAt = versionData?.created_at;

const result: VersionInfo = {
packageName: data.crate.name,
registry: "cargo",
latestStable,
latestStable: resolved.latestStable,
publishedAt: publishedAt ? new Date(publishedAt) : undefined,
};

// Include latest prerelease if requested
if (options?.includePrerelease) {
const latestPre = findLatestPrerelease(versions);
if (
latestPre &&
sortVersionsDescending([latestPre, latestStable])[0] === latestPre
) {
result.latestPrerelease = latestPre;
}
if (resolved.latestPrerelease) {
result.latestPrerelease = resolved.latestPrerelease;
}

return result;
Expand Down
39 changes: 17 additions & 22 deletions src/registries/docker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ import type {
} from "./types.ts";
import {
filterByPrefix,
findLatestPrerelease,
findLatestStable,
isPrerelease,
parseVersion,
resolveLatestVersions,
sortVersionsDescending,
} from "../utils/version.ts";
import { versionCache } from "../utils/cache.ts";
Expand Down Expand Up @@ -244,32 +243,36 @@ export class DockerClient implements RegistryClient {
const baseVersionTags = semverTags.map((t) => this.getBaseVersion(t));

// Find latest stable version from semver tags
let latestStable = findLatestStable(baseVersionTags);

// If no semver-like stable version found, check for "latest" tag
if (!latestStable && !options?.versionPrefix) {
// Compute Docker-specific fallback: "latest" tag, or most recently updated
let dockerFallback: string | undefined;
if (!options?.versionPrefix) {
if (tagNames.includes("latest")) {
latestStable = "latest";
dockerFallback = "latest";
} else if (tagNames.length > 0) {
// Fall back to most recently updated tag
const sortedTags = [...tags].sort((a, b) => {
const dateA = a.last_updated ? new Date(a.last_updated).getTime() : 0;
const dateB = b.last_updated ? new Date(b.last_updated).getTime() : 0;
return dateB - dateA;
});
latestStable = sortedTags[0].name;
dockerFallback = sortedTags[0].name;
}
}

if (!latestStable) {
const resolved = resolveLatestVersions(baseVersionTags, {
includePrerelease: options?.includePrerelease,
fallbackStable: dockerFallback,
});

if (!resolved) {
throw new Error(
`No stable version found for '${imageName}'${
`No version found for '${imageName}'${
options?.versionPrefix
? ` with prefix '${options.versionPrefix}'`
: ""
}`,
);
}
const latestStable = resolved.latestStable;

// Find the tag data for the latest stable
const latestTagData = tags.find(
Expand Down Expand Up @@ -297,17 +300,9 @@ export class DockerClient implements RegistryClient {
securityNotes: generateDockerSecurityNotes(),
};

// Include latest prerelease if requested
if (options?.includePrerelease) {
const prereleases = semverTags.filter((v) => isPrerelease(v));
const latestPre = findLatestPrerelease(prereleases);
if (
latestPre &&
latestStable !== "latest" &&
sortVersionsDescending([latestPre, latestStable])[0] === latestPre
) {
result.latestPrerelease = latestPre;
}
// Use the resolved prerelease (only valid when latestStable is a real version)
if (resolved.latestPrerelease && latestStable !== "latest") {
result.latestPrerelease = resolved.latestPrerelease;
}

return result;
Expand Down
29 changes: 12 additions & 17 deletions src/registries/github-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ import type {
} from "./types.ts";
import {
filterByPrefix,
findLatestPrerelease,
findLatestStable,
isPrerelease,
resolveLatestVersions,
sortVersionsDescending,
} from "../utils/version.ts";
import { versionCache } from "../utils/cache.ts";
Expand Down Expand Up @@ -197,11 +196,13 @@ export class GitHubActionsClient implements RegistryClient {
}
}

const latestStable = findLatestStable(versionStrings);
const resolved = resolveLatestVersions(versionStrings, {
includePrerelease: options?.includePrerelease,
});

if (!latestStable) {
if (!resolved) {
throw new Error(
`No stable version found for '${packageName}'${
`No version found for '${packageName}'${
options?.versionPrefix
? ` with prefix '${options.versionPrefix}'`
: ""
Expand All @@ -211,21 +212,21 @@ export class GitHubActionsClient implements RegistryClient {

// Find the tag with matching version to get commit SHA
const matchingTag = semverTags.find(
(t) => stripVPrefix(t.name) === latestStable,
(t) => stripVPrefix(t.name) === resolved.latestStable,
);
const commitSha = matchingTag?.commit.sha;

// Find release data for publish date
const release = releases.find(
(r) => stripVPrefix(r.tag_name) === latestStable,
(r) => stripVPrefix(r.tag_name) === resolved.latestStable,
);

const versionTag = matchingTag?.name ?? `v${latestStable}`;
const versionTag = matchingTag?.name ?? `v${resolved.latestStable}`;

const result: VersionInfo = {
packageName,
registry: "github-actions",
latestStable,
latestStable: resolved.latestStable,
publishedAt: release?.published_at
? new Date(release.published_at)
: undefined,
Expand All @@ -242,14 +243,8 @@ export class GitHubActionsClient implements RegistryClient {
],
};

if (options?.includePrerelease) {
const latestPre = findLatestPrerelease(versionStrings);
if (
latestPre &&
sortVersionsDescending([latestPre, latestStable])[0] === latestPre
) {
result.latestPrerelease = latestPre;
}
if (resolved.latestPrerelease) {
result.latestPrerelease = resolved.latestPrerelease;
}

return result;
Expand Down
27 changes: 10 additions & 17 deletions src/registries/go.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ import type {
} from "./types.ts";
import {
filterByPrefix,
findLatestPrerelease,
findLatestStable,
isPrerelease,
resolveLatestVersions,
sortVersionsDescending,
} from "../utils/version.ts";
import { versionCache } from "../utils/cache.ts";
Expand Down Expand Up @@ -121,12 +120,13 @@ export class GoClient implements RegistryClient {
}
}

// Find latest stable version
const latestStable = findLatestStable(versions);
const resolved = resolveLatestVersions(versions, {
includePrerelease: options?.includePrerelease,
});

if (!latestStable) {
if (!resolved) {
throw new Error(
`No stable version found for '${packageName}'${
`No version found for '${packageName}'${
options?.versionPrefix
? ` with prefix '${options.versionPrefix}'`
: ""
Expand All @@ -139,7 +139,7 @@ export class GoClient implements RegistryClient {
try {
const info = await this.fetchVersionInfo(
packageName,
latestStable,
resolved.latestStable,
options?.repository,
);
publishedAt = new Date(info.Time);
Expand All @@ -150,19 +150,12 @@ export class GoClient implements RegistryClient {
const result: VersionInfo = {
packageName,
registry: "go",
latestStable,
latestStable: resolved.latestStable,
publishedAt,
};

// Include latest prerelease if requested
if (options?.includePrerelease) {
const latestPre = findLatestPrerelease(versions);
if (
latestPre &&
sortVersionsDescending([latestPre, latestStable])[0] === latestPre
) {
result.latestPrerelease = latestPre;
}
if (resolved.latestPrerelease) {
result.latestPrerelease = resolved.latestPrerelease;
}

return result;
Expand Down
35 changes: 13 additions & 22 deletions src/registries/jsr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ import type {
} from "./types.ts";
import {
filterByPrefix,
findLatestPrerelease,
findLatestStable,
isPrerelease,
resolveLatestVersions,
sortVersionsDescending,
} from "../utils/version.ts";
import { versionCache } from "../utils/cache.ts";
Expand Down Expand Up @@ -156,17 +155,16 @@ export class JsrClient implements RegistryClient {
versions = filterByPrefix(versions, options.versionPrefix);
}

// Find latest stable version
let latestStable = findLatestStable(versions);

// If no stable found with prefix, fall back to package metadata
if (!latestStable && !options?.versionPrefix) {
latestStable = packageData.latestVersion ?? null;
}
const resolved = resolveLatestVersions(versions, {
includePrerelease: options?.includePrerelease,
fallbackStable: !options?.versionPrefix
? packageData.latestVersion ?? undefined
: undefined,
});

if (!latestStable) {
if (!resolved) {
throw new Error(
`No stable version found for '${packageName}'${
`No version found for '${packageName}'${
options?.versionPrefix
? ` with prefix '${options.versionPrefix}'`
: ""
Expand All @@ -176,28 +174,21 @@ export class JsrClient implements RegistryClient {

// Find publish date for the latest version
const latestVersionData = versionsData.find((v) =>
v.version === latestStable
v.version === resolved.latestStable
);

const result: VersionInfo = {
packageName,
registry: "jsr",
latestStable,
latestStable: resolved.latestStable,
publishedAt: latestVersionData?.createdAt
? new Date(latestVersionData.createdAt)
: undefined,
deprecated: packageData.isArchived ?? false,
};

// Include latest prerelease if requested
if (options?.includePrerelease) {
const latestPre = findLatestPrerelease(versions);
if (
latestPre &&
sortVersionsDescending([latestPre, latestStable])[0] === latestPre
) {
result.latestPrerelease = latestPre;
}
if (resolved.latestPrerelease) {
result.latestPrerelease = resolved.latestPrerelease;
}

return result;
Expand Down
24 changes: 9 additions & 15 deletions src/registries/maven.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ import type {
} from "./types.ts";
import {
filterByPrefix,
findLatestPrerelease,
findLatestStable,
isPrerelease,
resolveLatestVersions,
sortVersionsDescending,
} from "../utils/version.ts";
import { versionCache } from "../utils/cache.ts";
Expand Down Expand Up @@ -155,11 +154,13 @@ export class MavenClient implements RegistryClient {
}
}

const latestStable = findLatestStable(versionStrings);
const resolved = resolveLatestVersions(versionStrings, {
includePrerelease: options?.includePrerelease,
});

if (!latestStable) {
if (!resolved) {
throw new Error(
`No stable version found for '${packageName}'${
`No version found for '${packageName}'${
options?.versionPrefix
? ` with prefix '${options.versionPrefix}'`
: ""
Expand All @@ -170,18 +171,11 @@ export class MavenClient implements RegistryClient {
const result: VersionInfo = {
packageName,
registry: "maven",
latestStable,
latestStable: resolved.latestStable,
};

// Include latest prerelease if requested
if (options?.includePrerelease) {
const latestPre = findLatestPrerelease(versionStrings);
if (
latestPre &&
sortVersionsDescending([latestPre, latestStable])[0] === latestPre
) {
result.latestPrerelease = latestPre;
}
if (resolved.latestPrerelease) {
result.latestPrerelease = resolved.latestPrerelease;
}

return result;
Expand Down
Loading