mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-25 12:05:06 +02:00
Co-authored-by: Lambda <lambda@multica.ai> Co-authored-by: multica-agent <github@multica.ai>
101 lines
3.5 KiB
TypeScript
101 lines
3.5 KiB
TypeScript
/**
|
|
* Parses the GitHub Releases API asset array into a structured
|
|
* download asset map. Skips auxiliary files (blockmaps, update
|
|
* manifests, checksums) and the CLI tarballs — only desktop
|
|
* installer artifacts are relevant on the /download page.
|
|
*
|
|
* Desktop artifact naming (see apps/desktop/electron-builder.yml):
|
|
* multica-desktop-{version}-mac-{arch}.{dmg|zip}
|
|
* multica-desktop-{version}-windows-{arch}.exe
|
|
* multica-desktop-{version}-linux-{arch}.{AppImage|deb|rpm}
|
|
*
|
|
* Linux arch appears as amd64 / x86_64 / arm64 / aarch64 depending
|
|
* on the format; we normalize to amd64 and arm64.
|
|
*/
|
|
|
|
export interface GitHubAsset {
|
|
name: string;
|
|
browser_download_url: string;
|
|
}
|
|
|
|
export interface DownloadAssets {
|
|
macArm64Dmg?: string;
|
|
macArm64Zip?: string;
|
|
macX64Dmg?: string;
|
|
macX64Zip?: string;
|
|
winX64Exe?: string;
|
|
winArm64Exe?: string;
|
|
linuxAmd64AppImage?: string;
|
|
linuxAmd64Deb?: string;
|
|
linuxAmd64Rpm?: string;
|
|
linuxArm64AppImage?: string;
|
|
linuxArm64Deb?: string;
|
|
linuxArm64Rpm?: string;
|
|
}
|
|
|
|
const DESKTOP_ARTIFACT_RE =
|
|
/^multica-desktop-[^-]+-(mac|windows|linux)-([a-z0-9_]+)\.(dmg|zip|exe|AppImage|deb|rpm)$/i;
|
|
|
|
function normalizeLinuxArch(arch: string): "amd64" | "arm64" | null {
|
|
const a = arch.toLowerCase();
|
|
if (a === "amd64" || a === "x86_64") return "amd64";
|
|
if (a === "arm64" || a === "aarch64") return "arm64";
|
|
return null;
|
|
}
|
|
|
|
export function parseReleaseAssets(raw: GitHubAsset[]): DownloadAssets {
|
|
const out: DownloadAssets = {};
|
|
for (const asset of raw) {
|
|
const name = asset.name;
|
|
// Skip auxiliary files that share the release (update manifests,
|
|
// blockmaps, checksums). CLI tarballs and other non-desktop
|
|
// artifacts are excluded automatically because they don't match
|
|
// DESKTOP_ARTIFACT_RE below.
|
|
if (name.endsWith(".blockmap") || name.endsWith(".yml")) continue;
|
|
if (name.startsWith("checksums")) continue;
|
|
|
|
const match = DESKTOP_ARTIFACT_RE.exec(name);
|
|
if (!match) continue;
|
|
const platform = match[1];
|
|
const arch = match[2];
|
|
const ext = match[3];
|
|
if (!platform || !arch || !ext) continue;
|
|
const archLower = arch.toLowerCase();
|
|
const extLower = ext.toLowerCase();
|
|
const url = asset.browser_download_url;
|
|
|
|
if (platform === "mac") {
|
|
if (archLower === "arm64") {
|
|
if (extLower === "dmg") out.macArm64Dmg = url;
|
|
else if (extLower === "zip") out.macArm64Zip = url;
|
|
} else if (archLower === "x64") {
|
|
if (extLower === "dmg") out.macX64Dmg = url;
|
|
else if (extLower === "zip") out.macX64Zip = url;
|
|
}
|
|
} else if (platform === "windows") {
|
|
if (extLower !== "exe") continue;
|
|
if (archLower === "x64") out.winX64Exe = url;
|
|
else if (archLower === "arm64") out.winArm64Exe = url;
|
|
} else if (platform === "linux") {
|
|
const normalized = normalizeLinuxArch(arch);
|
|
if (!normalized) continue;
|
|
const e = extLower;
|
|
if (normalized === "amd64") {
|
|
if (e === "appimage") out.linuxAmd64AppImage = url;
|
|
else if (e === "deb") out.linuxAmd64Deb = url;
|
|
else if (e === "rpm") out.linuxAmd64Rpm = url;
|
|
} else {
|
|
if (e === "appimage") out.linuxArm64AppImage = url;
|
|
else if (e === "deb") out.linuxArm64Deb = url;
|
|
else if (e === "rpm") out.linuxArm64Rpm = url;
|
|
}
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
/** Whether any desktop asset was parsed out. Used for UI degradation. */
|
|
export function hasAnyAsset(assets: DownloadAssets): boolean {
|
|
return Object.values(assets).some((v) => typeof v === "string");
|
|
}
|