nestjs-doctor 0.4.10 → 0.4.12

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
@@ -41,7 +41,7 @@ npx nestjs-doctor@latest . --verbose
41
41
  npx nestjs-doctor@latest . --report
42
42
  ```
43
43
 
44
- Generates a self-contained HTML file with four tabs: **Summary** (health score overview), **Diagnosis** (source-level findings), **Modules Graph** (interactive physics-based visualization), and **Lab** (custom rule playground). Click any module to focus it — unrelated modules fade out and the detail panel shows its providers, controllers, imports, and exports.
44
+ Self-contained HTML file with four sections: score summary, source-level diagnostics with code viewer, interactive module graph, and a custom rule playground. Opens in your browser.
45
45
 
46
46
  ![Module Graph](https://nestjs.doctor/module-graph.png)
47
47
 
@@ -110,6 +110,15 @@ npx nestjs-doctor --init
110
110
 
111
111
  A project-level fallback is always written to `.agents/nestjs-doctor/`. Commit it so every contributor gets the skill automatically.
112
112
 
113
+ ### Skills
114
+
115
+ `--init` installs two skills per agent:
116
+
117
+ | Skill | Command | Description |
118
+ |-------|---------|-------------|
119
+ | nestjs-doctor | `/nestjs-doctor` | Runs the scan, shows the report, and fixes what it can |
120
+ | nestjs-doctor-create-rule | `/nestjs-doctor-create-rule` | Scaffolds a custom rule: checks feasibility, writes the `.ts` file, updates config, verifies it loads |
121
+
113
122
  ---
114
123
 
115
124
  ## Configuration
@@ -176,49 +176,78 @@ function isProjectRule(rule) {
176
176
 
177
177
  //#endregion
178
178
  //#region src/engine/rule-runner.ts
179
- function runRules(project, files, rules, options) {
180
- const diagnostics = [];
181
- const errors = [];
179
+ function separateRules(rules) {
182
180
  const fileRules = [];
183
181
  const projectRules = [];
184
182
  for (const rule of rules) if (isProjectRule(rule)) projectRules.push(rule);
185
183
  else fileRules.push(rule);
186
- for (const filePath of files) {
187
- const sourceFile = project.getSourceFile(filePath);
188
- if (!sourceFile) continue;
189
- const allLines = sourceFile.getFullText().split("\n");
190
- for (const rule of fileRules) {
191
- const context = {
192
- sourceFile,
193
- filePath,
194
- report(partial) {
195
- const sourceLines = [];
196
- const start = Math.max(0, partial.line - 6);
197
- const end = Math.min(allLines.length, partial.line + 5);
198
- for (let i = start; i < end; i++) sourceLines.push({
199
- line: i + 1,
200
- text: allLines[i]
201
- });
202
- diagnostics.push({
203
- ...partial,
204
- rule: rule.meta.id,
205
- category: rule.meta.category,
206
- severity: rule.meta.severity,
207
- sourceLines
208
- });
209
- }
210
- };
211
- try {
212
- rule.check(context);
213
- } catch (error) {
214
- errors.push({
215
- ruleId: rule.meta.id,
216
- error
184
+ return {
185
+ fileRules,
186
+ projectRules
187
+ };
188
+ }
189
+ function runFileRulesOnFile(project, filePath, rules) {
190
+ const diagnostics = [];
191
+ const errors = [];
192
+ const sourceFile = project.getSourceFile(filePath);
193
+ if (!sourceFile) return {
194
+ diagnostics,
195
+ errors
196
+ };
197
+ const allLines = sourceFile.getFullText().split("\n");
198
+ for (const rule of rules) {
199
+ const context = {
200
+ sourceFile,
201
+ filePath,
202
+ report(partial) {
203
+ const sourceLines = [];
204
+ const start = Math.max(0, partial.line - 6);
205
+ const end = Math.min(allLines.length, partial.line + 5);
206
+ for (let i = start; i < end; i++) sourceLines.push({
207
+ line: i + 1,
208
+ text: allLines[i]
209
+ });
210
+ diagnostics.push({
211
+ ...partial,
212
+ rule: rule.meta.id,
213
+ category: rule.meta.category,
214
+ scope: "file",
215
+ severity: rule.meta.severity,
216
+ sourceLines
217
217
  });
218
218
  }
219
+ };
220
+ try {
221
+ rule.check(context);
222
+ } catch (error) {
223
+ errors.push({
224
+ ruleId: rule.meta.id,
225
+ error
226
+ });
219
227
  }
220
228
  }
221
- for (const rule of projectRules) {
229
+ return {
230
+ diagnostics,
231
+ errors
232
+ };
233
+ }
234
+ function runFileRules(project, files, rules) {
235
+ const diagnostics = [];
236
+ const errors = [];
237
+ for (const filePath of files) {
238
+ const result = runFileRulesOnFile(project, filePath, rules);
239
+ diagnostics.push(...result.diagnostics);
240
+ errors.push(...result.errors);
241
+ }
242
+ return {
243
+ diagnostics,
244
+ errors
245
+ };
246
+ }
247
+ function runProjectRules(project, files, rules, options) {
248
+ const diagnostics = [];
249
+ const errors = [];
250
+ for (const rule of rules) {
222
251
  const context = {
223
252
  project,
224
253
  files,
@@ -230,6 +259,7 @@ function runRules(project, files, rules, options) {
230
259
  ...partial,
231
260
  rule: rule.meta.id,
232
261
  category: rule.meta.category,
262
+ scope: "project",
233
263
  severity: rule.meta.severity
234
264
  });
235
265
  }
@@ -248,6 +278,15 @@ function runRules(project, files, rules, options) {
248
278
  errors
249
279
  };
250
280
  }
281
+ function runRules(project, files, rules, options) {
282
+ const { fileRules, projectRules } = separateRules(rules);
283
+ const fileResult = runFileRules(project, files, fileRules);
284
+ const projectResult = runProjectRules(project, files, projectRules, options);
285
+ return {
286
+ diagnostics: [...fileResult.diagnostics, ...projectResult.diagnostics],
287
+ errors: [...fileResult.errors, ...projectResult.errors]
288
+ };
289
+ }
251
290
 
252
291
  //#endregion
253
292
  //#region src/engine/type-resolver.ts
@@ -2449,28 +2488,82 @@ function formatRuleError(error) {
2449
2488
  if (error instanceof Error) return error.message;
2450
2489
  return String(error);
2451
2490
  }
2452
- async function scan(targetPath, options = {}) {
2453
- const startTime = node_perf_hooks.performance.now();
2491
+ async function prepareScan(targetPath, options = {}) {
2454
2492
  const config = await loadConfig(targetPath, options.config);
2455
2493
  const { rules: customRules, warnings: customRuleWarnings } = await resolveCustomRules(config, targetPath);
2456
2494
  const combinedRules = mergeRules(allRules, customRules, customRuleWarnings);
2457
- const project = await detectProject(targetPath);
2458
2495
  const files = await collectFiles(targetPath, config);
2459
2496
  const astProject = createAstParser(files);
2460
2497
  const moduleGraph = buildModuleGraph(astProject, files);
2461
2498
  const providers = resolveProviders(astProject, files);
2462
- const { diagnostics: rawDiagnostics, errors } = runRules(astProject, files, filterRules(config, combinedRules), {
2463
- moduleGraph,
2464
- providers,
2465
- config
2466
- });
2467
- const diagnostics = filterIgnoredDiagnostics(rawDiagnostics, config, targetPath);
2468
- const score = calculateScore(diagnostics, files.length);
2499
+ const { fileRules, projectRules } = separateRules(filterRules(config, combinedRules));
2500
+ return {
2501
+ context: {
2502
+ astProject,
2503
+ config,
2504
+ fileRules,
2505
+ files,
2506
+ moduleGraph,
2507
+ projectRules,
2508
+ providers,
2509
+ targetPath
2510
+ },
2511
+ customRuleWarnings
2512
+ };
2513
+ }
2514
+ function updateFile(context, filePath) {
2515
+ const existing = context.astProject.getSourceFile(filePath);
2516
+ if (existing) context.astProject.removeSourceFile(existing);
2517
+ context.astProject.addSourceFileAtPath(filePath);
2518
+ if (!context.files.includes(filePath)) context.files.push(filePath);
2519
+ context.moduleGraph = buildModuleGraph(context.astProject, context.files);
2520
+ context.providers = resolveProviders(context.astProject, context.files);
2521
+ }
2522
+ function scanFile(context, filePath) {
2523
+ const { diagnostics: rawDiagnostics, errors } = runFileRules(context.astProject, [filePath], context.fileRules);
2524
+ return {
2525
+ diagnostics: filterIgnoredDiagnostics(rawDiagnostics, context.config, context.targetPath),
2526
+ errors: errors.map((e) => ({
2527
+ ruleId: e.ruleId,
2528
+ error: formatRuleError(e.error)
2529
+ }))
2530
+ };
2531
+ }
2532
+ function scanAllFiles(context) {
2533
+ const { diagnostics: rawDiagnostics, errors } = runFileRules(context.astProject, context.files, context.fileRules);
2534
+ return {
2535
+ diagnostics: filterIgnoredDiagnostics(rawDiagnostics, context.config, context.targetPath),
2536
+ errors: errors.map((e) => ({
2537
+ ruleId: e.ruleId,
2538
+ error: formatRuleError(e.error)
2539
+ }))
2540
+ };
2541
+ }
2542
+ function scanProject(context) {
2543
+ const options = {
2544
+ moduleGraph: context.moduleGraph,
2545
+ providers: context.providers,
2546
+ config: context.config
2547
+ };
2548
+ const { diagnostics: rawDiagnostics, errors } = runProjectRules(context.astProject, context.files, context.projectRules, options);
2549
+ return {
2550
+ diagnostics: filterIgnoredDiagnostics(rawDiagnostics, context.config, context.targetPath),
2551
+ errors: errors.map((e) => ({
2552
+ ruleId: e.ruleId,
2553
+ error: formatRuleError(e.error)
2554
+ }))
2555
+ };
2556
+ }
2557
+ async function scan(targetPath, options = {}) {
2558
+ const startTime = node_perf_hooks.performance.now();
2559
+ const { context, customRuleWarnings } = await prepareScan(targetPath, options);
2560
+ const fileResult = scanAllFiles(context);
2561
+ const projectResult = scanProject(context);
2562
+ const diagnostics = [...fileResult.diagnostics, ...projectResult.diagnostics];
2563
+ const ruleErrors = [...fileResult.errors, ...projectResult.errors];
2564
+ const project = await detectProject(targetPath);
2565
+ const score = calculateScore(diagnostics, context.files.length);
2469
2566
  const summary = buildSummary(diagnostics);
2470
- const ruleErrors = errors.map((e) => ({
2471
- ruleId: e.ruleId,
2472
- error: formatRuleError(e.error)
2473
- }));
2474
2567
  const elapsedMs = node_perf_hooks.performance.now() - startTime;
2475
2568
  return {
2476
2569
  result: {
@@ -2478,17 +2571,17 @@ async function scan(targetPath, options = {}) {
2478
2571
  diagnostics,
2479
2572
  project: {
2480
2573
  ...project,
2481
- fileCount: files.length,
2482
- moduleCount: moduleGraph.modules.size
2574
+ fileCount: context.files.length,
2575
+ moduleCount: context.moduleGraph.modules.size
2483
2576
  },
2484
2577
  summary,
2485
2578
  ruleErrors,
2486
2579
  elapsedMs
2487
2580
  },
2488
- moduleGraph,
2581
+ moduleGraph: context.moduleGraph,
2489
2582
  customRuleWarnings,
2490
- files,
2491
- providers
2583
+ files: context.files,
2584
+ providers: context.providers
2492
2585
  };
2493
2586
  }
2494
2587
  function filterRules(config, rules) {
@@ -2700,4 +2793,9 @@ exports.ScanError = ScanError;
2700
2793
  exports.ValidationError = ValidationError;
2701
2794
  exports.diagnose = diagnose;
2702
2795
  exports.diagnoseMonorepo = diagnoseMonorepo;
2703
- exports.getRules = getRules;
2796
+ exports.getRules = getRules;
2797
+ exports.prepareScan = prepareScan;
2798
+ exports.scanAllFiles = scanAllFiles;
2799
+ exports.scanFile = scanFile;
2800
+ exports.scanProject = scanProject;
2801
+ exports.updateFile = updateFile;
@@ -40,6 +40,7 @@ interface Diagnostic {
40
40
  line: number;
41
41
  message: string;
42
42
  rule: string;
43
+ scope?: RuleScope;
43
44
  severity: Severity;
44
45
  sourceLines?: SourceLine[];
45
46
  }
@@ -96,23 +97,6 @@ interface ProjectRule {
96
97
  }
97
98
  type AnyRule = Rule | ProjectRule;
98
99
  //#endregion
99
- //#region src/rules/index.d.ts
100
- declare function getRules(): AnyRule[];
101
- //#endregion
102
- //#region src/types/errors.d.ts
103
- declare class NestjsDoctorError extends Error {
104
- constructor(message: string);
105
- }
106
- declare class ConfigurationError extends NestjsDoctorError {
107
- constructor(message: string);
108
- }
109
- declare class ScanError extends NestjsDoctorError {
110
- constructor(message: string);
111
- }
112
- declare class ValidationError extends NestjsDoctorError {
113
- constructor(message: string);
114
- }
115
- //#endregion
116
100
  //#region src/types/result.d.ts
117
101
  interface Score {
118
102
  label: string;
@@ -156,6 +140,55 @@ interface MonorepoResult {
156
140
  subProjects: SubProjectResult[];
157
141
  }
158
142
  //#endregion
143
+ //#region src/core/scanner.d.ts
144
+ interface ScanOptions {
145
+ config?: string;
146
+ }
147
+ interface ScanContext {
148
+ astProject: Project;
149
+ config: NestjsDoctorConfig;
150
+ fileRules: Rule[];
151
+ files: string[];
152
+ moduleGraph: ModuleGraph;
153
+ projectRules: ProjectRule[];
154
+ providers: Map<string, ProviderInfo>;
155
+ targetPath: string;
156
+ }
157
+ declare function prepareScan(targetPath: string, options?: ScanOptions): Promise<{
158
+ context: ScanContext;
159
+ customRuleWarnings: string[];
160
+ }>;
161
+ declare function updateFile(context: ScanContext, filePath: string): void;
162
+ declare function scanFile(context: ScanContext, filePath: string): {
163
+ diagnostics: Diagnostic[];
164
+ errors: RuleErrorInfo[];
165
+ };
166
+ declare function scanAllFiles(context: ScanContext): {
167
+ diagnostics: Diagnostic[];
168
+ errors: RuleErrorInfo[];
169
+ };
170
+ declare function scanProject(context: ScanContext): {
171
+ diagnostics: Diagnostic[];
172
+ errors: RuleErrorInfo[];
173
+ };
174
+ //#endregion
175
+ //#region src/rules/index.d.ts
176
+ declare function getRules(): AnyRule[];
177
+ //#endregion
178
+ //#region src/types/errors.d.ts
179
+ declare class NestjsDoctorError extends Error {
180
+ constructor(message: string);
181
+ }
182
+ declare class ConfigurationError extends NestjsDoctorError {
183
+ constructor(message: string);
184
+ }
185
+ declare class ScanError extends NestjsDoctorError {
186
+ constructor(message: string);
187
+ }
188
+ declare class ValidationError extends NestjsDoctorError {
189
+ constructor(message: string);
190
+ }
191
+ //#endregion
159
192
  //#region src/api/index.d.ts
160
193
  /**
161
194
  * Scans a single NestJS project and returns a health diagnostic result.
@@ -183,5 +216,5 @@ declare function diagnoseMonorepo(path: string, options?: {
183
216
  config?: string;
184
217
  }): Promise<MonorepoResult>;
185
218
  //#endregion
186
- export { type AnyRule, type Category, ConfigurationError, type DiagnoseResult, type DiagnoseSummary, type Diagnostic, type MonorepoResult, type NestjsDoctorConfig, NestjsDoctorError, type ProjectInfo, type ProjectRule, type ProjectRuleContext, type Rule, type RuleContext, type RuleErrorInfo, type RuleMeta, ScanError, type Score, type Severity, type SubProjectResult, ValidationError, diagnose, diagnoseMonorepo, getRules };
219
+ export { type AnyRule, type Category, ConfigurationError, type DiagnoseResult, type DiagnoseSummary, type Diagnostic, type MonorepoResult, type NestjsDoctorConfig, NestjsDoctorError, type ProjectInfo, type ProjectRule, type ProjectRuleContext, type Rule, type RuleContext, type RuleErrorInfo, type RuleMeta, type ScanContext, ScanError, type Score, type Severity, type SubProjectResult, ValidationError, diagnose, diagnoseMonorepo, getRules, prepareScan, scanAllFiles, scanFile, scanProject, updateFile };
187
220
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/engine/type-resolver.ts","../../src/engine/module-graph.ts","../../src/types/diagnostic.ts","../../src/types/config.ts","../../src/rules/types.ts","../../src/rules/index.ts","../../src/types/errors.ts","../../src/types/result.ts","../../src/api/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/engine/type-resolver.ts","../../src/engine/module-graph.ts","../../src/types/diagnostic.ts","../../src/types/config.ts","../../src/rules/types.ts","../../src/types/result.ts","../../src/core/scanner.ts","../../src/rules/index.ts","../../src/types/errors.ts","../../src/api/index.ts"],"mappings":"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"}
@@ -40,6 +40,7 @@ interface Diagnostic {
40
40
  line: number;
41
41
  message: string;
42
42
  rule: string;
43
+ scope?: RuleScope;
43
44
  severity: Severity;
44
45
  sourceLines?: SourceLine[];
45
46
  }
@@ -96,23 +97,6 @@ interface ProjectRule {
96
97
  }
97
98
  type AnyRule = Rule | ProjectRule;
98
99
  //#endregion
99
- //#region src/rules/index.d.ts
100
- declare function getRules(): AnyRule[];
101
- //#endregion
102
- //#region src/types/errors.d.ts
103
- declare class NestjsDoctorError extends Error {
104
- constructor(message: string);
105
- }
106
- declare class ConfigurationError extends NestjsDoctorError {
107
- constructor(message: string);
108
- }
109
- declare class ScanError extends NestjsDoctorError {
110
- constructor(message: string);
111
- }
112
- declare class ValidationError extends NestjsDoctorError {
113
- constructor(message: string);
114
- }
115
- //#endregion
116
100
  //#region src/types/result.d.ts
117
101
  interface Score {
118
102
  label: string;
@@ -156,6 +140,55 @@ interface MonorepoResult {
156
140
  subProjects: SubProjectResult[];
157
141
  }
158
142
  //#endregion
143
+ //#region src/core/scanner.d.ts
144
+ interface ScanOptions {
145
+ config?: string;
146
+ }
147
+ interface ScanContext {
148
+ astProject: Project;
149
+ config: NestjsDoctorConfig;
150
+ fileRules: Rule[];
151
+ files: string[];
152
+ moduleGraph: ModuleGraph;
153
+ projectRules: ProjectRule[];
154
+ providers: Map<string, ProviderInfo>;
155
+ targetPath: string;
156
+ }
157
+ declare function prepareScan(targetPath: string, options?: ScanOptions): Promise<{
158
+ context: ScanContext;
159
+ customRuleWarnings: string[];
160
+ }>;
161
+ declare function updateFile(context: ScanContext, filePath: string): void;
162
+ declare function scanFile(context: ScanContext, filePath: string): {
163
+ diagnostics: Diagnostic[];
164
+ errors: RuleErrorInfo[];
165
+ };
166
+ declare function scanAllFiles(context: ScanContext): {
167
+ diagnostics: Diagnostic[];
168
+ errors: RuleErrorInfo[];
169
+ };
170
+ declare function scanProject(context: ScanContext): {
171
+ diagnostics: Diagnostic[];
172
+ errors: RuleErrorInfo[];
173
+ };
174
+ //#endregion
175
+ //#region src/rules/index.d.ts
176
+ declare function getRules(): AnyRule[];
177
+ //#endregion
178
+ //#region src/types/errors.d.ts
179
+ declare class NestjsDoctorError extends Error {
180
+ constructor(message: string);
181
+ }
182
+ declare class ConfigurationError extends NestjsDoctorError {
183
+ constructor(message: string);
184
+ }
185
+ declare class ScanError extends NestjsDoctorError {
186
+ constructor(message: string);
187
+ }
188
+ declare class ValidationError extends NestjsDoctorError {
189
+ constructor(message: string);
190
+ }
191
+ //#endregion
159
192
  //#region src/api/index.d.ts
160
193
  /**
161
194
  * Scans a single NestJS project and returns a health diagnostic result.
@@ -183,5 +216,5 @@ declare function diagnoseMonorepo(path: string, options?: {
183
216
  config?: string;
184
217
  }): Promise<MonorepoResult>;
185
218
  //#endregion
186
- export { type AnyRule, type Category, ConfigurationError, type DiagnoseResult, type DiagnoseSummary, type Diagnostic, type MonorepoResult, type NestjsDoctorConfig, NestjsDoctorError, type ProjectInfo, type ProjectRule, type ProjectRuleContext, type Rule, type RuleContext, type RuleErrorInfo, type RuleMeta, ScanError, type Score, type Severity, type SubProjectResult, ValidationError, diagnose, diagnoseMonorepo, getRules };
219
+ export { type AnyRule, type Category, ConfigurationError, type DiagnoseResult, type DiagnoseSummary, type Diagnostic, type MonorepoResult, type NestjsDoctorConfig, NestjsDoctorError, type ProjectInfo, type ProjectRule, type ProjectRuleContext, type Rule, type RuleContext, type RuleErrorInfo, type RuleMeta, type ScanContext, ScanError, type Score, type Severity, type SubProjectResult, ValidationError, diagnose, diagnoseMonorepo, getRules, prepareScan, scanAllFiles, scanFile, scanProject, updateFile };
187
220
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/engine/type-resolver.ts","../../src/engine/module-graph.ts","../../src/types/diagnostic.ts","../../src/types/config.ts","../../src/rules/types.ts","../../src/rules/index.ts","../../src/types/errors.ts","../../src/types/result.ts","../../src/api/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/engine/type-resolver.ts","../../src/engine/module-graph.ts","../../src/types/diagnostic.ts","../../src/types/config.ts","../../src/rules/types.ts","../../src/types/result.ts","../../src/core/scanner.ts","../../src/rules/index.ts","../../src/types/errors.ts","../../src/api/index.ts"],"mappings":"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"}