@kevinrabun/judges 2.3.0 → 3.0.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 (319) hide show
  1. package/README.md +177 -12
  2. package/dist/api.d.ts +40 -0
  3. package/dist/api.d.ts.map +1 -0
  4. package/dist/api.js +56 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/ast/cross-file-taint.d.ts +43 -0
  7. package/dist/ast/cross-file-taint.d.ts.map +1 -0
  8. package/dist/ast/cross-file-taint.js +713 -0
  9. package/dist/ast/cross-file-taint.js.map +1 -0
  10. package/dist/ast/index.d.ts +4 -0
  11. package/dist/ast/index.d.ts.map +1 -1
  12. package/dist/ast/index.js +5 -0
  13. package/dist/ast/index.js.map +1 -1
  14. package/dist/ast/structural-parser.d.ts.map +1 -1
  15. package/dist/ast/structural-parser.js +66 -11
  16. package/dist/ast/structural-parser.js.map +1 -1
  17. package/dist/ast/taint-tracker.d.ts +35 -0
  18. package/dist/ast/taint-tracker.d.ts.map +1 -0
  19. package/dist/ast/taint-tracker.js +518 -0
  20. package/dist/ast/taint-tracker.js.map +1 -0
  21. package/dist/ast/types.d.ts +2 -0
  22. package/dist/ast/types.d.ts.map +1 -1
  23. package/dist/ast/typescript-ast.d.ts.map +1 -1
  24. package/dist/ast/typescript-ast.js +25 -5
  25. package/dist/ast/typescript-ast.js.map +1 -1
  26. package/dist/config.d.ts.map +1 -1
  27. package/dist/config.js +10 -9
  28. package/dist/config.js.map +1 -1
  29. package/dist/dedup.d.ts +19 -0
  30. package/dist/dedup.d.ts.map +1 -0
  31. package/dist/dedup.js +222 -0
  32. package/dist/dedup.js.map +1 -0
  33. package/dist/errors.d.ts +37 -0
  34. package/dist/errors.d.ts.map +1 -0
  35. package/dist/errors.js +57 -0
  36. package/dist/errors.js.map +1 -0
  37. package/dist/evaluators/accessibility.d.ts +1 -1
  38. package/dist/evaluators/accessibility.d.ts.map +1 -1
  39. package/dist/evaluators/accessibility.js +22 -16
  40. package/dist/evaluators/accessibility.js.map +1 -1
  41. package/dist/evaluators/agent-instructions.d.ts +1 -1
  42. package/dist/evaluators/agent-instructions.d.ts.map +1 -1
  43. package/dist/evaluators/agent-instructions.js +1 -2
  44. package/dist/evaluators/agent-instructions.js.map +1 -1
  45. package/dist/evaluators/ai-code-safety.d.ts +1 -1
  46. package/dist/evaluators/ai-code-safety.d.ts.map +1 -1
  47. package/dist/evaluators/ai-code-safety.js +2 -6
  48. package/dist/evaluators/ai-code-safety.js.map +1 -1
  49. package/dist/evaluators/api-design.d.ts +1 -1
  50. package/dist/evaluators/api-design.d.ts.map +1 -1
  51. package/dist/evaluators/api-design.js +2 -1
  52. package/dist/evaluators/api-design.js.map +1 -1
  53. package/dist/evaluators/app-builder.d.ts +34 -0
  54. package/dist/evaluators/app-builder.d.ts.map +1 -0
  55. package/dist/evaluators/app-builder.js +156 -0
  56. package/dist/evaluators/app-builder.js.map +1 -0
  57. package/dist/evaluators/authentication.d.ts +1 -1
  58. package/dist/evaluators/authentication.d.ts.map +1 -1
  59. package/dist/evaluators/authentication.js +2 -66
  60. package/dist/evaluators/authentication.js.map +1 -1
  61. package/dist/evaluators/backwards-compatibility.d.ts +1 -1
  62. package/dist/evaluators/backwards-compatibility.d.ts.map +1 -1
  63. package/dist/evaluators/backwards-compatibility.js.map +1 -1
  64. package/dist/evaluators/caching.d.ts +1 -1
  65. package/dist/evaluators/caching.d.ts.map +1 -1
  66. package/dist/evaluators/caching.js.map +1 -1
  67. package/dist/evaluators/ci-cd.d.ts +1 -1
  68. package/dist/evaluators/ci-cd.d.ts.map +1 -1
  69. package/dist/evaluators/ci-cd.js +4 -4
  70. package/dist/evaluators/ci-cd.js.map +1 -1
  71. package/dist/evaluators/cloud-readiness.d.ts +1 -1
  72. package/dist/evaluators/cloud-readiness.d.ts.map +1 -1
  73. package/dist/evaluators/cloud-readiness.js.map +1 -1
  74. package/dist/evaluators/code-structure.d.ts +1 -1
  75. package/dist/evaluators/code-structure.d.ts.map +1 -1
  76. package/dist/evaluators/code-structure.js +2 -6
  77. package/dist/evaluators/code-structure.js.map +1 -1
  78. package/dist/evaluators/compliance.d.ts +1 -1
  79. package/dist/evaluators/compliance.d.ts.map +1 -1
  80. package/dist/evaluators/compliance.js +15 -6
  81. package/dist/evaluators/compliance.js.map +1 -1
  82. package/dist/evaluators/concurrency.d.ts +1 -1
  83. package/dist/evaluators/concurrency.d.ts.map +1 -1
  84. package/dist/evaluators/concurrency.js +9 -4
  85. package/dist/evaluators/concurrency.js.map +1 -1
  86. package/dist/evaluators/configuration-management.d.ts +1 -1
  87. package/dist/evaluators/configuration-management.d.ts.map +1 -1
  88. package/dist/evaluators/configuration-management.js +7 -2
  89. package/dist/evaluators/configuration-management.js.map +1 -1
  90. package/dist/evaluators/cost-effectiveness.d.ts +1 -1
  91. package/dist/evaluators/cost-effectiveness.d.ts.map +1 -1
  92. package/dist/evaluators/cost-effectiveness.js +1 -3
  93. package/dist/evaluators/cost-effectiveness.js.map +1 -1
  94. package/dist/evaluators/cybersecurity.d.ts +1 -1
  95. package/dist/evaluators/cybersecurity.d.ts.map +1 -1
  96. package/dist/evaluators/cybersecurity.js +50 -1
  97. package/dist/evaluators/cybersecurity.js.map +1 -1
  98. package/dist/evaluators/data-security.d.ts +1 -1
  99. package/dist/evaluators/data-security.d.ts.map +1 -1
  100. package/dist/evaluators/data-security.js +9 -66
  101. package/dist/evaluators/data-security.js.map +1 -1
  102. package/dist/evaluators/data-sovereignty.d.ts +1 -1
  103. package/dist/evaluators/data-sovereignty.d.ts.map +1 -1
  104. package/dist/evaluators/data-sovereignty.js +4 -2
  105. package/dist/evaluators/data-sovereignty.js.map +1 -1
  106. package/dist/evaluators/database.d.ts +1 -1
  107. package/dist/evaluators/database.d.ts.map +1 -1
  108. package/dist/evaluators/database.js +3 -1
  109. package/dist/evaluators/database.js.map +1 -1
  110. package/dist/evaluators/dependencies.d.ts +6 -0
  111. package/dist/evaluators/dependencies.d.ts.map +1 -0
  112. package/dist/evaluators/dependencies.js +204 -0
  113. package/dist/evaluators/dependencies.js.map +1 -0
  114. package/dist/evaluators/dependency-health.d.ts +1 -1
  115. package/dist/evaluators/dependency-health.d.ts.map +1 -1
  116. package/dist/evaluators/dependency-health.js +198 -6
  117. package/dist/evaluators/dependency-health.js.map +1 -1
  118. package/dist/evaluators/documentation.d.ts +1 -1
  119. package/dist/evaluators/documentation.d.ts.map +1 -1
  120. package/dist/evaluators/documentation.js +5 -2
  121. package/dist/evaluators/documentation.js.map +1 -1
  122. package/dist/evaluators/error-handling.d.ts +1 -1
  123. package/dist/evaluators/error-handling.d.ts.map +1 -1
  124. package/dist/evaluators/error-handling.js.map +1 -1
  125. package/dist/evaluators/ethics-bias.d.ts +1 -1
  126. package/dist/evaluators/ethics-bias.d.ts.map +1 -1
  127. package/dist/evaluators/ethics-bias.js +10 -5
  128. package/dist/evaluators/ethics-bias.js.map +1 -1
  129. package/dist/evaluators/framework-safety.d.ts +13 -0
  130. package/dist/evaluators/framework-safety.d.ts.map +1 -0
  131. package/dist/evaluators/framework-safety.js +424 -0
  132. package/dist/evaluators/framework-safety.js.map +1 -0
  133. package/dist/evaluators/index.d.ts +20 -24
  134. package/dist/evaluators/index.d.ts.map +1 -1
  135. package/dist/evaluators/index.js +294 -728
  136. package/dist/evaluators/index.js.map +1 -1
  137. package/dist/evaluators/internationalization.d.ts +1 -1
  138. package/dist/evaluators/internationalization.d.ts.map +1 -1
  139. package/dist/evaluators/internationalization.js +14 -6
  140. package/dist/evaluators/internationalization.js.map +1 -1
  141. package/dist/evaluators/logging-privacy.d.ts +1 -1
  142. package/dist/evaluators/logging-privacy.d.ts.map +1 -1
  143. package/dist/evaluators/logging-privacy.js +3 -1
  144. package/dist/evaluators/logging-privacy.js.map +1 -1
  145. package/dist/evaluators/maintainability.d.ts +1 -1
  146. package/dist/evaluators/maintainability.d.ts.map +1 -1
  147. package/dist/evaluators/maintainability.js +15 -9
  148. package/dist/evaluators/maintainability.js.map +1 -1
  149. package/dist/evaluators/observability.d.ts +1 -1
  150. package/dist/evaluators/observability.d.ts.map +1 -1
  151. package/dist/evaluators/observability.js +2 -1
  152. package/dist/evaluators/observability.js.map +1 -1
  153. package/dist/evaluators/performance.d.ts +1 -1
  154. package/dist/evaluators/performance.d.ts.map +1 -1
  155. package/dist/evaluators/performance.js +181 -4
  156. package/dist/evaluators/performance.js.map +1 -1
  157. package/dist/evaluators/portability.d.ts +1 -1
  158. package/dist/evaluators/portability.d.ts.map +1 -1
  159. package/dist/evaluators/portability.js +2 -1
  160. package/dist/evaluators/portability.js.map +1 -1
  161. package/dist/evaluators/project.d.ts +16 -0
  162. package/dist/evaluators/project.d.ts.map +1 -0
  163. package/dist/evaluators/project.js +353 -0
  164. package/dist/evaluators/project.js.map +1 -0
  165. package/dist/evaluators/rate-limiting.d.ts +1 -1
  166. package/dist/evaluators/rate-limiting.d.ts.map +1 -1
  167. package/dist/evaluators/rate-limiting.js.map +1 -1
  168. package/dist/evaluators/reliability.d.ts +1 -1
  169. package/dist/evaluators/reliability.d.ts.map +1 -1
  170. package/dist/evaluators/reliability.js.map +1 -1
  171. package/dist/evaluators/scalability.d.ts +1 -1
  172. package/dist/evaluators/scalability.d.ts.map +1 -1
  173. package/dist/evaluators/scalability.js +3 -1
  174. package/dist/evaluators/scalability.js.map +1 -1
  175. package/dist/evaluators/shared.d.ts +24 -2
  176. package/dist/evaluators/shared.d.ts.map +1 -1
  177. package/dist/evaluators/shared.js +190 -2
  178. package/dist/evaluators/shared.js.map +1 -1
  179. package/dist/evaluators/software-practices.d.ts +1 -1
  180. package/dist/evaluators/software-practices.d.ts.map +1 -1
  181. package/dist/evaluators/software-practices.js +3 -3
  182. package/dist/evaluators/software-practices.js.map +1 -1
  183. package/dist/evaluators/testing.d.ts +1 -1
  184. package/dist/evaluators/testing.d.ts.map +1 -1
  185. package/dist/evaluators/testing.js +12 -4
  186. package/dist/evaluators/testing.js.map +1 -1
  187. package/dist/evaluators/ux.d.ts +1 -1
  188. package/dist/evaluators/ux.d.ts.map +1 -1
  189. package/dist/evaluators/ux.js.map +1 -1
  190. package/dist/evaluators/v2.d.ts +1 -1
  191. package/dist/evaluators/v2.d.ts.map +1 -1
  192. package/dist/evaluators/v2.js +13 -35
  193. package/dist/evaluators/v2.js.map +1 -1
  194. package/dist/formatters/sarif.d.ts +75 -0
  195. package/dist/formatters/sarif.d.ts.map +1 -0
  196. package/dist/formatters/sarif.js +93 -0
  197. package/dist/formatters/sarif.js.map +1 -0
  198. package/dist/index.d.ts +4 -1
  199. package/dist/index.d.ts.map +1 -1
  200. package/dist/index.js +9 -806
  201. package/dist/index.js.map +1 -1
  202. package/dist/judges/accessibility.d.ts +1 -1
  203. package/dist/judges/accessibility.d.ts.map +1 -1
  204. package/dist/judges/agent-instructions.d.ts +1 -1
  205. package/dist/judges/agent-instructions.d.ts.map +1 -1
  206. package/dist/judges/ai-code-safety.d.ts +1 -1
  207. package/dist/judges/ai-code-safety.d.ts.map +1 -1
  208. package/dist/judges/api-design.d.ts +1 -1
  209. package/dist/judges/api-design.d.ts.map +1 -1
  210. package/dist/judges/authentication.d.ts +1 -1
  211. package/dist/judges/authentication.d.ts.map +1 -1
  212. package/dist/judges/backwards-compatibility.d.ts +1 -1
  213. package/dist/judges/backwards-compatibility.d.ts.map +1 -1
  214. package/dist/judges/caching.d.ts +1 -1
  215. package/dist/judges/caching.d.ts.map +1 -1
  216. package/dist/judges/ci-cd.d.ts +1 -1
  217. package/dist/judges/ci-cd.d.ts.map +1 -1
  218. package/dist/judges/cloud-readiness.d.ts +1 -1
  219. package/dist/judges/cloud-readiness.d.ts.map +1 -1
  220. package/dist/judges/code-structure.d.ts +1 -1
  221. package/dist/judges/code-structure.d.ts.map +1 -1
  222. package/dist/judges/compliance.d.ts +1 -1
  223. package/dist/judges/compliance.d.ts.map +1 -1
  224. package/dist/judges/concurrency.d.ts +1 -1
  225. package/dist/judges/concurrency.d.ts.map +1 -1
  226. package/dist/judges/configuration-management.d.ts +1 -1
  227. package/dist/judges/configuration-management.d.ts.map +1 -1
  228. package/dist/judges/cost-effectiveness.d.ts +1 -1
  229. package/dist/judges/cost-effectiveness.d.ts.map +1 -1
  230. package/dist/judges/cybersecurity.d.ts +1 -1
  231. package/dist/judges/cybersecurity.d.ts.map +1 -1
  232. package/dist/judges/data-security.d.ts +1 -1
  233. package/dist/judges/data-security.d.ts.map +1 -1
  234. package/dist/judges/data-sovereignty.d.ts +1 -1
  235. package/dist/judges/data-sovereignty.d.ts.map +1 -1
  236. package/dist/judges/database.d.ts +1 -1
  237. package/dist/judges/database.d.ts.map +1 -1
  238. package/dist/judges/dependency-health.d.ts +1 -1
  239. package/dist/judges/dependency-health.d.ts.map +1 -1
  240. package/dist/judges/documentation.d.ts +1 -1
  241. package/dist/judges/documentation.d.ts.map +1 -1
  242. package/dist/judges/error-handling.d.ts +1 -1
  243. package/dist/judges/error-handling.d.ts.map +1 -1
  244. package/dist/judges/ethics-bias.d.ts +1 -1
  245. package/dist/judges/ethics-bias.d.ts.map +1 -1
  246. package/dist/judges/framework-safety.d.ts +3 -0
  247. package/dist/judges/framework-safety.d.ts.map +1 -0
  248. package/dist/judges/framework-safety.js +25 -0
  249. package/dist/judges/framework-safety.js.map +1 -0
  250. package/dist/judges/index.d.ts +1 -1
  251. package/dist/judges/index.d.ts.map +1 -1
  252. package/dist/judges/index.js +74 -0
  253. package/dist/judges/index.js.map +1 -1
  254. package/dist/judges/internationalization.d.ts +1 -1
  255. package/dist/judges/internationalization.d.ts.map +1 -1
  256. package/dist/judges/logging-privacy.d.ts +1 -1
  257. package/dist/judges/logging-privacy.d.ts.map +1 -1
  258. package/dist/judges/maintainability.d.ts +1 -1
  259. package/dist/judges/maintainability.d.ts.map +1 -1
  260. package/dist/judges/observability.d.ts +1 -1
  261. package/dist/judges/observability.d.ts.map +1 -1
  262. package/dist/judges/performance.d.ts +1 -1
  263. package/dist/judges/performance.d.ts.map +1 -1
  264. package/dist/judges/portability.d.ts +1 -1
  265. package/dist/judges/portability.d.ts.map +1 -1
  266. package/dist/judges/rate-limiting.d.ts +1 -1
  267. package/dist/judges/rate-limiting.d.ts.map +1 -1
  268. package/dist/judges/reliability.d.ts +1 -1
  269. package/dist/judges/reliability.d.ts.map +1 -1
  270. package/dist/judges/scalability.d.ts +1 -1
  271. package/dist/judges/scalability.d.ts.map +1 -1
  272. package/dist/judges/software-practices.d.ts +1 -1
  273. package/dist/judges/software-practices.d.ts.map +1 -1
  274. package/dist/judges/testing.d.ts +1 -1
  275. package/dist/judges/testing.d.ts.map +1 -1
  276. package/dist/judges/ux.d.ts +1 -1
  277. package/dist/judges/ux.d.ts.map +1 -1
  278. package/dist/language-patterns.d.ts +37 -0
  279. package/dist/language-patterns.d.ts.map +1 -1
  280. package/dist/language-patterns.js +58 -3
  281. package/dist/language-patterns.js.map +1 -1
  282. package/dist/patches/index.d.ts +10 -0
  283. package/dist/patches/index.d.ts.map +1 -0
  284. package/dist/patches/index.js +533 -0
  285. package/dist/patches/index.js.map +1 -0
  286. package/dist/reports/public-repo-report.d.ts +1 -1
  287. package/dist/reports/public-repo-report.d.ts.map +1 -1
  288. package/dist/scoring.d.ts +18 -0
  289. package/dist/scoring.d.ts.map +1 -0
  290. package/dist/scoring.js +178 -0
  291. package/dist/scoring.js.map +1 -0
  292. package/dist/tools/deep-review.d.ts +4 -0
  293. package/dist/tools/deep-review.d.ts.map +1 -0
  294. package/dist/tools/deep-review.js +56 -0
  295. package/dist/tools/deep-review.js.map +1 -0
  296. package/dist/tools/prompts.d.ts +8 -0
  297. package/dist/tools/prompts.d.ts.map +1 -0
  298. package/dist/tools/prompts.js +66 -0
  299. package/dist/tools/prompts.js.map +1 -0
  300. package/dist/tools/register-evaluation.d.ts +7 -0
  301. package/dist/tools/register-evaluation.d.ts.map +1 -0
  302. package/dist/tools/register-evaluation.js +303 -0
  303. package/dist/tools/register-evaluation.js.map +1 -0
  304. package/dist/tools/register-workflow.d.ts +7 -0
  305. package/dist/tools/register-workflow.d.ts.map +1 -0
  306. package/dist/tools/register-workflow.js +395 -0
  307. package/dist/tools/register-workflow.js.map +1 -0
  308. package/dist/tools/register.d.ts +7 -0
  309. package/dist/tools/register.d.ts.map +1 -0
  310. package/dist/tools/register.js +14 -0
  311. package/dist/tools/register.js.map +1 -0
  312. package/dist/tools/schemas.d.ts +26 -0
  313. package/dist/tools/schemas.d.ts.map +1 -0
  314. package/dist/tools/schemas.js +42 -0
  315. package/dist/tools/schemas.js.map +1 -0
  316. package/dist/types.d.ts +29 -2
  317. package/dist/types.d.ts.map +1 -1
  318. package/package.json +42 -3
  319. package/server.json +51 -3
