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.
Files changed (2) hide show
  1. package/dist/index.js +59 -3
  2. 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 matches = ownText.match(new RegExp(`\\.${methodName}\\s*\\(`, "g"));
19341
- const internalCallCount = matches?.length ?? 0;
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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "technical-debt-radar",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "Stop Node.js production crashes before merge. 47 detection patterns across 5 categories.",
5
5
  "bin": {
6
6
  "radar": "dist/index.js",