From 1598de9f5f5ae1e13d6859851307b00ae0566aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Sun, 11 Jan 2026 11:51:02 -0600 Subject: [PATCH] feat: imageProxy --- bun.lock | 1 + packages/website-ue/package.json | 1 + .../website-ue/src/core/api/imageProxy.ts | 23 +++++++++++++++++++ .../src/pages/api/avatars/[id].webp.ts | 10 ++------ .../src/pages/api/backgrounds/[id].webp.ts | 10 ++------ 5 files changed, 29 insertions(+), 16 deletions(-) create mode 100644 packages/website-ue/src/core/api/imageProxy.ts diff --git a/bun.lock b/bun.lock index ebe442f81..4ff81eebc 100644 --- a/bun.lock +++ b/bun.lock @@ -208,6 +208,7 @@ "react": "^19.2.0", "react-dom": "^19.2.0", "react-promise-suspense": "^0.3.4", + "sharp": "^0.34.5", "three": "^0.180.0", "three-stdlib": "^2.36.0", "typescript": "^5.9.3", diff --git a/packages/website-ue/package.json b/packages/website-ue/package.json index 36e86a566..9237c2d1d 100644 --- a/packages/website-ue/package.json +++ b/packages/website-ue/package.json @@ -37,6 +37,7 @@ "react": "^19.2.0", "react-dom": "^19.2.0", "react-promise-suspense": "^0.3.4", + "sharp": "^0.34.5", "three": "^0.180.0", "three-stdlib": "^2.36.0", "typescript": "^5.9.3", diff --git a/packages/website-ue/src/core/api/imageProxy.ts b/packages/website-ue/src/core/api/imageProxy.ts new file mode 100644 index 000000000..bd2ae7b17 --- /dev/null +++ b/packages/website-ue/src/core/api/imageProxy.ts @@ -0,0 +1,23 @@ +import sharp from "sharp"; + +export async function imageProxy(url: string) { + if (import.meta.env.DEV) { + return Response.redirect(url); + } + + let response: Response; + + try { + response = await fetch(url); + } catch (error) { + console.warn(`Failed to fetch image proxy ${url}:`, error); + return new Response(null, { status: 404 }); + } + + const buffer = await response.arrayBuffer(); + const image = sharp(buffer); + const webp = await image.webp().toBuffer(); + const array = new Uint8Array(webp); + + return new Response(array); +} diff --git a/packages/website-ue/src/pages/api/avatars/[id].webp.ts b/packages/website-ue/src/pages/api/avatars/[id].webp.ts index a53bfa200..54400e653 100644 --- a/packages/website-ue/src/pages/api/avatars/[id].webp.ts +++ b/packages/website-ue/src/pages/api/avatars/[id].webp.ts @@ -1,5 +1,6 @@ import type { APIContext, GetStaticPaths } from "astro"; import { api } from "../../../core/api/dynamic"; +import { imageProxy } from "../../../core/api/imageProxy"; export const getStaticPaths = (async () => { const avatars = await api.avatars(); @@ -16,12 +17,5 @@ export async function GET({ params }: APIContext) { const avatar = await api.avatar(params.id); const profileAvatar = avatar.ProfileAvatar(); - if (import.meta.env.DEV) { - return Response.redirect(profileAvatar.avatar); - } - - const response = await fetch(profileAvatar.avatar); - const buffer = await response.arrayBuffer(); - - return new Response(buffer); + return await imageProxy(profileAvatar.avatar); } diff --git a/packages/website-ue/src/pages/api/backgrounds/[id].webp.ts b/packages/website-ue/src/pages/api/backgrounds/[id].webp.ts index bfb7b0f39..58a8ff9c1 100644 --- a/packages/website-ue/src/pages/api/backgrounds/[id].webp.ts +++ b/packages/website-ue/src/pages/api/backgrounds/[id].webp.ts @@ -1,5 +1,6 @@ import type { APIContext, GetStaticPaths } from "astro"; import { api } from "../../../core/api/dynamic"; +import { imageProxy } from "../../../core/api/imageProxy"; export const getStaticPaths = (async () => { const backgrounds = await api.backgrounds(); @@ -16,12 +17,5 @@ export async function GET({ params }: APIContext) { const avatar = await api.background(params.id); const profileBackground = avatar.ProfileBackground(); - if (import.meta.env.DEV) { - return Response.redirect(profileBackground.background); - } - - const response = await fetch(profileBackground.background); - const buffer = await response.arrayBuffer(); - - return new Response(buffer); + return await imageProxy(profileBackground.background); }