feat(cli): Complete the check rule catalog
Add D002 (malformed attribute blocks), R004 (skipped declare rows), and V001-V005 (CSV data files). CSV checks run once per referenced file and also cover inline spark-table bodies. Generate docs/reference.md from the known.ts catalog via npm run gen:reference, and add drift guards asserting the catalog matches the customElement call sites and the committed reference.
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Drift guard: `KNOWN_ELEMENTS` in `known.ts` must match the `customElement`
|
||||
* registrations under `src/components`. This is what would have caught
|
||||
* `:md-card` — matched by the completion scanner but registered nowhere.
|
||||
*/
|
||||
|
||||
import { readdirSync, readFileSync } from "fs";
|
||||
import { join } from "path";
|
||||
import { ELEMENT_NAMES } from "./known.js";
|
||||
import { renderReference } from "./reference.js";
|
||||
|
||||
const COMPONENTS_DIR = join(process.cwd(), "src", "components");
|
||||
const CUSTOM_ELEMENT_RE = /customElement(?:<[^>]*>)?\(\s*["'](md-[\w-]+)["']/g;
|
||||
|
||||
function sourceFiles(dir: string): string[] {
|
||||
const files: string[] = [];
|
||||
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
||||
const full = join(dir, entry.name);
|
||||
if (entry.isDirectory()) files.push(...sourceFiles(full));
|
||||
else if (/\.tsx?$/.test(entry.name)) files.push(full);
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
function registeredElements(): Set<string> {
|
||||
const names = new Set<string>();
|
||||
for (const file of sourceFiles(COMPONENTS_DIR)) {
|
||||
const source = readFileSync(file, "utf-8");
|
||||
for (const match of source.matchAll(CUSTOM_ELEMENT_RE)) {
|
||||
names.add(match[1]);
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
describe("known element catalog", () => {
|
||||
test("matches the customElement registrations under src/components", () => {
|
||||
const registered = [...registeredElements()].sort();
|
||||
const known = [...ELEMENT_NAMES].sort();
|
||||
|
||||
expect(known).toEqual(registered);
|
||||
});
|
||||
|
||||
test("docs/reference.md is up to date", () => {
|
||||
const committed = readFileSync(
|
||||
join(process.cwd(), "docs", "reference.md"),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
expect(committed).toBe(renderReference());
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user