import { readFileSync } from "node:fs"; import { join } from "node:path"; import { uiComponentsDir } from "./registry.ts"; export interface UiComponentMetadata { name: string; mount: string; category?: string; purpose?: string; props?: Array<{ name: string; default?: unknown }>; events?: string[]; } export interface UiComponentReference { count: number; components: UiComponentMetadata[]; } let referenceCache: UiComponentReference | undefined; export function uiComponentReference(): UiComponentReference { if (!referenceCache) referenceCache = JSON.parse( readFileSync(join(uiComponentsDir(), "..", "component-reference.json"), "utf8"), ) as UiComponentReference; return structuredClone(referenceCache); } export function findUiComponent(name: string): UiComponentMetadata | undefined { return uiComponentReference().components.find( (component) => component.name === name || component.mount === name, ); } export function auditUiComponents(): Array<{ component: string; issue: string }> { const issues: Array<{ component: string; issue: string }> = []; for (const component of uiComponentReference().components) { const props = new Set((component.props ?? []).map((prop) => prop.name)); if (!props.has("class")) issues.push({ component: component.name, issue: "missing class prop" }); if (!props.has("size")) issues.push({ component: component.name, issue: "missing size prop" }); if (!props.has("color")) issues.push({ component: component.name, issue: "missing color prop" }); } return issues; }