nestjs-doctor 0.4.12 → 0.4.13
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 +4 -0
- package/dist/api/index.cjs +118 -35
- package/dist/api/index.d.cts +3 -1
- package/dist/api/index.d.cts.map +1 -1
- package/dist/api/index.d.mts +3 -1
- package/dist/api/index.d.mts.map +1 -1
- package/dist/api/index.mjs +116 -35
- package/dist/api/index.mjs.map +1 -1
- package/dist/cli/index.mjs +39 -45
- package/package.json +1 -1
- package/skill/SKILL.md +1 -1
package/README.md
CHANGED
package/dist/api/index.cjs
CHANGED
|
@@ -114,6 +114,55 @@ function extractArrayPropertyNames(obj, propertyName) {
|
|
|
114
114
|
return text;
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
|
+
function updateModuleGraphForFile(graph, project, filePath) {
|
|
118
|
+
for (const [name, node] of graph.modules) if (node.filePath === filePath) {
|
|
119
|
+
graph.modules.delete(name);
|
|
120
|
+
graph.edges.delete(name);
|
|
121
|
+
for (const provider of node.providers) if (graph.providerToModule.get(provider) === node) graph.providerToModule.delete(provider);
|
|
122
|
+
for (const edgeSet of graph.edges.values()) edgeSet.delete(name);
|
|
123
|
+
}
|
|
124
|
+
const sourceFile = project.getSourceFile(filePath);
|
|
125
|
+
if (!sourceFile) return;
|
|
126
|
+
const newModules = [];
|
|
127
|
+
for (const cls of sourceFile.getClasses()) {
|
|
128
|
+
const moduleDecorator = cls.getDecorator("Module");
|
|
129
|
+
if (!moduleDecorator) continue;
|
|
130
|
+
const name = cls.getName() ?? "AnonymousModule";
|
|
131
|
+
const args = moduleDecorator.getArguments()[0];
|
|
132
|
+
const node = {
|
|
133
|
+
name,
|
|
134
|
+
filePath,
|
|
135
|
+
classDeclaration: cls,
|
|
136
|
+
imports: [],
|
|
137
|
+
exports: [],
|
|
138
|
+
providers: [],
|
|
139
|
+
controllers: []
|
|
140
|
+
};
|
|
141
|
+
if (args && args.getKind() === ts_morph.SyntaxKind.ObjectLiteralExpression) {
|
|
142
|
+
const obj = args.asKind(ts_morph.SyntaxKind.ObjectLiteralExpression);
|
|
143
|
+
if (obj) {
|
|
144
|
+
node.imports = extractArrayPropertyNames(obj, "imports");
|
|
145
|
+
node.exports = extractArrayPropertyNames(obj, "exports");
|
|
146
|
+
node.providers = extractArrayPropertyNames(obj, "providers");
|
|
147
|
+
node.controllers = extractArrayPropertyNames(obj, "controllers");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
graph.modules.set(name, node);
|
|
151
|
+
newModules.push(node);
|
|
152
|
+
}
|
|
153
|
+
for (const node of newModules) {
|
|
154
|
+
const importSet = /* @__PURE__ */ new Set();
|
|
155
|
+
for (const imp of node.imports) if (graph.modules.has(imp)) importSet.add(imp);
|
|
156
|
+
graph.edges.set(node.name, importSet);
|
|
157
|
+
for (const provider of node.providers) graph.providerToModule.set(provider, node);
|
|
158
|
+
}
|
|
159
|
+
for (const [name, node] of graph.modules) {
|
|
160
|
+
if (node.filePath === filePath) continue;
|
|
161
|
+
const importSet = /* @__PURE__ */ new Set();
|
|
162
|
+
for (const imp of node.imports) if (graph.modules.has(imp)) importSet.add(imp);
|
|
163
|
+
graph.edges.set(name, importSet);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
117
166
|
function findCircularDeps(graph) {
|
|
118
167
|
const cycles = [];
|
|
119
168
|
const visited = /* @__PURE__ */ new Set();
|
|
@@ -321,6 +370,32 @@ function resolveProviders(project, files) {
|
|
|
321
370
|
}
|
|
322
371
|
return providers;
|
|
323
372
|
}
|
|
373
|
+
function updateProvidersForFile(providers, project, filePath) {
|
|
374
|
+
for (const [name, info] of providers) if (info.filePath === filePath) providers.delete(name);
|
|
375
|
+
const sourceFile = project.getSourceFile(filePath);
|
|
376
|
+
if (!sourceFile) return;
|
|
377
|
+
for (const cls of sourceFile.getClasses()) {
|
|
378
|
+
if (!cls.getDecorator("Injectable")) continue;
|
|
379
|
+
const name = cls.getName();
|
|
380
|
+
if (!name) continue;
|
|
381
|
+
const ctor = cls.getConstructors()[0];
|
|
382
|
+
const dependencies = ctor ? ctor.getParameters().map((p) => {
|
|
383
|
+
const typeNode = p.getTypeNode();
|
|
384
|
+
return extractSimpleTypeName(typeNode ? typeNode.getText() : p.getType().getText());
|
|
385
|
+
}) : [];
|
|
386
|
+
const publicMethodCount = cls.getMethods().filter((m) => {
|
|
387
|
+
const scope = m.getScope();
|
|
388
|
+
return !scope || scope === "public";
|
|
389
|
+
}).length;
|
|
390
|
+
providers.set(name, {
|
|
391
|
+
name,
|
|
392
|
+
filePath,
|
|
393
|
+
classDeclaration: cls,
|
|
394
|
+
dependencies,
|
|
395
|
+
publicMethodCount
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
}
|
|
324
399
|
function extractSimpleTypeName(typeText) {
|
|
325
400
|
const importMatch = typeText.match(IMPORT_TYPE_REGEX);
|
|
326
401
|
if (importMatch) return importMatch[1];
|
|
@@ -2265,11 +2340,11 @@ async function collectFiles(targetPath, config = {}) {
|
|
|
2265
2340
|
})).sort();
|
|
2266
2341
|
}
|
|
2267
2342
|
async function collectMonorepoFiles(targetPath, monorepo, config = {}) {
|
|
2343
|
+
const entries = await Promise.all([...monorepo.projects.entries()].map(async ([name, root]) => {
|
|
2344
|
+
return [name, await collectFiles((0, node_path.join)(targetPath, root), config)];
|
|
2345
|
+
}));
|
|
2268
2346
|
const result = /* @__PURE__ */ new Map();
|
|
2269
|
-
for (const [name,
|
|
2270
|
-
const files = await collectFiles((0, node_path.join)(targetPath, root), config);
|
|
2271
|
-
result.set(name, files);
|
|
2272
|
-
}
|
|
2347
|
+
for (const [name, files] of entries) result.set(name, files);
|
|
2273
2348
|
return result;
|
|
2274
2349
|
}
|
|
2275
2350
|
|
|
@@ -2490,9 +2565,8 @@ function formatRuleError(error) {
|
|
|
2490
2565
|
}
|
|
2491
2566
|
async function prepareScan(targetPath, options = {}) {
|
|
2492
2567
|
const config = await loadConfig(targetPath, options.config);
|
|
2493
|
-
const { rules: customRules, warnings: customRuleWarnings } = await resolveCustomRules(config, targetPath);
|
|
2568
|
+
const [{ rules: customRules, warnings: customRuleWarnings }, files] = await Promise.all([resolveCustomRules(config, targetPath), collectFiles(targetPath, config)]);
|
|
2494
2569
|
const combinedRules = mergeRules(allRules, customRules, customRuleWarnings);
|
|
2495
|
-
const files = await collectFiles(targetPath, config);
|
|
2496
2570
|
const astProject = createAstParser(files);
|
|
2497
2571
|
const moduleGraph = buildModuleGraph(astProject, files);
|
|
2498
2572
|
const providers = resolveProviders(astProject, files);
|
|
@@ -2516,8 +2590,8 @@ function updateFile(context, filePath) {
|
|
|
2516
2590
|
if (existing) context.astProject.removeSourceFile(existing);
|
|
2517
2591
|
context.astProject.addSourceFileAtPath(filePath);
|
|
2518
2592
|
if (!context.files.includes(filePath)) context.files.push(filePath);
|
|
2519
|
-
context.moduleGraph
|
|
2520
|
-
context.providers
|
|
2593
|
+
updateModuleGraphForFile(context.moduleGraph, context.astProject, filePath);
|
|
2594
|
+
updateProvidersForFile(context.providers, context.astProject, filePath);
|
|
2521
2595
|
}
|
|
2522
2596
|
function scanFile(context, filePath) {
|
|
2523
2597
|
const { diagnostics: rawDiagnostics, errors } = runFileRules(context.astProject, [filePath], context.fileRules);
|
|
@@ -2557,11 +2631,12 @@ function scanProject(context) {
|
|
|
2557
2631
|
async function scan(targetPath, options = {}) {
|
|
2558
2632
|
const startTime = node_perf_hooks.performance.now();
|
|
2559
2633
|
const { context, customRuleWarnings } = await prepareScan(targetPath, options);
|
|
2634
|
+
const projectPromise = detectProject(targetPath);
|
|
2560
2635
|
const fileResult = scanAllFiles(context);
|
|
2561
2636
|
const projectResult = scanProject(context);
|
|
2562
2637
|
const diagnostics = [...fileResult.diagnostics, ...projectResult.diagnostics];
|
|
2563
2638
|
const ruleErrors = [...fileResult.errors, ...projectResult.errors];
|
|
2564
|
-
const project = await
|
|
2639
|
+
const project = await projectPromise;
|
|
2565
2640
|
const score = calculateScore(diagnostics, context.files.length);
|
|
2566
2641
|
const summary = buildSummary(diagnostics);
|
|
2567
2642
|
const elapsedMs = node_perf_hooks.performance.now() - startTime;
|
|
@@ -2618,16 +2693,9 @@ async function scanMonorepo(targetPath, options = {}) {
|
|
|
2618
2693
|
const { rules: customRules, warnings: customRuleWarnings } = await resolveCustomRules(rootConfig, targetPath);
|
|
2619
2694
|
const combinedRules = mergeRules(allRules, customRules, customRuleWarnings);
|
|
2620
2695
|
const filesByProject = await collectMonorepoFiles(targetPath, monorepo, rootConfig);
|
|
2621
|
-
const
|
|
2622
|
-
const allDiagnostics = [];
|
|
2623
|
-
const allRuleErrors = [];
|
|
2624
|
-
const moduleGraphs = /* @__PURE__ */ new Map();
|
|
2625
|
-
let totalFiles = 0;
|
|
2626
|
-
for (const [name, files] of filesByProject) {
|
|
2627
|
-
if (files.length === 0) continue;
|
|
2696
|
+
const subProjectEntries = await Promise.all([...filesByProject.entries()].filter(([, files]) => files.length > 0).map(async ([name, files]) => {
|
|
2628
2697
|
const projectPath = (0, node_path.join)(targetPath, monorepo.projects.get(name));
|
|
2629
|
-
const project = await detectProject(projectPath);
|
|
2630
|
-
const projectConfig = await loadConfigWithFallback(projectPath, rootConfig);
|
|
2698
|
+
const [project, projectConfig] = await Promise.all([detectProject(projectPath), loadConfigWithFallback(projectPath, rootConfig)]);
|
|
2631
2699
|
const astProject = createAstParser(files);
|
|
2632
2700
|
const moduleGraph = buildModuleGraph(astProject, files);
|
|
2633
2701
|
const providers = resolveProviders(astProject, files);
|
|
@@ -2643,26 +2711,39 @@ async function scanMonorepo(targetPath, options = {}) {
|
|
|
2643
2711
|
ruleId: e.ruleId,
|
|
2644
2712
|
error: formatRuleError(e.error)
|
|
2645
2713
|
}));
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2714
|
+
return {
|
|
2715
|
+
name,
|
|
2716
|
+
result: {
|
|
2717
|
+
score,
|
|
2718
|
+
diagnostics,
|
|
2719
|
+
project: {
|
|
2720
|
+
...project,
|
|
2721
|
+
fileCount: files.length,
|
|
2722
|
+
moduleCount: moduleGraph.modules.size
|
|
2723
|
+
},
|
|
2724
|
+
summary,
|
|
2725
|
+
ruleErrors,
|
|
2726
|
+
elapsedMs: 0
|
|
2653
2727
|
},
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2728
|
+
moduleGraph,
|
|
2729
|
+
diagnostics,
|
|
2730
|
+
ruleErrors
|
|
2657
2731
|
};
|
|
2732
|
+
}));
|
|
2733
|
+
const subProjects = [];
|
|
2734
|
+
const allDiagnostics = [];
|
|
2735
|
+
const allRuleErrors = [];
|
|
2736
|
+
const moduleGraphs = /* @__PURE__ */ new Map();
|
|
2737
|
+
let totalFiles = 0;
|
|
2738
|
+
for (const entry of subProjectEntries) {
|
|
2658
2739
|
subProjects.push({
|
|
2659
|
-
name,
|
|
2660
|
-
result
|
|
2740
|
+
name: entry.name,
|
|
2741
|
+
result: entry.result
|
|
2661
2742
|
});
|
|
2662
|
-
moduleGraphs.set(name, moduleGraph);
|
|
2663
|
-
allDiagnostics.push(...diagnostics);
|
|
2664
|
-
allRuleErrors.push(...ruleErrors);
|
|
2665
|
-
totalFiles +=
|
|
2743
|
+
moduleGraphs.set(entry.name, entry.moduleGraph);
|
|
2744
|
+
allDiagnostics.push(...entry.diagnostics);
|
|
2745
|
+
allRuleErrors.push(...entry.ruleErrors);
|
|
2746
|
+
totalFiles += entry.result.project.fileCount;
|
|
2666
2747
|
}
|
|
2667
2748
|
const combinedScore = calculateScore(allDiagnostics, totalFiles);
|
|
2668
2749
|
const combinedSummary = buildSummary(allDiagnostics);
|
|
@@ -2798,4 +2879,6 @@ exports.prepareScan = prepareScan;
|
|
|
2798
2879
|
exports.scanAllFiles = scanAllFiles;
|
|
2799
2880
|
exports.scanFile = scanFile;
|
|
2800
2881
|
exports.scanProject = scanProject;
|
|
2801
|
-
exports.updateFile = updateFile;
|
|
2882
|
+
exports.updateFile = updateFile;
|
|
2883
|
+
exports.updateModuleGraphForFile = updateModuleGraphForFile;
|
|
2884
|
+
exports.updateProvidersForFile = updateProvidersForFile;
|
package/dist/api/index.d.cts
CHANGED
|
@@ -8,6 +8,7 @@ interface ProviderInfo {
|
|
|
8
8
|
name: string;
|
|
9
9
|
publicMethodCount: number;
|
|
10
10
|
}
|
|
11
|
+
declare function updateProvidersForFile(providers: Map<string, ProviderInfo>, project: Project, filePath: string): void;
|
|
11
12
|
//#endregion
|
|
12
13
|
//#region src/engine/module-graph.d.ts
|
|
13
14
|
interface ModuleNode {
|
|
@@ -24,6 +25,7 @@ interface ModuleGraph {
|
|
|
24
25
|
modules: Map<string, ModuleNode>;
|
|
25
26
|
providerToModule: Map<string, ModuleNode>;
|
|
26
27
|
}
|
|
28
|
+
declare function updateModuleGraphForFile(graph: ModuleGraph, project: Project, filePath: string): void;
|
|
27
29
|
//#endregion
|
|
28
30
|
//#region src/types/diagnostic.d.ts
|
|
29
31
|
type Severity = "error" | "warning" | "info";
|
|
@@ -216,5 +218,5 @@ declare function diagnoseMonorepo(path: string, options?: {
|
|
|
216
218
|
config?: string;
|
|
217
219
|
}): Promise<MonorepoResult>;
|
|
218
220
|
//#endregion
|
|
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 };
|
|
221
|
+
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, updateModuleGraphForFile, updateProvidersForFile };
|
|
220
222
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/api/index.d.cts.map
CHANGED
|
@@ -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/types/result.ts","../../src/core/scanner.ts","../../src/rules/index.ts","../../src/types/errors.ts","../../src/api/index.ts"],"mappings":";;;UAKiB,YAAA;EAChB,gBAAA,EAAkB,gBAAA;EAClB,YAAA;EACA,QAAA;EACA,IAAA;EACA,iBAAA;AAAA;;;
|
|
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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"}
|
package/dist/api/index.d.mts
CHANGED
|
@@ -8,6 +8,7 @@ interface ProviderInfo {
|
|
|
8
8
|
name: string;
|
|
9
9
|
publicMethodCount: number;
|
|
10
10
|
}
|
|
11
|
+
declare function updateProvidersForFile(providers: Map<string, ProviderInfo>, project: Project, filePath: string): void;
|
|
11
12
|
//#endregion
|
|
12
13
|
//#region src/engine/module-graph.d.ts
|
|
13
14
|
interface ModuleNode {
|
|
@@ -24,6 +25,7 @@ interface ModuleGraph {
|
|
|
24
25
|
modules: Map<string, ModuleNode>;
|
|
25
26
|
providerToModule: Map<string, ModuleNode>;
|
|
26
27
|
}
|
|
28
|
+
declare function updateModuleGraphForFile(graph: ModuleGraph, project: Project, filePath: string): void;
|
|
27
29
|
//#endregion
|
|
28
30
|
//#region src/types/diagnostic.d.ts
|
|
29
31
|
type Severity = "error" | "warning" | "info";
|
|
@@ -216,5 +218,5 @@ declare function diagnoseMonorepo(path: string, options?: {
|
|
|
216
218
|
config?: string;
|
|
217
219
|
}): Promise<MonorepoResult>;
|
|
218
220
|
//#endregion
|
|
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 };
|
|
221
|
+
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, updateModuleGraphForFile, updateProvidersForFile };
|
|
220
222
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/api/index.d.mts.map
CHANGED
|
@@ -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/types/result.ts","../../src/core/scanner.ts","../../src/rules/index.ts","../../src/types/errors.ts","../../src/api/index.ts"],"mappings":";;;UAKiB,YAAA;EAChB,gBAAA,EAAkB,gBAAA;EAClB,YAAA;EACA,QAAA;EACA,IAAA;EACA,iBAAA;AAAA;;;
|
|
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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"}
|
package/dist/api/index.mjs
CHANGED
|
@@ -85,6 +85,55 @@ function extractArrayPropertyNames(obj, propertyName) {
|
|
|
85
85
|
return text;
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
|
+
function updateModuleGraphForFile(graph, project, filePath) {
|
|
89
|
+
for (const [name, node] of graph.modules) if (node.filePath === filePath) {
|
|
90
|
+
graph.modules.delete(name);
|
|
91
|
+
graph.edges.delete(name);
|
|
92
|
+
for (const provider of node.providers) if (graph.providerToModule.get(provider) === node) graph.providerToModule.delete(provider);
|
|
93
|
+
for (const edgeSet of graph.edges.values()) edgeSet.delete(name);
|
|
94
|
+
}
|
|
95
|
+
const sourceFile = project.getSourceFile(filePath);
|
|
96
|
+
if (!sourceFile) return;
|
|
97
|
+
const newModules = [];
|
|
98
|
+
for (const cls of sourceFile.getClasses()) {
|
|
99
|
+
const moduleDecorator = cls.getDecorator("Module");
|
|
100
|
+
if (!moduleDecorator) continue;
|
|
101
|
+
const name = cls.getName() ?? "AnonymousModule";
|
|
102
|
+
const args = moduleDecorator.getArguments()[0];
|
|
103
|
+
const node = {
|
|
104
|
+
name,
|
|
105
|
+
filePath,
|
|
106
|
+
classDeclaration: cls,
|
|
107
|
+
imports: [],
|
|
108
|
+
exports: [],
|
|
109
|
+
providers: [],
|
|
110
|
+
controllers: []
|
|
111
|
+
};
|
|
112
|
+
if (args && args.getKind() === SyntaxKind.ObjectLiteralExpression) {
|
|
113
|
+
const obj = args.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
114
|
+
if (obj) {
|
|
115
|
+
node.imports = extractArrayPropertyNames(obj, "imports");
|
|
116
|
+
node.exports = extractArrayPropertyNames(obj, "exports");
|
|
117
|
+
node.providers = extractArrayPropertyNames(obj, "providers");
|
|
118
|
+
node.controllers = extractArrayPropertyNames(obj, "controllers");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
graph.modules.set(name, node);
|
|
122
|
+
newModules.push(node);
|
|
123
|
+
}
|
|
124
|
+
for (const node of newModules) {
|
|
125
|
+
const importSet = /* @__PURE__ */ new Set();
|
|
126
|
+
for (const imp of node.imports) if (graph.modules.has(imp)) importSet.add(imp);
|
|
127
|
+
graph.edges.set(node.name, importSet);
|
|
128
|
+
for (const provider of node.providers) graph.providerToModule.set(provider, node);
|
|
129
|
+
}
|
|
130
|
+
for (const [name, node] of graph.modules) {
|
|
131
|
+
if (node.filePath === filePath) continue;
|
|
132
|
+
const importSet = /* @__PURE__ */ new Set();
|
|
133
|
+
for (const imp of node.imports) if (graph.modules.has(imp)) importSet.add(imp);
|
|
134
|
+
graph.edges.set(name, importSet);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
88
137
|
function findCircularDeps(graph) {
|
|
89
138
|
const cycles = [];
|
|
90
139
|
const visited = /* @__PURE__ */ new Set();
|
|
@@ -292,6 +341,32 @@ function resolveProviders(project, files) {
|
|
|
292
341
|
}
|
|
293
342
|
return providers;
|
|
294
343
|
}
|
|
344
|
+
function updateProvidersForFile(providers, project, filePath) {
|
|
345
|
+
for (const [name, info] of providers) if (info.filePath === filePath) providers.delete(name);
|
|
346
|
+
const sourceFile = project.getSourceFile(filePath);
|
|
347
|
+
if (!sourceFile) return;
|
|
348
|
+
for (const cls of sourceFile.getClasses()) {
|
|
349
|
+
if (!cls.getDecorator("Injectable")) continue;
|
|
350
|
+
const name = cls.getName();
|
|
351
|
+
if (!name) continue;
|
|
352
|
+
const ctor = cls.getConstructors()[0];
|
|
353
|
+
const dependencies = ctor ? ctor.getParameters().map((p) => {
|
|
354
|
+
const typeNode = p.getTypeNode();
|
|
355
|
+
return extractSimpleTypeName(typeNode ? typeNode.getText() : p.getType().getText());
|
|
356
|
+
}) : [];
|
|
357
|
+
const publicMethodCount = cls.getMethods().filter((m) => {
|
|
358
|
+
const scope = m.getScope();
|
|
359
|
+
return !scope || scope === "public";
|
|
360
|
+
}).length;
|
|
361
|
+
providers.set(name, {
|
|
362
|
+
name,
|
|
363
|
+
filePath,
|
|
364
|
+
classDeclaration: cls,
|
|
365
|
+
dependencies,
|
|
366
|
+
publicMethodCount
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
295
370
|
function extractSimpleTypeName(typeText) {
|
|
296
371
|
const importMatch = typeText.match(IMPORT_TYPE_REGEX);
|
|
297
372
|
if (importMatch) return importMatch[1];
|
|
@@ -2236,11 +2311,11 @@ async function collectFiles(targetPath, config = {}) {
|
|
|
2236
2311
|
})).sort();
|
|
2237
2312
|
}
|
|
2238
2313
|
async function collectMonorepoFiles(targetPath, monorepo, config = {}) {
|
|
2314
|
+
const entries = await Promise.all([...monorepo.projects.entries()].map(async ([name, root]) => {
|
|
2315
|
+
return [name, await collectFiles(join(targetPath, root), config)];
|
|
2316
|
+
}));
|
|
2239
2317
|
const result = /* @__PURE__ */ new Map();
|
|
2240
|
-
for (const [name,
|
|
2241
|
-
const files = await collectFiles(join(targetPath, root), config);
|
|
2242
|
-
result.set(name, files);
|
|
2243
|
-
}
|
|
2318
|
+
for (const [name, files] of entries) result.set(name, files);
|
|
2244
2319
|
return result;
|
|
2245
2320
|
}
|
|
2246
2321
|
|
|
@@ -2461,9 +2536,8 @@ function formatRuleError(error) {
|
|
|
2461
2536
|
}
|
|
2462
2537
|
async function prepareScan(targetPath, options = {}) {
|
|
2463
2538
|
const config = await loadConfig(targetPath, options.config);
|
|
2464
|
-
const { rules: customRules, warnings: customRuleWarnings } = await resolveCustomRules(config, targetPath);
|
|
2539
|
+
const [{ rules: customRules, warnings: customRuleWarnings }, files] = await Promise.all([resolveCustomRules(config, targetPath), collectFiles(targetPath, config)]);
|
|
2465
2540
|
const combinedRules = mergeRules(allRules, customRules, customRuleWarnings);
|
|
2466
|
-
const files = await collectFiles(targetPath, config);
|
|
2467
2541
|
const astProject = createAstParser(files);
|
|
2468
2542
|
const moduleGraph = buildModuleGraph(astProject, files);
|
|
2469
2543
|
const providers = resolveProviders(astProject, files);
|
|
@@ -2487,8 +2561,8 @@ function updateFile(context, filePath) {
|
|
|
2487
2561
|
if (existing) context.astProject.removeSourceFile(existing);
|
|
2488
2562
|
context.astProject.addSourceFileAtPath(filePath);
|
|
2489
2563
|
if (!context.files.includes(filePath)) context.files.push(filePath);
|
|
2490
|
-
context.moduleGraph
|
|
2491
|
-
context.providers
|
|
2564
|
+
updateModuleGraphForFile(context.moduleGraph, context.astProject, filePath);
|
|
2565
|
+
updateProvidersForFile(context.providers, context.astProject, filePath);
|
|
2492
2566
|
}
|
|
2493
2567
|
function scanFile(context, filePath) {
|
|
2494
2568
|
const { diagnostics: rawDiagnostics, errors } = runFileRules(context.astProject, [filePath], context.fileRules);
|
|
@@ -2528,11 +2602,12 @@ function scanProject(context) {
|
|
|
2528
2602
|
async function scan(targetPath, options = {}) {
|
|
2529
2603
|
const startTime = performance.now();
|
|
2530
2604
|
const { context, customRuleWarnings } = await prepareScan(targetPath, options);
|
|
2605
|
+
const projectPromise = detectProject(targetPath);
|
|
2531
2606
|
const fileResult = scanAllFiles(context);
|
|
2532
2607
|
const projectResult = scanProject(context);
|
|
2533
2608
|
const diagnostics = [...fileResult.diagnostics, ...projectResult.diagnostics];
|
|
2534
2609
|
const ruleErrors = [...fileResult.errors, ...projectResult.errors];
|
|
2535
|
-
const project = await
|
|
2610
|
+
const project = await projectPromise;
|
|
2536
2611
|
const score = calculateScore(diagnostics, context.files.length);
|
|
2537
2612
|
const summary = buildSummary(diagnostics);
|
|
2538
2613
|
const elapsedMs = performance.now() - startTime;
|
|
@@ -2589,16 +2664,9 @@ async function scanMonorepo(targetPath, options = {}) {
|
|
|
2589
2664
|
const { rules: customRules, warnings: customRuleWarnings } = await resolveCustomRules(rootConfig, targetPath);
|
|
2590
2665
|
const combinedRules = mergeRules(allRules, customRules, customRuleWarnings);
|
|
2591
2666
|
const filesByProject = await collectMonorepoFiles(targetPath, monorepo, rootConfig);
|
|
2592
|
-
const
|
|
2593
|
-
const allDiagnostics = [];
|
|
2594
|
-
const allRuleErrors = [];
|
|
2595
|
-
const moduleGraphs = /* @__PURE__ */ new Map();
|
|
2596
|
-
let totalFiles = 0;
|
|
2597
|
-
for (const [name, files] of filesByProject) {
|
|
2598
|
-
if (files.length === 0) continue;
|
|
2667
|
+
const subProjectEntries = await Promise.all([...filesByProject.entries()].filter(([, files]) => files.length > 0).map(async ([name, files]) => {
|
|
2599
2668
|
const projectPath = join(targetPath, monorepo.projects.get(name));
|
|
2600
|
-
const project = await detectProject(projectPath);
|
|
2601
|
-
const projectConfig = await loadConfigWithFallback(projectPath, rootConfig);
|
|
2669
|
+
const [project, projectConfig] = await Promise.all([detectProject(projectPath), loadConfigWithFallback(projectPath, rootConfig)]);
|
|
2602
2670
|
const astProject = createAstParser(files);
|
|
2603
2671
|
const moduleGraph = buildModuleGraph(astProject, files);
|
|
2604
2672
|
const providers = resolveProviders(astProject, files);
|
|
@@ -2614,26 +2682,39 @@ async function scanMonorepo(targetPath, options = {}) {
|
|
|
2614
2682
|
ruleId: e.ruleId,
|
|
2615
2683
|
error: formatRuleError(e.error)
|
|
2616
2684
|
}));
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2685
|
+
return {
|
|
2686
|
+
name,
|
|
2687
|
+
result: {
|
|
2688
|
+
score,
|
|
2689
|
+
diagnostics,
|
|
2690
|
+
project: {
|
|
2691
|
+
...project,
|
|
2692
|
+
fileCount: files.length,
|
|
2693
|
+
moduleCount: moduleGraph.modules.size
|
|
2694
|
+
},
|
|
2695
|
+
summary,
|
|
2696
|
+
ruleErrors,
|
|
2697
|
+
elapsedMs: 0
|
|
2624
2698
|
},
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2699
|
+
moduleGraph,
|
|
2700
|
+
diagnostics,
|
|
2701
|
+
ruleErrors
|
|
2628
2702
|
};
|
|
2703
|
+
}));
|
|
2704
|
+
const subProjects = [];
|
|
2705
|
+
const allDiagnostics = [];
|
|
2706
|
+
const allRuleErrors = [];
|
|
2707
|
+
const moduleGraphs = /* @__PURE__ */ new Map();
|
|
2708
|
+
let totalFiles = 0;
|
|
2709
|
+
for (const entry of subProjectEntries) {
|
|
2629
2710
|
subProjects.push({
|
|
2630
|
-
name,
|
|
2631
|
-
result
|
|
2711
|
+
name: entry.name,
|
|
2712
|
+
result: entry.result
|
|
2632
2713
|
});
|
|
2633
|
-
moduleGraphs.set(name, moduleGraph);
|
|
2634
|
-
allDiagnostics.push(...diagnostics);
|
|
2635
|
-
allRuleErrors.push(...ruleErrors);
|
|
2636
|
-
totalFiles +=
|
|
2714
|
+
moduleGraphs.set(entry.name, entry.moduleGraph);
|
|
2715
|
+
allDiagnostics.push(...entry.diagnostics);
|
|
2716
|
+
allRuleErrors.push(...entry.ruleErrors);
|
|
2717
|
+
totalFiles += entry.result.project.fileCount;
|
|
2637
2718
|
}
|
|
2638
2719
|
const combinedScore = calculateScore(allDiagnostics, totalFiles);
|
|
2639
2720
|
const combinedSummary = buildSummary(allDiagnostics);
|
|
@@ -2758,5 +2839,5 @@ async function diagnoseMonorepo(path, options = {}) {
|
|
|
2758
2839
|
}
|
|
2759
2840
|
|
|
2760
2841
|
//#endregion
|
|
2761
|
-
export { ConfigurationError, NestjsDoctorError, ScanError, ValidationError, diagnose, diagnoseMonorepo, getRules, prepareScan, scanAllFiles, scanFile, scanProject, updateFile };
|
|
2842
|
+
export { ConfigurationError, NestjsDoctorError, ScanError, ValidationError, diagnose, diagnoseMonorepo, getRules, prepareScan, scanAllFiles, scanFile, scanProject, updateFile, updateModuleGraphForFile, updateProvidersForFile };
|
|
2762
2843
|
//# sourceMappingURL=index.mjs.map
|