tools/rules/literal.rule.ts
tools/rules/literal.rule.ts is a file in Coordination Surface. 65 lines of code and 14 definitions.
import type { RuleContext, RuleDeclaration, RuleResult } from "../core/types/rule.types.ts";
import { callBefore, isPathShaped, quotedLiterals, unboundedEnumerations } from "../core/analyzers/literal.analyzer.ts";
import { enumerationFinding, rawPathFinding } from "../core/factories/literal.factory.ts";
import { AUTHORED_ROOTS } from "../core/constants/path.constants.ts";
import type { Finding } from "../core/types/segment.types.ts";
import { underRoots } from "../core/filters/scope.filter.ts";
const COMPOSERS: ReadonlySet<string> = new Set(["within", "withinSurface", "surfacePath", "slotText", "inSurface"]);
const FILESYSTEM_CALLS: ReadonlySet<string> = new Set([
"join",
"resolve",
"existsSync",
"readFileSync",
"readdirSync",
"writeFileSync",
"statSync",
"mkdirSync",
"rmdirSync",
"renameSync",
"walk",
"readSource",
]);
interface LiteralScan {
readonly findings: Finding[];
readonly literals: number;
}
const scanLiterals = function scanLiterals(path: string, source: string): LiteralScan {
const shaped = quotedLiterals(source).filter((literal) => isPathShaped(literal.value));
const findings = shaped.flatMap((literal) => {
const composer = callBefore(source, literal.open);
const raw = FILESYSTEM_CALLS.has(composer) && !COMPOSERS.has(composer);
return raw ? [rawPathFinding(path, source, literal, composer)] : [];
});
return { findings, literals: shaped.length };
};
export const rule: RuleDeclaration = {
check(context: RuleContext): RuleResult {
const findings: Finding[] = [];
const scoped = underRoots(context.paths, AUTHORED_ROOTS);
let literals = 0;
for (const path of scoped) {
const source = context.read(path);
const scan = scanLiterals(path, source);
literals += scan.literals;
findings.push(
...unboundedEnumerations(source).map((found) => enumerationFinding(path, found)),
...scan.findings,
);
}
return {
derivations: {
literals,
reached: scoped,
skippedAsOutsideAuthoredRoots: context.paths.filter((path) => !scoped.includes(path)),
},
findings,
healed: [],
};
},
extensions: [".ts"],
heals: false,
invariant: "a path-shaped string literal in authored source is composed through the parameter surface",
jurisdiction: "all",
kinds: ["rawPath", "unboundedEnumeration"],
stage: "structure",
};