@opensip-cli/checks-typescript 0.1.10 → 0.1.11

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 (244) hide show
  1. package/README.md +4 -2
  2. package/dist/__tests__/all-checks-execute.test.d.ts.map +1 -1
  3. package/dist/__tests__/all-checks-execute.test.js +0 -1
  4. package/dist/__tests__/all-checks-execute.test.js.map +1 -1
  5. package/dist/__tests__/behavior-fixtures-2.test.d.ts.map +1 -1
  6. package/dist/__tests__/behavior-fixtures-2.test.js +0 -1
  7. package/dist/__tests__/behavior-fixtures-2.test.js.map +1 -1
  8. package/dist/__tests__/behavior-fixtures-3.test.d.ts.map +1 -1
  9. package/dist/__tests__/behavior-fixtures-3.test.js +0 -1
  10. package/dist/__tests__/behavior-fixtures-3.test.js.map +1 -1
  11. package/dist/__tests__/behavior-fixtures-4.test.d.ts.map +1 -1
  12. package/dist/__tests__/behavior-fixtures-4.test.js +0 -1
  13. package/dist/__tests__/behavior-fixtures-4.test.js.map +1 -1
  14. package/dist/__tests__/behavior-fixtures-5.test.d.ts.map +1 -1
  15. package/dist/__tests__/behavior-fixtures-5.test.js +0 -1
  16. package/dist/__tests__/behavior-fixtures-5.test.js.map +1 -1
  17. package/dist/__tests__/behavior-fixtures-6.test.js +10 -0
  18. package/dist/__tests__/behavior-fixtures-6.test.js.map +1 -1
  19. package/dist/__tests__/behavior-fixtures.test.d.ts.map +1 -1
  20. package/dist/__tests__/behavior-fixtures.test.js +2 -4
  21. package/dist/__tests__/behavior-fixtures.test.js.map +1 -1
  22. package/dist/__tests__/branch-fixtures-2.test.d.ts.map +1 -1
  23. package/dist/__tests__/branch-fixtures-2.test.js +0 -1
  24. package/dist/__tests__/branch-fixtures-2.test.js.map +1 -1
  25. package/dist/__tests__/branch-fixtures-3.test.d.ts.map +1 -1
  26. package/dist/__tests__/branch-fixtures-3.test.js +0 -1
  27. package/dist/__tests__/branch-fixtures-3.test.js.map +1 -1
  28. package/dist/__tests__/branch-fixtures.test.d.ts.map +1 -1
  29. package/dist/__tests__/branch-fixtures.test.js +0 -1
  30. package/dist/__tests__/branch-fixtures.test.js.map +1 -1
  31. package/dist/checks/architecture/__tests__/live-view-through-cli-live.test.d.ts +2 -0
  32. package/dist/checks/architecture/__tests__/live-view-through-cli-live.test.d.ts.map +1 -0
  33. package/dist/checks/architecture/__tests__/live-view-through-cli-live.test.js +13 -0
  34. package/dist/checks/architecture/__tests__/live-view-through-cli-live.test.js.map +1 -0
  35. package/dist/checks/architecture/contracts-schema-consistency.d.ts.map +1 -1
  36. package/dist/checks/architecture/contracts-schema-consistency.js +0 -3
  37. package/dist/checks/architecture/contracts-schema-consistency.js.map +1 -1
  38. package/dist/checks/architecture/drizzle-orm-migration-guardrails.d.ts.map +1 -1
  39. package/dist/checks/architecture/drizzle-orm-migration-guardrails.js +1 -0
  40. package/dist/checks/architecture/drizzle-orm-migration-guardrails.js.map +1 -1
  41. package/dist/checks/architecture/index.d.ts +1 -0
  42. package/dist/checks/architecture/index.d.ts.map +1 -1
  43. package/dist/checks/architecture/index.js +1 -0
  44. package/dist/checks/architecture/index.js.map +1 -1
  45. package/dist/checks/architecture/live-view-through-cli-live.d.ts +8 -0
  46. package/dist/checks/architecture/live-view-through-cli-live.d.ts.map +1 -0
  47. package/dist/checks/architecture/live-view-through-cli-live.js +43 -0
  48. package/dist/checks/architecture/live-view-through-cli-live.js.map +1 -0
  49. package/dist/checks/architecture/missing-type-exports.d.ts.map +1 -1
  50. package/dist/checks/architecture/missing-type-exports.js +1 -1
  51. package/dist/checks/architecture/missing-type-exports.js.map +1 -1
  52. package/dist/checks/architecture/module-coupling-fan-out.d.ts.map +1 -1
  53. package/dist/checks/architecture/module-coupling-fan-out.js +6 -2
  54. package/dist/checks/architecture/module-coupling-fan-out.js.map +1 -1
  55. package/dist/checks/architecture/no-bootstrap-tool-import.d.ts.map +1 -1
  56. package/dist/checks/architecture/no-bootstrap-tool-import.js +1 -0
  57. package/dist/checks/architecture/no-bootstrap-tool-import.js.map +1 -1
  58. package/dist/checks/architecture/no-run-done-result.d.ts.map +1 -1
  59. package/dist/checks/architecture/no-run-done-result.js +1 -0
  60. package/dist/checks/architecture/no-run-done-result.js.map +1 -1
  61. package/dist/checks/architecture/package-json-exports-field.d.ts.map +1 -1
  62. package/dist/checks/architecture/package-json-exports-field.js +1 -1
  63. package/dist/checks/architecture/package-json-exports-field.js.map +1 -1
  64. package/dist/checks/architecture/phantom-dependency-detection.d.ts.map +1 -1
  65. package/dist/checks/architecture/phantom-dependency-detection.js +0 -3
  66. package/dist/checks/architecture/phantom-dependency-detection.js.map +1 -1
  67. package/dist/checks/architecture/tsconfig-extends-validation.d.ts.map +1 -1
  68. package/dist/checks/architecture/tsconfig-extends-validation.js +0 -2
  69. package/dist/checks/architecture/tsconfig-extends-validation.js.map +1 -1
  70. package/dist/checks/quality/code-structure/__tests__/duplicate-utility-lang-substrate.test.d.ts +5 -0
  71. package/dist/checks/quality/code-structure/__tests__/duplicate-utility-lang-substrate.test.d.ts.map +1 -0
  72. package/dist/checks/quality/code-structure/__tests__/duplicate-utility-lang-substrate.test.js +17 -0
  73. package/dist/checks/quality/code-structure/__tests__/duplicate-utility-lang-substrate.test.js.map +1 -0
  74. package/dist/checks/quality/code-structure/duplicate-utility-functions-config.d.ts +18 -0
  75. package/dist/checks/quality/code-structure/duplicate-utility-functions-config.d.ts.map +1 -0
  76. package/dist/checks/quality/code-structure/duplicate-utility-functions-config.js +36 -0
  77. package/dist/checks/quality/code-structure/duplicate-utility-functions-config.js.map +1 -0
  78. package/dist/checks/quality/code-structure/duplicate-utility-functions-helpers.d.ts +15 -0
  79. package/dist/checks/quality/code-structure/duplicate-utility-functions-helpers.d.ts.map +1 -0
  80. package/dist/checks/quality/code-structure/duplicate-utility-functions-helpers.js +288 -0
  81. package/dist/checks/quality/code-structure/duplicate-utility-functions-helpers.js.map +1 -0
  82. package/dist/checks/quality/code-structure/duplicate-utility-functions.d.ts +1 -26
  83. package/dist/checks/quality/code-structure/duplicate-utility-functions.d.ts.map +1 -1
  84. package/dist/checks/quality/code-structure/duplicate-utility-functions.js +3 -407
  85. package/dist/checks/quality/code-structure/duplicate-utility-functions.js.map +1 -1
  86. package/dist/checks/quality/data-integrity/__tests__/null-safety-fp.test.js +39 -2
  87. package/dist/checks/quality/data-integrity/__tests__/null-safety-fp.test.js.map +1 -1
  88. package/dist/checks/quality/data-integrity/array-validation-detectors.d.ts +17 -0
  89. package/dist/checks/quality/data-integrity/array-validation-detectors.d.ts.map +1 -0
  90. package/dist/checks/quality/data-integrity/array-validation-detectors.js +184 -0
  91. package/dist/checks/quality/data-integrity/array-validation-detectors.js.map +1 -0
  92. package/dist/checks/quality/data-integrity/array-validation.d.ts +0 -2
  93. package/dist/checks/quality/data-integrity/array-validation.d.ts.map +1 -1
  94. package/dist/checks/quality/data-integrity/array-validation.js +2 -360
  95. package/dist/checks/quality/data-integrity/array-validation.js.map +1 -1
  96. package/dist/checks/quality/data-integrity/database-schema-validation.d.ts.map +1 -1
  97. package/dist/checks/quality/data-integrity/database-schema-validation.js +0 -1
  98. package/dist/checks/quality/data-integrity/database-schema-validation.js.map +1 -1
  99. package/dist/checks/quality/data-integrity/null-safety-analyze.d.ts +33 -0
  100. package/dist/checks/quality/data-integrity/null-safety-analyze.d.ts.map +1 -0
  101. package/dist/checks/quality/data-integrity/null-safety-analyze.js +164 -0
  102. package/dist/checks/quality/data-integrity/null-safety-analyze.js.map +1 -0
  103. package/dist/checks/quality/data-integrity/null-safety-config.d.ts +50 -0
  104. package/dist/checks/quality/data-integrity/null-safety-config.d.ts.map +1 -0
  105. package/dist/checks/quality/data-integrity/null-safety-config.js +69 -0
  106. package/dist/checks/quality/data-integrity/null-safety-config.js.map +1 -0
  107. package/dist/checks/quality/data-integrity/null-safety-heuristics.d.ts +76 -0
  108. package/dist/checks/quality/data-integrity/null-safety-heuristics.d.ts.map +1 -0
  109. package/dist/checks/quality/data-integrity/null-safety-heuristics.js +276 -0
  110. package/dist/checks/quality/data-integrity/null-safety-heuristics.js.map +1 -0
  111. package/dist/checks/quality/data-integrity/null-safety-prefixes.d.ts +13 -0
  112. package/dist/checks/quality/data-integrity/null-safety-prefixes.d.ts.map +1 -0
  113. package/dist/checks/quality/data-integrity/null-safety-prefixes.js +333 -0
  114. package/dist/checks/quality/data-integrity/null-safety-prefixes.js.map +1 -0
  115. package/dist/checks/quality/data-integrity/null-safety.d.ts +2 -82
  116. package/dist/checks/quality/data-integrity/null-safety.d.ts.map +1 -1
  117. package/dist/checks/quality/data-integrity/null-safety.js +3 -796
  118. package/dist/checks/quality/data-integrity/null-safety.js.map +1 -1
  119. package/dist/checks/quality/frontend/test-only-frontend-modules.d.ts.map +1 -1
  120. package/dist/checks/quality/frontend/test-only-frontend-modules.js +0 -2
  121. package/dist/checks/quality/frontend/test-only-frontend-modules.js.map +1 -1
  122. package/dist/checks/quality/linting/typescript-frontend.d.ts.map +1 -1
  123. package/dist/checks/quality/linting/typescript-frontend.js +1 -0
  124. package/dist/checks/quality/linting/typescript-frontend.js.map +1 -1
  125. package/dist/checks/quality/observability/logger-event-name-format.d.ts.map +1 -1
  126. package/dist/checks/quality/observability/logger-event-name-format.js +0 -1
  127. package/dist/checks/quality/observability/logger-event-name-format.js.map +1 -1
  128. package/dist/checks/quality/observability/no-hardcoded-correlation-id.d.ts.map +1 -1
  129. package/dist/checks/quality/observability/no-hardcoded-correlation-id.js +2 -3
  130. package/dist/checks/quality/observability/no-hardcoded-correlation-id.js.map +1 -1
  131. package/dist/checks/quality/patterns/__tests__/async-waterfall-sequential.test.d.ts +8 -0
  132. package/dist/checks/quality/patterns/__tests__/async-waterfall-sequential.test.d.ts.map +1 -0
  133. package/dist/checks/quality/patterns/__tests__/async-waterfall-sequential.test.js +87 -0
  134. package/dist/checks/quality/patterns/__tests__/async-waterfall-sequential.test.js.map +1 -0
  135. package/dist/checks/quality/patterns/__tests__/error-handling-probes.test.d.ts +2 -0
  136. package/dist/checks/quality/patterns/__tests__/error-handling-probes.test.d.ts.map +1 -0
  137. package/dist/checks/quality/patterns/__tests__/error-handling-probes.test.js +51 -0
  138. package/dist/checks/quality/patterns/__tests__/error-handling-probes.test.js.map +1 -0
  139. package/dist/checks/quality/patterns/__tests__/result-pattern-registration-guards.test.d.ts +2 -0
  140. package/dist/checks/quality/patterns/__tests__/result-pattern-registration-guards.test.d.ts.map +1 -0
  141. package/dist/checks/quality/patterns/__tests__/result-pattern-registration-guards.test.js +89 -0
  142. package/dist/checks/quality/patterns/__tests__/result-pattern-registration-guards.test.js.map +1 -0
  143. package/dist/checks/quality/patterns/__tests__/throws-documentation-analyze.test.d.ts +5 -0
  144. package/dist/checks/quality/patterns/__tests__/throws-documentation-analyze.test.d.ts.map +1 -0
  145. package/dist/checks/quality/patterns/__tests__/throws-documentation-analyze.test.js +78 -0
  146. package/dist/checks/quality/patterns/__tests__/throws-documentation-analyze.test.js.map +1 -0
  147. package/dist/checks/quality/patterns/__tests__/toctou-fp.test.js +44 -0
  148. package/dist/checks/quality/patterns/__tests__/toctou-fp.test.js.map +1 -1
  149. package/dist/checks/quality/patterns/async-waterfall-analysis.d.ts +17 -0
  150. package/dist/checks/quality/patterns/async-waterfall-analysis.d.ts.map +1 -0
  151. package/dist/checks/quality/patterns/async-waterfall-analysis.js +215 -0
  152. package/dist/checks/quality/patterns/async-waterfall-analysis.js.map +1 -0
  153. package/dist/checks/quality/patterns/async-waterfall-branch-keys.d.ts +6 -0
  154. package/dist/checks/quality/patterns/async-waterfall-branch-keys.d.ts.map +1 -0
  155. package/dist/checks/quality/patterns/async-waterfall-branch-keys.js +54 -0
  156. package/dist/checks/quality/patterns/async-waterfall-branch-keys.js.map +1 -0
  157. package/dist/checks/quality/patterns/async-waterfall-detection.d.ts.map +1 -1
  158. package/dist/checks/quality/patterns/async-waterfall-detection.js +3 -352
  159. package/dist/checks/quality/patterns/async-waterfall-detection.js.map +1 -1
  160. package/dist/checks/quality/patterns/containing-function-name.d.ts +3 -0
  161. package/dist/checks/quality/patterns/containing-function-name.d.ts.map +1 -0
  162. package/dist/checks/quality/patterns/containing-function-name.js +21 -0
  163. package/dist/checks/quality/patterns/containing-function-name.js.map +1 -0
  164. package/dist/checks/quality/patterns/error-handling-quality.d.ts +3 -0
  165. package/dist/checks/quality/patterns/error-handling-quality.d.ts.map +1 -1
  166. package/dist/checks/quality/patterns/error-handling-quality.js +150 -30
  167. package/dist/checks/quality/patterns/error-handling-quality.js.map +1 -1
  168. package/dist/checks/quality/patterns/result-pattern-consistency.d.ts +3 -0
  169. package/dist/checks/quality/patterns/result-pattern-consistency.d.ts.map +1 -1
  170. package/dist/checks/quality/patterns/result-pattern-consistency.js +136 -69
  171. package/dist/checks/quality/patterns/result-pattern-consistency.js.map +1 -1
  172. package/dist/checks/quality/patterns/throws-documentation-analyze.d.ts +14 -0
  173. package/dist/checks/quality/patterns/throws-documentation-analyze.d.ts.map +1 -0
  174. package/dist/checks/quality/patterns/throws-documentation-analyze.js +352 -0
  175. package/dist/checks/quality/patterns/throws-documentation-analyze.js.map +1 -0
  176. package/dist/checks/quality/patterns/throws-documentation-constants.d.ts +15 -0
  177. package/dist/checks/quality/patterns/throws-documentation-constants.d.ts.map +1 -0
  178. package/dist/checks/quality/patterns/throws-documentation-constants.js +94 -0
  179. package/dist/checks/quality/patterns/throws-documentation-constants.js.map +1 -0
  180. package/dist/checks/quality/patterns/throws-documentation.d.ts +1 -11
  181. package/dist/checks/quality/patterns/throws-documentation.d.ts.map +1 -1
  182. package/dist/checks/quality/patterns/throws-documentation.js +4 -472
  183. package/dist/checks/quality/patterns/throws-documentation.js.map +1 -1
  184. package/dist/checks/quality/patterns/toctou-race-condition-classify.d.ts +23 -0
  185. package/dist/checks/quality/patterns/toctou-race-condition-classify.d.ts.map +1 -0
  186. package/dist/checks/quality/patterns/toctou-race-condition-classify.js +125 -0
  187. package/dist/checks/quality/patterns/toctou-race-condition-classify.js.map +1 -0
  188. package/dist/checks/quality/patterns/toctou-race-condition-collection.d.ts +24 -0
  189. package/dist/checks/quality/patterns/toctou-race-condition-collection.d.ts.map +1 -0
  190. package/dist/checks/quality/patterns/toctou-race-condition-collection.js +248 -0
  191. package/dist/checks/quality/patterns/toctou-race-condition-collection.js.map +1 -0
  192. package/dist/checks/quality/patterns/toctou-race-condition-constants.d.ts +32 -0
  193. package/dist/checks/quality/patterns/toctou-race-condition-constants.d.ts.map +1 -0
  194. package/dist/checks/quality/patterns/toctou-race-condition-constants.js +115 -0
  195. package/dist/checks/quality/patterns/toctou-race-condition-constants.js.map +1 -0
  196. package/dist/checks/quality/patterns/toctou-race-condition.d.ts +1 -29
  197. package/dist/checks/quality/patterns/toctou-race-condition.d.ts.map +1 -1
  198. package/dist/checks/quality/patterns/toctou-race-condition.js +11 -536
  199. package/dist/checks/quality/patterns/toctou-race-condition.js.map +1 -1
  200. package/dist/checks/quality/unused-config-options.d.ts.map +1 -1
  201. package/dist/checks/quality/unused-config-options.js +0 -4
  202. package/dist/checks/quality/unused-config-options.js.map +1 -1
  203. package/dist/checks/resilience/__tests__/detached-promises-sync-detection.test.d.ts +2 -0
  204. package/dist/checks/resilience/__tests__/detached-promises-sync-detection.test.d.ts.map +1 -0
  205. package/dist/checks/resilience/__tests__/detached-promises-sync-detection.test.js +98 -0
  206. package/dist/checks/resilience/__tests__/detached-promises-sync-detection.test.js.map +1 -0
  207. package/dist/checks/resilience/callback-invocation-safe.d.ts.map +1 -1
  208. package/dist/checks/resilience/callback-invocation-safe.js +0 -1
  209. package/dist/checks/resilience/callback-invocation-safe.js.map +1 -1
  210. package/dist/checks/resilience/context-leakage.d.ts.map +1 -1
  211. package/dist/checks/resilience/context-leakage.js +1 -0
  212. package/dist/checks/resilience/context-leakage.js.map +1 -1
  213. package/dist/checks/resilience/detached-promises-detection.d.ts +7 -0
  214. package/dist/checks/resilience/detached-promises-detection.d.ts.map +1 -0
  215. package/dist/checks/resilience/detached-promises-detection.js +228 -0
  216. package/dist/checks/resilience/detached-promises-detection.js.map +1 -0
  217. package/dist/checks/resilience/detached-promises-sync-constants.d.ts +36 -0
  218. package/dist/checks/resilience/detached-promises-sync-constants.d.ts.map +1 -0
  219. package/dist/checks/resilience/detached-promises-sync-constants.js +299 -0
  220. package/dist/checks/resilience/detached-promises-sync-constants.js.map +1 -0
  221. package/dist/checks/resilience/detached-promises-sync-detection.d.ts +14 -0
  222. package/dist/checks/resilience/detached-promises-sync-detection.d.ts.map +1 -0
  223. package/dist/checks/resilience/detached-promises-sync-detection.js +69 -0
  224. package/dist/checks/resilience/detached-promises-sync-detection.js.map +1 -0
  225. package/dist/checks/resilience/detached-promises.d.ts +1 -14
  226. package/dist/checks/resilience/detached-promises.d.ts.map +1 -1
  227. package/dist/checks/resilience/detached-promises.js +2 -598
  228. package/dist/checks/resilience/detached-promises.js.map +1 -1
  229. package/dist/checks/resilience/no-raw-fetch.d.ts.map +1 -1
  230. package/dist/checks/resilience/no-raw-fetch.js +1 -0
  231. package/dist/checks/resilience/no-raw-fetch.js.map +1 -1
  232. package/dist/checks/resilience/no-unbounded-concurrency.d.ts.map +1 -1
  233. package/dist/checks/resilience/no-unbounded-concurrency.js +1 -0
  234. package/dist/checks/resilience/no-unbounded-concurrency.js.map +1 -1
  235. package/dist/checks/security/sql-injection.d.ts.map +1 -1
  236. package/dist/checks/security/sql-injection.js +0 -1
  237. package/dist/checks/security/sql-injection.js.map +1 -1
  238. package/dist/display/architecture.d.ts.map +1 -1
  239. package/dist/display/architecture.js +1 -0
  240. package/dist/display/architecture.js.map +1 -1
  241. package/dist/display/types.d.ts.map +1 -1
  242. package/dist/display/types.js +0 -1
  243. package/dist/display/types.js.map +1 -1
  244. package/package.json +5 -5
