@machina.ai/openapi-contract-tester 2.1.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 (431) hide show
  1. package/.env.example +91 -0
  2. package/README.md +472 -0
  3. package/dist/ai-engine/assertion-generator.d.ts +48 -0
  4. package/dist/ai-engine/assertion-generator.d.ts.map +1 -0
  5. package/dist/ai-engine/assertion-generator.js +166 -0
  6. package/dist/ai-engine/assertion-generator.js.map +1 -0
  7. package/dist/ai-engine/context-data-generator.d.ts +38 -0
  8. package/dist/ai-engine/context-data-generator.d.ts.map +1 -0
  9. package/dist/ai-engine/context-data-generator.js +146 -0
  10. package/dist/ai-engine/context-data-generator.js.map +1 -0
  11. package/dist/ai-engine/dataflow-detector.d.ts +53 -0
  12. package/dist/ai-engine/dataflow-detector.d.ts.map +1 -0
  13. package/dist/ai-engine/dataflow-detector.js +217 -0
  14. package/dist/ai-engine/dataflow-detector.js.map +1 -0
  15. package/dist/ai-engine/dependency-detector.d.ts +52 -0
  16. package/dist/ai-engine/dependency-detector.d.ts.map +1 -0
  17. package/dist/ai-engine/dependency-detector.js +241 -0
  18. package/dist/ai-engine/dependency-detector.js.map +1 -0
  19. package/dist/ai-engine/edge-case-suggester.d.ts +63 -0
  20. package/dist/ai-engine/edge-case-suggester.d.ts.map +1 -0
  21. package/dist/ai-engine/edge-case-suggester.js +177 -0
  22. package/dist/ai-engine/edge-case-suggester.js.map +1 -0
  23. package/dist/ai-engine/index.d.ts +13 -0
  24. package/dist/ai-engine/index.d.ts.map +1 -0
  25. package/dist/ai-engine/index.js +13 -0
  26. package/dist/ai-engine/index.js.map +1 -0
  27. package/dist/analyzers/ai-failure-analyzer.d.ts +41 -0
  28. package/dist/analyzers/ai-failure-analyzer.d.ts.map +1 -0
  29. package/dist/analyzers/ai-failure-analyzer.js +220 -0
  30. package/dist/analyzers/ai-failure-analyzer.js.map +1 -0
  31. package/dist/analyzers/comparison-utils.d.ts +31 -0
  32. package/dist/analyzers/comparison-utils.d.ts.map +1 -0
  33. package/dist/analyzers/comparison-utils.js +85 -0
  34. package/dist/analyzers/comparison-utils.js.map +1 -0
  35. package/dist/analyzers/context-analyzer.d.ts +49 -0
  36. package/dist/analyzers/context-analyzer.d.ts.map +1 -0
  37. package/dist/analyzers/context-analyzer.js +292 -0
  38. package/dist/analyzers/context-analyzer.js.map +1 -0
  39. package/dist/analyzers/dependency-analyzer.d.ts +44 -0
  40. package/dist/analyzers/dependency-analyzer.d.ts.map +1 -0
  41. package/dist/analyzers/dependency-analyzer.js +313 -0
  42. package/dist/analyzers/dependency-analyzer.js.map +1 -0
  43. package/dist/analyzers/failure-analyzer.d.ts +122 -0
  44. package/dist/analyzers/failure-analyzer.d.ts.map +1 -0
  45. package/dist/analyzers/failure-analyzer.js +140 -0
  46. package/dist/analyzers/failure-analyzer.js.map +1 -0
  47. package/dist/analyzers/failure-detectors/index.d.ts +33 -0
  48. package/dist/analyzers/failure-detectors/index.d.ts.map +1 -0
  49. package/dist/analyzers/failure-detectors/index.js +164 -0
  50. package/dist/analyzers/failure-detectors/index.js.map +1 -0
  51. package/dist/analyzers/failure-discrepancy-correlator.d.ts +111 -0
  52. package/dist/analyzers/failure-discrepancy-correlator.d.ts.map +1 -0
  53. package/dist/analyzers/failure-discrepancy-correlator.js +202 -0
  54. package/dist/analyzers/failure-discrepancy-correlator.js.map +1 -0
  55. package/dist/analyzers/index.d.ts +10 -0
  56. package/dist/analyzers/index.d.ts.map +1 -0
  57. package/dist/analyzers/index.js +10 -0
  58. package/dist/analyzers/index.js.map +1 -0
  59. package/dist/analyzers/semantic-matcher.d.ts +123 -0
  60. package/dist/analyzers/semantic-matcher.d.ts.map +1 -0
  61. package/dist/analyzers/semantic-matcher.js +297 -0
  62. package/dist/analyzers/semantic-matcher.js.map +1 -0
  63. package/dist/analyzers/source-comparator.d.ts +177 -0
  64. package/dist/analyzers/source-comparator.d.ts.map +1 -0
  65. package/dist/analyzers/source-comparator.js +225 -0
  66. package/dist/analyzers/source-comparator.js.map +1 -0
  67. package/dist/business-rules/business-rules-analyzer.d.ts +44 -0
  68. package/dist/business-rules/business-rules-analyzer.d.ts.map +1 -0
  69. package/dist/business-rules/business-rules-analyzer.js +363 -0
  70. package/dist/business-rules/business-rules-analyzer.js.map +1 -0
  71. package/dist/business-rules/business-rules-generator.d.ts +78 -0
  72. package/dist/business-rules/business-rules-generator.d.ts.map +1 -0
  73. package/dist/business-rules/business-rules-generator.js +357 -0
  74. package/dist/business-rules/business-rules-generator.js.map +1 -0
  75. package/dist/business-rules/extractors/rule-extractors.d.ts +50 -0
  76. package/dist/business-rules/extractors/rule-extractors.d.ts.map +1 -0
  77. package/dist/business-rules/extractors/rule-extractors.js +189 -0
  78. package/dist/business-rules/extractors/rule-extractors.js.map +1 -0
  79. package/dist/business-rules/value-generators.d.ts +70 -0
  80. package/dist/business-rules/value-generators.d.ts.map +1 -0
  81. package/dist/business-rules/value-generators.js +142 -0
  82. package/dist/business-rules/value-generators.js.map +1 -0
  83. package/dist/executor/auth-providers/auth-header-builder.d.ts +16 -0
  84. package/dist/executor/auth-providers/auth-header-builder.d.ts.map +1 -0
  85. package/dist/executor/auth-providers/auth-header-builder.js +47 -0
  86. package/dist/executor/auth-providers/auth-header-builder.js.map +1 -0
  87. package/dist/executor/auth-providers/oauth2-provider.d.ts +19 -0
  88. package/dist/executor/auth-providers/oauth2-provider.d.ts.map +1 -0
  89. package/dist/executor/auth-providers/oauth2-provider.js +114 -0
  90. package/dist/executor/auth-providers/oauth2-provider.js.map +1 -0
  91. package/dist/executor/http-client.d.ts +133 -0
  92. package/dist/executor/http-client.d.ts.map +1 -0
  93. package/dist/executor/http-client.js +172 -0
  94. package/dist/executor/http-client.js.map +1 -0
  95. package/dist/executor/http-request-builder.d.ts +69 -0
  96. package/dist/executor/http-request-builder.d.ts.map +1 -0
  97. package/dist/executor/http-request-builder.js +140 -0
  98. package/dist/executor/http-request-builder.js.map +1 -0
  99. package/dist/executor/http-response-parser.d.ts +28 -0
  100. package/dist/executor/http-response-parser.d.ts.map +1 -0
  101. package/dist/executor/http-response-parser.js +74 -0
  102. package/dist/executor/http-response-parser.js.map +1 -0
  103. package/dist/executor/response-handler.d.ts +66 -0
  104. package/dist/executor/response-handler.d.ts.map +1 -0
  105. package/dist/executor/response-handler.js +135 -0
  106. package/dist/executor/response-handler.js.map +1 -0
  107. package/dist/executor/result-processor.d.ts +27 -0
  108. package/dist/executor/result-processor.d.ts.map +1 -0
  109. package/dist/executor/result-processor.js +140 -0
  110. package/dist/executor/result-processor.js.map +1 -0
  111. package/dist/executor/result-utils.d.ts +21 -0
  112. package/dist/executor/result-utils.d.ts.map +1 -0
  113. package/dist/executor/result-utils.js +29 -0
  114. package/dist/executor/result-utils.js.map +1 -0
  115. package/dist/executor/test-executor.d.ts +49 -0
  116. package/dist/executor/test-executor.d.ts.map +1 -0
  117. package/dist/executor/test-executor.js +226 -0
  118. package/dist/executor/test-executor.js.map +1 -0
  119. package/dist/executor/test-runner.d.ts +85 -0
  120. package/dist/executor/test-runner.d.ts.map +1 -0
  121. package/dist/executor/test-runner.js +177 -0
  122. package/dist/executor/test-runner.js.map +1 -0
  123. package/dist/executor/token-detector/index.d.ts +7 -0
  124. package/dist/executor/token-detector/index.d.ts.map +1 -0
  125. package/dist/executor/token-detector/index.js +7 -0
  126. package/dist/executor/token-detector/index.js.map +1 -0
  127. package/dist/executor/token-detector/token-detector.d.ts +64 -0
  128. package/dist/executor/token-detector/token-detector.d.ts.map +1 -0
  129. package/dist/executor/token-detector/token-detector.js +140 -0
  130. package/dist/executor/token-detector/token-detector.js.map +1 -0
  131. package/dist/generators/business-rule-from-stories-generator.d.ts +30 -0
  132. package/dist/generators/business-rule-from-stories-generator.d.ts.map +1 -0
  133. package/dist/generators/business-rule-from-stories-generator.js +227 -0
  134. package/dist/generators/business-rule-from-stories-generator.js.map +1 -0
  135. package/dist/generators/data/ai-data-generator.d.ts +23 -0
  136. package/dist/generators/data/ai-data-generator.d.ts.map +1 -0
  137. package/dist/generators/data/ai-data-generator.js +41 -0
  138. package/dist/generators/data/ai-data-generator.js.map +1 -0
  139. package/dist/generators/data/base-generator.d.ts +121 -0
  140. package/dist/generators/data/base-generator.d.ts.map +1 -0
  141. package/dist/generators/data/base-generator.js +200 -0
  142. package/dist/generators/data/base-generator.js.map +1 -0
  143. package/dist/generators/data/heuristic-data-generator.d.ts +28 -0
  144. package/dist/generators/data/heuristic-data-generator.d.ts.map +1 -0
  145. package/dist/generators/data/heuristic-data-generator.js +49 -0
  146. package/dist/generators/data/heuristic-data-generator.js.map +1 -0
  147. package/dist/generators/data/index.d.ts +48 -0
  148. package/dist/generators/data/index.d.ts.map +1 -0
  149. package/dist/generators/data/index.js +201 -0
  150. package/dist/generators/data/index.js.map +1 -0
  151. package/dist/generators/data/schema-walker.d.ts +45 -0
  152. package/dist/generators/data/schema-walker.d.ts.map +1 -0
  153. package/dist/generators/data/schema-walker.js +103 -0
  154. package/dist/generators/data/schema-walker.js.map +1 -0
  155. package/dist/generators/data/type-strategies.d.ts +79 -0
  156. package/dist/generators/data/type-strategies.d.ts.map +1 -0
  157. package/dist/generators/data/type-strategies.js +394 -0
  158. package/dist/generators/data/type-strategies.js.map +1 -0
  159. package/dist/generators/data-generator.d.ts +11 -0
  160. package/dist/generators/data-generator.d.ts.map +1 -0
  161. package/dist/generators/data-generator.js +11 -0
  162. package/dist/generators/data-generator.js.map +1 -0
  163. package/dist/generators/edge-case-generator.d.ts +55 -0
  164. package/dist/generators/edge-case-generator.d.ts.map +1 -0
  165. package/dist/generators/edge-case-generator.js +327 -0
  166. package/dist/generators/edge-case-generator.js.map +1 -0
  167. package/dist/generators/edge-cases/boundary-analyzer.d.ts +26 -0
  168. package/dist/generators/edge-cases/boundary-analyzer.d.ts.map +1 -0
  169. package/dist/generators/edge-cases/boundary-analyzer.js +95 -0
  170. package/dist/generators/edge-cases/boundary-analyzer.js.map +1 -0
  171. package/dist/generators/error-case-generator.d.ts +11 -0
  172. package/dist/generators/error-case-generator.d.ts.map +1 -0
  173. package/dist/generators/error-case-generator.js +11 -0
  174. package/dist/generators/error-case-generator.js.map +1 -0
  175. package/dist/generators/errors/auth-error-strategy.d.ts +36 -0
  176. package/dist/generators/errors/auth-error-strategy.d.ts.map +1 -0
  177. package/dist/generators/errors/auth-error-strategy.js +118 -0
  178. package/dist/generators/errors/auth-error-strategy.js.map +1 -0
  179. package/dist/generators/errors/business-error-strategy.d.ts +44 -0
  180. package/dist/generators/errors/business-error-strategy.d.ts.map +1 -0
  181. package/dist/generators/errors/business-error-strategy.js +152 -0
  182. package/dist/generators/errors/business-error-strategy.js.map +1 -0
  183. package/dist/generators/errors/error-strategy-factory.d.ts +27 -0
  184. package/dist/generators/errors/error-strategy-factory.d.ts.map +1 -0
  185. package/dist/generators/errors/error-strategy-factory.js +47 -0
  186. package/dist/generators/errors/error-strategy-factory.js.map +1 -0
  187. package/dist/generators/errors/error-strategy.d.ts +62 -0
  188. package/dist/generators/errors/error-strategy.d.ts.map +1 -0
  189. package/dist/generators/errors/error-strategy.js +69 -0
  190. package/dist/generators/errors/error-strategy.js.map +1 -0
  191. package/dist/generators/errors/index.d.ts +23 -0
  192. package/dist/generators/errors/index.d.ts.map +1 -0
  193. package/dist/generators/errors/index.js +73 -0
  194. package/dist/generators/errors/index.js.map +1 -0
  195. package/dist/generators/errors/validation-error-strategy.d.ts +25 -0
  196. package/dist/generators/errors/validation-error-strategy.d.ts.map +1 -0
  197. package/dist/generators/errors/validation-error-strategy.js +214 -0
  198. package/dist/generators/errors/validation-error-strategy.js.map +1 -0
  199. package/dist/generators/happy-path-generator.d.ts +93 -0
  200. package/dist/generators/happy-path-generator.d.ts.map +1 -0
  201. package/dist/generators/happy-path-generator.js +275 -0
  202. package/dist/generators/happy-path-generator.js.map +1 -0
  203. package/dist/generators/test-enricher.d.ts +44 -0
  204. package/dist/generators/test-enricher.d.ts.map +1 -0
  205. package/dist/generators/test-enricher.js +109 -0
  206. package/dist/generators/test-enricher.js.map +1 -0
  207. package/dist/index.d.ts +9 -0
  208. package/dist/index.d.ts.map +1 -0
  209. package/dist/index.js +14 -0
  210. package/dist/index.js.map +1 -0
  211. package/dist/llm/ai-cache.d.ts +123 -0
  212. package/dist/llm/ai-cache.d.ts.map +1 -0
  213. package/dist/llm/ai-cache.js +220 -0
  214. package/dist/llm/ai-cache.js.map +1 -0
  215. package/dist/llm/ai-client.d.ts +92 -0
  216. package/dist/llm/ai-client.d.ts.map +1 -0
  217. package/dist/llm/ai-client.js +386 -0
  218. package/dist/llm/ai-client.js.map +1 -0
  219. package/dist/llm/data-generator-ai.d.ts +84 -0
  220. package/dist/llm/data-generator-ai.d.ts.map +1 -0
  221. package/dist/llm/data-generator-ai.js +284 -0
  222. package/dist/llm/data-generator-ai.js.map +1 -0
  223. package/dist/llm/index.d.ts +7 -0
  224. package/dist/llm/index.d.ts.map +1 -0
  225. package/dist/llm/index.js +7 -0
  226. package/dist/llm/index.js.map +1 -0
  227. package/dist/mcp/handlers/base-handler.d.ts +72 -0
  228. package/dist/mcp/handlers/base-handler.d.ts.map +1 -0
  229. package/dist/mcp/handlers/base-handler.js +86 -0
  230. package/dist/mcp/handlers/base-handler.js.map +1 -0
  231. package/dist/mcp/handlers/compare-sources.d.ts +91 -0
  232. package/dist/mcp/handlers/compare-sources.d.ts.map +1 -0
  233. package/dist/mcp/handlers/compare-sources.js +182 -0
  234. package/dist/mcp/handlers/compare-sources.js.map +1 -0
  235. package/dist/mcp/handlers/export-results.d.ts +53 -0
  236. package/dist/mcp/handlers/export-results.d.ts.map +1 -0
  237. package/dist/mcp/handlers/export-results.js +132 -0
  238. package/dist/mcp/handlers/export-results.js.map +1 -0
  239. package/dist/mcp/handlers/export-to-postman.d.ts +65 -0
  240. package/dist/mcp/handlers/export-to-postman.d.ts.map +1 -0
  241. package/dist/mcp/handlers/export-to-postman.js +128 -0
  242. package/dist/mcp/handlers/export-to-postman.js.map +1 -0
  243. package/dist/mcp/handlers/generate-tests.d.ts +74 -0
  244. package/dist/mcp/handlers/generate-tests.d.ts.map +1 -0
  245. package/dist/mcp/handlers/generate-tests.js +519 -0
  246. package/dist/mcp/handlers/generate-tests.js.map +1 -0
  247. package/dist/mcp/handlers/index.d.ts +13 -0
  248. package/dist/mcp/handlers/index.d.ts.map +1 -0
  249. package/dist/mcp/handlers/index.js +12 -0
  250. package/dist/mcp/handlers/index.js.map +1 -0
  251. package/dist/mcp/handlers/run-tests.d.ts +89 -0
  252. package/dist/mcp/handlers/run-tests.d.ts.map +1 -0
  253. package/dist/mcp/handlers/run-tests.js +233 -0
  254. package/dist/mcp/handlers/run-tests.js.map +1 -0
  255. package/dist/mcp/handlers/types.d.ts +61 -0
  256. package/dist/mcp/handlers/types.d.ts.map +1 -0
  257. package/dist/mcp/handlers/types.js +9 -0
  258. package/dist/mcp/handlers/types.js.map +1 -0
  259. package/dist/mcp/server.d.ts +64 -0
  260. package/dist/mcp/server.d.ts.map +1 -0
  261. package/dist/mcp/server.js +200 -0
  262. package/dist/mcp/server.js.map +1 -0
  263. package/dist/mcp/services/file-service.d.ts +66 -0
  264. package/dist/mcp/services/file-service.d.ts.map +1 -0
  265. package/dist/mcp/services/file-service.js +143 -0
  266. package/dist/mcp/services/file-service.js.map +1 -0
  267. package/dist/mcp/services/llm-service.d.ts +70 -0
  268. package/dist/mcp/services/llm-service.d.ts.map +1 -0
  269. package/dist/mcp/services/llm-service.js +189 -0
  270. package/dist/mcp/services/llm-service.js.map +1 -0
  271. package/dist/mcp/services/postman-service.d.ts +128 -0
  272. package/dist/mcp/services/postman-service.d.ts.map +1 -0
  273. package/dist/mcp/services/postman-service.js +266 -0
  274. package/dist/mcp/services/postman-service.js.map +1 -0
  275. package/dist/mcp/services/report-service.d.ts +81 -0
  276. package/dist/mcp/services/report-service.d.ts.map +1 -0
  277. package/dist/mcp/services/report-service.js +210 -0
  278. package/dist/mcp/services/report-service.js.map +1 -0
  279. package/dist/mcp/services/spec-service.d.ts +58 -0
  280. package/dist/mcp/services/spec-service.d.ts.map +1 -0
  281. package/dist/mcp/services/spec-service.js +140 -0
  282. package/dist/mcp/services/spec-service.js.map +1 -0
  283. package/dist/parsers/endpoint-extractor.d.ts +32 -0
  284. package/dist/parsers/endpoint-extractor.d.ts.map +1 -0
  285. package/dist/parsers/endpoint-extractor.js +160 -0
  286. package/dist/parsers/endpoint-extractor.js.map +1 -0
  287. package/dist/parsers/openapi-parser.d.ts +120 -0
  288. package/dist/parsers/openapi-parser.d.ts.map +1 -0
  289. package/dist/parsers/openapi-parser.js +257 -0
  290. package/dist/parsers/openapi-parser.js.map +1 -0
  291. package/dist/parsers/visitors/auth-visitor.d.ts +28 -0
  292. package/dist/parsers/visitors/auth-visitor.d.ts.map +1 -0
  293. package/dist/parsers/visitors/auth-visitor.js +116 -0
  294. package/dist/parsers/visitors/auth-visitor.js.map +1 -0
  295. package/dist/prd/index.d.ts +10 -0
  296. package/dist/prd/index.d.ts.map +1 -0
  297. package/dist/prd/index.js +10 -0
  298. package/dist/prd/index.js.map +1 -0
  299. package/dist/prd/prd-reader.d.ts +124 -0
  300. package/dist/prd/prd-reader.d.ts.map +1 -0
  301. package/dist/prd/prd-reader.js +308 -0
  302. package/dist/prd/prd-reader.js.map +1 -0
  303. package/dist/prd/prd-storage.d.ts +232 -0
  304. package/dist/prd/prd-storage.d.ts.map +1 -0
  305. package/dist/prd/prd-storage.js +129 -0
  306. package/dist/prd/prd-storage.js.map +1 -0
  307. package/dist/repairers/test-auto-repairer.d.ts +61 -0
  308. package/dist/repairers/test-auto-repairer.d.ts.map +1 -0
  309. package/dist/repairers/test-auto-repairer.js +213 -0
  310. package/dist/repairers/test-auto-repairer.js.map +1 -0
  311. package/dist/reporters/comparison-report-generator.d.ts +58 -0
  312. package/dist/reporters/comparison-report-generator.d.ts.map +1 -0
  313. package/dist/reporters/comparison-report-generator.js +369 -0
  314. package/dist/reporters/comparison-report-generator.js.map +1 -0
  315. package/dist/reporters/gherkin-formatter.d.ts +34 -0
  316. package/dist/reporters/gherkin-formatter.d.ts.map +1 -0
  317. package/dist/reporters/gherkin-formatter.js +231 -0
  318. package/dist/reporters/gherkin-formatter.js.map +1 -0
  319. package/dist/reporters/html-report-generator.d.ts +174 -0
  320. package/dist/reporters/html-report-generator.d.ts.map +1 -0
  321. package/dist/reporters/html-report-generator.js +194 -0
  322. package/dist/reporters/html-report-generator.js.map +1 -0
  323. package/dist/reporters/report-charts.d.ts +23 -0
  324. package/dist/reporters/report-charts.d.ts.map +1 -0
  325. package/dist/reporters/report-charts.js +182 -0
  326. package/dist/reporters/report-charts.js.map +1 -0
  327. package/dist/reporters/report-sections.d.ts +34 -0
  328. package/dist/reporters/report-sections.d.ts.map +1 -0
  329. package/dist/reporters/report-sections.js +481 -0
  330. package/dist/reporters/report-sections.js.map +1 -0
  331. package/dist/reporters/report-styles.d.ts +12 -0
  332. package/dist/reporters/report-styles.d.ts.map +1 -0
  333. package/dist/reporters/report-styles.js +412 -0
  334. package/dist/reporters/report-styles.js.map +1 -0
  335. package/dist/reporters/report-test-details.d.ts +56 -0
  336. package/dist/reporters/report-test-details.d.ts.map +1 -0
  337. package/dist/reporters/report-test-details.js +328 -0
  338. package/dist/reporters/report-test-details.js.map +1 -0
  339. package/dist/reporters/report-utils.d.ts +40 -0
  340. package/dist/reporters/report-utils.d.ts.map +1 -0
  341. package/dist/reporters/report-utils.js +163 -0
  342. package/dist/reporters/report-utils.js.map +1 -0
  343. package/dist/types/ai-config.d.ts +63 -0
  344. package/dist/types/ai-config.d.ts.map +1 -0
  345. package/dist/types/ai-config.js +79 -0
  346. package/dist/types/ai-config.js.map +1 -0
  347. package/dist/types/business-rules.d.ts +235 -0
  348. package/dist/types/business-rules.d.ts.map +1 -0
  349. package/dist/types/business-rules.js +6 -0
  350. package/dist/types/business-rules.js.map +1 -0
  351. package/dist/types/config.d.ts +106 -0
  352. package/dist/types/config.d.ts.map +1 -0
  353. package/dist/types/config.js +6 -0
  354. package/dist/types/config.js.map +1 -0
  355. package/dist/types/core.d.ts +72 -0
  356. package/dist/types/core.d.ts.map +1 -0
  357. package/dist/types/core.js +6 -0
  358. package/dist/types/core.js.map +1 -0
  359. package/dist/types/index.d.ts +17 -0
  360. package/dist/types/index.d.ts.map +1 -0
  361. package/dist/types/index.js +10 -0
  362. package/dist/types/index.js.map +1 -0
  363. package/dist/types/openapi.d.ts +139 -0
  364. package/dist/types/openapi.d.ts.map +1 -0
  365. package/dist/types/openapi.js +6 -0
  366. package/dist/types/openapi.js.map +1 -0
  367. package/dist/types/pact.d.ts +101 -0
  368. package/dist/types/pact.d.ts.map +1 -0
  369. package/dist/types/pact.js +6 -0
  370. package/dist/types/pact.js.map +1 -0
  371. package/dist/types/reporting.d.ts +93 -0
  372. package/dist/types/reporting.d.ts.map +1 -0
  373. package/dist/types/reporting.js +6 -0
  374. package/dist/types/reporting.js.map +1 -0
  375. package/dist/types/test-case.d.ts +233 -0
  376. package/dist/types/test-case.d.ts.map +1 -0
  377. package/dist/types/test-case.js +6 -0
  378. package/dist/types/test-case.js.map +1 -0
  379. package/dist/types/test-execution.d.ts +80 -0
  380. package/dist/types/test-execution.d.ts.map +1 -0
  381. package/dist/types/test-execution.js +6 -0
  382. package/dist/types/test-execution.js.map +1 -0
  383. package/dist/utils/auth-generator.d.ts +30 -0
  384. package/dist/utils/auth-generator.d.ts.map +1 -0
  385. package/dist/utils/auth-generator.js +68 -0
  386. package/dist/utils/auth-generator.js.map +1 -0
  387. package/dist/utils/config.d.ts +181 -0
  388. package/dist/utils/config.d.ts.map +1 -0
  389. package/dist/utils/config.js +141 -0
  390. package/dist/utils/config.js.map +1 -0
  391. package/dist/utils/coverage-calculator.d.ts +81 -0
  392. package/dist/utils/coverage-calculator.d.ts.map +1 -0
  393. package/dist/utils/coverage-calculator.js +134 -0
  394. package/dist/utils/coverage-calculator.js.map +1 -0
  395. package/dist/utils/data-loader.d.ts +52 -0
  396. package/dist/utils/data-loader.d.ts.map +1 -0
  397. package/dist/utils/data-loader.js +192 -0
  398. package/dist/utils/data-loader.js.map +1 -0
  399. package/dist/utils/errors.d.ts +167 -0
  400. package/dist/utils/errors.d.ts.map +1 -0
  401. package/dist/utils/errors.js +257 -0
  402. package/dist/utils/errors.js.map +1 -0
  403. package/dist/utils/logger.d.ts +220 -0
  404. package/dist/utils/logger.d.ts.map +1 -0
  405. package/dist/utils/logger.js +325 -0
  406. package/dist/utils/logger.js.map +1 -0
  407. package/dist/utils/openapi-discovery.d.ts +31 -0
  408. package/dist/utils/openapi-discovery.d.ts.map +1 -0
  409. package/dist/utils/openapi-discovery.js +322 -0
  410. package/dist/utils/openapi-discovery.js.map +1 -0
  411. package/dist/utils/path-resolver.d.ts +101 -0
  412. package/dist/utils/path-resolver.d.ts.map +1 -0
  413. package/dist/utils/path-resolver.js +167 -0
  414. package/dist/utils/path-resolver.js.map +1 -0
  415. package/dist/utils/resilience.d.ts +181 -0
  416. package/dist/utils/resilience.d.ts.map +1 -0
  417. package/dist/utils/resilience.js +269 -0
  418. package/dist/utils/resilience.js.map +1 -0
  419. package/dist/validators/openapi-validator.d.ts +198 -0
  420. package/dist/validators/openapi-validator.d.ts.map +1 -0
  421. package/dist/validators/openapi-validator.js +349 -0
  422. package/dist/validators/openapi-validator.js.map +1 -0
  423. package/dist/validators/response-matcher.d.ts +84 -0
  424. package/dist/validators/response-matcher.d.ts.map +1 -0
  425. package/dist/validators/response-matcher.js +234 -0
  426. package/dist/validators/response-matcher.js.map +1 -0
  427. package/dist/validators/schema-validator.d.ts +174 -0
  428. package/dist/validators/schema-validator.d.ts.map +1 -0
  429. package/dist/validators/schema-validator.js +340 -0
  430. package/dist/validators/schema-validator.js.map +1 -0
  431. package/package.json +76 -0
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Response Handler
3
+ *
4
+ * Pure functions that operate on a completed HTTP response:
5
+ * - path-based value extraction (dataFlow)
6
+ * - agnostic token auto-detection
7
+ * - dataFlow value extraction
8
+ * - response validation (schema or matcher-based)
9
+ *
10
+ * @module executor/response-handler
11
+ */
12
+ import { validateResponse } from '../validators/openapi-validator.js';
13
+ import { validateResponse as validateResponseMatchers } from '../validators/response-matcher.js';
14
+ import { findTokenInResponse } from './token-detector/index.js';
15
+ import { createLogger } from '../utils/logger.js';
16
+ const log = createLogger('response-handler');
17
+ /**
18
+ * Extracts a value from a response object using a dot-notation path.
19
+ * Path must start with "response" (e.g. "response.body.access_token").
20
+ *
21
+ * @param response - The HTTP response object
22
+ * @param path - Dot-notation path starting with "response"
23
+ * @returns The extracted value, or undefined if not found
24
+ */
25
+ export function extractValueFromPath(response, path) {
26
+ const parts = path.split('.');
27
+ if (parts[0] !== 'response') {
28
+ log.warn('DataFlow extract path must start with "response"', { path });
29
+ return undefined;
30
+ }
31
+ let current = response;
32
+ for (let i = 1; i < parts.length; i++) {
33
+ if (current === null || current === undefined || typeof current !== 'object') {
34
+ return undefined;
35
+ }
36
+ current = current[parts[i]];
37
+ }
38
+ return current;
39
+ }
40
+ /**
41
+ * Attempts to auto-detect an auth token in a successful response.
42
+ * Returns the token value if found, or null if the response is not a
43
+ * successful auth response or no token is detected.
44
+ *
45
+ * @param response - The HTTP response
46
+ * @param testCase - The test case that produced the response
47
+ * @param currentToken - Current auto-detected token (null if none yet)
48
+ * @returns Detected token string, or null if nothing new was found
49
+ */
50
+ export function handleTokenDetection(response, testCase, currentToken) {
51
+ if (currentToken !== null ||
52
+ response.status < 200 ||
53
+ response.status >= 300 ||
54
+ !response.body ||
55
+ typeof response.body !== 'object') {
56
+ return null;
57
+ }
58
+ const detected = findTokenInResponse(response.body, testCase.tokenField);
59
+ if (!detected)
60
+ return null;
61
+ log.info('Auto-detected authentication token (will use for all subsequent requests)', {
62
+ endpoint: `${testCase.method} ${testCase.path}`,
63
+ tokenField: detected.field,
64
+ tokenPath: detected.path,
65
+ method: detected.method,
66
+ tokenPreview: `${detected.value.substring(0, 20)}...`,
67
+ });
68
+ return detected.value;
69
+ }
70
+ /**
71
+ * Extracts dataFlow values from a successful response and returns them
72
+ * as a plain object to be merged into the shared data context.
73
+ *
74
+ * @param response - The HTTP response
75
+ * @param testDataFlow - DataFlow config entry for this test
76
+ * @param testId - Test ID (for logging)
77
+ * @returns Object with extracted key-value pairs (may be empty)
78
+ */
79
+ export function extractDataFlowValues(response, testDataFlow, testId) {
80
+ const extracted = {};
81
+ if (!testDataFlow?.extract || response.status < 200 || response.status >= 300) {
82
+ return extracted;
83
+ }
84
+ for (const [varName, extractPath] of Object.entries(testDataFlow.extract)) {
85
+ const value = extractValueFromPath(response, extractPath);
86
+ if (value !== undefined) {
87
+ extracted[varName] = value;
88
+ log.debug('DataFlow extract: saved to context', {
89
+ varName,
90
+ extractPath,
91
+ testId,
92
+ valuePreview: typeof value === 'string'
93
+ ? value.substring(0, 30) + '...'
94
+ : JSON.stringify(value).substring(0, 30),
95
+ });
96
+ }
97
+ else {
98
+ log.debug('DataFlow extract: value not found', { varName, extractPath, testId });
99
+ }
100
+ }
101
+ return extracted;
102
+ }
103
+ /**
104
+ * Validates the response against the endpoint schema or configured matchers.
105
+ *
106
+ * @param response - The HTTP response
107
+ * @param endpoint - Parsed endpoint definition (may be undefined)
108
+ * @param testCase - The test case
109
+ * @param validateSchemas - Whether schema validation is enabled
110
+ * @param useMatchers - Whether matcher-based validation is enabled
111
+ * @param matchers - Matcher configuration keyed by test ID or "*"
112
+ * @returns Array of schema errors (empty if valid)
113
+ */
114
+ export function validateTestResponse(response, endpoint, testCase, validateSchemas, useMatchers, matchers) {
115
+ if (useMatchers && matchers) {
116
+ const testMatchers = matchers[testCase.id] || matchers['*'];
117
+ if (testMatchers) {
118
+ const validation = validateResponseMatchers({ body: response.body, headers: response.headers }, testMatchers);
119
+ if (!validation.valid) {
120
+ return validation.errors.map(err => ({
121
+ field: err.split('"')[1] || 'unknown',
122
+ message: err,
123
+ }));
124
+ }
125
+ }
126
+ return [];
127
+ }
128
+ if (validateSchemas && endpoint && testCase.validateSchema !== false) {
129
+ const validation = validateResponse({ status: response.status, headers: response.headers ?? {}, body: response.body }, endpoint, testCase.expectedStatus);
130
+ if (!validation.valid)
131
+ return validation.errors;
132
+ }
133
+ return [];
134
+ }
135
+ //# sourceMappingURL=response-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-handler.js","sourceRoot":"","sources":["../../src/executor/response-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Result Processor
3
+ *
4
+ * Standalone functions for generating a TestSuiteSummary from results and
5
+ * persisting the results+summary to disk.
6
+ *
7
+ * @module executor/result-processor
8
+ */
9
+ import type { TestResult, TestSuiteSummary } from '../types/index.js';
10
+ /**
11
+ * Generates a summary from an array of test results.
12
+ *
13
+ * @param results - Array of test results
14
+ * @returns Aggregated test suite summary
15
+ */
16
+ export declare function generateSummary(results: TestResult[]): TestSuiteSummary;
17
+ /**
18
+ * Saves test results and summary to a JSON file in the test-results directory.
19
+ *
20
+ * @param results - Array of test results
21
+ * @param summary - Generated test suite summary
22
+ * @param workingDirectory - Base directory for test-results folder
23
+ * @param environmentName - Name of the environment (for the JSON payload)
24
+ * @returns Path to the saved file, or empty string on failure
25
+ */
26
+ export declare function saveResults(results: TestResult[], summary: TestSuiteSummary, workingDirectory: string, environmentName: string): Promise<string>;
27
+ //# sourceMappingURL=result-processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result-processor.d.ts","sourceRoot":"","sources":["../../src/executor/result-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAOtE;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,gBAAgB,CAsDvE;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,gBAAgB,EACzB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,MAAM,CAAC,CAqEjB"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Result Processor
3
+ *
4
+ * Standalone functions for generating a TestSuiteSummary from results and
5
+ * persisting the results+summary to disk.
6
+ *
7
+ * @module executor/result-processor
8
+ */
9
+ import { createLogger } from '../utils/logger.js';
10
+ import { promises as fs } from 'fs';
11
+ import { join } from 'path';
12
+ const log = createLogger('result-processor');
13
+ /**
14
+ * Generates a summary from an array of test results.
15
+ *
16
+ * @param results - Array of test results
17
+ * @returns Aggregated test suite summary
18
+ */
19
+ export function generateSummary(results) {
20
+ const passed = results.filter(r => r.status === 'passed').length;
21
+ const failed = results.filter(r => r.status === 'failed').length;
22
+ const skipped = results.filter(r => r.status === 'skipped').length;
23
+ const totalResponseTime = results.reduce((sum, r) => sum + (r.responseTime || 0), 0);
24
+ const avgResponseTime = results.length > 0 ? totalResponseTime / results.length : 0;
25
+ const startTime = results.length > 0
26
+ ? new Date(Math.min(...results.map(r => r.startTime.getTime())))
27
+ : new Date();
28
+ const endTime = results.length > 0 && results.every(r => r.endTime)
29
+ ? new Date(Math.max(...results.map(r => r.endTime.getTime())))
30
+ : new Date();
31
+ const duration = endTime.getTime() - startTime.getTime();
32
+ const byCategory = {};
33
+ const byEndpoint = {};
34
+ for (const result of results) {
35
+ const category = result.testCase.category;
36
+ const endpoint = `${result.testCase.method} ${result.testCase.path}`;
37
+ if (!byCategory[category]) {
38
+ byCategory[category] = { passed: 0, failed: 0, total: 0 };
39
+ }
40
+ byCategory[category].total++;
41
+ if (result.status === 'passed')
42
+ byCategory[category].passed++;
43
+ else if (result.status === 'failed')
44
+ byCategory[category].failed++;
45
+ if (!byEndpoint[endpoint]) {
46
+ byEndpoint[endpoint] = { passed: 0, failed: 0, total: 0 };
47
+ }
48
+ byEndpoint[endpoint].total++;
49
+ if (result.status === 'passed')
50
+ byEndpoint[endpoint].passed++;
51
+ else if (result.status === 'failed')
52
+ byEndpoint[endpoint].failed++;
53
+ }
54
+ return {
55
+ total: results.length,
56
+ passed,
57
+ failed,
58
+ skipped,
59
+ duration,
60
+ avgResponseTime,
61
+ startTime,
62
+ endTime,
63
+ byCategory,
64
+ byEndpoint,
65
+ };
66
+ }
67
+ /**
68
+ * Saves test results and summary to a JSON file in the test-results directory.
69
+ *
70
+ * @param results - Array of test results
71
+ * @param summary - Generated test suite summary
72
+ * @param workingDirectory - Base directory for test-results folder
73
+ * @param environmentName - Name of the environment (for the JSON payload)
74
+ * @returns Path to the saved file, or empty string on failure
75
+ */
76
+ export async function saveResults(results, summary, workingDirectory, environmentName) {
77
+ try {
78
+ const resultsDir = join(workingDirectory, 'test-results');
79
+ await fs.mkdir(resultsDir, { recursive: true });
80
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
81
+ const filename = `test-results-${timestamp}.json`;
82
+ const filepath = join(resultsDir, filename);
83
+ const allTests = results.map(r => ({
84
+ id: r.testCase.id,
85
+ name: r.testCase.name,
86
+ category: r.testCase.category,
87
+ status: r.status,
88
+ method: r.testCase.method,
89
+ path: r.testCase.path,
90
+ endpoint: `${r.testCase.method} ${r.testCase.path}`,
91
+ expectedStatus: r.testCase.expectedStatus,
92
+ actualStatus: r.actualStatus,
93
+ duration: r.responseTime,
94
+ error: r.error,
95
+ schemaErrors: r.schemaErrors,
96
+ }));
97
+ const failedTests = results
98
+ .filter(r => r.status === 'failed')
99
+ .map(r => ({
100
+ name: r.testCase.name,
101
+ error: r.error,
102
+ expectedStatus: r.testCase.expectedStatus,
103
+ actualStatus: r.actualStatus,
104
+ }));
105
+ const data = {
106
+ environment: environmentName,
107
+ timestamp: new Date().toISOString(),
108
+ summary: {
109
+ total: summary.total,
110
+ passed: summary.passed,
111
+ failed: summary.failed,
112
+ skipped: summary.skipped,
113
+ duration: summary.duration,
114
+ avgResponseTime: summary.avgResponseTime,
115
+ passRate: summary.total > 0
116
+ ? `${((summary.passed / summary.total) * 100).toFixed(2)}%`
117
+ : '0.00%',
118
+ },
119
+ byCategory: summary.byCategory,
120
+ byEndpoint: summary.byEndpoint,
121
+ allTests,
122
+ failedTests,
123
+ };
124
+ await fs.writeFile(filepath, JSON.stringify(data, null, 2), 'utf-8');
125
+ log.info('Test results saved', {
126
+ filepath,
127
+ totalTests: results.length,
128
+ passed: summary.passed,
129
+ failed: summary.failed,
130
+ });
131
+ return filepath;
132
+ }
133
+ catch (error) {
134
+ log.warn('Failed to save test results', {
135
+ error: error instanceof Error ? error.message : String(error),
136
+ });
137
+ return '';
138
+ }
139
+ }
140
+ //# sourceMappingURL=result-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result-processor.js","sourceRoot":"","sources":["../../src/executor/result-processor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Test Result Utilities
3
+ *
4
+ * Helper functions for filtering and analyzing test results.
5
+ *
6
+ * @module executor/result-utils
7
+ */
8
+ import type { TestResult, TestCase } from '../types/index.js';
9
+ /**
10
+ * Filters test results by status
11
+ */
12
+ export declare function filterResultsByStatus(results: TestResult[], status: TestResult['status']): TestResult[];
13
+ /**
14
+ * Filters test results by category
15
+ */
16
+ export declare function filterResultsByCategory(results: TestResult[], category: TestCase['category']): TestResult[];
17
+ /**
18
+ * Gets the slowest test results sorted by response time
19
+ */
20
+ export declare function getSlowestTests(results: TestResult[], count?: number): TestResult[];
21
+ //# sourceMappingURL=result-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result-utils.d.ts","sourceRoot":"","sources":["../../src/executor/result-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE9D;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,UAAU,EAAE,EACrB,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,GAC3B,UAAU,EAAE,CAEd;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,UAAU,EAAE,EACrB,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,GAC7B,UAAU,EAAE,CAEd;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK,SAAK,GAAG,UAAU,EAAE,CAK/E"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Test Result Utilities
3
+ *
4
+ * Helper functions for filtering and analyzing test results.
5
+ *
6
+ * @module executor/result-utils
7
+ */
8
+ /**
9
+ * Filters test results by status
10
+ */
11
+ export function filterResultsByStatus(results, status) {
12
+ return results.filter(r => r.status === status);
13
+ }
14
+ /**
15
+ * Filters test results by category
16
+ */
17
+ export function filterResultsByCategory(results, category) {
18
+ return results.filter(r => r.testCase.category === category);
19
+ }
20
+ /**
21
+ * Gets the slowest test results sorted by response time
22
+ */
23
+ export function getSlowestTests(results, count = 10) {
24
+ return results
25
+ .filter(r => r.responseTime !== undefined)
26
+ .sort((a, b) => (b.responseTime || 0) - (a.responseTime || 0))
27
+ .slice(0, count);
28
+ }
29
+ //# sourceMappingURL=result-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result-utils.js","sourceRoot":"","sources":["../../src/executor/result-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAqB,EACrB,MAA4B;IAE5B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAqB,EACrB,QAA8B;IAE9B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;AAC/D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,OAAqB,EAAE,KAAK,GAAG,EAAE;IAC/D,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,SAAS,CAAC;SACzC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC;SAC7D,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACrB,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Test Executor
3
+ *
4
+ * Standalone function that executes a single test case end-to-end:
5
+ * lifecycle hooks → dataFlow injection → HTTP request → token detection
6
+ * → dataFlow extraction → response validation → result construction.
7
+ *
8
+ * Chain of Responsibility pattern: inject → execute → validate → extract.
9
+ *
10
+ * @module executor/test-executor
11
+ */
12
+ import type { TestCase, TestResult, ParsedEndpoint } from '../types/index.js';
13
+ import type { HttpClient } from './http-client.js';
14
+ export interface ExecutionContext {
15
+ autoDetectedToken: string | null;
16
+ dataContext: Record<string, unknown>;
17
+ }
18
+ export interface ExecutionOptions {
19
+ validateSchemas: boolean;
20
+ dataFlow?: Record<string, {
21
+ extract?: Record<string, string>;
22
+ inject?: Record<string, string>;
23
+ }>;
24
+ useMatchers?: boolean;
25
+ matchers?: Record<string, Record<string, import('../types/index.js').ResponseMatcher>>;
26
+ beforeTest?: (testCase: TestCase) => Promise<void> | void;
27
+ afterTest?: (testCase: TestCase) => Promise<void> | void;
28
+ environment?: {
29
+ auth?: import('../types/index.js').Environment['auth'];
30
+ };
31
+ }
32
+ export interface ExecutionResult {
33
+ testResult: TestResult;
34
+ detectedToken: string | null;
35
+ extractedData: Record<string, unknown>;
36
+ }
37
+ /**
38
+ * Executes a single test case and returns the result plus any mutations to
39
+ * shared context (detected token, extracted dataFlow values).
40
+ *
41
+ * @param testCase - Test case to execute
42
+ * @param client - Initialized HTTP client
43
+ * @param context - Shared mutable execution context (token + dataContext)
44
+ * @param endpointMap - Map of endpoint definitions for schema validation
45
+ * @param options - Execution options (validation, dataFlow, hooks, etc.)
46
+ * @returns Execution result with test result and context mutations
47
+ */
48
+ export declare function executeSingleTest(testCase: TestCase, client: HttpClient, context: ExecutionContext, endpointMap: Map<string, ParsedEndpoint>, options: ExecutionOptions): Promise<ExecutionResult>;
49
+ //# sourceMappingURL=test-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-executor.d.ts","sourceRoot":"","sources":["../../src/executor/test-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAUnD,MAAM,WAAW,gBAAgB;IAC/B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,CAAC;IACjG,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,mBAAmB,EAAE,eAAe,CAAC,CAAC,CAAC;IACvF,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACzD,WAAW,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC;CAC1E;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAkHD;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,gBAAgB,EACzB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,EACxC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAiI1B"}
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Test Executor
3
+ *
4
+ * Standalone function that executes a single test case end-to-end:
5
+ * lifecycle hooks → dataFlow injection → HTTP request → token detection
6
+ * → dataFlow extraction → response validation → result construction.
7
+ *
8
+ * Chain of Responsibility pattern: inject → execute → validate → extract.
9
+ *
10
+ * @module executor/test-executor
11
+ */
12
+ import { createLogger } from '../utils/logger.js';
13
+ import { handleTokenDetection, extractDataFlowValues, validateTestResponse, } from './response-handler.js';
14
+ const log = createLogger('test-executor');
15
+ /**
16
+ * Applies dataFlow injection rules, mutating the provided header/body/path refs.
17
+ * Returns the potentially updated path so callers can use it for the HTTP request.
18
+ */
19
+ function applyDataFlowInject(testDataFlow, dataContext, testCase, requestHeaders, requestBody, requestPath) {
20
+ if (!testDataFlow?.inject || testCase.skipDataFlow === true) {
21
+ return { path: requestPath, body: requestBody };
22
+ }
23
+ let path = requestPath;
24
+ let body = requestBody;
25
+ for (const [varName, injectSpec] of Object.entries(testDataFlow.inject)) {
26
+ const value = dataContext[varName];
27
+ if (value === undefined) {
28
+ log.debug('DataFlow inject: variable not found in context', { varName, testId: testCase.id });
29
+ continue;
30
+ }
31
+ if (injectSpec.startsWith('header.')) {
32
+ const headerPart = injectSpec.substring(7);
33
+ const colonIdx = headerPart.indexOf(':');
34
+ if (colonIdx > 0) {
35
+ const headerName = headerPart.substring(0, colonIdx);
36
+ const format = headerPart.substring(colonIdx + 1);
37
+ requestHeaders[headerName] = format.replace('{value}', String(value));
38
+ log.debug('DataFlow inject: header', { headerName, varName, testId: testCase.id });
39
+ }
40
+ }
41
+ else if (injectSpec.startsWith('body.')) {
42
+ const fieldName = injectSpec.substring(5);
43
+ if (!body || typeof body !== 'object')
44
+ body = {};
45
+ body[fieldName] = value;
46
+ log.debug('DataFlow inject: body field', { fieldName, varName, testId: testCase.id });
47
+ }
48
+ else if (injectSpec.startsWith('path:')) {
49
+ const pathTemplate = injectSpec.substring(5);
50
+ path = pathTemplate.replace('{value}', String(value));
51
+ log.debug('DataFlow inject: path', { requestPath: path, varName, testId: testCase.id });
52
+ }
53
+ }
54
+ return { path, body };
55
+ }
56
+ /**
57
+ * Applies token injection rules to request headers based on priority:
58
+ * 1. Existing explicit token (already present in headers)
59
+ * 2. Placeholder replacement ({{TOKEN}} etc.)
60
+ * 3. No-header injection from env or auto-detected token
61
+ */
62
+ function applyTokenInjection(testCase, requestHeaders, context, auth) {
63
+ if (!testCase.requiresAuth || testCase.category === 'error-case')
64
+ return;
65
+ const envToken = auth?.type === 'bearer' ? auth.token : undefined;
66
+ if (requestHeaders['Authorization']) {
67
+ const authHeader = requestHeaders['Authorization'];
68
+ const isPlaceholder = authHeader.includes('{{TOKEN}}') ||
69
+ authHeader.includes('{{OAUTH_TOKEN}}') ||
70
+ authHeader.includes('{{OIDC_TOKEN}}');
71
+ if (isPlaceholder) {
72
+ if (envToken) {
73
+ requestHeaders['Authorization'] = `Bearer ${envToken}`;
74
+ log.info('Replaced placeholder with environment token', { path: testCase.path });
75
+ }
76
+ else if (context.autoDetectedToken) {
77
+ requestHeaders['Authorization'] = `Bearer ${context.autoDetectedToken}`;
78
+ log.info('Replaced placeholder with auto-detected token', {
79
+ path: testCase.path,
80
+ method: testCase.method,
81
+ tokenPreview: context.autoDetectedToken.substring(0, 20) + '...',
82
+ });
83
+ }
84
+ else {
85
+ log.warn('No token available to replace placeholder', {
86
+ path: testCase.path,
87
+ method: testCase.method,
88
+ placeholder: authHeader,
89
+ });
90
+ }
91
+ }
92
+ }
93
+ else {
94
+ if (envToken) {
95
+ requestHeaders['Authorization'] = `Bearer ${envToken}`;
96
+ log.info('Injected environment token', { path: testCase.path });
97
+ }
98
+ else if (context.autoDetectedToken) {
99
+ requestHeaders['Authorization'] = `Bearer ${context.autoDetectedToken}`;
100
+ log.info('Injected auto-detected token', {
101
+ path: testCase.path,
102
+ method: testCase.method,
103
+ tokenPreview: context.autoDetectedToken.substring(0, 20) + '...',
104
+ });
105
+ }
106
+ else {
107
+ log.warn('No token available for authenticated endpoint', {
108
+ path: testCase.path,
109
+ method: testCase.method,
110
+ });
111
+ }
112
+ }
113
+ }
114
+ /**
115
+ * Executes a single test case and returns the result plus any mutations to
116
+ * shared context (detected token, extracted dataFlow values).
117
+ *
118
+ * @param testCase - Test case to execute
119
+ * @param client - Initialized HTTP client
120
+ * @param context - Shared mutable execution context (token + dataContext)
121
+ * @param endpointMap - Map of endpoint definitions for schema validation
122
+ * @param options - Execution options (validation, dataFlow, hooks, etc.)
123
+ * @returns Execution result with test result and context mutations
124
+ */
125
+ export async function executeSingleTest(testCase, client, context, endpointMap, options) {
126
+ const startTime = new Date();
127
+ try {
128
+ // Lifecycle hook: before
129
+ if (options.beforeTest) {
130
+ log.debug('Executing beforeTest hook', { testId: testCase.id });
131
+ await options.beforeTest(testCase);
132
+ }
133
+ // Prepare mutable request properties
134
+ const requestHeaders = { ...testCase.headers };
135
+ const testDataFlow = options.dataFlow?.[testCase.id];
136
+ // DataFlow injection
137
+ const { path: requestPath, body: requestBody } = applyDataFlowInject(testDataFlow, context.dataContext, testCase, requestHeaders, testCase.body, testCase.path);
138
+ // Token injection
139
+ applyTokenInjection(testCase, requestHeaders, context, options.environment?.auth);
140
+ // Execute HTTP request
141
+ const response = await client.request(testCase.method, requestPath, {
142
+ body: requestBody,
143
+ queryParams: testCase.queryParams,
144
+ pathParams: testCase.pathParams,
145
+ headers: requestHeaders,
146
+ requiresAuth: testCase.requiresAuth,
147
+ contentType: testCase.contentType,
148
+ });
149
+ const endTime = new Date();
150
+ // Token auto-detection
151
+ const detectedToken = handleTokenDetection(response, testCase, context.autoDetectedToken);
152
+ // DataFlow extraction
153
+ const extractedData = extractDataFlowValues(response, testDataFlow, testCase.id);
154
+ // Schema / matcher validation
155
+ const endpoint = endpointMap.get(`${testCase.method}:${testCase.path}`);
156
+ const schemaErrors = validateTestResponse(response, endpoint, testCase, options.validateSchemas, options.useMatchers ?? false, options.matchers);
157
+ // Determine status
158
+ const statusMatches = response.status === testCase.expectedStatus;
159
+ const hasSchemaErrors = schemaErrors.length > 0;
160
+ let status;
161
+ let error;
162
+ if (statusMatches && !hasSchemaErrors) {
163
+ status = 'passed';
164
+ }
165
+ else {
166
+ status = 'failed';
167
+ const errors = [];
168
+ if (!statusMatches) {
169
+ errors.push(`Expected status ${testCase.expectedStatus}, got ${response.status}`);
170
+ }
171
+ if (hasSchemaErrors) {
172
+ errors.push(`Schema validation failed: ${schemaErrors.map(e => `${e.field}: ${e.message}`).join(', ')}`);
173
+ }
174
+ error = errors.join('; ');
175
+ }
176
+ const testResult = {
177
+ testCase,
178
+ status,
179
+ actualStatus: response.status,
180
+ actualBody: response.body,
181
+ actualHeaders: response.headers,
182
+ responseTime: response.responseTime,
183
+ error,
184
+ schemaErrors: hasSchemaErrors
185
+ ? schemaErrors.map(e => ({
186
+ instancePath: `/${e.field}`,
187
+ message: e.message,
188
+ keyword: e.code || 'validation',
189
+ }))
190
+ : undefined,
191
+ startTime,
192
+ endTime,
193
+ };
194
+ // Lifecycle hook: after
195
+ if (options.afterTest) {
196
+ log.debug('Executing afterTest hook', { testId: testCase.id });
197
+ await options.afterTest(testCase);
198
+ }
199
+ return { testResult, detectedToken, extractedData };
200
+ }
201
+ catch (error) {
202
+ const endTime = new Date();
203
+ // afterTest hook even on failure
204
+ if (options.afterTest) {
205
+ try {
206
+ log.debug('Executing afterTest hook (after error)', { testId: testCase.id });
207
+ await options.afterTest(testCase);
208
+ }
209
+ catch (hookError) {
210
+ log.warn('afterTest hook failed', { testId: testCase.id, error: hookError });
211
+ }
212
+ }
213
+ return {
214
+ testResult: {
215
+ testCase,
216
+ status: 'failed',
217
+ error: `Request failed: ${error instanceof Error ? error.message : String(error)}`,
218
+ startTime,
219
+ endTime,
220
+ },
221
+ detectedToken: null,
222
+ extractedData: {},
223
+ };
224
+ }
225
+ }
226
+ //# sourceMappingURL=test-executor.js.map