44 lines
1.7 KiB
TypeScript
44 lines
1.7 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import type { ScaffoldRecipe } from "./scaffold-recipes.js";
|
|
import type { StructuralRequest } from "./structural-plan.js";
|
|
export async function scaffoldController(
|
|
root: string,
|
|
prefix: string,
|
|
spec: ScaffoldRecipe,
|
|
): Promise<StructuralRequest> {
|
|
const entry = { id: spec.id, ...spec.controller };
|
|
const fields = ["id", "subject", "snapshot", "remote", "input"];
|
|
if (
|
|
Object.keys(entry).some((key) => ![...fields, "registry"].includes(key)) ||
|
|
(entry.registry !== undefined && typeof entry.registry !== "string") ||
|
|
fields.some((key) => typeof (entry as Record<string, unknown>)[key] !== "string") ||
|
|
!["unit", "value"].includes(entry.input ?? "")
|
|
)
|
|
throw Error("Controller requires id, subject, snapshot, remote and input (unit/value)");
|
|
const file = prefix + "quixos.controllers.json";
|
|
let before: string | undefined;
|
|
try {
|
|
before = await fs.readFile(path.join(root, file), "utf8");
|
|
} catch (error) {
|
|
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
|
|
}
|
|
const catalog = before ? JSON.parse(before) : { schemaVersion: 1, controllers: [] };
|
|
if (
|
|
catalog.schemaVersion !== 1 ||
|
|
!Array.isArray(catalog.controllers) ||
|
|
catalog.controllers.length >= 1000 ||
|
|
catalog.controllers.some((c: { id: string }) => c.id === entry.id)
|
|
)
|
|
throw Error("Invalid catalog or duplicate controller ID");
|
|
catalog.controllers.push(entry);
|
|
const content = JSON.stringify(catalog, null, 2) + "\n";
|
|
return {
|
|
kind: "package",
|
|
source: spec.source,
|
|
resourceRoot: spec.directory,
|
|
validation: "syntax",
|
|
files: [before === undefined ? { file, create: content } : { file, expected: before, replace: content }],
|
|
};
|
|
}
|