import "server-only"; import { NextRequest, NextResponse } from "next/server"; import { profileCosmeticActionSchema } from "@/shared/profile-cosmetics"; import { admin, required, user } from "./supabase"; import { browserAccount } from "./request-security"; import { profileCosmeticsState } from "./profile-cosmetics"; type Context = { jsonBody: (request: NextRequest) => Promise; limit: (key: string, count: number, seconds: number) => Promise; }; const json = (body: unknown, status = 200) => NextResponse.json(body, { status, headers: { "Cache-Control": "no-store" } }); export async function cosmeticsApi( request: NextRequest, path: string[], context: Context, ) { if (path.length !== 1) return json({ error: "Not found" }, 404); const account = await browserAccount(request, user); if (request.method === "GET") return json({ shop: await profileCosmeticsState(account.id) }); if (request.method !== "POST") return json({ error: "Method not allowed" }, 405); const body = profileCosmeticActionSchema.parse( await context.jsonBody(request), ); if (body.action === "purchase") { await context.limit("cosmetic-purchase:" + account.id, 8, 60); return json({ shop: required( await admin().rpc("buy_profile_cosmetic", { p_user: account.id, p_cosmetic_id: body.cosmeticId, }), ), }); } await context.limit("cosmetic-equip:" + account.id, 30, 60); return json({ shop: required( await admin().rpc("equip_profile_cosmetic", { p_user: account.id, p_cosmetic_id: body.cosmeticId, }), ), }); }