fix(landing): derive platform support from release assets
This commit is contained in:
1 parent
1453a8fa95
commit
f8ed2aa666
6 files changed
+227
-6
No files matched your search
@@ -0,0 +1,106 @@
|
||||
import {
|
||||
platformDownloads,
|
||||
type PlatformDownload,
|
||||
type PlatformDownloadAsset,
|
||||
type ReleaseArchitecture,
|
||||
} from "../components/release-links.generated";
|
||||
|
||||
const ARCHITECTURE_ORDER: ReleaseArchitecture[] = ["arm64", "x64", "x86"];
|
||||
|
||||
export type PlatformSupportSummary = {
|
||||
downloadAnswer: string;
|
||||
platformAnswer: string;
|
||||
};
|
||||
|
||||
export const platformSupportSummary = buildPlatformSupportSummary(platformDownloads);
|
||||
|
||||
export function buildPlatformSupportSummary(downloads: PlatformDownload[]): PlatformSupportSummary {
|
||||
const macos = requirePlatform(downloads, "macos");
|
||||
const windows = requirePlatform(downloads, "windows");
|
||||
const linux = requirePlatform(downloads, "linux");
|
||||
|
||||
return {
|
||||
downloadAnswer:
|
||||
`Use the download section on this page to choose the build that matches your architecture and package format. ` +
|
||||
`${formatDownloadSentence(macos)} ${formatDownloadSentence(windows)} ${formatDownloadSentence(linux)}`,
|
||||
platformAnswer:
|
||||
`AgentCompany is available on ${formatAvailability(macos)}, ${formatAvailability(windows)}, ` +
|
||||
`and ${formatAvailability(linux)}. It is built with Electron and the desktop feature set stays aligned across all supported targets.`,
|
||||
};
|
||||
}
|
||||
|
||||
function requirePlatform(downloads: PlatformDownload[], id: PlatformDownload["id"]): PlatformDownload {
|
||||
const platform = downloads.find((download) => download.id === id);
|
||||
if (!platform) {
|
||||
throw new Error(`Missing ${id} release download metadata.`);
|
||||
}
|
||||
return platform;
|
||||
}
|
||||
|
||||
function formatDownloadSentence(download: PlatformDownload): string {
|
||||
const architectures = formatArchitectureList(collectArchitectures(download));
|
||||
|
||||
if (!download.packageDescription.trim()) {
|
||||
throw new Error(`Release platform ${download.id} must include package format copy.`);
|
||||
}
|
||||
|
||||
return `${download.title} ships as ${download.packageDescription} for ${architectures}.`;
|
||||
}
|
||||
|
||||
function formatAvailability(download: PlatformDownload): string {
|
||||
return `${download.title} (${formatArchitectureList(collectArchitectures(download), "comma")})`;
|
||||
}
|
||||
|
||||
function collectArchitectures(download: PlatformDownload): ReleaseArchitecture[] {
|
||||
const architectures = new Set<ReleaseArchitecture>();
|
||||
|
||||
for (const asset of download.assets) {
|
||||
collectAssetArchitectures(download.id, asset).forEach((architecture) => architectures.add(architecture));
|
||||
}
|
||||
|
||||
return [...architectures].sort((left, right) => architectureRank(left) - architectureRank(right));
|
||||
}
|
||||
|
||||
function collectAssetArchitectures(
|
||||
platformId: PlatformDownload["id"],
|
||||
asset: PlatformDownloadAsset,
|
||||
): ReleaseArchitecture[] {
|
||||
if (asset.architectures.length === 0) {
|
||||
throw new Error(`Release asset ${platformId}/${asset.id} must declare at least one architecture.`);
|
||||
}
|
||||
|
||||
for (const architecture of asset.architectures) {
|
||||
if (!isReleaseArchitecture(architecture)) {
|
||||
throw new Error(`Release asset ${platformId}/${asset.id} declares unsupported architecture: ${architecture}`);
|
||||
}
|
||||
}
|
||||
|
||||
return asset.architectures;
|
||||
}
|
||||
|
||||
function isReleaseArchitecture(value: string): value is ReleaseArchitecture {
|
||||
return ARCHITECTURE_ORDER.includes(value as ReleaseArchitecture);
|
||||
}
|
||||
|
||||
function architectureRank(architecture: ReleaseArchitecture): number {
|
||||
return ARCHITECTURE_ORDER.indexOf(architecture);
|
||||
}
|
||||
|
||||
function formatArchitectureList(
|
||||
architectures: ReleaseArchitecture[],
|
||||
style: "and" | "comma" = "and",
|
||||
): string {
|
||||
if (architectures.length === 0) {
|
||||
throw new Error("Release download metadata must include at least one architecture.");
|
||||
}
|
||||
if (style === "comma") {
|
||||
return architectures.join(", ");
|
||||
}
|
||||
if (architectures.length === 1) {
|
||||
return architectures[0];
|
||||
}
|
||||
if (architectures.length === 2) {
|
||||
return `${architectures[0]} and ${architectures[1]}`;
|
||||
}
|
||||
return `${architectures.slice(0, -1).join(", ")}, and ${architectures.at(-1)}`;
|
||||
}
|
||||
Reference in new issue
Block a user