@mojaloop/central-ledger 19.14.0 → 20.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 (394) hide show
  1. package/.grype.yaml +3 -0
  2. package/.license-scanner.json +16 -0
  3. package/.ncurc.yaml +19 -13
  4. package/.nvmrc +1 -1
  5. package/.nycrc.yml +14 -2
  6. package/CHANGELOG.md +51 -0
  7. package/Dockerfile +13 -10
  8. package/README.md +39 -89
  9. package/audit-ci.jsonc +1 -1
  10. package/config/default.json +60 -3
  11. package/config/deprecated.default-settlement.json +160 -0
  12. package/docker/ml-api-adapter/default.json +28 -0
  13. package/docker-compose.yml +6 -0
  14. package/nodemon.json +6 -0
  15. package/package.json +128 -64
  16. package/{sbom-v19.13.2.csv → sbom-v20.0.0.csv} +886 -736
  17. package/scripts/_wait4_all.js +5 -5
  18. package/scripts/transferSettlementTemp/interchangeFeeCalculation.js +51 -0
  19. package/src/api/index.ts +30 -0
  20. package/src/api/interface/swagger.json +2249 -2054
  21. package/src/api/participants/routes.js +1 -1
  22. package/src/api/root/handler.int.ts +55 -0
  23. package/src/api/routes.js +7 -6
  24. package/src/api/server.ts +27 -0
  25. package/src/api/server.unit.ts +16 -0
  26. package/src/api/settlementModels/routes.js +4 -4
  27. package/src/domain/participant/index.d.ts +47 -0
  28. package/src/domain/participant/index.int.ts +724 -0
  29. package/src/domain/participant/index.js +4 -5
  30. package/src/domain/position/fx-prepare.js +1 -1
  31. package/src/domain/position/fx-timeout-reserved.js +6 -0
  32. package/src/domain/position/prepare.js +1 -1
  33. package/src/handlers/admin/handler.js +1 -1
  34. package/src/handlers/index.js +30 -0
  35. package/src/handlers/positions/handler.js +0 -2
  36. package/src/handlers/positions/handlerBatch.js +5 -5
  37. package/src/handlers/register.js +44 -29
  38. package/src/handlers/timeouts/handler.js +1 -4
  39. package/src/handlers/transfers/fx-abort.int.ts +209 -0
  40. package/src/handlers/transfers/fx-handlers.int.ts +275 -0
  41. package/src/handlers/transfers/fx-timeout.int.ts +284 -0
  42. package/src/handlers/transfers/handler.js +1 -3
  43. package/src/handlers/transfers/handlers.int.ts +538 -0
  44. package/src/handlers/transfers/prepare.int.ts +1283 -0
  45. package/src/handlers/transfers/prepare.js +2 -2
  46. package/src/knexfile.js +19 -0
  47. package/src/lib/cache.js +1 -1
  48. package/src/lib/config/index.ts +60 -0
  49. package/src/lib/config/resolver.ts +231 -0
  50. package/src/lib/config/resolver.unit.ts +72 -0
  51. package/src/lib/config/types.ts +372 -0
  52. package/src/lib/config/util.ts +523 -0
  53. package/src/lib/config/util.unit.ts +825 -0
  54. package/src/lib/migrator.js +3 -3
  55. package/src/lib/proxyCache.js +3 -3
  56. package/{migrations → src/migrations}/100100_event.js +1 -1
  57. package/{migrations → src/migrations}/110100_contactType.js +1 -1
  58. package/{migrations → src/migrations}/110200_currency.js +1 -1
  59. package/{migrations → src/migrations}/110201_currency-scale.js +1 -1
  60. package/{migrations → src/migrations}/110300_endpointType.js +1 -1
  61. package/{migrations → src/migrations}/110400_ledgerEntryType.js +1 -1
  62. package/{migrations → src/migrations}/110450_ledgerAccountType.js +1 -1
  63. package/{migrations → src/migrations}/110500_participantLimitType.js +1 -1
  64. package/{migrations → src/migrations}/110600_transferParticipantRoleType.js +1 -1
  65. package/{migrations → src/migrations}/110700_transferState.js +1 -1
  66. package/{migrations → src/migrations}/110900_settlementState.js +1 -1
  67. package/{migrations → src/migrations}/112000_bulkTransferState.js +1 -1
  68. package/{migrations → src/migrations}/112100_bulkProcessingState.js +1 -1
  69. package/{migrations → src/migrations}/200100_participant.js +1 -1
  70. package/{migrations → src/migrations}/200200_participantContact.js +1 -1
  71. package/{migrations → src/migrations}/200300_participantEndpoint.js +1 -1
  72. package/{migrations → src/migrations}/200400_participantParty.js +1 -1
  73. package/{migrations → src/migrations}/200600_token.js +1 -1
  74. package/{migrations → src/migrations}/200601_token-indexes.js +1 -1
  75. package/{migrations → src/migrations}/300100_transferDuplicateCheck.js +2 -2
  76. package/{migrations → src/migrations}/300150_bulkTransferDuplicateCheck.js +2 -2
  77. package/{migrations → src/migrations}/300200_transfer.js +2 -2
  78. package/{migrations → src/migrations}/300202_transfer-decimal184.js +1 -1
  79. package/{migrations → src/migrations}/300250_bulkTransfer.js +2 -3
  80. package/{migrations → src/migrations}/300275_bulkTransferAssociation.js +2 -3
  81. package/{migrations → src/migrations}/300300_ilpPacket.js +1 -1
  82. package/{migrations → src/migrations}/300400_transferStateChange.js +1 -1
  83. package/{migrations → src/migrations}/300450_bulkTransferStateChange.js +1 -1
  84. package/{migrations → src/migrations}/300500_segment.js +1 -1
  85. package/{migrations → src/migrations}/310100_participantCurrency.js +1 -1
  86. package/{migrations → src/migrations}/310200_transferParticipant.js +1 -1
  87. package/{migrations → src/migrations}/310202_transferParticipant-decimal184.js +1 -1
  88. package/{migrations → src/migrations}/310204_transferParticipant-participantId.js +2 -2
  89. package/{migrations → src/migrations}/310300_participantPosition.js +1 -1
  90. package/{migrations → src/migrations}/310302_participantPosition-decimal184.js +1 -1
  91. package/{migrations → src/migrations}/310400_participantPositionChange.js +1 -1
  92. package/{migrations → src/migrations}/310402_participantPositionChange-decimal184.js +1 -1
  93. package/{migrations → src/migrations}/310403_participantPositionChange-participantCurrencyId.js +2 -2
  94. package/{migrations → src/migrations}/310404_participantPositionChange-change.js +2 -2
  95. package/{migrations → src/migrations}/310500_participantLimit.js +1 -1
  96. package/{migrations → src/migrations}/310502_participantLimit-decimal184.js +1 -1
  97. package/{migrations → src/migrations}/400100_settlementWindow.js +1 -1
  98. package/{migrations → src/migrations}/400200_settlement.js +1 -1
  99. package/{migrations → src/migrations}/400300_settlementSettlementWindow.js +1 -1
  100. package/{migrations → src/migrations}/400301_settlementSettlementWindow-indexes.js +0 -1
  101. package/{migrations → src/migrations}/400400_settlementWindowStateChange.js +1 -1
  102. package/{migrations → src/migrations}/400500_settlementTransferParticipant.js +1 -1
  103. package/{migrations → src/migrations}/400502_settlementTransferParticipant-decimal184.js +1 -1
  104. package/{migrations → src/migrations}/400600_settlementParticipantCurrency.js +1 -1
  105. package/{migrations → src/migrations}/400602_settlementParticipantCurrency-decimal184.js +1 -1
  106. package/{migrations → src/migrations}/400700_settlementParticipantCurrencyStateChange.js +1 -1
  107. package/{migrations → src/migrations}/400800_settlementStateChange.js +1 -1
  108. package/{migrations → src/migrations}/400900_settlementWindowContent.js +1 -1
  109. package/{migrations → src/migrations}/401000_settlementWindowContentStateChange.js +1 -1
  110. package/{migrations → src/migrations}/401001_settlementWindowContentStateChange-indexes.js +6 -6
  111. package/{migrations → src/migrations}/401200_settlementContentAggregation.js +1 -1
  112. package/{migrations → src/migrations}/401300_settlementModel.js +1 -1
  113. package/{migrations → src/migrations}/410100_transferFulfilmentDuplicateCheck.js +1 -1
  114. package/{migrations → src/migrations}/410102_transferFulfilmentDuplicateCheck-dropForeignTransferId.js +1 -1
  115. package/{migrations → src/migrations}/410103_transferFulfilmentDuplicateCheck-hashNullable.js +1 -1
  116. package/{migrations → src/migrations}/410200_transferFulfilment.js +1 -1
  117. package/{migrations → src/migrations}/410202_transferFulfilment-ilpFulfilment.js +1 -1
  118. package/{migrations → src/migrations}/410203_transferFulfilment-foreignTransferFulfilmentId.js +1 -1
  119. package/{migrations → src/migrations}/410240_bulkTransferFulfilmentDuplicateCheck.js +1 -1
  120. package/{migrations → src/migrations}/410250_bulkTransferFulfilment.js +1 -1
  121. package/{migrations → src/migrations}/410300_transferExtension.js +1 -1
  122. package/{migrations → src/migrations}/410302_transferExtension-transferErrorId.js +1 -1
  123. package/{migrations → src/migrations}/410350_bulkTransferExtension.js +1 -1
  124. package/{migrations → src/migrations}/410400_transferTimeout.js +1 -1
  125. package/{migrations → src/migrations}/410450_transferErrorDuplicateCheck.js +1 -1
  126. package/{migrations → src/migrations}/410500_transferError.js +1 -1
  127. package/{migrations → src/migrations}/410502_transferError-foreignTransferErrorDuplicateCheckId.js +1 -1
  128. package/{migrations → src/migrations}/410550_bulkTransferError.js +1 -1
  129. package/{migrations → src/migrations}/410600_expiringTransfer.js +1 -1
  130. package/{migrations → src/migrations}/500401_quote-hotfix-2719.js +8 -8
  131. package/{migrations → src/migrations}/500501_feature-fixSubIdRef.js +12 -12
  132. package/{migrations → src/migrations}/500601_party-2480.js +3 -3
  133. package/{migrations → src/migrations}/501001_quoteExtension-quote-service-174.js +1 -2
  134. package/{migrations → src/migrations}/501002_quoteExtension-2522.js +3 -3
  135. package/{migrations → src/migrations}/600010_fxTransferType.js +1 -1
  136. package/{migrations → src/migrations}/600012_fxParticipantCurrencyType.js +1 -1
  137. package/{migrations → src/migrations}/600100_fxTransferDuplicateCheck.js +2 -2
  138. package/{migrations → src/migrations}/600110_fxTransferErrorDuplicateCheck.js.js +1 -1
  139. package/{migrations → src/migrations}/600200_fxTransfer.js +2 -2
  140. package/{migrations → src/migrations}/600400_fxTransferStateChange.js +1 -1
  141. package/{migrations → src/migrations}/600501_fxWatchList.js +2 -2
  142. package/{migrations → src/migrations}/600600_fxTransferFulfilmentDuplicateCheck.js +1 -1
  143. package/{migrations → src/migrations}/600700_fxTransferFulfilment.js +1 -1
  144. package/{migrations → src/migrations}/600800_fxTransferExtension.js +1 -1
  145. package/{migrations → src/migrations}/601400_fxTransferTimeout.js +1 -1
  146. package/{migrations → src/migrations}/601500_fxTransferError.js +1 -1
  147. package/{migrations → src/migrations}/610200_fxTransferParticipant.js +1 -1
  148. package/{migrations → src/migrations}/610202_fxTransferParticipant-participantId.js +2 -2
  149. package/{migrations → src/migrations}/610403_participantPositionChange-fxTransfer.js +1 -1
  150. package/{migrations → src/migrations}/800100_quotePartyView.js +1 -1
  151. package/{migrations → src/migrations}/800101_feature-fixSubIdRef.js +1 -1
  152. package/{migrations → src/migrations}/800200_quoteView.js +1 -1
  153. package/{migrations → src/migrations}/800300_quoteResponseView.js +1 -1
  154. package/{migrations → src/migrations}/900100_foreign-keys.js +18 -18
  155. package/{migrations → src/migrations}/900101_foreign-keys.js +6 -6
  156. package/{migrations → src/migrations}/910100_feature904DDL.js +7 -7
  157. package/{migrations → src/migrations}/910101_feature904DataMigration.js +1 -1
  158. package/{migrations → src/migrations}/910102_feature949DataMigration.js +1 -1
  159. package/{migrations → src/migrations}/910103_feature1093SettlementByCurrency.js +3 -3
  160. package/{migrations → src/migrations}/940101_quotePartyIdInfoExtension-2522.js +25 -25
  161. package/{migrations → src/migrations}/950101_transferParticipantStateChange.js +2 -2
  162. package/{migrations → src/migrations}/950102_settlementModel-adjustPosition.js +2 -2
  163. package/{migrations → src/migrations}/950103_dropTransferParticipantStateChange.js +3 -3
  164. package/{migrations → src/migrations}/950104_settlementModel-settlementAccountTypeId.js +3 -3
  165. package/src/migrations/950107_settlementWindowContent_foreign_settlementModel.js +63 -0
  166. package/{migrations → src/migrations}/950108_participantProxy.js +1 -2
  167. package/{migrations → src/migrations}/950120_fxQuoteConversionTerms_sourceAmount_nullable.js +1 -1
  168. package/{migrations → src/migrations}/960100_create_externalParticipant.js +2 -2
  169. package/{migrations → src/migrations}/960110_alter_transferParticipant__addFiled_externalParticipantId.js +2 -2
  170. package/{migrations → src/migrations}/961001_transferForwarded.js +1 -1
  171. package/{migrations → src/migrations}/961002_fxTransferForwarded.js +1 -1
  172. package/src/models/participant/externalParticipant.int.ts +85 -0
  173. package/src/models/participant/facade.js +4 -2
  174. package/src/models/participant/participantCurrencyCached.js +1 -1
  175. package/src/models/position/facade.js +8 -2
  176. package/src/models/transfer/facade.int.ts +139 -0
  177. package/src/models/transfer/facade.js +8 -3
  178. package/src/models/transfer/transferDuplicateCheck.js +2 -2
  179. package/src/models/transfer/transferError.int.ts +112 -0
  180. package/src/models/transfer/transferExtension.int.ts +137 -0
  181. package/src/models/transfer/transferStateChange.int.ts +117 -0
  182. package/{seeds → src/seeds}/participant.js +1 -1
  183. package/{seeds → src/seeds}/settlementInterchange.js +1 -0
  184. package/src/settlement/api/handlerRoutes.js +71 -0
  185. package/src/settlement/api/handlers/health.js +10 -0
  186. package/src/settlement/api/handlers/index.js +57 -0
  187. package/src/settlement/api/handlers/settlementWindows/{id}.js +103 -0
  188. package/src/settlement/api/handlers/settlementWindows.js +77 -0
  189. package/src/settlement/api/handlers/settlements/{id}.js +133 -0
  190. package/src/settlement/api/handlers/settlements/{sid}/participants/{pid}/accounts/{aid}.js +127 -0
  191. package/src/settlement/api/handlers/settlements/{sid}/participants/{pid}.js +127 -0
  192. package/src/settlement/api/handlers/settlements.js +114 -0
  193. package/src/settlement/api/openapiRouting.js +87 -0
  194. package/src/settlement/api/routes.js +176 -0
  195. package/src/settlement/domain/rules/index.js +46 -0
  196. package/src/settlement/domain/settlement/index.js +405 -0
  197. package/src/settlement/domain/settlementWindow/index.js +117 -0
  198. package/src/settlement/domain/transactions/index.js +83 -0
  199. package/src/settlement/domain/transferSettlement/index.js +57 -0
  200. package/src/settlement/handlers/deferredSettlement/handler.js +180 -0
  201. package/src/settlement/handlers/grossSettlement/handler.js +180 -0
  202. package/src/settlement/handlers/index.js +101 -0
  203. package/src/settlement/handlers/register.js +92 -0
  204. package/src/settlement/handlers/rules/handler.js +164 -0
  205. package/src/settlement/interface/swagger-handler.json +34 -0
  206. package/src/settlement/interface/swagger.json +1560 -0
  207. package/src/settlement/lib/db.js +32 -0
  208. package/src/settlement/lib/kafka/index.js +41 -0
  209. package/src/settlement/lib/kafka/producer.js +142 -0
  210. package/src/settlement/lib/scriptEngine.js +99 -0
  211. package/src/settlement/lib/scriptsLoader.js +175 -0
  212. package/src/settlement/lib/utility.js +243 -0
  213. package/src/settlement/models/ilpPackets/ilpPacket.js +42 -0
  214. package/src/settlement/models/lib/enums.js +192 -0
  215. package/src/settlement/models/misc/migrationLock.js +53 -0
  216. package/src/settlement/models/settlement/facade.js +1652 -0
  217. package/src/settlement/models/settlement/index.js +55 -0
  218. package/src/settlement/models/settlement/participantCurrency.js +48 -0
  219. package/src/settlement/models/settlement/settlement.js +49 -0
  220. package/src/settlement/models/settlement/settlementModel.js +44 -0
  221. package/src/settlement/models/settlement/settlementParticipantCurrency.js +61 -0
  222. package/src/settlement/models/settlement/settlementStateChange.js +44 -0
  223. package/src/settlement/models/settlement/settlementTransferParticipant.js +46 -0
  224. package/src/settlement/models/settlementWindow/facade.js +345 -0
  225. package/src/settlement/models/settlementWindow/index.js +47 -0
  226. package/src/settlement/models/settlementWindow/settlementWindowStateChange.js +55 -0
  227. package/src/settlement/models/settlementWindowContent/facade.js +79 -0
  228. package/src/settlement/models/settlementWindowContent/index.js +40 -0
  229. package/src/settlement/models/settlementWindowContent/settlementWindowContentStateChange.js +53 -0
  230. package/src/settlement/models/transferSettlement/facade.js +363 -0
  231. package/src/settlement/models/transferSettlement/index.js +42 -0
  232. package/src/settlement/shared/logger/index.js +7 -0
  233. package/src/settlement/shared/plugins.js +88 -0
  234. package/src/settlement/shared/setup.js +224 -0
  235. package/src/settlement/utils/truthyProperty.js +37 -0
  236. package/src/shared/legacyUtilShim.js +20 -0
  237. package/src/shared/plugins.js +3 -3
  238. package/src/shared/results.ts +22 -0
  239. package/src/shared/results.unit.ts +38 -0
  240. package/src/shared/setup.js +14 -1
  241. package/src/testing/api-helpers.ts +1222 -0
  242. package/src/testing/exec-async.ts +67 -0
  243. package/src/testing/harness.snapshot.sql +3895 -0
  244. package/src/testing/harness.test.ts +15 -0
  245. package/src/testing/harness.ts +1160 -0
  246. package/src/testing/kafka.ts +221 -0
  247. package/src/testing/prng.ts +82 -0
  248. package/src/testing/rdkafka.test.ts +263 -0
  249. package/src/testing/run.ts +559 -0
  250. package/src/testing/snapshot.test.ts +92 -0
  251. package/src/testing/snapshot.ts +549 -0
  252. package/src/testing/tap-stream.ts +164 -0
  253. package/src/testing/types.ts +95 -0
  254. package/src/testing/util.ts +333 -0
  255. package/src/types/central-services-error-handling.d.ts +72 -0
  256. package/src/types/central-services-stream.d.ts +148 -0
  257. package/test-integration.Dockerfile +0 -2
  258. package/test.Dockerfile +0 -2
  259. package/tsconfig.json +40 -0
  260. package/config/knexfile.js +0 -19
  261. package/migrations/950107_settlementWindowContent_foreign_settlementModel.js +0 -63
  262. package/src/api/index.js +0 -16
  263. package/src/lib/config.js +0 -81
  264. /package/{migrations → src/migrations}/110101_contactType-indexes.js +0 -0
  265. /package/{migrations → src/migrations}/110301_endpointType-indexes.js +0 -0
  266. /package/{migrations → src/migrations}/110401_ledgerEntryType-indexes.js +0 -0
  267. /package/{migrations → src/migrations}/110451_ledgerAccountType-indexes.js +0 -0
  268. /package/{migrations → src/migrations}/110501_participantLimitType-indexes.js +0 -0
  269. /package/{migrations → src/migrations}/110601_transferParticipantRoleType-indexes.js +0 -0
  270. /package/{migrations → src/migrations}/110800_settlementWindowState.js +0 -0
  271. /package/{migrations → src/migrations}/111000_amountType.js +0 -0
  272. /package/{migrations → src/migrations}/111001_amountType-indexes.js +0 -0
  273. /package/{migrations → src/migrations}/111100_balanceOfPayments.js +0 -0
  274. /package/{migrations → src/migrations}/111101_balanceOfPayments-indexes.js +0 -0
  275. /package/{migrations → src/migrations}/111200_partyIdentifierType.js +0 -0
  276. /package/{migrations → src/migrations}/111201_partyIdentifierType-indexes.js +0 -0
  277. /package/{migrations → src/migrations}/111300_partyType.js +0 -0
  278. /package/{migrations → src/migrations}/111301_partyType-indexes.js +0 -0
  279. /package/{migrations → src/migrations}/111400_quoteDuplicateCheck.js +0 -0
  280. /package/{migrations → src/migrations}/111500_transactionInitiator.js +0 -0
  281. /package/{migrations → src/migrations}/111501_transactionInitiator-indexes.js +0 -0
  282. /package/{migrations → src/migrations}/111600_transactionInitiatorType.js +0 -0
  283. /package/{migrations → src/migrations}/111601_transactionInitiatorType-indexes.js +0 -0
  284. /package/{migrations → src/migrations}/111700_settlementDelay.js +0 -0
  285. /package/{migrations → src/migrations}/111701_settlementDelay-indexes.js +0 -0
  286. /package/{migrations → src/migrations}/111800_settlementInterchange.js +0 -0
  287. /package/{migrations → src/migrations}/111801_settlementInterchange-indexes.js +0 -0
  288. /package/{migrations → src/migrations}/111900_settlementGranularity.js +0 -0
  289. /package/{migrations → src/migrations}/111901_settlementGranularity-indexes.js +0 -0
  290. /package/{migrations → src/migrations}/112101_bulkProcessingState-indexes.js +0 -0
  291. /package/{migrations → src/migrations}/200101_participant-indexes.js +0 -0
  292. /package/{migrations → src/migrations}/200201_participantContact-indexes.js +0 -0
  293. /package/{migrations → src/migrations}/200301_participantEndpoint-indexes.js +0 -0
  294. /package/{migrations → src/migrations}/200401_participantParty-indexes.js +0 -0
  295. /package/{migrations → src/migrations}/300201_transfer-indexes.js +0 -0
  296. /package/{migrations → src/migrations}/300251_bulkTransfer-indexes.js +0 -0
  297. /package/{migrations → src/migrations}/300276_bulkTransferAssociation-indexes.js +0 -0
  298. /package/{migrations → src/migrations}/300401_transferStateChange-indexes.js +0 -0
  299. /package/{migrations → src/migrations}/300451_bulkTransferStateChange-indexes.js +0 -0
  300. /package/{migrations → src/migrations}/300501_segment-indexes.js +0 -0
  301. /package/{migrations → src/migrations}/310101_participantCurrency-indexes.js +0 -0
  302. /package/{migrations → src/migrations}/310201_transferParticipant-indexes.js +0 -0
  303. /package/{migrations → src/migrations}/310203_transferParticipant-indexes.js +0 -0
  304. /package/{migrations → src/migrations}/310301_participantPosition-indexes.js +0 -0
  305. /package/{migrations → src/migrations}/310401_participantPositionChange-indexes.js +0 -0
  306. /package/{migrations → src/migrations}/310405_participantPositionChange-positionChange.js +0 -0
  307. /package/{migrations → src/migrations}/310406_participantPositionChange-positionChange-revert.js +0 -0
  308. /package/{migrations → src/migrations}/310501_participantLimit-indexes.js +0 -0
  309. /package/{migrations → src/migrations}/310503_participantLimit-indexes-composite.js +0 -0
  310. /package/{migrations → src/migrations}/400401_settlmentWindowStateChange-indexes.js +0 -0
  311. /package/{migrations → src/migrations}/400501_settlementTransferParticipant-indexes.js +0 -0
  312. /package/{migrations → src/migrations}/400601_settlementParticipantCurrency-indexes.js +0 -0
  313. /package/{migrations → src/migrations}/400701_settlementParticipantCurrencyStateChange-indexes.js +0 -0
  314. /package/{migrations → src/migrations}/400801_settlementStateChange-indexes.js +0 -0
  315. /package/{migrations → src/migrations}/401002_settlementWindowContent-indexes.js +0 -0
  316. /package/{migrations → src/migrations}/401201_settlementContentAggregation-indexes.js +0 -0
  317. /package/{migrations → src/migrations}/401301_settlementModel-indexes.js +0 -0
  318. /package/{migrations → src/migrations}/410101_transferFulfilmentDuplicateCheck-indexes.js +0 -0
  319. /package/{migrations → src/migrations}/410201_transferFulfilment-indexes.js +0 -0
  320. /package/{migrations → src/migrations}/410301_transferExtension-indexes.js +0 -0
  321. /package/{migrations → src/migrations}/410351_bulkTransferExtension-indexes.js +0 -0
  322. /package/{migrations → src/migrations}/410401_transferTimeout-indexes.js +0 -0
  323. /package/{migrations → src/migrations}/410501_transferError-indexes.js +0 -0
  324. /package/{migrations → src/migrations}/410551_bulkTransferError-indexes.js +0 -0
  325. /package/{migrations → src/migrations}/410601_expiringTransfer-indexes.js +0 -0
  326. /package/{migrations → src/migrations}/500100_transactionReference.js +0 -0
  327. /package/{migrations → src/migrations}/500101_transactionReference-indexes.js +0 -0
  328. /package/{migrations → src/migrations}/500200_transactionScenario.js +0 -0
  329. /package/{migrations → src/migrations}/500201_transactionScenario-indexes.js +0 -0
  330. /package/{migrations → src/migrations}/500300_transactionSubScenario.js +0 -0
  331. /package/{migrations → src/migrations}/500400_quote.js +0 -0
  332. /package/{migrations → src/migrations}/500500_quoteParty.js +0 -0
  333. /package/{migrations → src/migrations}/500600_party.js +0 -0
  334. /package/{migrations → src/migrations}/500700_quoteResponse.js +0 -0
  335. /package/{migrations → src/migrations}/500800_quoteResponseIlpPacket.js +0 -0
  336. /package/{migrations → src/migrations}/500900_geoCode.js +0 -0
  337. /package/{migrations → src/migrations}/501000_quoteExtension.js +0 -0
  338. /package/{migrations → src/migrations}/501100_quoteResponseDuplicateCheck.js +0 -0
  339. /package/{migrations → src/migrations}/501200_quoteError.js +0 -0
  340. /package/{migrations → src/migrations}/501300_transferRules.js +0 -0
  341. /package/{migrations → src/migrations}/600011_fxTransferType-indexes.js +0 -0
  342. /package/{migrations → src/migrations}/600013_fxParticipantCurrencyType-indexes.js +0 -0
  343. /package/{migrations → src/migrations}/600201_fxTransfer-indexes.js +0 -0
  344. /package/{migrations → src/migrations}/600401_fxTransferStateChange-indexes.js +0 -0
  345. /package/{migrations → src/migrations}/600502_fxWatchList-indexes.js +0 -0
  346. /package/{migrations → src/migrations}/600601_fxTransferFulfilmentDuplicateCheck-indexes.js +0 -0
  347. /package/{migrations → src/migrations}/600701_fxTransferFulfilment-indexes.js +0 -0
  348. /package/{migrations → src/migrations}/601401_fxTransferTimeout-indexes.js +0 -0
  349. /package/{migrations → src/migrations}/601501_fxTransferError-indexes.js +0 -0
  350. /package/{migrations → src/migrations}/610201_fxTransferParticipant-indexes.js +0 -0
  351. /package/{migrations → src/migrations}/910102_hotfix954.js +0 -0
  352. /package/{migrations → src/migrations}/940100_quotePartyIdInfoExtension.js +0 -0
  353. /package/{migrations → src/migrations}/950100_settlementContentAggregation-decimal184.js +0 -0
  354. /package/{migrations → src/migrations}/950106_unique_settlement_model_ledger_account_currency.js +0 -0
  355. /package/{migrations → src/migrations}/950109_fxQuote.js +0 -0
  356. /package/{migrations → src/migrations}/950110_fxQuoteResponse.js +0 -0
  357. /package/{migrations → src/migrations}/950111_fxQuoteError.js +0 -0
  358. /package/{migrations → src/migrations}/950113_fxQuoteDuplicateCheck.js +0 -0
  359. /package/{migrations → src/migrations}/950114_fxQuoteResponseDuplicateCheck.js +0 -0
  360. /package/{migrations → src/migrations}/950115_fxQuoteConversionTerms.js +0 -0
  361. /package/{migrations → src/migrations}/950116_fxQuoteConversionTermsExtension.js +0 -0
  362. /package/{migrations → src/migrations}/950117_fxQuoteResponseConversionTerms.js +0 -0
  363. /package/{migrations → src/migrations}/950118_fxQuoteResponseConversionTermsExtension.js +0 -0
  364. /package/{migrations → src/migrations}/950119_fxCharge.js +0 -0
  365. /package/{migrations → src/migrations}/960111_alter_fxTransferParticipant__addFiled_externalParticipantId.js +0 -0
  366. /package/{migrations → src/migrations}/960112_fxTransfer-indexes2.js +0 -0
  367. /package/{migrations → src/migrations}/960113_fxTransferExtension-indexes.js +0 -0
  368. /package/{migrations → src/migrations}/960114_fxTransferTimeout-indexes2.js +0 -0
  369. /package/{migrations → src/migrations}/961000_participantEndpoint_unique.js +0 -0
  370. /package/{migrations → src/migrations}/migration.template +0 -0
  371. /package/{seeds → src/seeds}/amountType.js +0 -0
  372. /package/{seeds → src/seeds}/balanceOfPayments.js +0 -0
  373. /package/{seeds → src/seeds}/bulkProcessingState.js +0 -0
  374. /package/{seeds → src/seeds}/bulkTransferState.js +0 -0
  375. /package/{seeds → src/seeds}/currency.js +0 -0
  376. /package/{seeds → src/seeds}/endpointType.js +0 -0
  377. /package/{seeds → src/seeds}/fxParticipantCurrencyType.js +0 -0
  378. /package/{seeds → src/seeds}/fxTransferType.js +0 -0
  379. /package/{seeds → src/seeds}/ledgerAccountType.js +0 -0
  380. /package/{seeds → src/seeds}/ledgerEntryType.js +0 -0
  381. /package/{seeds → src/seeds}/participantLimitType.js +0 -0
  382. /package/{seeds → src/seeds}/partyIdentifierType.js +0 -0
  383. /package/{seeds → src/seeds}/partyType.js +0 -0
  384. /package/{seeds → src/seeds}/settlementDelay.js +0 -0
  385. /package/{seeds → src/seeds}/settlementGranularity.js +0 -0
  386. /package/{seeds → src/seeds}/settlementState.js +0 -0
  387. /package/{seeds → src/seeds}/settlementWindow1State.js +0 -0
  388. /package/{seeds → src/seeds}/settlementWindow2Open.js +0 -0
  389. /package/{seeds → src/seeds}/transactionInitiator.js +0 -0
  390. /package/{seeds → src/seeds}/transactionInitiatorType.js +0 -0
  391. /package/{seeds → src/seeds}/transactionScenario.js +0 -0
  392. /package/{seeds → src/seeds}/transferParticipantRoleType.js +0 -0
  393. /package/{seeds → src/seeds}/transferState.js +0 -0
  394. /package/{seeds → src/seeds}/z1000_settlementModel-deprecated.js- +0 -0
