import { access, mkdir, readFile, writeFile } from "node:fs/promises"; import path from "node:path"; import { pathToFileURL } from "node:url"; const governance = JSON.parse( await readFile("config/contracts/registry-governance.json", "utf8"), ); const failures = []; const owners = new Map(); const snapshots = []; for (const specification of governance.registries) { if (owners.has(specification.registryId)) { failures.push(`duplicate owner for ${specification.registryId}`); } owners.set(specification.registryId, specification.owner); let rows = specification.declaredRows; try { await access(specification.path); const module = await import( `${pathToFileURL(path.resolve(specification.path)).href}?registry-check=${Date.now()}` ); rows = module[specification.exportName]; } catch { if (!rows) failures.push(`missing registry source ${specification.path}`); } if (!rows || typeof rows !== "object" || Array.isArray(rows)) { failures.push(`${specification.registryId} is not an object registry`); continue; } for (const [rowName, row] of Object.entries(rows)) { if (!row || typeof row !== "object" || Array.isArray(row)) { failures.push(`${specification.registryId}.${rowName} is not an object`); continue; } for (const field of specification.requiredFields) { if (!(field in row)) { failures.push(`${specification.registryId}.${rowName} missing ${field}`); } } } snapshots.push({ registryId: specification.registryId, owner: specification.owner, source: specification.path, rowCount: Object.keys(rows).length, rows, }); } const sourceFiles = [ "src/application", "src/presentation", "src/domain", ]; const adHocPatterns = [ { name: "direct fetch", expression: /\bfetch\s*\(/ }, { name: "direct localStorage", expression: /\blocalStorage\.(?:get|set|remove)Item/ }, { name: "direct import.meta.env", expression: /\bimport\.meta\.env\./ }, { name: "raw API path", expression: /["']\/api\// }, ]; /** @param {string} directory */ async function scanDirectory(directory) { const entries = await import("node:fs/promises").then(({ readdir }) => readdir(directory, { withFileTypes: true }), ); for (const entry of entries) { const target = path.join(directory, entry.name); if (entry.isDirectory()) { await scanDirectory(target); continue; } if (!/\.(js|jsx|mjs)$/.test(entry.name)) continue; const content = await readFile(target, "utf8"); for (const pattern of adHocPatterns) { if (pattern.expression.test(content)) { failures.push(`ad-hoc ${pattern.name} in ${target}`); } } } } for (const sourceDirectory of sourceFiles) { await scanDirectory(sourceDirectory); } await mkdir("artifacts/quality", { recursive: true }); await writeFile( "artifacts/quality/registries.json", `${JSON.stringify( { schemaVersion: 1, generatedAt: new Date().toISOString(), compatibilityImpact: governance.compatibilityImpact.current, failures, registries: snapshots, }, null, 2, )}\n`, ); if (failures.length > 0) { process.stderr.write(`Registry governance failed:\n${failures.join("\n")}\n`); process.exit(1); } process.stdout.write(`Registry governance: ${snapshots.length} registries PASS\n`);