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,290 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.parseBusinessRules = parseBusinessRules;
40
+ exports.analyzeBusinessCoverage = analyzeBusinessCoverage;
41
+ exports.buildBusinessCoverageReport = buildBusinessCoverageReport;
42
+ exports.generateBusinessReports = generateBusinessReports;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const yaml = __importStar(require("js-yaml"));
46
+ const fast_glob_1 = __importDefault(require("fast-glob"));
47
+ // ─── Parsing ──────────────────────────────────────────────────────────────────
48
+ /**
49
+ * Parse a YAML or JSON business-rules definition file.
50
+ * The file must contain a top-level `rules` array.
51
+ */
52
+ function parseBusinessRules(rulesPath) {
53
+ const raw = fs.readFileSync(rulesPath, 'utf-8');
54
+ const ext = path.extname(rulesPath).toLowerCase();
55
+ let parsed;
56
+ if (ext === '.json') {
57
+ parsed = JSON.parse(raw);
58
+ }
59
+ else {
60
+ // Default to YAML (also handles .yaml and .yml)
61
+ parsed = yaml.load(raw);
62
+ }
63
+ if (!parsed ||
64
+ typeof parsed !== 'object' ||
65
+ !Array.isArray(parsed.rules)) {
66
+ throw new Error(`Invalid business rules file: expected a top-level "rules" array in ${rulesPath}`);
67
+ }
68
+ return parsed.rules;
69
+ }
70
+ /**
71
+ * Extract all test / it declarations from a file, together with their
72
+ * description string and the surrounding code up to the next declaration.
73
+ */
74
+ function extractTestEntries(filePath, fileContents) {
75
+ const entries = [];
76
+ const declPattern = /\b(?:test|it)\s*\(\s*(['"`])([\s\S]*?)\1/g;
77
+ const positions = [];
78
+ let m;
79
+ while ((m = declPattern.exec(fileContents)) !== null) {
80
+ positions.push({ start: m.index, desc: m[2] });
81
+ }
82
+ for (let i = 0; i < positions.length; i++) {
83
+ const start = positions[i].start;
84
+ const end = i + 1 < positions.length ? positions[i + 1].start : fileContents.length;
85
+ entries.push({
86
+ description: positions[i].desc,
87
+ content: fileContents.slice(start, end),
88
+ filePath,
89
+ });
90
+ }
91
+ return entries;
92
+ }
93
+ /**
94
+ * Determine whether a test entry matches a given set of keywords or rule ID annotation.
95
+ *
96
+ * A match occurs when:
97
+ * 1. The test description contains `@rule <ruleId>` (case-insensitive), OR
98
+ * 2. The test description (lowercased) contains at least one of the keywords.
99
+ */
100
+ function testMatchesKeywords(entry, ruleId, keywords) {
101
+ const descLower = entry.description.toLowerCase();
102
+ // Annotation-based match: @rule BL001
103
+ const annotationPattern = new RegExp(`@rule\\s+${ruleId}`, 'i');
104
+ if (annotationPattern.test(entry.description) || annotationPattern.test(entry.content)) {
105
+ return true;
106
+ }
107
+ // Keyword-based match (checked against description only for precision)
108
+ for (const kw of keywords) {
109
+ if (descLower.includes(kw.toLowerCase())) {
110
+ return true;
111
+ }
112
+ }
113
+ return false;
114
+ }
115
+ /**
116
+ * Analyse test files matching the given glob pattern and determine which
117
+ * business rules are covered.
118
+ */
119
+ async function analyzeBusinessCoverage(rules, testGlob) {
120
+ const testFiles = await (0, fast_glob_1.default)(testGlob, { onlyFiles: true });
121
+ // Pre-read all test files and extract test entries
122
+ const allEntries = [];
123
+ for (const filePath of testFiles) {
124
+ const contents = fs.readFileSync(filePath, 'utf-8');
125
+ allEntries.push(...extractTestEntries(filePath, contents));
126
+ }
127
+ return rules.map((rule) => {
128
+ var _a;
129
+ const matchedTests = [];
130
+ const matchedFiles = new Set();
131
+ for (const entry of allEntries) {
132
+ if (testMatchesKeywords(entry, rule.id, rule.keywords)) {
133
+ matchedTests.push(entry.description);
134
+ matchedFiles.add(entry.filePath);
135
+ }
136
+ }
137
+ const covered = matchedTests.length > 0;
138
+ // Scenario-level coverage
139
+ const scenarios = ((_a = rule.scenarios) !== null && _a !== void 0 ? _a : []).map((scenario) => {
140
+ var _a;
141
+ const scenarioMatches = [];
142
+ const scenarioKeywords = [
143
+ scenario.id,
144
+ ...((_a = scenario.keywords) !== null && _a !== void 0 ? _a : []),
145
+ ];
146
+ for (const entry of allEntries) {
147
+ // A test matches a scenario if it already matched the rule AND
148
+ // matches the scenario keywords/ID
149
+ if (testMatchesKeywords(entry, rule.id, rule.keywords) &&
150
+ testMatchesKeywords(entry, scenario.id, scenarioKeywords)) {
151
+ scenarioMatches.push(entry.description);
152
+ }
153
+ }
154
+ return {
155
+ scenario,
156
+ covered: scenarioMatches.length > 0,
157
+ matchedTests: scenarioMatches,
158
+ };
159
+ });
160
+ return {
161
+ rule,
162
+ covered,
163
+ testFiles: Array.from(matchedFiles),
164
+ matchedTests,
165
+ scenarios,
166
+ };
167
+ });
168
+ }
169
+ // ─── Report building ──────────────────────────────────────────────────────────
170
+ /**
171
+ * Build the coverage summary from a list of per-rule coverages.
172
+ */
173
+ function buildBusinessCoverageReport(coverages) {
174
+ const total = coverages.length;
175
+ const coveredCount = coverages.filter((c) => c.covered).length;
176
+ const percentage = total === 0 ? 0 : Math.round((coveredCount / total) * 10000) / 100;
177
+ const uncoveredRules = coverages.filter((c) => !c.covered).map((c) => c.rule);
178
+ return { total, covered: coveredCount, percentage, uncoveredRules, rules: coverages };
179
+ }
180
+ // ─── Report generation ────────────────────────────────────────────────────────
181
+ /**
182
+ * Write JSON and HTML business-coverage reports to the given directory.
183
+ */
184
+ function generateBusinessReports(report, reportsDir) {
185
+ if (!fs.existsSync(reportsDir)) {
186
+ fs.mkdirSync(reportsDir, { recursive: true });
187
+ }
188
+ // ── JSON ─────────────────────────────────────────────────────────────────
189
+ const jsonPath = path.join(reportsDir, 'business-coverage.json');
190
+ const jsonReport = {
191
+ total: report.total,
192
+ covered: report.covered,
193
+ percentage: report.percentage,
194
+ uncoveredRules: report.uncoveredRules.map(({ id, description }) => ({ id, description })),
195
+ rules: report.rules.map(({ rule, covered, testFiles, matchedTests, scenarios }) => {
196
+ var _a;
197
+ return ({
198
+ id: rule.id,
199
+ description: rule.description,
200
+ endpoints: (_a = rule.endpoints) !== null && _a !== void 0 ? _a : [],
201
+ covered,
202
+ testFiles,
203
+ matchedTests,
204
+ scenarios: scenarios.map(({ scenario, covered: sCovered, matchedTests: sTests }) => ({
205
+ id: scenario.id,
206
+ description: scenario.description,
207
+ covered: sCovered,
208
+ matchedTests: sTests,
209
+ })),
210
+ });
211
+ }),
212
+ };
213
+ fs.writeFileSync(jsonPath, JSON.stringify(jsonReport, null, 2), 'utf-8');
214
+ // ── HTML ─────────────────────────────────────────────────────────────────
215
+ const htmlPath = path.join(reportsDir, 'business-coverage.html');
216
+ const rows = report.rules
217
+ .map(({ rule, covered, matchedTests, scenarios }) => {
218
+ var _a;
219
+ const rowClass = covered ? 'covered' : 'uncovered';
220
+ const status = covered ? '✅ Covered' : '❌ Not covered';
221
+ const tests = matchedTests.length > 0 ? matchedTests.join('<br>') : '—';
222
+ const endpoints = ((_a = rule.endpoints) !== null && _a !== void 0 ? _a : []).join(', ') || '—';
223
+ const scenarioRows = scenarios.length > 0
224
+ ? scenarios
225
+ .map(({ scenario, covered: sc, matchedTests: st }) => {
226
+ const scStatus = sc ? '✅' : '❌';
227
+ const scTests = st.length > 0 ? st.join('<br>') : '—';
228
+ return ` <tr class="scenario ${sc ? 'covered' : 'uncovered'}">
229
+ <td></td>
230
+ <td class="scenario-id">${scenario.id}</td>
231
+ <td>${scenario.description}</td>
232
+ <td>${scStatus}</td>
233
+ <td>${scTests}</td>
234
+ </tr>`;
235
+ })
236
+ .join('\n')
237
+ : '';
238
+ return ` <tr class="${rowClass}">
239
+ <td><strong>${rule.id}</strong></td>
240
+ <td>${rule.description}</td>
241
+ <td>${endpoints}</td>
242
+ <td>${status}</td>
243
+ <td>${tests}</td>
244
+ </tr>
245
+ ${scenarioRows}`;
246
+ })
247
+ .join('\n');
248
+ const html = `<!DOCTYPE html>
249
+ <html lang="en">
250
+ <head>
251
+ <meta charset="UTF-8">
252
+ <title>Business Logic Coverage Report</title>
253
+ <style>
254
+ body { font-family: sans-serif; padding: 2rem; }
255
+ h1 { margin-bottom: 0.5rem; }
256
+ .summary { margin-bottom: 1.5rem; font-size: 1.1rem; }
257
+ table { border-collapse: collapse; width: 100%; }
258
+ th, td { border: 1px solid #ccc; padding: 0.5rem 1rem; text-align: left; }
259
+ th { background: #f0f0f0; }
260
+ tr.covered { background: #e6ffe6; }
261
+ tr.uncovered { background: #ffe6e6; }
262
+ tr.scenario { font-size: 0.9rem; }
263
+ tr.scenario td { padding: 0.3rem 1rem; }
264
+ td.scenario-id { font-style: italic; padding-left: 2rem; }
265
+ </style>
266
+ </head>
267
+ <body>
268
+ <h1>Business Logic Coverage Report</h1>
269
+ <div class="summary">
270
+ Covered: <strong>${report.covered}/${report.total}</strong> business rules
271
+ (<strong>${report.percentage}%</strong>)
272
+ </div>
273
+ <table>
274
+ <thead>
275
+ <tr>
276
+ <th>Rule ID</th>
277
+ <th>Description</th>
278
+ <th>Endpoints</th>
279
+ <th>Status</th>
280
+ <th>Matched Tests</th>
281
+ </tr>
282
+ </thead>
283
+ <tbody>
284
+ ${rows}
285
+ </tbody>
286
+ </table>
287
+ </body>
288
+ </html>`;
289
+ fs.writeFileSync(htmlPath, html, 'utf-8');
290
+ }
@@ -0,0 +1,83 @@
1
+ import { OpenAPIV3 } from 'openapi-types';
2
+ export type ChangeType = 'added' | 'removed' | 'changed-response-codes' | 'changed-parameter' | 'changed-schema';
3
+ export interface EndpointChange {
4
+ method: string;
5
+ path: string;
6
+ changeType: ChangeType;
7
+ breaking: boolean;
8
+ description: string;
9
+ }
10
+ /** A single interaction parsed from a consumer contract (Pact) file. */
11
+ export interface ContractInteraction {
12
+ description: string;
13
+ method: string;
14
+ path: string;
15
+ requestBody?: unknown;
16
+ expectedStatus: number;
17
+ expectedBody?: unknown;
18
+ }
19
+ /** A parsed consumer contract (Pact JSON) file. */
20
+ export interface ConsumerContract {
21
+ consumer: string;
22
+ provider: string;
23
+ interactions: ContractInteraction[];
24
+ filePath: string;
25
+ }
26
+ export interface ContractVerificationResult {
27
+ contract: ConsumerContract;
28
+ interactionResults: InteractionVerificationResult[];
29
+ passed: boolean;
30
+ }
31
+ export interface InteractionVerificationResult {
32
+ interaction: ContractInteraction;
33
+ passed: boolean;
34
+ reason?: string;
35
+ }
36
+ export interface CompatibilityReport {
37
+ generatedAt: string;
38
+ oldSpecPath: string;
39
+ newSpecPath: string;
40
+ totalOldEndpoints: number;
41
+ breakingChanges: EndpointChange[];
42
+ nonBreakingChanges: EndpointChange[];
43
+ compatibilityPercent: number;
44
+ contractVerificationResults: ContractVerificationResult[];
45
+ totalNewEndpoints: number;
46
+ contractCoveredEndpoints: number;
47
+ contractCoveragePercent: number;
48
+ }
49
+ /**
50
+ * Load and dereference an OpenAPI/Swagger spec from a file path.
51
+ */
52
+ export declare function loadSpec(specPath: string): Promise<OpenAPIV3.Document>;
53
+ /**
54
+ * Compare two API specs and return a list of detected changes.
55
+ */
56
+ export declare function compareSpecs(oldApi: OpenAPIV3.Document, newApi: OpenAPIV3.Document): EndpointChange[];
57
+ /**
58
+ * Parse Pact-format JSON contract files matching the given glob pattern or directory.
59
+ */
60
+ export declare function parseContractFiles(contractsGlob: string): Promise<ConsumerContract[]>;
61
+ /**
62
+ * Verify consumer contracts against a new API spec.
63
+ */
64
+ export declare function verifyContracts(contracts: ConsumerContract[], newApi: OpenAPIV3.Document): ContractVerificationResult[];
65
+ /**
66
+ * Compute compatibility percentage based on detected breaking changes.
67
+ */
68
+ export declare function computeCompatibilityPercent(totalOldEndpoints: number, breakingChanges: EndpointChange[]): number;
69
+ /**
70
+ * Compute what fraction of new spec endpoints are covered by at least one
71
+ * contract interaction.
72
+ */
73
+ export declare function computeContractCoveragePercent(contracts: ConsumerContract[], newApi: OpenAPIV3.Document): {
74
+ coveredEndpoints: number;
75
+ totalEndpoints: number;
76
+ coveragePercent: number;
77
+ };
78
+ export declare function buildCompatibilityReport(oldApi: OpenAPIV3.Document, newApi: OpenAPIV3.Document, changes: EndpointChange[], verificationResults: ContractVerificationResult[], oldSpecPath: string, newSpecPath: string): CompatibilityReport;
79
+ /**
80
+ * Generate JSON and HTML compatibility reports.
81
+ */
82
+ export declare function generateCompatibilityReports(report: CompatibilityReport, reportsDir: string): void;
83
+ //# sourceMappingURL=compatibilityCoverage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compatibilityCoverage.d.ts","sourceRoot":"","sources":["../../src/compatibilityCoverage.ts"],"names":[],"mappings":"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"}