import appConfig from "./app.config.ts"; import { createPocketBaseClient } from "./pocketbase/client.ts"; const port = Number(Deno.env.get("PORT") || "8080"); const pocketbaseUrl = mustGetEnv("POCKETBASE_URL"); const pocketbaseEmail = mustGetEnv("POCKETBASE_SERVICE_EMAIL"); const pocketbasePassword = mustGetEnv("POCKETBASE_SERVICE_PASSWORD"); const ownerTeamId = mustGetEnv("APP_OWNER_TEAM_ID"); const appSlug = Deno.env.get("APP_SLUG") || appConfig.slug; const pocketbase = createPocketBaseClient({ baseUrl: pocketbaseUrl, email: pocketbaseEmail, password: pocketbasePassword, }); type DashboardCard = { id: string; title: string; metric: string; description: string | null; }; function renderHtml(cards: DashboardCard[]) { const cardsMarkup = cards.length === 0 ? `

No dashboard cards yet.

` : cards.map((card) => `

${escapeHtml(card.title)}

${escapeHtml(card.metric)} ${escapeHtml(card.description || "No description")}
`).join(""); return ` ${escapeHtml(appConfig.name)}

PocketBase + Deno

${escapeHtml(appConfig.name)}

App slug: ${escapeHtml(appSlug)} • Team: ${escapeHtml(ownerTeamId)}

${cardsMarkup}
`; } function mustGetEnv(name: string) { const value = Deno.env.get(name); if (!value) { throw new Error(`Missing required env: ${name}`); } return value; } function escapeHtml(value: string) { return value .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """) .replaceAll("'", "'"); } async function handleRequest() { const cards = await pocketbase.listRecords({ collectionName: `${appConfig.pocketbase.collectionPrefix}_cards`, filter: `teamId = "${ownerTeamId}"`, }); return new Response(renderHtml(cards), { headers: { "content-type": "text/html; charset=utf-8", }, }); } Deno.serve({ port }, () => handleRequest());