@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.
- package/.grype.yaml +3 -0
- package/.license-scanner.json +16 -0
- package/.ncurc.yaml +19 -13
- package/.nvmrc +1 -1
- package/.nycrc.yml +14 -2
- package/CHANGELOG.md +51 -0
- package/Dockerfile +13 -10
- package/README.md +39 -89
- package/audit-ci.jsonc +1 -1
- package/config/default.json +60 -3
- package/config/deprecated.default-settlement.json +160 -0
- package/docker/ml-api-adapter/default.json +28 -0
- package/docker-compose.yml +6 -0
- package/nodemon.json +6 -0
- package/package.json +128 -64
- package/{sbom-v19.13.2.csv → sbom-v20.0.0.csv} +886 -736
- package/scripts/_wait4_all.js +5 -5
- package/scripts/transferSettlementTemp/interchangeFeeCalculation.js +51 -0
- package/src/api/index.ts +30 -0
- package/src/api/interface/swagger.json +2249 -2054
- package/src/api/participants/routes.js +1 -1
- package/src/api/root/handler.int.ts +55 -0
- package/src/api/routes.js +7 -6
- package/src/api/server.ts +27 -0
- package/src/api/server.unit.ts +16 -0
- package/src/api/settlementModels/routes.js +4 -4
- package/src/domain/participant/index.d.ts +47 -0
- package/src/domain/participant/index.int.ts +724 -0
- package/src/domain/participant/index.js +4 -5
- package/src/domain/position/fx-prepare.js +1 -1
- package/src/domain/position/fx-timeout-reserved.js +6 -0
- package/src/domain/position/prepare.js +1 -1
- package/src/handlers/admin/handler.js +1 -1
- package/src/handlers/index.js +30 -0
- package/src/handlers/positions/handler.js +0 -2
- package/src/handlers/positions/handlerBatch.js +5 -5
- package/src/handlers/register.js +44 -29
- package/src/handlers/timeouts/handler.js +1 -4
- package/src/handlers/transfers/fx-abort.int.ts +209 -0
- package/src/handlers/transfers/fx-handlers.int.ts +275 -0
- package/src/handlers/transfers/fx-timeout.int.ts +284 -0
- package/src/handlers/transfers/handler.js +1 -3
- package/src/handlers/transfers/handlers.int.ts +538 -0
- package/src/handlers/transfers/prepare.int.ts +1283 -0
- package/src/handlers/transfers/prepare.js +2 -2
- package/src/knexfile.js +19 -0
- package/src/lib/cache.js +1 -1
- package/src/lib/config/index.ts +60 -0
- package/src/lib/config/resolver.ts +231 -0
- package/src/lib/config/resolver.unit.ts +72 -0
- package/src/lib/config/types.ts +372 -0
- package/src/lib/config/util.ts +523 -0
- package/src/lib/config/util.unit.ts +825 -0
- package/src/lib/migrator.js +3 -3
- package/src/lib/proxyCache.js +3 -3
- package/{migrations → src/migrations}/100100_event.js +1 -1
- package/{migrations → src/migrations}/110100_contactType.js +1 -1
- package/{migrations → src/migrations}/110200_currency.js +1 -1
- package/{migrations → src/migrations}/110201_currency-scale.js +1 -1
- package/{migrations → src/migrations}/110300_endpointType.js +1 -1
- package/{migrations → src/migrations}/110400_ledgerEntryType.js +1 -1
- package/{migrations → src/migrations}/110450_ledgerAccountType.js +1 -1
- package/{migrations → src/migrations}/110500_participantLimitType.js +1 -1
- package/{migrations → src/migrations}/110600_transferParticipantRoleType.js +1 -1
- package/{migrations → src/migrations}/110700_transferState.js +1 -1
- package/{migrations → src/migrations}/110900_settlementState.js +1 -1
- package/{migrations → src/migrations}/112000_bulkTransferState.js +1 -1
- package/{migrations → src/migrations}/112100_bulkProcessingState.js +1 -1
- package/{migrations → src/migrations}/200100_participant.js +1 -1
- package/{migrations → src/migrations}/200200_participantContact.js +1 -1
- package/{migrations → src/migrations}/200300_participantEndpoint.js +1 -1
- package/{migrations → src/migrations}/200400_participantParty.js +1 -1
- package/{migrations → src/migrations}/200600_token.js +1 -1
- package/{migrations → src/migrations}/200601_token-indexes.js +1 -1
- package/{migrations → src/migrations}/300100_transferDuplicateCheck.js +2 -2
- package/{migrations → src/migrations}/300150_bulkTransferDuplicateCheck.js +2 -2
- package/{migrations → src/migrations}/300200_transfer.js +2 -2
- package/{migrations → src/migrations}/300202_transfer-decimal184.js +1 -1
- package/{migrations → src/migrations}/300250_bulkTransfer.js +2 -3
- package/{migrations → src/migrations}/300275_bulkTransferAssociation.js +2 -3
- package/{migrations → src/migrations}/300300_ilpPacket.js +1 -1
- package/{migrations → src/migrations}/300400_transferStateChange.js +1 -1
- package/{migrations → src/migrations}/300450_bulkTransferStateChange.js +1 -1
- package/{migrations → src/migrations}/300500_segment.js +1 -1
- package/{migrations → src/migrations}/310100_participantCurrency.js +1 -1
- package/{migrations → src/migrations}/310200_transferParticipant.js +1 -1
- package/{migrations → src/migrations}/310202_transferParticipant-decimal184.js +1 -1
- package/{migrations → src/migrations}/310204_transferParticipant-participantId.js +2 -2
- package/{migrations → src/migrations}/310300_participantPosition.js +1 -1
- package/{migrations → src/migrations}/310302_participantPosition-decimal184.js +1 -1
- package/{migrations → src/migrations}/310400_participantPositionChange.js +1 -1
- package/{migrations → src/migrations}/310402_participantPositionChange-decimal184.js +1 -1
- package/{migrations → src/migrations}/310403_participantPositionChange-participantCurrencyId.js +2 -2
- package/{migrations → src/migrations}/310404_participantPositionChange-change.js +2 -2
- package/{migrations → src/migrations}/310500_participantLimit.js +1 -1
- package/{migrations → src/migrations}/310502_participantLimit-decimal184.js +1 -1
- package/{migrations → src/migrations}/400100_settlementWindow.js +1 -1
- package/{migrations → src/migrations}/400200_settlement.js +1 -1
- package/{migrations → src/migrations}/400300_settlementSettlementWindow.js +1 -1
- package/{migrations → src/migrations}/400301_settlementSettlementWindow-indexes.js +0 -1
- package/{migrations → src/migrations}/400400_settlementWindowStateChange.js +1 -1
- package/{migrations → src/migrations}/400500_settlementTransferParticipant.js +1 -1
- package/{migrations → src/migrations}/400502_settlementTransferParticipant-decimal184.js +1 -1
- package/{migrations → src/migrations}/400600_settlementParticipantCurrency.js +1 -1
- package/{migrations → src/migrations}/400602_settlementParticipantCurrency-decimal184.js +1 -1
- package/{migrations → src/migrations}/400700_settlementParticipantCurrencyStateChange.js +1 -1
- package/{migrations → src/migrations}/400800_settlementStateChange.js +1 -1
- package/{migrations → src/migrations}/400900_settlementWindowContent.js +1 -1
- package/{migrations → src/migrations}/401000_settlementWindowContentStateChange.js +1 -1
- package/{migrations → src/migrations}/401001_settlementWindowContentStateChange-indexes.js +6 -6
- package/{migrations → src/migrations}/401200_settlementContentAggregation.js +1 -1
- package/{migrations → src/migrations}/401300_settlementModel.js +1 -1
- package/{migrations → src/migrations}/410100_transferFulfilmentDuplicateCheck.js +1 -1
- package/{migrations → src/migrations}/410102_transferFulfilmentDuplicateCheck-dropForeignTransferId.js +1 -1
- package/{migrations → src/migrations}/410103_transferFulfilmentDuplicateCheck-hashNullable.js +1 -1
- package/{migrations → src/migrations}/410200_transferFulfilment.js +1 -1
- package/{migrations → src/migrations}/410202_transferFulfilment-ilpFulfilment.js +1 -1
- package/{migrations → src/migrations}/410203_transferFulfilment-foreignTransferFulfilmentId.js +1 -1
- package/{migrations → src/migrations}/410240_bulkTransferFulfilmentDuplicateCheck.js +1 -1
- package/{migrations → src/migrations}/410250_bulkTransferFulfilment.js +1 -1
- package/{migrations → src/migrations}/410300_transferExtension.js +1 -1
- package/{migrations → src/migrations}/410302_transferExtension-transferErrorId.js +1 -1
- package/{migrations → src/migrations}/410350_bulkTransferExtension.js +1 -1
- package/{migrations → src/migrations}/410400_transferTimeout.js +1 -1
- package/{migrations → src/migrations}/410450_transferErrorDuplicateCheck.js +1 -1
- package/{migrations → src/migrations}/410500_transferError.js +1 -1
- package/{migrations → src/migrations}/410502_transferError-foreignTransferErrorDuplicateCheckId.js +1 -1
- package/{migrations → src/migrations}/410550_bulkTransferError.js +1 -1
- package/{migrations → src/migrations}/410600_expiringTransfer.js +1 -1
- package/{migrations → src/migrations}/500401_quote-hotfix-2719.js +8 -8
- package/{migrations → src/migrations}/500501_feature-fixSubIdRef.js +12 -12
- package/{migrations → src/migrations}/500601_party-2480.js +3 -3
- package/{migrations → src/migrations}/501001_quoteExtension-quote-service-174.js +1 -2
- package/{migrations → src/migrations}/501002_quoteExtension-2522.js +3 -3
- package/{migrations → src/migrations}/600010_fxTransferType.js +1 -1
- package/{migrations → src/migrations}/600012_fxParticipantCurrencyType.js +1 -1
- package/{migrations → src/migrations}/600100_fxTransferDuplicateCheck.js +2 -2
- package/{migrations → src/migrations}/600110_fxTransferErrorDuplicateCheck.js.js +1 -1
- package/{migrations → src/migrations}/600200_fxTransfer.js +2 -2
- package/{migrations → src/migrations}/600400_fxTransferStateChange.js +1 -1
- package/{migrations → src/migrations}/600501_fxWatchList.js +2 -2
- package/{migrations → src/migrations}/600600_fxTransferFulfilmentDuplicateCheck.js +1 -1
- package/{migrations → src/migrations}/600700_fxTransferFulfilment.js +1 -1
- package/{migrations → src/migrations}/600800_fxTransferExtension.js +1 -1
- package/{migrations → src/migrations}/601400_fxTransferTimeout.js +1 -1
- package/{migrations → src/migrations}/601500_fxTransferError.js +1 -1
- package/{migrations → src/migrations}/610200_fxTransferParticipant.js +1 -1
- package/{migrations → src/migrations}/610202_fxTransferParticipant-participantId.js +2 -2
- package/{migrations → src/migrations}/610403_participantPositionChange-fxTransfer.js +1 -1
- package/{migrations → src/migrations}/800100_quotePartyView.js +1 -1
- package/{migrations → src/migrations}/800101_feature-fixSubIdRef.js +1 -1
- package/{migrations → src/migrations}/800200_quoteView.js +1 -1
- package/{migrations → src/migrations}/800300_quoteResponseView.js +1 -1
- package/{migrations → src/migrations}/900100_foreign-keys.js +18 -18
- package/{migrations → src/migrations}/900101_foreign-keys.js +6 -6
- package/{migrations → src/migrations}/910100_feature904DDL.js +7 -7
- package/{migrations → src/migrations}/910101_feature904DataMigration.js +1 -1
- package/{migrations → src/migrations}/910102_feature949DataMigration.js +1 -1
- package/{migrations → src/migrations}/910103_feature1093SettlementByCurrency.js +3 -3
- package/{migrations → src/migrations}/940101_quotePartyIdInfoExtension-2522.js +25 -25
- package/{migrations → src/migrations}/950101_transferParticipantStateChange.js +2 -2
- package/{migrations → src/migrations}/950102_settlementModel-adjustPosition.js +2 -2
- package/{migrations → src/migrations}/950103_dropTransferParticipantStateChange.js +3 -3
- package/{migrations → src/migrations}/950104_settlementModel-settlementAccountTypeId.js +3 -3
- package/src/migrations/950107_settlementWindowContent_foreign_settlementModel.js +63 -0
- package/{migrations → src/migrations}/950108_participantProxy.js +1 -2
- package/{migrations → src/migrations}/950120_fxQuoteConversionTerms_sourceAmount_nullable.js +1 -1
- package/{migrations → src/migrations}/960100_create_externalParticipant.js +2 -2
- package/{migrations → src/migrations}/960110_alter_transferParticipant__addFiled_externalParticipantId.js +2 -2
- package/{migrations → src/migrations}/961001_transferForwarded.js +1 -1
- package/{migrations → src/migrations}/961002_fxTransferForwarded.js +1 -1
- package/src/models/participant/externalParticipant.int.ts +85 -0
- package/src/models/participant/facade.js +4 -2
- package/src/models/participant/participantCurrencyCached.js +1 -1
- package/src/models/position/facade.js +8 -2
- package/src/models/transfer/facade.int.ts +139 -0
- package/src/models/transfer/facade.js +8 -3
- package/src/models/transfer/transferDuplicateCheck.js +2 -2
- package/src/models/transfer/transferError.int.ts +112 -0
- package/src/models/transfer/transferExtension.int.ts +137 -0
- package/src/models/transfer/transferStateChange.int.ts +117 -0
- package/{seeds → src/seeds}/participant.js +1 -1
- package/{seeds → src/seeds}/settlementInterchange.js +1 -0
- package/src/settlement/api/handlerRoutes.js +71 -0
- package/src/settlement/api/handlers/health.js +10 -0
- package/src/settlement/api/handlers/index.js +57 -0
- package/src/settlement/api/handlers/settlementWindows/{id}.js +103 -0
- package/src/settlement/api/handlers/settlementWindows.js +77 -0
- package/src/settlement/api/handlers/settlements/{id}.js +133 -0
- package/src/settlement/api/handlers/settlements/{sid}/participants/{pid}/accounts/{aid}.js +127 -0
- package/src/settlement/api/handlers/settlements/{sid}/participants/{pid}.js +127 -0
- package/src/settlement/api/handlers/settlements.js +114 -0
- package/src/settlement/api/openapiRouting.js +87 -0
- package/src/settlement/api/routes.js +176 -0
- package/src/settlement/domain/rules/index.js +46 -0
- package/src/settlement/domain/settlement/index.js +405 -0
- package/src/settlement/domain/settlementWindow/index.js +117 -0
- package/src/settlement/domain/transactions/index.js +83 -0
- package/src/settlement/domain/transferSettlement/index.js +57 -0
- package/src/settlement/handlers/deferredSettlement/handler.js +180 -0
- package/src/settlement/handlers/grossSettlement/handler.js +180 -0
- package/src/settlement/handlers/index.js +101 -0
- package/src/settlement/handlers/register.js +92 -0
- package/src/settlement/handlers/rules/handler.js +164 -0
- package/src/settlement/interface/swagger-handler.json +34 -0
- package/src/settlement/interface/swagger.json +1560 -0
- package/src/settlement/lib/db.js +32 -0
- package/src/settlement/lib/kafka/index.js +41 -0
- package/src/settlement/lib/kafka/producer.js +142 -0
- package/src/settlement/lib/scriptEngine.js +99 -0
- package/src/settlement/lib/scriptsLoader.js +175 -0
- package/src/settlement/lib/utility.js +243 -0
- package/src/settlement/models/ilpPackets/ilpPacket.js +42 -0
- package/src/settlement/models/lib/enums.js +192 -0
- package/src/settlement/models/misc/migrationLock.js +53 -0
- package/src/settlement/models/settlement/facade.js +1652 -0
- package/src/settlement/models/settlement/index.js +55 -0
- package/src/settlement/models/settlement/participantCurrency.js +48 -0
- package/src/settlement/models/settlement/settlement.js +49 -0
- package/src/settlement/models/settlement/settlementModel.js +44 -0
- package/src/settlement/models/settlement/settlementParticipantCurrency.js +61 -0
- package/src/settlement/models/settlement/settlementStateChange.js +44 -0
- package/src/settlement/models/settlement/settlementTransferParticipant.js +46 -0
- package/src/settlement/models/settlementWindow/facade.js +345 -0
- package/src/settlement/models/settlementWindow/index.js +47 -0
- package/src/settlement/models/settlementWindow/settlementWindowStateChange.js +55 -0
- package/src/settlement/models/settlementWindowContent/facade.js +79 -0
- package/src/settlement/models/settlementWindowContent/index.js +40 -0
- package/src/settlement/models/settlementWindowContent/settlementWindowContentStateChange.js +53 -0
- package/src/settlement/models/transferSettlement/facade.js +363 -0
- package/src/settlement/models/transferSettlement/index.js +42 -0
- package/src/settlement/shared/logger/index.js +7 -0
- package/src/settlement/shared/plugins.js +88 -0
- package/src/settlement/shared/setup.js +224 -0
- package/src/settlement/utils/truthyProperty.js +37 -0
- package/src/shared/legacyUtilShim.js +20 -0
- package/src/shared/plugins.js +3 -3
- package/src/shared/results.ts +22 -0
- package/src/shared/results.unit.ts +38 -0
- package/src/shared/setup.js +14 -1
- package/src/testing/api-helpers.ts +1222 -0
- package/src/testing/exec-async.ts +67 -0
- package/src/testing/harness.snapshot.sql +3895 -0
- package/src/testing/harness.test.ts +15 -0
- package/src/testing/harness.ts +1160 -0
- package/src/testing/kafka.ts +221 -0
- package/src/testing/prng.ts +82 -0
- package/src/testing/rdkafka.test.ts +263 -0
- package/src/testing/run.ts +559 -0
- package/src/testing/snapshot.test.ts +92 -0
- package/src/testing/snapshot.ts +549 -0
- package/src/testing/tap-stream.ts +164 -0
- package/src/testing/types.ts +95 -0
- package/src/testing/util.ts +333 -0
- package/src/types/central-services-error-handling.d.ts +72 -0
- package/src/types/central-services-stream.d.ts +148 -0
- package/test-integration.Dockerfile +0 -2
- package/test.Dockerfile +0 -2
- package/tsconfig.json +40 -0
- package/config/knexfile.js +0 -19
- package/migrations/950107_settlementWindowContent_foreign_settlementModel.js +0 -63
- package/src/api/index.js +0 -16
- package/src/lib/config.js +0 -81
- /package/{migrations → src/migrations}/110101_contactType-indexes.js +0 -0
- /package/{migrations → src/migrations}/110301_endpointType-indexes.js +0 -0
- /package/{migrations → src/migrations}/110401_ledgerEntryType-indexes.js +0 -0
- /package/{migrations → src/migrations}/110451_ledgerAccountType-indexes.js +0 -0
- /package/{migrations → src/migrations}/110501_participantLimitType-indexes.js +0 -0
- /package/{migrations → src/migrations}/110601_transferParticipantRoleType-indexes.js +0 -0
- /package/{migrations → src/migrations}/110800_settlementWindowState.js +0 -0
- /package/{migrations → src/migrations}/111000_amountType.js +0 -0
- /package/{migrations → src/migrations}/111001_amountType-indexes.js +0 -0
- /package/{migrations → src/migrations}/111100_balanceOfPayments.js +0 -0
- /package/{migrations → src/migrations}/111101_balanceOfPayments-indexes.js +0 -0
- /package/{migrations → src/migrations}/111200_partyIdentifierType.js +0 -0
- /package/{migrations → src/migrations}/111201_partyIdentifierType-indexes.js +0 -0
- /package/{migrations → src/migrations}/111300_partyType.js +0 -0
- /package/{migrations → src/migrations}/111301_partyType-indexes.js +0 -0
- /package/{migrations → src/migrations}/111400_quoteDuplicateCheck.js +0 -0
- /package/{migrations → src/migrations}/111500_transactionInitiator.js +0 -0
- /package/{migrations → src/migrations}/111501_transactionInitiator-indexes.js +0 -0
- /package/{migrations → src/migrations}/111600_transactionInitiatorType.js +0 -0
- /package/{migrations → src/migrations}/111601_transactionInitiatorType-indexes.js +0 -0
- /package/{migrations → src/migrations}/111700_settlementDelay.js +0 -0
- /package/{migrations → src/migrations}/111701_settlementDelay-indexes.js +0 -0
- /package/{migrations → src/migrations}/111800_settlementInterchange.js +0 -0
- /package/{migrations → src/migrations}/111801_settlementInterchange-indexes.js +0 -0
- /package/{migrations → src/migrations}/111900_settlementGranularity.js +0 -0
- /package/{migrations → src/migrations}/111901_settlementGranularity-indexes.js +0 -0
- /package/{migrations → src/migrations}/112101_bulkProcessingState-indexes.js +0 -0
- /package/{migrations → src/migrations}/200101_participant-indexes.js +0 -0
- /package/{migrations → src/migrations}/200201_participantContact-indexes.js +0 -0
- /package/{migrations → src/migrations}/200301_participantEndpoint-indexes.js +0 -0
- /package/{migrations → src/migrations}/200401_participantParty-indexes.js +0 -0
- /package/{migrations → src/migrations}/300201_transfer-indexes.js +0 -0
- /package/{migrations → src/migrations}/300251_bulkTransfer-indexes.js +0 -0
- /package/{migrations → src/migrations}/300276_bulkTransferAssociation-indexes.js +0 -0
- /package/{migrations → src/migrations}/300401_transferStateChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/300451_bulkTransferStateChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/300501_segment-indexes.js +0 -0
- /package/{migrations → src/migrations}/310101_participantCurrency-indexes.js +0 -0
- /package/{migrations → src/migrations}/310201_transferParticipant-indexes.js +0 -0
- /package/{migrations → src/migrations}/310203_transferParticipant-indexes.js +0 -0
- /package/{migrations → src/migrations}/310301_participantPosition-indexes.js +0 -0
- /package/{migrations → src/migrations}/310401_participantPositionChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/310405_participantPositionChange-positionChange.js +0 -0
- /package/{migrations → src/migrations}/310406_participantPositionChange-positionChange-revert.js +0 -0
- /package/{migrations → src/migrations}/310501_participantLimit-indexes.js +0 -0
- /package/{migrations → src/migrations}/310503_participantLimit-indexes-composite.js +0 -0
- /package/{migrations → src/migrations}/400401_settlmentWindowStateChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/400501_settlementTransferParticipant-indexes.js +0 -0
- /package/{migrations → src/migrations}/400601_settlementParticipantCurrency-indexes.js +0 -0
- /package/{migrations → src/migrations}/400701_settlementParticipantCurrencyStateChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/400801_settlementStateChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/401002_settlementWindowContent-indexes.js +0 -0
- /package/{migrations → src/migrations}/401201_settlementContentAggregation-indexes.js +0 -0
- /package/{migrations → src/migrations}/401301_settlementModel-indexes.js +0 -0
- /package/{migrations → src/migrations}/410101_transferFulfilmentDuplicateCheck-indexes.js +0 -0
- /package/{migrations → src/migrations}/410201_transferFulfilment-indexes.js +0 -0
- /package/{migrations → src/migrations}/410301_transferExtension-indexes.js +0 -0
- /package/{migrations → src/migrations}/410351_bulkTransferExtension-indexes.js +0 -0
- /package/{migrations → src/migrations}/410401_transferTimeout-indexes.js +0 -0
- /package/{migrations → src/migrations}/410501_transferError-indexes.js +0 -0
- /package/{migrations → src/migrations}/410551_bulkTransferError-indexes.js +0 -0
- /package/{migrations → src/migrations}/410601_expiringTransfer-indexes.js +0 -0
- /package/{migrations → src/migrations}/500100_transactionReference.js +0 -0
- /package/{migrations → src/migrations}/500101_transactionReference-indexes.js +0 -0
- /package/{migrations → src/migrations}/500200_transactionScenario.js +0 -0
- /package/{migrations → src/migrations}/500201_transactionScenario-indexes.js +0 -0
- /package/{migrations → src/migrations}/500300_transactionSubScenario.js +0 -0
- /package/{migrations → src/migrations}/500400_quote.js +0 -0
- /package/{migrations → src/migrations}/500500_quoteParty.js +0 -0
- /package/{migrations → src/migrations}/500600_party.js +0 -0
- /package/{migrations → src/migrations}/500700_quoteResponse.js +0 -0
- /package/{migrations → src/migrations}/500800_quoteResponseIlpPacket.js +0 -0
- /package/{migrations → src/migrations}/500900_geoCode.js +0 -0
- /package/{migrations → src/migrations}/501000_quoteExtension.js +0 -0
- /package/{migrations → src/migrations}/501100_quoteResponseDuplicateCheck.js +0 -0
- /package/{migrations → src/migrations}/501200_quoteError.js +0 -0
- /package/{migrations → src/migrations}/501300_transferRules.js +0 -0
- /package/{migrations → src/migrations}/600011_fxTransferType-indexes.js +0 -0
- /package/{migrations → src/migrations}/600013_fxParticipantCurrencyType-indexes.js +0 -0
- /package/{migrations → src/migrations}/600201_fxTransfer-indexes.js +0 -0
- /package/{migrations → src/migrations}/600401_fxTransferStateChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/600502_fxWatchList-indexes.js +0 -0
- /package/{migrations → src/migrations}/600601_fxTransferFulfilmentDuplicateCheck-indexes.js +0 -0
- /package/{migrations → src/migrations}/600701_fxTransferFulfilment-indexes.js +0 -0
- /package/{migrations → src/migrations}/601401_fxTransferTimeout-indexes.js +0 -0
- /package/{migrations → src/migrations}/601501_fxTransferError-indexes.js +0 -0
- /package/{migrations → src/migrations}/610201_fxTransferParticipant-indexes.js +0 -0
- /package/{migrations → src/migrations}/910102_hotfix954.js +0 -0
- /package/{migrations → src/migrations}/940100_quotePartyIdInfoExtension.js +0 -0
- /package/{migrations → src/migrations}/950100_settlementContentAggregation-decimal184.js +0 -0
- /package/{migrations → src/migrations}/950106_unique_settlement_model_ledger_account_currency.js +0 -0
- /package/{migrations → src/migrations}/950109_fxQuote.js +0 -0
- /package/{migrations → src/migrations}/950110_fxQuoteResponse.js +0 -0
- /package/{migrations → src/migrations}/950111_fxQuoteError.js +0 -0
- /package/{migrations → src/migrations}/950113_fxQuoteDuplicateCheck.js +0 -0
- /package/{migrations → src/migrations}/950114_fxQuoteResponseDuplicateCheck.js +0 -0
- /package/{migrations → src/migrations}/950115_fxQuoteConversionTerms.js +0 -0
- /package/{migrations → src/migrations}/950116_fxQuoteConversionTermsExtension.js +0 -0
- /package/{migrations → src/migrations}/950117_fxQuoteResponseConversionTerms.js +0 -0
- /package/{migrations → src/migrations}/950118_fxQuoteResponseConversionTermsExtension.js +0 -0
- /package/{migrations → src/migrations}/950119_fxCharge.js +0 -0
- /package/{migrations → src/migrations}/960111_alter_fxTransferParticipant__addFiled_externalParticipantId.js +0 -0
- /package/{migrations → src/migrations}/960112_fxTransfer-indexes2.js +0 -0
- /package/{migrations → src/migrations}/960113_fxTransferExtension-indexes.js +0 -0
- /package/{migrations → src/migrations}/960114_fxTransferTimeout-indexes2.js +0 -0
- /package/{migrations → src/migrations}/961000_participantEndpoint_unique.js +0 -0
- /package/{migrations → src/migrations}/migration.template +0 -0
- /package/{seeds → src/seeds}/amountType.js +0 -0
- /package/{seeds → src/seeds}/balanceOfPayments.js +0 -0
- /package/{seeds → src/seeds}/bulkProcessingState.js +0 -0
- /package/{seeds → src/seeds}/bulkTransferState.js +0 -0
- /package/{seeds → src/seeds}/currency.js +0 -0
- /package/{seeds → src/seeds}/endpointType.js +0 -0
- /package/{seeds → src/seeds}/fxParticipantCurrencyType.js +0 -0
- /package/{seeds → src/seeds}/fxTransferType.js +0 -0
- /package/{seeds → src/seeds}/ledgerAccountType.js +0 -0
- /package/{seeds → src/seeds}/ledgerEntryType.js +0 -0
- /package/{seeds → src/seeds}/participantLimitType.js +0 -0
- /package/{seeds → src/seeds}/partyIdentifierType.js +0 -0
- /package/{seeds → src/seeds}/partyType.js +0 -0
- /package/{seeds → src/seeds}/settlementDelay.js +0 -0
- /package/{seeds → src/seeds}/settlementGranularity.js +0 -0
- /package/{seeds → src/seeds}/settlementState.js +0 -0
- /package/{seeds → src/seeds}/settlementWindow1State.js +0 -0
- /package/{seeds → src/seeds}/settlementWindow2Open.js +0 -0
- /package/{seeds → src/seeds}/transactionInitiator.js +0 -0
- /package/{seeds → src/seeds}/transactionInitiatorType.js +0 -0
- /package/{seeds → src/seeds}/transactionScenario.js +0 -0
- /package/{seeds → src/seeds}/transferParticipantRoleType.js +0 -0
- /package/{seeds → src/seeds}/transferState.js +0 -0
- /package/{seeds → src/seeds}/z1000_settlementModel-deprecated.js- +0 -0
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
/*****
|
|
2
|
+
License
|
|
3
|
+
--------------
|
|
4
|
+
Copyright © 2020-2026 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
|
+
* TigerBeetle
|
|
23
|
+
- Lewis Daly <lewis@tigerbeetle.com>
|
|
24
|
+
--------------
|
|
25
|
+
|
|
26
|
+
******/
|
|
27
|
+
|
|
28
|
+
import assert from 'node:assert'
|
|
29
|
+
import { ApplicationConfig, DatabaseConfig, DistLockConfig, InstrumentationConfig, InstrumentationMetricsLabels, KafkaConfig, KafkaConsumerConfig, KafkaProducerConfig, RecursivePartial } from './types'
|
|
30
|
+
import { logger } from '../../shared/logger'
|
|
31
|
+
import { MySqlProxyCacheConfig, RedisClusterProxyCacheConfig, RedisProxyCacheConfig } from '@mojaloop/inter-scheme-proxy-cache-lib'
|
|
32
|
+
|
|
33
|
+
class ConfigValidationError extends Error {
|
|
34
|
+
constructor(message: string) {
|
|
35
|
+
super(message)
|
|
36
|
+
this.name = 'ConfigValidationError'
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @function assertString
|
|
42
|
+
* @description Assert that the input is a string.
|
|
43
|
+
*/
|
|
44
|
+
export function assertString(input: unknown): void {
|
|
45
|
+
if (typeof input !== 'string') {
|
|
46
|
+
throw new ConfigValidationError(`assertString() expected 'string', instead found ${typeof input}`)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @function assertNumber
|
|
52
|
+
* @description Assert that the input is a number.
|
|
53
|
+
*/
|
|
54
|
+
export function assertNumber(input: unknown): void {
|
|
55
|
+
if (typeof input !== 'number') {
|
|
56
|
+
throw new ConfigValidationError(`assertNumber() expected 'number', instead found ${typeof input}`)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (Number.isNaN(input)) {
|
|
60
|
+
throw new ConfigValidationError(`assertNumber() expected 'number', instead found NaN`)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @function assertBoolean
|
|
66
|
+
* @description Assert that the input is a boolean.
|
|
67
|
+
*/
|
|
68
|
+
export function assertBoolean(input: unknown): void {
|
|
69
|
+
if (typeof input !== 'boolean') {
|
|
70
|
+
throw new ConfigValidationError(`assertNumber() expected 'boolean', instead found ${typeof input}`)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @function assertStringOrNull
|
|
76
|
+
* @description Assert that the input is a string or null.
|
|
77
|
+
*/
|
|
78
|
+
export function assertStringOrNull(input: unknown): void {
|
|
79
|
+
if (input === null) {
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return assertString(input)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @function assertStringIfDefined
|
|
88
|
+
* @description Assert that the input is a string if it is defined.
|
|
89
|
+
*/
|
|
90
|
+
export function assertStringIfDefined(input: unknown): void {
|
|
91
|
+
if (input === undefined) {
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
assertString(input)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @function assertNumberIfDefined
|
|
99
|
+
* @description Assert that the input is a number if it is defined.
|
|
100
|
+
*/
|
|
101
|
+
export function assertNumberIfDefined(input: unknown): void {
|
|
102
|
+
if (input === undefined) {
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
assertNumber(input)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @function assertBooleanIfDefined
|
|
110
|
+
* @description Assert that the input is a boolean if it is defined.
|
|
111
|
+
*/
|
|
112
|
+
export function assertBooleanIfDefined(input: unknown): void {
|
|
113
|
+
if (input === undefined) {
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
assertBoolean(input)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @function assertProxyCacheConfig
|
|
121
|
+
* @description Assert that the proxy cache config is defined.
|
|
122
|
+
*/
|
|
123
|
+
export function assertProxyCacheConfig(input: unknown): void {
|
|
124
|
+
assert(input)
|
|
125
|
+
if ((input as RedisClusterProxyCacheConfig).cluster) {
|
|
126
|
+
const unsafeConfigCluster = input as RedisClusterProxyCacheConfig
|
|
127
|
+
assert(Array.isArray(unsafeConfigCluster.cluster), 'Expected `cluster` to be an array.')
|
|
128
|
+
assert(unsafeConfigCluster.cluster.length > 0, 'Expected .cluster to contain at least 1 item.')
|
|
129
|
+
for (const node of unsafeConfigCluster.cluster) {
|
|
130
|
+
assertString(node.host)
|
|
131
|
+
assertNumber(node.port)
|
|
132
|
+
}
|
|
133
|
+
assertStringIfDefined(unsafeConfigCluster.username)
|
|
134
|
+
assertStringIfDefined(unsafeConfigCluster.password)
|
|
135
|
+
assertBooleanIfDefined(unsafeConfigCluster.lazyConnect)
|
|
136
|
+
assertNumberIfDefined(unsafeConfigCluster.db)
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
const unsafeEither = input as RedisProxyCacheConfig | MySqlProxyCacheConfig
|
|
140
|
+
const unsafeRedis = input as RedisProxyCacheConfig
|
|
141
|
+
const unsafeMySQL = input as MySqlProxyCacheConfig
|
|
142
|
+
|
|
143
|
+
assertString(unsafeEither.host)
|
|
144
|
+
assertNumber(unsafeEither.port)
|
|
145
|
+
|
|
146
|
+
// Optional RedisOptions fields.
|
|
147
|
+
assertStringIfDefined(unsafeRedis.username)
|
|
148
|
+
assertStringIfDefined(unsafeRedis.password)
|
|
149
|
+
assertBooleanIfDefined(unsafeRedis.lazyConnect)
|
|
150
|
+
assertNumberIfDefined(unsafeRedis.db)
|
|
151
|
+
|
|
152
|
+
// Optional MySqlProxyCacheConfig fields.
|
|
153
|
+
assertStringIfDefined(unsafeMySQL.database)
|
|
154
|
+
assertStringIfDefined(unsafeMySQL.user)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @function assertKafkaConsumerConfig
|
|
159
|
+
* @description Assert that a Kafka consumer config is valid.
|
|
160
|
+
*/
|
|
161
|
+
export function assertKafkaConsumerConfig(input: unknown): void {
|
|
162
|
+
const unsafeConsumerConfig = input as KafkaConsumerConfig
|
|
163
|
+
assert(unsafeConsumerConfig)
|
|
164
|
+
assert(unsafeConsumerConfig.config)
|
|
165
|
+
assert(unsafeConsumerConfig.config.options)
|
|
166
|
+
assert(unsafeConsumerConfig.config.rdkafkaConf)
|
|
167
|
+
assert(unsafeConsumerConfig.config.topicConf)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* @function assertKafkaProducerConfig
|
|
172
|
+
* @description Assert that a Kafka producer config is valid.
|
|
173
|
+
*/
|
|
174
|
+
export function assertKafkaProducerConfig(input: unknown): void {
|
|
175
|
+
const unsafeProducerConfig = input as KafkaProducerConfig
|
|
176
|
+
assert(unsafeProducerConfig)
|
|
177
|
+
assert(unsafeProducerConfig.config)
|
|
178
|
+
assert(unsafeProducerConfig.config.options)
|
|
179
|
+
assert(unsafeProducerConfig.config.rdkafkaConf)
|
|
180
|
+
assert(unsafeProducerConfig.config.topicConf)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @function assertKafkaConfig
|
|
185
|
+
* @description Assert that the Kafka config is valid.
|
|
186
|
+
*/
|
|
187
|
+
export function assertKafkaConfig(input: unknown): void {
|
|
188
|
+
const unsafeConfig = input as KafkaConfig
|
|
189
|
+
assertNestedFields(unsafeConfig, 'EVENT_TYPE_ACTION_TOPIC_MAP.POSITION')
|
|
190
|
+
|
|
191
|
+
assertStringOrNull(unsafeConfig.EVENT_TYPE_ACTION_TOPIC_MAP.POSITION.PREPARE)
|
|
192
|
+
assertStringOrNull(unsafeConfig.EVENT_TYPE_ACTION_TOPIC_MAP.POSITION.FX_PREPARE)
|
|
193
|
+
assertStringOrNull(unsafeConfig.EVENT_TYPE_ACTION_TOPIC_MAP.POSITION.BULK_PREPARE)
|
|
194
|
+
assertStringOrNull(unsafeConfig.EVENT_TYPE_ACTION_TOPIC_MAP.POSITION.COMMIT)
|
|
195
|
+
assertStringOrNull(unsafeConfig.EVENT_TYPE_ACTION_TOPIC_MAP.POSITION.BULK_COMMIT)
|
|
196
|
+
assertStringOrNull(unsafeConfig.EVENT_TYPE_ACTION_TOPIC_MAP.POSITION.RESERVE)
|
|
197
|
+
assertStringOrNull(unsafeConfig.EVENT_TYPE_ACTION_TOPIC_MAP.POSITION.FX_RESERVE)
|
|
198
|
+
assertStringOrNull(unsafeConfig.EVENT_TYPE_ACTION_TOPIC_MAP.POSITION.TIMEOUT_RESERVED)
|
|
199
|
+
assertStringOrNull(unsafeConfig.EVENT_TYPE_ACTION_TOPIC_MAP.POSITION.FX_TIMEOUT_RESERVED)
|
|
200
|
+
assertStringOrNull(unsafeConfig.EVENT_TYPE_ACTION_TOPIC_MAP.POSITION.ABORT)
|
|
201
|
+
assertStringOrNull(unsafeConfig.EVENT_TYPE_ACTION_TOPIC_MAP.POSITION.FX_ABORT)
|
|
202
|
+
|
|
203
|
+
assertNestedFields(unsafeConfig, 'TOPIC_TEMPLATES.PARTICIPANT_TOPIC_TEMPLATE.TEMPLATE')
|
|
204
|
+
assertNestedFields(unsafeConfig, 'TOPIC_TEMPLATES.PARTICIPANT_TOPIC_TEMPLATE.REGEX')
|
|
205
|
+
assertNestedFields(unsafeConfig, 'TOPIC_TEMPLATES.GENERAL_TOPIC_TEMPLATE.TEMPLATE')
|
|
206
|
+
assertNestedFields(unsafeConfig, 'TOPIC_TEMPLATES.GENERAL_TOPIC_TEMPLATE.REGEX')
|
|
207
|
+
|
|
208
|
+
// Check the Consumer Configs. We can just check the leaf nodes.
|
|
209
|
+
assertNestedFields(unsafeConfig, 'CONSUMER.BULK.PREPARE')
|
|
210
|
+
assertNestedFields(unsafeConfig, 'CONSUMER.BULK.PROCESSING')
|
|
211
|
+
assertNestedFields(unsafeConfig, 'CONSUMER.BULK.FULFIL')
|
|
212
|
+
assertNestedFields(unsafeConfig, 'CONSUMER.BULK.GET')
|
|
213
|
+
assertNestedFields(unsafeConfig, 'CONSUMER.TRANSFER.PREPARE')
|
|
214
|
+
assertNestedFields(unsafeConfig, 'CONSUMER.TRANSFER.GET')
|
|
215
|
+
assertNestedFields(unsafeConfig, 'CONSUMER.TRANSFER.FULFIL')
|
|
216
|
+
assertNestedFields(unsafeConfig, 'CONSUMER.TRANSFER.POSITION')
|
|
217
|
+
assertNestedFields(unsafeConfig, 'CONSUMER.TRANSFER.POSITION_BATCH')
|
|
218
|
+
assertNestedFields(unsafeConfig, 'CONSUMER.ADMIN.TRANSFER')
|
|
219
|
+
assertNestedFields(unsafeConfig, 'CONSUMER.NOTIFICATION.EVENT')
|
|
220
|
+
assertNestedFields(unsafeConfig, 'CONSUMER.DEFERREDSETTLEMENT.CLOSE')
|
|
221
|
+
assertKafkaConsumerConfig(unsafeConfig.CONSUMER.BULK.PREPARE)
|
|
222
|
+
assertKafkaConsumerConfig(unsafeConfig.CONSUMER.BULK.PROCESSING)
|
|
223
|
+
assertKafkaConsumerConfig(unsafeConfig.CONSUMER.BULK.FULFIL)
|
|
224
|
+
assertKafkaConsumerConfig(unsafeConfig.CONSUMER.BULK.GET)
|
|
225
|
+
assertKafkaConsumerConfig(unsafeConfig.CONSUMER.TRANSFER.PREPARE)
|
|
226
|
+
assertKafkaConsumerConfig(unsafeConfig.CONSUMER.TRANSFER.GET)
|
|
227
|
+
assertKafkaConsumerConfig(unsafeConfig.CONSUMER.TRANSFER.FULFIL)
|
|
228
|
+
assertKafkaConsumerConfig(unsafeConfig.CONSUMER.TRANSFER.POSITION)
|
|
229
|
+
assertKafkaConsumerConfig(unsafeConfig.CONSUMER.TRANSFER.POSITION_BATCH)
|
|
230
|
+
assertKafkaConsumerConfig(unsafeConfig.CONSUMER.ADMIN.TRANSFER)
|
|
231
|
+
assertKafkaConsumerConfig(unsafeConfig.CONSUMER.NOTIFICATION.EVENT)
|
|
232
|
+
assertKafkaConsumerConfig(unsafeConfig.CONSUMER.DEFERREDSETTLEMENT.CLOSE)
|
|
233
|
+
|
|
234
|
+
// Check the Producer Configs.
|
|
235
|
+
assert(unsafeConfig.PRODUCER)
|
|
236
|
+
assert(unsafeConfig.PRODUCER.BULK)
|
|
237
|
+
assert(unsafeConfig.PRODUCER.BULK.PROCESSING)
|
|
238
|
+
assert(unsafeConfig.PRODUCER.TRANSFER)
|
|
239
|
+
assert(unsafeConfig.PRODUCER.TRANSFER.PREPARE)
|
|
240
|
+
assert(unsafeConfig.PRODUCER.TRANSFER.FULFIL)
|
|
241
|
+
assert(unsafeConfig.PRODUCER.TRANSFER.POSITION)
|
|
242
|
+
assert(unsafeConfig.PRODUCER.NOTIFICATION)
|
|
243
|
+
assert(unsafeConfig.PRODUCER.NOTIFICATION.EVENT)
|
|
244
|
+
assert(unsafeConfig.PRODUCER.ADMIN)
|
|
245
|
+
assert(unsafeConfig.PRODUCER.ADMIN.TRANSFER)
|
|
246
|
+
|
|
247
|
+
assertKafkaProducerConfig(unsafeConfig.PRODUCER.BULK.PROCESSING)
|
|
248
|
+
assertKafkaProducerConfig(unsafeConfig.PRODUCER.TRANSFER.PREPARE)
|
|
249
|
+
assertKafkaProducerConfig(unsafeConfig.PRODUCER.TRANSFER.FULFIL)
|
|
250
|
+
assertKafkaProducerConfig(unsafeConfig.PRODUCER.TRANSFER.POSITION)
|
|
251
|
+
assertKafkaProducerConfig(unsafeConfig.PRODUCER.NOTIFICATION.EVENT)
|
|
252
|
+
assertKafkaProducerConfig(unsafeConfig.PRODUCER.ADMIN.TRANSFER)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @function assertDatabaseConfig
|
|
257
|
+
* @description Assert that the Database config is valid.
|
|
258
|
+
*/
|
|
259
|
+
export function assertDatabaseConfig(input: unknown): void {
|
|
260
|
+
const unsafeConfig = input as DatabaseConfig
|
|
261
|
+
assertString(unsafeConfig.client)
|
|
262
|
+
assert(unsafeConfig.connection, 'Expected `.connection` to be defined.')
|
|
263
|
+
assertString(unsafeConfig.connection.host)
|
|
264
|
+
assertNumber(unsafeConfig.connection.port)
|
|
265
|
+
assertString(unsafeConfig.connection.user)
|
|
266
|
+
assertString(unsafeConfig.connection.password)
|
|
267
|
+
assertString(unsafeConfig.connection.database)
|
|
268
|
+
assert(unsafeConfig.pool, 'Expected `.pool` to be defined.')
|
|
269
|
+
assertNumber(unsafeConfig.pool.min)
|
|
270
|
+
assertNumber(unsafeConfig.pool.max)
|
|
271
|
+
assertNumber(unsafeConfig.pool.acquireTimeoutMillis)
|
|
272
|
+
assertNumber(unsafeConfig.pool.createTimeoutMillis)
|
|
273
|
+
assertNumber(unsafeConfig.pool.destroyTimeoutMillis)
|
|
274
|
+
assertNumber(unsafeConfig.pool.idleTimeoutMillis)
|
|
275
|
+
assertNumber(unsafeConfig.pool.reapIntervalMillis)
|
|
276
|
+
assertNumber(unsafeConfig.pool.createRetryIntervalMillis)
|
|
277
|
+
assertBoolean(unsafeConfig.debug)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* @function assertInstrumentationMetricsLabels
|
|
282
|
+
* @description Assert that the instrumentation metrics labels config is valid.
|
|
283
|
+
*/
|
|
284
|
+
export function assertInstrumentationMetricsLabels(input: unknown): void {
|
|
285
|
+
assert(input, 'Expected instrumentation metrics labels to be defined')
|
|
286
|
+
const unsafeConfig = input as InstrumentationMetricsLabels
|
|
287
|
+
assertString(unsafeConfig.fspId)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* @function assertInstrumentationConfig
|
|
292
|
+
* @description Assert that the instrumentation config is valid.
|
|
293
|
+
*/
|
|
294
|
+
export function assertInstrumentationConfig(input: unknown): void {
|
|
295
|
+
assert(input, 'Expected instrumentation config to be defined')
|
|
296
|
+
const unsafeConfig = input as InstrumentationConfig
|
|
297
|
+
assertNumber(unsafeConfig.timeout)
|
|
298
|
+
assertString(unsafeConfig.prefix)
|
|
299
|
+
assert(unsafeConfig.defaultLabels, 'Expected `.defaultLabels` to be defined')
|
|
300
|
+
assertString(unsafeConfig.defaultLabels.serviceName)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* @function assertDistLockConfig
|
|
305
|
+
* @description Assert that the distributed lock config is valid.
|
|
306
|
+
*/
|
|
307
|
+
export function assertDistLockConfig(input: unknown): void {
|
|
308
|
+
assert(input, 'Expected dist lock config to be defined')
|
|
309
|
+
const unsafeConfig = input as DistLockConfig
|
|
310
|
+
assertBoolean(unsafeConfig.enabled)
|
|
311
|
+
assertNumber(unsafeConfig.lockTimeout)
|
|
312
|
+
assertNumber(unsafeConfig.acquireTimeout)
|
|
313
|
+
assertNumber(unsafeConfig.driftFactor)
|
|
314
|
+
assertNumber(unsafeConfig.retryCount)
|
|
315
|
+
assertNumber(unsafeConfig.retryDelay)
|
|
316
|
+
assertNumber(unsafeConfig.retryJitter)
|
|
317
|
+
assert(Array.isArray(unsafeConfig.redisConfigs), 'Expected `.redisConfigs` to be an array')
|
|
318
|
+
for (const redisConfig of unsafeConfig.redisConfigs) {
|
|
319
|
+
assertString(redisConfig.type)
|
|
320
|
+
assert(Array.isArray(redisConfig.cluster), 'Expected `.cluster` to be an array')
|
|
321
|
+
for (const node of redisConfig.cluster) {
|
|
322
|
+
assertString(node.host)
|
|
323
|
+
assertNumber(node.port)
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* @function assertProvisioning
|
|
330
|
+
* @description Assert that the provisioning config is valid.
|
|
331
|
+
*/
|
|
332
|
+
export function assertProvisioning(input: unknown): void {
|
|
333
|
+
assert(input, 'Expected provisioning config to be defined.')
|
|
334
|
+
const unsafeConfig = input as ApplicationConfig['EXPERIMENTAL']['PROVISIONING']
|
|
335
|
+
|
|
336
|
+
assertBoolean(unsafeConfig.enabled)
|
|
337
|
+
if (unsafeConfig.enabled === false) {
|
|
338
|
+
return
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
assert(Array.isArray(unsafeConfig.currencies) && unsafeConfig.currencies.length > 0,
|
|
342
|
+
'expected .currencies to be an array with at least one element'
|
|
343
|
+
)
|
|
344
|
+
unsafeConfig.currencies.forEach(currency => assertString(currency))
|
|
345
|
+
assertStringIfDefined(unsafeConfig.hubAlertEmailAddress)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* @function defaultTo
|
|
350
|
+
* @description Return the input if defined, otherwise return the default value.
|
|
351
|
+
*/
|
|
352
|
+
export function defaultTo<T>(input: unknown, defaultValue: T): T {
|
|
353
|
+
if (input === undefined) {
|
|
354
|
+
return defaultValue
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
assert.equal(typeof input, typeof defaultValue)
|
|
358
|
+
return input as T
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* @function stringToBoolean
|
|
363
|
+
* @description Convert a string 'true' or 'false' to a boolean.
|
|
364
|
+
*/
|
|
365
|
+
export function stringToBoolean(input: string): boolean {
|
|
366
|
+
assert(input !== undefined)
|
|
367
|
+
assert(typeof input === 'string')
|
|
368
|
+
|
|
369
|
+
switch (input.toLowerCase()) {
|
|
370
|
+
case 'true': return true
|
|
371
|
+
case 'false': return false
|
|
372
|
+
default: {
|
|
373
|
+
throw new Error(`stringToBoolean, unknown input: ${input}`)
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* @function defaultEnvString
|
|
380
|
+
* @description Get an environment variable or return a default value.
|
|
381
|
+
*/
|
|
382
|
+
export function defaultEnvString(env: NodeJS.ProcessEnv, name: string, defaultValue: string): string {
|
|
383
|
+
assert(env, 'Expected env to be defined.')
|
|
384
|
+
assert(typeof name === 'string', 'Expected `name` to be a string.')
|
|
385
|
+
assert(defaultValue, 'Expected a default value.')
|
|
386
|
+
assert(typeof defaultValue === 'string', 'Expected default value to be a string')
|
|
387
|
+
|
|
388
|
+
let processEnvValue = env[name]
|
|
389
|
+
if (Array.isArray(processEnvValue)) {
|
|
390
|
+
processEnvValue = processEnvValue[0]
|
|
391
|
+
}
|
|
392
|
+
// Need to protect for cases where the value may intentionally false!
|
|
393
|
+
if (processEnvValue === undefined) {
|
|
394
|
+
logger.info(`defaultEnvString - ${name} not set - defaulting to: ${defaultValue}`)
|
|
395
|
+
return defaultValue
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
logger.info(`defaultEnvString - ${name} is set - resolved to: ${processEnvValue}`)
|
|
399
|
+
return processEnvValue
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* @function kafkaWithBrokerDefaults
|
|
404
|
+
* @description Configure the metadata.broker.list without needing to touch each individual config.
|
|
405
|
+
* If config.rdkafkaConf['metadata.broker.list'] is already set, then this doesn't modify it.
|
|
406
|
+
*/
|
|
407
|
+
export function kafkaWithBrokerDefaults(input: KafkaConfig, defaultBroker: string): KafkaConfig {
|
|
408
|
+
assert(defaultBroker)
|
|
409
|
+
assert(input.CONSUMER)
|
|
410
|
+
assert(input.PRODUCER)
|
|
411
|
+
|
|
412
|
+
const applyBrokerDefaults = (
|
|
413
|
+
group: Record<string, Record<string, KafkaConsumerConfig | KafkaProducerConfig>>,
|
|
414
|
+
groupName: string
|
|
415
|
+
) => {
|
|
416
|
+
Object.keys(group).forEach(key => {
|
|
417
|
+
const topic = group[key]
|
|
418
|
+
Object.keys(topic).forEach(topicKey => {
|
|
419
|
+
const leafConfig = topic[topicKey] as KafkaConsumerConfig | KafkaProducerConfig
|
|
420
|
+
const path = `input.${groupName}.${key}.${topicKey}`
|
|
421
|
+
if (leafConfig?.config?.rdkafkaConf
|
|
422
|
+
&& !leafConfig.config.rdkafkaConf['metadata.broker.list']
|
|
423
|
+
) {
|
|
424
|
+
logger.debug(`Config kafkaWithBrokerDefaults() defaulting: ${path}.config.rdkafkaConf['metadata.broker.list'] with: ${defaultBroker}`)
|
|
425
|
+
leafConfig.config.rdkafkaConf['metadata.broker.list'] = defaultBroker
|
|
426
|
+
}
|
|
427
|
+
})
|
|
428
|
+
})
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
applyBrokerDefaults(input.CONSUMER as Record<string, Record<string, KafkaConsumerConfig>>, 'CONSUMER')
|
|
432
|
+
applyBrokerDefaults(input.PRODUCER as Record<string, Record<string, KafkaProducerConfig>>, 'PRODUCER')
|
|
433
|
+
|
|
434
|
+
return input
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* @function convertBigIntToNumber
|
|
439
|
+
* @description Converts a bigint to a number, throwing an error if the bigint is outside of the
|
|
440
|
+
* range (MIN_SAFE_INTEGER, MAX_SAFE_INTEGER).
|
|
441
|
+
*/
|
|
442
|
+
export function convertBigIntToNumber(input: bigint): number {
|
|
443
|
+
if (input > BigInt(Number.MAX_SAFE_INTEGER) ||
|
|
444
|
+
input < BigInt(Number.MIN_SAFE_INTEGER)
|
|
445
|
+
) {
|
|
446
|
+
throw new Error(`convertBigIntToNumber failed: input is outside of safe range.`)
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return Number(input)
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* @function safeStringToNumber
|
|
454
|
+
* @description Safetly convert from a string representation of a number to a number.
|
|
455
|
+
*/
|
|
456
|
+
export function safeStringToNumber(input: string) {
|
|
457
|
+
assert(typeof input === 'string')
|
|
458
|
+
const trimmed = input.trim()
|
|
459
|
+
|
|
460
|
+
// Check if it's a valid number string.
|
|
461
|
+
if (trimmed === '' || Number.isNaN(Number(trimmed))) {
|
|
462
|
+
throw new TypeError(`Invalid number string: "${input}".`)
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
const num = Number(trimmed)
|
|
466
|
+
if (!Number.isFinite(num)) {
|
|
467
|
+
throw new TypeError(`Number out of range: "${input}".`)
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
return num
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* @function assertRange
|
|
475
|
+
* @description Assert that an input number is within a specified range.
|
|
476
|
+
*/
|
|
477
|
+
export function assertRange(input: any, minInclusive: number, maxInclusive: number): void {
|
|
478
|
+
assert(maxInclusive > minInclusive, `assertRange invalid args - expected maxInclusive > minInclusive.`)
|
|
479
|
+
assert(typeof input === 'number')
|
|
480
|
+
assert(input >= minInclusive && input <= maxInclusive, `assertRange valid range: [${minInclusive}, ${maxInclusive}].`)
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* @function assertNestedFields
|
|
485
|
+
* @description Assert that a nested field is defined in the raw config.
|
|
486
|
+
*/
|
|
487
|
+
export function assertNestedFields(rawConfig: any, path: string): void {
|
|
488
|
+
const parts = path.split('.')
|
|
489
|
+
let current = rawConfig
|
|
490
|
+
let traversed = ''
|
|
491
|
+
|
|
492
|
+
for (const part of parts) {
|
|
493
|
+
traversed = traversed ? `${traversed}.${part}` : part
|
|
494
|
+
assert(current[part] !== undefined, `expected \`${traversed}\` to be defined`)
|
|
495
|
+
current = current[part]
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* @function deepMerge
|
|
501
|
+
* @description Deep merge source into target, mutating target in place.
|
|
502
|
+
* Arrays are replaced, not merged. Only plain objects are recursively merged.
|
|
503
|
+
*/
|
|
504
|
+
export function deepMerge<T extends Record<string, any>>(target: T, source: RecursivePartial<T>): T {
|
|
505
|
+
for (const key of Object.keys(source) as Array<keyof T>) {
|
|
506
|
+
const valSource = source[key]
|
|
507
|
+
const valTarget = target[key]
|
|
508
|
+
|
|
509
|
+
if (
|
|
510
|
+
valSource !== null &&
|
|
511
|
+
typeof valSource === 'object' &&
|
|
512
|
+
!Array.isArray(valSource) &&
|
|
513
|
+
valTarget !== null &&
|
|
514
|
+
typeof valTarget === 'object' &&
|
|
515
|
+
!Array.isArray(valTarget)
|
|
516
|
+
) {
|
|
517
|
+
deepMerge(valTarget, valSource as any)
|
|
518
|
+
} else {
|
|
519
|
+
target[key] = valSource as T[keyof T]
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
return target
|
|
523
|
+
}
|