Custom rule configuration
How a project wires custom rules into the scan: where the files live, how they load, and the surfaces their findings appear on. Writing the rules themselves is covered on Custom rules.
Setup
Point customRulesDir at a directory of rule files in nestjs-doctor.config.json:
{
"customRulesDir": "./rules"
}The path resolves against the scanned directory. Rule files export rule objects, one or several per file; other extensions and subdirectories are ignored. Rules load through jiti at scan time, so CI needs no build step, no ts-node, and no tsconfig for them.
Loading and ids
Rule ids are prefixed with custom/, so id: "no-todo-comments" reports as custom/no-todo-comments and can never collide with a built-in rule. A custom rule is toggled by that prefixed id through the same rules and ignore.rules keys built-in rules use, described on Configuration.
An invalid rule produces a warning and never crashes the scan. The warnings appear in CLI output, and the usual causes are:
- Missing or non-function
checkexport - Invalid
categoryorseverityvalues - Missing required
metafields - Syntax errors in the rule file
Fix the warning and re-run. The rest of the scan continues unaffected.
Surfaces
A rule appears on four surfaces by default:
| Surface | Where |
|---|---|
cli | The console report, the HTML report, and a shared report |
prComment | The pull request summary, its inline review comments, the GitHub annotations, --format sarif and --format gitlab |
score | The 0-100 number |
ciFailure | --blocking |
--format json is the exception: it carries every finding, with surfaces on
each one, so a consumer filters however it wants.
Naming a subset in the rule's meta narrows it:
surfaces: ["cli"],That rule still shows every finding and still says how to fix it. It never comments on a pull request, never moves the score, and never fails a build. Use it for a rule that encodes a preference rather than a defect, so a project that disagrees is not punished for it.
A project can decide otherwise. surfaces on a rule override replaces what the
rule declares:
{
"rules": {
"correctness/prefer-readonly-injection": {
"surfaces": ["cli", "prComment", "score", "ciFailure"]
}
}
}That is how a team that does want a house style enforced puts it back on the score and the build.