technical-debt-radar 1.8.0 → 1.9.0
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/dist/index.js +59 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13176,6 +13176,9 @@ var require_boundary_checker = __commonJS({
|
|
|
13176
13176
|
const filePath = file.path;
|
|
13177
13177
|
const sourceModule = findModuleForFile(filePath, policy);
|
|
13178
13178
|
if (!sourceModule) {
|
|
13179
|
+
if (isNestJSFramework(policy)) {
|
|
13180
|
+
checkSharedFileImports(sourceFile, filePath, policy, input, violations);
|
|
13181
|
+
}
|
|
13179
13182
|
project.removeSourceFile(sourceFile);
|
|
13180
13183
|
continue;
|
|
13181
13184
|
}
|
|
@@ -13463,6 +13466,9 @@ var require_boundary_checker = __commonJS({
|
|
|
13463
13466
|
return "src/" + specifier.slice(2);
|
|
13464
13467
|
if (specifier.startsWith("~/"))
|
|
13465
13468
|
return "src/" + specifier.slice(2);
|
|
13469
|
+
if (specifier.startsWith("src/") || specifier.startsWith("lib/") || specifier.startsWith("app/")) {
|
|
13470
|
+
return specifier;
|
|
13471
|
+
}
|
|
13466
13472
|
return void 0;
|
|
13467
13473
|
}
|
|
13468
13474
|
function _resetPathAliasCache() {
|
|
@@ -13579,6 +13585,53 @@ var require_boundary_checker = __commonJS({
|
|
|
13579
13585
|
function _resetModuleParsingCache() {
|
|
13580
13586
|
_cachedModuleParsing = void 0;
|
|
13581
13587
|
}
|
|
13588
|
+
function checkSharedFileImports(sourceFile, filePath, policy, input, violations) {
|
|
13589
|
+
const basename2 = filePath.replace(/^.*\//, "");
|
|
13590
|
+
if (/^(main|cli|bootstrap|server)\.(ts|js)$/.test(basename2))
|
|
13591
|
+
return;
|
|
13592
|
+
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
13593
|
+
const isSharedTypeFile = /\/(interfaces|types|shared|common|contracts)\//i.test(normalizedPath);
|
|
13594
|
+
if (!isSharedTypeFile)
|
|
13595
|
+
return;
|
|
13596
|
+
for (const decl of sourceFile.getImportDeclarations()) {
|
|
13597
|
+
const specifier = decl.getModuleSpecifierValue();
|
|
13598
|
+
const line = decl.getStartLineNumber();
|
|
13599
|
+
let resolvedTarget;
|
|
13600
|
+
if (specifier.startsWith(".") || specifier.startsWith("/")) {
|
|
13601
|
+
const sourceDir = filePath.replace(/\/[^/]+$/, "");
|
|
13602
|
+
resolvedTarget = resolveRelativePath(sourceDir, specifier);
|
|
13603
|
+
} else {
|
|
13604
|
+
resolvedTarget = resolvePathAliasForBoundary(specifier, input);
|
|
13605
|
+
}
|
|
13606
|
+
if (!resolvedTarget)
|
|
13607
|
+
continue;
|
|
13608
|
+
const targetModule = findModuleForFile(resolvedTarget, policy);
|
|
13609
|
+
if (!targetModule)
|
|
13610
|
+
continue;
|
|
13611
|
+
if (/\.module\.(ts|js)$/.test(resolvedTarget))
|
|
13612
|
+
continue;
|
|
13613
|
+
const targetBasename = resolvedTarget.replace(/^.*\//, "");
|
|
13614
|
+
if (/\.(interface|dto|enum|types?)\.(ts|js)$/.test(targetBasename))
|
|
13615
|
+
continue;
|
|
13616
|
+
if (decl.isTypeOnly())
|
|
13617
|
+
continue;
|
|
13618
|
+
violations.push({
|
|
13619
|
+
category: "architecture",
|
|
13620
|
+
type: "module-boundary-violation",
|
|
13621
|
+
ruleId: shared_1.ARCHITECTURE_RULES.MODULE_BOUNDARY,
|
|
13622
|
+
severity: "critical",
|
|
13623
|
+
source: "deterministic",
|
|
13624
|
+
confidence: "high",
|
|
13625
|
+
file: filePath,
|
|
13626
|
+
line,
|
|
13627
|
+
module: "shared",
|
|
13628
|
+
message: `Shared file imports from "${targetModule}" module \u2014 shared files should not depend on feature modules (${filePath})`,
|
|
13629
|
+
explanation: `Shared/interfaces files should contain plain types, not dependencies on feature module internals.`,
|
|
13630
|
+
debtPoints: 5,
|
|
13631
|
+
gateAction: "block"
|
|
13632
|
+
});
|
|
13633
|
+
}
|
|
13634
|
+
}
|
|
13582
13635
|
function normalizeForMatching(filePath) {
|
|
13583
13636
|
let normalized = filePath.replace(/\\/g, "/");
|
|
13584
13637
|
if (normalized.startsWith("/")) {
|
|
@@ -18864,7 +18917,7 @@ var require_dead_code_detector = __commonJS({
|
|
|
18864
18917
|
const sf = sourceFiles.get(filePath);
|
|
18865
18918
|
if (sf && exp.type === "class" && isNestJSDIRegistered(sf, exp.name))
|
|
18866
18919
|
continue;
|
|
18867
|
-
if (sf && isReferencedInOwnFile(sf, exp.name))
|
|
18920
|
+
if (sf && !isTypeExport(exp.type) && isReferencedInOwnFile(sf, exp.name))
|
|
18868
18921
|
continue;
|
|
18869
18922
|
unusedExports.push({
|
|
18870
18923
|
export: exp,
|
|
@@ -19221,6 +19274,8 @@ var require_dead_code_detector = __commonJS({
|
|
|
19221
19274
|
for (const ext of extensions) {
|
|
19222
19275
|
if (fp.endsWith(suffix + ext))
|
|
19223
19276
|
return normalizeFilePath(fp);
|
|
19277
|
+
if (fp.endsWith(suffix + "/index" + ext))
|
|
19278
|
+
return normalizeFilePath(fp);
|
|
19224
19279
|
}
|
|
19225
19280
|
}
|
|
19226
19281
|
return void 0;
|
|
@@ -19337,8 +19392,9 @@ var require_dead_code_detector = __commonJS({
|
|
|
19337
19392
|
}
|
|
19338
19393
|
if (!hasExternalCall) {
|
|
19339
19394
|
const ownText = allFileTexts.get(filePath) ?? "";
|
|
19340
|
-
const
|
|
19341
|
-
const
|
|
19395
|
+
const selfCallPattern = new RegExp(`this\\.${methodName}\\s*\\(`, "g");
|
|
19396
|
+
const selfCallMatches = ownText.match(selfCallPattern);
|
|
19397
|
+
const internalCallCount = selfCallMatches?.length ?? 0;
|
|
19342
19398
|
if (internalCallCount === 0) {
|
|
19343
19399
|
violations.push({
|
|
19344
19400
|
category: "maintainability",
|