nestjs-doctor 0.4.18 → 0.4.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -169,10 +169,22 @@ Also works as a `"nestjs-doctor"` key in `package.json`.
169
169
  | `minScore` | `number` | Minimum passing score (0-100). Exits with code 1 if below threshold |
170
170
  | `ignore.rules` | `string[]` | Rule IDs to suppress |
171
171
  | `ignore.files` | `string[]` | Glob patterns for files whose diagnostics are hidden |
172
- | `rules` | `Record<string, boolean>` | Enable/disable individual rules |
172
+ | `rules` | `Record<string, RuleOverride \| boolean>` | Enable/disable individual rules, override severity, and pass rule-specific options |
173
173
  | `categories` | `Record<string, boolean>` | Enable/disable entire categories |
174
174
  | `customRulesDir` | `string` | Path to a directory containing custom rule files |
175
175
 
176
+ Example rule-specific override:
177
+
178
+ ```json
179
+ {
180
+ "rules": {
181
+ "architecture/no-manual-instantiation": {
182
+ "excludeClasses": ["Logger", "PinoLogger"]
183
+ }
184
+ }
185
+ }
186
+ ```
187
+
176
188
  ---
177
189
 
178
190
  ## Custom Rules
@@ -203,7 +215,7 @@ export const noTodoComments = {
203
215
  const pos = context.sourceFile.getLineAndColumnAtPos(match.index);
204
216
  context.report({
205
217
  message: "Unresolved TODO comment",
206
- file: context.filePath,
218
+ filePath: context.filePath,
207
219
  line: pos.line,
208
220
  });
209
221
  }
@@ -321,7 +333,7 @@ mono.combined; // Merged DiagnoseResult
321
333
 
322
334
  | Rule | Severity | What it catches |
323
335
  |------|----------|-----------------|
324
- | `no-missing-injectable` | error | Provider in module missing `@Injectable()` |
336
+ | `no-missing-injectable` | error | Provider with constructor deps missing `@Injectable()` |
325
337
  | `no-duplicate-routes` | error | Same method + path + version twice in a controller |
326
338
  | `no-missing-guard-method` | error | Guard class missing `canActivate()` |
327
339
  | `no-missing-pipe-method` | error | Pipe class missing `transform()` |
@@ -370,4 +382,3 @@ mono.combined; // Merged DiagnoseResult
370
382
  | `schema/require-primary-key` | error | Entity without a primary key column |
371
383
  | `schema/require-timestamps` | warning | Entity missing createdAt/updatedAt columns |
372
384
  | `schema/require-cascade-rule` | info | Relation missing explicit onDelete behavior |
373
-
@@ -1,64 +1,10 @@
1
1
  import { ClassDeclaration, Project, SourceFile } from "ts-morph";
2
2
 
3
- //#region src/engine/type-resolver.d.ts
4
- interface ProviderInfo {
5
- classDeclaration: ClassDeclaration;
6
- dependencies: string[];
7
- filePath: string;
8
- name: string;
9
- publicMethodCount: number;
10
- }
11
- declare function updateProvidersForFile(providers: Map<string, ProviderInfo>, project: Project, filePath: string): void;
12
- //#endregion
13
- //#region src/engine/module-graph.d.ts
14
- interface ModuleNode {
15
- classDeclaration: ClassDeclaration;
16
- controllers: string[];
17
- exports: string[];
18
- filePath: string;
19
- imports: string[];
20
- name: string;
21
- providers: string[];
22
- }
23
- interface ModuleGraph {
24
- edges: Map<string, Set<string>>;
25
- modules: Map<string, ModuleNode>;
26
- providerToModule: Map<string, ModuleNode>;
27
- }
28
- declare function updateModuleGraphForFile(graph: ModuleGraph, project: Project, filePath: string): void;
29
- //#endregion
30
- //#region src/types/diagnostic.d.ts
31
- type Severity = "error" | "warning" | "info";
32
- type Category = "security" | "performance" | "correctness" | "architecture" | "schema";
33
- interface SourceLine {
34
- line: number;
35
- text: string;
36
- }
37
- interface BaseDiagnostic {
38
- category: Category;
39
- filePath: string;
40
- help: string;
41
- message: string;
42
- rule: string;
43
- scope?: RuleScope;
44
- severity: Severity;
45
- }
46
- interface CodeDiagnostic extends BaseDiagnostic {
47
- column: number;
48
- line: number;
49
- sourceLines?: SourceLine[];
50
- }
51
- interface SchemaDiagnostic extends BaseDiagnostic {
52
- entity: string;
53
- schemaColumn?: string;
54
- }
55
- type Diagnostic = CodeDiagnostic | SchemaDiagnostic;
56
- declare function isCodeDiagnostic(d: Diagnostic): d is CodeDiagnostic;
57
- declare function isSchemaDiagnostic(d: Diagnostic): d is SchemaDiagnostic;
58
- //#endregion
59
- //#region src/types/config.d.ts
3
+ //#region src/common/config.d.ts
60
4
  interface RuleOverride {
61
5
  enabled?: boolean;
6
+ excludeClasses?: string[];
7
+ options?: Record<string, unknown>;
62
8
  severity?: Severity;
63
9
  }
