import { ImageResponse } from "next/og"
import { db } from "@/lib/db/index"
import { games, gameVersions, performanceEntries } from "@/lib/db/schema"
import { eq, and, sql } from "drizzle-orm"
import { readFile } from "node:fs/promises"
import { join } from "node:path"
export const alt = "DeckyVault - Game Benchmarks"
export const size = { width: 1200, height: 630 }
export const contentType = "image/png"
export default async function Image({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params
const isNumeric = /^\d+$/.test(id)
let game
if (isNumeric) {
const rows = await db.select().from(games).where(eq(games.steamAppId, Number(id))).limit(1)
game = rows[0]
} else {
const rows = await db.select().from(games).where(eq(games.id, id)).limit(1)
game = rows[0]
}
if (!game) {
return new ImageResponse(
(
Game Not Found
DeckyVault
),
{ ...size }
)
}
// Get best FPS stat
let avgFps: number | null = null
try {
const [bestStat] = await db
.select({ avgFps: sql`round(avg(${performanceEntries.fpsAvg})::numeric, 1)` })
.from(performanceEntries)
.innerJoin(gameVersions, eq(performanceEntries.versionId, gameVersions.id))
.where(and(eq(gameVersions.gameId, game.id), eq(performanceEntries.isRemoved, false)))
.limit(1)
avgFps = bestStat?.avgFps ?? null
} catch {
// No FPS data available — that's fine
}
const logoData = await readFile(join(process.cwd(), "app/icon.png"), "base64")
const logoSrc = `data:image/png;base64,${logoData}`
return new ImageResponse(
(
DeckyVault
{game.title}
{game.developer && by {game.developer}}
{avgFps !== null && ~{avgFps} avg FPS}
{game.genres && game.genres.length > 0 && (
{game.genres.slice(0, 4).map((genre: string) => (
{genre}
))}
)}
),
{ ...size }
)
}