From 029f407cb539690cdaf23926896bda09f9562c1e Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Tue, 28 Apr 2020 13:43:52 +0100 Subject: [PATCH 01/35] Add init container to onboard with central-ledger --- init/central-ledger/Dockerfile | 12 + ...nboard-Generic-FSP.postman_collection.json | 1201 +++++++++++++++++ ...board-Generic-FSP.postman_environment.json | 109 ++ .../inject-env-into-postman-env.js | 23 + 4 files changed, 1345 insertions(+) create mode 100644 init/central-ledger/Dockerfile create mode 100644 init/central-ledger/Onboard-Generic-FSP.postman_collection.json create mode 100644 init/central-ledger/Onboard-Generic-FSP.postman_environment.json create mode 100644 init/central-ledger/inject-env-into-postman-env.js diff --git a/init/central-ledger/Dockerfile b/init/central-ledger/Dockerfile new file mode 100644 index 00000000..4bdb06c2 --- /dev/null +++ b/init/central-ledger/Dockerfile @@ -0,0 +1,12 @@ +FROM postman/newman:5.0.0-alpine +LABEL maintainer="kamuela.franco@modusbox.com" + +WORKDIR /opt/init-central-ledger +COPY . . + +RUN ["node", "inject-env-into-postman-env.js"] + +RUN newman run \ + --delay-request=3000 \ + --environment="Onboard-Generic-FSP-POPULATED.postman_environment.json" \ + "Onboard-Generic-FSP.postman_collection.json" diff --git a/init/central-ledger/Onboard-Generic-FSP.postman_collection.json b/init/central-ledger/Onboard-Generic-FSP.postman_collection.json new file mode 100644 index 00000000..0bdbf943 --- /dev/null +++ b/init/central-ledger/Onboard-Generic-FSP.postman_collection.json @@ -0,0 +1,1201 @@ +{ + "info": { + "_postman_id": "f4aa52b2-fb4a-44d3-9a23-75fc65e3f486", + "name": "Onboard-Generic-FSP", + "description": "Author: Kamuela Franco\nPurpose: Used to add new FSP and relevant Callback Information", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "Add Generic DFSP", + "event": [ + { + "listen": "test", + "script": { + "id": "8869fdc9-c7b7-40da-b9da-c56308e3177a", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "FSPIOP-Source", + "value": "{{HUB_OPERATOR}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\"name\": \"{{DFSP_NAME}}\",\"currency\": \"{{DFSP_CURRENCY}}\"}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants" + ] + } + }, + "response": [] + }, + { + "name": "Add initial position and limits - Generic DFSP", + "event": [ + { + "listen": "test", + "script": { + "id": "e56b7c34-cc1a-4fd6-87c9-c4164b446036", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "type": "text", + "value": "{{HUB_OPERATOR}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"currency\": \"{{DFSP_CURRENCY}}\",\n\t\"limit\": {\n\t \"type\": \"NET_DEBIT_CAP\",\n\t \"value\": {{INITIAL_NET_DEBIT_CAP}}\n\t},\n\t\"initialPosition\": {{INITIAL_POSITION}}\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/initialPositionAndLimits", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "initialPositionAndLimits" + ] + } + }, + "response": [] + }, + { + "name": "Deposit Funds in Settlement Account - Generic DFSP", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "336b2f23-c2fb-41fe-8686-bafe38b85542", + "exec": [ + "var uuid = require('uuid');", + "var generatedUUID = uuid.v4();", + "pm.environment.set('FUNDS_IN_PREPARE_TRANSFER_ID', generatedUUID);", + "pm.environment.set('FUNDS_IN_PREPARE_AMOUNT', 1000);", + "", + "const genericDfspGetStatusRequest = {", + " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/{{DFSP_NAME}}/accounts',", + " method: 'GET',", + " header: {", + " \"Authorization\":\"Bearer \"+pm.environment.get(\"HUB_OPERATOR_BEARER_TOKEN\"),", + " \"FSPIOP-Source\": pm.environment.get(\"HUB_OPERATOR\"),", + " \"Content-Type\": \"application/json\"", + " }", + "};", + "pm.sendRequest(genericDfspGetStatusRequest, function (err, response) {", + " console.log(response.json())", + " var jsonData = response.json()", + " for(var i in jsonData) {", + " if(jsonData[i].ledgerAccountType === 'SETTLEMENT') {", + " pm.environment.set(\"GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID\",jsonData[i].id)", + " pm.environment.set(\"GENERIC_DFSP_SETTLEMENT_ACCOUNT_BALANCE_BEFORE_FUNDS_IN\",jsonData[i].value)", + " }", + " }", + "});", + "", + "const hubGetStatusRequest = {", + " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/{{HUB_NAME}}/accounts',", + " method: 'GET',", + " header: {", + " \"Authorization\":\"Bearer \"+pm.environment.get(\"HUB_OPERATOR_BEARER_TOKEN\"),", + " \"FSPIOP-Source\": pm.environment.get(\"HUB_OPERATOR\"),", + " \"Content-Type\": \"application/json\"", + " }", + "};", + "pm.sendRequest(hubGetStatusRequest, function (err, response) {", + " console.log(response.json())", + " response.json()", + " .filter( ledgerAccount => (ledgerAccount.currency === pm.environment.get('DFSP_CURRENCY') && ledgerAccount.ledgerAccountType === 'HUB_RECONCILIATION'))", + " .forEach(account => pm.environment.set(\"HUB_RECONCILIATION_ACCOUNT_BALANCE_BEFORE_FUNDS_IN\",account.value))", + "});", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "a085486c-acf5-4b04-8123-9f85cea73a07", + "exec": [ + "pm.test(\"Status code is 202\", function () {", + " pm.response.to.have.status(202);", + "});", + "", + "setTimeout(function () {", + " const genericDfspGetStatusRequest = {", + " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/'+pm.environment.get(\"DFSP_NAME\")+'/accounts',", + " method: 'GET',", + " header: {", + " \"Authorization\":\"Bearer \"+pm.environment.get(\"HUB_OPERATOR_BEARER_TOKEN\"),", + " \"FSPIOP-Source\": pm.environment.get(\"HUB_OPERATOR\"),", + " \"Content-Type\": \"application/json\"", + " }", + " };", + " pm.sendRequest(genericDfspGetStatusRequest, function (err, response) {", + " console.log(response.json())", + " var jsonData = response.json()", + " var genericDfspSettlementAccountBalanceAfterFundsIn", + " for(var i in jsonData) {", + " if(jsonData[i].ledgerAccountType === 'SETTLEMENT') {", + " payerfspSettlementAccountBalanceAfterFundsIn = jsonData[i].value", + " }", + " }", + " var genericDfspExpectedBalance = pm.environment.get('GENERIC_DFSP_SETTLEMENT_ACCOUNT_BALANCE_BEFORE_FUNDS_IN') - pm.environment.get('FUNDS_IN_PREPARE_AMOUNT')", + " pm.test(\"Final Generic DFSP Settlement Account Balance should be same as before FundsIn + fundsInPrepareAmount\", function () {", + " pm.expect(genericDfspSettlementAccountBalanceAfterFundsIn).to.eql(genericDfspExpectedBalance);", + " }); ", + " ", + " });", + " ", + " const hubGetStatusRequest = {", + " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/{{HUB_NAME}}/accounts',", + " method: 'GET',", + " header: {", + " \"Authorization\":\"Bearer \"+pm.environment.get(\"HUB_OPERATOR_BEARER_TOKEN\"),", + " \"FSPIOP-Source\": pm.environment.get(\"HUB_OPERATOR\"),", + " \"Content-Type\": \"application/json\"", + " }", + " };", + " pm.sendRequest(hubGetStatusRequest, function (err, response) {", + " console.log(response.json())", + " var jsonData = response.json()", + " var currentHubReconAccountBalance", + " response.json()", + " .filter( ledgerAccount => (ledgerAccount.currency === pm.environment.get('DFSP_CURRENCY') && ledgerAccount.ledgerAccountType === 'HUB_RECONCILIATION'))", + " .forEach(account => hubReconAccountBalanceAfterFundsIn = account.value)", + " // for(var i in jsonData) {", + " // if(jsonData[i].ledgerAccountType === 'HUB_RECONCILIATION') {", + " // hubReconAccountBalanceAfterFundsIn = jsonData[i].value", + " // }", + " // }", + " var hubExpectedBalance = pm.environment.get(\"HUB_RECONCILIATION_ACCOUNT_BALANCE_BEFORE_FUNDS_IN\")+pm.environment.get('FUNDS_IN_PREPARE_AMOUNT')", + " console.log(hubExpectedBalance)", + " pm.test(\"Final Hub Reconciliation Account Balance should increase by FundsIn Amount\", function () {", + " pm.expect(hubReconAccountBalanceAfterFundsIn).to.eql(hubExpectedBalance);", + " }); ", + " });", + "}, 2000)" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "type": "text", + "value": "{{HUB_OPERATOR}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"transferId\": \"{{FUNDS_IN_PREPARE_TRANSFER_ID}}\",\n \"externalReference\": \"string\",\n \"action\": \"recordFundsIn\",\n \"reason\": \"string\",\n \"amount\": {\n \"amount\": {{FUNDS_IN_PREPARE_AMOUNT}},\n \"currency\": \"{{DFSP_CURRENCY}}\"\n },\n \"extensionList\": {\n \"extension\": [\n {\n \"key\": \"string\",\n \"value\": \"string\"\n }\n ]\n }\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/accounts/{{GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID}}", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "accounts", + "{{GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID}}" + ] + } + }, + "response": [] + }, + { + "name": "Add Generic DFSP callback - PARTICIPANT PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "6438cf7a-96d3-40c9-ac00-0d8a5f87bbd9", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "value": "{{HUB_OPERATOR}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_PUT\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/participants/{{partyIdType}}/{{partyIdentifier}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add Generic DFSP callback - PARTICIPANT PUT Error", + "event": [ + { + "listen": "test", + "script": { + "id": "7bbe328e-7e30-497b-b5a3-6890480c1bbb", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/participants/{{partyIdType}}/{{partyIdentifier}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add Generic DFSP callback - PARTICIPANT PUT Batch", + "event": [ + { + "listen": "test", + "script": { + "id": "7d923fd4-5a1f-4697-ba30-94e0a2fbc8bc", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/participants/{{requestId}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add Generic DFSP callback - PARTICIPANT PUT Batch Error", + "event": [ + { + "listen": "test", + "script": { + "id": "b4a643af-f8e0-4aaa-955c-90b65cc14a17", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/participants/{{requestId}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add Generic DFSP callback - PARTIES GET", + "event": [ + { + "listen": "test", + "script": { + "id": "2658b8a2-07d2-4ae8-95fe-5fac947ba5a8", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_GET\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/parties/{{partyIdType}}/{{partyIdentifier}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add Generic DFSP callback - PARTIES PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "b121ee1f-7cdb-4814-998f-1ab25f35447c", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_PUT\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/parties/{{partyIdType}}/{{partyIdentifier}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add Generic DFSP callback - PARTIES PUT Error", + "event": [ + { + "listen": "test", + "script": { + "id": "56129f5c-9baf-46d7-b9a5-59f173436943", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/parties/{{partyIdType}}/{{partyIdentifier}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add Generic DFSP callback - QUOTES", + "event": [ + { + "listen": "test", + "script": { + "id": "78205452-8053-4c6c-9b3e-172c19db0b29", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "value": "{{HUB_OPERATOR}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_QUOTES\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add Generic DFSP callback - TRANSFER POST", + "event": [ + { + "listen": "test", + "script": { + "id": "3bb02ebd-e56f-46d7-b32c-8238c4178837", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "value": "{{HUB_OPERATOR}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_POST\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/transfers\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add Generic DFSP callback - TRANSFER PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "0d761f7f-51bf-4776-9907-217fc9665fbd", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "value": "{{HUB_OPERATOR}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_PUT\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/transfers/{{transferId}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add Generic DFSP callback - TRANSFER ERROR", + "event": [ + { + "listen": "test", + "script": { + "id": "936c1758-326b-4348-9dd3-2ea5f05a6091", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "value": "{{HUB_OPERATOR}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_ERROR\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/transfers/{{transferId}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Set Email-NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "value": "{{DFSP_NAME}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL\",\n \"value\": \"{{NDC_THRESHOLD_BREACH_EMAIL}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + }, + "description": "Generated from a curl request: \ncurl -i -X POST http://test-central-ledger.mojaloop.test/admin/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" + }, + "response": [ + { + "name": "2. Create Initial Position and Limits", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" + }, + "url": { + "raw": "http://test-central-ledger.mojaloop.live/admin/participants/testfsp/initialPositionAndLimits", + "protocol": "http", + "host": [ + "test-central-ledger", + "mojaloop", + "live" + ], + "path": [ + "admin", + "participants", + "testfsp", + "initialPositionAndLimits" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "Text", + "header": [], + "cookie": [], + "body": "" + } + ] + }, + { + "name": "Set Email-NET_DEBIT_CAP_ADJUSTMENT_EMAIL", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "value": "{{HUB_OPERATOR}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"NET_DEBIT_CAP_ADJUSTMENT_EMAIL\",\n \"value\": \"{{NDC_ADJUSTMENT_EMAIL}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + }, + "description": "Generated from a curl request: \ncurl -i -X POST http://test-central-ledger.mojaloop.test/admin/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" + }, + "response": [ + { + "name": "2. Create Initial Position and Limits", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" + }, + "url": { + "raw": "http://test-central-ledger.mojaloop.live/admin/participants/testfsp/initialPositionAndLimits", + "protocol": "http", + "host": [ + "test-central-ledger", + "mojaloop", + "live" + ], + "path": [ + "admin", + "participants", + "testfsp", + "initialPositionAndLimits" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "Text", + "header": [], + "cookie": [], + "body": "" + } + ] + }, + { + "name": "Set Email-SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "value": "{{DFSP_NAME}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL\",\n \"value\": \"{{SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" + ], + "path": [ + "participants", + "{{DFSP_NAME}}", + "endpoints" + ] + }, + "description": "Generated from a curl request: \ncurl -i -X POST http://test-central-ledger.mojaloop.test/admin/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" + }, + "response": [ + { + "name": "2. Create Initial Position and Limits", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" + }, + "url": { + "raw": "http://test-central-ledger.mojaloop.live/admin/participants/testfsp/initialPositionAndLimits", + "protocol": "http", + "host": [ + "test-central-ledger", + "mojaloop", + "live" + ], + "path": [ + "admin", + "participants", + "testfsp", + "initialPositionAndLimits" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "Text", + "header": [], + "cookie": [], + "body": "" + } + ] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "a3e74abc-7be6-49d7-88a1-1233d0582556", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "8e145984-2c7d-449e-918b-282655772ed3", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} +} diff --git a/init/central-ledger/Onboard-Generic-FSP.postman_environment.json b/init/central-ledger/Onboard-Generic-FSP.postman_environment.json new file mode 100644 index 00000000..0aacacba --- /dev/null +++ b/init/central-ledger/Onboard-Generic-FSP.postman_environment.json @@ -0,0 +1,109 @@ +{ + "id": "0e6e184d-85c5-4a4a-b2fb-f7a1360b2a62", + "name": "Onboard-Generic-FSP", + "values": [ + { + "key": "HOST_CENTRAL_LEDGER", + "value": "HOST_CENTRAL_LEDGER_VALUE", + "enabled": true + }, + { + "key": "BASE_CENTRAL_LEDGER_ADMIN", + "value": "BASE_CENTRAL_LEDGER_ADMIN_VALUE", + "enabled": true + }, + { + "key": "DFSP_NAME", + "value": "DFSP_NAME_VALUE", + "enabled": true + }, + { + "key": "HUB_OPERATOR", + "value": "HUB_OPERATOR_VALUE", + "enabled": true + }, + { + "key": "HUB_OPERATOR_BEARER_TOKEN", + "value": "HUB_OPERATOR_BEARER_TOKEN_VALUE", + "enabled": true + }, + { + "key": "DFSP_CURRENCY", + "value": "DFSP_CURRENCY_VALUE", + "enabled": true + }, + { + "key": "INITIAL_NET_DEBIT_CAP", + "value": "INITIAL_NET_DEBIT_CAP_VALUE", + "enabled": true + }, + { + "key": "INITIAL_POSITION", + "value": "INITIAL_POSITION_VALUE", + "enabled": true + }, + { + "key": "GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID", + "value": "GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID_VALUE", + "enabled": true + }, + { + "key": "FUNDS_IN_PREPARE_AMOUNT", + "value": "FUNDS_IN_PREPARE_AMOUNT_VALUE", + "enabled": true + }, + { + "key": "FUNDS_IN_PREPARE_TRANSFER_ID", + "value": "FUNDS_IN_PREPARE_TRANSFER_ID_VALUE", + "enabled": true + }, + { + "key": "GENERIC_DFSP_SETTLEMENT_ACCOUNT_BALANCE_BEFORE_FUNDS_IN", + "value": "GENERIC_DFSP_SETTLEMENT_ACCOUNT_BALANCE_BEFORE_FUNDS_IN_VALUE", + "enabled": true + }, + { + "key": "HUB_NAME", + "value": "HUB_NAME_VALUE", + "enabled": true + }, + { + "key": "HUB_RECONCILIATION_ACCOUNT_BALANCE_BEFORE_FUNDS_IN", + "value": "HUB_RECONCILIATION_ACCOUNT_BALANCE_BEFORE_FUNDS_IN_VALUE", + "enabled": true + }, + { + "key": "GENERIC_DFSP_CALLBACK_URL", + "value": "GENERIC_DFSP_CALLBACK_URL_VALUE", + "enabled": true + }, + { + "key": "REQUEST_ID", + "value": "REQUEST_ID_VALUE", + "enabled": true + }, + { + "key": "TRANSFER_ID", + "value": "TRANSFER_ID_VALUE", + "enabled": true + }, + { + "key": "NDC_THRESHOLD_BREACH_EMAIL", + "value": "NDC_THRESHOLD_BREACH_EMAIL_VALUE", + "enabled": true + }, + { + "key": "NDC_ADJUSTMENT_EMAIL", + "value": "NDC_ADJUSTMENT_EMAIL_VALUE", + "enabled": true + }, + { + "key": "SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL", + "value": "SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL_VALUE", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2020-04-28T08:22:18.685Z", + "_postman_exported_using": "Postman/7.23.0" +} \ No newline at end of file diff --git a/init/central-ledger/inject-env-into-postman-env.js b/init/central-ledger/inject-env-into-postman-env.js new file mode 100644 index 00000000..77efbb59 --- /dev/null +++ b/init/central-ledger/inject-env-into-postman-env.js @@ -0,0 +1,23 @@ +const fs = require('fs'); + +const envFileContents = fs.readFileSync('./Onboard-Generic-FSP.postman_environment.json'); + +const envJson = Object.freeze(JSON.parse(envFileContents)); + +const populatedEnvJson = { + ...envJson, + _postman_exported_at: (new Date()).toISOString(), + values: [ + ...envJson.values, + ].map(value => ({ + key: value.key, + value: process.env[value.key] || '', + enabled: value.enabled, + })), +}; + +fs.writeFileSync('./Onboard-Generic-FSP-POPULATED.postman_environment.json', JSON.stringify(populatedEnvJson)); + +console.log(`--- Onboard-Generic-FSP-POPULATED.postman_environment.json ---`); +console.log(JSON.parse(fs.readFileSync('./Onboard-Generic-FSP-POPULATED.postman_environment.json'))); +console.log(`---`); From 7090f8452b227e41a78fe6b1ad8f68c4e0928f4a Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Wed, 29 Apr 2020 11:37:55 +0100 Subject: [PATCH 02/35] Remove environment var processing script --- init/central-ledger/Dockerfile | 25 +++- ...board-Generic-FSP.postman_environment.json | 109 ------------------ .../inject-env-into-postman-env.js | 23 ---- 3 files changed, 21 insertions(+), 136 deletions(-) delete mode 100644 init/central-ledger/Onboard-Generic-FSP.postman_environment.json delete mode 100644 init/central-ledger/inject-env-into-postman-env.js diff --git a/init/central-ledger/Dockerfile b/init/central-ledger/Dockerfile index 4bdb06c2..efbd15ad 100644 --- a/init/central-ledger/Dockerfile +++ b/init/central-ledger/Dockerfile @@ -4,9 +4,26 @@ LABEL maintainer="kamuela.franco@modusbox.com" WORKDIR /opt/init-central-ledger COPY . . -RUN ["node", "inject-env-into-postman-env.js"] - RUN newman run \ - --delay-request=3000 \ - --environment="Onboard-Generic-FSP-POPULATED.postman_environment.json" \ + --delay-request=${DELAY_REQUEST} \ + --env-var "HOST_CENTRAL_LEDGER=${HOST_CENTRAL_LEDGER}" \ + --env-var "BASE_CENTRAL_LEDGER_ADMIN=${BASE_CENTRAL_LEDGER_ADMIN}" \ + --env-var "DFSP_NAME=${DFSP_NAME}" \ + --env-var "HUB_OPERATOR=${HUB_OPERATOR}" \ + --env-var "HUB_OPERATOR_BEARER_TOKEN=${HUB_OPERATOR_BEARER_TOKEN}" \ + --env-var "DFSP_CURRENCY=${DFSP_CURRENCY}" \ + --env-var "INITIAL_NET_DEBIT_CAP=${INITIAL_NET_DEBIT_CAP}" \ + --env-var "INITIAL_POSITION=${INITIAL_POSITION}" \ + --env-var "GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID=${GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID}" \ + --env-var "FUNDS_IN_PREPARE_AMOUNT=${FUNDS_IN_PREPARE_AMOUNT}" \ + --env-var "FUNDS_IN_PREPARE_TRANSFER_ID=${FUNDS_IN_PREPARE_TRANSFER_ID}" \ + --env-var "GENERIC_DFSP_SETTLEMENT_ACCOUNT_BALANCE_BEFORE_FUNDS_IN=${GENERIC_DFSP_SETTLEMENT_ACCOUNT_BALANCE_BEFORE_FUNDS_IN}" \ + --env-var "HUB_NAME=${HUB_NAME}" \ + --env-var "HUB_RECONCILIATION_ACCOUNT_BALANCE_BEFORE_FUNDS_IN=${HUB_RECONCILIATION_ACCOUNT_BALANCE_BEFORE_FUNDS_IN}" \ + --env-var "GENERIC_DFSP_CALLBACK_URL=${GENERIC_DFSP_CALLBACK_URL}" \ + --env-var "REQUEST_ID=${REQUEST_ID}" \ + --env-var "TRANSFER_ID=${TRANSFER_ID}" \ + --env-var "NDC_THRESHOLD_BREACH_EMAIL=${NDC_THRESHOLD_BREACH_EMAIL}" \ + --env-var "NDC_ADJUSTMENT_EMAIL=${NDC_ADJUSTMENT_EMAIL}" \ + --env-var "SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL=${SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL}" \ "Onboard-Generic-FSP.postman_collection.json" diff --git a/init/central-ledger/Onboard-Generic-FSP.postman_environment.json b/init/central-ledger/Onboard-Generic-FSP.postman_environment.json deleted file mode 100644 index 0aacacba..00000000 --- a/init/central-ledger/Onboard-Generic-FSP.postman_environment.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "id": "0e6e184d-85c5-4a4a-b2fb-f7a1360b2a62", - "name": "Onboard-Generic-FSP", - "values": [ - { - "key": "HOST_CENTRAL_LEDGER", - "value": "HOST_CENTRAL_LEDGER_VALUE", - "enabled": true - }, - { - "key": "BASE_CENTRAL_LEDGER_ADMIN", - "value": "BASE_CENTRAL_LEDGER_ADMIN_VALUE", - "enabled": true - }, - { - "key": "DFSP_NAME", - "value": "DFSP_NAME_VALUE", - "enabled": true - }, - { - "key": "HUB_OPERATOR", - "value": "HUB_OPERATOR_VALUE", - "enabled": true - }, - { - "key": "HUB_OPERATOR_BEARER_TOKEN", - "value": "HUB_OPERATOR_BEARER_TOKEN_VALUE", - "enabled": true - }, - { - "key": "DFSP_CURRENCY", - "value": "DFSP_CURRENCY_VALUE", - "enabled": true - }, - { - "key": "INITIAL_NET_DEBIT_CAP", - "value": "INITIAL_NET_DEBIT_CAP_VALUE", - "enabled": true - }, - { - "key": "INITIAL_POSITION", - "value": "INITIAL_POSITION_VALUE", - "enabled": true - }, - { - "key": "GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID", - "value": "GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID_VALUE", - "enabled": true - }, - { - "key": "FUNDS_IN_PREPARE_AMOUNT", - "value": "FUNDS_IN_PREPARE_AMOUNT_VALUE", - "enabled": true - }, - { - "key": "FUNDS_IN_PREPARE_TRANSFER_ID", - "value": "FUNDS_IN_PREPARE_TRANSFER_ID_VALUE", - "enabled": true - }, - { - "key": "GENERIC_DFSP_SETTLEMENT_ACCOUNT_BALANCE_BEFORE_FUNDS_IN", - "value": "GENERIC_DFSP_SETTLEMENT_ACCOUNT_BALANCE_BEFORE_FUNDS_IN_VALUE", - "enabled": true - }, - { - "key": "HUB_NAME", - "value": "HUB_NAME_VALUE", - "enabled": true - }, - { - "key": "HUB_RECONCILIATION_ACCOUNT_BALANCE_BEFORE_FUNDS_IN", - "value": "HUB_RECONCILIATION_ACCOUNT_BALANCE_BEFORE_FUNDS_IN_VALUE", - "enabled": true - }, - { - "key": "GENERIC_DFSP_CALLBACK_URL", - "value": "GENERIC_DFSP_CALLBACK_URL_VALUE", - "enabled": true - }, - { - "key": "REQUEST_ID", - "value": "REQUEST_ID_VALUE", - "enabled": true - }, - { - "key": "TRANSFER_ID", - "value": "TRANSFER_ID_VALUE", - "enabled": true - }, - { - "key": "NDC_THRESHOLD_BREACH_EMAIL", - "value": "NDC_THRESHOLD_BREACH_EMAIL_VALUE", - "enabled": true - }, - { - "key": "NDC_ADJUSTMENT_EMAIL", - "value": "NDC_ADJUSTMENT_EMAIL_VALUE", - "enabled": true - }, - { - "key": "SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL", - "value": "SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL_VALUE", - "enabled": true - } - ], - "_postman_variable_scope": "environment", - "_postman_exported_at": "2020-04-28T08:22:18.685Z", - "_postman_exported_using": "Postman/7.23.0" -} \ No newline at end of file diff --git a/init/central-ledger/inject-env-into-postman-env.js b/init/central-ledger/inject-env-into-postman-env.js deleted file mode 100644 index 77efbb59..00000000 --- a/init/central-ledger/inject-env-into-postman-env.js +++ /dev/null @@ -1,23 +0,0 @@ -const fs = require('fs'); - -const envFileContents = fs.readFileSync('./Onboard-Generic-FSP.postman_environment.json'); - -const envJson = Object.freeze(JSON.parse(envFileContents)); - -const populatedEnvJson = { - ...envJson, - _postman_exported_at: (new Date()).toISOString(), - values: [ - ...envJson.values, - ].map(value => ({ - key: value.key, - value: process.env[value.key] || '', - enabled: value.enabled, - })), -}; - -fs.writeFileSync('./Onboard-Generic-FSP-POPULATED.postman_environment.json', JSON.stringify(populatedEnvJson)); - -console.log(`--- Onboard-Generic-FSP-POPULATED.postman_environment.json ---`); -console.log(JSON.parse(fs.readFileSync('./Onboard-Generic-FSP-POPULATED.postman_environment.json'))); -console.log(`---`); From 8b423490c0c4c8d018812a2ee417f98c9f7df90c Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Wed, 29 Apr 2020 12:11:25 +0100 Subject: [PATCH 03/35] Switch RUN to CMD --- init/central-ledger/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/central-ledger/Dockerfile b/init/central-ledger/Dockerfile index efbd15ad..c42e2e02 100644 --- a/init/central-ledger/Dockerfile +++ b/init/central-ledger/Dockerfile @@ -4,7 +4,7 @@ LABEL maintainer="kamuela.franco@modusbox.com" WORKDIR /opt/init-central-ledger COPY . . -RUN newman run \ +CMD newman run \ --delay-request=${DELAY_REQUEST} \ --env-var "HOST_CENTRAL_LEDGER=${HOST_CENTRAL_LEDGER}" \ --env-var "BASE_CENTRAL_LEDGER_ADMIN=${BASE_CENTRAL_LEDGER_ADMIN}" \ From ad9b34a4d0a31a75eace37ea128e6b07e08bd670 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Wed, 29 Apr 2020 12:11:39 +0100 Subject: [PATCH 04/35] Add OCI labels --- init/central-ledger/Dockerfile | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/init/central-ledger/Dockerfile b/init/central-ledger/Dockerfile index c42e2e02..3bb4668d 100644 --- a/init/central-ledger/Dockerfile +++ b/init/central-ledger/Dockerfile @@ -1,5 +1,19 @@ FROM postman/newman:5.0.0-alpine -LABEL maintainer="kamuela.franco@modusbox.com" + +ARG CREATED +ARG SOURCE +ARG REVISION +ARG VERSION + +# See https://github.com/opencontainers/image-spec/blob/master/spec.md for info +LABEL org.opencontainers.image.created=${CREATED} +LABEL org.opencontainers.image.url="https://mojaloop.io/" +LABEL org.opencontainers.image.source=${SOURCE} +LABEL org.opencontainers.image.version=${VERSION} +LABEL org.opencontainers.image.revision=${REVISION} +LABEL org.opencontainers.image.title="init-central-ledger" +LABEL org.opencontainers.image.authors="kamuela.franco@modusbox.com" +LABEL org.opencontainers.image.licenses="Apache-2.0" WORKDIR /opt/init-central-ledger COPY . . From 65e15e23aaa52c2e30e778dc7884d9960a4bff32 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Wed, 29 Apr 2020 12:16:05 +0100 Subject: [PATCH 05/35] Add contributor --- src/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/package.json b/src/package.json index aa259586..22d9067c 100644 --- a/src/package.json +++ b/src/package.json @@ -7,6 +7,7 @@ "author": "Matt Kingston, ModusBox Inc.", "contributors": [ "Matt Kingston ", + "Kamuela Franco ", "ModusBox", "Mowali" ], From 8bb7315f3fe2674059526057e3fb14d369662471 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Wed, 29 Apr 2020 12:48:05 +0100 Subject: [PATCH 06/35] Update init/central-ledger/Dockerfile Co-Authored-By: Matt Kingston --- init/central-ledger/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/central-ledger/Dockerfile b/init/central-ledger/Dockerfile index 3bb4668d..0298c700 100644 --- a/init/central-ledger/Dockerfile +++ b/init/central-ledger/Dockerfile @@ -5,7 +5,7 @@ ARG SOURCE ARG REVISION ARG VERSION -# See https://github.com/opencontainers/image-spec/blob/master/spec.md for info +# See https://github.com/opencontainers/image-spec/blob/master/annotations.md#pre-defined-annotation-keys and https://github.com/opencontainers/image-spec/blob/master/spec.md for info LABEL org.opencontainers.image.created=${CREATED} LABEL org.opencontainers.image.url="https://mojaloop.io/" LABEL org.opencontainers.image.source=${SOURCE} From 17723633477411618ad984da28f0c6a315b2e285 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 30 Apr 2020 11:59:34 +0100 Subject: [PATCH 07/35] Clear whitespace and unused comments --- .circleci/config.yml | 49 +++++--------------------------------------- 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 79487703..a9ea0ef5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -116,12 +116,6 @@ defaults_license_scanner: &defaults_license_scanner git clone https://github.com/mojaloop/license-scanner /tmp/license-scanner cd /tmp/license-scanner && make build default-files set-up - -# defaults_working_directory: &defaults_working_directory -# # The working directory for this project (place where package.json is) is /src, -# # as opposed to the project root -# working_directory: /home/circleci/project/git - defaults_slack_announcement: &defaults_slack_announcement name: Slack announcement for tag releases command: | @@ -132,11 +126,10 @@ defaults_slack_announcement: &defaults_slack_announcement -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" src_working_directory: &src_working_directory - # The working directory for this project (place where package.json is) is /src, + # The working directory for this project (place where package.json is) is /src, # as opposed to the project root working_directory: /home/circleci/project/git/src - ## # Executors # @@ -145,7 +138,7 @@ src_working_directory: &src_working_directory executors: default-docker: working_directory: /home/circleci/project/git - docker: + docker: - image: node:12.16.0-alpine default-machine: @@ -155,7 +148,7 @@ executors: helm-kube: working_directory: /home/circleci/project - docker: + docker: - image: hypnoglow/kubernetes-helm ## @@ -171,9 +164,6 @@ jobs: - run: name: Install general dependencies command: *defaults_Dependencies - # - run: - # name: Build dependencies - # command: apk add --no-cache -t build-dependencies make gcc g++ python libtool autoconf automake - run: name: Access npm folder as root command: cd $(npm root -g)/npm @@ -273,7 +263,7 @@ jobs: <<: *src_working_directory - run: name: Check for new npm vulnerabilities - command: npm run audit:check --silent -- --json > ./audit/results/auditResults.json + command: npm run audit:check --silent -- --json > ./audit/results/auditResults.json <<: *src_working_directory - store_artifacts: path: ./src/audit/results @@ -411,21 +401,19 @@ jobs: printf "\n%s\n" "The following vulnerabilities were found:" jq '[.vulnerabilities | group_by(.package) | .[] | {package: .[0].package, vuln: [.[].vuln]}]' anchore-reports/*vuln*.json fi - - run: name: Upload Anchore reports to s3 command: | aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive - + # TODO: Enable this when we want to increase the strictness of our security policies # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) # if [ $failCount -gt 0 ]; then # printf "Failed with a policy failure count of: ${failCount}" # exit 1 # fi - - store_artifacts: path: anchore-reports @@ -451,33 +439,6 @@ jobs: <<: *defaults_build_docker_publish - run: <<: *defaults_slack_announcement - - # deploy: - # executor: helm-kube - # steps: - # - checkout - # - run: - # name: Install AWS CLI dependencies - # command: *defaults_awsCliDependencies - # - run: - # name: setup environment vars for release/snapshot - # command: ./.circleci/_set_up_deploy_envs.sh - # - run: - # <<: *defaults_deploy_prequisites - # - run: - # <<: *defaults_deploy_config_kubernetes_cluster - # - run: - # <<: *defaults_deploy_config_kubernetes_credentials - # - run: - # <<: *defaults_deploy_config_kubernetes_context - # - run: - # <<: *defaults_deploy_set_kubernetes_context - # - run: - # <<: *defaults_deploy_configure_helm - # - run: - # <<: *defaults_deploy_install_or_upgrade_helm_chart - - ## # Workflows # From b955310fa0714bf18441f5025c8d167007e46be4 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 30 Apr 2020 11:59:53 +0100 Subject: [PATCH 08/35] Add build and publish to CI for init-central-ledger --- .circleci/config.yml | 78 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a9ea0ef5..65c6ce2d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -351,6 +351,22 @@ jobs: paths: - ./docker-image.tar + build-init-central-ledger: + executor: default-machine + steps: + - checkout + - run: + name: Build the central-ledger init container + command: | + docker build -t $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$CIRCLE_TAG . + - run: + name: Save the central-ledger init container docker image to workspace + command: docker save -o /tmp/docker-image-init-central-ledger.tar $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$CIRCLE_TAG + - persist_to_workspace: + root: /tmp + paths: + - ./docker-image-init-central-ledger.tar + license-scan: executor: default-machine steps: @@ -439,6 +455,41 @@ jobs: <<: *defaults_build_docker_publish - run: <<: *defaults_slack_announcement + + publish-init-central-ledger: + executor: default-machine + steps: + - checkout + - attach_workspace: + at: /tmp + - run: + name: Load the pre-built docker image for init-central-ledger from workspace + command: docker load -i /tmp/docker-image-init-central-ledger.tar + - run: + <<: *defaults_build_docker_login + - run: + name: Setup environment vars for release/snapshot + command: ./.circleci/_set_up_deploy_envs.sh + - run: + name: Re-tag pre built image + command: | + docker tag $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$RELEASE_TAG + - run: + name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for init-central-ledger + command: | + echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$CIRCLE_TAG" + docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$CIRCLE_TAG + echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$RELEASE_TAG" + docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$RELEASE_TAG + - run: + name: Slack announcement for tag releases + command: | + curl -X POST \ + $SLACK_WEBHOOK_ANNOUNCEMENT \ + -H 'Content-type: application/json' \ + -H 'cache-control: no-cache' \ + -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}-init-central-ledger* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" + ## # Workflows # @@ -515,6 +566,20 @@ workflows: branches: ignore: - /.*/ + - build-init-central-ledger: + context: org-global + requires: + - setup + - test-unit + - test-coverage + - vulnerability-check + - audit-licenses + filters: + tags: + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ + branches: + ignore: + - /.*/ - license-scan: context: org-global requires: @@ -545,4 +610,15 @@ workflows: only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ branches: ignore: - - /.*/ \ No newline at end of file + - /.*/ + - publish-init-central-ledger: + context: org-global + requires: + - license-scan + - image-scan + filters: + tags: + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ + branches: + ignore: + - /.*/ From d0ceb92b038438d2ad8034af0eff33d7e58fafc0 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 30 Apr 2020 12:33:10 +0100 Subject: [PATCH 09/35] Fix indentation --- .circleci/config.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 65c6ce2d..65720c55 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -482,13 +482,13 @@ jobs: echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$RELEASE_TAG" docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$RELEASE_TAG - run: - name: Slack announcement for tag releases - command: | - curl -X POST \ - $SLACK_WEBHOOK_ANNOUNCEMENT \ - -H 'Content-type: application/json' \ - -H 'cache-control: no-cache' \ - -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}-init-central-ledger* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" + name: Slack announcement for tag releases + command: | + curl -X POST \ + $SLACK_WEBHOOK_ANNOUNCEMENT \ + -H 'Content-type: application/json' \ + -H 'cache-control: no-cache' \ + -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}-init-central-ledger* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" ## # Workflows From 3580f5d0a3f7f19d25623a3c1a8feba25b52a296 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Tue, 16 Jun 2020 10:43:26 +0100 Subject: [PATCH 10/35] Update .circleci/config.yml Co-authored-by: Matt Kingston --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7ba4d69f..fcd0b08c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -472,7 +472,7 @@ jobs: - run: name: Re-tag pre built image command: | - docker tag $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$RELEASE_TAG + docker tag $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$CIRCLE_TAG $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$RELEASE_TAG - run: name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for init-central-ledger command: | From 0b3591cfc40c6e2a68e3f942523f520783b0109b Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Fri, 19 Jun 2020 14:20:04 +0100 Subject: [PATCH 11/35] Add ESLint and node-fetch --- init/central-ledger/.eslintrc.json | 6 + init/central-ledger/package-lock.json | 1691 +++++++++++++++++++++++++ init/central-ledger/package.json | 19 + 3 files changed, 1716 insertions(+) create mode 100644 init/central-ledger/.eslintrc.json create mode 100644 init/central-ledger/package-lock.json create mode 100644 init/central-ledger/package.json diff --git a/init/central-ledger/.eslintrc.json b/init/central-ledger/.eslintrc.json new file mode 100644 index 00000000..2ad15fd8 --- /dev/null +++ b/init/central-ledger/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": "airbnb-base", + "env": { + "node": true + } +} diff --git a/init/central-ledger/package-lock.json b/init/central-ledger/package-lock.json new file mode 100644 index 00000000..424e482a --- /dev/null +++ b/init/central-ledger/package-lock.json @@ -0,0 +1,1691 @@ +{ + "name": "init-central-ledger", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "dev": true + }, + "acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "confusing-browser-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", + "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.2.0.tgz", + "integrity": "sha512-B3BtEyaDKC5MlfDa2Ha8/D6DsS4fju95zs0hjS3HdGazw+LNayai38A25qMppK37wWGWNYSPOR6oYzlz5MHsRQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.1.0", + "eslint-utils": "^2.0.0", + "eslint-visitor-keys": "^1.2.0", + "espree": "^7.1.0", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "eslint-config-airbnb-base": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.0.tgz", + "integrity": "sha512-Snswd5oC6nJaevs3nZoLSTvGJBvzTfnBqOIArkf3cbyTyq9UD79wOk8s+RiL6bhca0p/eRO6veczhf6A/7Jy8Q==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.9", + "object.assign": "^4.1.0", + "object.entries": "^1.1.2" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.21.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.21.2.tgz", + "integrity": "sha512-FEmxeGI6yaz+SnEB6YgNHlQK1Bs2DKLM+YF+vuTk5H8J9CLbJLtlPvRFgZZ2+sXiKAlN5dpdlrWOjK8ZoZJpQA==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.3", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz", + "integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==", + "dev": true + }, + "espree": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", + "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", + "dev": true, + "requires": { + "acorn": "^7.2.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.2.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", + "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "inquirer": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.2.0.tgz", + "integrity": "sha512-E0c4rPwr9ByePfNlTIB8z51kK1s2n6jrHuJeEHENl/sbq2G/S1auvibgEwNR4uSyiU+PiYHqSwsgGiXjG8p5ZQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "has": "^1.0.3" + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", + "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + } + } +} diff --git a/init/central-ledger/package.json b/init/central-ledger/package.json new file mode 100644 index 00000000..55a3d3a6 --- /dev/null +++ b/init/central-ledger/package.json @@ -0,0 +1,19 @@ +{ + "name": "init-central-ledger", + "version": "1.0.0", + "description": "", + "main": "onboard-dfsp.js", + "dependencies": { + "node-fetch": "^2.6.0" + }, + "devDependencies": { + "eslint": "^7.2.0", + "eslint-config-airbnb-base": "^14.2.0", + "eslint-plugin-import": "^2.21.2" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Kamuela Franco ", + "license": "Apache-2.0" +} From ea95717784b8dfeba95c63834d9f8df6feb3b225 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Fri, 19 Jun 2020 16:28:45 +0100 Subject: [PATCH 12/35] Update config to master branch --- .circleci/config.yml | 423 ++++++++++++++----------------------------- 1 file changed, 132 insertions(+), 291 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fcd0b08c..2d6a33ec 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,14 @@ # CircleCI v2.1 Config version: 2.1 + +## +# orbs +# +# Orbs used in this pipeline +## orbs: anchore: anchore/anchore-engine@1.6.0 + deploy-kube: mojaloop/deployment@0.1.6 ## # defaults @@ -9,105 +16,23 @@ orbs: # YAML defaults templates, in alphabetical order ## defaults_Dependencies: &defaults_Dependencies | - apk --no-cache add git - apk --no-cache add ca-certificates - apk --no-cache add curl - apk --no-cache add openssh-client - apk add --no-cache -t build-dependencies make gcc g++ python libtool autoconf automake - npm config set unsafe-perm true - npm install -g node-gyp + apk --update --no-cache add \ + git \ + ca-certificates \ + curl \ + openssh-client \ + -t build-dependencies make gcc g++ python3 libtool autoconf automake + npm config set unsafe-perm true + npm install -g node-gyp defaults_awsCliDependencies: &defaults_awsCliDependencies | - apk --no-cache add \ - python3 \ - py3-pip \ - groff \ - less \ - mailcap - pip3 install --upgrade pip awscli==1.14.5 s3cmd==2.0.1 python-magic - -defaults_build_docker_build: &defaults_build_docker_build - name: Build Docker image - command: | - docker build -t $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG . - -defaults_build_docker_login: &defaults_build_docker_login - name: Login to Docker Hub - command: | - docker login -u $DOCKER_USER -p $DOCKER_PASS - -defaults_build_docker_publish: &defaults_build_docker_publish - name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub - command: | - echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG" - docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG - echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG" - docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG - -defaults_deploy_config_kubernetes_cluster: &defaults_deploy_config_kubernetes_cluster - name: Configure Kubernetes cluster - command: | - echo "Configure Kubernetes cluster ${K8_CLUSTER_NAME}" - kubectl config set-cluster $K8_CLUSTER_NAME --server=$K8_CLUSTER_SERVER --insecure-skip-tls-verify=true - -defaults_deploy_config_kubernetes_context: &defaults_deploy_config_kubernetes_context - name: Confi gure Kubernetes context - command: | - echo "Configure Kubernetes context ${K8_CLUSTER_NAME}" - kubectl config set-context $K8_CLUSTER_NAME --cluster=$K8_CLUSTER_NAME --user=$K8_USER_NAME --namespace=$K8_NAMESPACE - -defaults_deploy_config_kubernetes_credentials: &defaults_deploy_config_kubernetes_credentials - name: Configure Kubernetes credentails - command: | - echo "Configure Kubernetes credentials ${K8_USER_NAME}" - if [ ! -z "$K8_USER_TOKEN" ]; - then - echo "Configure Kubernetes credentials ${K8_USER_NAME} using Token" - kubectl config set-credentials $K8_USER_NAME --token=$K8_USER_TOKEN - else - echo "Configure Kubernetes credentials ${K8_USER_NAME} using Certs" - kubectl config set-credentials $K8_USER_NAME --client-certificate=$CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS/$K8_USER_PEM_CERT_FILENAME --client-key=$CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS/$K8_USER_PEM_KEY_FILENAME - fi - -defaults_deploy_configure_helm: &defaults_deploy_configure_helm - name: Configure Helm - command: | - helm init --client-only - -defaults_deploy_install_or_upgrade_helm_chart: &defaults_deploy_install_or_upgrade_helm_chart - name: Install or Upgrade Helm Chart - command: | - echo "Install or Upgrade Chart ${K8_RELEASE_NAME} for Docker Image ${DOCKER_ORG}/${CIRCLE_PROJECT_REPONAME}:${CIRCLE_TAG}" - if [ -z "$(helm list -q | grep -E "^${K8_RELEASE_NAME}$")" ] && [ "$(helm list -q | grep -E "^${K8_RELEASE_NAME}$")" != "Error: Unauthorized" ]; - then - echo "Installing ${K8_RELEASE_NAME} new release" - helm install --namespace=$K8_NAMESPACE --name=$K8_RELEASE_NAME --repo=$K8_HELM_REPO $HELM_VALUE_SET_VALUES -f $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_HELM/$HELM_VALUE_FILENAME $K8_HELM_CHART_NAME - else - echo "Upgrading ${K8_RELEASE_NAME} release" - helm upgrade $K8_RELEASE_NAME --repo=$K8_HELM_REPO --reuse-values $HELM_VALUE_SET_VALUES -f $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_HELM/$HELM_VALUE_FILENAME $K8_HELM_CHART_NAME - fi - -defaults_deploy_prequisites: &defaults_deploy_prequisites - name: Copy deployment pre-requisites from S3 bucket - command: | - if [ -z "$K8_USER_TOKEN" ]; - then - echo "Copying K8 keys into $AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS folder" - mkdir $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS - aws s3 cp $AWS_S3_URI_DEVOPS_DEPLOYMENT_CONFIG/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS/$K8_USER_PEM_KEY_FILENAME $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS/ - aws s3 cp $AWS_S3_URI_DEVOPS_DEPLOYMENT_CONFIG/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS/$K8_USER_PEM_CERT_FILENAME $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS/ - else - echo "Skipping K8 keys into $AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS folder" - fi - echo "Copying Helm value file into $AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_HELM folder for $K8_RELEASE_NAME release" - mkdir $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_HELM - aws s3 cp $AWS_S3_URI_DEVOPS_DEPLOYMENT_CONFIG/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_HELM/$HELM_VALUE_FILENAME $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_HELM/ - -defaults_deploy_set_kubernetes_context: &defaults_deploy_set_kubernetes_context - name: Set Kubernetes context - command: | - echo "Configure Kubernetes context ${K8_CLUSTER_NAME}" - kubectl config use-context $K8_CLUSTER_NAME + apk --update --no-cache add \ + python3 \ + py3-pip \ + groff \ + less \ + mailcap + pip3 install --upgrade awscli==1.14.5 s3cmd==2.0.1 python-magic defaults_license_scanner: &defaults_license_scanner name: Install and set up license-scanner @@ -115,19 +40,10 @@ defaults_license_scanner: &defaults_license_scanner git clone https://github.com/mojaloop/license-scanner /tmp/license-scanner cd /tmp/license-scanner && make build default-files set-up -defaults_slack_announcement: &defaults_slack_announcement - name: Slack announcement for tag releases - command: | - curl -X POST \ - $SLACK_WEBHOOK_ANNOUNCEMENT \ - -H 'Content-type: application/json' \ - -H 'cache-control: no-cache' \ - -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" - src_working_directory: &src_working_directory # The working directory for this project (place where package.json is) is /src, # as opposed to the project root - working_directory: /home/circleci/project/git/src + working_directory: ~/git/src ## # Executors @@ -138,18 +54,13 @@ executors: default-docker: working_directory: /home/circleci/project/git docker: - - image: node:12.16.0-alpine + - image: node:12.18.0-alpine default-machine: working_directory: /home/circleci/project/git machine: image: ubuntu-1604:201903-01 - helm-kube: - working_directory: /home/circleci/project - docker: - - image: hypnoglow/kubernetes-helm - ## # Jobs # @@ -164,72 +75,62 @@ jobs: name: Install general dependencies command: *defaults_Dependencies - run: - name: Access npm folder as root - command: cd $(npm root -g)/npm - - run: - name: Install node-gyp globally - command: npm install -g node-gyp + name: Update NPM install (using `npm ci`) + command: cd src && npm ci - run: - name: Update NPM install - command: npm install - <<: *src_working_directory + name: Delete build dependencies + command: apk del build-dependencies - save_cache: - key: dependency-cache-{{ checksum "./src/package.json" }} + key: dependency-cache-v1-{{ checksum "src/package-lock.json" }} paths: - - ./src/node_modules + - src/node_modules + - src/lib/log/node_modules + - src/lib/validate/node_modules test-unit: executor: default-docker steps: - checkout - - run: - name: Install general dependencies - command: *defaults_Dependencies - restore_cache: - key: dependency-cache-{{ checksum "./src/package.json" }} + key: dependency-cache-v1-{{ checksum "src/package-lock.json" }} + paths: + - src/node_modules + - src/lib/log/node_modules + - src/lib/validate/node_modules - run: - name: Install tape and tap-xunit - command: npm install tape tap-xunit - <<: *src_working_directory + name: Execute linting pass + command: cd src && npm run lint - run: name: Create dir for test results command: mkdir -p ./test/results - <<: *src_working_directory - - run: - name: Install tapes - command: npm install -g tapes - <<: *src_working_directory - run: name: Execute unit tests - command: npm -s run test:xunit > ./test/results/tape.xml - <<: *src_working_directory + command: cd src && npm run test > ../test/results/results.txt - store_artifacts: - path: ./src/test/results + path: ./test/results prefix: test - store_test_results: - path: ./src/test/results + path: ./test/results test-coverage: executor: default-docker steps: - checkout + - restore_cache: + key: dependency-cache-v1-{{ checksum "src/package-lock.json" }} + paths: + - src/node_modules + - src/lib/log/node_modules + - src/lib/validate/node_modules - run: name: Install general dependencies command: *defaults_Dependencies - run: name: Install AWS CLI dependencies command: *defaults_awsCliDependencies - - restore_cache: - keys: - - dependency-cache-{{ checksum "./src/package.json" }} - - run: - name: Run install again for nested package.json files - command: npm install - <<: *src_working_directory - run: name: Execute code coverage check - command: npm -s run test:coverage-check - <<: *src_working_directory + command: cd src && npm -s run test:coverage-check - store_artifacts: path: ./src/coverage prefix: test @@ -245,103 +146,67 @@ jobs: else echo "Not a release (env CIRCLE_BRANCH != 'master'), skipping sending lcov.info to SonarQube." fi - <<: *src_working_directory vulnerability-check: executor: default-docker steps: - checkout + - restore_cache: + key: dependency-cache-v1-{{ checksum "src/package-lock.json" }} + paths: + - src/node_modules + - src/lib/log/node_modules + - src/lib/validate/node_modules - run: name: Install general dependencies command: *defaults_Dependencies - - restore_cache: - key: dependency-cache-{{ checksum "./src/package.json" }} - run: name: Create dir for test results command: mkdir -p ./audit/results - <<: *src_working_directory - run: name: Check for new npm vulnerabilities - command: npm run audit:check --silent -- --json > ./audit/results/auditResults.json - <<: *src_working_directory + command: cd src && npm run audit:check --silent -- --json > ../audit/results/auditResults.json - store_artifacts: - path: ./src/audit/results + path: ./audit/results prefix: audit audit-licenses: executor: default-docker steps: - checkout + - restore_cache: + key: dependency-cache-v1-{{ checksum "src/package-lock.json" }} + paths: + - src/node_modules + - src/lib/log/node_modules + - src/lib/validate/node_modules - run: name: Install general dependencies command: *defaults_Dependencies - run: <<: *defaults_license_scanner - - restore_cache: - key: dependency-cache-{{ checksum "./src/package.json" }} - run: name: Run the license-scanner command: cd /tmp/license-scanner && pathToRepo=$CIRCLE_WORKING_DIRECTORY make run - <<: *src_working_directory - store_artifacts: path: /tmp/license-scanner/results prefix: licenses - test-integration: - executor: default-machine - steps: - - checkout - - restore_cache: - key: dependency-cache-{{ checksum "./src/package.json" }} - - run: - name: Create dir for test results - command: mkdir -p ./test/results - <<: *src_working_directory - - run: - name: Execute integration tests - command: npm -s run test:integration - <<: *src_working_directory - - store_artifacts: - path: ./src/test/results - prefix: test - - store_test_results: - path: ./src/test/results - - test-functional: - executor: default-machine - steps: - - checkout - - run: - name: Add the Postgres 9.6 binaries to the path. - command: echo ‘/usr/lib/postgresql/9.6/bin/:$PATH’ >> $BASH_ENV - - run: - name: Install Docker Compose - command: | - curl -L https://github.com/docker/compose/releases/download/1.11.2/docker-compose-`uname -s`-`uname -m` > ~/docker-compose - chmod +x ~/docker-compose - mv ~/docker-compose /usr/local/bin/docker-compose - - restore_cache: - key: dependency-cache-{{ checksum "./src/package.json" }} - - run: - name: Create dir for test results - command: mkdir -p ./test/results - <<: *src_working_directory - - run: - name: Execute functional tests - command: npm -s run test:functional - <<: *src_working_directory - - store_artifacts: - path: ./src/test/results - prefix: test - - store_test_results: - path: ./src/test/results - build: executor: default-machine steps: - checkout - run: - <<: *defaults_build_docker_build + name: Build Docker $CIRCLE_TAG image + command: > + echo "Building Docker image: $CIRCLE_TAG" + + docker build + --build-arg=BUILD_DATE="$(date -u --iso-8601=seconds)" + --build-arg=VERSION="$RELEASE_TAG" + --build-arg=VCS_URL="$CIRCLE_REPOSITORY_URL" + --build-arg=VCS_REF="$CIRCLE_SHA1" + -t $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG . - run: name: Save docker image to workspace command: docker save -o /tmp/docker-image.tar $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG @@ -350,25 +215,33 @@ jobs: paths: - ./docker-image.tar - build-init-central-ledger: + build-local: executor: default-machine steps: - checkout - run: - name: Build the central-ledger init container - command: | - docker build -t $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$CIRCLE_TAG . + name: Build Docker local image for testing + command: > + echo "Building Docker image: local" + + docker build + --build-arg=BUILD_DATE="$(date -u --iso-8601=seconds)" + --build-arg=VERSION="local" + --build-arg=VCS_URL="$CIRCLE_REPOSITORY_URL" + --build-arg=VCS_REF="$CIRCLE_SHA1" + -t $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:local . - run: - name: Save the central-ledger init container docker image to workspace - command: docker save -o /tmp/docker-image-init-central-ledger.tar $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$CIRCLE_TAG + name: Save docker image to workspace + command: docker save -o /tmp/docker-image.tar $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:local - persist_to_workspace: root: /tmp paths: - - ./docker-image-init-central-ledger.tar + - ./docker-image.tar license-scan: executor: default-machine steps: + - checkout - attach_workspace: at: /tmp - run: @@ -378,7 +251,7 @@ jobs: <<: *defaults_license_scanner - run: name: Run the license-scanner - command: cd /tmp/license-scanner && mode=docker dockerImage=$DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG make run + command: cd /tmp/license-scanner && mode=docker dockerImages=$DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:local make run - store_artifacts: path: /tmp/license-scanner/results prefix: licenses @@ -398,7 +271,7 @@ jobs: command: docker load -i /tmp/docker-image.tar - anchore/analyze_local_image: dockerfile_path: ./Dockerfile - image_name: ${DOCKER_ORG}/${CIRCLE_PROJECT_REPONAME}:${CIRCLE_TAG} + image_name: ${DOCKER_ORG}/${CIRCLE_PROJECT_REPONAME}:local # Anchore bug: if policy_failure is `true`, reports don't get written - we manually check for failures below policy_failure: false timeout: '500' @@ -425,6 +298,7 @@ jobs: # TODO: Enable this when we want to increase the strictness of our security policies # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) + # echo "FailCount is: ${failCount}" # if [ $failCount -gt 0 ]; then # printf "Failed with a policy failure count of: ${failCount}" # exit 1 @@ -442,44 +316,19 @@ jobs: name: Load the pre-built docker image from workspace command: docker load -i /tmp/docker-image.tar - run: - <<: *defaults_build_docker_login - - run: - name: setup environment vars for release/snapshot - command: ./.circleci/_set_up_deploy_envs.sh + name: Login to Docker Hub + command: docker login -u $DOCKER_USER -p $DOCKER_PASS - run: name: Re-tag pre built image command: | docker tag $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG - run: - <<: *defaults_build_docker_publish - - run: - <<: *defaults_slack_announcement - - publish-init-central-ledger: - executor: default-machine - steps: - - checkout - - attach_workspace: - at: /tmp - - run: - name: Load the pre-built docker image for init-central-ledger from workspace - command: docker load -i /tmp/docker-image-init-central-ledger.tar - - run: - <<: *defaults_build_docker_login - - run: - name: Setup environment vars for release/snapshot - command: ./.circleci/_set_up_deploy_envs.sh - - run: - name: Re-tag pre built image - command: | - docker tag $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$CIRCLE_TAG $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$RELEASE_TAG - - run: - name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for init-central-ledger + name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub command: | - echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$CIRCLE_TAG" - docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$CIRCLE_TAG - echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$RELEASE_TAG" - docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$RELEASE_TAG + echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG" + docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG + echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG" + docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG - run: name: Slack announcement for tag releases command: | @@ -487,7 +336,16 @@ jobs: $SLACK_WEBHOOK_ANNOUNCEMENT \ -H 'Content-type: application/json' \ -H 'cache-control: no-cache' \ - -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}-init-central-ledger* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" + -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" + + deploy: + executor: deploy-kube/helm-kube + steps: + - checkout + - deploy-kube/setup_and_run: + helm_set_values: | + --set finance-portal.frontend.image.repository=$DOCKER_ORG/$CIRCLE_PROJECT_REPONAME \ + --set finance-portal.frontend.image.tag=$CIRCLE_TAG ## # Workflows @@ -507,92 +365,77 @@ workflows: ignore: - /feature*/ - /bugfix*/ + - /hotfix*/ - test-unit: context: org-global requires: - setup filters: - tags: - only: /.*/ branches: ignore: - /feature*/ - /bugfix*/ + - /hotfix*/ - test-coverage: context: org-global requires: - setup filters: - tags: - only: /.*/ branches: ignore: - /feature*/ - /bugfix*/ + - /hotfix*/ - vulnerability-check: context: org-global requires: - setup filters: - tags: - only: /.*/ branches: ignore: - /feature*/ - /bugfix*/ + - /hotfix*/ - audit-licenses: context: org-global requires: - setup filters: - tags: - only: /.*/ branches: ignore: - /feature*/ - /bugfix*/ - - build: + - /hotfix*/ + - build-local: context: org-global - requires: - - setup - - test-unit - - test-coverage - - vulnerability-check - - audit-licenses filters: - tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ branches: ignore: - - /.*/ - - build-init-central-ledger: + - /feature*/ + - /bugfix*/ + - /hotfix*/ + - license-scan: context: org-global requires: - - setup - - test-unit - - test-coverage - - vulnerability-check - - audit-licenses + - build-local filters: - tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ branches: ignore: - - /.*/ - - license-scan: + - /feature*/ + - /bugfix*/ + - /hotfix*/ + - image-scan: context: org-global requires: - - build + - build-local filters: - tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ branches: ignore: - - /.*/ - - image-scan: + - /feature*/ + - /bugfix*/ + - /hotfix*/ + - build: context: org-global - requires: - - build filters: tags: only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ @@ -602,22 +445,20 @@ workflows: - publish: context: org-global requires: - - license-scan - - image-scan + - build filters: tags: only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ branches: ignore: - /.*/ - - publish-init-central-ledger: + - deploy: context: org-global requires: - - license-scan - - image-scan + - publish filters: tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?/ branches: ignore: - /.*/ From 192d8bd682901b2ed21833ff5502319d041e37d6 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Mon, 29 Jun 2020 13:51:28 +0100 Subject: [PATCH 13/35] Add onboarding steps --- .circleci/config.yml | 74 + .dockerignore | 3 + init/central-ledger/Dockerfile | 43 - ...nboard-Generic-FSP.postman_collection.json | 1201 ----------------- .../.eslintrc.json | 0 init/onboard-central-ledger/.gitignore | 1 + init/onboard-central-ledger/Dockerfile | 32 + init/onboard-central-ledger/onboard-dfsp.js | 229 ++++ .../package-lock.json | 48 +- .../package.json | 9 +- 10 files changed, 393 insertions(+), 1247 deletions(-) delete mode 100644 init/central-ledger/Dockerfile delete mode 100644 init/central-ledger/Onboard-Generic-FSP.postman_collection.json rename init/{central-ledger => onboard-central-ledger}/.eslintrc.json (100%) create mode 100644 init/onboard-central-ledger/.gitignore create mode 100644 init/onboard-central-ledger/Dockerfile create mode 100644 init/onboard-central-ledger/onboard-dfsp.js rename init/{central-ledger => onboard-central-ledger}/package-lock.json (96%) rename init/{central-ledger => onboard-central-ledger}/package.json (62%) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2d6a33ec..a35c7eb5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -215,6 +215,29 @@ jobs: paths: - ./docker-image.tar + build-onboard-central-ledger: + executor: default-machine + steps: + - checkout + - run: + name: Build Docker $CIRCLE_TAG image + command: > + echo "Building Docker image: $CIRCLE_TAG" + + docker build + --build-arg=BUILD_DATE="$(date -u --iso-8601=seconds)" + --build-arg=VERSION="$RELEASE_TAG" + --build-arg=VCS_URL="$CIRCLE_REPOSITORY_URL" + --build-arg=VCS_REF="$CIRCLE_SHA1" + -t $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-onboard-central-ledger:$CIRCLE_TAG . + - run: + name: Save docker image to workspace + command: docker save -o /tmp/docker-image-onboard-central-ledger.tar $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-onboard-central-ledger:$CIRCLE_TAG + - persist_to_workspace: + root: /tmp + paths: + - ./docker-image-onboard-central-ledger.tar + build-local: executor: default-machine steps: @@ -238,6 +261,22 @@ jobs: paths: - ./docker-image.tar + build-local-onboard-central-ledger: + executor: default-machine + steps: + - checkout + - run: + name: Build the central-ledger init container + command: | + docker build -t $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$CIRCLE_TAG . + - run: + name: Save the central-ledger init container docker image to workspace + command: docker save -o /tmp/docker-image-init-central-ledger.tar $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-init-central-ledger:$CIRCLE_TAG + - persist_to_workspace: + root: /tmp + paths: + - ./docker-image-init-central-ledger.tar + license-scan: executor: default-machine steps: @@ -338,6 +377,41 @@ jobs: -H 'cache-control: no-cache' \ -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" +publish-onboard-central-ledger: + executor: default-machine + steps: + - checkout + - attach_workspace: + at: /tmp + - run: + name: Load the pre-built docker image for onboard-central-ledger from workspace + command: docker load -i /tmp/docker-image-onboard-central-ledger.tar + - run: + name: Login to Docker Hub + command: docker login -u $DOCKER_USER -p $DOCKER_PASS + - run: + name: Setup environment vars for release/snapshot + command: ./.circleci/_set_up_deploy_envs.sh + - run: + name: Re-tag pre built image + command: | + docker tag $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-onboard-central-ledger:$CIRCLE_TAG $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-onboard-central-ledger:$RELEASE_TAG + - run: + name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for onboard-central-ledger + command: | + echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-onboard-central-ledger:$CIRCLE_TAG" + docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-onboard-central-ledger:$CIRCLE_TAG + echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-onboard-central-ledger:$RELEASE_TAG" + docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME-onboard-central-ledger:$RELEASE_TAG + - run: + name: Slack announcement for tag releases + command: | + curl -X POST \ + $SLACK_WEBHOOK_ANNOUNCEMENT \ + -H 'Content-type: application/json' \ + -H 'cache-control: no-cache' \ + -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}-onboard-central-ledger* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" + deploy: executor: deploy-kube/helm-kube steps: diff --git a/.dockerignore b/.dockerignore index 04a8318e..c6e0e219 100644 --- a/.dockerignore +++ b/.dockerignore @@ -45,6 +45,9 @@ typings/ # Optional eslint cache .eslintcache +# ESlint config +.eslintrc.json + # Optional REPL history .node_repl_history diff --git a/init/central-ledger/Dockerfile b/init/central-ledger/Dockerfile deleted file mode 100644 index 0298c700..00000000 --- a/init/central-ledger/Dockerfile +++ /dev/null @@ -1,43 +0,0 @@ -FROM postman/newman:5.0.0-alpine - -ARG CREATED -ARG SOURCE -ARG REVISION -ARG VERSION - -# See https://github.com/opencontainers/image-spec/blob/master/annotations.md#pre-defined-annotation-keys and https://github.com/opencontainers/image-spec/blob/master/spec.md for info -LABEL org.opencontainers.image.created=${CREATED} -LABEL org.opencontainers.image.url="https://mojaloop.io/" -LABEL org.opencontainers.image.source=${SOURCE} -LABEL org.opencontainers.image.version=${VERSION} -LABEL org.opencontainers.image.revision=${REVISION} -LABEL org.opencontainers.image.title="init-central-ledger" -LABEL org.opencontainers.image.authors="kamuela.franco@modusbox.com" -LABEL org.opencontainers.image.licenses="Apache-2.0" - -WORKDIR /opt/init-central-ledger -COPY . . - -CMD newman run \ - --delay-request=${DELAY_REQUEST} \ - --env-var "HOST_CENTRAL_LEDGER=${HOST_CENTRAL_LEDGER}" \ - --env-var "BASE_CENTRAL_LEDGER_ADMIN=${BASE_CENTRAL_LEDGER_ADMIN}" \ - --env-var "DFSP_NAME=${DFSP_NAME}" \ - --env-var "HUB_OPERATOR=${HUB_OPERATOR}" \ - --env-var "HUB_OPERATOR_BEARER_TOKEN=${HUB_OPERATOR_BEARER_TOKEN}" \ - --env-var "DFSP_CURRENCY=${DFSP_CURRENCY}" \ - --env-var "INITIAL_NET_DEBIT_CAP=${INITIAL_NET_DEBIT_CAP}" \ - --env-var "INITIAL_POSITION=${INITIAL_POSITION}" \ - --env-var "GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID=${GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID}" \ - --env-var "FUNDS_IN_PREPARE_AMOUNT=${FUNDS_IN_PREPARE_AMOUNT}" \ - --env-var "FUNDS_IN_PREPARE_TRANSFER_ID=${FUNDS_IN_PREPARE_TRANSFER_ID}" \ - --env-var "GENERIC_DFSP_SETTLEMENT_ACCOUNT_BALANCE_BEFORE_FUNDS_IN=${GENERIC_DFSP_SETTLEMENT_ACCOUNT_BALANCE_BEFORE_FUNDS_IN}" \ - --env-var "HUB_NAME=${HUB_NAME}" \ - --env-var "HUB_RECONCILIATION_ACCOUNT_BALANCE_BEFORE_FUNDS_IN=${HUB_RECONCILIATION_ACCOUNT_BALANCE_BEFORE_FUNDS_IN}" \ - --env-var "GENERIC_DFSP_CALLBACK_URL=${GENERIC_DFSP_CALLBACK_URL}" \ - --env-var "REQUEST_ID=${REQUEST_ID}" \ - --env-var "TRANSFER_ID=${TRANSFER_ID}" \ - --env-var "NDC_THRESHOLD_BREACH_EMAIL=${NDC_THRESHOLD_BREACH_EMAIL}" \ - --env-var "NDC_ADJUSTMENT_EMAIL=${NDC_ADJUSTMENT_EMAIL}" \ - --env-var "SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL=${SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL}" \ - "Onboard-Generic-FSP.postman_collection.json" diff --git a/init/central-ledger/Onboard-Generic-FSP.postman_collection.json b/init/central-ledger/Onboard-Generic-FSP.postman_collection.json deleted file mode 100644 index 0bdbf943..00000000 --- a/init/central-ledger/Onboard-Generic-FSP.postman_collection.json +++ /dev/null @@ -1,1201 +0,0 @@ -{ - "info": { - "_postman_id": "f4aa52b2-fb4a-44d3-9a23-75fc65e3f486", - "name": "Onboard-Generic-FSP", - "description": "Author: Kamuela Franco\nPurpose: Used to add new FSP and relevant Callback Information", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "Add Generic DFSP", - "event": [ - { - "listen": "test", - "script": { - "id": "8869fdc9-c7b7-40da-b9da-c56308e3177a", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "value": "application/json", - "type": "text" - }, - { - "key": "FSPIOP-Source", - "value": "{{HUB_OPERATOR}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\"name\": \"{{DFSP_NAME}}\",\"currency\": \"{{DFSP_CURRENCY}}\"}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants" - ] - } - }, - "response": [] - }, - { - "name": "Add initial position and limits - Generic DFSP", - "event": [ - { - "listen": "test", - "script": { - "id": "e56b7c34-cc1a-4fd6-87c9-c4164b446036", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/json" - }, - { - "key": "FSPIOP-Source", - "type": "text", - "value": "{{HUB_OPERATOR}}" - } - ], - "body": { - "mode": "raw", - "raw": "{\n\t\"currency\": \"{{DFSP_CURRENCY}}\",\n\t\"limit\": {\n\t \"type\": \"NET_DEBIT_CAP\",\n\t \"value\": {{INITIAL_NET_DEBIT_CAP}}\n\t},\n\t\"initialPosition\": {{INITIAL_POSITION}}\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/initialPositionAndLimits", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "initialPositionAndLimits" - ] - } - }, - "response": [] - }, - { - "name": "Deposit Funds in Settlement Account - Generic DFSP", - "event": [ - { - "listen": "prerequest", - "script": { - "id": "336b2f23-c2fb-41fe-8686-bafe38b85542", - "exec": [ - "var uuid = require('uuid');", - "var generatedUUID = uuid.v4();", - "pm.environment.set('FUNDS_IN_PREPARE_TRANSFER_ID', generatedUUID);", - "pm.environment.set('FUNDS_IN_PREPARE_AMOUNT', 1000);", - "", - "const genericDfspGetStatusRequest = {", - " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/{{DFSP_NAME}}/accounts',", - " method: 'GET',", - " header: {", - " \"Authorization\":\"Bearer \"+pm.environment.get(\"HUB_OPERATOR_BEARER_TOKEN\"),", - " \"FSPIOP-Source\": pm.environment.get(\"HUB_OPERATOR\"),", - " \"Content-Type\": \"application/json\"", - " }", - "};", - "pm.sendRequest(genericDfspGetStatusRequest, function (err, response) {", - " console.log(response.json())", - " var jsonData = response.json()", - " for(var i in jsonData) {", - " if(jsonData[i].ledgerAccountType === 'SETTLEMENT') {", - " pm.environment.set(\"GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID\",jsonData[i].id)", - " pm.environment.set(\"GENERIC_DFSP_SETTLEMENT_ACCOUNT_BALANCE_BEFORE_FUNDS_IN\",jsonData[i].value)", - " }", - " }", - "});", - "", - "const hubGetStatusRequest = {", - " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/{{HUB_NAME}}/accounts',", - " method: 'GET',", - " header: {", - " \"Authorization\":\"Bearer \"+pm.environment.get(\"HUB_OPERATOR_BEARER_TOKEN\"),", - " \"FSPIOP-Source\": pm.environment.get(\"HUB_OPERATOR\"),", - " \"Content-Type\": \"application/json\"", - " }", - "};", - "pm.sendRequest(hubGetStatusRequest, function (err, response) {", - " console.log(response.json())", - " response.json()", - " .filter( ledgerAccount => (ledgerAccount.currency === pm.environment.get('DFSP_CURRENCY') && ledgerAccount.ledgerAccountType === 'HUB_RECONCILIATION'))", - " .forEach(account => pm.environment.set(\"HUB_RECONCILIATION_ACCOUNT_BALANCE_BEFORE_FUNDS_IN\",account.value))", - "});", - "" - ], - "type": "text/javascript" - } - }, - { - "listen": "test", - "script": { - "id": "a085486c-acf5-4b04-8123-9f85cea73a07", - "exec": [ - "pm.test(\"Status code is 202\", function () {", - " pm.response.to.have.status(202);", - "});", - "", - "setTimeout(function () {", - " const genericDfspGetStatusRequest = {", - " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/'+pm.environment.get(\"DFSP_NAME\")+'/accounts',", - " method: 'GET',", - " header: {", - " \"Authorization\":\"Bearer \"+pm.environment.get(\"HUB_OPERATOR_BEARER_TOKEN\"),", - " \"FSPIOP-Source\": pm.environment.get(\"HUB_OPERATOR\"),", - " \"Content-Type\": \"application/json\"", - " }", - " };", - " pm.sendRequest(genericDfspGetStatusRequest, function (err, response) {", - " console.log(response.json())", - " var jsonData = response.json()", - " var genericDfspSettlementAccountBalanceAfterFundsIn", - " for(var i in jsonData) {", - " if(jsonData[i].ledgerAccountType === 'SETTLEMENT') {", - " payerfspSettlementAccountBalanceAfterFundsIn = jsonData[i].value", - " }", - " }", - " var genericDfspExpectedBalance = pm.environment.get('GENERIC_DFSP_SETTLEMENT_ACCOUNT_BALANCE_BEFORE_FUNDS_IN') - pm.environment.get('FUNDS_IN_PREPARE_AMOUNT')", - " pm.test(\"Final Generic DFSP Settlement Account Balance should be same as before FundsIn + fundsInPrepareAmount\", function () {", - " pm.expect(genericDfspSettlementAccountBalanceAfterFundsIn).to.eql(genericDfspExpectedBalance);", - " }); ", - " ", - " });", - " ", - " const hubGetStatusRequest = {", - " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/{{HUB_NAME}}/accounts',", - " method: 'GET',", - " header: {", - " \"Authorization\":\"Bearer \"+pm.environment.get(\"HUB_OPERATOR_BEARER_TOKEN\"),", - " \"FSPIOP-Source\": pm.environment.get(\"HUB_OPERATOR\"),", - " \"Content-Type\": \"application/json\"", - " }", - " };", - " pm.sendRequest(hubGetStatusRequest, function (err, response) {", - " console.log(response.json())", - " var jsonData = response.json()", - " var currentHubReconAccountBalance", - " response.json()", - " .filter( ledgerAccount => (ledgerAccount.currency === pm.environment.get('DFSP_CURRENCY') && ledgerAccount.ledgerAccountType === 'HUB_RECONCILIATION'))", - " .forEach(account => hubReconAccountBalanceAfterFundsIn = account.value)", - " // for(var i in jsonData) {", - " // if(jsonData[i].ledgerAccountType === 'HUB_RECONCILIATION') {", - " // hubReconAccountBalanceAfterFundsIn = jsonData[i].value", - " // }", - " // }", - " var hubExpectedBalance = pm.environment.get(\"HUB_RECONCILIATION_ACCOUNT_BALANCE_BEFORE_FUNDS_IN\")+pm.environment.get('FUNDS_IN_PREPARE_AMOUNT')", - " console.log(hubExpectedBalance)", - " pm.test(\"Final Hub Reconciliation Account Balance should increase by FundsIn Amount\", function () {", - " pm.expect(hubReconAccountBalanceAfterFundsIn).to.eql(hubExpectedBalance);", - " }); ", - " });", - "}, 2000)" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "FSPIOP-Source", - "type": "text", - "value": "{{HUB_OPERATOR}}" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"transferId\": \"{{FUNDS_IN_PREPARE_TRANSFER_ID}}\",\n \"externalReference\": \"string\",\n \"action\": \"recordFundsIn\",\n \"reason\": \"string\",\n \"amount\": {\n \"amount\": {{FUNDS_IN_PREPARE_AMOUNT}},\n \"currency\": \"{{DFSP_CURRENCY}}\"\n },\n \"extensionList\": {\n \"extension\": [\n {\n \"key\": \"string\",\n \"value\": \"string\"\n }\n ]\n }\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/accounts/{{GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID}}", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "accounts", - "{{GENERIC_DFSP_SETTLEMENT_ACCOUNT_ID}}" - ] - } - }, - "response": [] - }, - { - "name": "Add Generic DFSP callback - PARTICIPANT PUT", - "event": [ - { - "listen": "test", - "script": { - "id": "6438cf7a-96d3-40c9-ac00-0d8a5f87bbd9", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/json" - }, - { - "key": "FSPIOP-Source", - "value": "{{HUB_OPERATOR}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_PUT\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/participants/{{partyIdType}}/{{partyIdentifier}}\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - } - }, - "response": [] - }, - { - "name": "Add Generic DFSP callback - PARTICIPANT PUT Error", - "event": [ - { - "listen": "test", - "script": { - "id": "7bbe328e-7e30-497b-b5a3-6890480c1bbb", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/participants/{{partyIdType}}/{{partyIdentifier}}/error\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - } - }, - "response": [] - }, - { - "name": "Add Generic DFSP callback - PARTICIPANT PUT Batch", - "event": [ - { - "listen": "test", - "script": { - "id": "7d923fd4-5a1f-4697-ba30-94e0a2fbc8bc", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/participants/{{requestId}}\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - } - }, - "response": [] - }, - { - "name": "Add Generic DFSP callback - PARTICIPANT PUT Batch Error", - "event": [ - { - "listen": "test", - "script": { - "id": "b4a643af-f8e0-4aaa-955c-90b65cc14a17", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/participants/{{requestId}}/error\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - } - }, - "response": [] - }, - { - "name": "Add Generic DFSP callback - PARTIES GET", - "event": [ - { - "listen": "test", - "script": { - "id": "2658b8a2-07d2-4ae8-95fe-5fac947ba5a8", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_GET\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/parties/{{partyIdType}}/{{partyIdentifier}}\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - } - }, - "response": [] - }, - { - "name": "Add Generic DFSP callback - PARTIES PUT", - "event": [ - { - "listen": "test", - "script": { - "id": "b121ee1f-7cdb-4814-998f-1ab25f35447c", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_PUT\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/parties/{{partyIdType}}/{{partyIdentifier}}\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - } - }, - "response": [] - }, - { - "name": "Add Generic DFSP callback - PARTIES PUT Error", - "event": [ - { - "listen": "test", - "script": { - "id": "56129f5c-9baf-46d7-b9a5-59f173436943", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/parties/{{partyIdType}}/{{partyIdentifier}}/error\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - } - }, - "response": [] - }, - { - "name": "Add Generic DFSP callback - QUOTES", - "event": [ - { - "listen": "test", - "script": { - "id": "78205452-8053-4c6c-9b3e-172c19db0b29", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/json" - }, - { - "key": "FSPIOP-Source", - "value": "{{HUB_OPERATOR}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_QUOTES\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - } - }, - "response": [] - }, - { - "name": "Add Generic DFSP callback - TRANSFER POST", - "event": [ - { - "listen": "test", - "script": { - "id": "3bb02ebd-e56f-46d7-b32c-8238c4178837", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/json" - }, - { - "key": "FSPIOP-Source", - "value": "{{HUB_OPERATOR}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_POST\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/transfers\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - } - }, - "response": [] - }, - { - "name": "Add Generic DFSP callback - TRANSFER PUT", - "event": [ - { - "listen": "test", - "script": { - "id": "0d761f7f-51bf-4776-9907-217fc9665fbd", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/json" - }, - { - "key": "FSPIOP-Source", - "value": "{{HUB_OPERATOR}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_PUT\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/transfers/{{transferId}}\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - } - }, - "response": [] - }, - { - "name": "Add Generic DFSP callback - TRANSFER ERROR", - "event": [ - { - "listen": "test", - "script": { - "id": "936c1758-326b-4348-9dd3-2ea5f05a6091", - "exec": [ - "pm.test(\"Status code is 201\", function () {", - " pm.response.to.have.status(201);", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/json" - }, - { - "key": "FSPIOP-Source", - "value": "{{HUB_OPERATOR}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_ERROR\",\n \"value\": \"{{GENERIC_DFSP_CALLBACK_URL}}/transfers/{{transferId}}/error\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - } - }, - "response": [] - }, - { - "name": "Set Email-NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL", - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Cache-Control", - "value": "no-cache" - }, - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "FSPIOP-Source", - "value": "{{DFSP_NAME}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL\",\n \"value\": \"{{NDC_THRESHOLD_BREACH_EMAIL}}\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - }, - "description": "Generated from a curl request: \ncurl -i -X POST http://test-central-ledger.mojaloop.test/admin/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" - }, - "response": [ - { - "name": "2. Create Initial Position and Limits", - "originalRequest": { - "method": "POST", - "header": [ - { - "key": "Cache-Control", - "value": "no-cache" - }, - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" - }, - "url": { - "raw": "http://test-central-ledger.mojaloop.live/admin/participants/testfsp/initialPositionAndLimits", - "protocol": "http", - "host": [ - "test-central-ledger", - "mojaloop", - "live" - ], - "path": [ - "admin", - "participants", - "testfsp", - "initialPositionAndLimits" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "Text", - "header": [], - "cookie": [], - "body": "" - } - ] - }, - { - "name": "Set Email-NET_DEBIT_CAP_ADJUSTMENT_EMAIL", - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Cache-Control", - "value": "no-cache" - }, - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "FSPIOP-Source", - "value": "{{HUB_OPERATOR}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"NET_DEBIT_CAP_ADJUSTMENT_EMAIL\",\n \"value\": \"{{NDC_ADJUSTMENT_EMAIL}}\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - }, - "description": "Generated from a curl request: \ncurl -i -X POST http://test-central-ledger.mojaloop.test/admin/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" - }, - "response": [ - { - "name": "2. Create Initial Position and Limits", - "originalRequest": { - "method": "POST", - "header": [ - { - "key": "Cache-Control", - "value": "no-cache" - }, - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" - }, - "url": { - "raw": "http://test-central-ledger.mojaloop.live/admin/participants/testfsp/initialPositionAndLimits", - "protocol": "http", - "host": [ - "test-central-ledger", - "mojaloop", - "live" - ], - "path": [ - "admin", - "participants", - "testfsp", - "initialPositionAndLimits" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "Text", - "header": [], - "cookie": [], - "body": "" - } - ] - }, - { - "name": "Set Email-SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL", - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{HUB_OPERATOR_BEARER_TOKEN}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Cache-Control", - "value": "no-cache" - }, - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "FSPIOP-Source", - "value": "{{DFSP_NAME}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL\",\n \"value\": \"{{SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL}}\"\n}" - }, - "url": { - "raw": "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}/participants/{{DFSP_NAME}}/endpoints", - "host": [ - "{{HOST_CENTRAL_LEDGER}}{{BASE_CENTRAL_LEDGER_ADMIN}}" - ], - "path": [ - "participants", - "{{DFSP_NAME}}", - "endpoints" - ] - }, - "description": "Generated from a curl request: \ncurl -i -X POST http://test-central-ledger.mojaloop.test/admin/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" - }, - "response": [ - { - "name": "2. Create Initial Position and Limits", - "originalRequest": { - "method": "POST", - "header": [ - { - "key": "Cache-Control", - "value": "no-cache" - }, - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" - }, - "url": { - "raw": "http://test-central-ledger.mojaloop.live/admin/participants/testfsp/initialPositionAndLimits", - "protocol": "http", - "host": [ - "test-central-ledger", - "mojaloop", - "live" - ], - "path": [ - "admin", - "participants", - "testfsp", - "initialPositionAndLimits" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "Text", - "header": [], - "cookie": [], - "body": "" - } - ] - } - ], - "event": [ - { - "listen": "prerequest", - "script": { - "id": "a3e74abc-7be6-49d7-88a1-1233d0582556", - "type": "text/javascript", - "exec": [ - "" - ] - } - }, - { - "listen": "test", - "script": { - "id": "8e145984-2c7d-449e-918b-282655772ed3", - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ], - "protocolProfileBehavior": {} -} diff --git a/init/central-ledger/.eslintrc.json b/init/onboard-central-ledger/.eslintrc.json similarity index 100% rename from init/central-ledger/.eslintrc.json rename to init/onboard-central-ledger/.eslintrc.json diff --git a/init/onboard-central-ledger/.gitignore b/init/onboard-central-ledger/.gitignore new file mode 100644 index 00000000..4c49bd78 --- /dev/null +++ b/init/onboard-central-ledger/.gitignore @@ -0,0 +1 @@ +.env diff --git a/init/onboard-central-ledger/Dockerfile b/init/onboard-central-ledger/Dockerfile new file mode 100644 index 00000000..03407a9c --- /dev/null +++ b/init/onboard-central-ledger/Dockerfile @@ -0,0 +1,32 @@ +FROM node:12.18.0-alpine as builder + +ARG CREATED +ARG SOURCE +ARG REVISION +ARG VERSION + +# See https://github.com/opencontainers/image-spec/blob/master/annotations.md#pre-defined-annotation-keys and https://github.com/opencontainers/image-spec/blob/master/spec.md for info +LABEL org.opencontainers.image.created=${CREATED} +LABEL org.opencontainers.image.url="https://mojaloop.io/" +LABEL org.opencontainers.image.source=${SOURCE} +LABEL org.opencontainers.image.version=${VERSION} +LABEL org.opencontainers.image.revision=${REVISION} +LABEL org.opencontainers.image.title="onboard-central-ledger" +LABEL org.opencontainers.image.authors="kamuela.franco@modusbox.com" +LABEL org.opencontainers.image.licenses="Apache-2.0" + +WORKDIR /opt/onboard-central-ledger +COPY init/onboard-central-ledger/package.json \ + init/onboard-central-ledger/package-lock.json \ + init/onboard-central-ledger/lib.js \ + init/onboard-central-ledger/ onboard-dfsp.js \ + /opt/onboard-central-ledger/ + +RUN ["npm", "ci", "--production"] + +FROM node:12.18.0-alpine +WORKDIR /opt/onboard-central-ledger + +COPY --from=builder /opt/onboard-central-ledger . + +CMD ["npm", "start"] diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js new file mode 100644 index 00000000..9eef498d --- /dev/null +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -0,0 +1,229 @@ +const uuid = require('uuid'); + +const { + onboarding: { + sendRequest, + settlementIdFromHubAccounts, + getDfspAccounts, + addDfsp, + addInitialPositionAndLimits, + depositFunds, + addCallbackParticipantPut, + addCallbackParticipantPutError, + addCallbackParticipantPutBatch, + addCallbackParticipantPutBatchError, + addCallbackPartiesGet, + addCallbackPartiesPut, + addCallbackPartiesPutError, + addCallbackQuotes, + addCallbackTransferPost, + addCallbackTransferPut, + addCallbackTransferError, + setEmailNetDebitCapAdjustment, + setEmailSettlementTransferPositionChange, + setEmailNetDebitCapThresholdBreach, + }, +} = require('@mojaloop/finance-portal-lib'); + +const amount = process.env.FUNDS_IN_PREPARE_AMOUNT; +const authToken = process.env.AUTH_BEARER_TOKEN; +const baseCentralLedgerAdmin = process.env.BASE_CENTRAL_LEDGER_ADMIN; +const dfspCallbackUrl = process.env.DFSP_CALLBACK_URL; +const dfspCurrency = process.env.DFSP_CURRENCY; +const dfspPartyIdType = process.env.DFSP_PARTY_ID_TYPE; +const dfspPartyId = process.env.DFSP_PARTY_ID; +const dfspName = process.env.DFSP_NAME; +const fspiopSource = process.env.HUB_OPERATOR_NAME; +const hostCentralLedger = process.env.HOST_CENTRAL_LEDGER; +const initialPosition = parseInt(process.env.INITIAL_POSITION, 10); +const netDebitCap = parseInt(process.env.NET_DEBIT_CAP, 10); +const ndcAdjustmentEmail = process.env.NDC_ADJUSTMENT_EMAIL; +const ndcThresholdBreachEmail = process.env.NDC_THRESHOLD_BREACH_EMAIL; +const settlementTransferPositionChangeEmail = process.env.SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL; + +async function onboardDfsp() { + await sendRequest(addDfsp({ + dfspName, + dfspCurrency, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(addInitialPositionAndLimits({ + dfspName, + dfspCurrency, + netDebitCap, + initialPosition, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + const hubAccounts = await sendRequest(getDfspAccounts({ + dfspName, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + const settlementAccountId = settlementIdFromHubAccounts(hubAccounts); + + await sendRequest(depositFunds({ + dfspName, + dfspCurrency, + amount, + transferId: uuid.v4(), + settlementAccountId, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(addCallbackParticipantPut({ + dfspName, + dfspCallbackUrl, + dfspPartyId, + dfspPartyIdType, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(addCallbackParticipantPutError({ + dfspName, + dfspCallbackUrl, + dfspPartyId, + dfspPartyIdType, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + // TODO: What is requestId? + await sendRequest(addCallbackParticipantPutBatch({ + dfspName, + dfspCallbackUrl, + requestId: 'requestId', + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + // TODO: What is requestId? + await sendRequest(addCallbackParticipantPutBatchError({ + dfspName, + dfspCallbackUrl, + requestId: 'requestId', + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(addCallbackPartiesGet({ + dfspName, + dfspCallbackUrl, + dfspPartyId, + dfspPartyIdType, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(addCallbackPartiesPut({ + dfspName, + dfspCallbackUrl, + dfspPartyId, + dfspPartyIdType, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(addCallbackPartiesPutError({ + dfspName, + dfspCallbackUrl, + dfspPartyId, + dfspPartyIdType, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(addCallbackQuotes({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(addCallbackTransferPost({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(addCallbackTransferPut({ + dfspName, + dfspCallbackUrl, + transferId: uuid.v4(), + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(addCallbackTransferError({ + dfspName, + dfspCallbackUrl, + transferId: uuid.v4(), + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(setEmailNetDebitCapAdjustment({ + dfspName, + email: ndcAdjustmentEmail, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(setEmailSettlementTransferPositionChange({ + dfspName, + email: settlementTransferPositionChangeEmail, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + await sendRequest(setEmailNetDebitCapThresholdBreach({ + dfspName, + email: ndcThresholdBreachEmail, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); +} + +onboardDfsp(); diff --git a/init/central-ledger/package-lock.json b/init/onboard-central-ledger/package-lock.json similarity index 96% rename from init/central-ledger/package-lock.json rename to init/onboard-central-ledger/package-lock.json index 424e482a..28030b9e 100644 --- a/init/central-ledger/package-lock.json +++ b/init/onboard-central-ledger/package-lock.json @@ -1,5 +1,5 @@ { - "name": "init-central-ledger", + "name": "onboard-central-ledger", "version": "1.0.0", "lockfileVersion": 1, "requires": true, @@ -43,6 +43,29 @@ } } }, + "@mojaloop/finance-portal-lib": { + "version": "0.0.1-snapshot", + "resolved": "https://registry.npmjs.org/@mojaloop/finance-portal-lib/-/finance-portal-lib-0.0.1-snapshot.tgz", + "integrity": "sha512-rEzsdAzIZjmisF3u4qTSAtI3ZuCNh1bvRG9//zNoqNb2GqQY3MCi/YWQJbsoB/1NSJqXClWsMXPkb5BYJbrL0g==", + "requires": { + "big.js": "5.2.2", + "node-fetch": "2.3.0", + "uuid": "3.3.2", + "xml-js": "1.6.8" + }, + "dependencies": { + "node-fetch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", + "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + } + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -153,6 +176,11 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1381,6 +1409,11 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", @@ -1641,6 +1674,11 @@ "punycode": "^2.1.0" } }, + "uuid": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz", + "integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==" + }, "v8-compile-cache": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", @@ -1686,6 +1724,14 @@ "requires": { "mkdirp": "^0.5.1" } + }, + "xml-js": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.8.tgz", + "integrity": "sha512-kUv/geyN80d+s1T68uBfjoz+PjNUjwwf5AWWRwKRqqQaGozpMVsFsKYnenPsxlbN/VL7f0ia8NfLLPCDwX+95Q==", + "requires": { + "sax": "^1.2.4" + } } } } diff --git a/init/central-ledger/package.json b/init/onboard-central-ledger/package.json similarity index 62% rename from init/central-ledger/package.json rename to init/onboard-central-ledger/package.json index 55a3d3a6..f5c57003 100644 --- a/init/central-ledger/package.json +++ b/init/onboard-central-ledger/package.json @@ -1,10 +1,12 @@ { - "name": "init-central-ledger", + "name": "onboard-central-ledger", "version": "1.0.0", "description": "", "main": "onboard-dfsp.js", "dependencies": { - "node-fetch": "^2.6.0" + "@mojaloop/finance-portal-lib": "0.0.14-snapshot", + "node-fetch": "^2.6.0", + "uuid": "^8.2.0" }, "devDependencies": { "eslint": "^7.2.0", @@ -12,6 +14,9 @@ "eslint-plugin-import": "^2.21.2" }, "scripts": { + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "start": "node onboard-dfsp.js", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Kamuela Franco ", From d4a1ec5ceedc4171a91b96e3fa593fe042e861b6 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Mon, 29 Jun 2020 15:58:58 +0100 Subject: [PATCH 14/35] Update finance-portal-lib dependency --- init/onboard-central-ledger/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/init/onboard-central-ledger/package-lock.json b/init/onboard-central-ledger/package-lock.json index 28030b9e..8456ed91 100644 --- a/init/onboard-central-ledger/package-lock.json +++ b/init/onboard-central-ledger/package-lock.json @@ -44,9 +44,9 @@ } }, "@mojaloop/finance-portal-lib": { - "version": "0.0.1-snapshot", - "resolved": "https://registry.npmjs.org/@mojaloop/finance-portal-lib/-/finance-portal-lib-0.0.1-snapshot.tgz", - "integrity": "sha512-rEzsdAzIZjmisF3u4qTSAtI3ZuCNh1bvRG9//zNoqNb2GqQY3MCi/YWQJbsoB/1NSJqXClWsMXPkb5BYJbrL0g==", + "version": "0.0.14-snapshot", + "resolved": "https://registry.npmjs.org/@mojaloop/finance-portal-lib/-/finance-portal-lib-0.0.14-snapshot.tgz", + "integrity": "sha512-Nso66p21XYUhad0/WfUnfyHJtZcordgSfpa9L9UXReqvpnnCe0jnVXHYCsAzFNUSBx5j5cRZ708E3+gHWm3OCw==", "requires": { "big.js": "5.2.2", "node-fetch": "2.3.0", From ec43525e154c0aef9c463e6f946a06cc85c912d5 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 2 Jul 2020 14:48:30 +0100 Subject: [PATCH 15/35] Add logging --- init/onboard-central-ledger/onboard-dfsp.js | 512 +++++++++++++------- 1 file changed, 329 insertions(+), 183 deletions(-) diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js index 9eef498d..9442bf19 100644 --- a/init/onboard-central-ledger/onboard-dfsp.js +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -1,5 +1,4 @@ const uuid = require('uuid'); - const { onboarding: { sendRequest, @@ -25,6 +24,28 @@ const { }, } = require('@mojaloop/finance-portal-lib'); +function log(message) { + const timestamp = (new Date()).toISOString(); + // eslint-disable-next-line no-console + console.log(`[${timestamp}] ${message}`); +} + +log(`ENV: AUTH_BEARER_TOKEN:\t${process.env.AUTH_BEARER_TOKEN}`); +log(`ENV: BASE_CENTRAL_LEDGER_ADMIN:\t${process.env.BASE_CENTRAL_LEDGER_ADMIN}`); +log(`ENV: DFSP_CALLBACK_URL:\t${process.env.DFSP_CALLBACK_URL}`); +log(`ENV: DFSP_CURRENCY:\t${process.env.DFSP_CURRENCY}`); +log(`ENV: DFSP_NAME:\t${process.env.DFSP_NAME}`); +log(`ENV: DFSP_PARTY_ID:\t${process.env.DFSP_PARTY_ID}`); +log(`ENV: DFSP_PARTY_ID_TYPE:\t${process.env.DFSP_PARTY_ID_TYPE}`); +log(`ENV: FUNDS_IN_PREPARE_AMOUNT:\t${process.env.FUNDS_IN_PREPARE_AMOUNT}`); +log(`ENV: HOST_CENTRAL_LEDGER:\t${process.env.HOST_CENTRAL_LEDGER}`); +log(`ENV: HUB_OPERATOR_NAME:\t${process.env.HUB_OPERATOR_NAME}`); +log(`ENV: INITIAL_POSITION:\t${process.env.INITIAL_POSITION}`); +log(`ENV: NDC_ADJUSTMENT_EMAIL:\t${process.env.NDC_ADJUSTMENT_EMAIL}`); +log(`ENV: NDC_THRESHOLD_BREACH_EMAIL:\t${process.env.NDC_THRESHOLD_BREACH_EMAIL}`); +log(`ENV: NET_DEBIT_CAP:\t${process.env.NET_DEBIT_CAP}`); +log(`ENV: SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL:\t${process.env.SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL}`); + const amount = process.env.FUNDS_IN_PREPARE_AMOUNT; const authToken = process.env.AUTH_BEARER_TOKEN; const baseCentralLedgerAdmin = process.env.BASE_CENTRAL_LEDGER_ADMIN; @@ -36,194 +57,319 @@ const dfspName = process.env.DFSP_NAME; const fspiopSource = process.env.HUB_OPERATOR_NAME; const hostCentralLedger = process.env.HOST_CENTRAL_LEDGER; const initialPosition = parseInt(process.env.INITIAL_POSITION, 10); +log(`LOC: initialPosition:\t${initialPosition}`); const netDebitCap = parseInt(process.env.NET_DEBIT_CAP, 10); +log(`LOC: netDebitCap:\t${netDebitCap}`); const ndcAdjustmentEmail = process.env.NDC_ADJUSTMENT_EMAIL; const ndcThresholdBreachEmail = process.env.NDC_THRESHOLD_BREACH_EMAIL; const settlementTransferPositionChangeEmail = process.env.SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL; async function onboardDfsp() { - await sendRequest(addDfsp({ - dfspName, - dfspCurrency, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(addInitialPositionAndLimits({ - dfspName, - dfspCurrency, - netDebitCap, - initialPosition, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - const hubAccounts = await sendRequest(getDfspAccounts({ - dfspName, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - const settlementAccountId = settlementIdFromHubAccounts(hubAccounts); - - await sendRequest(depositFunds({ - dfspName, - dfspCurrency, - amount, - transferId: uuid.v4(), - settlementAccountId, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(addCallbackParticipantPut({ - dfspName, - dfspCallbackUrl, - dfspPartyId, - dfspPartyIdType, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(addCallbackParticipantPutError({ - dfspName, - dfspCallbackUrl, - dfspPartyId, - dfspPartyIdType, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - // TODO: What is requestId? - await sendRequest(addCallbackParticipantPutBatch({ - dfspName, - dfspCallbackUrl, - requestId: 'requestId', - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - // TODO: What is requestId? - await sendRequest(addCallbackParticipantPutBatchError({ - dfspName, - dfspCallbackUrl, - requestId: 'requestId', - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(addCallbackPartiesGet({ - dfspName, - dfspCallbackUrl, - dfspPartyId, - dfspPartyIdType, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(addCallbackPartiesPut({ - dfspName, - dfspCallbackUrl, - dfspPartyId, - dfspPartyIdType, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(addCallbackPartiesPutError({ - dfspName, - dfspCallbackUrl, - dfspPartyId, - dfspPartyIdType, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(addCallbackQuotes({ - dfspName, - dfspCallbackUrl, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(addCallbackTransferPost({ - dfspName, - dfspCallbackUrl, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(addCallbackTransferPut({ - dfspName, - dfspCallbackUrl, - transferId: uuid.v4(), - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(addCallbackTransferError({ - dfspName, - dfspCallbackUrl, - transferId: uuid.v4(), - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(setEmailNetDebitCapAdjustment({ - dfspName, - email: ndcAdjustmentEmail, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(setEmailSettlementTransferPositionChange({ - dfspName, - email: settlementTransferPositionChangeEmail, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - - await sendRequest(setEmailNetDebitCapThresholdBreach({ - dfspName, - email: ndcThresholdBreachEmail, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); + try { + log('EXE: INIT: sendRequest->addDfsp'); + await sendRequest(addDfsp({ + dfspName, + dfspCurrency, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->addDfsp'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addDfsp:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->addInitialPositionAndLimits'); + await sendRequest(addInitialPositionAndLimits({ + dfspName, + dfspCurrency, + netDebitCap, + initialPosition, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->addInitialPositionAndLimits'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addInitialPositionAndLimits:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->getDfspAccounts'); + const hubAccounts = await sendRequest(getDfspAccounts({ + dfspName, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->getDfspAccounts'); + + const settlementAccountId = settlementIdFromHubAccounts(hubAccounts); + log(`LOC: settlementAccountId:\t${settlementAccountId}`); + + log('EXE: INIT: sendRequest->depositFunds'); + await sendRequest(depositFunds({ + dfspName, + dfspCurrency, + amount, + transferId: uuid.v4(), + settlementAccountId, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->depositFunds'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->depositFunds:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->addCallbackParticipantPut'); + await sendRequest(addCallbackParticipantPut({ + dfspName, + dfspCallbackUrl, + dfspPartyId, + dfspPartyIdType, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->addCallbackParticipantPut'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackParticipantPut:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->addCallbackParticipantPutError'); + await sendRequest(addCallbackParticipantPutError({ + dfspName, + dfspCallbackUrl, + dfspPartyId, + dfspPartyIdType, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->addCallbackParticipantPutError'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackParticipantPutError:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->addCallbackParticipantPutBatch'); + await sendRequest(addCallbackParticipantPutBatch({ + dfspName, + dfspCallbackUrl, + requestId: uuid.v4(), + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->addCallbackParticipantPutBatch'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackParticipantPutBatch:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->addCallbackParticipantPutBatchError'); + await sendRequest(addCallbackParticipantPutBatchError({ + dfspName, + dfspCallbackUrl, + requestId: uuid.v4(), + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->addCallbackParticipantPutBatchError'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackParticipantPutBatchError:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->addCallbackPartiesGet'); + await sendRequest(addCallbackPartiesGet({ + dfspName, + dfspCallbackUrl, + dfspPartyId, + dfspPartyIdType, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->addCallbackPartiesGet'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackPartiesGet:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->addCallbackPartiesPut'); + await sendRequest(addCallbackPartiesPut({ + dfspName, + dfspCallbackUrl, + dfspPartyId, + dfspPartyIdType, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + log('EXE: SUCC: sendRequest->addCallbackPartiesPut'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackPartiesPut:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->addCallbackPartiesPutError'); + await sendRequest(addCallbackPartiesPutError({ + dfspName, + dfspCallbackUrl, + dfspPartyId, + dfspPartyIdType, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + + log('EXE: SUCC: sendRequest->addCallbackPartiesPutError'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackPartiesPutError:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->addCallbackQuotes'); + await sendRequest(addCallbackQuotes({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->addCallbackQuotes'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackQuotes:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->addCallbackTransferPost'); + await sendRequest(addCallbackTransferPost({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->addCallbackTransferPost'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackTransferPost:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->addCallbackTransferPut'); + await sendRequest(addCallbackTransferPut({ + dfspName, + dfspCallbackUrl, + transferId: uuid.v4(), + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->addCallbackTransferPut'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackTransferPut:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->addCallbackTransferError'); + await sendRequest(addCallbackTransferError({ + dfspName, + dfspCallbackUrl, + transferId: uuid.v4(), + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->addCallbackTransferError'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackTransferError:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->setEmailNetDebitCapAdjustment'); + await sendRequest(setEmailNetDebitCapAdjustment({ + dfspName, + email: ndcAdjustmentEmail, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->setEmailNetDebitCapAdjustment'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->setEmailNetDebitCapAdjustment:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->setEmailSettlementTransferPositionChange'); + await sendRequest(setEmailSettlementTransferPositionChange({ + dfspName, + email: settlementTransferPositionChangeEmail, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->setEmailSettlementTransferPositionChange'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->setEmailSettlementTransferPositionChange:\t${message}`); + process.exit(-1); + } + + try { + log('EXE: INIT: sendRequest->setEmailNetDebitCapThresholdBreach'); + await sendRequest(setEmailNetDebitCapThresholdBreach({ + dfspName, + email: ndcThresholdBreachEmail, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + log('EXE: SUCC: sendRequest->setEmailNetDebitCapThresholdBreach'); + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->setEmailNetDebitCapThresholdBreach:\t${message}`); + process.exit(-1); + } } onboardDfsp(); From 97cf8c7a291865e08ae3bca668b1a0d17dbe5d72 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 2 Jul 2020 15:17:24 +0100 Subject: [PATCH 16/35] Update Dockerfile --- init/onboard-central-ledger/Dockerfile | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/init/onboard-central-ledger/Dockerfile b/init/onboard-central-ledger/Dockerfile index 03407a9c..f4735b08 100644 --- a/init/onboard-central-ledger/Dockerfile +++ b/init/onboard-central-ledger/Dockerfile @@ -1,4 +1,4 @@ -FROM node:12.18.0-alpine as builder +FROM node:12.18.2-alpine as builder ARG CREATED ARG SOURCE @@ -16,15 +16,11 @@ LABEL org.opencontainers.image.authors="kamuela.franco@modusbox.com" LABEL org.opencontainers.image.licenses="Apache-2.0" WORKDIR /opt/onboard-central-ledger -COPY init/onboard-central-ledger/package.json \ - init/onboard-central-ledger/package-lock.json \ - init/onboard-central-ledger/lib.js \ - init/onboard-central-ledger/ onboard-dfsp.js \ - /opt/onboard-central-ledger/ +COPY package* *.js /opt/onboard-central-ledger/ RUN ["npm", "ci", "--production"] -FROM node:12.18.0-alpine +FROM node:12.18.2-alpine WORKDIR /opt/onboard-central-ledger COPY --from=builder /opt/onboard-central-ledger . From 8fa47207f9254ee5038af1661f160d565b4e690b Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 2 Jul 2020 15:17:37 +0100 Subject: [PATCH 17/35] Add items to .gitignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 93d2e811..951bbeda 100644 --- a/.gitignore +++ b/.gitignore @@ -68,4 +68,6 @@ goldenpayerfsp goldenpayeefsp #vscode configs -.vscode/ \ No newline at end of file +.vscode/ +/init/.DS_Store +/.DS_Store From f8986238a7fcafdac3bad7eef294faf84948e883 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 2 Jul 2020 15:24:54 +0100 Subject: [PATCH 18/35] Align output --- init/onboard-central-ledger/onboard-dfsp.js | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js index 9442bf19..80eebb95 100644 --- a/init/onboard-central-ledger/onboard-dfsp.js +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -30,20 +30,20 @@ function log(message) { console.log(`[${timestamp}] ${message}`); } -log(`ENV: AUTH_BEARER_TOKEN:\t${process.env.AUTH_BEARER_TOKEN}`); -log(`ENV: BASE_CENTRAL_LEDGER_ADMIN:\t${process.env.BASE_CENTRAL_LEDGER_ADMIN}`); -log(`ENV: DFSP_CALLBACK_URL:\t${process.env.DFSP_CALLBACK_URL}`); -log(`ENV: DFSP_CURRENCY:\t${process.env.DFSP_CURRENCY}`); -log(`ENV: DFSP_NAME:\t${process.env.DFSP_NAME}`); -log(`ENV: DFSP_PARTY_ID:\t${process.env.DFSP_PARTY_ID}`); -log(`ENV: DFSP_PARTY_ID_TYPE:\t${process.env.DFSP_PARTY_ID_TYPE}`); -log(`ENV: FUNDS_IN_PREPARE_AMOUNT:\t${process.env.FUNDS_IN_PREPARE_AMOUNT}`); -log(`ENV: HOST_CENTRAL_LEDGER:\t${process.env.HOST_CENTRAL_LEDGER}`); -log(`ENV: HUB_OPERATOR_NAME:\t${process.env.HUB_OPERATOR_NAME}`); -log(`ENV: INITIAL_POSITION:\t${process.env.INITIAL_POSITION}`); -log(`ENV: NDC_ADJUSTMENT_EMAIL:\t${process.env.NDC_ADJUSTMENT_EMAIL}`); -log(`ENV: NDC_THRESHOLD_BREACH_EMAIL:\t${process.env.NDC_THRESHOLD_BREACH_EMAIL}`); -log(`ENV: NET_DEBIT_CAP:\t${process.env.NET_DEBIT_CAP}`); +log(`ENV: AUTH_BEARER_TOKEN:\t\t\t\t${process.env.AUTH_BEARER_TOKEN}`); +log(`ENV: BASE_CENTRAL_LEDGER_ADMIN:\t\t\t${process.env.BASE_CENTRAL_LEDGER_ADMIN}`); +log(`ENV: DFSP_CALLBACK_URL:\t\t\t\t${process.env.DFSP_CALLBACK_URL}`); +log(`ENV: DFSP_CURRENCY:\t\t\t\t\t${process.env.DFSP_CURRENCY}`); +log(`ENV: DFSP_NAME:\t\t\t\t\t${process.env.DFSP_NAME}`); +log(`ENV: DFSP_PARTY_ID:\t\t\t\t\t${process.env.DFSP_PARTY_ID}`); +log(`ENV: DFSP_PARTY_ID_TYPE:\t\t\t\t${process.env.DFSP_PARTY_ID_TYPE}`); +log(`ENV: FUNDS_IN_PREPARE_AMOUNT:\t\t\t${process.env.FUNDS_IN_PREPARE_AMOUNT}`); +log(`ENV: HOST_CENTRAL_LEDGER:\t\t\t\t${process.env.HOST_CENTRAL_LEDGER}`); +log(`ENV: HUB_OPERATOR_NAME:\t\t\t\t${process.env.HUB_OPERATOR_NAME}`); +log(`ENV: INITIAL_POSITION:\t\t\t\t${process.env.INITIAL_POSITION}`); +log(`ENV: NDC_ADJUSTMENT_EMAIL:\t\t\t\t${process.env.NDC_ADJUSTMENT_EMAIL}`); +log(`ENV: NDC_THRESHOLD_BREACH_EMAIL:\t\t\t${process.env.NDC_THRESHOLD_BREACH_EMAIL}`); +log(`ENV: NET_DEBIT_CAP:\t\t\t\t\t${process.env.NET_DEBIT_CAP}`); log(`ENV: SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL:\t${process.env.SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL}`); const amount = process.env.FUNDS_IN_PREPARE_AMOUNT; @@ -59,7 +59,7 @@ const hostCentralLedger = process.env.HOST_CENTRAL_LEDGER; const initialPosition = parseInt(process.env.INITIAL_POSITION, 10); log(`LOC: initialPosition:\t${initialPosition}`); const netDebitCap = parseInt(process.env.NET_DEBIT_CAP, 10); -log(`LOC: netDebitCap:\t${netDebitCap}`); +log(`LOC: netDebitCap:\t\t${netDebitCap}`); const ndcAdjustmentEmail = process.env.NDC_ADJUSTMENT_EMAIL; const ndcThresholdBreachEmail = process.env.NDC_THRESHOLD_BREACH_EMAIL; const settlementTransferPositionChangeEmail = process.env.SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL; From b3c9d28b7b8419ace65e5d7733610f96bb537583 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 2 Jul 2020 17:04:06 +0100 Subject: [PATCH 19/35] Graceful exit on failure --- init/onboard-central-ledger/onboard-dfsp.js | 50 ++++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js index 80eebb95..27749fef 100644 --- a/init/onboard-central-ledger/onboard-dfsp.js +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -78,7 +78,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addDfsp'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addDfsp:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -96,7 +97,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addInitialPositionAndLimits'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addInitialPositionAndLimits:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -128,7 +130,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->depositFunds'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->depositFunds:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -146,7 +149,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addCallbackParticipantPut'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackParticipantPut:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -164,7 +168,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addCallbackParticipantPutError'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackParticipantPutError:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -181,7 +186,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addCallbackParticipantPutBatch'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackParticipantPutBatch:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -198,7 +204,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addCallbackParticipantPutBatchError'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackParticipantPutBatchError:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -216,7 +223,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addCallbackPartiesGet'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackPartiesGet:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -235,7 +243,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addCallbackPartiesPut'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackPartiesPut:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -254,7 +263,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addCallbackPartiesPutError'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackPartiesPutError:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -270,7 +280,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addCallbackQuotes'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackQuotes:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -286,7 +297,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addCallbackTransferPost'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackTransferPost:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -303,7 +315,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addCallbackTransferPut'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackTransferPut:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -320,7 +333,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addCallbackTransferError'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackTransferError:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -336,7 +350,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->setEmailNetDebitCapAdjustment'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->setEmailNetDebitCapAdjustment:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -352,7 +367,8 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->setEmailSettlementTransferPositionChange'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->setEmailSettlementTransferPositionChange:\t${message}`); - process.exit(-1); + process.exitCode = 1; + return; } try { @@ -368,7 +384,7 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->setEmailNetDebitCapThresholdBreach'); } catch ({ message }) { log(`EXE: FAIL: sendRequest->setEmailNetDebitCapThresholdBreach:\t${message}`); - process.exit(-1); + process.exitCode = 1; } } From 4a5753dc26a9ba80de1fe71fc92e2967a0fce004 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Fri, 3 Jul 2020 14:11:11 +0100 Subject: [PATCH 20/35] Add log output --- init/onboard-central-ledger/onboard-dfsp.js | 1 + 1 file changed, 1 insertion(+) diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js index 27749fef..9864d842 100644 --- a/init/onboard-central-ledger/onboard-dfsp.js +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -111,6 +111,7 @@ async function onboardDfsp() { fspiopSource, })); log('EXE: SUCC: sendRequest->getDfspAccounts'); + log(`LOC: hubAccounts:\t${hubAccounts}`); const settlementAccountId = settlementIdFromHubAccounts(hubAccounts); log(`LOC: settlementAccountId:\t${settlementAccountId}`); From 4e540d720cd451bc0751c020283c502a13269b51 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Fri, 3 Jul 2020 17:02:20 +0100 Subject: [PATCH 21/35] Add detailed logging on error --- init/onboard-central-ledger/onboard-dfsp.js | 177 ++++++++++++++------ 1 file changed, 123 insertions(+), 54 deletions(-) diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js index 9864d842..3694f2ba 100644 --- a/init/onboard-central-ledger/onboard-dfsp.js +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -67,7 +67,7 @@ const settlementTransferPositionChangeEmail = process.env.SETTLEMENT_TRANSFER_PO async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addDfsp'); - await sendRequest(addDfsp({ + const response = await sendRequest(addDfsp({ dfspName, dfspCurrency, authToken, @@ -75,7 +75,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->addDfsp'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addDfsp'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addDfsp:\t${message}`); process.exitCode = 1; @@ -84,7 +88,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addInitialPositionAndLimits'); - await sendRequest(addInitialPositionAndLimits({ + const response = await sendRequest(addInitialPositionAndLimits({ dfspName, dfspCurrency, netDebitCap, @@ -94,7 +98,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->addInitialPositionAndLimits'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addInitialPositionAndLimits'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addInitialPositionAndLimits:\t${message}`); process.exitCode = 1; @@ -103,32 +111,39 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->getDfspAccounts'); - const hubAccounts = await sendRequest(getDfspAccounts({ + const response = await sendRequest(getDfspAccounts({ dfspName, authToken, hostCentralLedger, baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->getDfspAccounts'); - log(`LOC: hubAccounts:\t${hubAccounts}`); - - const settlementAccountId = settlementIdFromHubAccounts(hubAccounts); - log(`LOC: settlementAccountId:\t${settlementAccountId}`); - - log('EXE: INIT: sendRequest->depositFunds'); - await sendRequest(depositFunds({ - dfspName, - dfspCurrency, - amount, - transferId: uuid.v4(), - settlementAccountId, - authToken, - hostCentralLedger, - baseCentralLedgerAdmin, - fspiopSource, - })); - log('EXE: SUCC: sendRequest->depositFunds'); + if (response.ok) { + const dfspAccounts = await response.json(); + log('EXE: SUCC: sendRequest->getDfspAccounts'); + log(`LOC: dfspAccounts:\t${JSON.stringify(dfspAccounts)}`); + const settlementAccountId = settlementIdFromHubAccounts(dfspAccounts); + log(`LOC: settlementAccountId:\t${settlementAccountId}`); + log('EXE: INIT: sendRequest->depositFunds'); + const innerResponse = await sendRequest(depositFunds({ + dfspName, + dfspCurrency, + amount, + transferId: uuid.v4(), + settlementAccountId, + authToken, + hostCentralLedger, + baseCentralLedgerAdmin, + fspiopSource, + })); + if (innerResponse.ok) { + log('EXE: SUCC: sendRequest->depositFunds'); + } else { + throw new Error('Response not OK/2XX'); + } + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->depositFunds:\t${message}`); process.exitCode = 1; @@ -137,7 +152,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addCallbackParticipantPut'); - await sendRequest(addCallbackParticipantPut({ + const response = await sendRequest(addCallbackParticipantPut({ dfspName, dfspCallbackUrl, dfspPartyId, @@ -147,7 +162,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->addCallbackParticipantPut'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackParticipantPut'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackParticipantPut:\t${message}`); process.exitCode = 1; @@ -156,7 +175,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addCallbackParticipantPutError'); - await sendRequest(addCallbackParticipantPutError({ + const response = await sendRequest(addCallbackParticipantPutError({ dfspName, dfspCallbackUrl, dfspPartyId, @@ -166,7 +185,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->addCallbackParticipantPutError'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackParticipantPutError'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackParticipantPutError:\t${message}`); process.exitCode = 1; @@ -175,7 +198,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addCallbackParticipantPutBatch'); - await sendRequest(addCallbackParticipantPutBatch({ + const response = await sendRequest(addCallbackParticipantPutBatch({ dfspName, dfspCallbackUrl, requestId: uuid.v4(), @@ -184,7 +207,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->addCallbackParticipantPutBatch'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackParticipantPutBatch'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackParticipantPutBatch:\t${message}`); process.exitCode = 1; @@ -193,7 +220,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addCallbackParticipantPutBatchError'); - await sendRequest(addCallbackParticipantPutBatchError({ + const response = await sendRequest(addCallbackParticipantPutBatchError({ dfspName, dfspCallbackUrl, requestId: uuid.v4(), @@ -202,7 +229,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->addCallbackParticipantPutBatchError'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackParticipantPutBatchError'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackParticipantPutBatchError:\t${message}`); process.exitCode = 1; @@ -211,7 +242,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addCallbackPartiesGet'); - await sendRequest(addCallbackPartiesGet({ + const response = await sendRequest(addCallbackPartiesGet({ dfspName, dfspCallbackUrl, dfspPartyId, @@ -221,7 +252,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->addCallbackPartiesGet'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackPartiesGet'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackPartiesGet:\t${message}`); process.exitCode = 1; @@ -230,7 +265,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addCallbackPartiesPut'); - await sendRequest(addCallbackPartiesPut({ + const response = await sendRequest(addCallbackPartiesPut({ dfspName, dfspCallbackUrl, dfspPartyId, @@ -240,8 +275,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - - log('EXE: SUCC: sendRequest->addCallbackPartiesPut'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackPartiesPut'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackPartiesPut:\t${message}`); process.exitCode = 1; @@ -250,7 +288,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addCallbackPartiesPutError'); - await sendRequest(addCallbackPartiesPutError({ + const response = await sendRequest(addCallbackPartiesPutError({ dfspName, dfspCallbackUrl, dfspPartyId, @@ -260,8 +298,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - - log('EXE: SUCC: sendRequest->addCallbackPartiesPutError'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackPartiesPutError'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackPartiesPutError:\t${message}`); process.exitCode = 1; @@ -270,7 +311,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addCallbackQuotes'); - await sendRequest(addCallbackQuotes({ + const response = await sendRequest(addCallbackQuotes({ dfspName, dfspCallbackUrl, authToken, @@ -278,7 +319,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->addCallbackQuotes'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackQuotes'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackQuotes:\t${message}`); process.exitCode = 1; @@ -287,7 +332,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addCallbackTransferPost'); - await sendRequest(addCallbackTransferPost({ + const response = await sendRequest(addCallbackTransferPost({ dfspName, dfspCallbackUrl, authToken, @@ -295,7 +340,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->addCallbackTransferPost'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackTransferPost'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackTransferPost:\t${message}`); process.exitCode = 1; @@ -304,7 +353,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addCallbackTransferPut'); - await sendRequest(addCallbackTransferPut({ + const response = await sendRequest(addCallbackTransferPut({ dfspName, dfspCallbackUrl, transferId: uuid.v4(), @@ -313,7 +362,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->addCallbackTransferPut'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackTransferPut'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackTransferPut:\t${message}`); process.exitCode = 1; @@ -322,7 +375,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->addCallbackTransferError'); - await sendRequest(addCallbackTransferError({ + const response = await sendRequest(addCallbackTransferError({ dfspName, dfspCallbackUrl, transferId: uuid.v4(), @@ -331,7 +384,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->addCallbackTransferError'); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackTransferError'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackTransferError:\t${message}`); process.exitCode = 1; @@ -340,7 +397,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->setEmailNetDebitCapAdjustment'); - await sendRequest(setEmailNetDebitCapAdjustment({ + const response = await sendRequest(setEmailNetDebitCapAdjustment({ dfspName, email: ndcAdjustmentEmail, authToken, @@ -348,7 +405,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->setEmailNetDebitCapAdjustment'); + if (response.ok) { + log('EXE: SUCC: sendRequest->setEmailNetDebitCapAdjustment'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->setEmailNetDebitCapAdjustment:\t${message}`); process.exitCode = 1; @@ -357,7 +418,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->setEmailSettlementTransferPositionChange'); - await sendRequest(setEmailSettlementTransferPositionChange({ + const response = await sendRequest(setEmailSettlementTransferPositionChange({ dfspName, email: settlementTransferPositionChangeEmail, authToken, @@ -365,7 +426,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->setEmailSettlementTransferPositionChange'); + if (response.ok) { + log('EXE: SUCC: sendRequest->setEmailSettlementTransferPositionChange'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->setEmailSettlementTransferPositionChange:\t${message}`); process.exitCode = 1; @@ -374,7 +439,7 @@ async function onboardDfsp() { try { log('EXE: INIT: sendRequest->setEmailNetDebitCapThresholdBreach'); - await sendRequest(setEmailNetDebitCapThresholdBreach({ + const response = await sendRequest(setEmailNetDebitCapThresholdBreach({ dfspName, email: ndcThresholdBreachEmail, authToken, @@ -382,7 +447,11 @@ async function onboardDfsp() { baseCentralLedgerAdmin, fspiopSource, })); - log('EXE: SUCC: sendRequest->setEmailNetDebitCapThresholdBreach'); + if (response.ok) { + log('EXE: SUCC: sendRequest->setEmailNetDebitCapThresholdBreach'); + } else { + throw new Error('Response not OK/2XX'); + } } catch ({ message }) { log(`EXE: FAIL: sendRequest->setEmailNetDebitCapThresholdBreach:\t${message}`); process.exitCode = 1; From 2a7829383529711b5a3c271ed842880527b1035d Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Mon, 6 Jul 2020 13:39:20 +0100 Subject: [PATCH 22/35] Update finance-portal-lib dependency --- init/onboard-central-ledger/package-lock.json | 6 +++--- init/onboard-central-ledger/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/init/onboard-central-ledger/package-lock.json b/init/onboard-central-ledger/package-lock.json index 8456ed91..1076312d 100644 --- a/init/onboard-central-ledger/package-lock.json +++ b/init/onboard-central-ledger/package-lock.json @@ -44,9 +44,9 @@ } }, "@mojaloop/finance-portal-lib": { - "version": "0.0.14-snapshot", - "resolved": "https://registry.npmjs.org/@mojaloop/finance-portal-lib/-/finance-portal-lib-0.0.14-snapshot.tgz", - "integrity": "sha512-Nso66p21XYUhad0/WfUnfyHJtZcordgSfpa9L9UXReqvpnnCe0jnVXHYCsAzFNUSBx5j5cRZ708E3+gHWm3OCw==", + "version": "0.0.16-snapshot", + "resolved": "https://registry.npmjs.org/@mojaloop/finance-portal-lib/-/finance-portal-lib-0.0.16-snapshot.tgz", + "integrity": "sha512-dPB/xrbGtzg7w5o78Xhg/HXXuttSyxi6ELXyE4xXMhal5qXKEiwfX5Yeuu3MDZuCqmCi2XcY+VQhFiMQAw/oJQ==", "requires": { "big.js": "5.2.2", "node-fetch": "2.3.0", diff --git a/init/onboard-central-ledger/package.json b/init/onboard-central-ledger/package.json index f5c57003..2b1bc5e8 100644 --- a/init/onboard-central-ledger/package.json +++ b/init/onboard-central-ledger/package.json @@ -4,7 +4,7 @@ "description": "", "main": "onboard-dfsp.js", "dependencies": { - "@mojaloop/finance-portal-lib": "0.0.14-snapshot", + "@mojaloop/finance-portal-lib": "0.0.16-snapshot", "node-fetch": "^2.6.0", "uuid": "^8.2.0" }, From 91149b9077881bcaf3a6abb91f407eddb2c42184 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Mon, 6 Jul 2020 16:13:05 +0100 Subject: [PATCH 23/35] Add more detailed logging --- init/onboard-central-ledger/onboard-dfsp.js | 54 ++++++++++++++------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js index 3694f2ba..90aeb6fc 100644 --- a/init/onboard-central-ledger/onboard-dfsp.js +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -78,7 +78,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addDfsp'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addDfsp:\t${message}`); @@ -101,7 +102,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addInitialPositionAndLimits'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addInitialPositionAndLimits:\t${message}`); @@ -139,10 +141,12 @@ async function onboardDfsp() { if (innerResponse.ok) { log('EXE: SUCC: sendRequest->depositFunds'); } else { - throw new Error('Response not OK/2XX'); + const innerError = await innerResponse.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(innerError)}`); } } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->depositFunds:\t${message}`); @@ -165,7 +169,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addCallbackParticipantPut'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackParticipantPut:\t${message}`); @@ -188,7 +193,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addCallbackParticipantPutError'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackParticipantPutError:\t${message}`); @@ -210,7 +216,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addCallbackParticipantPutBatch'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackParticipantPutBatch:\t${message}`); @@ -232,7 +239,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addCallbackParticipantPutBatchError'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackParticipantPutBatchError:\t${message}`); @@ -255,7 +263,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addCallbackPartiesGet'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackPartiesGet:\t${message}`); @@ -278,7 +287,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addCallbackPartiesPut'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackPartiesPut:\t${message}`); @@ -301,7 +311,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addCallbackPartiesPutError'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackPartiesPutError:\t${message}`); @@ -322,7 +333,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addCallbackQuotes'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackQuotes:\t${message}`); @@ -343,7 +355,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addCallbackTransferPost'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackTransferPost:\t${message}`); @@ -365,7 +378,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addCallbackTransferPut'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackTransferPut:\t${message}`); @@ -387,7 +401,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->addCallbackTransferError'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addCallbackTransferError:\t${message}`); @@ -408,7 +423,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->setEmailNetDebitCapAdjustment'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->setEmailNetDebitCapAdjustment:\t${message}`); @@ -429,7 +445,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->setEmailSettlementTransferPositionChange'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->setEmailSettlementTransferPositionChange:\t${message}`); @@ -450,7 +467,8 @@ async function onboardDfsp() { if (response.ok) { log('EXE: SUCC: sendRequest->setEmailNetDebitCapThresholdBreach'); } else { - throw new Error('Response not OK/2XX'); + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { log(`EXE: FAIL: sendRequest->setEmailNetDebitCapThresholdBreach:\t${message}`); From f5523219852e3bf0463fec2433d304451b5a49ec Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Tue, 7 Jul 2020 16:52:13 +0100 Subject: [PATCH 24/35] Allow re-registration of same DFSP name and currency --- init/onboard-central-ledger/onboard-dfsp.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js index 90aeb6fc..df2c6ccc 100644 --- a/init/onboard-central-ledger/onboard-dfsp.js +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -79,7 +79,13 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addDfsp'); } else { const error = await response.json(); - throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + // Allow re-registering of the same DFSP name and currency + if (response.status === 400 && error.code === '3000' + && /currency.*already.*registered/.test(error.errorDescription)) { + log(`EXE: FAIL: sendRequest->addDfsp:\t${JSON.stringify(error)}`); + } else { + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addDfsp:\t${message}`); From 40abbf538e35a22ae82725d4598472fe2eee7905 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Tue, 7 Jul 2020 16:57:40 +0100 Subject: [PATCH 25/35] Fix bug --- init/onboard-central-ledger/onboard-dfsp.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js index df2c6ccc..86fe61e5 100644 --- a/init/onboard-central-ledger/onboard-dfsp.js +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -80,7 +80,7 @@ async function onboardDfsp() { } else { const error = await response.json(); // Allow re-registering of the same DFSP name and currency - if (response.status === 400 && error.code === '3000' + if (response.status === 400 && error.errorCode === '3000' && /currency.*already.*registered/.test(error.errorDescription)) { log(`EXE: FAIL: sendRequest->addDfsp:\t${JSON.stringify(error)}`); } else { From fc499cbe91f2f2a98c2651f0106a5ceb239f3a54 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Wed, 8 Jul 2020 14:45:15 +0100 Subject: [PATCH 26/35] Fix output by calling script directly --- init/onboard-central-ledger/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/onboard-central-ledger/Dockerfile b/init/onboard-central-ledger/Dockerfile index f4735b08..c6db93b7 100644 --- a/init/onboard-central-ledger/Dockerfile +++ b/init/onboard-central-ledger/Dockerfile @@ -25,4 +25,4 @@ WORKDIR /opt/onboard-central-ledger COPY --from=builder /opt/onboard-central-ledger . -CMD ["npm", "start"] +CMD ["node", "onboard-dfsp.js"] From 20e34acb331298c829fbe96a8d1309acea66ff98 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Wed, 8 Jul 2020 14:45:35 +0100 Subject: [PATCH 27/35] Fix logging and request edge cases --- init/onboard-central-ledger/onboard-dfsp.js | 34 +++++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js index 86fe61e5..734e8897 100644 --- a/init/onboard-central-ledger/onboard-dfsp.js +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -57,9 +57,9 @@ const dfspName = process.env.DFSP_NAME; const fspiopSource = process.env.HUB_OPERATOR_NAME; const hostCentralLedger = process.env.HOST_CENTRAL_LEDGER; const initialPosition = parseInt(process.env.INITIAL_POSITION, 10); -log(`LOC: initialPosition:\t${initialPosition}`); +log(`LOC: initialPosition:\t\t\t\t${initialPosition}`); const netDebitCap = parseInt(process.env.NET_DEBIT_CAP, 10); -log(`LOC: netDebitCap:\t\t${netDebitCap}`); +log(`LOC: netDebitCap:\t\t\t\t\t${netDebitCap}`); const ndcAdjustmentEmail = process.env.NDC_ADJUSTMENT_EMAIL; const ndcThresholdBreachEmail = process.env.NDC_THRESHOLD_BREACH_EMAIL; const settlementTransferPositionChangeEmail = process.env.SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL; @@ -80,9 +80,10 @@ async function onboardDfsp() { } else { const error = await response.json(); // Allow re-registering of the same DFSP name and currency - if (response.status === 400 && error.errorCode === '3000' - && /currency.*already.*registered/.test(error.errorDescription)) { - log(`EXE: FAIL: sendRequest->addDfsp:\t${JSON.stringify(error)}`); + if (response.status === 400 && error.errorInformation.errorCode === '3000' + && /already/.test(error.errorInformation.errorDescription)) { + log(`EXE: FAIL: sendRequest->addDfsp:\t\t\t${JSON.stringify(error)}`); + log('EXE: INFO: Allowed failure:\t\t\t\tProceeding with next request'); } else { throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } @@ -109,7 +110,14 @@ async function onboardDfsp() { log('EXE: SUCC: sendRequest->addInitialPositionAndLimits'); } else { const error = await response.json(); - throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + // Allow re-registering + if (response.status === 500 && error.errorInformation.errorCode === '2001' + && /already/.test(error.errorInformation.errorDescription)) { + log(`EXE: FAIL: sendRequest->addInitialPositionAndLimits:\t${JSON.stringify(error)}`); + log('EXE: INFO: Allowed failure:\t\t\t\tProceeding with next request'); + } else { + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } } } catch ({ message }) { log(`EXE: FAIL: sendRequest->addInitialPositionAndLimits:\t${message}`); @@ -129,9 +137,11 @@ async function onboardDfsp() { if (response.ok) { const dfspAccounts = await response.json(); log('EXE: SUCC: sendRequest->getDfspAccounts'); - log(`LOC: dfspAccounts:\t${JSON.stringify(dfspAccounts)}`); - const settlementAccountId = settlementIdFromHubAccounts(dfspAccounts); - log(`LOC: settlementAccountId:\t${settlementAccountId}`); + log(`LOC: dfspAccounts:\t\t\t\t\t${JSON.stringify(dfspAccounts)}`); + log('EXE: INIT: settlementAccountIdFromHubAccounts'); + const settlementAccountId = settlementIdFromHubAccounts(dfspAccounts, dfspCurrency); + log('EXE: SUCC: settlementAccountIdFromHubAccounts'); + log(`LOC: settlementAccountId:\t\t\t\t${settlementAccountId}`); log('EXE: INIT: sendRequest->depositFunds'); const innerResponse = await sendRequest(depositFunds({ dfspName, @@ -155,7 +165,11 @@ async function onboardDfsp() { throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { - log(`EXE: FAIL: sendRequest->depositFunds:\t${message}`); + if (/property/.test(message)) { + log(`EXE: FAIL: settlementAccountIdFromHubAccounts:\t${message}`); + } else { + log(`EXE: FAIL: sendRequest->depositFunds:\t\t${message}`); + } process.exitCode = 1; return; } From 75b69bcff365f603e450491482b94bc1967d592d Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 9 Jul 2020 17:08:38 +0100 Subject: [PATCH 28/35] Add onboard-central-ledger to pipeline --- .circleci/config.yml | 111 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 87da64e9..b2b84203 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -215,6 +215,29 @@ jobs: paths: - ./docker-image.tar + build-onboard-central-ledger: + executor: default-machine + steps: + - checkout + - run: + name: Build Docker onboard-central-ledger $CIRCLE_TAG image + command: > + echo "Building Docker image: onboard-central-ledger $CIRCLE_TAG" + + docker build + --build-arg BUILD_DATE="$(date -u --iso-8601=seconds)" + --build-arg VERSION="$RELEASE_TAG" + --build-arg VCS_URL="$CIRCLE_REPOSITORY_URL" + --build-arg VCS_REF="$CIRCLE_SHA1" + -t $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG . + - run: + name: Save docker image to workspace + command: docker save -o /tmp/docker-onboard-msisdn-oracle.tar $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG + - persist_to_workspace: + root: /tmp + paths: + - ./docker-onboard-central-ledger.tar + build-onboard-msisdn-oracle: executor: default-machine steps: @@ -261,6 +284,29 @@ jobs: paths: - ./docker-image.tar + build-local-onboard-central-ledger: + executor: default-machine + steps: + - checkout + - run: + name: Build Docker onboard-central-ledger local image for testing + command: > + echo "Building Docker image: onboard-central-ledger local" + + docker build + --build-arg BUILD_DATE="$(date -u --iso-8601=seconds)" + --build-arg VERSION="local" + --build-arg VCS_URL="$CIRCLE_REPOSITORY_URL" + --build-arg VCS_REF="$CIRCLE_SHA1" + -t $DOCKER_ORG/onboard-central-ledger:local ./init/onboard-central-ledger/ + - run: + name: Save docker image to workspace + command: docker save -o /tmp/docker-onboard-central-ledger.tar $DOCKER_ORG/onboard-central-ledger:local + - persist_to_workspace: + root: /tmp + paths: + - ./docker-onboard-central-ledger.tar + build-local-onboard-msisdn-oracle: executor: default-machine steps: @@ -384,6 +430,39 @@ jobs: -H 'cache-control: no-cache' \ -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" + publish-onboard-central-ledger: + executor: default-machine + steps: + - checkout + - attach_workspace: + at: /tmp + - run: + name: Load the pre-built docker image for onboard-central-ledger from workspace + command: docker load -i /tmp/docker-onboard-central-ledger.tar + - run: + name: Login to Docker Hub + command: docker login -u $DOCKER_USER -p $DOCKER_PASS + - run: + name: Setup environment vars for release/snapshot + command: ./.circleci/_set_up_deploy_envs.sh + - run: + name: Re-tag pre built image + command: | + docker tag $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG $DOCKER_ORG/onboard-central-ledger:$RELEASE_TAG + - run: + name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for onboard-central-ledger + command: | + echo "Publishing $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG" + docker push $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG + - run: + name: Slack announcement for tag releases + command: | + curl -X POST \ + $SLACK_WEBHOOK_ANNOUNCEMENT \ + -H 'Content-type: application/json' \ + -H 'cache-control: no-cache' \ + -d "{\"text\": \"*onboard-central-ledger* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" + publish-onboard-msisdn-oracle: executor: default-machine steps: @@ -493,6 +572,14 @@ workflows: - /feature*/ - /bugfix*/ - /hotfix*/ + - build-local-onboard-central-ledger: + context: org-global + filters: + branches: + ignore: + - /feature*/ + - /bugfix*/ + - /hotfix*/ - build-local-onboard-msisdn-oracle: context: org-global filters: @@ -531,6 +618,16 @@ workflows: branches: ignore: - /.*/ + - build-onboard-central-ledger: + context: org-global + requires: + - setup + filters: + tags: + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ + branches: + ignore: + - /.*/ - build-onboard-msisdn-oracle: context: org-global requires: @@ -552,10 +649,23 @@ workflows: branches: ignore: - /.*/ + - publish-onboard-central-ledger: + context: org-global + requires: + - build + - build-onboard-central-ledger + - build-onboard-msisdn-oracle + filters: + tags: + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ + branches: + ignore: + - /.*/ - publish-onboard-msisdn-oracle: context: org-global requires: - build + - build-onboard-central-ledger - build-onboard-msisdn-oracle filters: tags: @@ -567,6 +677,7 @@ workflows: context: org-global requires: - publish + - publish-onboard-central-ledger - publish-onboard-msisdn-oracle filters: tags: From fd67730213c4e3e1a1bbe782e8a489a86485010c Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 9 Jul 2020 17:10:23 +0100 Subject: [PATCH 29/35] Bump version --- init/onboard-central-ledger/package-lock.json | 2 +- init/onboard-central-ledger/package.json | 2 +- src/package-lock.json | 2 +- src/package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/init/onboard-central-ledger/package-lock.json b/init/onboard-central-ledger/package-lock.json index 1076312d..616bc46e 100644 --- a/init/onboard-central-ledger/package-lock.json +++ b/init/onboard-central-ledger/package-lock.json @@ -1,6 +1,6 @@ { "name": "onboard-central-ledger", - "version": "1.0.0", + "version": "10.6.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/init/onboard-central-ledger/package.json b/init/onboard-central-ledger/package.json index 2b1bc5e8..4c667cbe 100644 --- a/init/onboard-central-ledger/package.json +++ b/init/onboard-central-ledger/package.json @@ -1,6 +1,6 @@ { "name": "onboard-central-ledger", - "version": "1.0.0", + "version": "10.6.2", "description": "", "main": "onboard-dfsp.js", "dependencies": { diff --git a/src/package-lock.json b/src/package-lock.json index 2338474a..2a2349f0 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -1,6 +1,6 @@ { "name": "mojaloop-simulator", - "version": "10.6.1", + "version": "10.6.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/package.json b/src/package.json index d9f7c510..c9546951 100644 --- a/src/package.json +++ b/src/package.json @@ -1,6 +1,6 @@ { "name": "mojaloop-simulator", - "version": "10.6.1", + "version": "10.6.2", "description": "A canonical test example implementation of the parties, transfers and quotes resources of the Mojaloop API", "license": "Apache-2.0", "main": "index.js", From 53e9436eac2d7dd464cf2d7498c63d1ae90a6de2 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 9 Jul 2020 21:17:24 +0100 Subject: [PATCH 30/35] Add comments --- init/onboard-central-ledger/onboard-dfsp.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js index 734e8897..baa41e4f 100644 --- a/init/onboard-central-ledger/onboard-dfsp.js +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -165,7 +165,9 @@ async function onboardDfsp() { throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { + // Identify an issue with settlementAccountIdFromHubAccounts with a pattern match if (/property/.test(message)) { + // So that a more specific failure can be logged log(`EXE: FAIL: settlementAccountIdFromHubAccounts:\t${message}`); } else { log(`EXE: FAIL: sendRequest->depositFunds:\t\t${message}`); From a258d15e081261c3b3229d38e634f601f38b28cc Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 9 Jul 2020 21:24:48 +0100 Subject: [PATCH 31/35] Fix build argument references --- .circleci/config.yml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b2b84203..1684b1c9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -202,10 +202,10 @@ jobs: echo "Building Docker image: $CIRCLE_TAG" docker build - --build-arg BUILD_DATE="$(date -u --iso-8601=seconds)" + --build-arg CREATED="$(date -u --iso-8601=seconds)" --build-arg VERSION="$RELEASE_TAG" - --build-arg VCS_URL="$CIRCLE_REPOSITORY_URL" - --build-arg VCS_REF="$CIRCLE_SHA1" + --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + --build-arg REVISION="$CIRCLE_SHA1" -t $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG . - run: name: Save docker image to workspace @@ -225,10 +225,10 @@ jobs: echo "Building Docker image: onboard-central-ledger $CIRCLE_TAG" docker build - --build-arg BUILD_DATE="$(date -u --iso-8601=seconds)" + --build-arg CREATED="$(date -u --iso-8601=seconds)" --build-arg VERSION="$RELEASE_TAG" - --build-arg VCS_URL="$CIRCLE_REPOSITORY_URL" - --build-arg VCS_REF="$CIRCLE_SHA1" + --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + --build-arg REVISION="$CIRCLE_SHA1" -t $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG . - run: name: Save docker image to workspace @@ -248,10 +248,10 @@ jobs: echo "Building Docker image: onboard-msisdn-oracle $CIRCLE_TAG" docker build - --build-arg BUILD_DATE="$(date -u --iso-8601=seconds)" + --build-arg CREATED="$(date -u --iso-8601=seconds)" --build-arg VERSION="$RELEASE_TAG" - --build-arg VCS_URL="$CIRCLE_REPOSITORY_URL" - --build-arg VCS_REF="$CIRCLE_SHA1" + --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + --build-arg REVISION="$CIRCLE_SHA1" -t $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG . - run: name: Save docker image to workspace @@ -271,10 +271,10 @@ jobs: echo "Building Docker image: local" docker build - --build-arg BUILD_DATE="$(date -u --iso-8601=seconds)" + --build-arg CREATED="$(date -u --iso-8601=seconds)" --build-arg VERSION="local" - --build-arg VCS_URL="$CIRCLE_REPOSITORY_URL" - --build-arg VCS_REF="$CIRCLE_SHA1" + --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + --build-arg REVISION="$CIRCLE_SHA1" -t $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:local . - run: name: Save docker image to workspace @@ -294,10 +294,10 @@ jobs: echo "Building Docker image: onboard-central-ledger local" docker build - --build-arg BUILD_DATE="$(date -u --iso-8601=seconds)" + --build-arg CREATED="$(date -u --iso-8601=seconds)" --build-arg VERSION="local" - --build-arg VCS_URL="$CIRCLE_REPOSITORY_URL" - --build-arg VCS_REF="$CIRCLE_SHA1" + --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + --build-arg REVISION="$CIRCLE_SHA1" -t $DOCKER_ORG/onboard-central-ledger:local ./init/onboard-central-ledger/ - run: name: Save docker image to workspace @@ -317,10 +317,10 @@ jobs: echo "Building Docker image: onboard-msisdn-oracle local" docker build - --build-arg BUILD_DATE="$(date -u --iso-8601=seconds)" + --build-arg CREATED="$(date -u --iso-8601=seconds)" --build-arg VERSION="local" - --build-arg VCS_URL="$CIRCLE_REPOSITORY_URL" - --build-arg VCS_REF="$CIRCLE_SHA1" + --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + --build-arg REVISION="$CIRCLE_SHA1" -t $DOCKER_ORG/onboard-msisdn-oracle:local ./init/onboard-msisdn-oracle/ - run: name: Save docker image to workspace From 875c446f272f2f532384b0271ba20c96cff1ee13 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 9 Jul 2020 21:27:22 +0100 Subject: [PATCH 32/35] Require setup for local builds --- .circleci/config.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1684b1c9..46df0aa7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -566,6 +566,8 @@ workflows: - /hotfix*/ - build-local: context: org-global + requires: + - setup filters: branches: ignore: @@ -574,6 +576,8 @@ workflows: - /hotfix*/ - build-local-onboard-central-ledger: context: org-global + requires: + - setup filters: branches: ignore: @@ -582,6 +586,8 @@ workflows: - /hotfix*/ - build-local-onboard-msisdn-oracle: context: org-global + requires: + - setup filters: branches: ignore: From e7f4fab7e3e0d1ccc3d453d8b99c5a72c0d93594 Mon Sep 17 00:00:00 2001 From: Kamuela Franco Date: Thu, 9 Jul 2020 22:02:06 +0100 Subject: [PATCH 33/35] Update init/onboard-central-ledger/onboard-dfsp.js Co-authored-by: Matt Kingston --- init/onboard-central-ledger/onboard-dfsp.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js index baa41e4f..785f24ac 100644 --- a/init/onboard-central-ledger/onboard-dfsp.js +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -165,7 +165,8 @@ async function onboardDfsp() { throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); } } catch ({ message }) { - // Identify an issue with settlementAccountIdFromHubAccounts with a pattern match + // Testing indicates this regex will match a settlementAccountIdFromHubAccounts error, but not a + // depositFunds error if (/property/.test(message)) { // So that a more specific failure can be logged log(`EXE: FAIL: settlementAccountIdFromHubAccounts:\t${message}`); From 4020ca8606936a3ae3ddf4a6382c3117f68f40cb Mon Sep 17 00:00:00 2001 From: Matt Kingston Date: Thu, 9 Jul 2020 22:10:29 +0100 Subject: [PATCH 34/35] Log script commands and exit on error --- init/onboard-msisdn-oracle/insert_msisdns.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/init/onboard-msisdn-oracle/insert_msisdns.sh b/init/onboard-msisdn-oracle/insert_msisdns.sh index bc23e536..d0b90f73 100755 --- a/init/onboard-msisdn-oracle/insert_msisdns.sh +++ b/init/onboard-msisdn-oracle/insert_msisdns.sh @@ -1,5 +1,7 @@ #!/usr/bin/env sh +set -ex + CURRENT_DATE=$(date) for participantMSISDN in $(echo "${MSISDN_LIST}" | jq -c '.[]'); do MSISDN=$(echo "${participantMSISDN}" | jq -r '.MSISDN'); From d1c4cc884877327a6e4413ef1ee11ca1a00e30ed Mon Sep 17 00:00:00 2001 From: Matt Kingston Date: Thu, 9 Jul 2020 22:14:02 +0100 Subject: [PATCH 35/35] Exit when required variable is not present --- init/onboard-msisdn-oracle/insert_msisdns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/onboard-msisdn-oracle/insert_msisdns.sh b/init/onboard-msisdn-oracle/insert_msisdns.sh index d0b90f73..2daf8a1e 100755 --- a/init/onboard-msisdn-oracle/insert_msisdns.sh +++ b/init/onboard-msisdn-oracle/insert_msisdns.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -set -ex +set -eux CURRENT_DATE=$(date) for participantMSISDN in $(echo "${MSISDN_LIST}" | jq -c '.[]'); do