api-tests-coverage 1.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 (288) hide show
  1. package/README.md +703 -0
  2. package/config.yaml.example +227 -0
  3. package/dist/action/src/index.d.ts +2 -0
  4. package/dist/action/src/index.d.ts.map +1 -0
  5. package/dist/action/src/index.js +349 -0
  6. package/dist/action/src/prComment.d.ts +34 -0
  7. package/dist/action/src/prComment.d.ts.map +1 -0
  8. package/dist/action/src/prComment.js +146 -0
  9. package/dist/src/ast/astAnalysisOrchestrator.d.ts +36 -0
  10. package/dist/src/ast/astAnalysisOrchestrator.d.ts.map +1 -0
  11. package/dist/src/ast/astAnalysisOrchestrator.js +123 -0
  12. package/dist/src/ast/astTypes.d.ts +105 -0
  13. package/dist/src/ast/astTypes.d.ts.map +1 -0
  14. package/dist/src/ast/astTypes.js +9 -0
  15. package/dist/src/ast/languageAnalyzer.d.ts +46 -0
  16. package/dist/src/ast/languageAnalyzer.d.ts.map +1 -0
  17. package/dist/src/ast/languageAnalyzer.js +9 -0
  18. package/dist/src/ast/languageCapabilities.d.ts +24 -0
  19. package/dist/src/ast/languageCapabilities.d.ts.map +1 -0
  20. package/dist/src/ast/languageCapabilities.js +92 -0
  21. package/dist/src/ast/parseFile.d.ts +16 -0
  22. package/dist/src/ast/parseFile.d.ts.map +1 -0
  23. package/dist/src/ast/parseFile.js +65 -0
  24. package/dist/src/ast/parserRegistry.d.ts +39 -0
  25. package/dist/src/ast/parserRegistry.d.ts.map +1 -0
  26. package/dist/src/ast/parserRegistry.js +66 -0
  27. package/dist/src/buildSummary.d.ts +26 -0
  28. package/dist/src/buildSummary.d.ts.map +1 -0
  29. package/dist/src/buildSummary.js +193 -0
  30. package/dist/src/businessCoverage.d.ts +68 -0
  31. package/dist/src/businessCoverage.d.ts.map +1 -0
  32. package/dist/src/businessCoverage.js +290 -0
  33. package/dist/src/compatibilityCoverage.d.ts +83 -0
  34. package/dist/src/compatibilityCoverage.d.ts.map +1 -0
  35. package/dist/src/compatibilityCoverage.js +501 -0
  36. package/dist/src/config/defaultConfig.d.ts +9 -0
  37. package/dist/src/config/defaultConfig.d.ts.map +1 -0
  38. package/dist/src/config/defaultConfig.js +97 -0
  39. package/dist/src/config/index.d.ts +12 -0
  40. package/dist/src/config/index.d.ts.map +1 -0
  41. package/dist/src/config/index.js +37 -0
  42. package/dist/src/config/loadConfig.d.ts +29 -0
  43. package/dist/src/config/loadConfig.d.ts.map +1 -0
  44. package/dist/src/config/loadConfig.js +135 -0
  45. package/dist/src/config/mergeConfig.d.ts +15 -0
  46. package/dist/src/config/mergeConfig.d.ts.map +1 -0
  47. package/dist/src/config/mergeConfig.js +57 -0
  48. package/dist/src/config/schema.d.ts +15 -0
  49. package/dist/src/config/schema.d.ts.map +1 -0
  50. package/dist/src/config/schema.js +30 -0
  51. package/dist/src/config/types.d.ts +175 -0
  52. package/dist/src/config/types.d.ts.map +1 -0
  53. package/dist/src/config/types.js +9 -0
  54. package/dist/src/config/validateConfig.d.ts +22 -0
  55. package/dist/src/config/validateConfig.d.ts.map +1 -0
  56. package/dist/src/config/validateConfig.js +171 -0
  57. package/dist/src/config.d.ts +168 -0
  58. package/dist/src/config.d.ts.map +1 -0
  59. package/dist/src/config.js +204 -0
  60. package/dist/src/coverage/deep-analysis/callGraph.d.ts +67 -0
  61. package/dist/src/coverage/deep-analysis/callGraph.d.ts.map +1 -0
  62. package/dist/src/coverage/deep-analysis/callGraph.js +275 -0
  63. package/dist/src/coverage/deep-analysis/deepEndpointResolver.d.ts +23 -0
  64. package/dist/src/coverage/deep-analysis/deepEndpointResolver.d.ts.map +1 -0
  65. package/dist/src/coverage/deep-analysis/deepEndpointResolver.js +394 -0
  66. package/dist/src/coverage/deep-analysis/index.d.ts +17 -0
  67. package/dist/src/coverage/deep-analysis/index.d.ts.map +1 -0
  68. package/dist/src/coverage/deep-analysis/index.js +63 -0
  69. package/dist/src/coverage/deep-analysis/resolveAssertions.d.ts +60 -0
  70. package/dist/src/coverage/deep-analysis/resolveAssertions.d.ts.map +1 -0
  71. package/dist/src/coverage/deep-analysis/resolveAssertions.js +121 -0
  72. package/dist/src/coverage/deep-analysis/resolveConstants.d.ts +36 -0
  73. package/dist/src/coverage/deep-analysis/resolveConstants.d.ts.map +1 -0
  74. package/dist/src/coverage/deep-analysis/resolveConstants.js +92 -0
  75. package/dist/src/coverage/deep-analysis/resolveEnums.d.ts +55 -0
  76. package/dist/src/coverage/deep-analysis/resolveEnums.d.ts.map +1 -0
  77. package/dist/src/coverage/deep-analysis/resolveEnums.js +152 -0
  78. package/dist/src/coverage/deep-analysis/resolveMethodChains.d.ts +70 -0
  79. package/dist/src/coverage/deep-analysis/resolveMethodChains.d.ts.map +1 -0
  80. package/dist/src/coverage/deep-analysis/resolveMethodChains.js +152 -0
  81. package/dist/src/coverage/deep-analysis/resolvePaths.d.ts +80 -0
  82. package/dist/src/coverage/deep-analysis/resolvePaths.d.ts.map +1 -0
  83. package/dist/src/coverage/deep-analysis/resolvePaths.js +216 -0
  84. package/dist/src/coverage/deep-analysis/resolveRequestWrappers.d.ts +71 -0
  85. package/dist/src/coverage/deep-analysis/resolveRequestWrappers.d.ts.map +1 -0
  86. package/dist/src/coverage/deep-analysis/resolveRequestWrappers.js +226 -0
  87. package/dist/src/coverage/deep-analysis/symbolTable.d.ts +58 -0
  88. package/dist/src/coverage/deep-analysis/symbolTable.d.ts.map +1 -0
  89. package/dist/src/coverage/deep-analysis/symbolTable.js +230 -0
  90. package/dist/src/coverage/deep-analysis/types.d.ts +122 -0
  91. package/dist/src/coverage/deep-analysis/types.d.ts.map +1 -0
  92. package/dist/src/coverage/deep-analysis/types.js +21 -0
  93. package/dist/src/discovery/fileClassifier.d.ts +50 -0
  94. package/dist/src/discovery/fileClassifier.d.ts.map +1 -0
  95. package/dist/src/discovery/fileClassifier.js +238 -0
  96. package/dist/src/discovery/projectDiscovery.d.ts +66 -0
  97. package/dist/src/discovery/projectDiscovery.d.ts.map +1 -0
  98. package/dist/src/discovery/projectDiscovery.js +287 -0
  99. package/dist/src/endpointCoverage.d.ts +70 -0
  100. package/dist/src/endpointCoverage.d.ts.map +1 -0
  101. package/dist/src/endpointCoverage.js +381 -0
  102. package/dist/src/errorCoverage.d.ts +93 -0
  103. package/dist/src/errorCoverage.d.ts.map +1 -0
  104. package/dist/src/errorCoverage.js +698 -0
  105. package/dist/src/index.d.ts +3 -0
  106. package/dist/src/index.d.ts.map +1 -0
  107. package/dist/src/index.js +1441 -0
  108. package/dist/src/inference/businessRuleInference.d.ts +63 -0
  109. package/dist/src/inference/businessRuleInference.d.ts.map +1 -0
  110. package/dist/src/inference/businessRuleInference.js +268 -0
  111. package/dist/src/inference/integrationFlowInference.d.ts +56 -0
  112. package/dist/src/inference/integrationFlowInference.d.ts.map +1 -0
  113. package/dist/src/inference/integrationFlowInference.js +266 -0
  114. package/dist/src/integrationCoverage.d.ts +72 -0
  115. package/dist/src/integrationCoverage.d.ts.map +1 -0
  116. package/dist/src/integrationCoverage.js +317 -0
  117. package/dist/src/intelligence/index.d.ts +20 -0
  118. package/dist/src/intelligence/index.d.ts.map +1 -0
  119. package/dist/src/intelligence/index.js +105 -0
  120. package/dist/src/intelligence/linkageEngine.d.ts +20 -0
  121. package/dist/src/intelligence/linkageEngine.d.ts.map +1 -0
  122. package/dist/src/intelligence/linkageEngine.js +522 -0
  123. package/dist/src/intelligence/markdownReporter.d.ts +12 -0
  124. package/dist/src/intelligence/markdownReporter.d.ts.map +1 -0
  125. package/dist/src/intelligence/markdownReporter.js +265 -0
  126. package/dist/src/intelligence/riskScoring.d.ts +53 -0
  127. package/dist/src/intelligence/riskScoring.d.ts.map +1 -0
  128. package/dist/src/intelligence/riskScoring.js +181 -0
  129. package/dist/src/intelligence/types.d.ts +121 -0
  130. package/dist/src/intelligence/types.d.ts.map +1 -0
  131. package/dist/src/intelligence/types.js +8 -0
  132. package/dist/src/languageDetection.d.ts +100 -0
  133. package/dist/src/languageDetection.d.ts.map +1 -0
  134. package/dist/src/languageDetection.js +349 -0
  135. package/dist/src/languages/java/index.d.ts +16 -0
  136. package/dist/src/languages/java/index.d.ts.map +1 -0
  137. package/dist/src/languages/java/index.js +103 -0
  138. package/dist/src/languages/java/parser.d.ts +7 -0
  139. package/dist/src/languages/java/parser.d.ts.map +1 -0
  140. package/dist/src/languages/java/parser.js +50 -0
  141. package/dist/src/languages/java/semanticBuilder.d.ts +21 -0
  142. package/dist/src/languages/java/semanticBuilder.d.ts.map +1 -0
  143. package/dist/src/languages/java/semanticBuilder.js +358 -0
  144. package/dist/src/languages/javascript/annotationExtractor.d.ts +20 -0
  145. package/dist/src/languages/javascript/annotationExtractor.d.ts.map +1 -0
  146. package/dist/src/languages/javascript/annotationExtractor.js +94 -0
  147. package/dist/src/languages/javascript/assertionResolver.d.ts +18 -0
  148. package/dist/src/languages/javascript/assertionResolver.d.ts.map +1 -0
  149. package/dist/src/languages/javascript/assertionResolver.js +150 -0
  150. package/dist/src/languages/javascript/callResolver.d.ts +23 -0
  151. package/dist/src/languages/javascript/callResolver.d.ts.map +1 -0
  152. package/dist/src/languages/javascript/callResolver.js +236 -0
  153. package/dist/src/languages/javascript/httpInteractionExtractor.d.ts +23 -0
  154. package/dist/src/languages/javascript/httpInteractionExtractor.d.ts.map +1 -0
  155. package/dist/src/languages/javascript/httpInteractionExtractor.js +205 -0
  156. package/dist/src/languages/javascript/index.d.ts +20 -0
  157. package/dist/src/languages/javascript/index.d.ts.map +1 -0
  158. package/dist/src/languages/javascript/index.js +136 -0
  159. package/dist/src/languages/javascript/parser.d.ts +14 -0
  160. package/dist/src/languages/javascript/parser.d.ts.map +1 -0
  161. package/dist/src/languages/javascript/parser.js +38 -0
  162. package/dist/src/languages/javascript/symbolResolver.d.ts +31 -0
  163. package/dist/src/languages/javascript/symbolResolver.d.ts.map +1 -0
  164. package/dist/src/languages/javascript/symbolResolver.js +183 -0
  165. package/dist/src/languages/kotlin/index.d.ts +16 -0
  166. package/dist/src/languages/kotlin/index.d.ts.map +1 -0
  167. package/dist/src/languages/kotlin/index.js +151 -0
  168. package/dist/src/languages/kotlin/parser.d.ts +11 -0
  169. package/dist/src/languages/kotlin/parser.d.ts.map +1 -0
  170. package/dist/src/languages/kotlin/parser.js +74 -0
  171. package/dist/src/languages/python/index.d.ts +15 -0
  172. package/dist/src/languages/python/index.d.ts.map +1 -0
  173. package/dist/src/languages/python/index.js +293 -0
  174. package/dist/src/languages/ruby/index.d.ts +15 -0
  175. package/dist/src/languages/ruby/index.d.ts.map +1 -0
  176. package/dist/src/languages/ruby/index.js +274 -0
  177. package/dist/src/languages/shared/treeSitterUtils.d.ts +43 -0
  178. package/dist/src/languages/shared/treeSitterUtils.d.ts.map +1 -0
  179. package/dist/src/languages/shared/treeSitterUtils.js +100 -0
  180. package/dist/src/languages/typescript/index.d.ts +14 -0
  181. package/dist/src/languages/typescript/index.d.ts.map +1 -0
  182. package/dist/src/languages/typescript/index.js +25 -0
  183. package/dist/src/lib/index.d.ts +228 -0
  184. package/dist/src/lib/index.d.ts.map +1 -0
  185. package/dist/src/lib/index.js +486 -0
  186. package/dist/src/mcp/client/index.d.ts +37 -0
  187. package/dist/src/mcp/client/index.d.ts.map +1 -0
  188. package/dist/src/mcp/client/index.js +235 -0
  189. package/dist/src/mcp/config.d.ts +50 -0
  190. package/dist/src/mcp/config.d.ts.map +1 -0
  191. package/dist/src/mcp/config.js +125 -0
  192. package/dist/src/mcp/events.d.ts +24 -0
  193. package/dist/src/mcp/events.d.ts.map +1 -0
  194. package/dist/src/mcp/events.js +48 -0
  195. package/dist/src/mcp/fallback/index.d.ts +50 -0
  196. package/dist/src/mcp/fallback/index.d.ts.map +1 -0
  197. package/dist/src/mcp/fallback/index.js +216 -0
  198. package/dist/src/mcp/index.d.ts +67 -0
  199. package/dist/src/mcp/index.d.ts.map +1 -0
  200. package/dist/src/mcp/index.js +212 -0
  201. package/dist/src/mcp/normalizer.d.ts +21 -0
  202. package/dist/src/mcp/normalizer.d.ts.map +1 -0
  203. package/dist/src/mcp/normalizer.js +99 -0
  204. package/dist/src/mcp/prompts/index.d.ts +86 -0
  205. package/dist/src/mcp/prompts/index.d.ts.map +1 -0
  206. package/dist/src/mcp/prompts/index.js +304 -0
  207. package/dist/src/mcp/templates/index.d.ts +35 -0
  208. package/dist/src/mcp/templates/index.d.ts.map +1 -0
  209. package/dist/src/mcp/templates/index.js +143 -0
  210. package/dist/src/mcp/testing/mock-server/index.d.ts +47 -0
  211. package/dist/src/mcp/testing/mock-server/index.d.ts.map +1 -0
  212. package/dist/src/mcp/testing/mock-server/index.js +157 -0
  213. package/dist/src/mcp/types.d.ts +127 -0
  214. package/dist/src/mcp/types.d.ts.map +1 -0
  215. package/dist/src/mcp/types.js +8 -0
  216. package/dist/src/observability.d.ts +138 -0
  217. package/dist/src/observability.d.ts.map +1 -0
  218. package/dist/src/observability.js +519 -0
  219. package/dist/src/parameterCoverage.d.ts +75 -0
  220. package/dist/src/parameterCoverage.d.ts.map +1 -0
  221. package/dist/src/parameterCoverage.js +629 -0
  222. package/dist/src/perfResilienceCoverage.d.ts +155 -0
  223. package/dist/src/perfResilienceCoverage.d.ts.map +1 -0
  224. package/dist/src/perfResilienceCoverage.js +670 -0
  225. package/dist/src/pluginLoader.d.ts +51 -0
  226. package/dist/src/pluginLoader.d.ts.map +1 -0
  227. package/dist/src/pluginLoader.js +72 -0
  228. package/dist/src/publishing.d.ts +63 -0
  229. package/dist/src/publishing.d.ts.map +1 -0
  230. package/dist/src/publishing.js +379 -0
  231. package/dist/src/qualityGate.d.ts +58 -0
  232. package/dist/src/qualityGate.d.ts.map +1 -0
  233. package/dist/src/qualityGate.js +118 -0
  234. package/dist/src/reporting.d.ts +41 -0
  235. package/dist/src/reporting.d.ts.map +1 -0
  236. package/dist/src/reporting.js +278 -0
  237. package/dist/src/screenshots.d.ts +71 -0
  238. package/dist/src/screenshots.d.ts.map +1 -0
  239. package/dist/src/screenshots.js +141 -0
  240. package/dist/src/security/gate/index.d.ts +11 -0
  241. package/dist/src/security/gate/index.d.ts.map +1 -0
  242. package/dist/src/security/gate/index.js +65 -0
  243. package/dist/src/security/index.d.ts +30 -0
  244. package/dist/src/security/index.d.ts.map +1 -0
  245. package/dist/src/security/index.js +342 -0
  246. package/dist/src/security/normalizers/semgrep.d.ts +10 -0
  247. package/dist/src/security/normalizers/semgrep.d.ts.map +1 -0
  248. package/dist/src/security/normalizers/semgrep.js +104 -0
  249. package/dist/src/security/normalizers/trivy.d.ts +10 -0
  250. package/dist/src/security/normalizers/trivy.d.ts.map +1 -0
  251. package/dist/src/security/normalizers/trivy.js +78 -0
  252. package/dist/src/security/normalizers/zap.d.ts +10 -0
  253. package/dist/src/security/normalizers/zap.d.ts.map +1 -0
  254. package/dist/src/security/normalizers/zap.js +104 -0
  255. package/dist/src/security/scanners/semgrep.d.ts +6 -0
  256. package/dist/src/security/scanners/semgrep.d.ts.map +1 -0
  257. package/dist/src/security/scanners/semgrep.js +125 -0
  258. package/dist/src/security/scanners/trivy.d.ts +6 -0
  259. package/dist/src/security/scanners/trivy.d.ts.map +1 -0
  260. package/dist/src/security/scanners/trivy.js +115 -0
  261. package/dist/src/security/scanners/zap.d.ts +6 -0
  262. package/dist/src/security/scanners/zap.d.ts.map +1 -0
  263. package/dist/src/security/scanners/zap.js +135 -0
  264. package/dist/src/security/types.d.ts +146 -0
  265. package/dist/src/security/types.d.ts.map +1 -0
  266. package/dist/src/security/types.js +6 -0
  267. package/dist/src/securityCoverage.d.ts +116 -0
  268. package/dist/src/securityCoverage.d.ts.map +1 -0
  269. package/dist/src/securityCoverage.js +725 -0
  270. package/dist/src/summary/buildSummary.d.ts +28 -0
  271. package/dist/src/summary/buildSummary.d.ts.map +1 -0
  272. package/dist/src/summary/buildSummary.js +257 -0
  273. package/dist/src/summary/evaluateMetrics.d.ts +31 -0
  274. package/dist/src/summary/evaluateMetrics.d.ts.map +1 -0
  275. package/dist/src/summary/evaluateMetrics.js +118 -0
  276. package/dist/src/summary/index.d.ts +10 -0
  277. package/dist/src/summary/index.d.ts.map +1 -0
  278. package/dist/src/summary/index.js +22 -0
  279. package/dist/src/summary/markdownRenderer.d.ts +139 -0
  280. package/dist/src/summary/markdownRenderer.d.ts.map +1 -0
  281. package/dist/src/summary/markdownRenderer.js +459 -0
  282. package/dist/src/summary/prSummary.d.ts +24 -0
  283. package/dist/src/summary/prSummary.d.ts.map +1 -0
  284. package/dist/src/summary/prSummary.js +233 -0
  285. package/dist/src/summary/summaryTypes.d.ts +35 -0
  286. package/dist/src/summary/summaryTypes.d.ts.map +1 -0
  287. package/dist/src/summary/summaryTypes.js +27 -0
  288. package/package.json +84 -0