@@ -0,0 +1,559 @@
1
+ import assert from 'node:assert'
2
+ import { spawn, spawnSync } from 'node:child_process'
3
+ import path from 'node:path'
4
+ import process from 'node:process'
5
+ import test, { run } from "node:test"
6
+ import { tap, spec } from 'node:test/reporters'
7
+ import Harness from './harness'
8
+ import { mergeTapStreams } from './tap-stream'
9
+ import { ResultTest, RunTask, RunTaskCoverage, RunTaskIntegration, RunTaskUnit, TagTask } from './types'
10
+ import { convertToXunit, findFiles } from './util'
11
+ import { finished, pipeline } from 'node:stream/promises'
12
+
13
+ /**
14
+ * @file run.ts
15
+ * @description Single entrypoint for running unit tests, coverage checks, integration tests.
16
+ */
17
+
18
+ export const PROJECT_ROOT = path.resolve(__dirname, '../..')
19
+
20
+ // Local binaries.
21
+ export const NYC_BIN = path.join(PROJECT_ROOT, 'node_modules/.bin/nyc')
22
+ export const TAPE_BIN = path.join(PROJECT_ROOT, 'node_modules/.bin/tape')
23
+ export const TAP_XUNIT_BIN = path.join(PROJECT_ROOT, 'node_modules/.bin/tap-xunit')
24
+
25
+ /**
26
+ * @function exitWhenStdoutFlushed
27
+ * @description Exit the process only once everything already queued on stdout has actually been
28
+ * written. `process.exit()` is synchronous, but writes to a non-TTY stdout (e.g. when piped into
29
+ * `tap-spec`) are not - calling it right after a large `console.log`/`write` can truncate that
30
+ * write mid-flight. Queuing an empty write and exiting in its callback guarantees everything
31
+ * enqueued before it has already drained, since a writable stream processes writes in order.
32
+ */
33
+ function exitWhenStdoutFlushed(code: number): void {
34
+ process.stdout.write('', () => process.exit(code))
35
+ }
36
+
37
+ async function main() {
38
+ try {
39
+ const task = parseOptions(process.argv.slice(2), process.env)
40
+ switch (task.tag) {
41
+ case 'TEST_UNIT': {
42
+ const result = await runUnitTests(task)
43
+ exitWhenStdoutFlushed(result.exitCode)
44
+ break
45
+ }
46
+ case 'TEST_COVERAGE': {
47
+ await runCoverage(task)
48
+ if (task.onlyReport) {
49
+ exitWhenStdoutFlushed(0)
50
+ }
51
+ return
52
+ }
53
+ case 'TEST_INTEGRATION': {
54
+ const result = await runIntegrationTests(task)
55
+ exitWhenStdoutFlushed(result.exitCode)
56
+ break
57
+ }
58
+ }
59
+ } catch (err: any) {
60
+ console.log('Error:', err.message)
61
+ console.log(usage)
62
+ }
63
+ }
64
+
65
+ /**
66
+ * @function runUnitTests
67
+ * @description Run the unit tests based on the RunTaskUnit settings.
68
+ */
69
+ async function runUnitTests(task: RunTaskUnit): Promise<ResultTest> {
70
+ let results: ResultTest
71
+ switch (task.type) {
72
+ case 'TAPE':
73
+ console.error('==== Running Legacy (Tape) unit tests ====')
74
+ results = await runUnitTestsTape()
75
+ break
76
+ case 'NATIVE':
77
+ console.error('==== Running New (Native) unit tests ====')
78
+ results = await runUnitTestsNative()
79
+ break
80
+ case 'BOTH': {
81
+ // Run both suites silently (only accumulating their output, not relaying it live) because
82
+ // each one emits its own separate "TAP version 13" document. Concatenating two raw TAP
83
+ // documents on stdout is not valid TAP, and Node's native-test TAP dialect (nested
84
+ // subtests, large stack-trace diagnostics) crashes older TAP consumers like tap-spec
85
+ // outright - which then throws EPIPE back into this process when it keeps writing to a
86
+ // closed pipe. mergeTapStreams() below produces the one valid, flattened TAP document
87
+ // that should actually reach stdout.
88
+ console.error('==== Running Legacy (Tape) unit tests ====')
89
+ const resultsTape = await runUnitTestsTape({ silent: true })
90
+ assert(resultsTape.exitCode !== null, 'Encountered unknown error when runUnitTestsTape().')
91
+ console.error('==== Running New (Native) unit tests ====')
92
+ const resultsNative = await runUnitTestsNative({ silent: true })
93
+ assert(resultsNative.exitCode !== null, 'Encountered unknown error when runUnitTestsNative().')
94
+
95
+ const outputMerged = mergeTapStreams(resultsTape.output, resultsNative.output)
96
+ const exitCodeMerged = [resultsTape, resultsNative].reduce((acc, result) => {
97
+ assert(result.exitCode !== null)
98
+ return acc > 0 ? acc : result.exitCode
99
+ }, 0)
100
+
101
+ console.log(outputMerged)
102
+
103
+ results = {
104
+ output: outputMerged,
105
+ exitCode: exitCodeMerged
106
+ }
107
+ break
108
+ }
109
+ }
110
+
111
+ if (task.output === 'XUNIT') {
112
+ assert(task.outputPath, 'expected outputPath to be defined')
113
+
114
+ // Export to xunit.
115
+ await convertToXunit(results.output, task.outputPath)
116
+ }
117
+
118
+ return results
119
+ }
120
+
121
+ /**
122
+ * @function runCoverage
123
+ * @description Run the unit tests while collecting coverage, and produce the coverage report.
124
+ * See: https://github.com/istanbuljs/nyc#combining-reports-from-multiple-runs to understand the
125
+ * approach here.
126
+ */
127
+ async function runCoverage(task: RunTaskCoverage): Promise<void> {
128
+ switch (task.type) {
129
+ case 'TAPE':
130
+ runCoverageTape({ silent: false, noClean: false })
131
+ break
132
+ case 'NATIVE':
133
+ runCoverageNative({ silent: false, noClean: false })
134
+ break
135
+ case 'BOTH':
136
+ // First run native check, but don't cleanup so we accumulate coverage between runs.
137
+ runCoverageTape({ silent: true, noClean: false })
138
+ runCoverageNative({ silent: true, noClean: true })
139
+ // Generate combined report.
140
+ spawnSync(NYC_BIN, ['report', '--reporter=lcov', '--reporter=text-summary'], {
141
+ cwd: PROJECT_ROOT,
142
+ stdio: 'inherit'
143
+ })
144
+ break
145
+ }
146
+
147
+ // Check coverage thresholds unless --only-report was specified.
148
+ if (!task.onlyReport) {
149
+ const checkResult = spawnSync(NYC_BIN, ['check-coverage'], {
150
+ cwd: PROJECT_ROOT,
151
+ stdio: 'inherit'
152
+ })
153
+ if (checkResult.status !== 0) {
154
+ process.exit(checkResult.status ?? 1)
155
+ }
156
+ }
157
+ }
158
+
159
+ type NycOptions = {
160
+ silent: boolean
161
+ noClean: boolean
162
+ }
163
+
164
+ /**
165
+ * @function runCoverageTape
166
+ * @description Run legacy tape tests under nyc coverage.
167
+ */
168
+ function runCoverageTape(opts: NycOptions): void {
169
+ const testFiles = findFiles(
170
+ path.join(PROJECT_ROOT, 'test/unit'),
171
+ '**/*.test.js'
172
+ ).map(file => path.join(PROJECT_ROOT, 'test/unit', file))
173
+
174
+ if (testFiles.length === 0) {
175
+ console.warn(`runCoverageTape() - no test files found.`)
176
+ return
177
+ }
178
+
179
+ const nycArgs: string[] = []
180
+ if (opts.silent) nycArgs.push('--silent')
181
+ if (opts.noClean) nycArgs.push('--no-clean')
182
+ if (!opts.silent) nycArgs.push('--reporter=lcov', '--reporter=text-summary')
183
+
184
+ const args = [...nycArgs, '--', TAPE_BIN, ...testFiles]
185
+ const result = spawnSync(NYC_BIN, args, {
186
+ cwd: PROJECT_ROOT,
187
+ stdio: 'inherit',
188
+ env: {
189
+ ...process.env,
190
+ NODE_OPTIONS: '-r ts-node/register'
191
+ }
192
+ })
193
+
194
+ if (result.error) {
195
+ console.error('Failed to run tape tests with coverage:', result.error.message)
196
+ process.exit(1)
197
+ }
198
+ }
199
+
200
+ /**
201
+ * @function runCoverageNative
202
+ * @description Run native Node.js tests under nyc coverage.
203
+ */
204
+ function runCoverageNative(opts: NycOptions): void {
205
+ const testFiles = findFiles(
206
+ path.join(PROJECT_ROOT, 'src'),
207
+ '**/*.unit.ts'
208
+ ).map(f => path.join(PROJECT_ROOT, 'src', f))
209
+
210
+ if (testFiles.length === 0) {
211
+ console.warn(`runCoverageNative() - no test files found.`)
212
+ return
213
+ }
214
+
215
+ const nycArgs: string[] = []
216
+ if (opts.silent) nycArgs.push('--silent')
217
+ if (opts.noClean) nycArgs.push('--no-clean')
218
+ if (!opts.silent) nycArgs.push('--reporter=lcov', '--reporter=text-summary')
219
+
220
+ const args = [
221
+ ...nycArgs,
222
+ '--',
223
+ process.execPath,
224
+ '--require', 'ts-node/register',
225
+ '--test',
226
+ '--test-reporter=tap',
227
+ ...testFiles
228
+ ]
229
+ const result = spawnSync(NYC_BIN, args, {
230
+ cwd: PROJECT_ROOT,
231
+ stdio: 'inherit',
232
+ env: process.env
233
+ })
234
+
235
+ if (result.error) {
236
+ console.error('Failed to run native tests with coverage:', result.error.message)
237
+ process.exit(1)
238
+ }
239
+ }
240
+
241
+ /**
242
+ * @function runUnitTestsTape
243
+ * @description Run the legacy unit tests written with tape.
244
+ */
245
+ async function runUnitTestsTape(opts: { silent?: boolean } = {}): Promise<ResultTest> {
246
+ return new Promise((resolve) => {
247
+ const testFiles = findFiles(
248
+ path.join(PROJECT_ROOT, 'test/unit'),
249
+ '**/*.test.js'
250
+ )
251
+ .map(file => path.join(PROJECT_ROOT, 'test/unit', file))
252
+
253
+
254
+ if (testFiles.length === 0) {
255
+ console.warn(`runUnitTestsTape() - no test files found.`)
256
+ resolve({ output: '', exitCode: 0 })
257
+ return
258
+ }
259
+
260
+ // Run node directly with tape module to allow debugging.
261
+ const tapeEntry = path.join(PROJECT_ROOT, 'node_modules/tape/bin/tape')
262
+ const proc = spawn(process.execPath, [
263
+ '-r', 'ts-node/register',
264
+ '--inspect',
265
+ tapeEntry,
266
+ ...testFiles
267
+ ], {
268
+ cwd: PROJECT_ROOT,
269
+ env: {
270
+ ...process.env,
271
+ NODE_OPTIONS: '-r ts-node/register'
272
+ },
273
+ stdio: ['inherit', 'pipe', 'pipe']
274
+ })
275
+
276
+ let output = ''
277
+ proc.stdout.on('data', (data: Buffer) => {
278
+ const chunk = data.toString()
279
+ output += chunk
280
+ if (!opts.silent) process.stdout.write(chunk)
281
+ })
282
+
283
+ proc.stderr.on('data', (data: Buffer) => {
284
+ process.stderr.write(data)
285
+ })
286
+
287
+ proc.on('close', (code) => {
288
+ resolve({ output, exitCode: code })
289
+ })
290
+
291
+ proc.on('error', (err) => {
292
+ console.error('Failed to run legacy tests:', err.message)
293
+ resolve({ output: '', exitCode: 1 })
294
+ })
295
+ })
296
+ }
297
+
298
+ /**
299
+ * @function runUnitTestsNative
300
+ * @description Run the unit tests with the native nodejs test suite.
301
+ */
302
+ async function runUnitTestsNative(opts: { silent?: boolean } = {}): Promise<ResultTest> {
303
+ return new Promise((resolve) => {
304
+ const testFiles = findFiles(
305
+ path.join(PROJECT_ROOT, 'src'),
306
+ '**/*.unit.ts'
307
+ ).map(f => path.join(PROJECT_ROOT, 'src', f))
308
+
309
+ if (testFiles.length === 0) {
310
+ resolve({ output: '', exitCode: 0 })
311
+ return
312
+ }
313
+
314
+ const proc = spawn(process.execPath, [
315
+ '--require', 'ts-node/register',
316
+ '--test',
317
+ '--test-reporter=tap',
318
+ ...testFiles
319
+ ], {
320
+ cwd: PROJECT_ROOT,
321
+ env: process.env,
322
+ stdio: ['inherit', 'pipe', 'pipe']
323
+ })
324
+
325
+ let output = ''
326
+ proc.stdout.on('data', (data: Buffer) => {
327
+ const chunk = data.toString()
328
+ output += chunk
329
+ if (!opts.silent) process.stdout.write(chunk)
330
+ })
331
+
332
+ proc.stderr.on('data', (data: Buffer) => {
333
+ process.stderr.write(data)
334
+ })
335
+
336
+ proc.on('close', (code) => {
337
+ resolve({ output, exitCode: code })
338
+ })
339
+
340
+ proc.on('error', (err) => {
341
+ console.error('Failed to run native tests:', err.message)
342
+ resolve({ output: '', exitCode: 1 })
343
+ })
344
+ })
345
+ }
346
+
347
+ /**
348
+ * @function runIntegrationTests
349
+ * @description Runs the integration tests with the native nodejs test suite.
350
+ */
351
+ async function runIntegrationTests(task: RunTaskIntegration): Promise<ResultTest> {
352
+ const files = findFiles(
353
+ path.join(PROJECT_ROOT, 'src'),
354
+ '**/*.int.ts'
355
+ ).map(f => path.join(PROJECT_ROOT, 'src', f))
356
+
357
+ if (files.length === 0) {
358
+ return { output: '', exitCode: 0 }
359
+ }
360
+
361
+ let exitCode = 0
362
+
363
+ process.once('uncaughtException', async (err) => {
364
+ console.error(`Uncaught exception:`, err)
365
+ process.exit(1)
366
+ })
367
+
368
+ process.once('unhandledRejection', async (err) => {
369
+ console.error(`Unhandled rejection:`, err)
370
+ process.exit(1)
371
+ })
372
+
373
+ const testStream = run({
374
+ files,
375
+ // Run each test file in a separate process.
376
+ isolation: 'process',
377
+ // Tweak this depending on what resources we have.
378
+ concurrency: 2,
379
+ })
380
+ .on('test:fail', () => {
381
+ exitCode = 1
382
+ })
383
+
384
+ const tapStream = testStream.compose(spec)
385
+ tapStream.pipe(process.stdout)
386
+ await finished(testStream)
387
+
388
+ // TODO: figure out how to export to xml to be compatible with circleci.
389
+
390
+ return {
391
+ output: '',
392
+ exitCode
393
+ }
394
+ }
395
+
396
+ const parseUnitTestOptions = (args: Array<string>): Omit<RunTaskUnit, 'tag'> => {
397
+ let type = 'BOTH' as RunTaskUnit['type']
398
+ let output = 'DEFAULT' as RunTaskUnit['output']
399
+ let outputPath = undefined
400
+ args.forEach(arg => {
401
+ const matchType = arg.match(/--type=(.*)$/)
402
+ if (matchType) {
403
+ assert(matchType.length >= 2)
404
+ switch (matchType[1]) {
405
+ case 'tape': type = 'TAPE'; return
406
+ case 'native': type = 'NATIVE'; return
407
+ case 'both': type = 'BOTH'; return
408
+ default: {
409
+ throw new Error(`Invalid --type=${matchType[1]}, expected: tape | native | both`)
410
+ }
411
+ }
412
+ }
413
+
414
+ const matchOutput = arg.match(/^--output=(.*)$/)
415
+ if (matchOutput) {
416
+ assert(matchOutput.length >= 2)
417
+ switch (matchOutput[1]) {
418
+ case 'default': output = 'DEFAULT'; return
419
+ case 'xunit': output = 'XUNIT'; return
420
+ default: {
421
+ throw new Error(`Invalid --output=${matchOutput[1]}, expected: default | xunit`)
422
+ }
423
+ }
424
+ }
425
+
426
+ const matchOutputPath = arg.match(/^--outputPath=(.*)$/)
427
+ if (matchOutputPath) {
428
+ assert(matchOutputPath.length >= 2)
429
+ outputPath = matchOutputPath[1]
430
+ assert(typeof outputPath === 'string')
431
+ return
432
+ }
433
+
434
+ throw new Error(`unhandled arg: ${arg}`)
435
+ })
436
+
437
+ // Validate options.
438
+ if (output === 'XUNIT' && !outputPath) {
439
+ throw new Error('Validation error:\n Required: `--outputPath` when `--output=xunit`.')
440
+ }
441
+
442
+ return { type, output, outputPath }
443
+ }
444
+
445
+ const parseCoverageOptions = (args: Array<string>): Omit<RunTaskCoverage, 'tag'> => {
446
+ let type = 'BOTH' as RunTaskUnit['type']
447
+ let onlyReport = false
448
+ args.forEach(arg => {
449
+ const matchType = arg.match(/--type=(.*)$/)
450
+ if (matchType) {
451
+ assert(matchType.length >= 2)
452
+ switch (matchType[1]) {
453
+ case 'tape': type = 'TAPE'; return
454
+ case 'native': type = 'NATIVE'; return
455
+ case 'both': type = 'BOTH'; return
456
+ default: {
457
+ throw new Error(`Invalid --type=${matchType[1]}, expected: tape | native | both .`)
458
+ }
459
+ }
460
+ }
461
+
462
+ if (arg.match(/^--only-report$/)) {
463
+ onlyReport = true
464
+ return
465
+ }
466
+
467
+ throw new Error(`unhandled arg: ${arg}. Supported args for coverage are:\n --type=[tape|native|both]\n --only-report .`)
468
+ })
469
+
470
+ return {
471
+ type,
472
+ onlyReport
473
+ }
474
+ }
475
+
476
+ const parseIntegrationOptions = (args: Array<string>): Omit<RunTaskIntegration, 'tag'> => {
477
+ return {
478
+
479
+ }
480
+ }
481
+
482
+ function parseOptions(args: Array<string>, _env: NodeJS.ProcessEnv): RunTask {
483
+ assert(args.length > 0, 'expected at least one arg.')
484
+ const taskCommand = args.shift()
485
+ let tag: TagTask
486
+
487
+ switch (taskCommand) {
488
+ case 'unit': {
489
+ tag = 'TEST_UNIT'
490
+ const options = parseUnitTestOptions(args)
491
+
492
+ return {
493
+ tag,
494
+ ...options,
495
+ }
496
+ }
497
+ case 'coverage': {
498
+ tag = 'TEST_COVERAGE'
499
+ const options = parseCoverageOptions(args)
500
+
501
+ return {
502
+ tag,
503
+ ...options
504
+ }
505
+ }
506
+ case 'integration': {
507
+ tag = 'TEST_INTEGRATION'
508
+ const options = parseIntegrationOptions(args)
509
+
510
+ return {
511
+ tag,
512
+ ...options
513
+ }
514
+ }
515
+ case 'functional': {
516
+ throw new Error(`'${taskCommand}' not implemented.`)
517
+ }
518
+ default: {
519
+ throw new Error(`'${taskCommand}' not found.`)
520
+ }
521
+ }
522
+ }
523
+
524
+ const usage = `
525
+ Usage:
526
+
527
+ ./testing/run.ts [unit | coverage | integration | functional]\n\n\
528
+ 'unit' : Run the unit tests.
529
+ 'coverage' : Run the unit tests then check coverage.
530
+ 'integration' : Run the integration tests.
531
+ 'functional' : *Preview - not yet implemented* Run the functional tests.
532
+
533
+
534
+ Examples:
535
+
536
+ # Run the unit tests.
537
+ ./testing/run.ts unit
538
+
539
+ # Run only the the legacy tape tests.
540
+ ./testing/run.ts unit --type=tape
541
+
542
+ # Run all the tests, outputting xunit
543
+ ./testing/run.ts unit --output=xunit
544
+
545
+ # Run the unit tests then check for coverage (will exit != 0 if it fails.)
546
+ ./testing/run.ts coverage
547
+
548
+ # Run coverage report only (don't check thresholds)
549
+ ./testing/run.ts coverage --only-report
550
+
551
+ # Run all of the integration tests.
552
+ ./testing/run.ts integration
553
+
554
+ `
555
+
556
+ main().catch((error) => {
557
+ console.error(error)
558
+ process.exit(1)
559
+ })
@@ -0,0 +1,92 @@
1
+ import { describe, it } from "node:test";
2
+ import { Snapshot, SnapshotRange } from "./snapshot";
3
+ import assert from "node:assert";
4
+
5
+ /**
6
+ * This is an example test for how the snapshot testing library works.
7
+ */
8
+ describe('snapshot smoke test', () => {
9
+ it('updates the snapshot', () => {
10
+ const result = {
11
+ a: true,
12
+ b: {
13
+ icecream: 'yummy21'
14
+ },
15
+ c: new Date()
16
+ }
17
+
18
+ Snapshot.from(`{
19
+ "a": true,
20
+ "b": {
21
+ "icecream": "yummy21"
22
+ },
23
+ "c": ":ignore"
24
+ }`).checkStringUnwrap(JSON.stringify(result, null, 2))
25
+ })
26
+ })
27
+
28
+ describe('replaceSnapshot()', () => {
29
+ it('replaces the old snapshot with the new', () => {
30
+ const contents = '\n\nSnapshot.from(\`{\n "a": true,\n "c": ":ignore"\n }\n `).checkStringUnwrap(JSON.stringify(result, null, 2))'
31
+ const range = Snapshot._snapshotRange(contents, 3)
32
+ const newSnapshot = '\`{\n "a": true,\n "c": ":ignore"\n}\n`'
33
+ const expected = '\n\nSnapshot.from(\`{\n "a": true,\n "c": ":ignore"\n }\n `).checkStringUnwrap(JSON.stringify(result, null, 2))'
34
+ const actual = Snapshot._replaceSnapshot(contents, range, newSnapshot)
35
+
36
+ assert.equal(actual, expected)
37
+ })
38
+ })
39
+
40
+ describe('snapshotRange()', () => {
41
+ it('snapshotRange() gets the range inbetween ``', () => {
42
+ check('\n`thing`\n', 2, {start: 2, end: 8, indent: 0})
43
+
44
+ check('aaa`thingbbb`ccc', 1, {start: 4, end: 13, indent: 0})
45
+ checkSplit('aaa`thingbbb`ccc', 1, ['aaa', '`thingbbb`', 'ccc'])
46
+
47
+ check('\nblabla\n `{\n "a": true,\n "b": {\n "icecream": "yummy"\n },\n "c": ":ignore"\n }\n `', 3, {start: 15, end: 116, indent: 4} )
48
+ checkSplit(
49
+ '\nblabla\n `{\n "a": true,\n "b": {\n "icecream": "yummy"\n },\n "c": ":ignore"\n }\n `',
50
+ 3,
51
+ [
52
+ '\nblabla\n ',
53
+ '`{\n "a": true,\n "b": {\n "icecream": "yummy"\n },\n "c": ":ignore"\n }\n `',
54
+ '',
55
+ ]
56
+ )
57
+
58
+ check(
59
+ `Snapshot.from(\`{
60
+ "a": true,
61
+ "b": {
62
+ "icecream": "yummy"
63
+ },
64
+ "c": ":ignore"
65
+ }\`).checkStringUnwrap(JSON.stringify(result, null, 2))`
66
+ , 1, {start: 15, end: 111, indent: 4})
67
+
68
+ check(
69
+ `Snapshot.from(\`{
70
+ "a": true,
71
+ "c": ":ignore"
72
+ }
73
+ \`).checkStringUnwrap(JSON.stringify(result, null, 2))`
74
+ , 1, {start: 15, end: 66, indent: 4})
75
+ })
76
+
77
+ const check = (input: string, startLine: number, expected: SnapshotRange) => {
78
+ const result = Snapshot._snapshotRange(input, startLine)
79
+ assert.deepEqual(result, expected)
80
+ }
81
+
82
+ const checkSplit = (input: string, startLine: number, expect: [string, string, string]) => {
83
+ const result = Snapshot._snapshotRange(input, startLine)
84
+ const head = input.slice(0, result.start - 1)
85
+ const body = input.slice(result.start - 1, result.end)
86
+ const tail = input.slice(result.end)
87
+
88
+ assert.equal(head, expect[0])
89
+ assert.equal(body, expect[1])
90
+ assert.equal(tail, expect[2])
91
+ }
92
+ })