import "./env.js"; import express from "express"; import path from "path"; import { fileURLToPath } from "url"; import cors from "cors"; import zoosRouter from "./routes/zoos.js"; import salesRouter from "./routes/sales.js"; import { createAccount } from "./db.js"; import { startBotTickInterval } from "./bot-tick.js"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const webDir = path.join(__dirname, "..", "web"); const app = express(); app.use(cors({ origin: true, credentials: true })); app.use( "/api/zoos", express.raw({ type: "*/*", limit: "2mb" }), (req, res, next) => { req.bodyRaw = req.body && Buffer.isBuffer(req.body) ? req.body.toString("utf8") : ""; try { req.body = req.bodyRaw ? JSON.parse(req.bodyRaw) : {}; } catch { req.body = {}; } next(); }, zoosRouter ); app.use( "/api/sales", express.raw({ type: "*/*", limit: "2mb" }), (req, res, next) => { req.bodyRaw = req.body && Buffer.isBuffer(req.body) ? req.body.toString("utf8") : ""; try { req.body = req.bodyRaw ? JSON.parse(req.bodyRaw) : {}; } catch { req.body = {}; } next(); }, salesRouter ); app.use( "/api/auth", express.raw({ type: "*/*", limit: "10kb" }), (req, res, next) => { req.bodyRaw = req.body && Buffer.isBuffer(req.body) ? req.body.toString("utf8") : ""; try { req.body = req.bodyRaw ? JSON.parse(req.bodyRaw) : {}; } catch { req.body = {}; } next(); } ); app.post("/api/auth/register", (req, res, next) => { const publicKey = req.headers["x-public-key"]; const pseudo = req.body?.pseudo?.trim(); if (!publicKey || !pseudo || pseudo.length < 2) { res.status(400).json({ error: "pseudo required (min 2 chars) and X-Public-Key", }); return; } createAccount(publicKey, pseudo) .then((account) => { res.status(201).json({ id: account.id, pseudo: account.pseudo }); }) .catch((err) => { console.error("[auth/register]", err?.message ?? err); if (err.code === "23505") { res.status(409).json({ error: "pseudo or publicKey already used" }); return; } next(err); }); }); app.get("/api/health", (req, res) => { res.json({ ok: true }); }); app.use(express.static(webDir)); app.get("*", (req, res) => { res.sendFile(path.join(webDir, "index.html")); }); app.use((err, _req, res, _next) => { console.error("[api]", err?.message ?? err); res.status(500).json({ error: "Internal server error" }); }); const port = Number(process.env.PORT) || 3000; app.listen(port, () => { console.warn(`builazoo API listening on port ${port}`); startBotTickInterval(); });