nestjs-doctorGitHub

Diagnostic Filtering

Source: src/engine/filter-diagnostics.ts

What

Removes diagnostics that match the user's ignore configuration after all rules have run.

Why

Users may want to suppress known issues or exclude generated files from results without disabling the rule entirely. For example, you might want no-orm-in-services to run everywhere except in your legacy module.

Input

diagnostics: Diagnostic[]          // all diagnostics from rule execution
config: NestjsDoctorConfig         // contains ignore.rules and ignore.files
targetPath: string                 // root directory (used to convert absolute paths to relative for glob matching)

Output

Diagnostic[]    // filtered array (subset of input)

How It Works

Two filtering mechanisms:

Rule Ignoring

ignore.rules contains rule IDs to suppress:

{
  "ignore": {
    "rules": ["architecture/no-orm-in-services"]
  }
}

Exact match against the diagnostic's rule field. All diagnostics from that rule are removed.

File Ignoring

ignore.files contains glob patterns for files whose diagnostics should be hidden:

{
  "ignore": {
    "files": ["src/generated/**", "src/legacy/**"]
  }
}

File paths are normalized to forward slashes before matching, so patterns work across platforms.

Inline Suppression

Source: src/engine/inline-suppressions.ts

After config-based filtering, a second pass (filterSuppressedDiagnostics) removes diagnostics silenced by comments in the source itself. Directives use the ignore verb (or disable as an alias) inside a // or /* */ comment:

const config = eval(raw); // nestjs-doctor-ignore security/no-eval

// nestjs-doctor-ignore-next-line security/no-eval
const config = eval(raw);

// nestjs-doctor-ignore-file security/no-eval
DirectiveScope
nestjs-doctor-ignore[-line] <rules>The comment's own line
nestjs-doctor-ignore-next-line <rules>The line below the comment
nestjs-doctor-ignore-file <rules>Every line in the file

The rule list is space- or comma-separated; omitting it suppresses every rule for that scope. Because every rule id has the form category/name, only tokens containing / are treated as rules — so a -- reason trailer is ignored wherever it sits (its words carry no slash). A directive is only honoured inside a real comment: TypeScript source has its string/template/regex-literal contents blanked (via the AST) before parsing, so a directive that merely appears inside a string cannot suppress a real finding.

TypeScript source text is resolved from the in-memory AST project (no extra disk reads); Prisma .prisma schema files are not in that project, so they are read from disk on demand. Each file is parsed at most once per pass. Because line-scoped directives key off the diagnostic's line, they apply only to code diagnostics — schema diagnostics (which have no line) are suppressed only by nestjs-doctor-ignore-file, including a directive placed anywhere in a schema.prisma file.

Performance

If no ignore config is set (the default), the filter returns the original array immediately without iterating. The inline-suppression pass skips any file whose source contains no nestjs-doctor-ignore/-disable token.

Difference from rules Config

  • config.rules disables a rule entirely — it never runs
  • config.ignore.rules lets the rule run but hides its output

This distinction matters for project-scoped rules that cross-reference data. For example, no-missing-injectable checks providers against the module graph. Disabling it with config.rules means the rule will not run at all. Ignoring it with config.ignore.rules means the rule runs (maintaining data consistency) but its diagnostics are hidden.

Debugging Tips

  • If diagnostics are disappearing unexpectedly, check ignore.rules and ignore.files in your config.
  • File patterns use glob syntax via picomatch. Double-star ** matches any depth.