@@ -1,5 +1,3 @@
1
- // @fitness-ignore-file file-length-limit -- Complex module with tightly coupled logic; splitting would fragment cohesive functionality
2
- // @fitness-ignore-file null-safety -- null checks are intentional guards
3
1
  /**
4
2
  * @fileoverview Async Waterfall Detection Check
5
3
  *
@@ -13,352 +11,7 @@
13
11
  * - Skips sleep/delay in polling loops
14
12
  */
15
13
  import { defineCheck, isTestFile } from '@opensip-cli/fitness';
16
- import { getSharedSourceFile, isAsync } from '@opensip-cli/lang-typescript';
17
- import * as ts from 'typescript';
18
- /**
19
- * Minimum line gap to consider awaits as consecutive (0 = adjacent lines)
20
- */
21
- const MAX_LINE_GAP = 1;
22
- /**
23
- * Function names that indicate sleep/delay/timer patterns (inherently sequential)
24
- */
25
- const SLEEP_DELAY_NAMES = new Set(['sleep', 'delay', 'wait', 'setTimeout', 'pause']);
26
- /**
27
- * Function names that indicate mutex/lock acquire patterns (inherently sequential)
28
- */
29
- const LOCK_ACQUIRE_NAMES = new Set(['acquire', 'lock', 'runExclusive', 'withLock']);
30
- /**
31
- * Check if a node is an async function (function, method, or arrow function).
32
- *
33
- * Defers the modifier inspection to `lang-typescript`'s canonical `isAsync`
34
- * (modern `canHaveModifiers` + `getModifiers` API); the function-like guard
35
- * stays inline so callers downstream still get the narrowed-via-control-flow
36
- * type for `node` at the call site.
37
- */
38
- function isAsyncFunction(node) {
39
- if (ts.isFunctionDeclaration(node) ||
40
- ts.isMethodDeclaration(node) ||
41
- ts.isArrowFunction(node) ||
42
- ts.isFunctionExpression(node)) {
43
- return isAsync(node);
44
- }
45
- return false;
46
- }
47
- /**
48
- * Check if a node is an if/else branch and return the branch key.
49
- */
50
- function getIfElseBranchKey(current, sourceFile) {
51
- const parentNode = current.parent;
52
- if (!ts.isIfStatement(parentNode))
53
- return null;
54
- const ifLine = sourceFile.getLineAndCharacterOfPosition(parentNode.getStart()).line;
55
- if (current === parentNode.thenStatement)
56
- return `if@L${ifLine}`;
57
- if (current === parentNode.elseStatement)
58
- return `else@L${ifLine}`;
59
- return null;
60
- }
61
- /**
62
- * Check if a node is inside a ternary expression and return the branch key.
63
- */
64
- function getTernaryBranchKey(current, sourceFile) {
65
- const parentNode = current.parent;
66
- /* v8 ignore next -- defensive AST/type guard */
67
- if (!ts.isConditionalExpression(parentNode))
68
- return null;
69
- const condLine = sourceFile.getLineAndCharacterOfPosition(parentNode.getStart()).line;
70
- if (current === parentNode.whenTrue)
71
- return `ternary-true@L${condLine}`;
72
- if (current === parentNode.whenFalse)
73
- return `ternary-false@L${condLine}`;
74
- return null;
75
- }
76
- /**
77
- * Check if a node is a switch case clause and return the branch key.
78
- */
79
- function getSwitchBranchKey(current, sourceFile) {
80
- /* v8 ignore next -- defensive AST/type guard */
81
- if (!ts.isCaseClause(current) && !ts.isDefaultClause(current))
82
- return null;
83
- // @fitness-ignore-next-line null-safety -- CaseClause/DefaultClause parent is CaseBlock, grandparent is SwitchStatement per TS AST spec
84
- const switchStmt = current.parent.parent;
85
- if (!ts.isSwitchStatement(switchStmt))
86
- return null;
87
- const switchLine = sourceFile.getLineAndCharacterOfPosition(switchStmt.getStart()).line;
88
- if (ts.isCaseClause(current)) {
89
- const caseText = current.expression.getText(sourceFile);
90
- return `case-${caseText}@L${switchLine}`;
91
- }
92
- return `default@L${switchLine}`;
93
- }
94
- /**
95
- * Walk up the AST from a node to find if it's inside a conditional branch.
96
- * Returns a branch key like 'if@L42' or 'else@L42' to identify which branch,
97
- * or null if not inside a conditional branch.
98
- *
99
- * Starts at the node itself (not node.parent) so that direct children of
100
- * ternary expressions are correctly identified as branch members. For example,
101
- * in `cond ? await X : await Y`, the AwaitExpression is a direct child of
102
- * the ConditionalExpression. Starting at node.parent would skip past the
103
- * AwaitExpression level and miss the ternary branch detection.
104
- */
105
- function getBranchKey(node, sourceFile, functionNode) {
106
- let current = node;
107
- while (current !== functionNode) {
108
- const ifElseKey = getIfElseBranchKey(current, sourceFile);
109
- if (ifElseKey)
110
- return ifElseKey;
111
- const ternaryKey = getTernaryBranchKey(current, sourceFile);
112
- /* v8 ignore next -- defensive AST/type guard */
113
- if (ternaryKey)
114
- return ternaryKey;
115
- const switchKey = getSwitchBranchKey(current, sourceFile);
116
- /* v8 ignore next -- defensive AST/type guard */
117
- if (switchKey)
118
- return switchKey;
119
- current = current.parent;
120
- }
121
- return null;
122
- }
123
- /**
124
- * Extract individual binding names from a destructuring pattern.
125
- * For `const { foo, bar } = ...` returns ['foo', 'bar'].
126
- * For `const [a, b] = ...` returns ['a', 'b'].
127
- */
128
- function extractDestructuredBindings(pattern, sourceFile) {
129
- const names = [];
130
- // @lazy-ok -- iterating binding elements, not awaiting
131
- for (const element of pattern.elements) {
132
- if (ts.isBindingElement(element)) {
133
- if (ts.isIdentifier(element.name)) {
134
- names.push(element.name.getText(sourceFile));
135
- }
136
- else if (ts.isObjectBindingPattern(element.name) ||
137
- ts.isArrayBindingPattern(element.name)) {
138
- // Nested destructuring: recurse
139
- names.push(...extractDestructuredBindings(element.name, sourceFile));
140
- }
141
- }
142
- }
143
- return names;
144
- }
145
- /**
146
- * Collect all await expressions within an async function (non-recursive into nested async functions)
147
- */
148
- function collectAwaitExpressions(node, sourceFile) {
149
- const awaitInfos = [];
150
- const visit = (n) => {
151
- // Don't recurse into nested async functions
152
- if (n !== node && isAsyncFunction(n)) {
153
- return;
154
- }
155
- if (ts.isAwaitExpression(n)) {
156
- const { line, character } = sourceFile.getLineAndCharacterOfPosition(n.getStart());
157
- const assignedVariable = getAssignedVariable(n, sourceFile);
158
- const destructuredBindings = getDestructuredBindings(n, sourceFile);
159
- const isDynamicImport = isDynamicImportExpression(n);
160
- const branchKey = getBranchKey(n, sourceFile, node);
161
- awaitInfos.push({
162
- line: line + 1, // Convert to 1-indexed
163
- column: character + 1,
164
- assignedVariable,
165
- destructuredBindings,
166
- expressionText: n.getText(sourceFile),
167
- isDynamicImport,
168
- branchKey,
169
- node: n,
170
- });
171
- }
172
- ts.forEachChild(n, visit);
173
- };
174
- ts.forEachChild(node, visit);
175
- return awaitInfos;
176
- }
177
- /**
178
- * Get the variable name if this await is part of a variable declaration or assignment
179
- */
180
- function getAssignedVariable(awaitNode, sourceFile) {
181
- // Check if parent is a variable declaration: const foo = await ...
182
- const parent = awaitNode.parent;
183
- if (ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
184
- return parent.name.getText(sourceFile);
185
- }
186
- // Check for destructuring: const { foo } = await ... or const [foo] = await ...
187
- if (ts.isVariableDeclaration(parent) &&
188
- (ts.isObjectBindingPattern(parent.name) || ts.isArrayBindingPattern(parent.name))) {
189
- // Return a placeholder to indicate there's an assigned variable
190
- return parent.name.getText(sourceFile);
191
- }
192
- // Check for assignment: foo = await ...
193
- if (ts.isBinaryExpression(parent) &&
194
- parent.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
195
- ts.isIdentifier(parent.left)) {
196
- return parent.left.getText(sourceFile);
197
- }
198
- return null;
199
- }
200
- /**
201
- * Get individual binding names from destructured await patterns
202
- */
203
- function getDestructuredBindings(awaitNode, sourceFile) {
204
- const parent = awaitNode.parent;
205
- if (ts.isVariableDeclaration(parent) &&
206
- (ts.isObjectBindingPattern(parent.name) || ts.isArrayBindingPattern(parent.name))) {
207
- return extractDestructuredBindings(parent.name, sourceFile);
208
- }
209
- return [];
210
- }
211
- /**
212
- * Check if an await expression is a dynamic import: `await import('...')`
213
- */
214
- function isDynamicImportExpression(awaitNode) {
215
- const expr = awaitNode.expression;
216
- // import(...) appears as a CallExpression with an ImportKeyword
217
- return ts.isCallExpression(expr) && expr.expression.kind === ts.SyntaxKind.ImportKeyword;
218
- }
219
- /**
220
- * Check if an await expression calls a sleep/delay function
221
- */
222
- function isSleepOrDelay(expressionText) {
223
- const afterAwait = expressionText.replace(/^await\s+/, '');
224
- // Extract the function name from patterns like: sleep(100), this.sleep(100), delay(ms)
225
- // eslint-disable-next-line sonarjs/slow-regex -- `\w+` bounded by `(`; optional `this.` prefix is fixed
226
- const match = /(?:this\.)?(\w+)\s*\(/.exec(afterAwait);
227
- if (match?.[1] !== undefined) {
228
- return SLEEP_DELAY_NAMES.has(match[1]);
229
- }
230
- return false;
231
- }
232
- /**
233
- * Check if an await expression calls a lock/acquire function
234
- */
235
- function isLockAcquire(expressionText) {
236
- const afterAwait = expressionText.replace(/^await\s+/, '');
237
- // Extract the function name from patterns like: this.acquire(), acquire(timeout)
238
- // eslint-disable-next-line sonarjs/slow-regex -- `\w+` bounded by `(`; optional `this.` prefix is fixed
239
- const match = /(?:this\.)?(\w+)\s*\(/.exec(afterAwait);
240
- if (match?.[1] !== undefined) {
241
- return LOCK_ACQUIRE_NAMES.has(match[1]);
242
- }
243
- return false;
244
- }
245
- /**
246
- * Check if the next await references any of the destructured bindings from the current await
247
- */
248
- function nextUsesDestructuredBindings(current, next) {
249
- if (current.destructuredBindings.length === 0) {
250
- return false;
251
- }
252
- return current.destructuredBindings.some((binding) => next.expressionText.includes(binding));
253
- }
254
- /**
255
- * Check whether a pair of consecutive await expressions should be skipped (not flagged).
256
- * Returns true if the pair is NOT a parallelizable waterfall.
257
- */
258
- function shouldSkipAwaitPair(current, next) {
259
- // Skip if awaits are not on consecutive or near-consecutive lines
260
- /* v8 ignore next -- defensive AST/type guard */
261
- if (next.line - current.line > MAX_LINE_GAP + 1)
262
- return true;
263
- // Skip if both awaits are in different branches of a conditional
264
- if (current.branchKey !== null &&
265
- next.branchKey !== null &&
266
- // @fitness-ignore-next-line unsafe-secret-comparison -- Comparing AST branch identifiers, not cryptographic keys
267
- current.branchKey !== next.branchKey) {
268
- return true;
269
- }
270
- // Skip if either await is a sleep/delay call (inherently sequential in polling loops)
271
- /* v8 ignore next -- defensive AST/type guard */
272
- if (isSleepOrDelay(current.expressionText) || isSleepOrDelay(next.expressionText))
273
- return true;
274
- // Skip if the first await is a lock/acquire call (inherently sequential)
275
- /* v8 ignore next -- defensive AST/type guard */
276
- if (isLockAcquire(current.expressionText))
277
- return true;
278
- // If the first await has an assigned variable, check if the second await uses it
279
- if (current.assignedVariable !== null && next.expressionText.includes(current.assignedVariable)) {
280
- return true;
281
- }
282
- // Check if the first await has destructured bindings used by the second
283
- /* v8 ignore next -- defensive AST/type guard */
284
- if (nextUsesDestructuredBindings(current, next))
285
- return true;
286
- // Skip if the first await is a dynamic import (next line typically uses the import)
287
- /* v8 ignore next -- defensive AST/type guard */
288
- if (current.isDynamicImport)
289
- return true;
290
- // Skip if either await is not a function call (just awaiting a variable)
291
- if (!isAwaitingFunctionCall(current.expressionText) ||
292
- !isAwaitingFunctionCall(next.expressionText)) {
293
- return true;
294
- }
295
- return false;
296
- }
297
- /**
298
- * Detect waterfall patterns in a list of await expressions
299
- */
300
- function detectWaterfalls(awaitInfos) {
301
- const violations = [];
302
- // Sort by line number
303
- const sorted = [...awaitInfos].sort((a, b) => a.line - b.line);
304
- // @lazy-ok -- validation depends on preceding await result
305
- for (let i = 0; i < sorted.length - 1; i++) {
306
- const current = sorted[i];
307
- const next = sorted[i + 1];
308
- // Array access with bounds-checked index is safe here
309
- if (current === undefined || next === undefined)
310
- continue;
311
- if (shouldSkipAwaitPair(current, next))
312
- continue;
313
- // This looks like a potential waterfall pattern
314
- violations.push({
315
- line: current.line,
316
- column: current.column,
317
- message: 'Sequential await statements may be parallelizable with Promise.all()',
318
- severity: 'warning',
319
- suggestion: 'Consider using Promise.all() to parallelize independent async operations. ' +
320
- 'Example: const [result1, result2] = await Promise.all([asyncOp1(), asyncOp2()]);',
321
- type: 'async-waterfall',
322
- match: `${current.expressionText} followed by ${next.expressionText}`,
323
- });
324
- // Skip the next await since we already flagged this pair
325
- i++;
326
- }
327
- return violations;
328
- }
329
- /**
330
- * Check if an await expression is awaiting a function call (not just a variable or property)
331
- */
332
- function isAwaitingFunctionCall(expressionText) {
333
- // Remove the "await " prefix
334
- const afterAwait = expressionText.replace(/^await\s+/, '');
335
- // Check if it ends with () or has a call pattern
336
- // This catches: foo(), foo.bar(), this.foo(), obj.method(args)
337
- // eslint-disable-next-line sonarjs/slow-regex -- [^)]* bounded by ')' delimiter; $ anchored
338
- return /\([^)]*\)\s*$/.test(afterAwait);
339
- }
340
- /**
341
- * Analyze a file for async waterfall patterns
342
- */
343
- function analyzeFile(absolutePath, content) {
344
- const violations = [];
345
- const sourceFile = getSharedSourceFile(absolutePath, content);
346
- /* v8 ignore next -- defensive guard */
347
- if (!sourceFile)
348
- return [];
349
- // Find all async functions and analyze their await expressions
350
- const visit = (node) => {
351
- if (isAsyncFunction(node)) {
352
- const asyncNode = node;
353
- const awaitInfos = collectAwaitExpressions(asyncNode, sourceFile);
354
- const newViolations = detectWaterfalls(awaitInfos);
355
- violations.push(...newViolations);
356
- }
357
- ts.forEachChild(node, visit);
358
- };
359
- visit(sourceFile);
360
- return violations;
361
- }
14
+ import { analyzeFile, MAX_LINE_GAP } from './async-waterfall-analysis.js';
362
15
  /**
363
16
  * Check: quality/async-waterfall-detection
364
17
  *
@@ -386,8 +39,9 @@ export const asyncWaterfallDetection = defineCheck({
386
39
  - Awaits in different conditional branches (if/else, ternary, switch/case)
387
40
  - Dynamic \`await import()\` expressions (next statement almost always depends on the import)
388
41
  - Destructured binding dependencies (e.g., \`const { x } = await import(...); await x()\`)
389
- - Sleep/delay calls in polling loops (\`await sleep()\`, \`await delay()\`)
42
+ - Sleep/delay/backoff/yield calls (\`await sleep()\`, \`await backoff()\`, \`await yieldToEventLoop()\`)
390
43
  - Mutex/lock acquire patterns (\`await this.acquire()\`, \`await lock()\`)
44
+ - Documented sequential orchestration (setup-then-run, collect-then-count scans)
391
45
  - CLI entry point files (\`**/bin/**\`)
392
46
 
393
47
  **Why it matters:** Sequential independent awaits double latency unnecessarily; parallelizing them with \`Promise.all()\` can significantly improve performance.
@@ -396,11 +50,8 @@ export const asyncWaterfallDetection = defineCheck({
396
50
  tags: ['quality', 'performance', 'async', 'patterns'],
397
51
  fileTypes: ['ts'],
398
52
  analyze(content, filePath) {
399
- // Skip test files — sequential awaits in tests are low-risk
400
53
  if (isTestFile(filePath))
401
54
  return [];
402
- // @lazy-ok -- 'await' appears as a string literal, not an actual await expression
403
- // Quick filter: skip files without async/await
404
55
  if (!content.includes('await')) {
405
56
  return [];
406
57
  }
@@ -1 +1 @@
1
- {"version":3,"file":"async-waterfall-detection.js","sourceRoot":"","sources":["../../../../src/checks/quality/patterns/async-waterfall-detection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"async-waterfall-detection.js","sourceRoot":"","sources":["../../../../src/checks/quality/patterns/async-waterfall-detection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE1E;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,WAAW,CAAC;IACjD,EAAE,EAAE,sCAAsC;IAC1C,IAAI,EAAE,2BAA2B;IACjC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;IACrE,aAAa,EAAE,eAAe;IAE9B,UAAU,EAAE,MAAM;IAClB,WAAW,EAAE,+DAA+D;IAC5E,eAAe,EAAE;;iHAE8F,YAAY,GAAG,CAAC;;;;;;;;;;;;;iCAahG;IAC/B,IAAI,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,CAAC;IACrD,SAAS,EAAE,CAAC,IAAI,CAAC;IAEjB,OAAO,CAAC,OAAO,EAAE,QAAQ;QACvB,IAAI,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QAEpC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import * as ts from 'typescript';
2
+ export declare function getContainingFunctionName(node: ts.Node, sourceFile: ts.SourceFile): string | undefined;
3
+ //# sourceMappingURL=containing-function-name.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"containing-function-name.d.ts","sourceRoot":"","sources":["../../../../src/checks/quality/patterns/containing-function-name.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,UAAU,EAAE,EAAE,CAAC,UAAU,GACxB,MAAM,GAAG,SAAS,CAqBpB"}
@@ -0,0 +1,21 @@
1
+ import * as ts from 'typescript';
2
+ export function getContainingFunctionName(node, sourceFile) {
3
+ let current = node.parent;
4
+ while (current) {
5
+ if (ts.isFunctionDeclaration(current) && current.name) {
6
+ return current.name.getText(sourceFile);
7
+ }
8
+ if (ts.isMethodDeclaration(current) && current.name) {
9
+ return current.name.getText(sourceFile);
10
+ }
11
+ if (ts.isArrowFunction(current) || ts.isFunctionExpression(current)) {
12
+ const parent = current.parent;
13
+ if (ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
14
+ return parent.name.getText(sourceFile);
15
+ }
16
+ }
17
+ current = current.parent;
18
+ }
19
+ return undefined;
20
+ }
21
+ //# sourceMappingURL=containing-function-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"containing-function-name.js","sourceRoot":"","sources":["../../../../src/checks/quality/patterns/containing-function-name.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,MAAM,UAAU,yBAAyB,CACvC,IAAa,EACb,UAAyB;IAEzB,IAAI,OAAO,GAAwB,IAAI,CAAC,MAAM,CAAC;IAE/C,OAAO,OAAO,EAAE,CAAC;QACf,IAAI,EAAE,CAAC,qBAAqB,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACtD,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC1C,CAAC;QAED,IAAI,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACpD,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC1C,CAAC;QAED,IAAI,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;YACpE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC9B,IAAI,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrE,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAC3B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -4,6 +4,9 @@
4
4
  * Detects silent error handling in both try/catch and Result patterns.
5
5
  * Replaces: resilience/no-empty-catch, quality/error-swallowing-boolean
6
6
  */
7
+ import { type CheckViolation } from '@opensip-cli/fitness';
8
+ /** Analyze a file for silent error-handling issues. */
9
+ export declare function analyzeFileForErrorHandlingQuality(content: string, filePath: string): CheckViolation[];
7
10
  /**
8
11
  * Check: quality/error-handling-quality
9
12
  *
@@ -1 +1 @@
1
- {"version":3,"file":"error-handling-quality.d.ts","sourceRoot":"","sources":["../../../../src/checks/quality/patterns/error-handling-quality.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAkSH;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,sCAwD/B,CAAC"}
1
+ {"version":3,"file":"error-handling-quality.d.ts","sourceRoot":"","sources":["../../../../src/checks/quality/patterns/error-handling-quality.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AA6ZpF,uDAAuD;AACvD,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,cAAc,EAAE,CAgClB;AAMD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,sCAuB/B,CAAC"}