technical-debt-radar 1.6.0 → 1.6.2

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 +37 -26
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -16282,12 +16282,21 @@ var require_reliability_detector = __commonJS({
16282
16282
  }
16283
16283
  return false;
16284
16284
  }
16285
+ function isNestJSInjectable(classNode) {
16286
+ return classNode.getDecorators().some((d) => d.getName() === "Injectable");
16287
+ }
16285
16288
  function isNestJSController(classNode) {
16286
16289
  return classNode.getDecorators().some((d) => {
16287
16290
  const name = d.getName();
16288
16291
  return name === "Controller" || name === "Resolver";
16289
16292
  });
16290
16293
  }
16294
+ function isInsideNestJSInjectable(node) {
16295
+ const classDecl = node.getFirstAncestorByKind(ts_morph_1.SyntaxKind.ClassDeclaration);
16296
+ if (!classDecl)
16297
+ return false;
16298
+ return isNestJSInjectable(classDecl);
16299
+ }
16291
16300
  function fileImportsNestJS(sourceFile) {
16292
16301
  for (const decl of sourceFile.getImportDeclarations()) {
16293
16302
  const spec = decl.getModuleSpecifierValue();
@@ -16398,6 +16407,8 @@ var require_reliability_detector = __commonJS({
16398
16407
  return;
16399
16408
  if (isNestJSControllerMethod(node, sourceFile))
16400
16409
  return;
16410
+ if (fileImportsNestJS(sourceFile) && isInsideNestJSInjectable(node))
16411
+ return;
16401
16412
  if (functionHasTryCatch(fn.node))
16402
16413
  return;
16403
16414
  const isRisky = isRiskyAwaitCall(node);
@@ -16586,39 +16597,39 @@ var require_reliability_detector = __commonJS({
16586
16597
  continue;
16587
16598
  if (isNestJSControllerMethod(fn.node, _sourceFile))
16588
16599
  continue;
16589
- let hasAwait = false;
16590
- fn.node.forEachDescendant((child) => {
16591
- if (ts_morph_1.Node.isAwaitExpression(child))
16592
- hasAwait = true;
16593
- });
16594
- if (!hasAwait)
16595
- continue;
16596
16600
  const body = fn.node.getBody();
16597
16601
  if (!body || !ts_morph_1.Node.isBlock(body))
16598
16602
  continue;
16599
- const hasTryAtTop = body.getStatements().some((s) => ts_morph_1.Node.isTryStatement(s));
16600
- if (hasTryAtTop)
16601
- continue;
16602
- let hasTryNested = false;
16603
- body.forEachDescendant((child) => {
16604
- if (hasTryNested)
16605
- return;
16603
+ let unhandledAwaitCount = 0;
16604
+ let totalAwaitCount = 0;
16605
+ fn.node.forEachDescendant((child) => {
16606
16606
  if (child !== fn.node && (ts_morph_1.Node.isFunctionDeclaration(child) || ts_morph_1.Node.isMethodDeclaration(child) || ts_morph_1.Node.isArrowFunction(child) || ts_morph_1.Node.isFunctionExpression(child)))
16607
16607
  return;
16608
- if (ts_morph_1.Node.isTryStatement(child))
16609
- hasTryNested = true;
16610
- });
16611
- if (hasTryNested)
16612
- continue;
16613
- let awaitCount = 0;
16614
- fn.node.forEachDescendant((child) => {
16615
- if (ts_morph_1.Node.isFunctionDeclaration(child) || ts_morph_1.Node.isMethodDeclaration(child) || ts_morph_1.Node.isArrowFunction(child) || ts_morph_1.Node.isFunctionExpression(child)) {
16616
- if (child !== fn.node)
16617
- return;
16608
+ if (!ts_morph_1.Node.isAwaitExpression(child))
16609
+ return;
16610
+ totalAwaitCount++;
16611
+ let current = child.getParent();
16612
+ let isHandled = false;
16613
+ while (current && current !== fn.node) {
16614
+ if (ts_morph_1.Node.isTryStatement(current)) {
16615
+ const tryBlock = current.getTryBlock();
16616
+ if (tryBlock && child.getPos() >= tryBlock.getPos() && child.getEnd() <= tryBlock.getEnd()) {
16617
+ isHandled = true;
16618
+ }
16619
+ break;
16620
+ }
16621
+ if (ts_morph_1.Node.isFunctionDeclaration(current) || ts_morph_1.Node.isMethodDeclaration(current) || ts_morph_1.Node.isArrowFunction(current) || ts_morph_1.Node.isFunctionExpression(current))
16622
+ break;
16623
+ current = current.getParent();
16618
16624
  }
16619
- if (ts_morph_1.Node.isAwaitExpression(child))
16620
- awaitCount++;
16625
+ if (!isHandled)
16626
+ unhandledAwaitCount++;
16621
16627
  });
16628
+ if (totalAwaitCount === 0)
16629
+ continue;
16630
+ if (unhandledAwaitCount === 0)
16631
+ continue;
16632
+ const awaitCount = unhandledAwaitCount;
16622
16633
  if (awaitCount < 2)
16623
16634
  continue;
16624
16635
  violations.push(makeViolation(shared_1.RELIABILITY_RULES.MISSING_TRY_CATCH, filePath, fn.node.getStartLineNumber(), `Async function '${fn.name}' has multiple awaits but no try/catch`, policy, fn.name, "Add try/catch around the async operations or use an error-handling wrapper"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "technical-debt-radar",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
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",