ml-testing-toolkit 18.13.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 (319) hide show
  1. package/.dockerignore +10 -0
  2. package/.grype.yaml +16 -0
  3. package/.ncurc.yaml +9 -0
  4. package/.nvmrc +1 -0
  5. package/.versionrc.js +16 -0
  6. package/CHANGELOG.md +504 -0
  7. package/CODEOWNERS +30 -0
  8. package/Dockerfile +42 -0
  9. package/Dockerfile-newman +13 -0
  10. package/LICENSE.md +9 -0
  11. package/README.md +119 -0
  12. package/assets/diagrams/architectural/architectural-diagram.svg +3 -0
  13. package/assets/diagrams/flow/flow-diagram.svg +3 -0
  14. package/assets/images/Sample-Response-Failure.png +0 -0
  15. package/assets/images/Screenshot 2020-04-16 at 22.58.04.png +0 -0
  16. package/assets/images/TLS-Enabled-on-Environment.png +0 -0
  17. package/assets/images/adapter-mutual-tls-enabled.png +0 -0
  18. package/assets/images/add-additional-input-values.png +0 -0
  19. package/assets/images/add-condition-button.png +0 -0
  20. package/assets/images/add-new-assertion.png +0 -0
  21. package/assets/images/add-new-input-value.png +0 -0
  22. package/assets/images/add-new-input-variable.png +0 -0
  23. package/assets/images/additional-transfers.png +0 -0
  24. package/assets/images/api-provisioning-add-new-api-confirmation.png +0 -0
  25. package/assets/images/api-provisioning-file-input-window.png +0 -0
  26. package/assets/images/api-provisioning-list-apis-view.png +0 -0
  27. package/assets/images/api-provisioning-menu-item.png +0 -0
  28. package/assets/images/apply_and_restart.jpg +0 -0
  29. package/assets/images/assess-request-or-response.png +0 -0
  30. package/assets/images/assess-response-equation-save.png +0 -0
  31. package/assets/images/assess-response-equation.png +0 -0
  32. package/assets/images/assess-response-status.png +0 -0
  33. package/assets/images/building-new-rules-file.png +0 -0
  34. package/assets/images/callback-rules-screen.png +0 -0
  35. package/assets/images/configurable-parameter-assertion.png +0 -0
  36. package/assets/images/configurable-parameter-currency.png +0 -0
  37. package/assets/images/configurable-parameter.png +0 -0
  38. package/assets/images/connection-manager-ui-opening.png +0 -0
  39. package/assets/images/create-inbound-user-simulator.png +0 -0
  40. package/assets/images/creating-new-rule-file.png +0 -0
  41. package/assets/images/dfsp-client-cacert.png +0 -0
  42. package/assets/images/dfsp-client-submit.png +0 -0
  43. package/assets/images/dfsp-client.png +0 -0
  44. package/assets/images/dfsp-p2p-happy-path.png +0 -0
  45. package/assets/images/dfsp-server-cacert.png +0 -0
  46. package/assets/images/dfsp-server-cert.png +0 -0
  47. package/assets/images/download-report.png +0 -0
  48. package/assets/images/drive_have_not_been_shared.jpg +0 -0
  49. package/assets/images/event-response-options.png +0 -0
  50. package/assets/images/expand-monitoring-messages.png +0 -0
  51. package/assets/images/fixed-response-sample.png +0 -0
  52. package/assets/images/header-selection.png +0 -0
  53. package/assets/images/heap_error_windows.jpg +0 -0
  54. package/assets/images/hosted-mode-docker-compose-intro.png +0 -0
  55. package/assets/images/hub-client-cert.png +0 -0
  56. package/assets/images/import-template.png +0 -0
  57. package/assets/images/inbound-requests-environment.png +0 -0
  58. package/assets/images/inbound-requests-scripts.png +0 -0
  59. package/assets/images/jws-certificate-submit.png +0 -0
  60. package/assets/images/jws-certificate.png +0 -0
  61. package/assets/images/jws-certs-keys.png +0 -0
  62. package/assets/images/jws-hub-certs-keys.png +0 -0
  63. package/assets/images/local-enable-jws-publickey.png +0 -0
  64. package/assets/images/local-mutual-tls-enabled.png +0 -0
  65. package/assets/images/local_drives_to_be_available.jpg +0 -0
  66. package/assets/images/mcm-environment-opening.png +0 -0
  67. package/assets/images/menu-items.png +0 -0
  68. package/assets/images/mock-response-sample.png +0 -0
  69. package/assets/images/monitoring-initial-state.png +0 -0
  70. package/assets/images/monitoring-messages.png +0 -0
  71. package/assets/images/new-empty-assertion.png +0 -0
  72. package/assets/images/opened-imported-template.png +0 -0
  73. package/assets/images/opening-default-settings.png +0 -0
  74. package/assets/images/opening-sync-response-rules.png +0 -0
  75. package/assets/images/opening-view.png +0 -0
  76. package/assets/images/outbound-display-opening-hub.png +0 -0
  77. package/assets/images/outbound-display-opening.png +0 -0
  78. package/assets/images/override-with-environment-variable.png +0 -0
  79. package/assets/images/populate-with-sample-body.png +0 -0
  80. package/assets/images/resource-selection.png +0 -0
  81. package/assets/images/rule-builder-select-api.png +0 -0
  82. package/assets/images/sample-condition-add-configurable-params.png +0 -0
  83. package/assets/images/sample-condition.png +0 -0
  84. package/assets/images/sample-editor.png +0 -0
  85. package/assets/images/sample-request.png +0 -0
  86. package/assets/images/sample-test-assertion.png +0 -0
  87. package/assets/images/send-transfer.png +0 -0
  88. package/assets/images/sending-single-test-case-1.png +0 -0
  89. package/assets/images/sending-single-test-case-2.png +0 -0
  90. package/assets/images/sending-test-cases.png +0 -0
  91. package/assets/images/server-certificates-submitted.png +0 -0
  92. package/assets/images/simulator-response.png +0 -0
  93. package/assets/images/simulator-scheme-adapter-endpoint.png +0 -0
  94. package/assets/images/summarized-view-of-rule.png +0 -0
  95. package/assets/images/template-window.png +0 -0
  96. package/assets/images/test-case-editor-console-log.png +0 -0
  97. package/assets/images/test-case-editor-environment-state.png +0 -0
  98. package/assets/images/test-case-editor-scripts.png +0 -0
  99. package/assets/images/test-case-editor.png +0 -0
  100. package/assets/images/testcase-definition-download.png +0 -0
  101. package/assets/images/testcase-definition-edit-meta-info.png +0 -0
  102. package/assets/images/testing-toolkit-mojaloop-testing-toolkit-endpoint.png +0 -0
  103. package/assets/images/tls-hub-certs-keys.png +0 -0
  104. package/assets/images/tls-jws-enabled-on-environment.png +0 -0
  105. package/assets/images/updated-sample-body-data.png +0 -0
  106. package/assets/images/using-configurable-parameter.png +0 -0
  107. package/assets/images/validation-rules-screen.png +0 -0
  108. package/assets/images/view-response.png +0 -0
  109. package/audit-ci.jsonc +7 -0
  110. package/connection-manager/docker-compose.yml +55 -0
  111. package/database/docker-compose.yml +16 -0
  112. package/docker/hosted-mode/docker-compose.yaml +107 -0
  113. package/docker/hosted-mode/keycloak/keycloak-realm.json +2298 -0
  114. package/docker/hosted-mode/mongo-init.sh +1 -0
  115. package/docker/hosted-mode-tls/docker-compose.yaml +171 -0
  116. package/docker/hosted-mode-tls/keycloak/keycloak-realm.json +2298 -0
  117. package/docker/hosted-mode-tls/mongo-init.sh +1 -0
  118. package/docker-compose.yml +62 -0
  119. package/documents/Mojaloop-Testing-Toolkit.md +296 -0
  120. package/documents/RULES_ENGINE.md +403 -0
  121. package/documents/User-Guide-API-Provisioning.md +121 -0
  122. package/documents/User-Guide-CLI.md +218 -0
  123. package/documents/User-Guide-Connection-Manager.md +282 -0
  124. package/documents/User-Guide-Frequently-Asked-Questions.md +39 -0
  125. package/documents/User-Guide-Hosted-Mode-Docker-Compose.md +110 -0
  126. package/documents/User-Guide-Installation.md +163 -0
  127. package/documents/User-Guide-Mojaloop-Testing-Toolkit.md +642 -0
  128. package/documents/User-Guide-OAuth-Server-Deployment.md +283 -0
  129. package/documents/User-Guide-Onboarding-DFSP.md +197 -0
  130. package/documents/User-Guide-Onboarding-HUB.md +191 -0
  131. package/documents/User-Guide.md +53 -0
  132. package/examples/collections/dfsp/p2p_failed_tests.json +7161 -0
  133. package/examples/collections/dfsp/p2p_fx_happy_path.json +502 -0
  134. package/examples/collections/dfsp/p2p_happy_path.json +350 -0
  135. package/examples/collections/dfsp/p2p_happy_path_extended.json +6106 -0
  136. package/examples/collections/dfsp/p2p_happy_path_jws.json +511 -0
  137. package/examples/collections/dfsp/p2p_payee_assertions_websocket.json +441 -0
  138. package/examples/collections/dfsp/sample.json +5029 -0
  139. package/examples/collections/dfsp/transaction_request_service.json +240 -0
  140. package/examples/collections/fxp/FXP.json +264 -0
  141. package/examples/collections/fxp/SDK_backend.json +98 -0
  142. package/examples/collections/fxp/SDK_outbound.json +163 -0
  143. package/examples/collections/hub/hub_01_p2p_happy_path/hub_p2p_receive_quote.json +400 -0
  144. package/examples/collections/hub/hub_01_p2p_happy_path/hub_p2p_send_quote.json +395 -0
  145. package/examples/collections/hub/hub_02_block_transfer/hub_block_transfer.json +393 -0
  146. package/examples/collections/hub/hub_03_funds_in_out/hub_funds_in.json +224 -0
  147. package/examples/collections/hub/hub_03_funds_in_out/hub_funds_out.json +780 -0
  148. package/examples/collections/hub/hub_04_settlements/hub_settlements.json +3138 -0
  149. package/examples/collections/hub/hub_05_transfer_negative_scenarios/hub_transfer_negative_payee_abort.json +475 -0
  150. package/examples/collections/hub/hub_05_transfer_negative_scenarios/hub_transfer_negative_payee_invalid_fulfillment.json +370 -0
  151. package/examples/collections/hub/hub_05_transfer_negative_scenarios/hub_transfer_negative_transfer_timeout.json +262 -0
  152. package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_authorizations.json +117 -0
  153. package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_error_framework.json +591 -0
  154. package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_received_state.json +379 -0
  155. package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_reject_state.json +361 -0
  156. package/examples/collections/hub/hub_07_quoting_service.json +525 -0
  157. package/examples/collections/hub/hub_08_participant_inactive_stop_transfers.json +706 -0
  158. package/examples/collections/hub/hub_09_duplicate_handling_transfers.json +1377 -0
  159. package/examples/collections/hub/hub_10_on_us_transfers.json +245 -0
  160. package/examples/collections/hub/hub_11_accented_and_spl_chars.json +629 -0
  161. package/examples/collections/hub/hub_12_fspiop_version_1.1.json +646 -0
  162. package/examples/collections/hub/hub_13_bulk_transfers.json +1857 -0
  163. package/examples/collections/iso20022/self_referencing_iso20022.json +926 -0
  164. package/examples/collections/provisioning/testingtoolkitdfsp.json +904 -0
  165. package/examples/environments/dfsp_local_environment.json +46 -0
  166. package/examples/environments/hub_local_environment.json +57 -0
  167. package/jest.config.js +17 -0
  168. package/package.json +199 -0
  169. package/sbom-v18.12.4.csv +1553 -0
  170. package/secrets/keygen.sh +5 -0
  171. package/secrets/privatekey.pem +27 -0
  172. package/secrets/publickey.cer +21 -0
  173. package/secrets/tls/01.pem +132 -0
  174. package/secrets/tls/createSecrets.sh +20 -0
  175. package/secrets/tls/hub_client.csr +32 -0
  176. package/secrets/tls/hub_client_cacert.pem +35 -0
  177. package/secrets/tls/hub_client_cakey.pem +52 -0
  178. package/secrets/tls/hub_client_key.key +52 -0
  179. package/secrets/tls/hub_server.csr +31 -0
  180. package/secrets/tls/hub_server_cacert.pem +35 -0
  181. package/secrets/tls/hub_server_cakey.pem +52 -0
  182. package/secrets/tls/hub_server_cert.pem +132 -0
  183. package/secrets/tls/hub_server_key.key +52 -0
  184. package/secrets/tls/index.txt +1 -0
  185. package/secrets/tls/index.txt.attr +1 -0
  186. package/secrets/tls/openssl-client.cnf +36 -0
  187. package/secrets/tls/openssl-clientca.cnf +71 -0
  188. package/secrets/tls/openssl-server.cnf +39 -0
  189. package/secrets/tls/openssl-serverca.cnf +71 -0
  190. package/secrets/tls/serial.txt +1 -0
  191. package/spec_files/api_definitions/als_admin_1.1/api_spec.yaml +804 -0
  192. package/spec_files/api_definitions/central_admin_1.0/api_spec.yaml +1850 -0
  193. package/spec_files/api_definitions/central_admin_1.0/response_map.json +96 -0
  194. package/spec_files/api_definitions/central_admin_old_9.3/api_spec.yaml +2467 -0
  195. package/spec_files/api_definitions/central_admin_old_9.3/response_map.json +96 -0
  196. package/spec_files/api_definitions/fspiop_1.0/api_spec.yaml +4187 -0
  197. package/spec_files/api_definitions/fspiop_1.0/callback_map.json +568 -0
  198. package/spec_files/api_definitions/fspiop_1.0/mockRef.json +79 -0
  199. package/spec_files/api_definitions/fspiop_1.0/trigger_templates/transaction_request_followup.json +126 -0
  200. package/spec_files/api_definitions/fspiop_1.0/trigger_templates/transaction_request_followup_quotes_only.json +97 -0
  201. package/spec_files/api_definitions/fspiop_1.1/api_spec.yaml +3778 -0
  202. package/spec_files/api_definitions/fspiop_1.1/callback_map.json +568 -0
  203. package/spec_files/api_definitions/fspiop_1.1/mockRef.json +79 -0
  204. package/spec_files/api_definitions/fspiop_1.1/trigger_templates/transaction_request_followup.json +125 -0
  205. package/spec_files/api_definitions/fspiop_2.0/api_spec.yaml +4839 -0
  206. package/spec_files/api_definitions/fspiop_2.0/callback_map.json +716 -0
  207. package/spec_files/api_definitions/fspiop_2.0/mockRef.json +79 -0
  208. package/spec_files/api_definitions/fspiop_2.0/trigger_templates/transaction_request_followup.json +125 -0
  209. package/spec_files/api_definitions/fspiop_2.0_iso20022/api_spec.yaml +8331 -0
  210. package/spec_files/api_definitions/fspiop_2.0_iso20022/callback_map.json +508 -0
  211. package/spec_files/api_definitions/fspiop_2.0_iso20022/mockRef.json +66 -0
  212. package/spec_files/api_definitions/fx-api_2.0/api_spec.yaml +1768 -0
  213. package/spec_files/api_definitions/fx-api_2.0/callback_map.json +188 -0
  214. package/spec_files/api_definitions/fx-api_2.0/mockRef.json +83 -0
  215. package/spec_files/api_definitions/mojaloop_sdk_outbound_scheme_adapter_1.0/api_spec.yaml +2612 -0
  216. package/spec_files/api_definitions/mojaloop_sdk_outbound_scheme_adapter_1.0/mockRef.json +22 -0
  217. package/spec_files/api_definitions/mojaloop_sdk_outbound_scheme_adapter_1.0/response_map.json +35 -0
  218. package/spec_files/api_definitions/mojaloop_simulator_0.1/api_spec.yaml +225 -0
  219. package/spec_files/api_definitions/mojaloop_simulator_sim_1.4/api_spec.yaml +1087 -0
  220. package/spec_files/api_definitions/mojaloop_simulator_sim_1.4/mockRef.json +75 -0
  221. package/spec_files/api_definitions/mojaloop_simulator_sim_1.4/response_map.json +55 -0
  222. package/spec_files/api_definitions/payment_manager_1.4/api_spec.yaml +1389 -0
  223. package/spec_files/api_definitions/sdk-scheme-adapter-backend-v2_1_0-openapi3-snippets_2.1/api_spec.yaml +2834 -0
  224. package/spec_files/api_definitions/sdk-scheme-adapter-outbound-v2_1_0-openapi3-snippets_2.1/api_spec.yaml +3449 -0
  225. package/spec_files/api_definitions/settlements_1.0/api_spec.yaml +983 -0
  226. package/spec_files/api_definitions/settlements_1.0/mockRef.json +38 -0
  227. package/spec_files/api_definitions/settlements_1.0/response_map.json +34 -0
  228. package/spec_files/api_definitions/settlements_2.0/api_spec.yaml +1001 -0
  229. package/spec_files/api_definitions/settlements_2.0/mockRef.json +38 -0
  230. package/spec_files/api_definitions/settlements_2.0/response_map.json +34 -0
  231. package/spec_files/api_definitions/thirdparty_sdk_outbound_0.1/api_spec.yaml +2139 -0
  232. package/spec_files/reports/templates/newman/html_template.html +1202 -0
  233. package/spec_files/reports/templates/newman/pdf_template.html +790 -0
  234. package/spec_files/reports/templates/testcase_definition/table_view.html +1602 -0
  235. package/spec_files/rules_callback/config.json +3 -0
  236. package/spec_files/rules_callback/default.json +2698 -0
  237. package/spec_files/rules_callback/p2p-limit.json +129 -0
  238. package/spec_files/rules_forward/config.json +3 -0
  239. package/spec_files/rules_forward/default.json +482 -0
  240. package/spec_files/rules_response/config.json +3 -0
  241. package/spec_files/rules_response/default.json +295 -0
  242. package/spec_files/rules_validation/config.json +3 -0
  243. package/spec_files/rules_validation/default.json +1 -0
  244. package/spec_files/rules_validation/p2p-limit.json +55 -0
  245. package/spec_files/system_config.json +175 -0
  246. package/spec_files/user_config.json +109 -0
  247. package/src/index.js +67 -0
  248. package/src/lib/MyEventEmitter.js +54 -0
  249. package/src/lib/api-management.js +143 -0
  250. package/src/lib/api-routes/config.js +83 -0
  251. package/src/lib/api-routes/history.js +139 -0
  252. package/src/lib/api-routes/keycloak.js +54 -0
  253. package/src/lib/api-routes/longpolling.js +70 -0
  254. package/src/lib/api-routes/oauth2.js +149 -0
  255. package/src/lib/api-routes/objectstore.js +53 -0
  256. package/src/lib/api-routes/openapi.js +224 -0
  257. package/src/lib/api-routes/outbound.js +134 -0
  258. package/src/lib/api-routes/reports.js +72 -0
  259. package/src/lib/api-routes/rules.js +356 -0
  260. package/src/lib/api-routes/samples.js +92 -0
  261. package/src/lib/api-routes/server-logs.js +44 -0
  262. package/src/lib/api-routes/settings.js +71 -0
  263. package/src/lib/api-server.js +135 -0
  264. package/src/lib/arrayStore.js +101 -0
  265. package/src/lib/callbackHandler.js +201 -0
  266. package/src/lib/config.js +177 -0
  267. package/src/lib/configuration-providers/mb-connection-manager.js +625 -0
  268. package/src/lib/db/adapters/dbAdapter.js +184 -0
  269. package/src/lib/db/dfspMockUsers.js +64 -0
  270. package/src/lib/db/models/mongoDBWrapper.js +78 -0
  271. package/src/lib/eventListenerClient/inboundEventListener.js +176 -0
  272. package/src/lib/fileAdapter.js +57 -0
  273. package/src/lib/httpAgentStore.js +135 -0
  274. package/src/lib/importExport.js +186 -0
  275. package/src/lib/jws/JwsSigning.js +141 -0
  276. package/src/lib/loadSamples.js +128 -0
  277. package/src/lib/logger.js +20 -0
  278. package/src/lib/longpollingEmitter.js +56 -0
  279. package/src/lib/metrics.js +51 -0
  280. package/src/lib/mocking/custom-functions/generic.js +57 -0
  281. package/src/lib/mocking/middleware-functions/ilpModel.js +238 -0
  282. package/src/lib/mocking/middleware-functions/quotesAssociation.js +75 -0
  283. package/src/lib/mocking/middleware-functions/transactionRequestsService.js +78 -0
  284. package/src/lib/mocking/openApiDefinitionsModel.js +64 -0
  285. package/src/lib/mocking/openApiMockHandler.js +466 -0
  286. package/src/lib/mocking/openApiRulesEngine.js +492 -0
  287. package/src/lib/mocking/openApiVersionTools.js +136 -0
  288. package/src/lib/mocking/transformers/fspiopToISO20022.js +230 -0
  289. package/src/lib/mocking/transformers/index.js +41 -0
  290. package/src/lib/notificationEmitter.js +64 -0
  291. package/src/lib/oauth/KeycloakHelper.js +220 -0
  292. package/src/lib/oauth/LoginService.js +133 -0
  293. package/src/lib/oauth/OAuthHelper.js +181 -0
  294. package/src/lib/oauth/OAuthValidator.js +118 -0
  295. package/src/lib/oauth/Wso2Client.js +64 -0
  296. package/src/lib/objectStore/inMemoryImpl.js +50 -0
  297. package/src/lib/objectStore/objectStoreInterface.js +51 -0
  298. package/src/lib/objectStore.js +122 -0
  299. package/src/lib/report-generator/generator.js +126 -0
  300. package/src/lib/report-generator/helpers.js +154 -0
  301. package/src/lib/requestLogger.js +190 -0
  302. package/src/lib/resources/wso2carbon-publickey.cert +20 -0
  303. package/src/lib/rulesEngine.js +95 -0
  304. package/src/lib/rulesEngineModel.js +463 -0
  305. package/src/lib/scripting-engines/postman-sandbox.js +142 -0
  306. package/src/lib/scripting-engines/vm-javascript-sandbox.js +294 -0
  307. package/src/lib/server-logs/adapters/elastic-search.js +102 -0
  308. package/src/lib/server-logs/adapters/grafana.js +0 -0
  309. package/src/lib/server-logs/index.js +75 -0
  310. package/src/lib/socket-server.js +55 -0
  311. package/src/lib/storageAdapter.js +109 -0
  312. package/src/lib/test-outbound/TestCaseRunner.js +173 -0
  313. package/src/lib/test-outbound/getTracing.js +19 -0
  314. package/src/lib/test-outbound/outbound-initiator.js +1107 -0
  315. package/src/lib/uniqueIdGenerator.js +35 -0
  316. package/src/lib/utils.js +89 -0
  317. package/src/lib/utilsInternal.js +56 -0
  318. package/src/lib/webSocketClient/WebSocketClientManager.js +197 -0
  319. package/src/server.js +218 -0
