technical-debt-radar 1.0.5 → 1.0.7

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 +47 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -17735,14 +17735,15 @@ var require_dead_code_detector = __commonJS({
17735
17735
  excludeTypes: true,
17736
17736
  severity: "info"
17737
17737
  };
17738
- async function detectDeadCode(input, config = {}) {
17738
+ async function detectDeadCode(input, config = {}, projectRoot) {
17739
17739
  const cfg = { ...DEFAULT_CONFIG, ...config };
17740
17740
  if (!cfg.enabled) {
17741
17741
  return emptyResult();
17742
17742
  }
17743
17743
  const project = createProject(input);
17744
17744
  const sourceFiles = /* @__PURE__ */ new Map();
17745
- const { aliases } = parsePathAliases(input);
17745
+ const effectiveRoot = projectRoot ?? input.projectRoot;
17746
+ const { aliases } = parsePathAliases(input, effectiveRoot);
17746
17747
  for (const sf of project.getSourceFiles()) {
17747
17748
  const filePath = normalizeFilePath(sf.getFilePath());
17748
17749
  sourceFiles.set(filePath, sf);
@@ -17803,6 +17804,8 @@ var require_dead_code_detector = __commonJS({
17803
17804
  const sf = sourceFiles.get(filePath);
17804
17805
  if (sf && exp.type === "class" && isNestJSDIRegistered(sf, exp.name))
17805
17806
  continue;
17807
+ if (sf && isReferencedInOwnFile(sf, exp.name))
17808
+ continue;
17806
17809
  unusedExports.push({
17807
17810
  export: exp,
17808
17811
  file: filePath,
@@ -17984,18 +17987,46 @@ var require_dead_code_detector = __commonJS({
17984
17987
  function isTypeExport(type) {
17985
17988
  return type === "type" || type === "interface" || type === "enum";
17986
17989
  }
17987
- function parsePathAliases(input) {
17990
+ function isReferencedInOwnFile(sourceFile, exportName) {
17991
+ const identifiers = sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.Identifier).filter((id) => id.getText() === exportName);
17992
+ let declarationCount = 0;
17993
+ let totalCount = 0;
17994
+ for (const id of identifiers) {
17995
+ totalCount++;
17996
+ const parent = id.getParent();
17997
+ if (!parent)
17998
+ continue;
17999
+ const parentKind = parent.getKind();
18000
+ if (parentKind === ts_morph_1.SyntaxKind.ClassDeclaration || parentKind === ts_morph_1.SyntaxKind.FunctionDeclaration || parentKind === ts_morph_1.SyntaxKind.VariableDeclaration || parentKind === ts_morph_1.SyntaxKind.EnumDeclaration || parentKind === ts_morph_1.SyntaxKind.InterfaceDeclaration || parentKind === ts_morph_1.SyntaxKind.TypeAliasDeclaration) {
18001
+ const nameNode = parent.getNameNode?.();
18002
+ if (nameNode && nameNode.getPos() === id.getPos()) {
18003
+ declarationCount++;
18004
+ continue;
18005
+ }
18006
+ }
18007
+ if (parentKind === ts_morph_1.SyntaxKind.ExportSpecifier) {
18008
+ declarationCount++;
18009
+ continue;
18010
+ }
18011
+ }
18012
+ return totalCount > declarationCount;
18013
+ }
18014
+ function parsePathAliases(input, projectRoot) {
17988
18015
  let tsconfigContent;
17989
18016
  const tsconfigFile = input.changedFiles.find((f) => f.status !== "deleted" && /tsconfig(?:\.build)?\.json$/.test(f.path));
17990
18017
  if (tsconfigFile) {
17991
18018
  tsconfigContent = tsconfigFile.content;
17992
18019
  }
17993
- if (!tsconfigContent && input.projectRoot) {
18020
+ const root = projectRoot ?? input.projectRoot;
18021
+ if (!tsconfigContent && root) {
17994
18022
  try {
17995
18023
  const fs9 = require("fs");
17996
- const tsconfigPath = path9.join(input.projectRoot, "tsconfig.json");
17997
- if (fs9.existsSync(tsconfigPath)) {
17998
- tsconfigContent = fs9.readFileSync(tsconfigPath, "utf-8");
18024
+ for (const name of ["tsconfig.json", "tsconfig.build.json"]) {
18025
+ const tsconfigPath = path9.join(root, name);
18026
+ if (fs9.existsSync(tsconfigPath)) {
18027
+ tsconfigContent = fs9.readFileSync(tsconfigPath, "utf-8");
18028
+ break;
18029
+ }
17999
18030
  }
18000
18031
  } catch {
18001
18032
  }
@@ -18007,7 +18038,8 @@ var require_dead_code_detector = __commonJS({
18007
18038
  const stripped = tsconfigContent.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/,\s*([}\]])/g, "$1");
18008
18039
  const tsconfig = JSON.parse(stripped);
18009
18040
  const compilerOptions = tsconfig.compilerOptions ?? {};
18010
- const baseUrl = compilerOptions.baseUrl ?? ".";
18041
+ const rawBaseUrl = (compilerOptions.baseUrl ?? ".").replace(/\/+$/, "");
18042
+ const baseUrl = rawBaseUrl === "" ? "." : rawBaseUrl;
18011
18043
  const paths = compilerOptions.paths ?? {};
18012
18044
  const aliases = [];
18013
18045
  for (const [pattern, targets] of Object.entries(paths)) {
@@ -18090,8 +18122,13 @@ var require_dead_code_detector = __commonJS({
18090
18122
  return resolveInProject(resolved, project) ?? resolved;
18091
18123
  }
18092
18124
  if (aliases.length > 0) {
18093
- return resolvePathAlias(specifier, aliases, project);
18125
+ const aliasResolved = resolvePathAlias(specifier, aliases, project);
18126
+ if (aliasResolved)
18127
+ return aliasResolved;
18094
18128
  }
18129
+ const directResolved = resolveInProject(specifier, project);
18130
+ if (directResolved)
18131
+ return directResolved;
18095
18132
  return void 0;
18096
18133
  }
18097
18134
  function resolveInProject(resolved, project) {
@@ -18538,7 +18575,7 @@ var require_orchestrator = __commonJS({
18538
18575
  (0, reliability_detector_1.detectReliabilityIssues)(filteredInput, policy),
18539
18576
  (0, duplication_detector_1.detectDuplication)(filteredInput),
18540
18577
  projectRoot ? (0, missing_tests_detector_1.detectMissingTests)(filteredInput, projectRoot) : Promise.resolve(null),
18541
- (0, dead_code_detector_1.detectDeadCode)(filteredInput),
18578
+ (0, dead_code_detector_1.detectDeadCode)(filteredInput, {}, projectRoot),
18542
18579
  projectRoot ? Promise.resolve((0, coverage_delta_detector_1.detectCoverageDelta)(projectRoot)) : Promise.resolve(null)
18543
18580
  ]);
18544
18581
  const runtimeViolations = runtimeResult.violations;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "technical-debt-radar",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
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",