Skip to content

Commit c80be39

Browse files
fix(api): cache GitHub release assets
Cache GitHub release fetches locally and keep the release route dynamic.
1 parent 27cb4e9 commit c80be39

3 files changed

Lines changed: 12 additions & 16 deletions

File tree

apps/api/nitro.config.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,6 @@ export default defineConfig({
3636
},
3737
},
3838
routeRules: {
39-
"/release/**": {
40-
headers: {
41-
"cache-control":
42-
"public, max-age=60, s-maxage=300, stale-while-revalidate=3600",
43-
},
44-
},
4539
"/main.user.css": {
4640
redirect: "/release/latest/?asset=main.user.css",
4741
},

apps/api/src/routes/release/[tag]/index.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,10 @@ export default defineHandler(async (event) => {
9090
if (import.meta.dev) {
9191
event.res.headers.set("X-Source", "local");
9292
} else {
93-
event.res.headers.set(
94-
"Cache-Control",
95-
tag === "latest"
96-
? "public, max-age=60, s-maxage=300, stale-while-revalidate=3600"
97-
: "public, max-age=31536000, immutable",
98-
);
9993
event.res.headers.set("X-Source", "github");
10094
event.res.headers.set("X-Proxy-Host", "github.com");
10195
for (const name of allowedHeaders) {
102-
const value = headers?.get(name);
96+
const value = headers?.[name];
10397
if (value) event.res.headers.set(name, value);
10498
}
10599
}

apps/api/src/utils/fetcher.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { readFile } from "node:fs/promises";
22
import { isAbsolute, resolve } from "node:path";
3+
import { defineCachedFunction } from "nitro/cache";
34
import { HTTPError } from "nitro/h3";
45
import { useRuntimeConfig } from "nitro/runtime-config";
56
import { $fetch } from "ofetch";
@@ -12,7 +13,7 @@ const RETRYABLE_STATUS_CODES = new Set([408, 425, 429, 500, 502, 503, 504]);
1213

1314
export interface FetchResult {
1415
content: string;
15-
headers?: Headers;
16+
headers?: Record<string, string>;
1617
}
1718

1819
export async function fetchAsset(
@@ -22,9 +23,16 @@ export async function fetchAsset(
2223
if (import.meta.dev) {
2324
return fetchFromLocal(asset);
2425
}
25-
return fetchFromGitHub(tag, asset);
26+
return cachedFetchFromGitHub(tag, asset);
2627
}
2728

29+
const cachedFetchFromGitHub = defineCachedFunction(fetchFromGitHub, {
30+
name: "github-release-asset",
31+
maxAge: 60,
32+
staleMaxAge: 300,
33+
getKey: (tag: string, asset: string) => `${tag}:${asset}`,
34+
});
35+
2836
async function fetchFromGitHub(
2937
tag: string,
3038
asset: string,
@@ -46,7 +54,7 @@ async function fetchFromGitHub(
4654

4755
return {
4856
content: typeof response._data === "string" ? response._data : "",
49-
headers: new Headers(response.headers),
57+
headers: Object.fromEntries(response.headers),
5058
};
5159
}
5260

0 commit comments

Comments
 (0)