All checks were successful
Deploy MineGeo to Dokploy / deploy (push) Successful in 7m10s
53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
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<unknown>;
|
|
limit: (key: string, count: number, seconds: number) => Promise<void>;
|
|
};
|
|
|
|
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,
|
|
}),
|
|
),
|
|
});
|
|
}
|