Skip to content

Commit cf35ada

Browse files
committed
feat: add file proxy for private repos
1 parent 4bcc86a commit cf35ada

File tree

1 file changed

+49
-4
lines changed

1 file changed

+49
-4
lines changed

src/handler.ts

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@ declare global {
1313
const GITHUB_TOKEN: string
1414
}
1515

16+
const SendJSON = (data: Record<string, unknown>) => {
17+
return new Response(JSON.stringify(data), {
18+
headers: { 'Content-Type': 'application/json; charset=utf-8' },
19+
})
20+
}
21+
1622
const responses = {
1723
NotFound: () => new Response('Not found', { status: 404 }),
1824
NoContent: () => new Response(null, { status: 204 }),
1925
SendUpdate: (data: TauriUpdateResponse) =>
20-
new Response(JSON.stringify(data), {
21-
headers: { 'Content-Type': 'application/json; charset=utf-8' },
22-
}),
26+
SendJSON(data),
27+
SendJSON
28+
2329
}
2430

2531
type RequestPathParts = [
@@ -60,8 +66,10 @@ const handleV1Request = async (request: Request) => {
6066
}
6167

6268
const signature = await findAssetSignature(match.name, release.assets)
69+
const proxy = GITHUB_TOKEN?.length;
70+
const downloadURL = proxy ? createProxiedFileUrl(match.browser_download_url, request) : match.browser_download_url
6371
const data: TauriUpdateResponse = {
64-
url: match.browser_download_url,
72+
url: downloadURL,
6573
version: remoteVersion,
6674
notes: release.body,
6775
pub_date: release.published_at,
@@ -71,8 +79,45 @@ const handleV1Request = async (request: Request) => {
7179
return responses.SendUpdate(data)
7280
}
7381

82+
const createProxiedFileUrl = (downloadURL: string, request: Request) => {
83+
84+
const fileName = downloadURL.split('/')?.at(-1)
85+
if (!fileName) { throw new Error('Could not get file name from download URL') }
86+
87+
88+
const path = new URL(request.url)
89+
const root = `${path.protocol}//${path.host}`
90+
91+
return new URL(`/latest/${fileName}`, root).toString()
92+
}
93+
94+
const getLatestAssets = async (request: Request) => {
95+
const fileName = request.url.split('/')?.at(-1)
96+
if (!fileName) { throw new Error('Could not get file name from download URL') }
97+
98+
const release = await getLatestRelease(request)
99+
const downloadPath = release.assets.find(({ name }) => name === fileName)?.browser_download_url
100+
101+
if (!downloadPath) { throw new Error('Could not get file path from download URL') }
102+
103+
const { readable, writable } = new TransformStream();
104+
const file_response = await fetch(downloadPath, {
105+
method: 'GET',
106+
redirect: 'follow'
107+
})
108+
109+
file_response?.body?.pipeTo(writable);
110+
return new Response(readable, file_response);
111+
112+
}
113+
74114
export async function handleRequest(request: Request): Promise<Response> {
75115
const path = new URL(request.url).pathname
116+
117+
118+
if (path.includes('/latest')) {
119+
return getLatestAssets(request)
120+
}
76121
const version = path.slice(1).split('/')[0]
77122

78123
if (version.includes('v')) {

0 commit comments

Comments
 (0)