@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,349 @@
1
+ /**
2
+ * OpenAPI Response Validator
3
+ *
4
+ * Validates API responses against OpenAPI specifications.
5
+ * Checks status codes, headers, content types, and response bodies.
6
+ *
7
+ * @module validators/openapi-validator
8
+ */
9
+ import { validateSchema } from './schema-validator.js';
10
+ /**
11
+ * Validates an API response against OpenAPI specification
12
+ *
13
+ * Checks:
14
+ * - Status code matches expected
15
+ * - Content-Type header is correct
16
+ * - Response body matches schema
17
+ *
18
+ * @param response - Actual API response
19
+ * @param endpoint - Expected endpoint definition
20
+ * @param expectedStatus - Expected status code
21
+ * @returns Validation result with detailed errors
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const response = {
26
+ * status: 200,
27
+ * headers: { 'content-type': 'application/json' },
28
+ * body: { id: 1, name: 'John' }
29
+ * };
30
+ *
31
+ * const result = validateResponse(response, endpoint, 200);
32
+ * if (!result.valid) {
33
+ * console.error('Response validation failed:', result.errors);
34
+ * }
35
+ * ```
36
+ */
37
+ export function validateResponse(response, endpoint, expectedStatus) {
38
+ const errors = [];
39
+ // 1. Validate status code
40
+ if (response.status !== expectedStatus) {
41
+ errors.push({
42
+ field: 'status',
43
+ message: `Expected status ${expectedStatus}, got ${response.status}`,
44
+ code: 'STATUS_MISMATCH',
45
+ });
46
+ }
47
+ // 2. Validate content-type (if response has body)
48
+ // AGNOSTIC: Accept any valid content type, don't force application/json
49
+ // The actual content type validation should be based on what the OpenAPI spec declares
50
+ if (response.body !== null && response.body !== undefined) {
51
+ const contentType = response.headers['content-type'] || response.headers['Content-Type'];
52
+ // Only warn if no content-type header is present (but don't error on non-JSON)
53
+ if (!contentType) {
54
+ errors.push({
55
+ field: 'content-type',
56
+ message: 'Response has body but no Content-Type header',
57
+ code: 'MISSING_CONTENT_TYPE',
58
+ });
59
+ }
60
+ // Note: We no longer reject non-JSON responses - APIs can return XML, text, etc.
61
+ }
62
+ // 3. Validate response body schema
63
+ const responseSchema = endpoint.responses[expectedStatus];
64
+ if (responseSchema && response.body !== null && response.body !== undefined) {
65
+ const schemaValidation = validateSchema(response.body, responseSchema);
66
+ if (!schemaValidation.valid) {
67
+ errors.push(...schemaValidation.errors.map((err) => ({
68
+ ...err,
69
+ field: `body.${err.field}`,
70
+ })));
71
+ }
72
+ }
73
+ return {
74
+ valid: errors.length === 0,
75
+ errors,
76
+ };
77
+ }
78
+ /**
79
+ * Validates that response status code is in the 2xx success range
80
+ *
81
+ * @param status - HTTP status code
82
+ * @returns True if status is successful (200-299)
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * isSuccessStatus(200) // true
87
+ * isSuccessStatus(201) // true
88
+ * isSuccessStatus(204) // true
89
+ * isSuccessStatus(400) // false
90
+ * isSuccessStatus(500) // false
91
+ * ```
92
+ */
93
+ export function isSuccessStatus(status) {
94
+ return status >= 200 && status < 300;
95
+ }
96
+ /**
97
+ * Validates that response status code is in the 4xx client error range
98
+ *
99
+ * @param status - HTTP status code
100
+ * @returns True if status is client error (400-499)
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * isClientError(400) // true
105
+ * isClientError(404) // true
106
+ * isClientError(422) // true
107
+ * isClientError(200) // false
108
+ * isClientError(500) // false
109
+ * ```
110
+ */
111
+ export function isClientError(status) {
112
+ return status >= 400 && status < 500;
113
+ }
114
+ /**
115
+ * Validates that response status code is in the 5xx server error range
116
+ *
117
+ * @param status - HTTP status code
118
+ * @returns True if status is server error (500-599)
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * isServerError(500) // true
123
+ * isServerError(503) // true
124
+ * isServerError(200) // false
125
+ * isServerError(400) // false
126
+ * ```
127
+ */
128
+ export function isServerError(status) {
129
+ return status >= 500 && status < 600;
130
+ }
131
+ /**
132
+ * Gets a human-readable description of an HTTP status code
133
+ *
134
+ * @param status - HTTP status code
135
+ * @returns Description of the status code
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * getStatusDescription(200) // "OK"
140
+ * getStatusDescription(404) // "Not Found"
141
+ * getStatusDescription(500) // "Internal Server Error"
142
+ * ```
143
+ */
144
+ export function getStatusDescription(status) {
145
+ const descriptions = {
146
+ 200: 'OK',
147
+ 201: 'Created',
148
+ 204: 'No Content',
149
+ 400: 'Bad Request',
150
+ 401: 'Unauthorized',
151
+ 403: 'Forbidden',
152
+ 404: 'Not Found',
153
+ 422: 'Unprocessable Entity',
154
+ 500: 'Internal Server Error',
155
+ 502: 'Bad Gateway',
156
+ 503: 'Service Unavailable',
157
+ };
158
+ return descriptions[status] || `HTTP ${status}`;
159
+ }
160
+ /**
161
+ * Validates test result against expected outcome
162
+ *
163
+ * Compares actual test result with expected values and generates
164
+ * detailed validation errors.
165
+ *
166
+ * @param testResult - Actual test execution result
167
+ * @param expectedStatus - Expected HTTP status code
168
+ * @param endpoint - Endpoint definition with response schemas
169
+ * @returns Validation result
170
+ *
171
+ * @example
172
+ * ```typescript
173
+ * const testResult = {
174
+ * id: 'test-1',
175
+ * name: 'POST /users',
176
+ * status: 'passed',
177
+ * actualStatus: 201,
178
+ * response: { id: 1, email: 'user@example.com' }
179
+ * };
180
+ *
181
+ * const result = validateTestResult(testResult, 201, endpoint);
182
+ * if (!result.valid) {
183
+ * console.error('Test result validation failed');
184
+ * }
185
+ * ```
186
+ */
187
+ export function validateTestResult(testResult, expectedStatus, endpoint) {
188
+ const errors = [];
189
+ // Check if test execution succeeded
190
+ if (testResult.status === 'failed' && testResult.error) {
191
+ errors.push({
192
+ field: 'execution',
193
+ message: `Test execution failed: ${testResult.error}`,
194
+ code: 'EXECUTION_FAILED',
195
+ });
196
+ return {
197
+ valid: false,
198
+ errors,
199
+ };
200
+ }
201
+ // Validate status code
202
+ if (testResult.actualStatus !== expectedStatus) {
203
+ errors.push({
204
+ field: 'status',
205
+ message: `Expected status ${expectedStatus}, got ${testResult.actualStatus}`,
206
+ code: 'STATUS_MISMATCH',
207
+ });
208
+ }
209
+ // Validate response schema if available
210
+ if (testResult.actualBody && endpoint.responses[expectedStatus]) {
211
+ const schemaValidation = validateSchema(testResult.actualBody, endpoint.responses[expectedStatus]);
212
+ if (!schemaValidation.valid) {
213
+ errors.push(...schemaValidation.errors.map((err) => ({
214
+ ...err,
215
+ field: `response.${err.field}`,
216
+ })));
217
+ }
218
+ }
219
+ return {
220
+ valid: errors.length === 0,
221
+ errors,
222
+ };
223
+ }
224
+ /**
225
+ * Validates error response format
226
+ *
227
+ * Many APIs follow standard error response formats (RFC 7807, JSON:API, etc.).
228
+ * This function checks if error responses contain expected fields.
229
+ *
230
+ * @param response - Error response body
231
+ * @param expectedFormat - Expected error format
232
+ * @returns Validation result
233
+ *
234
+ * @example
235
+ * ```typescript
236
+ * const errorResponse = {
237
+ * error: 'Bad Request',
238
+ * message: 'Email is required',
239
+ * statusCode: 400
240
+ * };
241
+ *
242
+ * const result = validateErrorResponse(errorResponse, 'standard');
243
+ * ```
244
+ */
245
+ export function validateErrorResponse(response, expectedFormat = 'standard') {
246
+ const errors = [];
247
+ if (typeof response !== 'object' || response === null) {
248
+ errors.push({
249
+ field: 'response',
250
+ message: 'Error response must be an object',
251
+ code: 'INVALID_FORMAT',
252
+ });
253
+ return {
254
+ valid: false,
255
+ errors,
256
+ };
257
+ }
258
+ const errorObj = response;
259
+ switch (expectedFormat) {
260
+ case 'standard':
261
+ // Common format: { error, message, statusCode }
262
+ if (!errorObj.message && !errorObj.error) {
263
+ errors.push({
264
+ field: 'response',
265
+ message: 'Error response should contain "message" or "error" field',
266
+ code: 'MISSING_ERROR_FIELD',
267
+ });
268
+ }
269
+ break;
270
+ case 'rfc7807':
271
+ // RFC 7807 Problem Details: { type, title, status, detail, instance }
272
+ if (!errorObj.type && !errorObj.title) {
273
+ errors.push({
274
+ field: 'response',
275
+ message: 'RFC 7807 error response should contain "type" or "title" field',
276
+ code: 'MISSING_RFC7807_FIELD',
277
+ });
278
+ }
279
+ break;
280
+ case 'jsonapi':
281
+ // JSON:API format: { errors: [{ status, title, detail }] }
282
+ if (!Array.isArray(errorObj.errors)) {
283
+ errors.push({
284
+ field: 'response',
285
+ message: 'JSON:API error response should contain "errors" array',
286
+ code: 'MISSING_JSONAPI_ERRORS',
287
+ });
288
+ }
289
+ break;
290
+ }
291
+ return {
292
+ valid: errors.length === 0,
293
+ errors,
294
+ };
295
+ }
296
+ /**
297
+ * Compares two response bodies for equality
298
+ *
299
+ * Performs deep comparison, useful for contract testing where
300
+ * exact response structure is expected.
301
+ *
302
+ * @param actual - Actual response body
303
+ * @param expected - Expected response body
304
+ * @returns True if responses match
305
+ *
306
+ * @example
307
+ * ```typescript
308
+ * const actual = { id: 1, name: 'John' };
309
+ * const expected = { id: 1, name: 'John' };
310
+ * const matches = compareResponses(actual, expected); // true
311
+ * ```
312
+ */
313
+ export function compareResponses(actual, expected) {
314
+ return JSON.stringify(actual) === JSON.stringify(expected);
315
+ }
316
+ /**
317
+ * Extracts error details from a failed response
318
+ *
319
+ * Attempts to extract meaningful error information from various
320
+ * error response formats.
321
+ *
322
+ * @param response - Error response body
323
+ * @returns Extracted error details
324
+ *
325
+ * @example
326
+ * ```typescript
327
+ * const errorResponse = {
328
+ * error: 'ValidationError',
329
+ * message: 'Email is required',
330
+ * statusCode: 400,
331
+ * details: { field: 'email' }
332
+ * };
333
+ *
334
+ * const details = extractErrorDetails(errorResponse);
335
+ * // { message: 'Email is required', code: 'ValidationError', details: { field: 'email' } }
336
+ * ```
337
+ */
338
+ export function extractErrorDetails(response) {
339
+ if (typeof response !== 'object' || response === null) {
340
+ return { message: String(response) };
341
+ }
342
+ const errorObj = response;
343
+ return {
344
+ message: (errorObj.message || errorObj.error || errorObj.title || errorObj.detail),
345
+ code: (errorObj.error || errorObj.type || errorObj.code),
346
+ details: errorObj.details || errorObj.errors || undefined,
347
+ };
348
+ }
349
+ //# sourceMappingURL=openapi-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-validator.js","sourceRoot":"","sources":["../../src/validators/openapi-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Response Matcher
3
+ *
4
+ * Validates API responses using type-based matchers instead of exact values.
5
+ * Inspired by Pact matchers but implemented without dependencies.
6
+ *
7
+ * @module validators/response-matcher
8
+ */
9
+ import type { ResponseMatcher } from '../types/index.js';
10
+ /**
11
+ * Validates a value against a matcher
12
+ *
13
+ * @param value - Value to validate
14
+ * @param matcher - Matcher configuration
15
+ * @param fieldPath - Field path for error messages
16
+ * @returns Validation result
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const result = validateWithMatcher(
21
+ * { id: 123, email: 'user@example.com' },
22
+ * {
23
+ * 'id': { type: 'type', expectedType: 'number' },
24
+ * 'email': { type: 'regex', pattern: '^[^@]+@[^@]+$' }
25
+ * }
26
+ * );
27
+ *
28
+ * if (!result.valid) {
29
+ * console.error('Validation failed:', result.errors);
30
+ * }
31
+ * ```
32
+ */
33
+ export declare function validateWithMatcher(value: unknown, matcher: ResponseMatcher, fieldPath: string): {
34
+ valid: boolean;
35
+ error?: string;
36
+ };
37
+ /**
38
+ * Gets nested value from object using dot notation path
39
+ *
40
+ * @param obj - Object to get value from
41
+ * @param path - Dot notation path (e.g., "response.body.user.id")
42
+ * @returns Value at path or undefined
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const obj = { response: { body: { user: { id: 123 } } } };
47
+ * const value = getNestedValue(obj, 'response.body.user.id'); // 123
48
+ * ```
49
+ */
50
+ export declare function getNestedValue(obj: any, path: string): unknown;
51
+ /**
52
+ * Validates response against matchers
53
+ *
54
+ * @param response - Response object to validate
55
+ * @param matchers - Matchers configuration (field path to matcher)
56
+ * @returns Validation result with errors
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const response = {
61
+ * body: {
62
+ * id: 123,
63
+ * email: 'user@example.com',
64
+ * createdAt: '2024-01-01T00:00:00Z'
65
+ * }
66
+ * };
67
+ *
68
+ * const matchers = {
69
+ * 'body.id': { type: 'type', expectedType: 'number' },
70
+ * 'body.email': { type: 'regex', pattern: '^[^@]+@[^@]+$' },
71
+ * 'body.createdAt': { type: 'regex', pattern: '^\\d{4}-\\d{2}-\\d{2}T' }
72
+ * };
73
+ *
74
+ * const result = validateResponse(response, matchers);
75
+ * if (!result.valid) {
76
+ * console.error('Validation failed:', result.errors);
77
+ * }
78
+ * ```
79
+ */
80
+ export declare function validateResponse(response: any, matchers: Record<string, ResponseMatcher>): {
81
+ valid: boolean;
82
+ errors: string[];
83
+ };
84
+ //# sourceMappingURL=response-matcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-matcher.d.ts","sourceRoot":"","sources":["../../src/validators/response-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAoBpC;AA4ID;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAqB9D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GACxC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAgBtC"}
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Response Matcher
3
+ *
4
+ * Validates API responses using type-based matchers instead of exact values.
5
+ * Inspired by Pact matchers but implemented without dependencies.
6
+ *
7
+ * @module validators/response-matcher
8
+ */
9
+ /**
10
+ * Validates a value against a matcher
11
+ *
12
+ * @param value - Value to validate
13
+ * @param matcher - Matcher configuration
14
+ * @param fieldPath - Field path for error messages
15
+ * @returns Validation result
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const result = validateWithMatcher(
20
+ * { id: 123, email: 'user@example.com' },
21
+ * {
22
+ * 'id': { type: 'type', expectedType: 'number' },
23
+ * 'email': { type: 'regex', pattern: '^[^@]+@[^@]+$' }
24
+ * }
25
+ * );
26
+ *
27
+ * if (!result.valid) {
28
+ * console.error('Validation failed:', result.errors);
29
+ * }
30
+ * ```
31
+ */
32
+ export function validateWithMatcher(value, matcher, fieldPath) {
33
+ switch (matcher.type) {
34
+ case 'type':
35
+ return validateType(value, matcher.expectedType, fieldPath);
36
+ case 'regex':
37
+ return validateRegex(value, matcher.pattern, fieldPath);
38
+ case 'range':
39
+ return validateRange(value, matcher.min, matcher.max, fieldPath);
40
+ case 'exists':
41
+ return validateExists(value, matcher.required, fieldPath);
42
+ default:
43
+ return {
44
+ valid: false,
45
+ error: `Unknown matcher type: ${matcher.type}`,
46
+ };
47
+ }
48
+ }
49
+ /**
50
+ * Validates type of a value
51
+ *
52
+ * @param value - Value to validate
53
+ * @param expectedType - Expected type
54
+ * @param fieldPath - Field path for error messages
55
+ * @returns Validation result
56
+ * @internal
57
+ */
58
+ function validateType(value, expectedType, fieldPath) {
59
+ const actualType = getType(value);
60
+ if (actualType === expectedType) {
61
+ return { valid: true };
62
+ }
63
+ return {
64
+ valid: false,
65
+ error: `Field "${fieldPath}" expected type "${expectedType}" but got "${actualType}"`,
66
+ };
67
+ }
68
+ /**
69
+ * Validates value matches regex pattern
70
+ *
71
+ * @param value - Value to validate
72
+ * @param pattern - Regular expression pattern
73
+ * @param fieldPath - Field path for error messages
74
+ * @returns Validation result
75
+ * @internal
76
+ */
77
+ function validateRegex(value, pattern, fieldPath) {
78
+ if (typeof value !== 'string') {
79
+ return {
80
+ valid: false,
81
+ error: `Field "${fieldPath}" must be a string for regex matching, got ${getType(value)}`,
82
+ };
83
+ }
84
+ const regex = new RegExp(pattern);
85
+ if (regex.test(value)) {
86
+ return { valid: true };
87
+ }
88
+ return {
89
+ valid: false,
90
+ error: `Field "${fieldPath}" value "${value}" does not match pattern "${pattern}"`,
91
+ };
92
+ }
93
+ /**
94
+ * Validates value is within range
95
+ *
96
+ * @param value - Value to validate
97
+ * @param min - Minimum value (optional)
98
+ * @param max - Maximum value (optional)
99
+ * @param fieldPath - Field path for error messages
100
+ * @returns Validation result
101
+ * @internal
102
+ */
103
+ function validateRange(value, min, max, fieldPath) {
104
+ if (typeof value !== 'number') {
105
+ return {
106
+ valid: false,
107
+ error: `Field "${fieldPath}" must be a number for range validation, got ${getType(value)}`,
108
+ };
109
+ }
110
+ if (min !== undefined && value < min) {
111
+ return {
112
+ valid: false,
113
+ error: `Field "${fieldPath}" value ${value} is less than minimum ${min}`,
114
+ };
115
+ }
116
+ if (max !== undefined && value > max) {
117
+ return {
118
+ valid: false,
119
+ error: `Field "${fieldPath}" value ${value} is greater than maximum ${max}`,
120
+ };
121
+ }
122
+ return { valid: true };
123
+ }
124
+ /**
125
+ * Validates field exists or not
126
+ *
127
+ * @param value - Value to validate
128
+ * @param required - Whether field is required
129
+ * @param fieldPath - Field path for error messages
130
+ * @returns Validation result
131
+ * @internal
132
+ */
133
+ function validateExists(value, required, fieldPath) {
134
+ const exists = value !== undefined && value !== null;
135
+ if (required && !exists) {
136
+ return {
137
+ valid: false,
138
+ error: `Field "${fieldPath}" is required but was ${value === undefined ? 'undefined' : 'null'}`,
139
+ };
140
+ }
141
+ // required: false means optional — field may be present or absent, both are valid
142
+ return { valid: true };
143
+ }
144
+ /**
145
+ * Gets the type of a value as a string
146
+ *
147
+ * @param value - Value to get type of
148
+ * @returns Type string
149
+ * @internal
150
+ */
151
+ function getType(value) {
152
+ if (value === null)
153
+ return 'null';
154
+ if (Array.isArray(value))
155
+ return 'array';
156
+ return typeof value;
157
+ }
158
+ /**
159
+ * Gets nested value from object using dot notation path
160
+ *
161
+ * @param obj - Object to get value from
162
+ * @param path - Dot notation path (e.g., "response.body.user.id")
163
+ * @returns Value at path or undefined
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * const obj = { response: { body: { user: { id: 123 } } } };
168
+ * const value = getNestedValue(obj, 'response.body.user.id'); // 123
169
+ * ```
170
+ */
171
+ export function getNestedValue(obj, path) {
172
+ const parts = path.split('.');
173
+ let current = obj;
174
+ for (const part of parts) {
175
+ if (current === null || current === undefined) {
176
+ return undefined;
177
+ }
178
+ // Handle array indices
179
+ const arrayMatch = part.match(/^(.+)\[(\d+)\]$/);
180
+ if (arrayMatch) {
181
+ const key = arrayMatch[1];
182
+ const index = parseInt(arrayMatch[2], 10);
183
+ current = current[key]?.[index];
184
+ }
185
+ else {
186
+ current = current[part];
187
+ }
188
+ }
189
+ return current;
190
+ }
191
+ /**
192
+ * Validates response against matchers
193
+ *
194
+ * @param response - Response object to validate
195
+ * @param matchers - Matchers configuration (field path to matcher)
196
+ * @returns Validation result with errors
197
+ *
198
+ * @example
199
+ * ```typescript
200
+ * const response = {
201
+ * body: {
202
+ * id: 123,
203
+ * email: 'user@example.com',
204
+ * createdAt: '2024-01-01T00:00:00Z'
205
+ * }
206
+ * };
207
+ *
208
+ * const matchers = {
209
+ * 'body.id': { type: 'type', expectedType: 'number' },
210
+ * 'body.email': { type: 'regex', pattern: '^[^@]+@[^@]+$' },
211
+ * 'body.createdAt': { type: 'regex', pattern: '^\\d{4}-\\d{2}-\\d{2}T' }
212
+ * };
213
+ *
214
+ * const result = validateResponse(response, matchers);
215
+ * if (!result.valid) {
216
+ * console.error('Validation failed:', result.errors);
217
+ * }
218
+ * ```
219
+ */
220
+ export function validateResponse(response, matchers) {
221
+ const errors = [];
222
+ for (const [path, matcher] of Object.entries(matchers)) {
223
+ const value = getNestedValue(response, path);
224
+ const result = validateWithMatcher(value, matcher, path);
225
+ if (!result.valid && result.error) {
226
+ errors.push(result.error);
227
+ }
228
+ }
229
+ return {
230
+ valid: errors.length === 0,
231
+ errors,
232
+ };
233
+ }
234
+ //# sourceMappingURL=response-matcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-matcher.js","sourceRoot":"","sources":["../../src/validators/response-matcher.ts"],"names":[],"mappings":"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"}