3 Commits

Author SHA1 Message Date
def7c52d98 Error Images 2025-06-03 19:44:35 -06:00
465d674efa omg middleware fix 2025-06-03 19:34:32 -06:00
aebe0310f7 Fix thumbnails without needing to change API_HOST 2025-06-03 19:33:44 -06:00
7 changed files with 44 additions and 14 deletions
README.md
web
public
src
app
lib
thumbnails
asset
[assetId]
maps
[mapId]
middleware.ts

@ -26,10 +26,10 @@ Prerequisite: golang installed
Prerequisite: bun installed
The environment variables `BASE_URL` and `AUTH_HOST` will need to be set for the middleware.
The environment variables `API_HOST` and `AUTH_HOST` will need to be set for the middleware.
Example `.env` in web's root:
```
BASE_URL="http://localhost:8082/"
API_HOST="http://localhost:8082/v1"
AUTH_HOST="http://localhost:8083/"
```

BIN
web/public/errors/404.png Normal file

Binary file not shown.

After

(image error) Size: 30 KiB

BIN
web/public/errors/500.png Normal file

Binary file not shown.

After

(image error) Size: 35 KiB

@ -0,0 +1,28 @@
import path from 'path'
import { promises as fs } from 'fs'
export async function errorImageResponse(statusCode: number = 500): Promise<Response> {
const file = `${statusCode}.png`
const filePath = path.join(process.cwd(), 'public/errors', file)
try {
const buffer = await fs.readFile(filePath)
return new Response(buffer, {
status: statusCode,
headers: {
'Content-Type': 'image/png',
'Content-Length': buffer.length.toString(),
},
})
} catch {
const fallback = path.join(process.cwd(), 'public/errors', '500.png')
const buffer = await fs.readFile(fallback)
return new Response(buffer, {
status: 500,
headers: {
'Content-Type': 'image/png',
'Content-Length': buffer.length.toString(),
},
})
}
}

@ -49,7 +49,7 @@ export async function GET(
);
if (!response.ok) {
throw new Error('Failed to fetch thumbnail JSON');
throw new Error(`Failed to fetch thumbnail JSON [${response.status}]`);
}
const data = await response.json();
@ -64,7 +64,7 @@ export async function GET(
const imageResponse = await fetch(imageUrl);
if (!imageResponse.ok) {
throw new Error('Failed to fetch the image');
throw new Error(`Failed to fetch the image [${imageResponse.status}]`);
}
const arrayBuffer = await imageResponse.arrayBuffer();
@ -79,9 +79,9 @@ export async function GET(
'Cache-Control': `public, max-age=${CACHE_TTL / 1000}`,
},
});
} catch {
} catch (err) {
return NextResponse.json(
{ error: 'Failed to fetch or process thumbnail' },
{ error: `Failed to fetch or process thumbnail: ${err}` },
{ status: 500 }
);
}

@ -4,13 +4,15 @@ export async function GET(
request: NextRequest,
context: { params: Promise<{ mapId: string }> }
): Promise<NextResponse> {
// TODO: implement this, we need a cdn for in-game map thumbnails...
const { mapId } = await context.params;
if (!process.env.API_HOST) {
throw new Error('env variable "API_HOST" is not set')
}
const protocol = request.headers.get("x-forwarded-proto") || "https";
const host = request.headers.get("host");
const origin = `${protocol}://${host}`;
const { mapId } = await context.params
return NextResponse.redirect(`${origin}/thumbnails/asset/${mapId}`);
const apiHost = process.env.API_HOST.replace(/\/api\/?$/, "")
const redirectPath = `/thumbnails/asset/${mapId}`
const redirectUrl = `${apiHost}${redirectPath}`
return NextResponse.redirect(redirectUrl)
}

@ -13,7 +13,7 @@ export function middleware(request: NextRequest) {
}
const baseUrl = process.env.BASE_URL.replace(/\/$/, "");
const apiUrl = new URL(baseUrl + pathname + search);
const apiUrl = new URL(baseUrl + pathname.replace(/^\/api/, '') + search);
return NextResponse.rewrite(apiUrl, { request });
} else if (pathname.startsWith("/auth")) {