driftdetect-core 0.4.6 → 0.5.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 (325) hide show
  1. package/dist/call-graph/extractors/csharp-data-access-extractor.d.ts +8 -0
  2. package/dist/call-graph/extractors/csharp-data-access-extractor.d.ts.map +1 -1
  3. package/dist/call-graph/extractors/csharp-data-access-extractor.js +8 -0
  4. package/dist/call-graph/extractors/csharp-data-access-extractor.js.map +1 -1
  5. package/dist/call-graph/extractors/csharp-extractor.d.ts +35 -0
  6. package/dist/call-graph/extractors/csharp-extractor.d.ts.map +1 -1
  7. package/dist/call-graph/extractors/csharp-extractor.js +362 -4
  8. package/dist/call-graph/extractors/csharp-extractor.js.map +1 -1
  9. package/dist/call-graph/extractors/csharp-hybrid-extractor.d.ts +37 -0
  10. package/dist/call-graph/extractors/csharp-hybrid-extractor.d.ts.map +1 -0
  11. package/dist/call-graph/extractors/csharp-hybrid-extractor.js +408 -0
  12. package/dist/call-graph/extractors/csharp-hybrid-extractor.js.map +1 -0
  13. package/dist/call-graph/extractors/hybrid-extractor-base.d.ts +102 -0
  14. package/dist/call-graph/extractors/hybrid-extractor-base.d.ts.map +1 -0
  15. package/dist/call-graph/extractors/hybrid-extractor-base.js +289 -0
  16. package/dist/call-graph/extractors/hybrid-extractor-base.js.map +1 -0
  17. package/dist/call-graph/extractors/index.d.ts +17 -13
  18. package/dist/call-graph/extractors/index.d.ts.map +1 -1
  19. package/dist/call-graph/extractors/index.js +24 -23
  20. package/dist/call-graph/extractors/index.js.map +1 -1
  21. package/dist/call-graph/extractors/java-data-access-extractor.d.ts +8 -0
  22. package/dist/call-graph/extractors/java-data-access-extractor.d.ts.map +1 -1
  23. package/dist/call-graph/extractors/java-data-access-extractor.js +8 -0
  24. package/dist/call-graph/extractors/java-data-access-extractor.js.map +1 -1
  25. package/dist/call-graph/extractors/java-extractor.d.ts +15 -0
  26. package/dist/call-graph/extractors/java-extractor.d.ts.map +1 -1
  27. package/dist/call-graph/extractors/java-extractor.js +120 -4
  28. package/dist/call-graph/extractors/java-extractor.js.map +1 -1
  29. package/dist/call-graph/extractors/java-hybrid-extractor.d.ts +36 -0
  30. package/dist/call-graph/extractors/java-hybrid-extractor.d.ts.map +1 -0
  31. package/dist/call-graph/extractors/java-hybrid-extractor.js +426 -0
  32. package/dist/call-graph/extractors/java-hybrid-extractor.js.map +1 -0
  33. package/dist/call-graph/extractors/php-data-access-extractor.d.ts +8 -0
  34. package/dist/call-graph/extractors/php-data-access-extractor.d.ts.map +1 -1
  35. package/dist/call-graph/extractors/php-data-access-extractor.js +8 -0
  36. package/dist/call-graph/extractors/php-data-access-extractor.js.map +1 -1
  37. package/dist/call-graph/extractors/php-extractor.d.ts +48 -1
  38. package/dist/call-graph/extractors/php-extractor.d.ts.map +1 -1
  39. package/dist/call-graph/extractors/php-extractor.js +460 -6
  40. package/dist/call-graph/extractors/php-extractor.js.map +1 -1
  41. package/dist/call-graph/extractors/php-hybrid-extractor.d.ts +35 -0
  42. package/dist/call-graph/extractors/php-hybrid-extractor.d.ts.map +1 -0
  43. package/dist/call-graph/extractors/php-hybrid-extractor.js +393 -0
  44. package/dist/call-graph/extractors/php-hybrid-extractor.js.map +1 -0
  45. package/dist/call-graph/extractors/python-data-access-extractor.d.ts +8 -0
  46. package/dist/call-graph/extractors/python-data-access-extractor.d.ts.map +1 -1
  47. package/dist/call-graph/extractors/python-data-access-extractor.js +8 -0
  48. package/dist/call-graph/extractors/python-data-access-extractor.js.map +1 -1
  49. package/dist/call-graph/extractors/python-hybrid-extractor.d.ts +85 -0
  50. package/dist/call-graph/extractors/python-hybrid-extractor.d.ts.map +1 -0
  51. package/dist/call-graph/extractors/python-hybrid-extractor.js +462 -0
  52. package/dist/call-graph/extractors/python-hybrid-extractor.js.map +1 -0
  53. package/dist/call-graph/extractors/regex/base-regex-extractor.d.ts +154 -0
  54. package/dist/call-graph/extractors/regex/base-regex-extractor.d.ts.map +1 -0
  55. package/dist/call-graph/extractors/regex/base-regex-extractor.js +346 -0
  56. package/dist/call-graph/extractors/regex/base-regex-extractor.js.map +1 -0
  57. package/dist/call-graph/extractors/regex/csharp-regex.d.ts +34 -0
  58. package/dist/call-graph/extractors/regex/csharp-regex.d.ts.map +1 -0
  59. package/dist/call-graph/extractors/regex/csharp-regex.js +393 -0
  60. package/dist/call-graph/extractors/regex/csharp-regex.js.map +1 -0
  61. package/dist/call-graph/extractors/regex/index.d.ts +25 -0
  62. package/dist/call-graph/extractors/regex/index.d.ts.map +1 -0
  63. package/dist/call-graph/extractors/regex/index.js +66 -0
  64. package/dist/call-graph/extractors/regex/index.js.map +1 -0
  65. package/dist/call-graph/extractors/regex/java-regex.d.ts +34 -0
  66. package/dist/call-graph/extractors/regex/java-regex.d.ts.map +1 -0
  67. package/dist/call-graph/extractors/regex/java-regex.js +327 -0
  68. package/dist/call-graph/extractors/regex/java-regex.js.map +1 -0
  69. package/dist/call-graph/extractors/regex/php-regex.d.ts +30 -0
  70. package/dist/call-graph/extractors/regex/php-regex.d.ts.map +1 -0
  71. package/dist/call-graph/extractors/regex/php-regex.js +333 -0
  72. package/dist/call-graph/extractors/regex/php-regex.js.map +1 -0
  73. package/dist/call-graph/extractors/regex/python-regex.d.ts +46 -0
  74. package/dist/call-graph/extractors/regex/python-regex.d.ts.map +1 -0
  75. package/dist/call-graph/extractors/regex/python-regex.js +380 -0
  76. package/dist/call-graph/extractors/regex/python-regex.js.map +1 -0
  77. package/dist/call-graph/extractors/regex/typescript-regex.d.ts +27 -0
  78. package/dist/call-graph/extractors/regex/typescript-regex.d.ts.map +1 -0
  79. package/dist/call-graph/extractors/regex/typescript-regex.js +349 -0
  80. package/dist/call-graph/extractors/regex/typescript-regex.js.map +1 -0
  81. package/dist/call-graph/extractors/semantic-data-access-scanner.d.ts +7 -0
  82. package/dist/call-graph/extractors/semantic-data-access-scanner.d.ts.map +1 -1
  83. package/dist/call-graph/extractors/semantic-data-access-scanner.js +7 -0
  84. package/dist/call-graph/extractors/semantic-data-access-scanner.js.map +1 -1
  85. package/dist/call-graph/extractors/types.d.ts +111 -0
  86. package/dist/call-graph/extractors/types.d.ts.map +1 -0
  87. package/dist/call-graph/extractors/types.js +68 -0
  88. package/dist/call-graph/extractors/types.js.map +1 -0
  89. package/dist/call-graph/extractors/typescript-data-access-extractor.d.ts +8 -0
  90. package/dist/call-graph/extractors/typescript-data-access-extractor.d.ts.map +1 -1
  91. package/dist/call-graph/extractors/typescript-data-access-extractor.js +8 -0
  92. package/dist/call-graph/extractors/typescript-data-access-extractor.js.map +1 -1
  93. package/dist/call-graph/extractors/typescript-hybrid-extractor.d.ts +116 -0
  94. package/dist/call-graph/extractors/typescript-hybrid-extractor.d.ts.map +1 -0
  95. package/dist/call-graph/extractors/typescript-hybrid-extractor.js +635 -0
  96. package/dist/call-graph/extractors/typescript-hybrid-extractor.js.map +1 -0
  97. package/dist/error-handling/error-handling-analyzer.d.ts +73 -0
  98. package/dist/error-handling/error-handling-analyzer.d.ts.map +1 -0
  99. package/dist/error-handling/error-handling-analyzer.js +706 -0
  100. package/dist/error-handling/error-handling-analyzer.js.map +1 -0
  101. package/dist/error-handling/index.d.ts +8 -0
  102. package/dist/error-handling/index.d.ts.map +1 -0
  103. package/dist/error-handling/index.js +8 -0
  104. package/dist/error-handling/index.js.map +1 -0
  105. package/dist/error-handling/types.d.ts +307 -0
  106. package/dist/error-handling/types.d.ts.map +1 -0
  107. package/dist/error-handling/types.js +7 -0
  108. package/dist/error-handling/types.js.map +1 -0
  109. package/dist/index.d.ts +14 -0
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +29 -0
  112. package/dist/index.js.map +1 -1
  113. package/dist/lake/pattern-shard-store.d.ts +6 -0
  114. package/dist/lake/pattern-shard-store.d.ts.map +1 -1
  115. package/dist/lake/pattern-shard-store.js +6 -0
  116. package/dist/lake/pattern-shard-store.js.map +1 -1
  117. package/dist/module-coupling/coupling-analyzer.d.ts +73 -0
  118. package/dist/module-coupling/coupling-analyzer.d.ts.map +1 -0
  119. package/dist/module-coupling/coupling-analyzer.js +668 -0
  120. package/dist/module-coupling/coupling-analyzer.js.map +1 -0
  121. package/dist/module-coupling/index.d.ts +9 -0
  122. package/dist/module-coupling/index.d.ts.map +1 -0
  123. package/dist/module-coupling/index.js +9 -0
  124. package/dist/module-coupling/index.js.map +1 -0
  125. package/dist/module-coupling/types.d.ts +273 -0
  126. package/dist/module-coupling/types.d.ts.map +1 -0
  127. package/dist/module-coupling/types.js +8 -0
  128. package/dist/module-coupling/types.js.map +1 -0
  129. package/dist/patterns/adapters/index.d.ts +11 -0
  130. package/dist/patterns/adapters/index.d.ts.map +1 -0
  131. package/dist/patterns/adapters/index.js +11 -0
  132. package/dist/patterns/adapters/index.js.map +1 -0
  133. package/dist/patterns/adapters/pattern-store-adapter.d.ts +59 -0
  134. package/dist/patterns/adapters/pattern-store-adapter.d.ts.map +1 -0
  135. package/dist/patterns/adapters/pattern-store-adapter.js +468 -0
  136. package/dist/patterns/adapters/pattern-store-adapter.js.map +1 -0
  137. package/dist/patterns/adapters/service-factory.d.ts +40 -0
  138. package/dist/patterns/adapters/service-factory.d.ts.map +1 -0
  139. package/dist/patterns/adapters/service-factory.js +144 -0
  140. package/dist/patterns/adapters/service-factory.js.map +1 -0
  141. package/dist/patterns/errors.d.ts +32 -0
  142. package/dist/patterns/errors.d.ts.map +1 -0
  143. package/dist/patterns/errors.js +45 -0
  144. package/dist/patterns/errors.js.map +1 -0
  145. package/dist/patterns/impl/cached-repository.d.ts +79 -0
  146. package/dist/patterns/impl/cached-repository.d.ts.map +1 -0
  147. package/dist/patterns/impl/cached-repository.js +296 -0
  148. package/dist/patterns/impl/cached-repository.js.map +1 -0
  149. package/dist/patterns/impl/file-repository.d.ts +75 -0
  150. package/dist/patterns/impl/file-repository.d.ts.map +1 -0
  151. package/dist/patterns/impl/file-repository.js +507 -0
  152. package/dist/patterns/impl/file-repository.js.map +1 -0
  153. package/dist/patterns/impl/index.d.ts +16 -0
  154. package/dist/patterns/impl/index.d.ts.map +1 -0
  155. package/dist/patterns/impl/index.js +21 -0
  156. package/dist/patterns/impl/index.js.map +1 -0
  157. package/dist/patterns/impl/memory-repository.d.ts +56 -0
  158. package/dist/patterns/impl/memory-repository.d.ts.map +1 -0
  159. package/dist/patterns/impl/memory-repository.js +323 -0
  160. package/dist/patterns/impl/memory-repository.js.map +1 -0
  161. package/dist/patterns/impl/pattern-service.d.ts +52 -0
  162. package/dist/patterns/impl/pattern-service.d.ts.map +1 -0
  163. package/dist/patterns/impl/pattern-service.js +382 -0
  164. package/dist/patterns/impl/pattern-service.js.map +1 -0
  165. package/dist/patterns/impl/repository-factory.d.ts +44 -0
  166. package/dist/patterns/impl/repository-factory.d.ts.map +1 -0
  167. package/dist/patterns/impl/repository-factory.js +140 -0
  168. package/dist/patterns/impl/repository-factory.js.map +1 -0
  169. package/dist/patterns/impl/unified-file-repository.d.ts +111 -0
  170. package/dist/patterns/impl/unified-file-repository.d.ts.map +1 -0
  171. package/dist/patterns/impl/unified-file-repository.js +677 -0
  172. package/dist/patterns/impl/unified-file-repository.js.map +1 -0
  173. package/dist/patterns/index.d.ts +23 -0
  174. package/dist/patterns/index.d.ts.map +1 -0
  175. package/dist/patterns/index.js +41 -0
  176. package/dist/patterns/index.js.map +1 -0
  177. package/dist/patterns/repository.d.ts +241 -0
  178. package/dist/patterns/repository.d.ts.map +1 -0
  179. package/dist/patterns/repository.js +23 -0
  180. package/dist/patterns/repository.js.map +1 -0
  181. package/dist/patterns/service.d.ts +245 -0
  182. package/dist/patterns/service.d.ts.map +1 -0
  183. package/dist/patterns/service.js +25 -0
  184. package/dist/patterns/service.js.map +1 -0
  185. package/dist/patterns/types.d.ts +227 -0
  186. package/dist/patterns/types.d.ts.map +1 -0
  187. package/dist/patterns/types.js +117 -0
  188. package/dist/patterns/types.js.map +1 -0
  189. package/dist/store/pattern-store.d.ts +6 -0
  190. package/dist/store/pattern-store.d.ts.map +1 -1
  191. package/dist/store/pattern-store.js +6 -0
  192. package/dist/store/pattern-store.js.map +1 -1
  193. package/dist/test-topology/extractors/base-test-extractor.d.ts +89 -0
  194. package/dist/test-topology/extractors/base-test-extractor.d.ts.map +1 -0
  195. package/dist/test-topology/extractors/base-test-extractor.js +187 -0
  196. package/dist/test-topology/extractors/base-test-extractor.js.map +1 -0
  197. package/dist/test-topology/extractors/csharp-test-extractor.d.ts +23 -0
  198. package/dist/test-topology/extractors/csharp-test-extractor.d.ts.map +1 -0
  199. package/dist/test-topology/extractors/csharp-test-extractor.js +367 -0
  200. package/dist/test-topology/extractors/csharp-test-extractor.js.map +1 -0
  201. package/dist/test-topology/extractors/index.d.ts +12 -0
  202. package/dist/test-topology/extractors/index.d.ts.map +1 -0
  203. package/dist/test-topology/extractors/index.js +12 -0
  204. package/dist/test-topology/extractors/index.js.map +1 -0
  205. package/dist/test-topology/extractors/java-test-extractor.d.ts +20 -0
  206. package/dist/test-topology/extractors/java-test-extractor.d.ts.map +1 -0
  207. package/dist/test-topology/extractors/java-test-extractor.js +275 -0
  208. package/dist/test-topology/extractors/java-test-extractor.js.map +1 -0
  209. package/dist/test-topology/extractors/php-test-extractor.d.ts +24 -0
  210. package/dist/test-topology/extractors/php-test-extractor.d.ts.map +1 -0
  211. package/dist/test-topology/extractors/php-test-extractor.js +409 -0
  212. package/dist/test-topology/extractors/php-test-extractor.js.map +1 -0
  213. package/dist/test-topology/extractors/python-test-extractor.d.ts +23 -0
  214. package/dist/test-topology/extractors/python-test-extractor.d.ts.map +1 -0
  215. package/dist/test-topology/extractors/python-test-extractor.js +342 -0
  216. package/dist/test-topology/extractors/python-test-extractor.js.map +1 -0
  217. package/dist/test-topology/extractors/regex/csharp-test-regex.d.ts +51 -0
  218. package/dist/test-topology/extractors/regex/csharp-test-regex.d.ts.map +1 -0
  219. package/dist/test-topology/extractors/regex/csharp-test-regex.js +383 -0
  220. package/dist/test-topology/extractors/regex/csharp-test-regex.js.map +1 -0
  221. package/dist/test-topology/extractors/regex/index.d.ts +18 -0
  222. package/dist/test-topology/extractors/regex/index.d.ts.map +1 -0
  223. package/dist/test-topology/extractors/regex/index.js +43 -0
  224. package/dist/test-topology/extractors/regex/index.js.map +1 -0
  225. package/dist/test-topology/extractors/regex/java-test-regex.d.ts +50 -0
  226. package/dist/test-topology/extractors/regex/java-test-regex.d.ts.map +1 -0
  227. package/dist/test-topology/extractors/regex/java-test-regex.js +370 -0
  228. package/dist/test-topology/extractors/regex/java-test-regex.js.map +1 -0
  229. package/dist/test-topology/extractors/regex/php-test-regex.d.ts +56 -0
  230. package/dist/test-topology/extractors/regex/php-test-regex.d.ts.map +1 -0
  231. package/dist/test-topology/extractors/regex/php-test-regex.js +503 -0
  232. package/dist/test-topology/extractors/regex/php-test-regex.js.map +1 -0
  233. package/dist/test-topology/extractors/regex/python-test-regex.d.ts +57 -0
  234. package/dist/test-topology/extractors/regex/python-test-regex.d.ts.map +1 -0
  235. package/dist/test-topology/extractors/regex/python-test-regex.js +381 -0
  236. package/dist/test-topology/extractors/regex/python-test-regex.js.map +1 -0
  237. package/dist/test-topology/extractors/regex/typescript-test-regex.d.ts +60 -0
  238. package/dist/test-topology/extractors/regex/typescript-test-regex.d.ts.map +1 -0
  239. package/dist/test-topology/extractors/regex/typescript-test-regex.js +368 -0
  240. package/dist/test-topology/extractors/regex/typescript-test-regex.js.map +1 -0
  241. package/dist/test-topology/extractors/typescript-test-extractor.d.ts +24 -0
  242. package/dist/test-topology/extractors/typescript-test-extractor.d.ts.map +1 -0
  243. package/dist/test-topology/extractors/typescript-test-extractor.js +266 -0
  244. package/dist/test-topology/extractors/typescript-test-extractor.js.map +1 -0
  245. package/dist/test-topology/hybrid-test-topology-analyzer.d.ts +98 -0
  246. package/dist/test-topology/hybrid-test-topology-analyzer.d.ts.map +1 -0
  247. package/dist/test-topology/hybrid-test-topology-analyzer.js +555 -0
  248. package/dist/test-topology/hybrid-test-topology-analyzer.js.map +1 -0
  249. package/dist/test-topology/index.d.ts +16 -0
  250. package/dist/test-topology/index.d.ts.map +1 -0
  251. package/dist/test-topology/index.js +19 -0
  252. package/dist/test-topology/index.js.map +1 -0
  253. package/dist/test-topology/test-topology-analyzer.d.ts +85 -0
  254. package/dist/test-topology/test-topology-analyzer.d.ts.map +1 -0
  255. package/dist/test-topology/test-topology-analyzer.js +538 -0
  256. package/dist/test-topology/test-topology-analyzer.js.map +1 -0
  257. package/dist/test-topology/types.d.ts +300 -0
  258. package/dist/test-topology/types.d.ts.map +1 -0
  259. package/dist/test-topology/types.js +7 -0
  260. package/dist/test-topology/types.js.map +1 -0
  261. package/dist/wrappers/clustering/clusterer.d.ts +43 -0
  262. package/dist/wrappers/clustering/clusterer.d.ts.map +1 -0
  263. package/dist/wrappers/clustering/clusterer.js +374 -0
  264. package/dist/wrappers/clustering/clusterer.js.map +1 -0
  265. package/dist/wrappers/clustering/exclusions.d.ts +47 -0
  266. package/dist/wrappers/clustering/exclusions.d.ts.map +1 -0
  267. package/dist/wrappers/clustering/exclusions.js +318 -0
  268. package/dist/wrappers/clustering/exclusions.js.map +1 -0
  269. package/dist/wrappers/clustering/index.d.ts +6 -0
  270. package/dist/wrappers/clustering/index.d.ts.map +1 -0
  271. package/dist/wrappers/clustering/index.js +6 -0
  272. package/dist/wrappers/clustering/index.js.map +1 -0
  273. package/dist/wrappers/detection/detector.d.ts +69 -0
  274. package/dist/wrappers/detection/detector.d.ts.map +1 -0
  275. package/dist/wrappers/detection/detector.js +279 -0
  276. package/dist/wrappers/detection/detector.js.map +1 -0
  277. package/dist/wrappers/detection/index.d.ts +5 -0
  278. package/dist/wrappers/detection/index.d.ts.map +1 -0
  279. package/dist/wrappers/detection/index.js +5 -0
  280. package/dist/wrappers/detection/index.js.map +1 -0
  281. package/dist/wrappers/export/index.d.ts +5 -0
  282. package/dist/wrappers/export/index.d.ts.map +1 -0
  283. package/dist/wrappers/export/index.js +5 -0
  284. package/dist/wrappers/export/index.js.map +1 -0
  285. package/dist/wrappers/export/json.d.ts +127 -0
  286. package/dist/wrappers/export/json.d.ts.map +1 -0
  287. package/dist/wrappers/export/json.js +160 -0
  288. package/dist/wrappers/export/json.js.map +1 -0
  289. package/dist/wrappers/index.d.ts +56 -0
  290. package/dist/wrappers/index.d.ts.map +1 -0
  291. package/dist/wrappers/index.js +159 -0
  292. package/dist/wrappers/index.js.map +1 -0
  293. package/dist/wrappers/integration/adapter.d.ts +52 -0
  294. package/dist/wrappers/integration/adapter.d.ts.map +1 -0
  295. package/dist/wrappers/integration/adapter.js +209 -0
  296. package/dist/wrappers/integration/adapter.js.map +1 -0
  297. package/dist/wrappers/integration/index.d.ts +9 -0
  298. package/dist/wrappers/integration/index.d.ts.map +1 -0
  299. package/dist/wrappers/integration/index.js +12 -0
  300. package/dist/wrappers/integration/index.js.map +1 -0
  301. package/dist/wrappers/integration/pattern-adapter.d.ts +52 -0
  302. package/dist/wrappers/integration/pattern-adapter.d.ts.map +1 -0
  303. package/dist/wrappers/integration/pattern-adapter.js +192 -0
  304. package/dist/wrappers/integration/pattern-adapter.js.map +1 -0
  305. package/dist/wrappers/integration/scanner.d.ts +85 -0
  306. package/dist/wrappers/integration/scanner.d.ts.map +1 -0
  307. package/dist/wrappers/integration/scanner.js +367 -0
  308. package/dist/wrappers/integration/scanner.js.map +1 -0
  309. package/dist/wrappers/primitives/discovery.d.ts +57 -0
  310. package/dist/wrappers/primitives/discovery.d.ts.map +1 -0
  311. package/dist/wrappers/primitives/discovery.js +389 -0
  312. package/dist/wrappers/primitives/discovery.js.map +1 -0
  313. package/dist/wrappers/primitives/index.d.ts +6 -0
  314. package/dist/wrappers/primitives/index.d.ts.map +1 -0
  315. package/dist/wrappers/primitives/index.js +6 -0
  316. package/dist/wrappers/primitives/index.js.map +1 -0
  317. package/dist/wrappers/primitives/registry.d.ts +63 -0
  318. package/dist/wrappers/primitives/registry.d.ts.map +1 -0
  319. package/dist/wrappers/primitives/registry.js +447 -0
  320. package/dist/wrappers/primitives/registry.js.map +1 -0
  321. package/dist/wrappers/types.d.ts +137 -0
  322. package/dist/wrappers/types.d.ts.map +1 -0
  323. package/dist/wrappers/types.js +7 -0
  324. package/dist/wrappers/types.js.map +1 -0
  325. package/package.json +5 -1
