Skip to content

Commit 21af966

Browse files
committed
Add fallback logic for download route
1 parent 8f2ae37 commit 21af966

1 file changed

Lines changed: 97 additions & 23 deletions

File tree

  • apps/web/app/(site)/download/[platform]
Lines changed: 97 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,116 @@
11
import { type NextRequest, NextResponse } from "next/server";
2+
import { getGitHubReleases } from "@/utils/releases";
23

34
export const runtime = "edge";
45

6+
type FallbackPlatform = "macos-arm64" | "macos-x64" | "windows";
7+
8+
async function checkCrabNebulaDownload(
9+
url: string,
10+
): Promise<{ ok: true; finalUrl: string } | { ok: false }> {
11+
try {
12+
const res = await fetch(url, {
13+
redirect: "follow",
14+
cache: "no-store",
15+
headers: {
16+
Range: "bytes=0-0",
17+
},
18+
});
19+
20+
if (res.status >= 200 && res.status < 300) {
21+
return { ok: true, finalUrl: res.url };
22+
}
23+
} catch {}
24+
25+
return { ok: false };
26+
}
27+
28+
async function getGitHubFallbackDownloadUrl(
29+
platform: FallbackPlatform,
30+
): Promise<string | null> {
31+
try {
32+
const releases = await getGitHubReleases();
33+
34+
for (const release of releases) {
35+
const url =
36+
platform === "windows"
37+
? release.downloads.windows
38+
: platform === "macos-arm64"
39+
? release.downloads["macos-arm64"]
40+
: release.downloads["macos-x64"];
41+
42+
if (url) return url;
43+
}
44+
} catch {}
45+
46+
return null;
47+
}
48+
549
export async function GET(
650
request: NextRequest,
751
props: { params: Promise<{ platform: string }> },
852
) {
953
const params = await props.params;
1054
const platform = params.platform.toLowerCase();
1155

12-
// Define download URLs for different platforms
13-
const downloadUrls: Record<string, string> = {
14-
"apple-intel":
15-
"https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-x86_64",
16-
intel:
17-
"https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-x86_64", // Keep for backward compatibility
18-
mac: "https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-aarch64", // Default to Apple Silicon
19-
macos:
20-
"https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-aarch64", // Default to Apple Silicon
21-
"apple-silicon":
22-
"https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-aarch64",
23-
aarch64:
24-
"https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-aarch64",
25-
x86_64:
26-
"https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-x86_64",
27-
windows:
28-
"https://cdn.crabnebula.app/download/cap/cap/latest/platform/nsis-x86_64",
29-
win: "https://cdn.crabnebula.app/download/cap/cap/latest/platform/nsis-x86_64",
56+
const downloadUrls: Record<
57+
string,
58+
{ url: string; fallback: FallbackPlatform }
59+
> = {
60+
"apple-intel": {
61+
url: "https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-x86_64",
62+
fallback: "macos-x64",
63+
},
64+
intel: {
65+
url: "https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-x86_64",
66+
fallback: "macos-x64",
67+
},
68+
mac: {
69+
url: "https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-aarch64",
70+
fallback: "macos-arm64",
71+
},
72+
macos: {
73+
url: "https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-aarch64",
74+
fallback: "macos-arm64",
75+
},
76+
"apple-silicon": {
77+
url: "https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-aarch64",
78+
fallback: "macos-arm64",
79+
},
80+
aarch64: {
81+
url: "https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-aarch64",
82+
fallback: "macos-arm64",
83+
},
84+
x86_64: {
85+
url: "https://cdn.crabnebula.app/download/cap/cap/latest/platform/dmg-x86_64",
86+
fallback: "macos-x64",
87+
},
88+
windows: {
89+
url: "https://cdn.crabnebula.app/download/cap/cap/latest/platform/nsis-x86_64",
90+
fallback: "windows",
91+
},
92+
win: {
93+
url: "https://cdn.crabnebula.app/download/cap/cap/latest/platform/nsis-x86_64",
94+
fallback: "windows",
95+
},
3096
};
3197

32-
// Get the download URL for the requested platform
33-
const downloadUrl = downloadUrls[platform];
98+
const download = downloadUrls[platform];
3499

35100
// If the platform is not supported, redirect to the main download page
36-
if (!downloadUrl) {
101+
if (!download) {
37102
return NextResponse.redirect(new URL("/download", request.url));
38103
}
39104

40-
// Redirect to the appropriate download URL
41-
return NextResponse.redirect(downloadUrl);
105+
const primary = await checkCrabNebulaDownload(download.url);
106+
if (primary.ok) {
107+
return NextResponse.redirect(primary.finalUrl);
108+
}
109+
110+
const fallback = await getGitHubFallbackDownloadUrl(download.fallback);
111+
if (fallback) {
112+
return NextResponse.redirect(fallback);
113+
}
114+
115+
return NextResponse.redirect(new URL("/download/versions", request.url));
42116
}

0 commit comments

Comments
 (0)