auth-yes/scripts/lint_arch.ts

56 lines
1.4 KiB
TypeScript

import { walk } from "jsr:@std/fs";
const targetDir = "./src";
let hasErrors = false;
async function checkFile(path: string) {
const content = await Deno.readTextFile(path);
const lines = content.split("\n");
lines.forEach((line, index) => {
// 1. Block banned DOM APIs
if (
line.includes("document.getElementById") ||
line.includes("document.querySelector") ||
line.includes("document.createElement")
) {
console.error(
`[Arch Lint] ❌ Banned DOM API used in ${path}:${index + 1}`,
);
console.error(` ${line.trim()}`);
console.error(
` -> Use Datastar reactive attributes or SSE morphs instead.`,
);
hasErrors = true;
}
// 2. Block unescaped HTML in raw strings (basic heuristic for dangerouslySetInnerHTML)
if (
line.includes("dangerouslySetInnerHTML") &&
!path.includes("error_fragments.tsx")
) {
console.error(
`[Arch Lint] ❌ dangerouslySetInnerHTML used in ${path}:${index + 1}`,
);
console.error(` ${line.trim()}`);
console.error(
` -> Native JSX HTML escaping should be used unless in explicit core fragments.`,
);
hasErrors = true;
}
});
}
for await (const entry of walk(targetDir, { exts: [".ts", ".tsx"] })) {
if (entry.isFile) {
await checkFile(entry.path);
}
}
if (hasErrors) {
Deno.exit(1);
} else {
console.log("✅ Architecture lint passed.");
}