#!/usr/bin/env node /* * HealthChat theme sync. * * Single source of truth for the "HealthChat Light" theme lives in * apps/web/element.io/healthchat/HealthChat-Light-Theme.json * This script injects it into every element-web config that ships the theme, so the palette * is authored once and never drifts between the dev and desktop configs. * * The production web deployment (matrix-docker-ansible-deploy) renders its config.json from * host_vars and carries an inline copy of this theme; re-copy this file there when it changes. * * Usage: * node apps/web/scripts/healthchat-sync-theme.mjs # write the theme into all configs * node apps/web/scripts/healthchat-sync-theme.mjs --check # exit 1 if any config is out of sync * * Run `pnpm --filter element-web healthchat:theme` after editing the canonical theme; * the --check variant runs in lint/CI to catch an un-synced edit. */ import { readFileSync, writeFileSync } from "node:fs"; import { fileURLToPath } from "node:url"; import { dirname, resolve } from "node:path"; import prettier from "prettier"; const scriptDir = dirname(fileURLToPath(import.meta.url)); const repoRoot = resolve(scriptDir, "../../.."); const CANONICAL = resolve(repoRoot, "apps/web/element.io/healthchat/HealthChat-Light-Theme.json"); // Configs that must carry the theme in setting_defaults.custom_themes. const TARGETS = [ "apps/web/config.json", // dev server config (also served by the web Docker image) "apps/desktop/element.io/healthchat/config.json", // desktop variant config bundled into the app ]; const check = process.argv.includes("--check"); const theme = JSON.parse(readFileSync(CANONICAL, "utf8")); let changed = 0; for (const rel of TARGETS) { const path = resolve(repoRoot, rel); const raw = readFileSync(path, "utf8"); const config = JSON.parse(raw); config.setting_defaults ??= {}; config.setting_defaults.custom_themes = [theme]; // Format identically to `prettier --write` so the output is byte-for-byte what the // repo's formatting lint expects, keeping --check stable. const options = await prettier.resolveConfig(path); const next = await prettier.format(JSON.stringify(config), { ...options, filepath: path }); if (next === raw) { continue; } changed++; if (check) { console.error(`out of sync: ${rel} (run: pnpm --filter element-web healthchat:theme)`); } else { writeFileSync(path, next); console.log(`synced theme -> ${rel}`); } } if (check) { if (changed > 0) process.exit(1); console.log("all configs in sync with the canonical HealthChat theme"); } else if (changed === 0) { console.log("all configs already in sync"); }