@@ -0,0 +1,126 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2025 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * Mojaloop Foundation
23
+ - Name Surname <name.surname@mojaloop.io>
24
+
25
+ * ModusBox
26
+ * Vijaya Kumar Guthi <vijaya.guthi@modusbox.com> (Original Author)
27
+ --------------
28
+ ******/
29
+ const Handlebars = require('handlebars')
30
+ const { readFileAsync } = require('../utils')
31
+ const reportHelpers = require('./helpers')
32
+ const customLogger = require('../requestLogger')
33
+ const BASE_TEMPLATE_PATH = 'spec_files/reports/templates'
34
+
35
+ const testResultTemplates = {
36
+ html: {
37
+ file: 'html_template.html',
38
+ handle: null
39
+ },
40
+ pdf: {
41
+ file: 'pdf_template.html',
42
+ handle: null
43
+ }
44
+ }
45
+
46
+ const testcaseDefinitionTemplates = {
47
+ html: {
48
+ file: 'table_view.html',
49
+ handle: null
50
+ }
51
+ }
52
+
53
+ const _initializeTestReports = async () => {
54
+ for (const key of Object.keys(testResultTemplates)) {
55
+ const templateContent = await readFileAsync(BASE_TEMPLATE_PATH + '/newman/' + testResultTemplates[key].file)
56
+ testResultTemplates[key].handle = Handlebars.compile(templateContent.toString())
57
+ customLogger.logMessage('debug', key + ' template compiled')
58
+ }
59
+ }
60
+
61
+ const _initializeTestcaseDefinition = async () => {
62
+ for (const key of Object.keys(testcaseDefinitionTemplates)) {
63
+ const templateContent = await readFileAsync(BASE_TEMPLATE_PATH + '/testcase_definition/' + testcaseDefinitionTemplates[key].file)
64
+ testcaseDefinitionTemplates[key].handle = Handlebars.compile(templateContent.toString())
65
+ customLogger.logMessage('debug', key + ' template compiled')
66
+ }
67
+ }
68
+
69
+ const initialize = async () => {
70
+ customLogger.logMessage('info', 'Initializing Report Generator...')
71
+ await _initializeTestReports()
72
+ await _initializeTestcaseDefinition()
73
+ }
74
+
75
+ const generateReport = async (jsonReport, format) => {
76
+ let templateHandle = testResultTemplates.html.handle
77
+ if (format === 'pdf' || format === 'printhtml') {
78
+ templateHandle = testResultTemplates.pdf.handle
79
+ }
80
+
81
+ if (templateHandle) {
82
+ try {
83
+ const data = jsonReport
84
+ const options = {
85
+ helpers: reportHelpers
86
+ }
87
+ const result = templateHandle(data, options)
88
+ customLogger.logMessage('debug', 'Report generated in ' + format + ' format')
89
+ return result
90
+ } catch (err) {
91
+ customLogger.logMessage('error', 'Error in generating template: ' + err.message)
92
+ throw (err)
93
+ }
94
+ } else {
95
+ customLogger.logMessage('error', 'No template generator found for ' + format)
96
+ throw (new Error('No template generator found for ' + format))
97
+ }
98
+ }
99
+
100
+ const generateTestcaseDefinition = async (template, format) => {
101
+ const templateHandle = testcaseDefinitionTemplates.html.handle
102
+
103
+ if (templateHandle) {
104
+ try {
105
+ const data = template
106
+ const options = {
107
+ // helpers: reportHelpers
108
+ }
109
+ const result = templateHandle(data, options)
110
+ customLogger.logMessage('debug', 'Report generated in ' + format + ' format')
111
+ return result
112
+ } catch (err) {
113
+ customLogger.logMessage('error', 'Error in generating template: ' + err.message)
114
+ throw (err)
115
+ }
116
+ } else {
117
+ customLogger.logMessage('error', 'No template generator found for ' + format)
118
+ throw (new Error('No template generator found for ' + format))
119
+ }
120
+ }
121
+
122
+ module.exports = {
123
+ initialize,
124
+ generateReport,
125
+ generateTestcaseDefinition
126
+ }
@@ -0,0 +1,154 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2025 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * Mojaloop Foundation
23
+ - Name Surname <name.surname@mojaloop.io>
24
+
25
+ * ModusBox
26
+ * Vijaya Kumar Guthi <vijaya.guthi@modusbox.com> (Original Author)
27
+ --------------
28
+ ******/
29
+
30
+ const now = () => {
31
+ return new Date().toLocaleDateString()
32
+ }
33
+
34
+ const totalAssertions = (testCases) => {
35
+ return testCases.reduce((total, curTestCase) => {
36
+ const assertionsInRequest = curTestCase.requests.reduce((assertionCountRequest, curRequest) => {
37
+ return assertionCountRequest + ((curRequest.request.tests && curRequest.request.tests.assertions) ? curRequest.request.tests.assertions.length : 0)
38
+ }, 0)
39
+ return total + assertionsInRequest
40
+ }, 0)
41
+ }
42
+
43
+ const totalPassedAssertions = (testCases) => {
44
+ return testCases.reduce((total, curTestCase) => {
45
+ const passedAssertionsInRequest = curTestCase.requests.reduce((passedAssertionCountRequest, curRequest) => {
46
+ return passedAssertionCountRequest + ((curRequest.request.tests && curRequest.request.tests.passedAssertionsCount) ? curRequest.request.tests.passedAssertionsCount : 0)
47
+ }, 0)
48
+ return total + passedAssertionsInRequest
49
+ }, 0)
50
+ }
51
+
52
+ const totalFailedAssertions = (testCases) => {
53
+ return totalAssertions(testCases) - totalPassedAssertions(testCases)
54
+ }
55
+
56
+ const totalTestCases = (testCases) => {
57
+ return testCases.length
58
+ }
59
+
60
+ const failedTestCases = (testCases) => {
61
+ return testCases.reduce((total, curTestCase) => {
62
+ const assertionsInRequest = curTestCase.requests.reduce((assertionCountRequest, curRequest) => {
63
+ return assertionCountRequest + ((curRequest.request.tests && curRequest.request.tests.assertions) ? curRequest.request.tests.assertions.length : 0)
64
+ }, 0)
65
+ const passedAssertionsInRequest = curTestCase.requests.reduce((passedAssertionCountRequest, curRequest) => {
66
+ return passedAssertionCountRequest + ((curRequest.request.tests && curRequest.request.tests.passedAssertionsCount) ? curRequest.request.tests.passedAssertionsCount : 0)
67
+ }, 0)
68
+ return total + (passedAssertionsInRequest === assertionsInRequest ? 0 : 1)
69
+ }, 0)
70
+ }
71
+
72
+ const totalRequests = (testCases) => {
73
+ return testCases.reduce((total, curTestCase) => {
74
+ return total + curTestCase.requests.length
75
+ }, 0)
76
+ }
77
+
78
+ const failedRequests = (testCases) => {
79
+ return testCases.reduce((total, curTestCase) => {
80
+ const faileRequestsCount = curTestCase.requests.reduce((failedRequestCountTemp, curRequest) => {
81
+ return failedRequestCountTemp + ((curRequest.request.tests && curRequest.request.tests.assertions) ? (curRequest.request.tests.assertions.length === curRequest.request.tests.passedAssertionsCount ? 0 : 1) : 0)
82
+ }, 0)
83
+ return total + faileRequestsCount
84
+ }, 0)
85
+ }
86
+
87
+ const testPassPercentage = (tests) => {
88
+ if (tests && tests.assertions) {
89
+ return Math.round(tests.passedAssertionsCount * 100 / tests.assertions.length)
90
+ } else {
91
+ return 100
92
+ }
93
+ }
94
+
95
+ const ifAllTestsPassedInRequest = (request) => {
96
+ if (request.tests && request.tests.assertions) {
97
+ return request.tests.passedAssertionsCount === request.tests.assertions.length
98
+ } else {
99
+ return true
100
+ }
101
+ }
102
+
103
+ const ifFailedTestCase = (testCase) => {
104
+ const failedRequest = testCase.requests.find((item) => {
105
+ if (item.request.tests && item.request.tests.assertions) {
106
+ return item.request.tests.passedAssertionsCount !== item.request.tests.assertions.length
107
+ } else {
108
+ return false
109
+ }
110
+ })
111
+ if (failedRequest) {
112
+ return true
113
+ } else {
114
+ return false
115
+ }
116
+ }
117
+
118
+ const ifSkippedRequest = (status) => {
119
+ if (status && status === 'SKIPPED') {
120
+ return true
121
+ } else {
122
+ return false
123
+ }
124
+ }
125
+
126
+ const jsonStringify = (inputObject) => {
127
+ return JSON.stringify(inputObject, null, 2)
128
+ }
129
+
130
+ const isAssertionPassed = (status) => {
131
+ return status === 'SUCCESS'
132
+ }
133
+
134
+ const isAssertionSkipped = (status) => {
135
+ return status === 'SKIPPED'
136
+ }
137
+
138
+ module.exports = {
139
+ now,
140
+ totalAssertions,
141
+ totalPassedAssertions,
142
+ totalFailedAssertions,
143
+ totalTestCases,
144
+ failedTestCases,
145
+ totalRequests,
146
+ failedRequests,
147
+ testPassPercentage,
148
+ ifAllTestsPassedInRequest,
149
+ ifFailedTestCase,
150
+ jsonStringify,
151
+ isAssertionPassed,
152
+ isAssertionSkipped,
153
+ ifSkippedRequest
154
+ }
@@ -0,0 +1,190 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2025 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * Mojaloop Foundation
23
+ - Name Surname <name.surname@mojaloop.io>
24
+
25
+ * ModusBox
26
+ * Georgi Logodazhki <georgi.logodazhki@modusbox.com>
27
+ * Vijaya Kumar Guthi <vijaya.guthi@modusbox.com> (Original Author)
28
+ --------------
29
+ ******/
30
+
31
+ 'use strict'
32
+
33
+ const util = require('node:util')
34
+ const Logger = require('@mojaloop/central-services-logger')
35
+ const Config = require('./config')
36
+ const NotificationEmitter = require('./notificationEmitter')
37
+ const DBAdapter = require('./db/adapters/dbAdapter')
38
+ const { TraceHeaderUtils } = require('@mojaloop/ml-testing-toolkit-shared-lib')
39
+
40
+ const logRequest = async (request, user) => {
41
+ let message = `Request: ${request.method} ${request.path}`
42
+ if (request.body) {
43
+ message += ` Body: ${request.body}`
44
+ }
45
+ const userConfig = await Config.getUserConfig()
46
+ logMessage('info', message, {
47
+ additionalData: {
48
+ request: {
49
+ uniqueId: request.customInfo ? request.customInfo.uniqueId : null,
50
+ headers: request.headers,
51
+ queryParams: request.query,
52
+ body: userConfig.MONITORING_LOG_INCLUDE_PAYLOAD ? request.payload : 'Payload is hidden - enable it in user-config MONITORING_LOG_INCLUDE_PAYLOAD'
53
+ }
54
+ },
55
+ user,
56
+ request,
57
+ messageType: 'request'
58
+ })
59
+ }
60
+
61
+ const logOutboundRequest = (verbosity, message, externalData = {}) => {
62
+ externalData.notificationType = 'newOutboundLog'
63
+
64
+ if (externalData.request.headers && externalData.request.headers.traceparent) {
65
+ const traceparentHeaderArr = externalData.request.headers.traceparent.split('-')
66
+ if (traceparentHeaderArr.length > 1) {
67
+ const traceID = traceparentHeaderArr[1]
68
+ if (!externalData.request.customInfo) {
69
+ externalData.request.customInfo = {}
70
+ }
71
+ externalData.request.customInfo.traceID = traceID
72
+ if (TraceHeaderUtils.isCustomTraceID(traceID)) {
73
+ externalData.request.customInfo.endToEndID = TraceHeaderUtils.getEndToEndID(traceID)
74
+ externalData.request.customInfo.sessionID = TraceHeaderUtils.getSessionID(traceID)
75
+ }
76
+ }
77
+ }
78
+
79
+ if (externalData.additionalData) {
80
+ if (externalData.additionalData.request) {
81
+ externalData.additionalData.request = {
82
+ url: externalData.additionalData.request.url,
83
+ uniqueId: externalData.uniqueId,
84
+ headers: externalData.additionalData.request.headers,
85
+ queryParams: externalData.additionalData.request.query,
86
+ body: externalData.additionalData.request.payload || externalData.additionalData.request.data
87
+ }
88
+ } else if (externalData.additionalData.response) {
89
+ const response = externalData.additionalData.response
90
+ externalData.additionalData.response = {
91
+ status: response.status,
92
+ statusText: response.statusText,
93
+ uniqueId: externalData.uniqueId,
94
+ headers: response.headers,
95
+ body: response.payload || response.data
96
+ }
97
+ }
98
+ }
99
+ logMessage(verbosity, message, externalData)
100
+ }
101
+
102
+ const logResponse = async (request, user) => {
103
+ if (request.response) {
104
+ const message = `Response: ${request.method} ${request.path} Status: ${request.response.statusCode}`
105
+ const userConfig = await Config.getUserConfig()
106
+ logMessage('info', message, {
107
+ additionalData: {
108
+ response: {
109
+ uniqueId: request.customInfo.uniqueId || null,
110
+ body: userConfig.MONITORING_LOG_INCLUDE_PAYLOAD ? request.response.source : 'Payload is hidden - enable it in user-config MONITORING_LOG_INCLUDE_PAYLOAD',
111
+ status: request.response.statusCode
112
+ }
113
+ },
114
+ user,
115
+ request,
116
+ messageType: 'response'
117
+ })
118
+ }
119
+ }
120
+
121
+ const logMessage = (verbosity, message, externalData = {}) => {
122
+ const data = {
123
+ additionalData: externalData.additionalData,
124
+ notification: typeof externalData.notification !== 'undefined' ? externalData.notification : true,
125
+ messageType: externalData.messageType || 'generic',
126
+ request: externalData.request || null,
127
+ user: externalData.user
128
+ }
129
+ switch (verbosity) {
130
+ case 'debug':
131
+ Logger.debug(message)
132
+ if (data.additionalData !== undefined) Logger.debug(util.inspect(data.additionalData))
133
+ break
134
+ case 'warn':
135
+ Logger.warn(message)
136
+ if (data.additionalData !== undefined) Logger.warn(util.inspect(data.additionalData))
137
+ break
138
+ case 'error':
139
+ Logger.error(message)
140
+ if (data.additionalData !== undefined) Logger.error(util.inspect(data.additionalData))
141
+ break
142
+ case 'info':
143
+ default: {
144
+ Logger.info(message)
145
+ if (data.additionalData !== undefined) Logger.info(util.inspect(data.additionalData))
146
+ }
147
+ }
148
+
149
+ if (data.notification) {
150
+ const log = {
151
+ uniqueId: externalData.uniqueId || ((data.request && data.request.customInfo) ? data.request.customInfo.uniqueId : null),
152
+ traceID: externalData.traceID || ((data.request && data.request.customInfo) ? data.request.customInfo.traceID : null),
153
+ resource: externalData.resource || (data.request ? { method: data.request.method, path: data.request.path } : null),
154
+ messageType: data.messageType,
155
+ notificationType: externalData.notificationType || 'newLog',
156
+ verbosity,
157
+ message,
158
+ additionalData: data.additionalData,
159
+ logTime: new Date()
160
+ }
161
+
162
+ let sessionID
163
+ const hostingEnabled = Config.getSystemConfig().HOSTING_ENABLED
164
+ if (hostingEnabled) {
165
+ if (!data.user && data.request && data.request.customInfo) {
166
+ data.user = data.request.customInfo.user
167
+ }
168
+ sessionID = data.user ? data.user.dfspId : null
169
+ } else {
170
+ sessionID = data.request && data.request.customInfo ? data.request.customInfo.sessionID : null
171
+ }
172
+
173
+ if (log.notificationType === 'newOutboundLog') {
174
+ NotificationEmitter.broadcastOutboundLog(log, sessionID)
175
+ } else {
176
+ NotificationEmitter.broadcastLog(log, sessionID)
177
+ }
178
+
179
+ if (hostingEnabled && data.user) {
180
+ DBAdapter.upsert('logs', log, data.user)
181
+ }
182
+ }
183
+ }
184
+
185
+ module.exports = {
186
+ logRequest,
187
+ logOutboundRequest,
188
+ logResponse,
189
+ logMessage
190
+ }
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDSTCCAjGgAwIBAgIEAoLQ/TANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJV
3
+ UzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxDTALBgNVBAoT
4
+ BFdTTzIxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xNzA3MTkwNjUyNTFaFw0yNzA3
5
+ MTcwNjUyNTFaMFUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMN
6
+ TW91bnRhaW4gVmlldzENMAsGA1UEChMEV1NPMjESMBAGA1UEAxMJbG9jYWxob3N0
7
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAluZFdW1ynitztkWLC6xK
8
+ egbRWxky+5P0p4ShYEOkHs30QI2VCuR6Qo4Bz5rTgLBrky03W1GAVrZxuvKRGj9V
9
+ 9+PmjdGtau4CTXu9pLLcqnruaczoSdvBYA3lS9a7zgFU0+s6kMl2EhB+rk7gXluE
10
+ ep7lIOenzfl2f6IoTKa2fVgVd3YKiSGsyL4tztS70vmmX121qm0sTJdKWP4HxXyq
11
+ K9neolXI9fYyHOYILVNZ69z/73OOVhkh/mvTmWZLM7GM6sApmyLX6OXUp8z0pkY+
12
+ vT/9+zRxxQs7GurC4/C1nK3rI/0ySUgGEafO1atNjYmlFN+M3tZX6nEcA6g94Iav
13
+ yQIDAQABoyEwHzAdBgNVHQ4EFgQUtS8kIYxQ8UVvVrZSdgyide9OHxUwDQYJKoZI
14
+ hvcNAQELBQADggEBABfk5mqsVUrpFCYTZZhOxTRRpGXqoW1G05bOxHxs42Paxw8r
15
+ AJ06Pty9jqM1CgRPpqvZa2lPQBQqZrHkdDE06q4NG0DqMH8NT+tNkXBe9YTre3EJ
16
+ CSfsvswtLVDZ7GDvTHKojJjQvdVCzRj6XH5Truwefb4BJz9APtnlyJIvjHk1hdoz
17
+ qyOniVZd0QOxLAbcdt946chNdQvCm6aUOputp8Xogr0KBnEy3U8es2cAfNZaEkPU
18
+ 8Va5bU6Xjny8zGQnXCXxPKp7sMpgO93nPBt/liX1qfyXM7xEotWoxmm6HZx8oWQ8
19
+ U5aiXjZ5RKDWCCq4ZuXl6wVsUz1iE61suO5yWi8=
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,95 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2025 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * Mojaloop Foundation
23
+ - Name Surname <name.surname@mojaloop.io>
24
+
25
+ * ModusBox
26
+ * Vijaya Kumar Guthi <vijaya.guthi@modusbox.com> (Original Author)
27
+ --------------
28
+ ******/
29
+
30
+ const { Engine } = require('json-rules-engine')
31
+ const customLogger = require('./requestLogger')
32
+
33
+ class RulesEngine {
34
+ constructor (config) {
35
+ this.config = config
36
+ this.init()
37
+ }
38
+
39
+ init () {
40
+ this.engine = new Engine()
41
+ this._addCustomOperators()
42
+ }
43
+
44
+ _addCustomOperators () {
45
+ this.engine.addOperator('numberStringLessThanInclusive', (a, b) => Number(a) <= b)
46
+ this.engine.addOperator('numberStringGreaterThanInclusive', (a, b) => Number(a) >= b)
47
+ this.engine.addOperator('numericEqual', (a, b) => Number(a) === Number(b))
48
+ this.engine.addOperator('numericNotEqual', (a, b) => Number(a) !== Number(b))
49
+ this.engine.addOperator('numericLessThan', (a, b) => Number(a) < Number(b))
50
+ this.engine.addOperator('numericGreaterThan', (a, b) => Number(a) > Number(b))
51
+ this.engine.addOperator('numericLessThanInclusive', (a, b) => Number(a) <= Number(b))
52
+ this.engine.addOperator('numericGreaterThanInclusive', (a, b) => Number(a) >= Number(b))
53
+ this.engine.addOperator('includesString', (a, b) => a.includes(b))
54
+ this.engine.addOperator('excludesString', (a, b) => !a.includes(b))
55
+ }
56
+
57
+ /**
58
+ * Loads an array of rules into the engine
59
+ *
60
+ * @param {object[]} rules - an array of rules to load into the engine
61
+ * @returns {undefined}
62
+ */
63
+ loadRules (rules, user) {
64
+ try {
65
+ this.init()
66
+ const rulesLength = rules.length
67
+ rules.forEach((r, index) => {
68
+ r.priority = rulesLength - index
69
+ this.engine.addRule(r)
70
+ })
71
+ } catch (err) {
72
+ customLogger.logMessage('error', 'Error loading rules ' + err, { notification: false })
73
+ throw err
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Runs the engine to evaluate facts
79
+ *
80
+ * @async
81
+ * @param {Object} facts facts to evalute
82
+ * @returns {Promise.<Object>} response
83
+ */
84
+ async evaluate (facts) {
85
+ return new Promise((resolve, reject) => {
86
+ this.engine
87
+ .run(facts)
88
+ .then((events) => {
89
+ return resolve(events.events.length === 0 ? null : events.events)
90
+ }).catch(reject)
91
+ })
92
+ }
93
+ }
94
+
95
+ module.exports = RulesEngine