Add cloud state sync

This commit is contained in:
Theodore Song
2026-07-05 22:30:26 -04:00
parent f98ec33f04
commit 7168779bcb
5 changed files with 442 additions and 9 deletions
+44
View File
@@ -0,0 +1,44 @@
import { get, put } from "@vercel/blob";
const STATE_PATH = process.env.PMA_STATE_PATH || "shared/state.json";
async function readJsonBlob() {
const blob = await get(STATE_PATH, { access: "private" });
if (!blob || blob.statusCode !== 200 || !blob.stream) return null;
const text = await new Response(blob.stream).text();
return text ? JSON.parse(text) : null;
}
export default async function handler(req, res) {
res.setHeader("Cache-Control", "no-store");
try {
if (!process.env.BLOB_READ_WRITE_TOKEN && !process.env.VERCEL_OIDC_TOKEN) {
return res.status(503).json({ ok: false, error: "Cloud state is not configured" });
}
if (req.method === "GET") {
return res.status(200).json({ ok: true, state: await readJsonBlob() });
}
if (req.method === "POST") {
const body = typeof req.body === "string" ? JSON.parse(req.body || "{}") : (req.body || {});
if (!body || typeof body !== "object" || !body.items || typeof body.items !== "object") {
return res.status(400).json({ ok: false, error: "Invalid state payload" });
}
const state = { version: 1, updated_at: new Date().toISOString(), items: body.items };
await put(STATE_PATH, JSON.stringify(state), {
access: "private",
allowOverwrite: true,
contentType: "application/json",
cacheControlMaxAge: 60,
});
return res.status(200).json({ ok: true, state });
}
res.setHeader("Allow", "GET, POST");
return res.status(405).json({ ok: false, error: "Method not allowed" });
} catch (err) {
const message = err && err.message ? err.message : "State sync failed";
return res.status(500).json({ ok: false, error: message });
}
}