import { globSync, readFileSync } from "node:fs"; import { matchesGlob, relative, resolve, sep } from "node:path"; // The source text a contract test scans, read from disk. Not `import.meta.glob(…, { query: "?raw" })`: // knip reads every such glob as an import of each file it matches, and two tests globbed all of src — // so its unused-files lane counted every source file as used and could never name an orphaned one // (the shared-link entry was "used" only by those globs). /** Every file matching `patterns` (relative to `dir`, the calling test's directory; a leading "!" * excludes) with its text, keyed the way `import.meta.glob` keyed it: "./x.tsx", "../lib/y.ts". */ export function readSources(dir: string, patterns: string | string[]): Record { const list = typeof patterns === "string" ? [patterns] : patterns; const include = list.filter((p) => !p.startsWith("!")); const exclude = list.filter((p) => p.startsWith("!")).map((p) => key(p.slice(1))); const out: Record = {}; for (const pattern of include) { for (const rel of globSync(pattern, { cwd: dir })) { // Canonical, as Vite's: "../ui/Modal.tsx" from inside ui/ is "./Modal.tsx", matched once. const k = key(relative(dir, resolve(dir, rel))); // An exclusion names the file either way: "!../**/*.test.*" as the pattern spelled it // ("../lib/x.test.ts"), "!./**" by its canonical key ("./x.test.ts" from inside lib/). if (exclude.some((x) => matchesGlob(key(rel), x) || matchesGlob(k, x))) continue; out[k] = readFileSync(resolve(dir, rel), "utf8"); } } return out; } /** A path relative to the test's directory, as `import.meta.glob` spells it. */ function key(path: string): string { const posix = path.split(sep).join("/"); return posix.startsWith(".") ? posix : `./${posix}`; }