#!/usr/bin/env node /** * Mirror /design-system/ → /public/design-system/ AND /src/styles/design-system/ * * The canonical tokens live at the project root in design-system/. They need * to land in two places before the build runs: * * • public/design-system/ — served as static assets so partner sites can * ``. * * • src/styles/design-system/ — Starlight's `customCss` only accepts paths * under src/, so the site itself imports the tokens from here. * * Both are copies of the same source. Rather than hand-maintain three trees, * this script syncs them on every install / build. */ import { mkdir, readdir, copyFile, stat, rm } from 'node:fs/promises'; import { dirname, join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const SRC = resolve(__dirname, '..', 'design-system'); const DSTS = [ resolve(__dirname, '..', 'public', 'design-system'), resolve(__dirname, '..', 'src', 'styles', 'design-system'), ]; // Files we publish. Anything else (zips, internal notes) stays out of public/. const PUBLISHED = new Set([ 'README.md', 'tokens.css', 'tokens.scss', 'tokens.json', 'tailwind.preset.js', 'docs-page-mockup.html', ]); async function ensure(dir) { await mkdir(dir, { recursive: true }); } async function copyTree(src, dst) { await ensure(dst); const entries = await readdir(src, { withFileTypes: true }); for (const entry of entries) { if (!PUBLISHED.has(entry.name)) continue; const from = join(src, entry.name); const to = join(dst, entry.name); if (entry.isDirectory()) { await copyTree(from, to); } else { await copyFile(from, to); } } } async function pruneStale(dst) { try { const entries = await readdir(dst, { withFileTypes: true }); for (const entry of entries) { if (!PUBLISHED.has(entry.name)) { await rm(join(dst, entry.name), { recursive: true, force: true }); } } } catch (err) { if (err.code !== 'ENOENT') throw err; } } try { await stat(SRC); } catch { console.error(`[sync-design-system] no source directory at ${SRC}`); process.exit(1); } for (const dst of DSTS) { await pruneStale(dst); await copyTree(SRC, dst); console.log(`[sync-design-system] mirrored ${SRC} → ${dst}`); }