diff --git a/app/api/[[...slugs]]/route.ts b/app/api/[[...slugs]]/route.ts index 8624833..dc1f2ae 100644 --- a/app/api/[[...slugs]]/route.ts +++ b/app/api/[[...slugs]]/route.ts @@ -1,131 +1,7 @@ -import { Elysia } from "elysia" -import { auth } from "@/lib/auth" -import { rateLimit } from "@/lib/auth/rate-limit" -import { - healthRoutes, - userRoutes, - gamesRoutes, - gameVersionsRoutes, - gameSyncRoutes, - hardwareRoutes, - hardwareStatsRoutes, - performanceRoutes, - performanceVerifyRoutes, - performanceSubmitRoutes, - commentsRoutes, - savedGamesRoutes, - reportRoutes, - contactRoutes, - adminReportRoutes, - adminPerformanceRoutes, - adminCommentRoutes, -} from "@/lib/api" -import { steamSearchRoutes } from "@/lib/api/steam-search" -import { searchUnifiedRoutes } from "@/lib/api/search-unified" -import { gameStubRoutes } from "@/lib/api/game-stub" -import { gameStatsRoutes } from "@/lib/api/game-stats" -import { gamesManualRoutes } from "@/lib/api/games-manual" -import { compareRoutes } from "@/lib/api/compare" -import { playabilityRoutes } from "@/lib/api/playability" -import { steamReviewRoutes } from "@/lib/api/steam-reviews" -import { communitySuggestionRoutes } from "@/lib/api/community-suggestions" -import { gamesListingRoutes } from "@/lib/api/games-listing" -import { steamgridProxyRoutes } from "@/lib/api/steamgrid-proxy" -import { dashboardRoutes } from "@/lib/api/dashboard" -import { savedFilterRoutes } from "@/lib/api/saved-filters" - -const betterAuth = new Elysia({ name: "better-auth" }) - .mount(auth.handler) - .macro({ - auth: { - async resolve({ status, request: { headers } }) { - const session = await auth.api.getSession({ - headers, - }) - - if (!session) return status(401) - - return { - user: session.user, - session: session.session, - } - }, - }, - }) - -export const app = new Elysia({ prefix: "/api" }) - .onError(({ code, error, set, request }) => { - console.error( - `[API Error] ${code} ${request.url}`, - error instanceof Error ? error.message : error, - ) - set.status = code === "NOT_FOUND" ? 404 : 500 - return { - error: code === "NOT_FOUND" ? "Not found" : "Internal server error", - } - }) - .use(rateLimit(60, 100)) - .use(betterAuth) - // Health - .use(healthRoutes) - // Users - .use(userRoutes) - // Games + Versions - .use(gamesRoutes) - .use(gameVersionsRoutes) - .use(gameSyncRoutes) - .use(gamesListingRoutes) - // Hardware - .use(hardwareRoutes) - .use(hardwareStatsRoutes) - // Performance - .use(performanceRoutes) - .use(performanceVerifyRoutes) - .use(performanceSubmitRoutes) - .use(reportRoutes) - .use(adminReportRoutes) - .use(adminPerformanceRoutes) - .use(adminCommentRoutes) - // Comments - .use(commentsRoutes) - // Steam search proxy - .use(steamSearchRoutes) - // Unified search - .use(searchUnifiedRoutes) - // Game stub creation - .use(gameStubRoutes) - // SteamGridDB proxy - .use(steamgridProxyRoutes) - // Game stats aggregation - .use(gameStatsRoutes) - // Manual game creation - .use(gamesManualRoutes) - // Saved games - .use(savedGamesRoutes) - // Contact form - .use(contactRoutes) - // Compare - .use(compareRoutes) - // Playability - .use(playabilityRoutes) - // Steam reviews - .use(steamReviewRoutes) - // Community suggestions - .use(communitySuggestionRoutes) - // Saved filters - .use(savedFilterRoutes) - // Dashboard - .use(dashboardRoutes) - // Root - .get("/", () => ({ - name: "DeckyVault API", - version: "2026.0.9", - })) +import { app } from "@/lib/api/app" export const GET = app.fetch export const POST = app.fetch export const PUT = app.fetch export const DELETE = app.fetch export const PATCH = app.fetch - -export type App = typeof app diff --git a/app/devices/[slug]/opengraph-image.tsx b/app/devices/[slug]/opengraph-image.tsx index 21f93d8..53b7cab 100644 --- a/app/devices/[slug]/opengraph-image.tsx +++ b/app/devices/[slug]/opengraph-image.tsx @@ -3,7 +3,6 @@ import { db } from "@/lib/db/index" import { hardware, performanceEntries, gameVersions, games } from "@/lib/db/schema" import { eq, and, sql } from "drizzle-orm" -export const runtime = "nodejs" export const dynamic = "force-dynamic" export const alt = "Device benchmarks on DeckyVault" export const size = { width: 1200, height: 630 } diff --git a/app/sitemap.ts b/app/sitemap.ts index af8aa12..a0ff6bf 100644 --- a/app/sitemap.ts +++ b/app/sitemap.ts @@ -13,7 +13,7 @@ import { fetchDynamicEntries } from "@/lib/sitemap/fetch-dynamic-entries" * On-demand purging is handled by `/api/revalidate-sitemap` which * calls `revalidatePath("/sitemap.xml")`. */ -export const revalidate = Number(process.env.SITEMAP_REVALIDATE_SECONDS) || 3600 +export const revalidate = 3600 /** * Generates the sitemap for deckyvault.xyz. diff --git a/lib/api/app.ts b/lib/api/app.ts new file mode 100644 index 0000000..356b1fb --- /dev/null +++ b/lib/api/app.ts @@ -0,0 +1,125 @@ +import { Elysia } from "elysia" +import { auth } from "@/lib/auth" +import { rateLimit } from "@/lib/auth/rate-limit" +import { + healthRoutes, + userRoutes, + gamesRoutes, + gameVersionsRoutes, + gameSyncRoutes, + hardwareRoutes, + hardwareStatsRoutes, + performanceRoutes, + performanceVerifyRoutes, + performanceSubmitRoutes, + commentsRoutes, + savedGamesRoutes, + reportRoutes, + contactRoutes, + adminReportRoutes, + adminPerformanceRoutes, + adminCommentRoutes, +} from "@/lib/api" +import { steamSearchRoutes } from "@/lib/api/steam-search" +import { searchUnifiedRoutes } from "@/lib/api/search-unified" +import { gameStubRoutes } from "@/lib/api/game-stub" +import { gameStatsRoutes } from "@/lib/api/game-stats" +import { gamesManualRoutes } from "@/lib/api/games-manual" +import { compareRoutes } from "@/lib/api/compare" +import { playabilityRoutes } from "@/lib/api/playability" +import { steamReviewRoutes } from "@/lib/api/steam-reviews" +import { communitySuggestionRoutes } from "@/lib/api/community-suggestions" +import { gamesListingRoutes } from "@/lib/api/games-listing" +import { steamgridProxyRoutes } from "@/lib/api/steamgrid-proxy" +import { dashboardRoutes } from "@/lib/api/dashboard" +import { savedFilterRoutes } from "@/lib/api/saved-filters" + +const betterAuth = new Elysia({ name: "better-auth" }) + .mount(auth.handler) + .macro({ + auth: { + async resolve({ status, request: { headers } }) { + const session = await auth.api.getSession({ + headers, + }) + + if (!session) return status(401) + + return { + user: session.user, + session: session.session, + } + }, + }, + }) + +export const app = new Elysia({ prefix: "/api" }) + .onError(({ code, error, set, request }) => { + console.error( + `[API Error] ${code} ${request.url}`, + error instanceof Error ? error.message : error, + ) + set.status = code === "NOT_FOUND" ? 404 : 500 + return { + error: code === "NOT_FOUND" ? "Not found" : "Internal server error", + } + }) + .use(rateLimit(60, 100)) + .use(betterAuth) + // Health + .use(healthRoutes) + // Users + .use(userRoutes) + // Games + Versions + .use(gamesRoutes) + .use(gameVersionsRoutes) + .use(gameSyncRoutes) + .use(gamesListingRoutes) + // Hardware + .use(hardwareRoutes) + .use(hardwareStatsRoutes) + // Performance + .use(performanceRoutes) + .use(performanceVerifyRoutes) + .use(performanceSubmitRoutes) + .use(reportRoutes) + .use(adminReportRoutes) + .use(adminPerformanceRoutes) + .use(adminCommentRoutes) + // Comments + .use(commentsRoutes) + // Steam search proxy + .use(steamSearchRoutes) + // Unified search + .use(searchUnifiedRoutes) + // Game stub creation + .use(gameStubRoutes) + // SteamGridDB proxy + .use(steamgridProxyRoutes) + // Game stats aggregation + .use(gameStatsRoutes) + // Manual game creation + .use(gamesManualRoutes) + // Saved games + .use(savedGamesRoutes) + // Contact form + .use(contactRoutes) + // Compare + .use(compareRoutes) + // Playability + .use(playabilityRoutes) + // Steam reviews + .use(steamReviewRoutes) + // Community suggestions + .use(communitySuggestionRoutes) + // Saved filters + .use(savedFilterRoutes) + // Dashboard + .use(dashboardRoutes) + // Root + .get("/", () => ({ + name: "DeckyVault API", + version: "2026.0.9", + })) + +export type App = typeof app diff --git a/lib/eden.ts b/lib/eden.ts index 730dd7c..78993a2 100644 --- a/lib/eden.ts +++ b/lib/eden.ts @@ -1,5 +1,5 @@ import { treaty } from "@elysia/eden" -import type { App } from "@/app/api/[[...slugs]]/route" +import type { App } from "@/lib/api/app" // Use require() on the server branch to prevent the client bundler from // pulling in Elysia and the route module. The typeof window check is the @@ -7,5 +7,5 @@ import type { App } from "@/app/api/[[...slugs]]/route" export const api = typeof window === "undefined" ? // eslint-disable-next-line @typescript-eslint/no-require-imports - treaty((require("../app/api/[[...slugs]]/route") as { app: App }).app).api + treaty((require("@/lib/api/app") as { app: App }).app).api : treaty(process.env.NEXT_PUBLIC_SITE_URL || "http://localhost:3000").api