70 lines
2.0 KiB
TypeScript
70 lines
2.0 KiB
TypeScript
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
|
|
const DISALLOWED_PATTERNS = [
|
|
"node:fs",
|
|
"node:path",
|
|
"node:url",
|
|
"process.env",
|
|
"Buffer",
|
|
"document.",
|
|
"window.",
|
|
];
|
|
|
|
// Allow ReadableStream (Web Streams API — explicitly permitted)
|
|
|
|
function walkDir(dir: string, results: string[] = []): string[] {
|
|
for (const entry of readdirSync(dir)) {
|
|
const full = join(dir, entry);
|
|
if (statSync(full).isDirectory()) {
|
|
if (
|
|
entry !== "__benchmarks__" &&
|
|
entry !== "node_modules" &&
|
|
entry !== "dist"
|
|
) {
|
|
walkDir(full, results);
|
|
}
|
|
} else if (
|
|
full.endsWith(".ts") &&
|
|
!full.endsWith(".test.ts") &&
|
|
!full.endsWith(".bench.ts") &&
|
|
!full.endsWith(".types.ts")
|
|
) {
|
|
results.push(full);
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
describe("no-disallowed: source files must not use banned APIs", () => {
|
|
it("source files do not use node:fs, node:path, node:url, process.env, Buffer, document, window", {
|
|
timeout: 10000,
|
|
}, () => {
|
|
const srcDir = join(import.meta.dirname, "..", "src");
|
|
const files = walkDir(srcDir);
|
|
|
|
const violations: string[] = [];
|
|
|
|
for (const file of files) {
|
|
const content = readFileSync(file, "utf-8");
|
|
const relativePath = file.split("/src/")[1] ?? file;
|
|
|
|
for (const pattern of DISALLOWED_PATTERNS) {
|
|
if (content.includes(pattern)) {
|
|
violations.push(`${relativePath}: contains "${pattern}"`);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (violations.length > 0) {
|
|
throw new Error(
|
|
`Disallowed patterns found in source:\n${violations.join("\n")}`
|
|
);
|
|
}
|
|
|
|
// At least checked one file
|
|
expect(files.length).toBeGreaterThan(0);
|
|
});
|
|
});
|