import { readdir, readFile, mkdir, writeFile, stat } from "node:fs/promises"; import { fileURLToPath } from "node:url"; import path from "node:path"; import * as esbuild from "esbuild"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const ROOT = path.resolve(__dirname, ".."); const PRESENCES_DIR = path.join(ROOT, "presences"); const SDK_RUNTIME = path.join(ROOT, "scripts", "sdk-runtime.mjs"); async function listPresences() { const entries = await readdir(PRESENCES_DIR, { withFileTypes: true }); return entries.filter((e) => e.isDirectory()).map((e) => e.name); } async function readMetadata(presenceDir) { const metaPath = path.join(presenceDir, "metadata.json"); const json = JSON.parse(await readFile(metaPath, "utf8")); return json; } async function findEntry(presenceDir) { const candidates = ["src/presence.ts", "src/index.ts", "presence.ts", "index.ts"]; for (const candidate of candidates) { const full = path.join(presenceDir, candidate); try { await stat(full); return full; } catch { // try next } } throw new Error(`No entry script found in ${presenceDir} (tried ${candidates.join(", ")})`); } async function buildPresence(slug) { const presenceDir = path.join(PRESENCES_DIR, slug); const meta = await readMetadata(presenceDir); if (meta.id !== slug) { throw new Error(`metadata.id "${meta.id}" does not match folder name "${slug}"`); } const entry = await findEntry(presenceDir); const distDir = path.join(presenceDir, "dist"); await mkdir(distDir, { recursive: true }); await esbuild.build({ entryPoints: [entry], outfile: path.join(distDir, "presence.js"), bundle: true, platform: "browser", format: "cjs", target: ["chrome120", "firefox115"], minify: true, legalComments: "none", alias: { "@source/presence-sdk": SDK_RUNTIME, }, }); console.log(`✓ ${slug} v${meta.version}`); } async function main() { const list = await listPresences(); if (list.length === 0) { console.log("No presences found."); return; } for (const slug of list) { await buildPresence(slug); } } await main();