feat: add SteamGridDB proxy API for non-Steam game images
This commit is contained in:
@@ -81,3 +81,9 @@ EMAIL_FROM="DeckyVault <noreply@deckyvault.xyz>"
|
|||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Discord webhook URL for contact/report submissions
|
# Discord webhook URL for contact/report submissions
|
||||||
DISCORD_WEBHOOK_URL=""
|
DISCORD_WEBHOOK_URL=""
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# STEAMGRIDDB
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# API key for SteamGridDB image search proxy (optional — non-Steam game wizard will show no images without it)
|
||||||
|
STEAMGRIDDB_API_KEY=""
|
||||||
@@ -24,6 +24,7 @@ import { searchUnifiedRoutes } from "@/lib/api/search-unified"
|
|||||||
import { gameStubRoutes } from "@/lib/api/game-stub"
|
import { gameStubRoutes } from "@/lib/api/game-stub"
|
||||||
import { gameStatsRoutes } from "@/lib/api/game-stats"
|
import { gameStatsRoutes } from "@/lib/api/game-stats"
|
||||||
import { gamesListingRoutes } from "@/lib/api/games-listing"
|
import { gamesListingRoutes } from "@/lib/api/games-listing"
|
||||||
|
import { steamgridProxyRoutes } from "@/lib/api/steamgrid-proxy"
|
||||||
|
|
||||||
const betterAuth = new Elysia({ name: "better-auth" })
|
const betterAuth = new Elysia({ name: "better-auth" })
|
||||||
.mount(auth.handler)
|
.mount(auth.handler)
|
||||||
@@ -84,6 +85,8 @@ export const app = new Elysia({ prefix: "/api" })
|
|||||||
.use(searchUnifiedRoutes)
|
.use(searchUnifiedRoutes)
|
||||||
// Game stub creation
|
// Game stub creation
|
||||||
.use(gameStubRoutes)
|
.use(gameStubRoutes)
|
||||||
|
// SteamGridDB proxy
|
||||||
|
.use(steamgridProxyRoutes)
|
||||||
// Game stats aggregation
|
// Game stats aggregation
|
||||||
.use(gameStatsRoutes)
|
.use(gameStatsRoutes)
|
||||||
// Saved games
|
// Saved games
|
||||||
|
|||||||
@@ -14,3 +14,4 @@ export { contactRoutes } from "./contact"
|
|||||||
export { adminReportRoutes } from "./admin-reports"
|
export { adminReportRoutes } from "./admin-reports"
|
||||||
export { adminPerformanceRoutes } from "./admin-performance"
|
export { adminPerformanceRoutes } from "./admin-performance"
|
||||||
export { adminCommentRoutes } from "./admin-comments"
|
export { adminCommentRoutes } from "./admin-comments"
|
||||||
|
export { steamgridProxyRoutes } from "./steamgrid-proxy"
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import { Elysia, t } from "elysia"
|
||||||
|
|
||||||
|
const STEAMGRIDDB_BASE = "https://www.steamgriddb.com/api/v2"
|
||||||
|
|
||||||
|
export const steamgridProxyRoutes = new Elysia({ prefix: "/steamgrid" })
|
||||||
|
.get(
|
||||||
|
"/search",
|
||||||
|
async ({ query, set }) => {
|
||||||
|
const apiKey = process.env.STEAMGRIDDB_API_KEY
|
||||||
|
if (!apiKey) {
|
||||||
|
set.status = 503
|
||||||
|
return { error: "SteamGridDB API key not configured" }
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(
|
||||||
|
`${STEAMGRIDDB_BASE}/search/autocomplete/${encodeURIComponent(query.q)}`,
|
||||||
|
{
|
||||||
|
headers: { Authorization: `Bearer ${apiKey}` },
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
set.status = res.status
|
||||||
|
return { error: "SteamGridDB search failed" }
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await res.json()
|
||||||
|
return data
|
||||||
|
} catch (err) {
|
||||||
|
console.error("SteamGridDB search error:", err)
|
||||||
|
set.status = 500
|
||||||
|
return { error: "SteamGridDB search failed" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
query: t.Object({ q: t.String({ minLength: 2 }) }),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.get(
|
||||||
|
"/grids/:gameId",
|
||||||
|
async ({ params, query, set }) => {
|
||||||
|
const apiKey = process.env.STEAMGRIDDB_API_KEY
|
||||||
|
if (!apiKey) {
|
||||||
|
set.status = 503
|
||||||
|
return { error: "SteamGridDB API key not configured" }
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const url = new URL(`${STEAMGRIDDB_BASE}/grids/game/${params.gameId}`)
|
||||||
|
// Add dimensions filter for capsule-style images
|
||||||
|
url.searchParams.set("dimensions", "600x900,342x482")
|
||||||
|
if (query.styles) {
|
||||||
|
url.searchParams.set("styles", query.styles)
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await fetch(url.toString(), {
|
||||||
|
headers: { Authorization: `Bearer ${apiKey}` },
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
set.status = res.status
|
||||||
|
return { error: "SteamGridDB grids fetch failed" }
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await res.json()
|
||||||
|
return data
|
||||||
|
} catch (err) {
|
||||||
|
console.error("SteamGridDB grids fetch error:", err)
|
||||||
|
set.status = 500
|
||||||
|
return { error: "SteamGridDB grids fetch failed" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
params: t.Object({ gameId: t.String() }),
|
||||||
|
query: t.Object({
|
||||||
|
styles: t.Optional(t.String()),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -17,6 +17,10 @@ const nextConfig: NextConfig = {
|
|||||||
port: "",
|
port: "",
|
||||||
pathname: "/store_item_assets/**",
|
pathname: "/store_item_assets/**",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
protocol: "https",
|
||||||
|
hostname: "cdn.steamgriddb.com",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user