@@ -0,0 +1,518 @@
1
+ // ─────────────────────────────────────────────────────────────────────────────
2
+ // Taint Tracker — Single-file data-flow analysis
3
+ // ─────────────────────────────────────────────────────────────────────────────
4
+ // Traces user-input sources (req.body, req.params, etc.) through variable
5
+ // assignments to dangerous sinks (eval, exec, SQL queries, innerHTML).
6
+ // Uses the TypeScript compiler API for JS/TS and lightweight regex for others.
7
+ //
8
+ // Enhancements over v1:
9
+ // - Word-boundary-aware variable matching (prevents "id" matching "isValid")
10
+ // - Sanitizer recognition (DOMPurify, encodeURIComponent, parameterized queries, etc.)
11
+ // - Same-file inter-procedural taint (function parameter → return tracking)
12
+ // - Guard clause sensitivity (validation guards reduce taint confidence)
13
+ // ─────────────────────────────────────────────────────────────────────────────
14
+ import ts from "typescript";
15
+ import { normalizeLanguage } from "../language-patterns.js";
16
+ // ─── Source / Sink Definitions ───────────────────────────────────────────────
17
+ const SOURCE_PATTERNS = [
18
+ { pattern: /\breq(?:uest)?\.(?:body|query|params|headers|cookies)\b/i, kind: "http-param" },
19
+ { pattern: /\brequest\.(?:form|args|json|data|values|files|get)\b/i, kind: "http-param" },
20
+ { pattern: /\b(?:ctx|context)\.(?:query|params|request)\b/i, kind: "http-param" },
21
+ { pattern: /\bgetParameter\s*\(/i, kind: "http-param" },
22
+ { pattern: /\bRequest\.(?:Form|QueryString|Params)\b/i, kind: "http-param" },
23
+ { pattern: /\b(?:process\.argv|sys\.argv|os\.Args|args)\b/i, kind: "user-input" },
24
+ { pattern: /\b(?:prompt|readline|input)\s*\(/i, kind: "user-input" },
25
+ { pattern: /\bsearchParams\.get\s*\(/i, kind: "url-param" },
26
+ { pattern: /\.(?:useSearchParams|useParams)\b/i, kind: "url-param" },
27
+ ];
28
+ const SINK_PATTERNS = [
29
+ { pattern: /\beval\s*\(/i, kind: "code-execution" },
30
+ { pattern: /\bnew\s+Function\s*\(/i, kind: "code-execution" },
31
+ { pattern: /\bvm\.run(?:InContext|InNewContext|InThisContext)?\s*\(/i, kind: "code-execution" },
32
+ {
33
+ pattern: /\b(?:exec|execSync|system|popen|subprocess\.(?:Popen|run|call)|os\.system|Runtime\.getRuntime\(\)\.exec)\s*\(/i,
34
+ kind: "command-exec",
35
+ },
36
+ { pattern: /\b(?:spawn|spawnSync)\s*\(/i, kind: "command-exec" },
37
+ {
38
+ pattern: /\.(?:query|execute|exec|prepare)\s*\(\s*[`"']?\s*(?:SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER)\b/i,
39
+ kind: "sql-query",
40
+ },
41
+ { pattern: /\.(?:query|execute|exec)\s*\(/i, kind: "sql-query" },
42
+ { pattern: /\.innerHTML\s*=/i, kind: "xss" },
43
+ { pattern: /\bdocument\.write\s*\(/i, kind: "xss" },
44
+ { pattern: /\bdangerouslySetInnerHTML/i, kind: "xss" },
45
+ { pattern: /\b(?:readFile|readFileSync|open)\s*\(/i, kind: "path-traversal" },
46
+ { pattern: /\.redirect\s*\(/i, kind: "redirect" },
47
+ { pattern: /\b(?:render_template_string|nunjucks\.renderString|Handlebars\.compile)\s*\(/i, kind: "template" },
48
+ { pattern: /\bJSON\.parse\s*\(/i, kind: "deserialization" },
49
+ ];
50
+ // ─── Sanitizer Recognition ──────────────────────────────────────────────────
51
+ /** Known sanitizer/escaping functions that neutralize taint */
52
+ const SANITIZER_PATTERNS = [
53
+ // DOM / HTML sanitizers
54
+ /\bDOMPurify\.sanitize\s*\(/i,
55
+ /\bsanitizeHtml\s*\(/i,
56
+ /\bxss\s*\(/i,
57
+ /\bescapeHtml\s*\(/i,
58
+ /\bescape\s*\(/i,
59
+ // URL / encoding sanitizers
60
+ /\bencodeURIComponent\s*\(/i,
61
+ /\bencodeURI\s*\(/i,
62
+ /\burlEncode\s*\(/i,
63
+ /\bquote\s*\(/i,
64
+ // Input validation libraries
65
+ /\bvalidator\.\w+\s*\(/i,
66
+ /\b(?:joi|yup|zod|ajv)\b.*\.(?:validate|parse|safeParse)\s*\(/i,
67
+ // Parameterized query markers (taint is neutralized)
68
+ /\$\d+/, // PostgreSQL $1, $2, ...
69
+ /\?\s*(?:,|\))/, // MySQL ? placeholders
70
+ /:(?:param|value|id|name)\b/i, // Named parameters
71
+ // Path sanitization
72
+ /\bpath\.(?:normalize|resolve|basename)\s*\(/i,
73
+ // Python/Java/C# sanitizers
74
+ /\bbleach\.clean\s*\(/i,
75
+ /\bmarkup_safe\b/i,
76
+ /\bOWASP\.Encoder\b/i,
77
+ /\bAntiXss\.\w+\s*\(/i,
78
+ /\bHtmlEncoder\.Default\.Encode\s*\(/i,
79
+ /\bPreparedStatement\b/i,
80
+ /\b(?:html|url)\.EscapeString\s*\(/i,
81
+ ];
82
+ /** Check if a code expression passes through a known sanitizer */
83
+ function isSanitized(expression) {
84
+ return SANITIZER_PATTERNS.some((p) => p.test(expression));
85
+ }
86
+ // ─── Guard Clause Detection ─────────────────────────────────────────────────
87
+ /** Patterns that indicate validation/guard clauses for a variable */
88
+ const GUARD_PATTERNS = [
89
+ // Type checks
90
+ /typeof\s+\w+\s*(?:!==?|===?)\s*['"](?:string|number|boolean|object|undefined)['"]/i,
91
+ // Truthiness / nullish checks followed by return/throw
92
+ /if\s*\(\s*!?\s*\w+\s*\)\s*(?:return|throw|res\.status\(4\d\d\))/i,
93
+ // Validation function calls
94
+ /if\s*\(\s*!?\s*(?:isValid|validate|check|verify|sanitize|assert)\w*\s*\(/i,
95
+ // Length/range checks
96
+ /if\s*\(\s*\w+\.length\s*(?:[<>=!]+)/i,
97
+ /if\s*\(\s*\w+\s*(?:<|>|<=|>=)\s*\d+/i,
98
+ // Regex test guards
99
+ /if\s*\(\s*!?\s*\/[^/]+\/\.test\s*\(\s*\w+\s*\)/i,
100
+ // Express-validator / joi validation result check
101
+ /validationResult|\.isValid\(\)|\.error\b/i,
102
+ ];
103
+ /**
104
+ * Detect if a tainted variable has guard clauses between its source and a
105
+ * given sink line. Returns a confidence reduction (0.0 = no guards, up to
106
+ * -0.25 for strong validation).
107
+ */
108
+ function detectGuardClauses(varName, sourceLine, sinkLine, codeLines) {
109
+ const start = Math.min(sourceLine, sinkLine) - 1;
110
+ const end = Math.max(sourceLine, sinkLine);
111
+ let guardCount = 0;
112
+ for (let i = start; i < end && i < codeLines.length; i++) {
113
+ const line = codeLines[i];
114
+ // Check if the line references our variable in a guard pattern
115
+ if (!containsWordBoundary(line, varName))
116
+ continue;
117
+ for (const guard of GUARD_PATTERNS) {
118
+ if (guard.test(line)) {
119
+ guardCount++;
120
+ break;
121
+ }
122
+ }
123
+ }
124
+ // Each guard clause reduces confidence slightly (max -0.25)
125
+ return Math.min(guardCount * 0.1, 0.25);
126
+ }
127
+ // ─── Word-Boundary Matching ─────────────────────────────────────────────────
128
+ /**
129
+ * Check if `text` contains `varName` as a whole word (not a substring of
130
+ * another identifier). Prevents "id" from matching "isValid", "width", etc.
131
+ */
132
+ function containsWordBoundary(text, varName) {
133
+ // Escape regex special chars in varName
134
+ const escaped = varName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
135
+ // Use word boundary for alphanumeric names; for dotted names (req.body.name)
136
+ // use context-aware boundaries
137
+ const pattern = /^\w+$/.test(varName) ? new RegExp(`\\b${escaped}\\b`) : new RegExp(`(?<![\\w.])${escaped}(?![\\w])`);
138
+ return pattern.test(text);
139
+ }
140
+ /**
141
+ * Build a map of function name → taint propagation info.
142
+ * Tracks which function parameters flow to return values.
143
+ */
144
+ function buildFunctionTaintMap(sourceFile, taintMap) {
145
+ const result = new Map();
146
+ ts.forEachChild(sourceFile, function walk(node) {
147
+ if (ts.isFunctionDeclaration(node) ||
148
+ ts.isFunctionExpression(node) ||
149
+ ts.isArrowFunction(node) ||
150
+ ts.isMethodDeclaration(node)) {
151
+ const name = getFnName(node);
152
+ if (!name) {
153
+ ts.forEachChild(node, walk);
154
+ return;
155
+ }
156
+ const paramNames = node.parameters.map((p) => p.name.getText(sourceFile));
157
+ const paramSet = new Set(paramNames);
158
+ const taintedParams = new Set();
159
+ // Walk the function body to find return statements referencing params
160
+ function walkBody(n) {
161
+ if (ts.isReturnStatement(n) && n.expression) {
162
+ const retText = n.expression.getText(sourceFile);
163
+ for (let i = 0; i < paramNames.length; i++) {
164
+ if (containsWordBoundary(retText, paramNames[i])) {
165
+ taintedParams.add(i);
166
+ }
167
+ }
168
+ }
169
+ // Also track simple assignments from params that reach returns
170
+ if (ts.isVariableDeclaration(n) && n.initializer) {
171
+ const varName = n.name.getText(sourceFile);
172
+ const initText = n.initializer.getText(sourceFile);
173
+ for (const pName of paramSet) {
174
+ if (containsWordBoundary(initText, pName)) {
175
+ paramSet.add(varName);
176
+ }
177
+ }
178
+ }
179
+ ts.forEachChild(n, walkBody);
180
+ }
181
+ if (node.body) {
182
+ ts.forEachChild(node.body, walkBody);
183
+ }
184
+ if (taintedParams.size > 0) {
185
+ result.set(name, { taintedParams, paramNames, name });
186
+ }
187
+ }
188
+ ts.forEachChild(node, walk);
189
+ });
190
+ return result;
191
+ }
192
+ function getFnName(node) {
193
+ if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) {
194
+ return node.name?.getText();
195
+ }
196
+ if (ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)) {
197
+ return node.parent.name.text;
198
+ }
199
+ if (ts.isArrowFunction(node) && ts.isVariableDeclaration(node.parent)) {
200
+ const decl = node.parent;
201
+ if (ts.isIdentifier(decl.name))
202
+ return decl.name.text;
203
+ }
204
+ return undefined;
205
+ }
206
+ // ─── Public API ──────────────────────────────────────────────────────────────
207
+ /**
208
+ * Analyze a source file for taint flows: paths from untrusted input to
209
+ * dangerous sinks through variable assignments and string concatenation.
210
+ *
211
+ * For JS/TS, uses the TypeScript compiler AST for precise variable tracking.
212
+ * For other languages, falls back to regex-based lightweight analysis.
213
+ */
214
+ export function analyzeTaintFlows(code, language) {
215
+ const lang = normalizeLanguage(language);
216
+ switch (lang) {
217
+ case "javascript":
218
+ case "typescript":
219
+ return analyzeTypeScriptTaint(code, lang);
220
+ default:
221
+ return analyzeRegexTaint(code);
222
+ }
223
+ }
224
+ // ─── TypeScript / JavaScript Taint Analysis ──────────────────────────────────
225
+ function analyzeTypeScriptTaint(code, language) {
226
+ const scriptKind = language === "typescript" ? ts.ScriptKind.TS : ts.ScriptKind.JS;
227
+ const sourceFile = ts.createSourceFile("input." + (language === "typescript" ? "ts" : "js"), code, ts.ScriptTarget.Latest, true, scriptKind);
228
+ const flows = [];
229
+ const taintMap = new Map();
230
+ const codeLines = code.split("\n");
231
+ // Pass 1: Find tainted variable declarations/assignments
232
+ ts.forEachChild(sourceFile, function walk(node) {
233
+ // Variable declarations: const x = req.body.name
234
+ if (ts.isVariableDeclaration(node) && node.initializer) {
235
+ const varName = node.name.getText(sourceFile);
236
+ const initText = node.initializer.getText(sourceFile);
237
+ const line = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
238
+ // Skip if the initializer goes through a sanitizer
239
+ if (isSanitized(initText)) {
240
+ ts.forEachChild(node, walk);
241
+ return;
242
+ }
243
+ // Check if initializer is a source
244
+ for (const src of SOURCE_PATTERNS) {
245
+ if (src.pattern.test(initText)) {
246
+ taintMap.set(varName, {
247
+ sourceExpr: initText,
248
+ sourceKind: src.kind,
249
+ sourceLine: line,
250
+ assignmentChain: [{ line, variable: varName }],
251
+ });
252
+ break;
253
+ }
254
+ }
255
+ // Check if initializer references a tainted variable (propagation)
256
+ // Uses word-boundary matching to prevent "id" matching "isValid"
257
+ if (!taintMap.has(varName)) {
258
+ for (const [taintedVar, taintInfo] of taintMap) {
259
+ if (containsWordBoundary(initText, taintedVar)) {
260
+ taintMap.set(varName, {
261
+ ...taintInfo,
262
+ assignmentChain: [...taintInfo.assignmentChain, { line, variable: varName }],
263
+ });
264
+ break;
265
+ }
266
+ }
267
+ }
268
+ }
269
+ // Assignment expressions: x = req.body.name
270
+ if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
271
+ const leftText = node.left.getText(sourceFile);
272
+ const rightText = node.right.getText(sourceFile);
273
+ const line = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
274
+ // Skip sanitized assignments
275
+ if (isSanitized(rightText)) {
276
+ ts.forEachChild(node, walk);
277
+ return;
278
+ }
279
+ for (const src of SOURCE_PATTERNS) {
280
+ if (src.pattern.test(rightText)) {
281
+ taintMap.set(leftText, {
282
+ sourceExpr: rightText,
283
+ sourceKind: src.kind,
284
+ sourceLine: line,
285
+ assignmentChain: [{ line, variable: leftText }],
286
+ });
287
+ break;
288
+ }
289
+ }
290
+ if (!taintMap.has(leftText)) {
291
+ for (const [taintedVar, taintInfo] of taintMap) {
292
+ if (containsWordBoundary(rightText, taintedVar)) {
293
+ taintMap.set(leftText, {
294
+ ...taintInfo,
295
+ assignmentChain: [...taintInfo.assignmentChain, { line, variable: leftText }],
296
+ });
297
+ break;
298
+ }
299
+ }
300
+ }
301
+ }
302
+ // Destructuring: const { name } = req.body
303
+ if (ts.isVariableDeclaration(node) && ts.isObjectBindingPattern(node.name) && node.initializer) {
304
+ const initText = node.initializer.getText(sourceFile);
305
+ const line = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
306
+ for (const src of SOURCE_PATTERNS) {
307
+ if (src.pattern.test(initText)) {
308
+ for (const element of node.name.elements) {
309
+ const propName = element.name.getText(sourceFile);
310
+ taintMap.set(propName, {
311
+ sourceExpr: `${initText}.${propName}`,
312
+ sourceKind: src.kind,
313
+ sourceLine: line,
314
+ assignmentChain: [{ line, variable: propName }],
315
+ });
316
+ }
317
+ break;
318
+ }
319
+ }
320
+ }
321
+ ts.forEachChild(node, walk);
322
+ });
323
+ // Pass 1.5: Inter-procedural — propagate taint through same-file function calls
324
+ const fnTaintMap = buildFunctionTaintMap(sourceFile, taintMap);
325
+ ts.forEachChild(sourceFile, function walkCalls(node) {
326
+ if (ts.isVariableDeclaration(node) && node.initializer && ts.isCallExpression(node.initializer)) {
327
+ const call = node.initializer;
328
+ const fnName = call.expression.getText(sourceFile);
329
+ const fnInfo = fnTaintMap.get(fnName);
330
+ if (fnInfo) {
331
+ const varName = node.name.getText(sourceFile);
332
+ const line = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
333
+ // Check if any tainted variable is passed as an argument at a tainted param index
334
+ for (const paramIdx of fnInfo.taintedParams) {
335
+ if (paramIdx < call.arguments.length) {
336
+ const argText = call.arguments[paramIdx].getText(sourceFile);
337
+ for (const [taintedVar, taintInfo] of taintMap) {
338
+ if (containsWordBoundary(argText, taintedVar)) {
339
+ taintMap.set(varName, {
340
+ ...taintInfo,
341
+ assignmentChain: [...taintInfo.assignmentChain, { line, variable: `${fnName}(…) → ${varName}` }],
342
+ });
343
+ break;
344
+ }
345
+ }
346
+ }
347
+ }
348
+ }
349
+ }
350
+ ts.forEachChild(node, walkCalls);
351
+ });
352
+ // Pass 2: Check each line for sinks that use tainted variables
353
+ for (let i = 0; i < codeLines.length; i++) {
354
+ const line = codeLines[i];
355
+ const lineNum = i + 1;
356
+ // Skip lines that go through a sanitizer
357
+ if (isSanitized(line))
358
+ continue;
359
+ for (const sink of SINK_PATTERNS) {
360
+ if (!sink.pattern.test(line))
361
+ continue;
362
+ // Check if any tainted variable appears on this line (word-boundary match)
363
+ for (const [varName, taintInfo] of taintMap) {
364
+ if (containsWordBoundary(line, varName)) {
365
+ // Avoid self-referential flows (source IS the sink line)
366
+ if (lineNum === taintInfo.sourceLine)
367
+ continue;
368
+ // Detect guard clauses between source and sink
369
+ const guardReduction = detectGuardClauses(varName, taintInfo.sourceLine, lineNum, codeLines);
370
+ flows.push({
371
+ source: {
372
+ line: taintInfo.sourceLine,
373
+ expression: taintInfo.sourceExpr,
374
+ kind: taintInfo.sourceKind,
375
+ },
376
+ sink: {
377
+ line: lineNum,
378
+ api: sink.pattern.source.slice(0, 40),
379
+ kind: sink.kind,
380
+ },
381
+ intermediates: taintInfo.assignmentChain.filter((a) => a.line !== taintInfo.sourceLine && a.line !== lineNum),
382
+ confidence: Math.max(0.1, 1.0 - guardReduction),
383
+ });
384
+ break; // One flow per sink line
385
+ }
386
+ }
387
+ }
388
+ // Also check for inline source→sink (no variable): eval(req.body.code)
389
+ for (const sink of SINK_PATTERNS) {
390
+ if (!sink.pattern.test(line))
391
+ continue;
392
+ for (const src of SOURCE_PATTERNS) {
393
+ if (src.pattern.test(line)) {
394
+ // Only report if not already captured via variable tracking
395
+ const alreadyCaptured = flows.some((f) => f.sink.line === lineNum);
396
+ if (!alreadyCaptured) {
397
+ const srcMatch = line.match(src.pattern);
398
+ flows.push({
399
+ source: {
400
+ line: lineNum,
401
+ expression: srcMatch?.[0] ?? "user input",
402
+ kind: src.kind,
403
+ },
404
+ sink: {
405
+ line: lineNum,
406
+ api: sink.pattern.source.slice(0, 40),
407
+ kind: sink.kind,
408
+ },
409
+ intermediates: [],
410
+ confidence: 1.0,
411
+ });
412
+ }
413
+ break;
414
+ }
415
+ }
416
+ }
417
+ }
418
+ return deduplicateFlows(flows);
419
+ }
420
+ // ─── Regex-based Taint Analysis (non-JS/TS languages) ────────────────────────
421
+ function analyzeRegexTaint(code) {
422
+ const codeLines = code.split("\n");
423
+ const flows = [];
424
+ // Track tainted variable names
425
+ const tainted = new Map();
426
+ // Assignment pattern: variable = source_expression
427
+ const assignPattern = /^\s*(?:(?:let|const|var|val|auto)\s+)?(\w+)\s*[:=]\s*(.+)/;
428
+ for (let i = 0; i < codeLines.length; i++) {
429
+ const line = codeLines[i];
430
+ const lineNum = i + 1;
431
+ // Check for source assignments
432
+ const assignMatch = line.match(assignPattern);
433
+ if (assignMatch) {
434
+ const [, varName, rhs] = assignMatch;
435
+ // Skip sanitized assignments
436
+ if (isSanitized(rhs))
437
+ continue;
438
+ // Direct source
439
+ for (const src of SOURCE_PATTERNS) {
440
+ if (src.pattern.test(rhs)) {
441
+ tainted.set(varName, {
442
+ sourceExpr: rhs.trim(),
443
+ sourceKind: src.kind,
444
+ sourceLine: lineNum,
445
+ });
446
+ break;
447
+ }
448
+ }
449
+ // Propagation from tainted variable (word-boundary aware)
450
+ if (!tainted.has(varName)) {
451
+ for (const [taintedVar, info] of tainted) {
452
+ if (containsWordBoundary(rhs, taintedVar)) {
453
+ tainted.set(varName, info);
454
+ break;
455
+ }
456
+ }
457
+ }
458
+ }
459
+ // Skip lines with sanitizers for sink checking
460
+ if (isSanitized(line))
461
+ continue;
462
+ // Check for sinks using tainted data
463
+ for (const sink of SINK_PATTERNS) {
464
+ if (!sink.pattern.test(line))
465
+ continue;
466
+ // Check tainted variables (word-boundary aware)
467
+ for (const [varName, info] of tainted) {
468
+ if (containsWordBoundary(line, varName) && lineNum !== info.sourceLine) {
469
+ const guardReduction = detectGuardClauses(varName, info.sourceLine, lineNum, codeLines);
470
+ flows.push({
471
+ source: {
472
+ line: info.sourceLine,
473
+ expression: info.sourceExpr,
474
+ kind: info.sourceKind,
475
+ },
476
+ sink: { line: lineNum, api: sink.pattern.source.slice(0, 40), kind: sink.kind },
477
+ intermediates: [],
478
+ confidence: Math.max(0.1, 1.0 - guardReduction),
479
+ });
480
+ break;
481
+ }
482
+ }
483
+ // Inline source→sink
484
+ for (const src of SOURCE_PATTERNS) {
485
+ if (src.pattern.test(line)) {
486
+ const alreadyCaptured = flows.some((f) => f.sink.line === lineNum);
487
+ if (!alreadyCaptured) {
488
+ const srcMatch = line.match(src.pattern);
489
+ flows.push({
490
+ source: {
491
+ line: lineNum,
492
+ expression: srcMatch?.[0] ?? "user input",
493
+ kind: src.kind,
494
+ },
495
+ sink: { line: lineNum, api: sink.pattern.source.slice(0, 40), kind: sink.kind },
496
+ intermediates: [],
497
+ confidence: 1.0,
498
+ });
499
+ }
500
+ break;
501
+ }
502
+ }
503
+ }
504
+ }
505
+ return deduplicateFlows(flows);
506
+ }
507
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
508
+ function deduplicateFlows(flows) {
509
+ const seen = new Set();
510
+ return flows.filter((f) => {
511
+ const key = `${f.source.line}:${f.sink.line}:${f.sink.kind}`;
512
+ if (seen.has(key))
513
+ return false;
514
+ seen.add(key);
515
+ return true;
516
+ });
517
+ }
518
+ //# sourceMappingURL=taint-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taint-tracker.js","sourceRoot":"","sources":["../../src/ast/taint-tracker.ts"],"names":[],"mappings":"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"}
@@ -37,5 +37,7 @@ export interface CodeStructure {
37
37
  deepNestLines: number[];
38
38
  /** Line numbers with type-safety issues (e.g., `any` usage) */
39
39
  typeAnyLines: number[];
40
+ /** Imported module/package names (e.g., "express", "helmet", "DOMPurify") */
41
+ imports: string[];
40
42
  }
41
43
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ast/types.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gDAAgD;IAChD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,8DAA8D;IAC9D,wBAAwB,EAAE,MAAM,CAAC;IACjC,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAC;IACxB,oDAAoD;IACpD,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,0CAA0C;IAC1C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ast/types.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gDAAgD;IAChD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,8DAA8D;IAC9D,wBAAwB,EAAE,MAAM,CAAC;IACjC,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAC;IACxB,oDAAoD;IACpD,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,0CAA0C;IAC1C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"typescript-ast.d.ts","sourceRoot":"","sources":["../../src/ast/typescript-ast.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAgB,aAAa,EAAE,MAAM,YAAY,CAAC;AAI9D;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,YAAY,GAAG,YAAY,GACpC,aAAa,CAyCf"}
1
+ {"version":3,"file":"typescript-ast.d.ts","sourceRoot":"","sources":["../../src/ast/typescript-ast.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAgB,aAAa,EAAE,MAAM,YAAY,CAAC;AAI9D;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,YAAY,GAAG,aAAa,CA0DpG"}
@@ -19,7 +19,27 @@ export function analyzeTypeScript(code, language) {
19
19
  const deadCodeLines = [];
20
20
  const deepNestLines = [];
21
21
  const typeAnyLines = [];
22
+ const imports = [];
22
23
  const totalLines = code.split("\n").length;
24
+ // Extract imports (import declarations + require() calls)
25
+ ts.forEachChild(sourceFile, (node) => {
26
+ if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
27
+ imports.push(node.moduleSpecifier.text);
28
+ }
29
+ // Handle const x = require("module")
30
+ if (ts.isVariableStatement(node)) {
31
+ for (const decl of node.declarationList.declarations) {
32
+ if (decl.initializer &&
33
+ ts.isCallExpression(decl.initializer) &&
34
+ ts.isIdentifier(decl.initializer.expression) &&
35
+ decl.initializer.expression.text === "require" &&
36
+ decl.initializer.arguments.length === 1 &&
37
+ ts.isStringLiteral(decl.initializer.arguments[0])) {
38
+ imports.push(decl.initializer.arguments[0].text);
39
+ }
40
+ }
41
+ }
42
+ });
23
43
  // Walk the AST
24
44
  visitNode(sourceFile, 0, sourceFile, functions, deadCodeLines, deepNestLines, typeAnyLines);
25
45
  // Compute file-level cyclomatic complexity
@@ -34,6 +54,7 @@ export function analyzeTypeScript(code, language) {
34
54
  deadCodeLines,
35
55
  deepNestLines,
36
56
  typeAnyLines,
57
+ imports,
37
58
  };
38
59
  }
39
60
  // ─── AST Walker ──────────────────────────────────────────────────────────────
@@ -109,8 +130,7 @@ function getFunctionName(node) {
109
130
  if (ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)) {
110
131
  return node.parent.name.text;
111
132
  }
112
- if (ts.isPropertyAssignment(node.parent) &&
113
- ts.isIdentifier(node.parent.name)) {
133
+ if (ts.isPropertyAssignment(node.parent) && ts.isIdentifier(node.parent.name)) {
114
134
  return node.parent.name.text;
115
135
  }
116
136
  if (ts.isArrowFunction(node) && ts.isVariableDeclaration(node.parent)) {
@@ -149,11 +169,11 @@ function computeCyclomaticComplexity(node) {
149
169
  break;
150
170
  case ts.SyntaxKind.BinaryExpression: {
151
171
  const binOp = n.operatorToken.kind;
152
- if (binOp === ts.SyntaxKind.AmpersandAmpersandToken ||
153
- binOp === ts.SyntaxKind.BarBarToken ||
154
- binOp === ts.SyntaxKind.QuestionQuestionToken) {
172
+ if (binOp === ts.SyntaxKind.AmpersandAmpersandToken || binOp === ts.SyntaxKind.BarBarToken) {
155
173
  complexity++;
156
174
  }
175
+ // Note: ?? (QuestionQuestionToken) is intentionally excluded —
176
+ // it's a null-safe default, not genuine branching logic.
157
177
  break;
158
178
  }
159
179
  }