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 +15 -4
- package/dist/api/index.d.mts +148 -89
- package/dist/api/index.mjs +4 -3502
- package/dist/cli/index.d.mts +2 -0
- package/dist/cli/index.mjs +4 -9219
- package/dist/init-DBZfqc-K.mjs +431 -0
- package/dist/setup-9FpyLvnO.mjs +4969 -0
- package/package.json +7 -20
- package/dist/api/index.cjs +0 -3546
- package/dist/api/index.d.cts +0 -306
- package/dist/api/index.d.cts.map +0 -1
- package/dist/api/index.d.mts.map +0 -1
- package/dist/api/index.mjs.map +0 -1
- package/skill/CREATE-RULE-SKILL.md +0 -395
- package/skill/SKILL.md +0 -114
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
|
-
|
|
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
|
|
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
|
-
|
package/dist/api/index.d.mts
CHANGED
|
@@ -1,64 +1,10 @@
|
|
|
1
1
|
import { ClassDeclaration, Project, SourceFile } from "ts-morph";
|
|
2
2
|
|
|
3
|
-
//#region src/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
|
|
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
|
|
241
|
-
|
|
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:
|
|
245
|
-
|
|
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
|
|
293
|
+
declare function checkAllFiles(context: AnalysisContext): {
|
|
250
294
|
diagnostics: Diagnostic[];
|
|
251
295
|
errors: RuleErrorInfo[];
|
|
252
296
|
};
|
|
253
|
-
declare function
|
|
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/
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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
|
-
|
|
275
|
-
|
|
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
|
|
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 };
|