import type { ThemeManifest } from "./types"; // Themes are auto-discovered: each src/themes//manifest.ts default-export // is registered here. Keep this module CSS-free so server fns can import it; // theme stylesheets are aggregated separately in ./styles.ts. const modules = import.meta.glob<{ default: ThemeManifest }>("./*/manifest.ts", { eager: true, }); export const THEMES: Record = {}; for (const [path, mod] of Object.entries(modules)) { const folder = path.split("/")[1]; const manifest = mod.default; if (!manifest || manifest.id !== folder) { console.warn(`[themes] skipping ${path}: manifest id must equal folder name`); continue; } THEMES[manifest.id] = manifest; } export const DEFAULT_THEME_ID = "default"; if (!THEMES[DEFAULT_THEME_ID]) { throw new Error("[themes] default theme manifest is missing or invalid"); } export const THEME_IDS = Object.keys(THEMES); // Base order: default first, rest by id. Pickers re-sort by LOCALIZED title // at render time (labels are i18n descriptors, unresolvable here). export const THEME_LIST: ThemeManifest[] = Object.values(THEMES).sort( (a, b) => (a.order ?? 100) - (b.order ?? 100) || a.id.localeCompare(b.id) ); export const getTheme = (id?: string | null): ThemeManifest => (id ? THEMES[id] : undefined) ?? THEMES[DEFAULT_THEME_ID];