56 lines
1.4 KiB
TypeScript
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.");
|
|
}
|