@@ -0,0 +1,706 @@
1
+ /**
2
+ * Error Handling Analyzer
3
+ *
4
+ * Analyzes error handling patterns, boundaries, and propagation chains.
5
+ * Detects gaps in error handling coverage.
6
+ */
7
+ // ============================================================================
8
+ // Analyzer
9
+ // ============================================================================
10
+ export class ErrorHandlingAnalyzer {
11
+ topology = null;
12
+ callGraph = null;
13
+ options;
14
+ constructor(options) {
15
+ this.options = {
16
+ includeAsync: true,
17
+ detectFrameworkBoundaries: true,
18
+ maxPropagationDepth: 20,
19
+ ...options,
20
+ };
21
+ }
22
+ /**
23
+ * Set the call graph for analysis
24
+ */
25
+ setCallGraph(callGraph) {
26
+ this.callGraph = callGraph;
27
+ }
28
+ /**
29
+ * Build the error handling topology
30
+ */
31
+ build() {
32
+ if (!this.callGraph) {
33
+ throw new Error('Call graph required. Call setCallGraph() first.');
34
+ }
35
+ const functions = new Map();
36
+ const boundaries = [];
37
+ const propagationChains = [];
38
+ // Phase 1: Analyze each function's error handling
39
+ for (const [funcId, func] of this.callGraph.functions) {
40
+ const profile = this.analyzeFunction(funcId, func);
41
+ functions.set(funcId, profile);
42
+ // Detect boundaries
43
+ if (profile.hasTryCatch && profile.catchClauses.length > 0) {
44
+ const boundary = this.detectBoundary(funcId, func, profile);
45
+ if (boundary) {
46
+ boundaries.push(boundary);
47
+ }
48
+ }
49
+ }
50
+ // Phase 2: Build propagation chains for throwing functions
51
+ for (const [funcId, profile] of functions) {
52
+ if (profile.canThrow) {
53
+ const chain = this.traceErrorPropagation(funcId, functions);
54
+ if (chain) {
55
+ propagationChains.push(chain);
56
+ }
57
+ }
58
+ }
59
+ // Phase 3: Find unhandled paths
60
+ const unhandledPaths = this.findUnhandledPaths(propagationChains, functions);
61
+ this.topology = {
62
+ functions,
63
+ boundaries,
64
+ unhandledPaths,
65
+ propagationChains,
66
+ generatedAt: new Date().toISOString(),
67
+ projectRoot: this.options.rootDir,
68
+ };
69
+ return this.topology;
70
+ }
71
+ /**
72
+ * Get the built topology
73
+ */
74
+ getTopology() {
75
+ return this.topology;
76
+ }
77
+ /**
78
+ * Get aggregate metrics
79
+ */
80
+ getMetrics() {
81
+ if (!this.topology)
82
+ return null;
83
+ const functions = Array.from(this.topology.functions.values());
84
+ const totalFunctions = functions.length;
85
+ const functionsWithTryCatch = functions.filter(f => f.hasTryCatch).length;
86
+ const functionsThatThrow = functions.filter(f => f.canThrow).length;
87
+ const swallowedErrorCount = functions.filter(f => f.catchClauses.some(c => c.action === 'swallow')).length;
88
+ const unhandledAsyncCount = functions.filter(f => f.asyncHandling?.hasUnhandledPromises).length;
89
+ const avgQualityScore = totalFunctions > 0
90
+ ? Math.round(functions.reduce((sum, f) => sum + f.qualityScore, 0) / totalFunctions)
91
+ : 0;
92
+ const unhandledBySeverity = {
93
+ critical: 0,
94
+ high: 0,
95
+ medium: 0,
96
+ low: 0,
97
+ };
98
+ for (const path of this.topology.unhandledPaths) {
99
+ unhandledBySeverity[path.severity]++;
100
+ }
101
+ const frameworkBoundaries = this.topology.boundaries.filter(b => b.isFrameworkBoundary).length;
102
+ return {
103
+ totalFunctions,
104
+ functionsWithTryCatch,
105
+ functionsThatThrow,
106
+ boundaryCount: this.topology.boundaries.length,
107
+ unhandledCount: this.topology.unhandledPaths.length,
108
+ unhandledBySeverity,
109
+ avgQualityScore,
110
+ swallowedErrorCount,
111
+ unhandledAsyncCount,
112
+ frameworkBoundaries,
113
+ };
114
+ }
115
+ /**
116
+ * Get summary for display
117
+ */
118
+ getSummary() {
119
+ const metrics = this.getMetrics();
120
+ if (!metrics || !this.topology)
121
+ return null;
122
+ const coveragePercent = metrics.totalFunctions > 0
123
+ ? Math.round((metrics.functionsWithTryCatch / metrics.totalFunctions) * 100)
124
+ : 0;
125
+ const qualityDistribution = {
126
+ excellent: 0,
127
+ good: 0,
128
+ fair: 0,
129
+ poor: 0,
130
+ };
131
+ for (const func of this.topology.functions.values()) {
132
+ const quality = this.scoreToQuality(func.qualityScore);
133
+ qualityDistribution[quality]++;
134
+ }
135
+ const topIssues = [];
136
+ if (metrics.swallowedErrorCount > 0) {
137
+ topIssues.push({
138
+ type: 'swallowed',
139
+ count: metrics.swallowedErrorCount,
140
+ severity: 'high',
141
+ });
142
+ }
143
+ if (metrics.unhandledAsyncCount > 0) {
144
+ topIssues.push({
145
+ type: 'unhandled-async',
146
+ count: metrics.unhandledAsyncCount,
147
+ severity: 'high',
148
+ });
149
+ }
150
+ if (metrics.unhandledBySeverity.critical > 0) {
151
+ topIssues.push({
152
+ type: 'no-boundary',
153
+ count: metrics.unhandledBySeverity.critical,
154
+ severity: 'critical',
155
+ });
156
+ }
157
+ // Sort by severity
158
+ const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
159
+ topIssues.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
160
+ return {
161
+ totalFunctions: metrics.totalFunctions,
162
+ coveragePercent,
163
+ unhandledPaths: metrics.unhandledCount,
164
+ criticalUnhandled: metrics.unhandledBySeverity.critical,
165
+ avgQuality: metrics.avgQualityScore,
166
+ qualityDistribution,
167
+ topIssues: topIssues.slice(0, 5),
168
+ };
169
+ }
170
+ /**
171
+ * Analyze a specific function
172
+ */
173
+ analyzeFunction(funcId, func) {
174
+ const funcNode = func ?? this.callGraph?.functions.get(funcId);
175
+ if (!funcNode) {
176
+ throw new Error(`Function not found: ${funcId}`);
177
+ }
178
+ // Detect error handling constructs from function metadata
179
+ const hasTryCatch = this.detectTryCatch(funcNode);
180
+ const canThrow = this.detectThrows(funcNode);
181
+ const throwLocations = this.findThrowLocations(funcNode);
182
+ const catchClauses = this.extractCatchClauses(funcNode);
183
+ const rethrows = catchClauses.some(c => c.action === 'rethrow');
184
+ const isAsync = this.isAsyncFunction(funcNode);
185
+ const asyncHandling = isAsync && this.options.includeAsync
186
+ ? this.analyzeAsyncHandling(funcNode)
187
+ : null;
188
+ const qualityScore = this.calculateQualityScore({
189
+ hasTryCatch,
190
+ canThrow,
191
+ catchClauses,
192
+ rethrows,
193
+ asyncHandling,
194
+ isAsync,
195
+ });
196
+ return {
197
+ functionId: funcId,
198
+ file: funcNode.file,
199
+ name: funcNode.name,
200
+ qualifiedName: funcNode.className
201
+ ? `${funcNode.className}.${funcNode.name}`
202
+ : funcNode.name,
203
+ line: funcNode.startLine,
204
+ hasTryCatch,
205
+ canThrow,
206
+ throwLocations,
207
+ catchClauses,
208
+ rethrows,
209
+ asyncHandling,
210
+ isAsync,
211
+ qualityScore,
212
+ };
213
+ }
214
+ /**
215
+ * Get detailed analysis for a function
216
+ */
217
+ getFunctionAnalysis(funcId) {
218
+ if (!this.topology || !this.callGraph)
219
+ return null;
220
+ const profile = this.topology.functions.get(funcId);
221
+ if (!profile)
222
+ return null;
223
+ const func = this.callGraph.functions.get(funcId);
224
+ if (!func)
225
+ return null;
226
+ // Find incoming errors (from callees)
227
+ const incomingErrors = [];
228
+ for (const call of func.calls) {
229
+ for (const candidate of call.resolvedCandidates) {
230
+ const calleeProfile = this.topology.functions.get(candidate);
231
+ if (calleeProfile?.canThrow) {
232
+ incomingErrors.push({
233
+ from: candidate,
234
+ errorType: 'Error', // Would need AST analysis for specific types
235
+ });
236
+ }
237
+ }
238
+ }
239
+ // Find outgoing errors (to callers)
240
+ const outgoingErrors = [];
241
+ for (const caller of func.calledBy) {
242
+ const callerProfile = this.topology.functions.get(caller.callerId);
243
+ outgoingErrors.push({
244
+ to: caller.callerId,
245
+ caught: callerProfile?.hasTryCatch ?? false,
246
+ });
247
+ }
248
+ // Check if protected by boundary
249
+ const foundBoundary = this.topology.boundaries.find(b => b.catchesFrom.includes(funcId));
250
+ // Find issues
251
+ const issues = [];
252
+ if (profile.canThrow && !profile.hasTryCatch && !foundBoundary) {
253
+ issues.push({
254
+ type: 'unprotected-throw',
255
+ message: 'Function throws but has no error handling',
256
+ severity: 'high',
257
+ });
258
+ }
259
+ if (profile.catchClauses.some(c => c.action === 'swallow')) {
260
+ const swallowLine = profile.catchClauses.find(c => c.action === 'swallow')?.line;
261
+ issues.push({
262
+ type: 'swallowed-error',
263
+ message: 'Error is caught but swallowed (empty catch block)',
264
+ severity: 'medium',
265
+ ...(swallowLine !== undefined && { line: swallowLine }),
266
+ });
267
+ }
268
+ if (profile.asyncHandling?.hasUnhandledPromises) {
269
+ issues.push({
270
+ type: 'unhandled-promise',
271
+ message: 'Async function has unhandled promise rejections',
272
+ severity: 'high',
273
+ });
274
+ }
275
+ if (profile.catchClauses.some(c => c.errorType === 'any')) {
276
+ issues.push({
277
+ type: 'bare-catch',
278
+ message: 'Catch clause catches all errors without type checking',
279
+ severity: 'low',
280
+ });
281
+ }
282
+ // Generate suggestions
283
+ const suggestions = [];
284
+ if (issues.some(i => i.type === 'unprotected-throw')) {
285
+ suggestions.push('Add try/catch block or ensure caller handles errors');
286
+ }
287
+ if (issues.some(i => i.type === 'swallowed-error')) {
288
+ suggestions.push('Log the error or rethrow it instead of swallowing');
289
+ }
290
+ if (issues.some(i => i.type === 'unhandled-promise')) {
291
+ suggestions.push('Add .catch() to promise chains or use try/catch with await');
292
+ }
293
+ const result = {
294
+ profile,
295
+ incomingErrors,
296
+ outgoingErrors,
297
+ isProtected: !!foundBoundary,
298
+ issues,
299
+ suggestions,
300
+ };
301
+ if (foundBoundary) {
302
+ result.protectingBoundary = foundBoundary;
303
+ }
304
+ return result;
305
+ }
306
+ /**
307
+ * Find error handling gaps
308
+ */
309
+ getGaps(options = {}) {
310
+ if (!this.topology)
311
+ return [];
312
+ const { minSeverity = 'low', limit = 20, includeSuggestions = true, files } = options;
313
+ const gaps = [];
314
+ const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
315
+ const minOrder = severityOrder[minSeverity];
316
+ for (const [funcId, profile] of this.topology.functions) {
317
+ // Filter by files if specified
318
+ if (files && !files.some(f => profile.file.includes(f)))
319
+ continue;
320
+ // Check for various gaps
321
+ if (profile.canThrow && !profile.hasTryCatch) {
322
+ const severity = this.calculateGapSeverity(profile, 'no-try-catch');
323
+ if (severityOrder[severity] <= minOrder) {
324
+ gaps.push({
325
+ functionId: funcId,
326
+ file: profile.file,
327
+ name: profile.qualifiedName,
328
+ line: profile.line,
329
+ gapType: 'no-try-catch',
330
+ severity,
331
+ description: 'Function can throw but has no error handling',
332
+ suggestion: includeSuggestions
333
+ ? 'Add try/catch block to handle potential errors'
334
+ : '',
335
+ riskScore: this.calculateRiskScore(profile, 'no-try-catch'),
336
+ });
337
+ }
338
+ }
339
+ if (profile.catchClauses.some(c => c.action === 'swallow')) {
340
+ const severity = this.calculateGapSeverity(profile, 'swallowed-error');
341
+ if (severityOrder[severity] <= minOrder) {
342
+ gaps.push({
343
+ functionId: funcId,
344
+ file: profile.file,
345
+ name: profile.qualifiedName,
346
+ line: profile.catchClauses.find(c => c.action === 'swallow')?.line ?? profile.line,
347
+ gapType: 'swallowed-error',
348
+ severity,
349
+ description: 'Error is caught but not handled (empty catch block)',
350
+ suggestion: includeSuggestions
351
+ ? 'Log the error or rethrow it'
352
+ : '',
353
+ riskScore: this.calculateRiskScore(profile, 'swallowed-error'),
354
+ });
355
+ }
356
+ }
357
+ if (profile.asyncHandling?.hasUnhandledPromises) {
358
+ const severity = this.calculateGapSeverity(profile, 'unhandled-async');
359
+ if (severityOrder[severity] <= minOrder) {
360
+ gaps.push({
361
+ functionId: funcId,
362
+ file: profile.file,
363
+ name: profile.qualifiedName,
364
+ line: profile.asyncHandling.unhandledLocations[0]?.line ?? profile.line,
365
+ gapType: 'unhandled-async',
366
+ severity,
367
+ description: 'Async function has unhandled promise rejections',
368
+ suggestion: includeSuggestions
369
+ ? 'Add .catch() or wrap await in try/catch'
370
+ : '',
371
+ riskScore: this.calculateRiskScore(profile, 'unhandled-async'),
372
+ });
373
+ }
374
+ }
375
+ if (profile.catchClauses.some(c => c.errorType === 'any' && c.action !== 'rethrow')) {
376
+ const severity = 'low';
377
+ if (severityOrder[severity] <= minOrder) {
378
+ gaps.push({
379
+ functionId: funcId,
380
+ file: profile.file,
381
+ name: profile.qualifiedName,
382
+ line: profile.catchClauses.find(c => c.errorType === 'any')?.line ?? profile.line,
383
+ gapType: 'bare-catch',
384
+ severity,
385
+ description: 'Catch clause catches all errors without type checking',
386
+ suggestion: includeSuggestions
387
+ ? 'Consider catching specific error types'
388
+ : '',
389
+ riskScore: this.calculateRiskScore(profile, 'bare-catch'),
390
+ });
391
+ }
392
+ }
393
+ }
394
+ // Sort by risk score descending
395
+ gaps.sort((a, b) => b.riskScore - a.riskScore);
396
+ return gaps.slice(0, limit);
397
+ }
398
+ /**
399
+ * Get error boundaries
400
+ */
401
+ getBoundaries(options = {}) {
402
+ if (!this.topology)
403
+ return [];
404
+ let boundaries = this.topology.boundaries;
405
+ if (!options.includeFramework) {
406
+ boundaries = boundaries.filter(b => !b.isFrameworkBoundary);
407
+ }
408
+ if (options.minCoverage !== undefined) {
409
+ boundaries = boundaries.filter(b => b.coverage >= options.minCoverage);
410
+ }
411
+ return boundaries.sort((a, b) => b.coverage - a.coverage);
412
+ }
413
+ /**
414
+ * Get unhandled error paths
415
+ */
416
+ getUnhandledPaths(minSeverity = 'low') {
417
+ if (!this.topology)
418
+ return [];
419
+ const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
420
+ const minOrder = severityOrder[minSeverity];
421
+ return this.topology.unhandledPaths
422
+ .filter(p => severityOrder[p.severity] <= minOrder)
423
+ .sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
424
+ }
425
+ // ============================================================================
426
+ // Private Helpers
427
+ // ============================================================================
428
+ detectTryCatch(func) {
429
+ // Heuristic: check if function body contains try/catch patterns
430
+ // In a full implementation, this would use AST analysis
431
+ // For now, we use metadata from the call graph if available
432
+ return func.hasTryCatch ?? false;
433
+ }
434
+ detectThrows(func) {
435
+ // Heuristic: check if function can throw
436
+ // Functions that call other throwing functions can also throw
437
+ return func.canThrow ??
438
+ func.calls.length > 0; // Conservative: assume any function with calls can throw
439
+ }
440
+ findThrowLocations(func) {
441
+ // Would need AST analysis for precise locations
442
+ return func.throwLocations ?? [];
443
+ }
444
+ extractCatchClauses(func) {
445
+ // Would need AST analysis for precise extraction
446
+ // Return empty for now - real implementation would parse AST
447
+ return func.catchClauses ?? [];
448
+ }
449
+ isAsyncFunction(func) {
450
+ if (func.isAsync)
451
+ return true;
452
+ if (func.name.includes('async'))
453
+ return true;
454
+ return func.returnType?.includes('Promise') ?? false;
455
+ }
456
+ analyzeAsyncHandling(_func) {
457
+ // Would need AST analysis for precise detection
458
+ return {
459
+ hasCatch: false,
460
+ hasAsyncTryCatch: false,
461
+ hasUnhandledPromises: false,
462
+ unhandledLocations: [],
463
+ };
464
+ }
465
+ calculateQualityScore(profile) {
466
+ let score = 50; // Base score
467
+ // Positive factors
468
+ if (profile.hasTryCatch)
469
+ score += 20;
470
+ if (profile.catchClauses?.some(c => c.action === 'recover'))
471
+ score += 15;
472
+ if (profile.catchClauses?.some(c => c.action === 'transform'))
473
+ score += 10;
474
+ if (profile.catchClauses?.some(c => c.preservesError))
475
+ score += 5;
476
+ if (profile.asyncHandling?.hasAsyncTryCatch)
477
+ score += 10;
478
+ if (profile.asyncHandling?.hasCatch)
479
+ score += 5;
480
+ // Negative factors
481
+ if (profile.canThrow && !profile.hasTryCatch)
482
+ score -= 20;
483
+ if (profile.catchClauses?.some(c => c.action === 'swallow'))
484
+ score -= 25;
485
+ if (profile.catchClauses?.some(c => c.errorType === 'any'))
486
+ score -= 5;
487
+ if (profile.asyncHandling?.hasUnhandledPromises)
488
+ score -= 20;
489
+ return Math.max(0, Math.min(100, score));
490
+ }
491
+ scoreToQuality(score) {
492
+ if (score >= 80)
493
+ return 'excellent';
494
+ if (score >= 60)
495
+ return 'good';
496
+ if (score >= 40)
497
+ return 'fair';
498
+ return 'poor';
499
+ }
500
+ detectBoundary(funcId, func, profile) {
501
+ if (!this.callGraph)
502
+ return null;
503
+ // Find what this function catches from
504
+ const catchesFrom = [];
505
+ for (const call of func.calls) {
506
+ for (const candidate of call.resolvedCandidates) {
507
+ const calleeProfile = this.topology?.functions.get(candidate);
508
+ if (calleeProfile?.canThrow) {
509
+ catchesFrom.push(candidate);
510
+ }
511
+ }
512
+ }
513
+ if (catchesFrom.length === 0)
514
+ return null;
515
+ // Detect framework boundaries
516
+ const isFrameworkBoundary = this.isFrameworkBoundary(func);
517
+ const frameworkType = this.detectFrameworkType(func);
518
+ // Calculate coverage
519
+ const totalCallees = func.calls.reduce((sum, c) => sum + c.resolvedCandidates.length, 0);
520
+ const coverage = totalCallees > 0 ? (catchesFrom.length / totalCallees) * 100 : 0;
521
+ const boundary = {
522
+ functionId: funcId,
523
+ file: func.file,
524
+ name: profile.qualifiedName,
525
+ catchesFrom,
526
+ handledTypes: profile.catchClauses.map(c => c.errorType),
527
+ isFrameworkBoundary,
528
+ coverage: Math.round(coverage),
529
+ line: profile.catchClauses[0]?.line ?? func.startLine,
530
+ };
531
+ if (frameworkType) {
532
+ boundary.frameworkType = frameworkType;
533
+ }
534
+ return boundary;
535
+ }
536
+ isFrameworkBoundary(func) {
537
+ const name = func.name.toLowerCase();
538
+ const className = func.className?.toLowerCase() ?? '';
539
+ // React error boundaries
540
+ if (name === 'componentdidcatch' || className.includes('errorboundary'))
541
+ return true;
542
+ // Express/Koa middleware
543
+ if (func.parameters?.length === 4)
544
+ return true; // (err, req, res, next)
545
+ // NestJS exception filters
546
+ if (className.includes('filter') && name === 'catch')
547
+ return true;
548
+ // Spring exception handlers
549
+ if (func.annotations?.some((a) => a.includes('ExceptionHandler') || a.includes('ControllerAdvice')))
550
+ return true;
551
+ return false;
552
+ }
553
+ detectFrameworkType(func) {
554
+ const name = func.name.toLowerCase();
555
+ const className = func.className?.toLowerCase() ?? '';
556
+ if (name === 'componentdidcatch' || className.includes('errorboundary')) {
557
+ return 'react-error-boundary';
558
+ }
559
+ if (func.parameters?.length === 4) {
560
+ return 'express-middleware';
561
+ }
562
+ if (className.includes('filter') && name === 'catch') {
563
+ return 'nestjs-filter';
564
+ }
565
+ return undefined;
566
+ }
567
+ traceErrorPropagation(throwerId, functions) {
568
+ if (!this.callGraph)
569
+ return null;
570
+ const path = [throwerId];
571
+ let current = throwerId;
572
+ let depth = 0;
573
+ const maxDepth = this.options.maxPropagationDepth ?? 20;
574
+ while (depth < maxDepth) {
575
+ const func = this.callGraph.functions.get(current);
576
+ if (!func || func.calledBy.length === 0) {
577
+ // No more callers - error escapes
578
+ return {
579
+ source: { functionId: throwerId, throwLine: functions.get(throwerId)?.line ?? 0 },
580
+ sink: null,
581
+ propagationPath: path,
582
+ transformations: [],
583
+ depth,
584
+ };
585
+ }
586
+ // Check if any caller catches
587
+ for (const caller of func.calledBy) {
588
+ const callerProfile = functions.get(caller.callerId);
589
+ if (callerProfile?.hasTryCatch) {
590
+ // Found a boundary
591
+ return {
592
+ source: { functionId: throwerId, throwLine: functions.get(throwerId)?.line ?? 0 },
593
+ sink: {
594
+ functionId: caller.callerId,
595
+ catchLine: callerProfile.catchClauses[0]?.line ?? callerProfile.line
596
+ },
597
+ propagationPath: path,
598
+ transformations: [],
599
+ depth,
600
+ };
601
+ }
602
+ }
603
+ // Move to first caller (simplified - real impl would explore all paths)
604
+ const nextCaller = func.calledBy[0]?.callerId;
605
+ if (!nextCaller || path.includes(nextCaller))
606
+ break; // Avoid cycles
607
+ path.push(nextCaller);
608
+ current = nextCaller;
609
+ depth++;
610
+ }
611
+ return null;
612
+ }
613
+ findUnhandledPaths(chains, functions) {
614
+ const unhandled = [];
615
+ for (const chain of chains) {
616
+ if (chain.sink === null) {
617
+ // This error escapes without being caught
618
+ const sourceProfile = functions.get(chain.source.functionId);
619
+ const entryPoint = chain.propagationPath[chain.propagationPath.length - 1] ?? chain.source.functionId;
620
+ const entryProfile = functions.get(entryPoint);
621
+ const severity = this.calculatePathSeverity(entryProfile);
622
+ unhandled.push({
623
+ entryPoint,
624
+ path: chain.propagationPath,
625
+ errorType: 'Error', // Would need AST for specific type
626
+ severity,
627
+ suggestedBoundary: this.suggestBoundaryLocation(chain, functions),
628
+ reason: `Error from ${sourceProfile?.qualifiedName ?? chain.source.functionId} escapes to ${entryProfile?.qualifiedName ?? entryPoint}`,
629
+ });
630
+ }
631
+ }
632
+ return unhandled;
633
+ }
634
+ calculatePathSeverity(entryProfile) {
635
+ if (!entryProfile)
636
+ return 'medium';
637
+ // Entry points and exported functions are more critical
638
+ const func = this.callGraph?.functions.get(entryProfile.functionId);
639
+ if (func?.isExported)
640
+ return 'critical';
641
+ // Check if file is an entry point
642
+ if (this.callGraph?.entryPoints.includes(entryProfile.file))
643
+ return 'critical';
644
+ return 'medium';
645
+ }
646
+ suggestBoundaryLocation(chain, _functions) {
647
+ // Suggest adding error handling at the middle of the chain
648
+ const midIndex = Math.floor(chain.propagationPath.length / 2);
649
+ return chain.propagationPath[midIndex] ?? chain.source.functionId;
650
+ }
651
+ calculateGapSeverity(profile, gapType) {
652
+ const func = this.callGraph?.functions.get(profile.functionId);
653
+ // Entry points and exported functions are more critical
654
+ const isEntryPointFile = this.callGraph?.entryPoints.includes(profile.file) ?? false;
655
+ if (func?.isExported || isEntryPointFile) {
656
+ return gapType === 'swallowed-error' ? 'high' : 'critical';
657
+ }
658
+ switch (gapType) {
659
+ case 'no-try-catch':
660
+ return profile.canThrow ? 'high' : 'medium';
661
+ case 'swallowed-error':
662
+ return 'high';
663
+ case 'unhandled-async':
664
+ return 'high';
665
+ case 'bare-catch':
666
+ return 'low';
667
+ default:
668
+ return 'medium';
669
+ }
670
+ }
671
+ calculateRiskScore(profile, gapType) {
672
+ let score = 50;
673
+ // Gap type weights
674
+ switch (gapType) {
675
+ case 'no-try-catch':
676
+ score += 20;
677
+ break;
678
+ case 'swallowed-error':
679
+ score += 30;
680
+ break;
681
+ case 'unhandled-async':
682
+ score += 25;
683
+ break;
684
+ case 'bare-catch':
685
+ score += 5;
686
+ break;
687
+ }
688
+ // Function importance
689
+ const func = this.callGraph?.functions.get(profile.functionId);
690
+ const isEntryPointFile = this.callGraph?.entryPoints.includes(profile.file) ?? false;
691
+ if (func?.isExported)
692
+ score += 15;
693
+ if (isEntryPointFile)
694
+ score += 20;
695
+ if ((func?.calledBy.length ?? 0) > 5)
696
+ score += 10;
697
+ return Math.min(100, score);
698
+ }
699
+ }
700
+ // ============================================================================
701
+ // Factory
702
+ // ============================================================================
703
+ export function createErrorHandlingAnalyzer(options) {
704
+ return new ErrorHandlingAnalyzer(options);
705
+ }
706
+ //# sourceMappingURL=error-handling-analyzer.js.map