@@ -0,0 +1,23 @@
1
+ /**
2
+ * JavaScript/TypeScript call graph resolver.
3
+ *
4
+ * Extracts function and method definitions from the AST alongside:
5
+ * - their call graph edges (which local functions they call)
6
+ * - any HTTP call sites within the function body
7
+ * - a static return value if the function just returns a string literal
8
+ */
9
+ import type { SemanticFunction } from '../../ast/astTypes';
10
+ import type { SemanticSymbol } from '../../ast/astTypes';
11
+ type AstNode = any;
12
+ /**
13
+ * Build a map of function name → SemanticFunction from the AST.
14
+ */
15
+ export declare function buildCallGraph(ast: AstNode, constants: Map<string, SemanticSymbol>): Map<string, SemanticFunction>;
16
+ /**
17
+ * Try to evaluate a node to a static string value.
18
+ * Handles: Literal, TemplateLiteral, Identifier (symbol lookup), BinaryExpression (+).
19
+ */
20
+ export declare function evaluateStringNode(node: AstNode, constants: Map<string, SemanticSymbol>, localVars?: Map<string, SemanticSymbol>): string | undefined;
21
+ export declare function memberKey(node: AstNode): string | undefined;
22
+ export {};
23
+ //# sourceMappingURL=callResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callResolver.d.ts","sourceRoot":"","sources":["../../../../src/languages/javascript/callResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAoB,MAAM,oBAAoB,CAAC;AAE7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,KAAK,OAAO,GAAG,GAAG,CAAC;AAEnB;;GAEG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GACrC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAQ/B;AA6LD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,EACtC,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GACtC,MAAM,GAAG,SAAS,CA2CpB;AAuBD,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQ3D"}
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+ /**
3
+ * JavaScript/TypeScript call graph resolver.
4
+ *
5
+ * Extracts function and method definitions from the AST alongside:
6
+ * - their call graph edges (which local functions they call)
7
+ * - any HTTP call sites within the function body
8
+ * - a static return value if the function just returns a string literal
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.buildCallGraph = buildCallGraph;
12
+ exports.evaluateStringNode = evaluateStringNode;
13
+ exports.memberKey = memberKey;
14
+ const httpInteractionExtractor_1 = require("./httpInteractionExtractor");
15
+ /**
16
+ * Build a map of function name → SemanticFunction from the AST.
17
+ */
18
+ function buildCallGraph(ast, constants) {
19
+ const graph = new Map();
20
+ if (!(ast === null || ast === void 0 ? void 0 : ast.body))
21
+ return graph;
22
+ for (const node of ast.body) {
23
+ extractFunctionFromTopLevel(node, graph, constants);
24
+ }
25
+ return graph;
26
+ }
27
+ function extractFunctionFromTopLevel(node, graph, constants) {
28
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
29
+ if (!node)
30
+ return;
31
+ switch (node.type) {
32
+ case 'FunctionDeclaration':
33
+ if ((_a = node.id) === null || _a === void 0 ? void 0 : _a.name) {
34
+ addFunction(node.id.name, node.params, node.body, graph, constants);
35
+ }
36
+ break;
37
+ case 'VariableDeclaration':
38
+ for (const decl of (_b = node.declarations) !== null && _b !== void 0 ? _b : []) {
39
+ if (((_c = decl.id) === null || _c === void 0 ? void 0 : _c.name) &&
40
+ (((_d = decl.init) === null || _d === void 0 ? void 0 : _d.type) === 'ArrowFunctionExpression' ||
41
+ ((_e = decl.init) === null || _e === void 0 ? void 0 : _e.type) === 'FunctionExpression')) {
42
+ addFunction(decl.id.name, decl.init.params, decl.init.body, graph, constants);
43
+ }
44
+ }
45
+ break;
46
+ case 'ExpressionStatement':
47
+ // Detect test blocks: describe('...', () => { ... })
48
+ extractTestBlocks(node.expression, graph, constants);
49
+ break;
50
+ case 'ExportNamedDeclaration':
51
+ if (node.declaration)
52
+ extractFunctionFromTopLevel(node.declaration, graph, constants);
53
+ break;
54
+ case 'ExportDefaultDeclaration':
55
+ if (((_f = node.declaration) === null || _f === void 0 ? void 0 : _f.type) === 'FunctionDeclaration' ||
56
+ ((_g = node.declaration) === null || _g === void 0 ? void 0 : _g.type) === 'ArrowFunctionExpression') {
57
+ const name = (_j = (_h = node.declaration.id) === null || _h === void 0 ? void 0 : _h.name) !== null && _j !== void 0 ? _j : 'default';
58
+ addFunction(name, node.declaration.params, node.declaration.body, graph, constants);
59
+ }
60
+ break;
61
+ case 'ClassDeclaration':
62
+ extractClassMethods(node, graph, constants);
63
+ break;
64
+ }
65
+ }
66
+ function extractTestBlocks(expr, graph, constants) {
67
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
68
+ if (!expr || expr.type !== 'CallExpression')
69
+ return;
70
+ const callee = (_e = (_b = (_a = expr.callee) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : (_d = (_c = expr.callee) === null || _c === void 0 ? void 0 : _c.property) === null || _d === void 0 ? void 0 : _d.name) !== null && _e !== void 0 ? _e : '';
71
+ const isBlock = ['describe', 'it', 'test', 'beforeEach', 'afterEach', 'beforeAll', 'afterAll',
72
+ 'context', 'When', 'Given', 'Then'].includes(callee);
73
+ if (!isBlock)
74
+ return;
75
+ const labelArg = (_f = expr.arguments) === null || _f === void 0 ? void 0 : _f[0];
76
+ const label = (labelArg === null || labelArg === void 0 ? void 0 : labelArg.type) === 'Literal' ? ((_g = labelArg.value) !== null && _g !== void 0 ? _g : callee) : callee;
77
+ const fnArg = (_h = expr.arguments) === null || _h === void 0 ? void 0 : _h.find((a) => a.type === 'ArrowFunctionExpression' || a.type === 'FunctionExpression');
78
+ if (fnArg) {
79
+ const blockName = `${callee}:${label}`;
80
+ addFunction(blockName, fnArg.params, fnArg.body, graph, constants);
81
+ // Also recurse into the block body for nested describe/it
82
+ if ((_j = fnArg.body) === null || _j === void 0 ? void 0 : _j.body) {
83
+ for (const stmt of fnArg.body.body) {
84
+ extractTestBlocks(stmt === null || stmt === void 0 ? void 0 : stmt.expression, graph, constants);
85
+ }
86
+ }
87
+ }
88
+ }
89
+ function extractClassMethods(classNode, graph, constants) {
90
+ var _a, _b, _c, _d, _e, _f;
91
+ for (const member of (_b = (_a = classNode.body) === null || _a === void 0 ? void 0 : _a.body) !== null && _b !== void 0 ? _b : []) {
92
+ if (member.type === 'MethodDefinition' || member.type === 'PropertyDefinition') {
93
+ const methodName = (_d = (_c = member.key) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : (_e = member.key) === null || _e === void 0 ? void 0 : _e.value;
94
+ if (methodName && ((_f = member.value) === null || _f === void 0 ? void 0 : _f.type) === 'FunctionExpression') {
95
+ addFunction(methodName, member.value.params, member.value.body, graph, constants);
96
+ }
97
+ }
98
+ }
99
+ }
100
+ function addFunction(name, params, body, graph, constants) {
101
+ const paramNames = (params !== null && params !== void 0 ? params : [])
102
+ .map((p) => { var _a, _b, _c, _d, _e; return (_e = (_c = (_a = p.name) !== null && _a !== void 0 ? _a : (_b = p.left) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : (_d = p.argument) === null || _d === void 0 ? void 0 : _d.name) !== null && _e !== void 0 ? _e : ''; })
103
+ .filter(Boolean);
104
+ const calledFunctions = [];
105
+ const httpCalls = [];
106
+ let returnValue;
107
+ const annotations = [];
108
+ // Walk the body
109
+ if (body) {
110
+ walkForCalls(body, calledFunctions, constants);
111
+ (0, httpInteractionExtractor_1.extractHttpCallsFromNode)(body, constants, httpCalls);
112
+ returnValue = extractReturnValue(body, constants);
113
+ }
114
+ graph.set(name, {
115
+ name,
116
+ parameters: paramNames,
117
+ bodyHttpCalls: httpCalls,
118
+ calledFunctions,
119
+ returnValue,
120
+ annotations,
121
+ });
122
+ }
123
+ function walkForCalls(node, calls, constants) {
124
+ if (!node || typeof node !== 'object')
125
+ return;
126
+ if (node.type === 'CallExpression') {
127
+ const name = getCallName(node.callee);
128
+ if (name && !calls.includes(name))
129
+ calls.push(name);
130
+ }
131
+ for (const key of Object.keys(node)) {
132
+ if (key === 'parent' || key === 'tokens' || key === 'comments')
133
+ continue;
134
+ const child = node[key];
135
+ if (Array.isArray(child)) {
136
+ for (const c of child) {
137
+ if (c && typeof c === 'object' && c.type)
138
+ walkForCalls(c, calls, constants);
139
+ }
140
+ }
141
+ else if (child && typeof child === 'object' && child.type) {
142
+ walkForCalls(child, calls, constants);
143
+ }
144
+ }
145
+ }
146
+ function getCallName(callee) {
147
+ var _a, _b, _c, _d, _e, _f;
148
+ if (!callee)
149
+ return undefined;
150
+ if (callee.type === 'Identifier')
151
+ return callee.name;
152
+ if (callee.type === 'MemberExpression') {
153
+ const obj = (_d = (_b = (_a = callee.object) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : (_c = callee.object) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : '';
154
+ const prop = (_f = (_e = callee.property) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : '';
155
+ if (obj && prop)
156
+ return `${obj}.${prop}`;
157
+ return prop || undefined;
158
+ }
159
+ return undefined;
160
+ }
161
+ function extractReturnValue(body, constants) {
162
+ if (!(body === null || body === void 0 ? void 0 : body.body))
163
+ return undefined;
164
+ for (const stmt of body.body) {
165
+ if (stmt.type === 'ReturnStatement' && stmt.argument) {
166
+ return evaluateStringNode(stmt.argument, constants);
167
+ }
168
+ }
169
+ return undefined;
170
+ }
171
+ /**
172
+ * Try to evaluate a node to a static string value.
173
+ * Handles: Literal, TemplateLiteral, Identifier (symbol lookup), BinaryExpression (+).
174
+ */
175
+ function evaluateStringNode(node, constants, localVars) {
176
+ var _a, _b, _c, _d, _e, _f;
177
+ if (!node)
178
+ return undefined;
179
+ if (node.type === 'Literal') {
180
+ return typeof node.value === 'string' ? node.value : undefined;
181
+ }
182
+ if (node.type === 'TemplateLiteral') {
183
+ return evaluateTemplateLiteral(node, constants, localVars);
184
+ }
185
+ if (node.type === 'Identifier') {
186
+ return ((_b = (_a = localVars === null || localVars === void 0 ? void 0 : localVars.get(node.name)) === null || _a === void 0 ? void 0 : _a.resolvedValue) !== null && _b !== void 0 ? _b : (_c = constants.get(node.name)) === null || _c === void 0 ? void 0 : _c.resolvedValue);
187
+ }
188
+ if (node.type === 'MemberExpression') {
189
+ const key = memberKey(node);
190
+ if (key) {
191
+ return ((_e = (_d = localVars === null || localVars === void 0 ? void 0 : localVars.get(key)) === null || _d === void 0 ? void 0 : _d.resolvedValue) !== null && _e !== void 0 ? _e : (_f = constants.get(key)) === null || _f === void 0 ? void 0 : _f.resolvedValue);
192
+ }
193
+ return undefined;
194
+ }
195
+ if (node.type === 'BinaryExpression' && node.operator === '+') {
196
+ const left = evaluateStringNode(node.left, constants, localVars);
197
+ const right = evaluateStringNode(node.right, constants, localVars);
198
+ if (left !== undefined && right !== undefined)
199
+ return left + right;
200
+ if (left !== undefined)
201
+ return left + '{var}';
202
+ if (right !== undefined)
203
+ return '{var}' + right;
204
+ return undefined;
205
+ }
206
+ if (node.type === 'TSAsExpression' || node.type === 'TSSatisfiesExpression') {
207
+ return evaluateStringNode(node.expression, constants, localVars);
208
+ }
209
+ return undefined;
210
+ }
211
+ function evaluateTemplateLiteral(node, constants, localVars) {
212
+ var _a, _b, _c, _d, _e, _f, _g, _h;
213
+ // `text ${expr} text`
214
+ const quasis = (_a = node.quasis) !== null && _a !== void 0 ? _a : [];
215
+ const expressions = (_b = node.expressions) !== null && _b !== void 0 ? _b : [];
216
+ let result = '';
217
+ for (let i = 0; i < quasis.length; i++) {
218
+ result += (_h = (_e = (_d = (_c = quasis[i]) === null || _c === void 0 ? void 0 : _c.value) === null || _d === void 0 ? void 0 : _d.cooked) !== null && _e !== void 0 ? _e : (_g = (_f = quasis[i]) === null || _f === void 0 ? void 0 : _f.value) === null || _g === void 0 ? void 0 : _g.raw) !== null && _h !== void 0 ? _h : '';
219
+ if (i < expressions.length) {
220
+ const expr = expressions[i];
221
+ const resolved = evaluateStringNode(expr, constants, localVars);
222
+ result += resolved !== undefined ? resolved : '{id}';
223
+ }
224
+ }
225
+ return result;
226
+ }
227
+ function memberKey(node) {
228
+ var _a, _b, _c, _d, _e, _f;
229
+ if (node.type !== 'MemberExpression')
230
+ return undefined;
231
+ const objName = (_b = (_a = node.object) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : (((_c = node.object) === null || _c === void 0 ? void 0 : _c.type) === 'MemberExpression' ? memberKey(node.object) : undefined);
232
+ const propName = (_e = (_d = node.property) === null || _d === void 0 ? void 0 : _d.name) !== null && _e !== void 0 ? _e : (_f = node.property) === null || _f === void 0 ? void 0 : _f.value;
233
+ if (objName && propName)
234
+ return `${objName}.${propName}`;
235
+ return undefined;
236
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * JavaScript/TypeScript HTTP interaction extractor.
3
+ *
4
+ * Walks an AST node looking for HTTP client call patterns:
5
+ * - axios.METHOD(url, ...)
6
+ * - request.METHOD(url) / supertest(app).METHOD(url)
7
+ * - got.METHOD(url)
8
+ * - fetch(url, { method: 'POST' })
9
+ * - agent.METHOD(url)
10
+ * - http.METHOD(url) / https.METHOD(url)
11
+ *
12
+ * For each detected call, resolves the URL argument to a static string where
13
+ * possible (via constant lookup and template literal evaluation).
14
+ */
15
+ import type { SemanticHttpCall, SemanticSymbol } from '../../ast/astTypes';
16
+ type AstNode = any;
17
+ /**
18
+ * Extract all HTTP call sites from an AST subtree.
19
+ * Appends results to `out`. Recursively walks the full subtree.
20
+ */
21
+ export declare function extractHttpCallsFromNode(node: AstNode, constants: Map<string, SemanticSymbol>, out: SemanticHttpCall[], localVars?: Map<string, SemanticSymbol>): void;
22
+ export {};
23
+ //# sourceMappingURL=httpInteractionExtractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpInteractionExtractor.d.ts","sourceRoot":"","sources":["../../../../src/languages/javascript/httpInteractionExtractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAK3E,KAAK,OAAO,GAAG,GAAG,CAAC;AAyBnB;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,EACtC,GAAG,EAAE,gBAAgB,EAAE,EACvB,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GACtC,IAAI,CAyBN"}
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ /**
3
+ * JavaScript/TypeScript HTTP interaction extractor.
4
+ *
5
+ * Walks an AST node looking for HTTP client call patterns:
6
+ * - axios.METHOD(url, ...)
7
+ * - request.METHOD(url) / supertest(app).METHOD(url)
8
+ * - got.METHOD(url)
9
+ * - fetch(url, { method: 'POST' })
10
+ * - agent.METHOD(url)
11
+ * - http.METHOD(url) / https.METHOD(url)
12
+ *
13
+ * For each detected call, resolves the URL argument to a static string where
14
+ * possible (via constant lookup and template literal evaluation).
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.extractHttpCallsFromNode = extractHttpCallsFromNode;
18
+ const callResolver_1 = require("./callResolver");
19
+ const resolvePaths_1 = require("../../coverage/deep-analysis/resolvePaths");
20
+ const HTTP_METHODS = new Set(['get', 'post', 'put', 'patch', 'delete', 'head', 'options']);
21
+ /**
22
+ * HTTP client object names/prefixes that follow the pattern client.METHOD(url).
23
+ */
24
+ const HTTP_CLIENT_OBJECTS = new Set([
25
+ 'axios',
26
+ 'request',
27
+ 'supertest',
28
+ 'agent',
29
+ 'got',
30
+ 'client',
31
+ 'api',
32
+ 'http',
33
+ 'https',
34
+ 'instance',
35
+ 'app',
36
+ 'server',
37
+ 'testClient',
38
+ 'apiClient',
39
+ 'httpClient',
40
+ ]);
41
+ /**
42
+ * Extract all HTTP call sites from an AST subtree.
43
+ * Appends results to `out`. Recursively walks the full subtree.
44
+ */
45
+ function extractHttpCallsFromNode(node, constants, out, localVars) {
46
+ if (!node || typeof node !== 'object')
47
+ return;
48
+ if (node.type === 'CallExpression') {
49
+ const call = tryExtractHttpCall(node, constants, localVars);
50
+ if (call) {
51
+ out.push(call);
52
+ return; // Don't recurse into the args of a matched call
53
+ }
54
+ }
55
+ // Recurse
56
+ for (const key of Object.keys(node)) {
57
+ if (key === 'parent' || key === 'tokens' || key === 'comments')
58
+ continue;
59
+ const child = node[key];
60
+ if (Array.isArray(child)) {
61
+ for (const c of child) {
62
+ if (c && typeof c === 'object' && c.type) {
63
+ extractHttpCallsFromNode(c, constants, out, localVars);
64
+ }
65
+ }
66
+ }
67
+ else if (child && typeof child === 'object' && child.type) {
68
+ extractHttpCallsFromNode(child, constants, out, localVars);
69
+ }
70
+ }
71
+ }
72
+ function tryExtractHttpCall(callNode, constants, localVars) {
73
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
74
+ const callee = callNode.callee;
75
+ if (!callee)
76
+ return null;
77
+ // Pattern 1: axios.get(url), client.post(url), etc.
78
+ if (callee.type === 'MemberExpression') {
79
+ const methodName = (_b = (_a = callee.property) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.toLowerCase();
80
+ if (!methodName || !HTTP_METHODS.has(methodName))
81
+ return null;
82
+ const objName = getObjectName(callee.object);
83
+ // Check if object is a known HTTP client
84
+ if (!isHttpClientObject(objName, callee.object))
85
+ return null;
86
+ const urlArg = (_c = callNode.arguments) === null || _c === void 0 ? void 0 : _c[0];
87
+ if (!urlArg)
88
+ return null;
89
+ const rawPath = urlArg.type === 'Literal' ? urlArg.value : undefined;
90
+ const resolvedPath = (0, callResolver_1.evaluateStringNode)(urlArg, constants, localVars);
91
+ const path = (_d = resolvedPath !== null && resolvedPath !== void 0 ? resolvedPath : rawPath) !== null && _d !== void 0 ? _d : '';
92
+ // Detect response variable: const resp = client.get(...)
93
+ const responseVariable = extractResponseVariable(callNode);
94
+ return buildHttpCall(methodName.toUpperCase(), rawPath !== null && rawPath !== void 0 ? rawPath : argSource(urlArg), path, rawPath !== undefined, responseVariable, (_f = (_e = callNode.loc) === null || _e === void 0 ? void 0 : _e.start) === null || _f === void 0 ? void 0 : _f.line);
95
+ }
96
+ // Pattern 2: fetch(url, { method: 'POST' })
97
+ if (callee.type === 'Identifier' && callee.name === 'fetch') {
98
+ const urlArg = (_g = callNode.arguments) === null || _g === void 0 ? void 0 : _g[0];
99
+ const optionsArg = (_h = callNode.arguments) === null || _h === void 0 ? void 0 : _h[1];
100
+ const method = (_j = extractMethodFromOptions(optionsArg)) !== null && _j !== void 0 ? _j : 'GET';
101
+ if (!urlArg)
102
+ return null;
103
+ const rawPath = urlArg.type === 'Literal' ? urlArg.value : undefined;
104
+ const resolvedPath = (0, callResolver_1.evaluateStringNode)(urlArg, constants, localVars);
105
+ const path = (_k = resolvedPath !== null && resolvedPath !== void 0 ? resolvedPath : rawPath) !== null && _k !== void 0 ? _k : '';
106
+ return buildHttpCall(method.toUpperCase(), rawPath !== null && rawPath !== void 0 ? rawPath : argSource(urlArg), path, rawPath !== undefined, extractResponseVariable(callNode), (_m = (_l = callNode.loc) === null || _l === void 0 ? void 0 : _l.start) === null || _m === void 0 ? void 0 : _m.line);
107
+ }
108
+ return null;
109
+ }
110
+ function isHttpClientObject(objName, objectNode) {
111
+ var _a, _b, _c, _d, _e, _f, _g, _h;
112
+ if (!objName)
113
+ return false;
114
+ // Direct match: axios.get, client.post, etc.
115
+ if (HTTP_CLIENT_OBJECTS.has(objName.toLowerCase()))
116
+ return true;
117
+ // Chained call: supertest(app).get('/path') — the object is a CallExpression
118
+ if ((objectNode === null || objectNode === void 0 ? void 0 : objectNode.type) === 'CallExpression') {
119
+ const chainedCallee = (_e = (_b = (_a = objectNode.callee) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : (_d = (_c = objectNode.callee) === null || _c === void 0 ? void 0 : _c.property) === null || _d === void 0 ? void 0 : _d.name) !== null && _e !== void 0 ? _e : '';
120
+ const chainedLower = chainedCallee.toLowerCase();
121
+ if (HTTP_CLIENT_OBJECTS.has(chainedLower) || chainedLower === 'supertest')
122
+ return true;
123
+ }
124
+ // Member chains: this.client.get, app.agent().get, etc.
125
+ if ((objectNode === null || objectNode === void 0 ? void 0 : objectNode.type) === 'MemberExpression') {
126
+ const innerProp = (_h = (_g = (_f = objectNode.property) === null || _f === void 0 ? void 0 : _f.name) === null || _g === void 0 ? void 0 : _g.toLowerCase()) !== null && _h !== void 0 ? _h : '';
127
+ if (HTTP_CLIENT_OBJECTS.has(innerProp) ||
128
+ innerProp.includes('client') ||
129
+ innerProp.includes('agent') ||
130
+ innerProp.includes('api')) {
131
+ return true;
132
+ }
133
+ }
134
+ // Ends with 'Client', 'Api', 'Agent'
135
+ const lower = objName.toLowerCase();
136
+ if (lower.endsWith('client') || lower.endsWith('api') || lower.endsWith('agent'))
137
+ return true;
138
+ return false;
139
+ }
140
+ function getObjectName(objectNode) {
141
+ var _a, _b, _c, _d, _e, _f;
142
+ if (!objectNode)
143
+ return undefined;
144
+ if (objectNode.type === 'Identifier')
145
+ return objectNode.name;
146
+ if (objectNode.type === 'MemberExpression') {
147
+ return (_a = (0, callResolver_1.memberKey)(objectNode)) !== null && _a !== void 0 ? _a : (_b = objectNode.property) === null || _b === void 0 ? void 0 : _b.name;
148
+ }
149
+ if (objectNode.type === 'CallExpression') {
150
+ return (_d = (_c = objectNode.callee) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : (_f = (_e = objectNode.callee) === null || _e === void 0 ? void 0 : _e.property) === null || _f === void 0 ? void 0 : _f.name;
151
+ }
152
+ if (objectNode.type === 'ThisExpression')
153
+ return 'this';
154
+ return undefined;
155
+ }
156
+ function extractMethodFromOptions(optionsNode) {
157
+ var _a, _b, _c, _d, _e;
158
+ if (!optionsNode || optionsNode.type !== 'ObjectExpression')
159
+ return undefined;
160
+ for (const prop of (_a = optionsNode.properties) !== null && _a !== void 0 ? _a : []) {
161
+ const keyName = (_c = (_b = prop.key) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : (_d = prop.key) === null || _d === void 0 ? void 0 : _d.value;
162
+ if (keyName === 'method' && ((_e = prop.value) === null || _e === void 0 ? void 0 : _e.type) === 'Literal') {
163
+ return String(prop.value.value);
164
+ }
165
+ }
166
+ return undefined;
167
+ }
168
+ function extractResponseVariable(callNode) {
169
+ var _a, _b;
170
+ // Walk up to find assignment pattern: const response = client.get(...)
171
+ const parent = callNode._parent;
172
+ if (!parent)
173
+ return undefined;
174
+ if (parent.type === 'VariableDeclarator' && ((_a = parent.id) === null || _a === void 0 ? void 0 : _a.name)) {
175
+ return parent.id.name;
176
+ }
177
+ if (parent.type === 'AssignmentExpression' && ((_b = parent.left) === null || _b === void 0 ? void 0 : _b.name)) {
178
+ return parent.left.name;
179
+ }
180
+ return undefined;
181
+ }
182
+ function argSource(node) {
183
+ var _a;
184
+ if (!node)
185
+ return '';
186
+ if (node.type === 'Identifier')
187
+ return node.name;
188
+ if (node.type === 'MemberExpression')
189
+ return (_a = (0, callResolver_1.memberKey)(node)) !== null && _a !== void 0 ? _a : '';
190
+ return '';
191
+ }
192
+ function buildHttpCall(method, rawPathArg, resolvedPath, isDirect, responseVariable, line) {
193
+ const hasResolution = resolvedPath && resolvedPath.startsWith('/');
194
+ const normalizedPath = hasResolution ? (0, resolvePaths_1.normalizePathToTemplate)(resolvedPath) : undefined;
195
+ return {
196
+ method,
197
+ rawPathArg,
198
+ resolvedPath: hasResolution ? resolvedPath : undefined,
199
+ normalizedPath,
200
+ resolutionType: isDirect ? 'direct' : resolvedPath !== rawPathArg ? 'constant' : 'heuristic',
201
+ confidence: isDirect ? 'high' : resolvedPath ? 'medium' : 'low',
202
+ responseVariable,
203
+ line,
204
+ };
205
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * JavaScript language analyzer.
3
+ *
4
+ * Implements the LanguageAnalyzer contract using @typescript-eslint/typescript-estree.
5
+ * Registered for both 'javascript' and (via TypeScriptAnalyzer) 'typescript'.
6
+ */
7
+ import type { LanguageAnalyzer } from '../../ast/languageAnalyzer';
8
+ import type { SupportedLanguage, ParsedSourceFile, SemanticModel, ResolvedHttpInteraction, SemanticAssertion, BusinessRuleRef, FlowRef, AnalysisContext } from '../../ast/astTypes';
9
+ export declare class JavaScriptAnalyzer implements LanguageAnalyzer {
10
+ readonly language: SupportedLanguage;
11
+ parse(filePath: string, content: string): ParsedSourceFile;
12
+ buildSemanticModel(parsed: ParsedSourceFile, _context: AnalysisContext): SemanticModel;
13
+ extractHttpInteractions(model: SemanticModel, context: AnalysisContext): ResolvedHttpInteraction[];
14
+ private resolveWrappers;
15
+ private traceHelper;
16
+ extractAssertions(model: SemanticModel): SemanticAssertion[];
17
+ extractBusinessRuleRefs(model: SemanticModel): BusinessRuleRef[];
18
+ extractFlowRefs(model: SemanticModel): FlowRef[];
19
+ }
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/languages/javascript/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EAEb,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,OAAO,EACP,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAU5B,qBAAa,kBAAmB,YAAW,gBAAgB;IACzD,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAgB;IAEpD,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,gBAAgB;IAI1D,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,eAAe,GAAG,aAAa;IA2BtF,uBAAuB,CACrB,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,eAAe,GACvB,uBAAuB,EAAE;IAqE5B,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,WAAW;IAgCnB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,iBAAiB,EAAE;IAI5D,uBAAuB,CAAC,KAAK,EAAE,aAAa,GAAG,eAAe,EAAE;IAIhE,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,EAAE;CAGjD"}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ /**
3
+ * JavaScript language analyzer.
4
+ *
5
+ * Implements the LanguageAnalyzer contract using @typescript-eslint/typescript-estree.
6
+ * Registered for both 'javascript' and (via TypeScriptAnalyzer) 'typescript'.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.JavaScriptAnalyzer = void 0;
10
+ const parserRegistry_1 = require("../../ast/parserRegistry");
11
+ const parser_1 = require("./parser");
12
+ const symbolResolver_1 = require("./symbolResolver");
13
+ const callResolver_1 = require("./callResolver");
14
+ const httpInteractionExtractor_1 = require("./httpInteractionExtractor");
15
+ const assertionResolver_1 = require("./assertionResolver");
16
+ const resolvePaths_1 = require("../../coverage/deep-analysis/resolvePaths");
17
+ const annotationExtractor_1 = require("./annotationExtractor");
18
+ class JavaScriptAnalyzer {
19
+ constructor() {
20
+ this.language = 'javascript';
21
+ }
22
+ parse(filePath, content) {
23
+ return (0, parser_1.parseJsTs)(filePath, content, this.language);
24
+ }
25
+ buildSemanticModel(parsed, _context) {
26
+ var _a;
27
+ const { constants, localVariables } = (0, symbolResolver_1.extractSymbols)(parsed.ast);
28
+ const functions = (0, callResolver_1.buildCallGraph)(parsed.ast, constants);
29
+ const httpInteractions = [];
30
+ const assertions = (0, assertionResolver_1.extractAssertions)(parsed.ast);
31
+ const businessRuleRefs = (0, annotationExtractor_1.extractBusinessRuleRefs)(parsed.ast);
32
+ const flowRefs = (0, annotationExtractor_1.extractFlowRefs)(parsed.ast);
33
+ // Extract top-level HTTP calls (outside function bodies)
34
+ if ((_a = parsed.ast) === null || _a === void 0 ? void 0 : _a.body) {
35
+ (0, httpInteractionExtractor_1.extractHttpCallsFromNode)(parsed.ast, constants, httpInteractions);
36
+ }
37
+ return {
38
+ filePath: parsed.filePath,
39
+ language: this.language,
40
+ localVariables,
41
+ constants,
42
+ enums: new Map(),
43
+ functions,
44
+ httpInteractions,
45
+ assertions,
46
+ businessRuleRefs,
47
+ flowRefs,
48
+ };
49
+ }
50
+ extractHttpInteractions(model, context) {
51
+ var _a, _b, _c;
52
+ const results = [];
53
+ const seen = new Set();
54
+ const maxDepth = (_a = context.astConfig.maxCallDepth) !== null && _a !== void 0 ? _a : 4;
55
+ function addCall(method, path, rawPathArg, resolutionType, confidence, responseVariable) {
56
+ const normalizedPath = path.startsWith('/') ? (0, resolvePaths_1.normalizePathToTemplate)(path) : undefined;
57
+ const key = `${method}:${normalizedPath !== null && normalizedPath !== void 0 ? normalizedPath : path}:${resolutionType}`;
58
+ if (seen.has(key))
59
+ return;
60
+ seen.add(key);
61
+ results.push({
62
+ method,
63
+ path,
64
+ normalizedPath,
65
+ sourceFile: model.filePath,
66
+ sourceLanguage: model.language,
67
+ resolutionType,
68
+ confidence,
69
+ responseVariable,
70
+ rawCall: rawPathArg,
71
+ });
72
+ }
73
+ // From function bodies (most test interactions are inside it/test blocks)
74
+ for (const fn of model.functions.values()) {
75
+ for (const call of fn.bodyHttpCalls) {
76
+ const path = (_b = call.resolvedPath) !== null && _b !== void 0 ? _b : call.rawPathArg;
77
+ if (!path)
78
+ continue;
79
+ addCall(call.method, path, call.rawPathArg, call.resolutionType, call.confidence, call.responseVariable);
80
+ }
81
+ }
82
+ // From top-level (module-level calls)
83
+ for (const call of model.httpInteractions) {
84
+ const path = (_c = call.resolvedPath) !== null && _c !== void 0 ? _c : call.rawPathArg;
85
+ if (!path)
86
+ continue;
87
+ addCall(call.method, path, call.rawPathArg, call.resolutionType, call.confidence, call.responseVariable);
88
+ }
89
+ // Wrapper function resolution: trace calledFunctions up to maxDepth
90
+ if (context.deepConfig.resolveWrappers) {
91
+ this.resolveWrappers(model, maxDepth, addCall, seen);
92
+ }
93
+ return results;
94
+ }
95
+ resolveWrappers(model, maxDepth, addCall, seen) {
96
+ // For each function that calls another local function but has no direct HTTP calls,
97
+ // try to resolve the called function's HTTP interactions
98
+ for (const fn of model.functions.values()) {
99
+ if (fn.bodyHttpCalls.length > 0)
100
+ continue; // Already has direct calls
101
+ for (const calledName of fn.calledFunctions) {
102
+ this.traceHelper(calledName, model, maxDepth, addCall, seen, new Set());
103
+ }
104
+ }
105
+ }
106
+ traceHelper(fnName, model, depth, addCall, seen, visited) {
107
+ var _a;
108
+ if (depth <= 0 || visited.has(fnName))
109
+ return;
110
+ visited.add(fnName);
111
+ const fn = model.functions.get(fnName);
112
+ if (!fn)
113
+ return;
114
+ for (const call of fn.bodyHttpCalls) {
115
+ const path = (_a = call.resolvedPath) !== null && _a !== void 0 ? _a : call.rawPathArg;
116
+ if (!path)
117
+ continue;
118
+ addCall(call.method, path, call.rawPathArg, 'wrapper-method', 'medium');
119
+ }
120
+ for (const nested of fn.calledFunctions) {
121
+ this.traceHelper(nested, model, depth - 1, addCall, seen, visited);
122
+ }
123
+ }
124
+ extractAssertions(model) {
125
+ return model.assertions;
126
+ }
127
+ extractBusinessRuleRefs(model) {
128
+ return model.businessRuleRefs;
129
+ }
130
+ extractFlowRefs(model) {
131
+ return model.flowRefs;
132
+ }
133
+ }
134
+ exports.JavaScriptAnalyzer = JavaScriptAnalyzer;
135
+ // Register the JavaScript analyzer
136
+ (0, parserRegistry_1.registerAnalyzer)('javascript', () => new JavaScriptAnalyzer());