64
10
  interface NestjsDoctorIgnoreConfig {
@@ -75,7 +21,7 @@ interface NestjsDoctorConfig {
75
21
  rules?: Record<string, RuleOverride | boolean>;
76
22
  }
77
23
  //#endregion
78
- //#region src/types/schema.d.ts
24
+ //#region src/common/schema.d.ts
79
25
  interface SchemaColumn {
80
26
  defaultValue?: string;
81
27
  hasIndex?: boolean;
@@ -135,7 +81,34 @@ interface SerializedSchemaEntity {
135
81
  tableName: string;
136
82
  }
137
83
  //#endregion
138
- //#region src/rules/types.d.ts
84
+ //#region src/engine/graph/type-resolver.d.ts
85
+ interface ProviderInfo {
86
+ classDeclaration: ClassDeclaration;
87
+ dependencies: string[];
88
+ filePath: string;
89
+ name: string;
90
+ publicMethodCount: number;
91
+ }
92
+ declare function updateProvidersForFile(providers: Map<string, ProviderInfo>, project: Project, filePath: string): void;
93
+ //#endregion
94
+ //#region src/engine/graph/module-graph.d.ts
95
+ interface ModuleNode {
96
+ classDeclaration: ClassDeclaration;
97
+ controllers: string[];
98
+ exports: string[];
99
+ filePath: string;
100
+ imports: string[];
101
+ name: string;
102
+ providers: string[];
103
+ }
104
+ interface ModuleGraph {
105
+ edges: Map<string, Set<string>>;
106
+ modules: Map<string, ModuleNode>;
107
+ providerToModule: Map<string, ModuleNode>;
108
+ }
109
+ declare function updateModuleGraphForFile(graph: ModuleGraph, project: Project, filePath: string): void;
110
+ //#endregion
111
+ //#region src/engine/rules/types.d.ts
139
112
  type RuleScope = "file" | "project" | "schema";
140
113
  interface RuleMeta {
141
114
  category: Category;
@@ -146,6 +119,7 @@ interface RuleMeta {
146
119
  severity: Severity;
147
120
  }
148
121
  interface CodeRuleContext {
122
+ config?: NestjsDoctorConfig;
149
123
  filePath: string;
150
124
  report(diagnostic: Omit<CodeDiagnostic, "rule" | "category" | "severity" | "scope">): void;
151
125
  sourceFile: SourceFile;
@@ -177,7 +151,36 @@ interface SchemaRule {
177
151
  }
178
152
  type AnyRule = Rule | ProjectRule | SchemaRule;
179
153
  //#endregion
180
- //#region src/types/result.d.ts
154
+ //#region src/common/diagnostic.d.ts
155
+ type Severity = "error" | "warning" | "info";
156
+ type Category = "security" | "performance" | "correctness" | "architecture" | "schema";
157
+ interface SourceLine {
158
+ line: number;
159
+ text: string;
160
+ }
161
+ interface BaseDiagnostic {
162
+ category: Category;
163
+ filePath: string;
164
+ help: string;
165
+ message: string;
166
+ rule: string;
167
+ scope?: RuleScope;
168
+ severity: Severity;
169
+ }
170
+ interface CodeDiagnostic extends BaseDiagnostic {
171
+ column: number;
172
+ line: number;
173
+ sourceLines?: SourceLine[];
174
+ }
175
+ interface SchemaDiagnostic extends BaseDiagnostic {
176
+ entity: string;
177
+ schemaColumn?: string;
178
+ }
179
+ type Diagnostic = CodeDiagnostic | SchemaDiagnostic;
180
+ declare function isCodeDiagnostic(d: Diagnostic): d is CodeDiagnostic;
181
+ declare function isSchemaDiagnostic(d: Diagnostic): d is SchemaDiagnostic;
182
+ //#endregion
183
+ //#region src/common/result.d.ts
181
184
  interface Score {
182
185
  label: string;
183
186
  value: number;
@@ -221,59 +224,116 @@ interface MonorepoResult {
221
224
  subProjects: SubProjectResult[];
222
225
  }
223
226
  //#endregion
224
- //#region src/core/scanner.d.ts
225
- interface ScanOptions {
226
- config?: string;
227
+ //#region src/common/errors.d.ts
228
+ declare class NestjsDoctorError extends Error {
229
+ constructor(message: string);
230
+ }
231
+ declare class ConfigurationError extends NestjsDoctorError {
232
+ constructor(message: string);
233
+ }
234
+ declare class ScanError extends NestjsDoctorError {
235
+ constructor(message: string);
236
+ }
237
+ declare class ValidationError extends NestjsDoctorError {
238
+ constructor(message: string);
239
+ }
240
+ //#endregion
241
+ //#region src/engine/rules/index.d.ts
242
+ declare function getRules(): AnyRule[];
243
+ //#endregion
244
+ //#region src/engine/config/scan-config.d.ts
245
+ interface ScanConfig {
246
+ combinedRules: AnyRule[];
247
+ config: NestjsDoctorConfig;
248
+ customRuleWarnings: string[];
249
+ fileRules: Rule[];
250
+ projectRules: ProjectRule[];
251
+ schemaRules: SchemaRule[];
252
+ }
253
+ declare function resolveScanConfig(targetPath: string, configPath?: string): Promise<ScanConfig>;
254
+ //#endregion
255
+ //#region src/engine/project-detector.d.ts
256
+ interface MonorepoInfo {
257
+ projects: Map<string, string>;
227
258
  }
228
- interface ScanContext {
259
+ //#endregion
260
+ //#region src/engine/analysis-context.d.ts
261
+ interface AnalysisContext {
229
262
  astProject: Project;
230
263
  config: NestjsDoctorConfig;
231
264
  fileRules: Rule[];
232
265
  files: string[];
233
266
  moduleGraph: ModuleGraph;
267
+ project: ProjectInfo;
234
268
  projectRules: ProjectRule[];
235
269
  providers: Map<string, ProviderInfo>;
236
270
  schemaGraph?: SchemaGraph;
237
271
  schemaRules: SchemaRule[];
238
272
  targetPath: string;
239
273
  }
240
- declare function prepareScan(targetPath: string, options?: ScanOptions): Promise<{
241
- context: ScanContext;
274
+ declare function buildAnalysisContext(targetPath: string, scanConfig: ScanConfig): Promise<AnalysisContext>;
275
+ declare function prepareAnalysis(targetPath: string, options?: {
276
+ config?: string;
277
+ }): Promise<{
278
+ context: AnalysisContext;
242
279
  customRuleWarnings: string[];
243
280
  }>;
244
- declare function updateFile(context: ScanContext, filePath: string): void;
245
- declare function scanFile(context: ScanContext, filePath: string): {
281
+ declare function updateFile(context: AnalysisContext, filePath: string): void;
282
+ //#endregion
283
+ //#region src/engine/diagnostician.d.ts
284
+ interface RawDiagnosticOutput {
285
+ diagnostics: Diagnostic[];
286
+ elapsedMs: number;
287
+ ruleErrors: RuleErrorInfo[];
288
+ }
289
+ declare function checkFile(context: AnalysisContext, filePath: string): {
246
290
  diagnostics: Diagnostic[];
247
291
  errors: RuleErrorInfo[];
248
292
  };
249
- declare function scanAllFiles(context: ScanContext): {
293
+ declare function checkAllFiles(context: AnalysisContext): {
250
294
  diagnostics: Diagnostic[];
251
295
  errors: RuleErrorInfo[];
252
296
  };
253
- declare function scanProject(context: ScanContext): {
297
+ declare function checkProject(context: AnalysisContext): {
298
+ diagnostics: Diagnostic[];
299
+ errors: RuleErrorInfo[];
300
+ };
301
+ declare function checkSchema(context: AnalysisContext): {
254
302
  diagnostics: Diagnostic[];
255
303
  errors: RuleErrorInfo[];
256
304
  };
257
305
  //#endregion
258
- //#region src/engine/schema/extract.d.ts
259
- declare function extractSchema(project: Project, files: string[], orm: string | null, targetPath: string): SchemaGraph;
260
- //#endregion
261
- //#region src/rules/index.d.ts
262
- declare function getRules(): AnyRule[];
263
- //#endregion
264
- //#region src/types/errors.d.ts
265
- declare class NestjsDoctorError extends Error {
266
- constructor(message: string);
267
- }
268
- declare class ConfigurationError extends NestjsDoctorError {
269
- constructor(message: string);
270
- }
271
- declare class ScanError extends NestjsDoctorError {
272
- constructor(message: string);
306
+ //#region src/engine/result-builder.d.ts
307
+ interface EngineResult {
308
+ customRuleWarnings: string[];
309
+ files: string[];
310
+ moduleGraph: ModuleGraph;
311
+ providers: Map<string, ProviderInfo>;
312
+ result: DiagnoseResult;
313
+ schemaGraph: SchemaGraph;
273
314
  }
274
- declare class ValidationError extends NestjsDoctorError {
275
- constructor(message: string);
315
+ interface MonorepoEngineResult {
316
+ customRuleWarnings: string[];
317
+ moduleGraphs: Map<string, ModuleGraph>;
318
+ result: MonorepoResult;
276
319
  }
320
+ declare function buildResult(context: AnalysisContext, rawOutput: RawDiagnosticOutput, customRuleWarnings?: string[]): EngineResult;
321
+ //#endregion
322
+ //#region src/engine/scanner.d.ts
323
+ type AutoScanResult = {
324
+ isMonorepo: true;
325
+ monorepo: MonorepoEngineResult;
326
+ } | {
327
+ isMonorepo: false;
328
+ single: EngineResult;
329
+ };
330
+ declare function autoScan(targetPath: string, options?: {
331
+ config?: string;
332
+ monorepo?: MonorepoInfo;
333
+ }): Promise<AutoScanResult>;
334
+ //#endregion
335
+ //#region src/engine/schema/extract.d.ts
336
+ declare function extractSchema(project: Project, files: string[], orm: string | null, targetPath: string): SchemaGraph;
277
337
  //#endregion
278
338
  //#region src/api/index.d.ts
279
339
  /**
@@ -302,5 +362,4 @@ declare function diagnoseMonorepo(path: string, options?: {
302
362
  config?: string;
303
363
  }): Promise<MonorepoResult>;
304
364
  //#endregion
305
- export { type AnyRule, type BaseDiagnostic, type Category, type CodeDiagnostic, type CodeRuleContext, type CodeRuleContext as RuleContext, ConfigurationError, type DiagnoseResult, type DiagnoseSummary, type Diagnostic, type MonorepoResult, type NestjsDoctorConfig, NestjsDoctorError, type ProjectInfo, type ProjectRule, type ProjectRuleContext, type Rule, type RuleErrorInfo, type RuleMeta, type ScanContext, ScanError, type SchemaColumn, type SchemaDiagnostic, type SchemaEntity, type SchemaGraph, type SchemaRelation, type SchemaRule, type SchemaRuleContext, type Score, type SerializedSchemaGraph, type Severity, type SubProjectResult, ValidationError, diagnose, diagnoseMonorepo, extractSchema, getRules, isCodeDiagnostic, isSchemaDiagnostic, prepareScan, scanAllFiles, scanFile, scanProject, updateFile, updateModuleGraphForFile, updateProvidersForFile };
306
- //# sourceMappingURL=index.d.mts.map
365
+ export { type AnalysisContext, type AnyRule, type AutoScanResult, type BaseDiagnostic, type Category, type CodeDiagnostic, type CodeRuleContext, type CodeRuleContext as RuleContext, ConfigurationError, type DiagnoseResult, type DiagnoseSummary, type Diagnostic, type MonorepoResult, type NestjsDoctorConfig, NestjsDoctorError, type ProjectInfo, type ProjectRule, type ProjectRuleContext, type RawDiagnosticOutput, type Rule, type RuleErrorInfo, type RuleMeta, type ScanConfig, ScanError, type SchemaColumn, type SchemaDiagnostic, type SchemaEntity, type SchemaGraph, type SchemaRelation, type SchemaRule, type SchemaRuleContext, type Score, type SerializedSchemaGraph, type Severity, type SubProjectResult, ValidationError, autoScan, buildAnalysisContext, buildResult, checkAllFiles, checkFile, checkProject, checkSchema, diagnose, diagnoseMonorepo, extractSchema, getRules, isCodeDiagnostic, isSchemaDiagnostic, prepareAnalysis, resolveScanConfig, updateFile, updateModuleGraphForFile, updateProvidersForFile };