diff --git a/audit-resolve.json b/audit-resolve.json index 07450e07..64aac214 100644 --- a/audit-resolve.json +++ b/audit-resolve.json @@ -1,74 +1,9 @@ { "decisions": { - "1523|@mojaloop/central-services-error-handling>lodash": { + "1500|npm-audit-resolver>audit-resolve-core>yargs-parser": { "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|@mojaloop/central-services-shared>@mojaloop/central-services-error-handling>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|@mojaloop/central-services-logger>winston>async>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|@mojaloop/central-services-shared>@mojaloop/central-services-logger>winston>async>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|@mojaloop/central-services-shared>@mojaloop/event-sdk>@mojaloop/central-services-logger>winston>async>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|@mojaloop/event-sdk>@mojaloop/central-services-logger>winston>async>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|@mojaloop/central-services-shared>@mojaloop/event-sdk>winston>async>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|@mojaloop/event-sdk>winston>async>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|@mojaloop/central-services-shared>@mojaloop/event-sdk>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|@mojaloop/event-sdk>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|@mojaloop/central-services-shared>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|@mojaloop/central-services-shared>openapi-backend>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|@mojaloop/central-services-shared>openapi-backend>mock-json-schema>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 - }, - "1523|knex>lodash": { - "decision": "ignore", - "madeAt": 1593690759717, - "expiresAt": 1594295539291 + "madeAt": 1593089870124, + "expiresAt": 1595681864774 } }, "rules": {}, diff --git a/config/rules.example.json b/config/rules.example.json index 7e8b7e14..a03acfed 100644 --- a/config/rules.example.json +++ b/config/rules.example.json @@ -3,32 +3,76 @@ "conditions": { "all": [ { - "fact": "json-path", - "params": { - "fact": "payload", - "path": "$.payload.extensionList[?(@.key == 'KYCPayerTier')].value" - }, - "operator": "deepEqual", - "value": [ "1" ] + "fact": "payer", + "path": "$.accounts", + "operator": "isArray", + "value": false + } + ] + }, + "event": { + "type": "INVALID_QUOTE_REQUEST", + "params": { + "FSPIOPError": "PAYER_UNSUPPORTED_CURRENCY", + "message": "Payer does not have any active accounts" + } + } + }, + { + "conditions": { + "all": [ + { + "fact": "payee", + "path": "$.accounts", + "operator": "isArray", + "value": false + } + ] + }, + "event": { + "type": "INVALID_QUOTE_REQUEST", + "params": { + "FSPIOPError": "PAYEE_UNSUPPORTED_CURRENCY", + "message": "Payee does not have any active accounts" + } + } + }, + { + "conditions": { + "all": [ + { + "fact": "headers", + "path": "$.fspiop-source", + "operator": "notIn", + "value": [ + "DFSPXOF", + "DFSPEUR", + "DFSPMAD" + ] }, { "fact": "payload", - "path": ".amount.currency", + "path": "$.amount.currency", "operator": "notIn", "value": { - "fact": "json-path", - "params": { - "fact": "payee", - "path": "$.payee.accounts[?(@.ledgerAccountType == 'SETTLEMENT')].currency" - } + "fact": "payee", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" } + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "equal", + "value": "EUR" } ] }, "event": { "type": "INTERCEPT_QUOTE", "params": { - "rerouteToFsp": "DFSPEUR" + "rerouteToFsp": "DFSPEUR", + "sourceCurrency": "EUR", + "rerouteToFspCurrency": "XOF" } } }, @@ -36,24 +80,163 @@ "conditions": { "all": [ { - "fact": "json-path", - "params": { - "fact": "payload", - "path": "$.payload.extensionList[?(@.key == 'KYCPayerTier')].value" - }, - "operator": "notDeepEqual", - "value": [ "1" ] + "fact": "headers", + "path": "$.fspiop-source", + "operator": "notIn", + "value": [ + "DFSPXOF", + "DFSPEUR", + "DFSPMAD" + ] }, { "fact": "payload", - "path": ".amount.currency", + "path": "$.amount.currency", "operator": "notIn", "value": { - "fact": "json-path", - "params": { - "fact": "payee", - "path": "$.payee.accounts[?(@.ledgerAccountType == 'SETTLEMENT')].currency" - } + "fact": "payer", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "equal", + "value": "XOF" + } + ] + }, + "event": { + "type": "INTERCEPT_QUOTE", + "params": { + "rerouteToFsp": "DFSPEUR", + "sourceCurrency": "EUR", + "rerouteToFspCurrency": "XOF" + } + } + }, + { + "conditions": { + "all": [ + { + "fact": "headers", + "path": "$.fspiop-source", + "operator": "notIn", + "value": [ + "DFSPXOF", + "DFSPEUR", + "DFSPMAD" + ] + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payee", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "equal", + "value": "XOF" + } + ] + }, + "event": { + "type": "INTERCEPT_QUOTE", + "params": { + "rerouteToFsp": "DFSPXOF", + "sourceCurrency": "XOF", + "rerouteToFspCurrency": "EUR" + } + } + }, + { + "conditions": { + "all": [ + { + "fact": "headers", + "path": "$.fspiop-source", + "operator": "notIn", + "value": [ + "DFSPXOF", + "DFSPEUR", + "DFSPMAD" + ] + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payer", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "equal", + "value": "EUR" + } + ] + }, + "event": { + "type": "INTERCEPT_QUOTE", + "params": { + "rerouteToFsp": "DFSPXOF", + "sourceCurrency": "XOF", + "rerouteToFspCurrency": "EUR" + } + } + }, + { + "conditions": { + "all": [ + { + "fact": "payload", + "path": "$.amountType", + "operator": "equal", + "value": "SEND" + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payer", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + } + ] + }, + "event": { + "type": "INVALID_QUOTE_REQUEST", + "params": { + "FSPIOPError": "PAYER_UNSUPPORTED_CURRENCY", + "message": "Requested currency not available for payer" + } + } + }, + { + "conditions": { + "all": [ + { + "fact": "payload", + "path": "$.amountType", + "operator": "equal", + "value": "RECEIVE" + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payee", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" } } ] @@ -62,8 +245,286 @@ "type": "INVALID_QUOTE_REQUEST", "params": { "FSPIOPError": "PAYEE_UNSUPPORTED_CURRENCY", - "message": "The requested payee does not support the payment currency" + "message": "Requested currency not available for payee" + } + } + }, + { + "conditions": { + "all": [ + { + "fact": "headers", + "path": "$.fspiop-source", + "operator": "notIn", + "value": [ + "DFSPXOF", + "DFSPEUR", + "DFSPMAD" + ] + }, + { + "fact": "headers", + "path": "$.fspiop-source", + "operator": "notEqual", + "value": { + "fact": "payload", + "path": "$.payer.partyIdInfo.fspId" + } + } + ] + }, + "event": { + "type": "INVALID_QUOTE_REQUEST", + "params": { + "FSPIOPError": "PAYER_ERROR", + "message": "The payer FSP does not match the fspiop-source header" + } + } + }, + { + "conditions": { + "all": [ + { + "any": [ + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payee", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payer", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + } + ] + }, + { + "fact": "payload", + "path": "$.payer.personalInfo.complexName.firstName", + "operator": "isString", + "value": false + } + ] + }, + "event": { + "type": "INVALID_QUOTE_REQUEST", + "params": { + "FSPIOPError": "MISSING_ELEMENT", + "message": "firstName is required" + } + } + }, + { + "conditions": { + "all": [ + { + "any": [ + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payee", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payer", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + } + ] + }, + { + "fact": "payload", + "path": "$.payer.personalInfo.complexName.lastName", + "operator": "isString", + "value": false + } + ] + }, + "event": { + "type": "INVALID_QUOTE_REQUEST", + "params": { + "FSPIOPError": "MISSING_ELEMENT", + "message": "lastName is required" + } + } + }, + { + "conditions": { + "all": [ + { + "any": [ + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payee", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payer", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + } + ] + }, + { + "fact": "payload", + "path": "$.payer.personalInfo", + "operator": "isObject", + "value": false + } + ] + }, + "event": { + "type": "INVALID_QUOTE_REQUEST", + "params": { + "FSPIOPError": "MISSING_ELEMENT", + "message": "PartyPersonalInfo is required" + } + } + }, + { + "conditions": { + "all": [ + { + "any": [ + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payee", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payer", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + } + ] + }, + { + "fact": "payload", + "path": "$.payer.personalInfo.dateOfBirth", + "operator": "isString", + "value": false + } + ] + }, + "event": { + "type": "INVALID_QUOTE_REQUEST", + "params": { + "FSPIOPError": "MISSING_ELEMENT", + "message": "dateOfBirth is required" + } + } + }, + { + "conditions": { + "all": [ + { + "any": [ + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payer", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payee", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + } + ] + }, + { + "fact": "payer", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)]", + "operator": "isArray", + "value": true + } + ] + }, + "event": { + "type": "INVALID_QUOTE_REQUEST", + "params": { + "FSPIOPError": "PAYER_ERROR", + "message": "Payer should not have more than 1 currency account" + } + } + }, + { + "conditions": { + "all": [ + { + "any": [ + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payee", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + }, + { + "fact": "payload", + "path": "$.amount.currency", + "operator": "notIn", + "value": { + "fact": "payer", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)].currency" + } + } + ] + }, + { + "fact": "payee", + "path": "$.accounts[?(@.ledgerAccountType == 'POSITION' && @.isActive == 1)]", + "operator": "isArray", + "value": true + } + ] + }, + "event": { + "type": "INVALID_QUOTE_REQUEST", + "params": { + "FSPIOPError": "PAYEE_ERROR", + "message": "Payee should not have more than 1 currency account" } } } -] +] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8571d3bb..8fb9a857 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "quoting-service", - "version": "11.0.1", + "version": "12.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -481,14 +481,14 @@ } }, "@hapi/catbox": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@hapi/catbox/-/catbox-11.1.0.tgz", - "integrity": "sha512-FDEjfn26RZRyOEPeZdaAL7dRiAK5FOGuwTnTw0gxK30csAlKeOHsEnoIxnLIXx7QOS17eUaOk6+MiweWQM6Keg==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@hapi/catbox/-/catbox-11.1.1.tgz", + "integrity": "sha512-u/8HvB7dD/6X8hsZIpskSDo4yMKpHxFd7NluoylhGrL6cUfYxdQPnvUp9YU2C6F9hsyBVLGulBd9vBN1ebfXOQ==", "requires": { "@hapi/boom": "9.x.x", "@hapi/hoek": "9.x.x", - "@hapi/joi": "17.x.x", - "@hapi/podium": "4.x.x" + "@hapi/podium": "4.x.x", + "@hapi/validate": "1.x.x" } }, "@hapi/catbox-memory": { @@ -538,38 +538,38 @@ } }, "@hapi/hapi": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/@hapi/hapi/-/hapi-19.2.0.tgz", - "integrity": "sha512-Isf/BUPQMRMYK+xx4y2B05lrrGw6PSbJKytk1SlaXeV7tXm6m+6tFRBog6c/na0QNgojafb0bjMB+vBg64CwUA==", + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@hapi/hapi/-/hapi-20.0.0.tgz", + "integrity": "sha512-Wh0tIDFsl7nemU2JQYW4zZVr9XkpuZ1eM3yaX8tzaYdaYXon8QeB5NzrTNQY3R1/+fO7amQUrOoLLNPRwIZfgw==", "requires": { "@hapi/accept": "^5.0.1", "@hapi/ammo": "^5.0.1", "@hapi/boom": "9.x.x", "@hapi/bounce": "2.x.x", "@hapi/call": "8.x.x", - "@hapi/catbox": "^11.1.0", + "@hapi/catbox": "^11.1.1", "@hapi/catbox-memory": "5.x.x", - "@hapi/heavy": "7.x.x", + "@hapi/heavy": "^7.0.1", "@hapi/hoek": "9.x.x", - "@hapi/joi": "17.x.x", "@hapi/mimos": "5.x.x", - "@hapi/podium": "4.x.x", - "@hapi/shot": "5.x.x", + "@hapi/podium": "^4.1.1", + "@hapi/shot": "^5.0.1", "@hapi/somever": "3.x.x", - "@hapi/statehood": "^7.0.2", + "@hapi/statehood": "^7.0.3", "@hapi/subtext": "^7.0.3", - "@hapi/teamwork": "4.x.x", - "@hapi/topo": "5.x.x" + "@hapi/teamwork": "5.x.x", + "@hapi/topo": "5.x.x", + "@hapi/validate": "^1.1.0" } }, "@hapi/heavy": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@hapi/heavy/-/heavy-7.0.0.tgz", - "integrity": "sha512-n/nheUG6zNleWkjY+3fzV3VJIAumUCaa/WoTmurjqlYY5JgC5ZKOpvP7tWi8rXmKZhbcXgjH3fHFoM55LoBT7g==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@hapi/heavy/-/heavy-7.0.1.tgz", + "integrity": "sha512-vJ/vzRQ13MtRzz6Qd4zRHWS3FaUc/5uivV2TIuExGTM9Qk+7Zzqj0e2G7EpE6KztO9SalTbiIkTh7qFKj/33cA==", "requires": { "@hapi/boom": "9.x.x", "@hapi/hoek": "9.x.x", - "@hapi/joi": "17.x.x" + "@hapi/validate": "1.x.x" } }, "@hapi/hoek": { @@ -645,22 +645,22 @@ "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw==" }, "@hapi/podium": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@hapi/podium/-/podium-4.1.0.tgz", - "integrity": "sha512-k/n0McAu8PvonfQRLyKKUvvdb+Gh/O5iAeIwv535Hpxw9B1qZcrYdZyWtHZ8O5PkA9/b/Kk+BdvtgcxeKMB/2g==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@hapi/podium/-/podium-4.1.1.tgz", + "integrity": "sha512-jh7a6+5Z4FUWzx8fgmxjaAa1DTBu+Qfg+NbVdo0f++rE5DgsVidUYrLDp3db65+QjDLleA2MfKQXkpT8ylBDXA==", "requires": { "@hapi/hoek": "9.x.x", - "@hapi/joi": "17.x.x", - "@hapi/teamwork": "4.x.x" + "@hapi/teamwork": "5.x.x", + "@hapi/validate": "1.x.x" } }, "@hapi/shot": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@hapi/shot/-/shot-5.0.0.tgz", - "integrity": "sha512-JXddnJkRh3Xhv9lY1tA+TSIUaoODKbdNIPL/M8WFvFQKOttmGaDeqTW5e8Gf01LtLI7L5DraLMULHjrK1+YNFg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@hapi/shot/-/shot-5.0.1.tgz", + "integrity": "sha512-AnhIhB0UCBi8JpJ+BEkNs29FQGpp9yrFWDzPO/J9maS11VyDRh5cd1c6di6dX8IpYs/rUYr6uchXZ94OCo1ZDA==", "requires": { "@hapi/hoek": "9.x.x", - "@hapi/joi": "17.x.x" + "@hapi/validate": "1.x.x" } }, "@hapi/somever": { @@ -673,9 +673,9 @@ } }, "@hapi/statehood": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@hapi/statehood/-/statehood-7.0.2.tgz", - "integrity": "sha512-+0VNxysQu+UYzkfvAXq3X4aN65TnUwiR7gsq2cQ/4Rq26nCJjHAfrkYReEeshU2hPmJ3m5QuaBzyDqRm8WOpyg==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@hapi/statehood/-/statehood-7.0.3.tgz", + "integrity": "sha512-pYB+pyCHkf2Amh67QAXz7e/DN9jcMplIL7Z6N8h0K+ZTy0b404JKPEYkbWHSnDtxLjJB/OtgElxocr2fMH4G7w==", "requires": { "@hapi/boom": "9.x.x", "@hapi/bounce": "2.x.x", @@ -683,7 +683,7 @@ "@hapi/cryptiles": "5.x.x", "@hapi/hoek": "9.x.x", "@hapi/iron": "6.x.x", - "@hapi/joi": "17.x.x" + "@hapi/validate": "1.x.x" } }, "@hapi/subtext": { @@ -701,9 +701,9 @@ } }, "@hapi/teamwork": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@hapi/teamwork/-/teamwork-4.0.0.tgz", - "integrity": "sha512-V6xYOrr5aFv/IJqNPneaYCu8vuGTKisamqHVRS3JJnbZr18TrpXdsJOYk9pjPhFti+M2YETPebQLUr820N5NoQ==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/teamwork/-/teamwork-5.1.0.tgz", + "integrity": "sha512-llqoQTrAJDTXxG3c4Kz/uzhBS1TsmSBa/XG5SPcVXgmffHE1nFtyLIK0hNJHCB3EuBKT84adzd1hZNY9GJLWtg==" }, "@hapi/topo": { "version": "5.0.0", @@ -713,6 +713,15 @@ "@hapi/hoek": "^9.0.0" } }, + "@hapi/validate": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-1.1.2.tgz", + "integrity": "sha512-ojg3iE/haKh8aCZFObkOzuJ1vQ8NP+EiuibliJKe01IMstBPXQc4Xl08+8zqAL+iZSZKp1TaWdwaNSzq8HIMKA==", + "requires": { + "@hapi/hoek": "^9.0.0", + "@hapi/topo": "^5.0.0" + } + }, "@hapi/vise": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@hapi/vise/-/vise-4.0.0.tgz", @@ -765,32 +774,41 @@ "dev": true }, "@jest/console": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.2.0.tgz", - "integrity": "sha512-mXQfx3nSLwiHm1i7jbu+uvi+vvpVjNGzIQYLCfsat9rapC+MJkS4zBseNrgJE0vU921b3P67bQzhduphjY3Tig==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.3.0.tgz", + "integrity": "sha512-/5Pn6sJev0nPUcAdpJHMVIsA8sKizL2ZkcKPE5+dJrCccks7tcM7c9wbgHudBJbxXLoTbqsHkG1Dofoem4F09w==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.2.0", - "jest-util": "^26.2.0", + "jest-message-util": "^26.3.0", + "jest-util": "^26.3.0", "slash": "^3.0.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -829,34 +847,34 @@ } }, "@jest/core": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.2.2.tgz", - "integrity": "sha512-UwA8gNI8aeV4FHGfGAUfO/DHjrFVvlBravF1Tm9Kt6qFE+6YHR47kFhgdepOFpADEKstyO+MVdPvkV6/dyt9sA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.4.0.tgz", + "integrity": "sha512-mpXm4OjWQbz7qbzGIiSqvfNZ1FxX6ywWgLtdSD2luPORt5zKPtqcdDnX7L8RdfMaj1znDBgN2+gB094ZIr7vnA==", "dev": true, "requires": { - "@jest/console": "^26.2.0", - "@jest/reporters": "^26.2.2", - "@jest/test-result": "^26.2.0", - "@jest/transform": "^26.2.2", - "@jest/types": "^26.2.0", + "@jest/console": "^26.3.0", + "@jest/reporters": "^26.4.0", + "@jest/test-result": "^26.3.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.2.0", - "jest-config": "^26.2.2", - "jest-haste-map": "^26.2.2", - "jest-message-util": "^26.2.0", + "jest-changed-files": "^26.3.0", + "jest-config": "^26.4.0", + "jest-haste-map": "^26.3.0", + "jest-message-util": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.2.2", - "jest-resolve-dependencies": "^26.2.2", - "jest-runner": "^26.2.2", - "jest-runtime": "^26.2.2", - "jest-snapshot": "^26.2.2", - "jest-util": "^26.2.0", - "jest-validate": "^26.2.0", - "jest-watcher": "^26.2.0", + "jest-resolve": "^26.4.0", + "jest-resolve-dependencies": "^26.4.0", + "jest-runner": "^26.4.0", + "jest-runtime": "^26.4.0", + "jest-snapshot": "^26.4.0", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.0", + "jest-watcher": "^26.3.0", "micromatch": "^4.0.2", "p-each-series": "^2.1.0", "rimraf": "^3.0.0", @@ -865,18 +883,27 @@ }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -982,30 +1009,39 @@ } }, "@jest/environment": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.2.0.tgz", - "integrity": "sha512-oCgp9NmEiJ5rbq9VI/v/yYLDpladAAVvFxZgNsnJxOETuzPZ0ZcKKHYjKYwCtPOP1WCrM5nmyuOhMStXFGHn+g==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.3.0.tgz", + "integrity": "sha512-EW+MFEo0DGHahf83RAaiqQx688qpXgl99wdb8Fy67ybyzHwR1a58LHcO376xQJHfmoXTu89M09dH3J509cx2AA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.2.0", - "@jest/types": "^26.2.0", + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", "@types/node": "*", - "jest-mock": "^26.2.0" + "jest-mock": "^26.3.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -1044,32 +1080,41 @@ } }, "@jest/fake-timers": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.2.0.tgz", - "integrity": "sha512-45Gfe7YzYTKqTayBrEdAF0qYyAsNRBzfkV0IyVUm3cx7AsCWlnjilBM4T40w7IXT5VspOgMPikQlV0M6gHwy/g==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.3.0.tgz", + "integrity": "sha512-ZL9ytUiRwVP8ujfRepffokBvD2KbxbqMhrXSBhSdAhISCw3gOkuntisiSFv+A6HN0n0fF4cxzICEKZENLmW+1A==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "@sinonjs/fake-timers": "^6.0.1", "@types/node": "*", - "jest-message-util": "^26.2.0", - "jest-mock": "^26.2.0", - "jest-util": "^26.2.0" + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -1108,29 +1153,38 @@ } }, "@jest/globals": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.2.0.tgz", - "integrity": "sha512-Hoc6ScEIPaym7RNytIL2ILSUWIGKlwEv+JNFof9dGYOdvPjb2evEURSslvCMkNuNg1ECEClTE8PH7ULlMJntYA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.4.0.tgz", + "integrity": "sha512-QKwoVAeL9d0xaEM9ebPvfc+bolN04F+o3zM2jswGDBiiNjCogZ3LvOaqumRdDyz6kLmbx+UhgMBAVuLunbXZ2A==", "dev": true, "requires": { - "@jest/environment": "^26.2.0", - "@jest/types": "^26.2.0", - "expect": "^26.2.0" + "@jest/environment": "^26.3.0", + "@jest/types": "^26.3.0", + "expect": "^26.4.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -1169,16 +1223,16 @@ } }, "@jest/reporters": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.2.2.tgz", - "integrity": "sha512-7854GPbdFTAorWVh+RNHyPO9waRIN6TcvCezKVxI1khvFq9YjINTW7J3WU+tbR038Ynn6WjYred6vtT0YmIWVQ==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.4.0.tgz", + "integrity": "sha512-14OPAAuYhgRBSNxAocVluX6ksdMdK/EuP9NmtBXU9g1uKaVBrPnohn/CVm6iMot1a9iU8BCxa5715YRf8FEg/A==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.2.0", - "@jest/test-result": "^26.2.0", - "@jest/transform": "^26.2.2", - "@jest/types": "^26.2.0", + "@jest/console": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", @@ -1189,31 +1243,40 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.2.2", - "jest-resolve": "^26.2.2", - "jest-util": "^26.2.0", - "jest-worker": "^26.2.1", + "jest-haste-map": "^26.3.0", + "jest-resolve": "^26.4.0", + "jest-util": "^26.3.0", + "jest-worker": "^26.3.0", "node-notifier": "^7.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^4.1.3" + "v8-to-istanbul": "^5.0.1" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -1258,9 +1321,9 @@ } }, "@jest/source-map": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.1.0.tgz", - "integrity": "sha512-XYRPYx4eEVX15cMT9mstnO7hkHP3krNtKfxUYd8L7gbtia8JvZZ6bMzSwa6IQJENbudTwKMw5R1BePRD+bkEmA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.3.0.tgz", + "integrity": "sha512-hWX5IHmMDWe1kyrKl7IhFwqOuAreIwHhbe44+XH2ZRHjrKIh0LO5eLQ/vxHFeAfRwJapmxuqlGAEYLadDq6ZGQ==", "dev": true, "requires": { "callsites": "^3.0.0", @@ -1277,30 +1340,39 @@ } }, "@jest/test-result": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.2.0.tgz", - "integrity": "sha512-kgPlmcVafpmfyQEu36HClK+CWI6wIaAWDHNxfQtGuKsgoa2uQAYdlxjMDBEa3CvI40+2U3v36gQF6oZBkoKatw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz", + "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==", "dev": true, "requires": { - "@jest/console": "^26.2.0", - "@jest/types": "^26.2.0", + "@jest/console": "^26.3.0", + "@jest/types": "^26.3.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -1339,34 +1411,34 @@ } }, "@jest/test-sequencer": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.2.2.tgz", - "integrity": "sha512-SliZWon5LNqV/lVXkeowSU6L8++FGOu3f43T01L1Gv6wnFDP00ER0utV9jyK9dVNdXqfMNCN66sfcyar/o7BNw==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.4.0.tgz", + "integrity": "sha512-9Z7lCShS7vERp+DRwIVNH/6sHMWwJK1DPnGCpGeVLGJJWJ4Y08sQI3vIKdmKHu2KmwlUBpRM+BFf7NlVUkl5XA==", "dev": true, "requires": { - "@jest/test-result": "^26.2.0", + "@jest/test-result": "^26.3.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.2.2", - "jest-runner": "^26.2.2", - "jest-runtime": "^26.2.2" + "jest-haste-map": "^26.3.0", + "jest-runner": "^26.4.0", + "jest-runtime": "^26.4.0" } }, "@jest/transform": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.2.2.tgz", - "integrity": "sha512-c1snhvi5wRVre1XyoO3Eef5SEWpuBCH/cEbntBUd9tI5sNYiBDmO0My/lc5IuuGYKp/HFIHV1eZpSx5yjdkhKw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.3.0.tgz", + "integrity": "sha512-Isj6NB68QorGoFWvcOjlUhpkT56PqNIsXKR7XfvoDlCANn/IANlh8DrKAA2l2JKC3yWSMH5wS0GwuQM20w3b2A==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "babel-plugin-istanbul": "^6.0.0", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.2.2", + "jest-haste-map": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-util": "^26.2.0", + "jest-util": "^26.3.0", "micromatch": "^4.0.2", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -1375,18 +1447,27 @@ }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -1541,6 +1622,20 @@ "requires": { "@mojaloop/sdk-standard-components": "10.3.2", "lodash": "4.17.19" + }, + "dependencies": { + "@mojaloop/sdk-standard-components": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@mojaloop/sdk-standard-components/-/sdk-standard-components-10.3.2.tgz", + "integrity": "sha512-O5DqUL+ncS718nFDFUMx8QO0pmTmg+/CNYuaXPrFfHDgf8c05mgSjg6Z8wt69Auwph6WXWaNjKTQRqZG2/BDdQ==", + "requires": { + "base64url": "3.0.1", + "fast-safe-stringify": "^2.0.7", + "ilp-packet": "2.2.0", + "jsonwebtoken": "8.5.1", + "jws": "4.0.0" + } + } } }, "@mojaloop/central-services-logger": { @@ -1562,9 +1657,9 @@ } }, "@mojaloop/central-services-shared": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@mojaloop/central-services-shared/-/central-services-shared-11.1.0.tgz", - "integrity": "sha512-CZqmbJ1VPiRn42U/4KXxGRxuTAUlQ/+kIVb9CmjffJ8aOn9nd/GboP5zzqDdJarqtSUw0J54CHFbV2jgBxf7TA==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@mojaloop/central-services-shared/-/central-services-shared-11.1.2.tgz", + "integrity": "sha512-MGqtFlYijTdDrxboZhLg/IZgH5+8tF2X2FlHMbENrl5lSxNjD1vNklKj6fIV9335HlImzd4QPnUO4vrjkcKaIw==", "requires": { "@hapi/catbox": "11.1.0", "@hapi/catbox-memory": "5.0.0", @@ -1584,6 +1679,19 @@ "openapi-backend": "3.5.1", "raw-body": "2.4.1", "uuid4": "2.0.2" + }, + "dependencies": { + "@hapi/catbox": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@hapi/catbox/-/catbox-11.1.0.tgz", + "integrity": "sha512-FDEjfn26RZRyOEPeZdaAL7dRiAK5FOGuwTnTw0gxK30csAlKeOHsEnoIxnLIXx7QOS17eUaOk6+MiweWQM6Keg==", + "requires": { + "@hapi/boom": "9.x.x", + "@hapi/hoek": "9.x.x", + "@hapi/joi": "17.x.x", + "@hapi/podium": "4.x.x" + } + } } }, "@mojaloop/event-sdk": { @@ -1607,6 +1715,22 @@ "tslib": "2.0.0", "uuid4": "2.0.2", "winston": "3.3.3" + }, + "dependencies": { + "sinon": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.2.tgz", + "integrity": "sha512-0uF8Q/QHkizNUmbK3LRFqx5cpTttEVXudywY9Uwzy8bTfZUhljZ7ARzSxnRHWYWtVTeh4Cw+tTb3iU21FQVO9A==", + "requires": { + "@sinonjs/commons": "^1.7.2", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/formatio": "^5.0.1", + "@sinonjs/samsam": "^5.0.3", + "diff": "^4.0.2", + "nise": "^4.0.1", + "supports-color": "^7.1.0" + } + } } }, "@mojaloop/ml-number": { @@ -1625,9 +1749,9 @@ } }, "@mojaloop/sdk-standard-components": { - "version": "10.3.2", - "resolved": "https://registry.npmjs.org/@mojaloop/sdk-standard-components/-/sdk-standard-components-10.3.2.tgz", - "integrity": "sha512-O5DqUL+ncS718nFDFUMx8QO0pmTmg+/CNYuaXPrFfHDgf8c05mgSjg6Z8wt69Auwph6WXWaNjKTQRqZG2/BDdQ==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@mojaloop/sdk-standard-components/-/sdk-standard-components-11.0.0.tgz", + "integrity": "sha512-PWVbrs+8RFea4ZM5UQonr0/fyHxyH6OfmtOD5q+J/RAy42j+9IpBywVVK2jYdMS4HnJnHGT6EOjBA63HsSk+xw==", "requires": { "base64url": "3.0.1", "fast-safe-stringify": "^2.0.7", @@ -1721,9 +1845,9 @@ } }, "@npmcli/run-script": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.4.0.tgz", - "integrity": "sha512-evlD0Ur2ILGyTP7FfMYi90x80bto9+nEbGjoWzdF+gmIX3HuA1nW0Ghj91JFaTJAHiXnDEEduZS24oAve/aeOA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.5.0.tgz", + "integrity": "sha512-z7AzLmsMtVntMRJt35M5VAjb/jH6yH37Q8Ku011JVR7rEoy+p2a6/NkwqChCRZORlJaS9rwjXmZKM6UmwXLkqA==", "dev": true, "requires": { "@npmcli/promise-spawn": "^1.2.0", @@ -1818,9 +1942,9 @@ } }, "@sinonjs/samsam": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.0.3.tgz", - "integrity": "sha512-QucHkc2uMJ0pFGjJUDP3F9dq5dx8QIaqISl9QgwLOh6P9yv877uONPGXh/OH/0zmM3tW1JjuJltAZV2l7zU+uQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.1.0.tgz", + "integrity": "sha512-42nyaQOVunX5Pm6GRJobmzbS7iLI+fhERITnETXzzwDZh+TtDr/Au3yAvXVjFmZ4wEUaE4Y3NFZfKv0bV0cbtg==", "requires": { "@sinonjs/commons": "^1.6.0", "lodash.get": "^4.4.2", @@ -2351,9 +2475,9 @@ "dev": true }, "aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz", + "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", "dev": true }, "axios": { @@ -2365,34 +2489,43 @@ } }, "babel-jest": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.2.2.tgz", - "integrity": "sha512-JmLuePHgA+DSOdOL8lPxCgD2LhPPm+rdw1vnxR73PpIrnmKCS2/aBhtkAcxQWuUcW2hBrH8MJ3LKXE7aWpNZyA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.3.0.tgz", + "integrity": "sha512-sxPnQGEyHAOPF8NcUsD0g7hDCnvLL2XyblRBcgrzTWBB/mAIpWow3n1bEL+VghnnZfreLhFSBsFluRoK2tRK4g==", "dev": true, "requires": { - "@jest/transform": "^26.2.2", - "@jest/types": "^26.2.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", "@types/babel__core": "^7.1.7", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.2.0", + "babel-preset-jest": "^26.3.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -2475,13 +2608,13 @@ } }, "babel-preset-jest": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.2.0.tgz", - "integrity": "sha512-R1k8kdP3R9phYQugXeNnK/nvCGlBzG4m3EoIIukC80GXb6wCv2XiwPhK6K9MAkQcMszWBYvl2Wm+yigyXFQqXg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.3.0.tgz", + "integrity": "sha512-5WPdf7nyYi2/eRxCbVrE1kKCWxgWY4RsPEbdJWFm7QsesFGqjdkyLeu1zRkwM1cxK6EPIlNd6d2AxLk7J+t4pw==", "dev": true, "requires": { "babel-plugin-jest-hoist": "^26.2.0", - "babel-preset-current-node-syntax": "^0.1.2" + "babel-preset-current-node-syntax": "^0.1.3" } }, "balanced-match": { @@ -2932,9 +3065,9 @@ }, "dependencies": { "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -4588,32 +4721,41 @@ } }, "expect": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.2.0.tgz", - "integrity": "sha512-8AMBQ9UVcoUXt0B7v+5/U5H6yiUR87L6eKCfjE3spx7Ya5lF+ebUo37MCFBML2OiLfkX1sxmQOZhIDonyVTkcw==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.4.0.tgz", + "integrity": "sha512-dbYDJhFcqQsamlos6nEwAMe+ahdckJBk5fmw1DYGLQGabGSlUuT+Fm2jHYw5119zG3uIhP+lCQbjJhFEdZMJtg==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.2.0", - "jest-message-util": "^26.2.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.4.0", + "jest-message-util": "^26.3.0", "jest-regex-util": "^26.0.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -4650,9 +4792,9 @@ "dev": true }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true } } @@ -6185,29 +6327,38 @@ } }, "jest": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.2.2.tgz", - "integrity": "sha512-EkJNyHiAG1+A8pqSz7cXttoVa34hOEzN/MrnJhYnfp5VHxflVcf2pu3oJSrhiy6LfIutLdWo+n6q63tjcoIeig==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.4.0.tgz", + "integrity": "sha512-lNCOS+ckRHE1wFyVtQClBmbsOVuH2GWUTJMDL3vunp9DXcah+V8vfvVVApngClcdoc3rgZpqOfCNKLjxjj2l4g==", "dev": true, "requires": { - "@jest/core": "^26.2.2", + "@jest/core": "^26.4.0", "import-local": "^3.0.2", - "jest-cli": "^26.2.2" + "jest-cli": "^26.4.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -6273,22 +6424,22 @@ "dev": true }, "jest-cli": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.2.2.tgz", - "integrity": "sha512-vVcly0n/ijZvdy6gPQiQt0YANwX2hLTPQZHtW7Vi3gcFdKTtif7YpI85F8R8JYy5DFSWz4x1OW0arnxlziu5Lw==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.4.0.tgz", + "integrity": "sha512-kw2Pr3V2x9/WzSDGsbz/MJBNlCoPMxMudrIavft4bqRlv5tASjU51tyO+1Os1LdW2dAnLQZYsxFUZ8oWPyssGQ==", "dev": true, "requires": { - "@jest/core": "^26.2.2", - "@jest/test-result": "^26.2.0", - "@jest/types": "^26.2.0", + "@jest/core": "^26.4.0", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", "is-ci": "^2.0.0", - "jest-config": "^26.2.2", - "jest-util": "^26.2.0", - "jest-validate": "^26.2.0", + "jest-config": "^26.4.0", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.0", "prompts": "^2.0.1", "yargs": "^15.3.1" } @@ -6352,29 +6503,38 @@ } }, "jest-changed-files": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.2.0.tgz", - "integrity": "sha512-+RyJb+F1K/XBLIYiL449vo5D+CvlHv29QveJUWNPXuUicyZcq+tf1wNxmmFeRvAU1+TzhwqczSjxnCCFt7+8iA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.3.0.tgz", + "integrity": "sha512-1C4R4nijgPltX6fugKxM4oQ18zimS7LqQ+zTTY8lMCMFPrxqBFb7KJH0Z2fRQJvw2Slbaipsqq7s1mgX5Iot+g==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "execa": "^4.0.0", "throat": "^5.0.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -6428,9 +6588,9 @@ } }, "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -6458,44 +6618,53 @@ } }, "jest-config": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.2.2.tgz", - "integrity": "sha512-2lhxH0y4YFOijMJ65usuf78m7+9/8+hAb1PZQtdRdgnQpAb4zP6KcVDDktpHEkspBKnc2lmFu+RQdHukUUbiTg==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.4.0.tgz", + "integrity": "sha512-MxsvrBug8YY+C4QcUBtmgnHyFeW7w3Ouk/w9eplCDN8VJGVyBEZFe8Lxzfp2pSqh0Dqurqv8Oik2YkbekGUlxg==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.2.2", - "@jest/types": "^26.2.0", - "babel-jest": "^26.2.2", + "@jest/test-sequencer": "^26.4.0", + "@jest/types": "^26.3.0", + "babel-jest": "^26.3.0", "chalk": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.2.0", - "jest-environment-node": "^26.2.0", - "jest-get-type": "^26.0.0", - "jest-jasmine2": "^26.2.2", + "jest-environment-jsdom": "^26.3.0", + "jest-environment-node": "^26.3.0", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.4.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.2.2", - "jest-util": "^26.2.0", - "jest-validate": "^26.2.0", + "jest-resolve": "^26.4.0", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.0", "micromatch": "^4.0.2", - "pretty-format": "^26.2.0" + "pretty-format": "^26.4.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -6562,9 +6731,9 @@ "dev": true }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "micromatch": { @@ -6578,12 +6747,12 @@ } }, "pretty-format": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.2.0.tgz", - "integrity": "sha512-qi/8IuBu2clY9G7qCXgCdD1Bf9w+sXakdHTRToknzMtVy0g7c4MBWaZy7MfB7ndKZovRO6XRwJiAYqq+MC7SDA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.0.tgz", + "integrity": "sha512-mEEwwpCseqrUtuMbrJG4b824877pM5xald3AkilJ47Po2YLr97/siejYQHqj2oDQBeJNbu+Q0qUuekJ8F0NAPg==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -6659,31 +6828,40 @@ } }, "jest-each": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.2.0.tgz", - "integrity": "sha512-gHPCaho1twWHB5bpcfnozlc6mrMi+VAewVPNgmwf81x2Gzr6XO4dl+eOrwPWxbkYlgjgrYjWK2xgKnixbzH3Ew==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.4.0.tgz", + "integrity": "sha512-+cyBh1ehs6thVT/bsZVG+WwmRn2ix4Q4noS9yLZgM10yGWPW12/TDvwuOV2VZXn1gi09/ZwJKJWql6YW1C9zNw==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-util": "^26.2.0", - "pretty-format": "^26.2.0" + "jest-get-type": "^26.3.0", + "jest-util": "^26.3.0", + "pretty-format": "^26.4.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -6726,18 +6904,18 @@ "dev": true }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "pretty-format": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.2.0.tgz", - "integrity": "sha512-qi/8IuBu2clY9G7qCXgCdD1Bf9w+sXakdHTRToknzMtVy0g7c4MBWaZy7MfB7ndKZovRO6XRwJiAYqq+MC7SDA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.0.tgz", + "integrity": "sha512-mEEwwpCseqrUtuMbrJG4b824877pM5xald3AkilJ47Po2YLr97/siejYQHqj2oDQBeJNbu+Q0qUuekJ8F0NAPg==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -6746,33 +6924,42 @@ } }, "jest-environment-jsdom": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.2.0.tgz", - "integrity": "sha512-sDG24+5M4NuIGzkI3rJW8XUlrpkvIdE9Zz4jhD8OBnVxAw+Y1jUk9X+lAOD48nlfUTlnt3lbAI3k2Ox+WF3S0g==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.3.0.tgz", + "integrity": "sha512-zra8He2btIMJkAzvLaiZ9QwEPGEetbxqmjEBQwhH3CA+Hhhu0jSiEJxnJMbX28TGUvPLxBt/zyaTLrOPF4yMJA==", "dev": true, "requires": { - "@jest/environment": "^26.2.0", - "@jest/fake-timers": "^26.2.0", - "@jest/types": "^26.2.0", + "@jest/environment": "^26.3.0", + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", "@types/node": "*", - "jest-mock": "^26.2.0", - "jest-util": "^26.2.0", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0", "jsdom": "^16.2.2" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -6811,32 +6998,41 @@ } }, "jest-environment-node": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.2.0.tgz", - "integrity": "sha512-4M5ExTYkJ19efBzkiXtBi74JqKLDciEk4CEsp5tTjWGYMrlKFQFtwIVG3tW1OGE0AlXhZjuHPwubuRYY4j4uOw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.3.0.tgz", + "integrity": "sha512-c9BvYoo+FGcMj5FunbBgtBnbR5qk3uky8PKyRVpSfe2/8+LrNQMiXX53z6q2kY+j15SkjQCOSL/6LHnCPLVHNw==", "dev": true, "requires": { - "@jest/environment": "^26.2.0", - "@jest/fake-timers": "^26.2.0", - "@jest/types": "^26.2.0", + "@jest/environment": "^26.3.0", + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", "@types/node": "*", - "jest-mock": "^26.2.0", - "jest-util": "^26.2.0" + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -6881,12 +7077,12 @@ "dev": true }, "jest-haste-map": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.2.2.tgz", - "integrity": "sha512-3sJlMSt+NHnzCB+0KhJ1Ut4zKJBiJOlbrqEYNdRQGlXTv8kqzZWjUKQRY3pkjmlf+7rYjAV++MQ4D6g4DhAyOg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.3.0.tgz", + "integrity": "sha512-DHWBpTJgJhLLGwE5Z1ZaqLTYqeODQIZpby0zMBsCU9iRFHYyhklYqP4EiG73j5dkbaAdSZhgB938mL51Q5LeZA==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", @@ -6894,27 +7090,36 @@ "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.2.0", - "jest-util": "^26.2.0", - "jest-worker": "^26.2.1", + "jest-serializer": "^26.3.0", + "jest-util": "^26.3.0", + "jest-worker": "^26.3.0", "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -6996,44 +7201,53 @@ } }, "jest-jasmine2": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.2.2.tgz", - "integrity": "sha512-Q8AAHpbiZMVMy4Hz9j1j1bg2yUmPa1W9StBvcHqRaKa9PHaDUMwds8LwaDyzP/2fkybcTQE4+pTMDOG9826tEw==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.4.0.tgz", + "integrity": "sha512-cGBxwzDDKB09EPJ4pE69BMDv+2lO442IB1xQd+vL3cua2OKdeXQK6iDlQKoRX/iP0RgU5T8sn9yahLcx/+ox8Q==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.2.0", - "@jest/source-map": "^26.1.0", - "@jest/test-result": "^26.2.0", - "@jest/types": "^26.2.0", + "@jest/environment": "^26.3.0", + "@jest/source-map": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^26.2.0", + "expect": "^26.4.0", "is-generator-fn": "^2.0.0", - "jest-each": "^26.2.0", - "jest-matcher-utils": "^26.2.0", - "jest-message-util": "^26.2.0", - "jest-runtime": "^26.2.2", - "jest-snapshot": "^26.2.2", - "jest-util": "^26.2.0", - "pretty-format": "^26.2.0", + "jest-each": "^26.4.0", + "jest-matcher-utils": "^26.4.0", + "jest-message-util": "^26.3.0", + "jest-runtime": "^26.4.0", + "jest-snapshot": "^26.4.0", + "jest-util": "^26.3.0", + "pretty-format": "^26.4.0", "throat": "^5.0.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -7076,12 +7290,12 @@ "dev": true }, "pretty-format": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.2.0.tgz", - "integrity": "sha512-qi/8IuBu2clY9G7qCXgCdD1Bf9w+sXakdHTRToknzMtVy0g7c4MBWaZy7MfB7ndKZovRO6XRwJiAYqq+MC7SDA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.0.tgz", + "integrity": "sha512-mEEwwpCseqrUtuMbrJG4b824877pM5xald3AkilJ47Po2YLr97/siejYQHqj2oDQBeJNbu+Q0qUuekJ8F0NAPg==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -7131,28 +7345,37 @@ } }, "jest-leak-detector": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.2.0.tgz", - "integrity": "sha512-aQdzTX1YiufkXA1teXZu5xXOJgy7wZQw6OJ0iH5CtQlOETe6gTSocaYKUNui1SzQ91xmqEUZ/WRavg9FD82rtQ==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.4.0.tgz", + "integrity": "sha512-7EXKKEKnAWUPyiVtGZzJflbPOtYUdlNoevNVOkAcPpdR8xWiYKPGNGA6sz25S+8YhZq3rmkQJYAh3/P0VnoRwA==", "dev": true, "requires": { - "jest-get-type": "^26.0.0", - "pretty-format": "^26.2.0" + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -7195,18 +7418,18 @@ "dev": true }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "pretty-format": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.2.0.tgz", - "integrity": "sha512-qi/8IuBu2clY9G7qCXgCdD1Bf9w+sXakdHTRToknzMtVy0g7c4MBWaZy7MfB7ndKZovRO6XRwJiAYqq+MC7SDA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.0.tgz", + "integrity": "sha512-mEEwwpCseqrUtuMbrJG4b824877pM5xald3AkilJ47Po2YLr97/siejYQHqj2oDQBeJNbu+Q0qUuekJ8F0NAPg==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -7215,30 +7438,39 @@ } }, "jest-matcher-utils": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.2.0.tgz", - "integrity": "sha512-2cf/LW2VFb3ayPHrH36ZDjp9+CAeAe/pWBAwsV8t3dKcrINzXPVxq8qMWOxwt5BaeBCx4ZupVGH7VIgB8v66vQ==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.4.0.tgz", + "integrity": "sha512-u+xdCdq+F262DH+PutJKXLGr2H5P3DImdJCir51PGSfi3TtbLQ5tbzKaN8BkXbiTIU6ayuAYBWTlU1nyckVdzA==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.2.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.2.0" + "jest-diff": "^26.4.0", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -7281,36 +7513,36 @@ "dev": true }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.3.0.tgz", + "integrity": "sha512-5j5vdRcw3CNctePNYN0Wy2e/JbWT6cAYnXv5OuqPhDpyCGc0uLu2TK0zOCJWNB9kOIfYMSpIulRaDgIi4HJ6Ig==", "dev": true }, "jest-diff": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.2.0.tgz", - "integrity": "sha512-Wu4Aopi2nzCsHWLBlD48TgRy3Z7OsxlwvHNd1YSnHc7q1NJfrmyCPoUXrTIrydQOG5ApaYpsAsdfnMbJqV1/wQ==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.4.0.tgz", + "integrity": "sha512-wwC38HlOW+iTq6j5tkj/ZamHn6/nrdcEOc/fKaVILNtN2NLWGdkfRaHWwfNYr5ehaLvuoG2LfCZIcWByVj0gjg==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.2.0" + "diff-sequences": "^26.3.0", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.0" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "pretty-format": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.2.0.tgz", - "integrity": "sha512-qi/8IuBu2clY9G7qCXgCdD1Bf9w+sXakdHTRToknzMtVy0g7c4MBWaZy7MfB7ndKZovRO6XRwJiAYqq+MC7SDA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.0.tgz", + "integrity": "sha512-mEEwwpCseqrUtuMbrJG4b824877pM5xald3AkilJ47Po2YLr97/siejYQHqj2oDQBeJNbu+Q0qUuekJ8F0NAPg==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -7319,13 +7551,13 @@ } }, "jest-message-util": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.2.0.tgz", - "integrity": "sha512-g362RhZaJuqeqG108n1sthz5vNpzTNy926eNDszo4ncRbmmcMRIUAZibnd6s5v2XSBCChAxQtCoN25gnzp7JbQ==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.3.0.tgz", + "integrity": "sha512-xIavRYqr4/otGOiLxLZGj3ieMmjcNE73Ui+LdSW/Y790j5acqCsAdDiLIbzHCZMpN07JOENRWX5DcU+OQ+TjTA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "@types/stack-utils": "^1.0.1", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -7335,18 +7567,27 @@ }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -7428,28 +7669,37 @@ } }, "jest-mock": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.2.0.tgz", - "integrity": "sha512-XeC7yWtWmWByoyVOHSsE7NYsbXJLtJNgmhD7z4MKumKm6ET0si81bsSLbQ64L5saK3TgsHo2B/UqG5KNZ1Sp/Q==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.3.0.tgz", + "integrity": "sha512-PeaRrg8Dc6mnS35gOo/CbZovoDPKAeB1FICZiuagAgGvbWdNNyjQjkOaGUa/3N3JtpQ/Mh9P4A2D4Fv51NnP8Q==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "@types/node": "*" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -7500,34 +7750,43 @@ "dev": true }, "jest-resolve": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.2.2.tgz", - "integrity": "sha512-ye9Tj/ILn/0OgFPE/3dGpQPUqt4dHwIocxt5qSBkyzxQD8PbL0bVxBogX2FHxsd3zJA7V2H/cHXnBnNyyT9YoQ==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.4.0.tgz", + "integrity": "sha512-bn/JoZTEXRSlEx3+SfgZcJAVuTMOksYq9xe9O6s4Ekg84aKBObEaVXKOEilULRqviSLAYJldnoWV9c07kwtiCg==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.2.0", + "jest-util": "^26.3.0", "read-pkg-up": "^7.0.1", "resolve": "^1.17.0", "slash": "^3.0.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -7566,29 +7825,38 @@ } }, "jest-resolve-dependencies": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.2.2.tgz", - "integrity": "sha512-S5vufDmVbQXnpP7435gr710xeBGUFcKNpNswke7RmFvDQtmqPjPVU/rCeMlEU0p6vfpnjhwMYeaVjKZAy5QYJA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.4.0.tgz", + "integrity": "sha512-hznK/hlrlhu8hwdbieRdHFKmcV83GW8t30libt/v6j1L3IEzb8iN21SaWzV8KRAAK4ijiU0kuge0wnHn+0rytQ==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.2.2" + "jest-snapshot": "^26.4.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -7627,46 +7895,55 @@ } }, "jest-runner": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.2.2.tgz", - "integrity": "sha512-/qb6ptgX+KQ+aNMohJf1We695kaAfuu3u3ouh66TWfhTpLd9WbqcF6163d/tMoEY8GqPztXPLuyG0rHRVDLxCA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.4.0.tgz", + "integrity": "sha512-XF+tnUGolnPriu6Gg+HHWftspMjD5NkTV2mQppQnpZe39GcUangJ0al7aBGtA3GbVAcRd048DQiJPmsQRdugjw==", "dev": true, "requires": { - "@jest/console": "^26.2.0", - "@jest/environment": "^26.2.0", - "@jest/test-result": "^26.2.0", - "@jest/types": "^26.2.0", + "@jest/console": "^26.3.0", + "@jest/environment": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.7.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-config": "^26.2.2", + "jest-config": "^26.4.0", "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.2.2", - "jest-leak-detector": "^26.2.0", - "jest-message-util": "^26.2.0", - "jest-resolve": "^26.2.2", - "jest-runtime": "^26.2.2", - "jest-util": "^26.2.0", - "jest-worker": "^26.2.1", + "jest-haste-map": "^26.3.0", + "jest-leak-detector": "^26.4.0", + "jest-message-util": "^26.3.0", + "jest-resolve": "^26.4.0", + "jest-runtime": "^26.4.0", + "jest-util": "^26.3.0", + "jest-worker": "^26.3.0", "source-map-support": "^0.5.6", "throat": "^5.0.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -7705,52 +7982,61 @@ } }, "jest-runtime": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.2.2.tgz", - "integrity": "sha512-a8VXM3DxCDnCIdl9+QucWFfQ28KdqmyVFqeKLigHdErtsx56O2ZIdQkhFSuP1XtVrG9nTNHbKxjh5XL1UaFDVQ==", - "dev": true, - "requires": { - "@jest/console": "^26.2.0", - "@jest/environment": "^26.2.0", - "@jest/fake-timers": "^26.2.0", - "@jest/globals": "^26.2.0", - "@jest/source-map": "^26.1.0", - "@jest/test-result": "^26.2.0", - "@jest/transform": "^26.2.2", - "@jest/types": "^26.2.0", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.4.0.tgz", + "integrity": "sha512-1fjZgGpkyQBUTo59Vi19I4IcsBwzY6uwVFNjUmR06iIi3XRErkY28yimi4IUDRrofQErqcDEw2n3DF9WmQ6vEg==", + "dev": true, + "requires": { + "@jest/console": "^26.3.0", + "@jest/environment": "^26.3.0", + "@jest/fake-timers": "^26.3.0", + "@jest/globals": "^26.4.0", + "@jest/source-map": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", "@types/yargs": "^15.0.0", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-config": "^26.2.2", - "jest-haste-map": "^26.2.2", - "jest-message-util": "^26.2.0", - "jest-mock": "^26.2.0", + "jest-config": "^26.4.0", + "jest-haste-map": "^26.3.0", + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.2.2", - "jest-snapshot": "^26.2.2", - "jest-util": "^26.2.0", - "jest-validate": "^26.2.0", + "jest-resolve": "^26.4.0", + "jest-snapshot": "^26.4.0", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.0", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^15.3.1" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -7874,9 +8160,9 @@ } }, "jest-serializer": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.2.0.tgz", - "integrity": "sha512-V7snZI9IVmyJEu0Qy0inmuXgnMWDtrsbV2p9CRAcmlmPVwpC2ZM8wXyYpiugDQnwLHx0V4+Pnog9Exb3UO8M6Q==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.3.0.tgz", + "integrity": "sha512-IDRBQBLPlKa4flg77fqg0n/pH87tcRKwe8zxOVTWISxGpPHYkRZ1dXKyh04JOja7gppc60+soKVZ791mruVdow==", "dev": true, "requires": { "@types/node": "*", @@ -7884,41 +8170,50 @@ } }, "jest-snapshot": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.2.2.tgz", - "integrity": "sha512-NdjD8aJS7ePu268Wy/n/aR1TUisG0BOY+QOW4f6h46UHEKOgYmmkvJhh2BqdVZQ0BHSxTMt04WpCf9njzx8KtA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.4.0.tgz", + "integrity": "sha512-vFGmNGWHMBomrlOpheTMoqihymovuH3GqfmaEIWoPpsxUXyxT3IlbxI5I4m2vg0uv3HUJYg5JoGrkgMzVsAwCg==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.2.0", + "expect": "^26.4.0", "graceful-fs": "^4.2.4", - "jest-diff": "^26.2.0", - "jest-get-type": "^26.0.0", - "jest-haste-map": "^26.2.2", - "jest-matcher-utils": "^26.2.0", - "jest-message-util": "^26.2.0", - "jest-resolve": "^26.2.2", + "jest-diff": "^26.4.0", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.3.0", + "jest-matcher-utils": "^26.4.0", + "jest-message-util": "^26.3.0", + "jest-resolve": "^26.4.0", "natural-compare": "^1.4.0", - "pretty-format": "^26.2.0", + "pretty-format": "^26.4.0", "semver": "^7.3.2" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -7961,36 +8256,36 @@ "dev": true }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.3.0.tgz", + "integrity": "sha512-5j5vdRcw3CNctePNYN0Wy2e/JbWT6cAYnXv5OuqPhDpyCGc0uLu2TK0zOCJWNB9kOIfYMSpIulRaDgIi4HJ6Ig==", "dev": true }, "jest-diff": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.2.0.tgz", - "integrity": "sha512-Wu4Aopi2nzCsHWLBlD48TgRy3Z7OsxlwvHNd1YSnHc7q1NJfrmyCPoUXrTIrydQOG5ApaYpsAsdfnMbJqV1/wQ==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.4.0.tgz", + "integrity": "sha512-wwC38HlOW+iTq6j5tkj/ZamHn6/nrdcEOc/fKaVILNtN2NLWGdkfRaHWwfNYr5ehaLvuoG2LfCZIcWByVj0gjg==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.2.0" + "diff-sequences": "^26.3.0", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.0" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "pretty-format": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.2.0.tgz", - "integrity": "sha512-qi/8IuBu2clY9G7qCXgCdD1Bf9w+sXakdHTRToknzMtVy0g7c4MBWaZy7MfB7ndKZovRO6XRwJiAYqq+MC7SDA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.0.tgz", + "integrity": "sha512-mEEwwpCseqrUtuMbrJG4b824877pM5xald3AkilJ47Po2YLr97/siejYQHqj2oDQBeJNbu+Q0qUuekJ8F0NAPg==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -8005,12 +8300,12 @@ } }, "jest-util": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.2.0.tgz", - "integrity": "sha512-YmDwJxLZ1kFxpxPfhSJ0rIkiZOM0PQbRcfH0TzJOhqCisCAsI1WcmoQqO83My9xeVA2k4n+rzg2UuexVKzPpig==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", + "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -8019,18 +8314,27 @@ }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -8112,32 +8416,41 @@ } }, "jest-validate": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.2.0.tgz", - "integrity": "sha512-8XKn3hM6VIVmLNuyzYLCPsRCT83o8jMZYhbieh4dAyKLc4Ypr36rVKC+c8WMpWkfHHpGnEkvWUjjIAyobEIY/Q==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.4.0.tgz", + "integrity": "sha512-t56Z/FRMrLP6mpmje7/YgHy0wOzcuc6i3LBXz6kjmsUWYN62OuMdC86Vg9/dX59SvyitSqqegOrx+h7BkNXeaQ==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "camelcase": "^6.0.0", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", + "jest-get-type": "^26.3.0", "leven": "^3.1.0", - "pretty-format": "^26.2.0" + "pretty-format": "^26.4.0" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -8186,18 +8499,18 @@ "dev": true }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "pretty-format": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.2.0.tgz", - "integrity": "sha512-qi/8IuBu2clY9G7qCXgCdD1Bf9w+sXakdHTRToknzMtVy0g7c4MBWaZy7MfB7ndKZovRO6XRwJiAYqq+MC7SDA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.0.tgz", + "integrity": "sha512-mEEwwpCseqrUtuMbrJG4b824877pM5xald3AkilJ47Po2YLr97/siejYQHqj2oDQBeJNbu+Q0qUuekJ8F0NAPg==", "dev": true, "requires": { - "@jest/types": "^26.2.0", + "@jest/types": "^26.3.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -8206,33 +8519,42 @@ } }, "jest-watcher": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.2.0.tgz", - "integrity": "sha512-674Boco4Joe0CzgKPL6K4Z9LgyLx+ZvW2GilbpYb8rFEUkmDGgsZdv1Hv5rxsRpb1HLgKUOL/JfbttRCuFdZXQ==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.3.0.tgz", + "integrity": "sha512-XnLdKmyCGJ3VoF6G/p5ohbJ04q/vv5aH9ENI+i6BL0uu9WWB6Z7Z2lhQQk0d2AVZcRGp1yW+/TsoToMhBFPRdQ==", "dev": true, "requires": { - "@jest/test-result": "^26.2.0", - "@jest/types": "^26.2.0", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.2.0", + "jest-util": "^26.3.0", "string-length": "^4.0.1" }, "dependencies": { "@jest/types": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", - "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -8271,9 +8593,9 @@ } }, "jest-worker": { - "version": "26.2.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.2.1.tgz", - "integrity": "sha512-+XcGMMJDTeEGncRb5M5Zq9P7K4sQ1sirhjdOxsN1462h6lFo9w59bl2LVQmdGEEeU3m+maZCkS2Tcc9SfCHO4A==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.3.0.tgz", + "integrity": "sha512-Vmpn2F6IASefL+DVBhPzI2J9/GJUsqzomdeN+P+dK8/jKxbh8R3BtFnx3FIta7wYlPU62cpJMJQo4kuOowcMnw==", "dev": true, "requires": { "@types/node": "*", @@ -8319,9 +8641,9 @@ "dev": true }, "jsdom": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.3.0.tgz", - "integrity": "sha512-zggeX5UuEknpdZzv15+MS1dPYG0J/TftiiNunOeNxSl3qr8Z6cIlQpN0IdJa44z9aFxZRIVqRncvEhQ7X5DtZg==", + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", + "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", "dev": true, "requires": { "abab": "^2.0.3", @@ -8612,9 +8934,9 @@ "dev": true }, "knex": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.21.2.tgz", - "integrity": "sha512-hNp9f3yXCHtMrhV2pVsuCNYmPlgXhyqviMQGLBd9zdF03ZqCO9MPng0oYhNMgIs+vDr55VC6tjEbF1OQ1La7Kg==", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/knex/-/knex-0.21.4.tgz", + "integrity": "sha512-vUrR4mJBKWJPouV9C7kqvle9cTpiuuzBWqrQXP7bAv+Ua9oeKkEhhorJwArzcjVrVBojZYPMMtNVliW9B00sTA==", "requires": { "colorette": "1.2.1", "commander": "^5.1.0", @@ -9580,9 +9902,9 @@ } }, "npm-check-updates": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-7.0.3.tgz", - "integrity": "sha512-20R5Zp5H/3Uw3VAeYAwuEECtA4ML5QxaMVCsKviFZtN5p2ONDeXQT18+31vughQEDexDyNWRDU7JwwPeao2apA==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-7.1.0.tgz", + "integrity": "sha512-xxEObkGnT361LY57GY/+FQUgCARoAeRfIU5M2GxnESoZFMeDv1W7Ck01MBswyTEQgjD4A3HBolcBTYaJsSl03A==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -9592,6 +9914,7 @@ "find-up": "4.1.0", "get-stdin": "^8.0.0", "json-parse-helpfulerror": "^1.0.3", + "jsonlines": "^0.1.1", "libnpmconfig": "^1.2.1", "lodash": "^4.17.19", "p-map": "^4.0.0", @@ -11575,16 +11898,17 @@ } }, "sinon": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.2.tgz", - "integrity": "sha512-0uF8Q/QHkizNUmbK3LRFqx5cpTttEVXudywY9Uwzy8bTfZUhljZ7ARzSxnRHWYWtVTeh4Cw+tTb3iU21FQVO9A==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.3.tgz", + "integrity": "sha512-IKo9MIM111+smz9JGwLmw5U1075n1YXeAq8YeSFlndCLhAL5KGn6bLgu7b/4AYHTV/LcEMcRm2wU2YiL55/6Pg==", + "dev": true, "requires": { "@sinonjs/commons": "^1.7.2", "@sinonjs/fake-timers": "^6.0.1", "@sinonjs/formatio": "^5.0.1", - "@sinonjs/samsam": "^5.0.3", + "@sinonjs/samsam": "^5.1.0", "diff": "^4.0.2", - "nise": "^4.0.1", + "nise": "^4.0.4", "supports-color": "^7.1.0" } }, @@ -12923,9 +13247,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", - "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-5.0.1.tgz", + "integrity": "sha512-mbDNjuDajqYe3TXFk5qxcQy8L1msXNE37WTlLoqqpBfRsimbNcrlhQlDPntmECEcUvdC+AQ8CyMMf6EUx1r74Q==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", diff --git a/package.json b/package.json index 4174b4f4..175c0657 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "quoting-service", "description": "Quoting Service hosted by a scheme", "license": "Apache-2.0", - "version": "11.0.1", + "version": "12.0.0", "author": "ModusBox", "contributors": [ "James Bush ", @@ -59,20 +59,20 @@ }, "dependencies": { "@hapi/good": "9.0.0", - "@hapi/hapi": "19.2.0", + "@hapi/hapi": "20.0.0", "@mojaloop/central-services-error-handling": "10.6.0", "@mojaloop/central-services-logger": "10.6.0", - "@mojaloop/central-services-shared": "11.1.0", + "@mojaloop/central-services-shared": "11.1.2", "@mojaloop/event-sdk": "10.6.0", "@mojaloop/ml-number": "8.2.0", - "@mojaloop/sdk-standard-components": "10.3.2", + "@mojaloop/sdk-standard-components": "11.0.0", "axios": "0.19.2", "blipp": "4.0.1", "eslint-config-standard": "14.1.1", "good-console": "8.0.0", "good-squeeze": "5.1.0", "json-rules-engine": "5.0.2", - "knex": "0.21.2", + "knex": "0.21.4", "memory-cache": "0.2.0", "minimist": "1.2.5", "mysql": "2.18.1", @@ -83,14 +83,14 @@ "devDependencies": { "@types/jest": "26.0.9", "eslint": "7.6.0", - "jest": "26.2.2", + "jest": "26.4.0", "jest-junit": "11.1.0", "npm-audit-resolver": "2.2.1", - "npm-check-updates": "7.0.3", + "npm-check-updates": "7.1.0", "nyc": "15.1.0", "pre-commit": "1.2.2", "proxyquire": "2.1.3", - "sinon": "9.0.2", + "sinon": "9.0.3", "standard": "14.3.4", "swagmock": "1.0.0" }, diff --git a/src/data/database.js b/src/data/database.js index 1bb32b1b..9f3b3505 100644 --- a/src/data/database.js +++ b/src/data/database.js @@ -342,20 +342,30 @@ class Database { * * @returns {promise} - id of the participant */ - async getParticipant (participantName, participantType, currencyId, ledgerAccountTypeId = Enum.Accounts.LedgerAccountType.POSITION) { + async getParticipant (participantName, participantType, currencyId = null, ledgerAccountTypeId = Enum.Accounts.LedgerAccountType.POSITION) { try { - const rows = await this.queryBuilder('participant') - .innerJoin('participantCurrency', 'participantCurrency.participantId', 'participant.participantId') - .where({ 'participant.name': participantName }) - .andWhere({ 'participantCurrency.currencyId': currencyId }) - .andWhere({ 'participantCurrency.ledgerAccountTypeId': ledgerAccountTypeId }) - .andWhere({ 'participantCurrency.isActive': true }) - .andWhere({ 'participant.isActive': true }) - .select( - 'participant.*', - 'participantCurrency.participantCurrencyId', - 'participantCurrency.currencyId' - ) + let rows + if (currencyId != null) { + rows = await this.queryBuilder('participant') + .innerJoin('participantCurrency', 'participantCurrency.participantId', 'participant.participantId') + .where({ 'participant.name': participantName }) + .andWhere({ 'participantCurrency.currencyId': currencyId }) + .andWhere({ 'participantCurrency.ledgerAccountTypeId': ledgerAccountTypeId }) + .andWhere({ 'participantCurrency.isActive': true }) + .andWhere({ 'participant.isActive': true }) + .select( + 'participant.*', + 'participantCurrency.participantCurrencyId', + 'participantCurrency.currencyId' + ) + } else { + rows = await this.queryBuilder('participant') + .where({ + name: participantName, + isActive: 1 + }) + .select() + } if ((!rows) || rows.length < 1) { // active participant does not exist, this is an error if (participantType && participantType === LOCAL_ENUM.PAYEE_DFSP) { diff --git a/src/handlers/quotes.js b/src/handlers/quotes.js index 2244585c..11f62af4 100644 --- a/src/handlers/quotes.js +++ b/src/handlers/quotes.js @@ -78,14 +78,13 @@ module.exports = { // call the quote request handler in the model const result = await model.handleQuoteRequest(request.headers, request.payload, span) request.server.log(['info'], `POST quote request succeeded and returned: ${util.inspect(result)}`) + return h.response().code(Enum.Http.ReturnCodes.ACCEPTED.CODE) } catch (err) { // something went wrong, use the model to handle the error in a sensible way request.server.log(['error'], `ERROR - POST /quotes: ${LibUtil.getStackOrInspect(err)}`) const fspiopError = ErrorHandler.ReformatFSPIOPError(err) - await model.handleException(fspiopSource, quoteId, fspiopError, request.headers, span) - } finally { - // eslint-disable-next-line no-unsafe-finally - return h.response().code(Enum.Http.ReturnCodes.ACCEPTED.CODE) + const { body, code } = await model.handleException(fspiopSource, quoteId, fspiopError, request.headers, span) + return h.response(body).code(code) } } } diff --git a/src/handlers/quotes/{id}/error.js b/src/handlers/quotes/{id}/error.js index 0bdfe5a4..3b249d8f 100644 --- a/src/handlers/quotes/{id}/error.js +++ b/src/handlers/quotes/{id}/error.js @@ -76,13 +76,12 @@ module.exports = { // call the quote error handler in the model const result = await model.handleQuoteError(request.headers, quoteId, request.payload.errorInformation, span) request.server.log(['info'], `PUT quote error request succeeded and returned: ${util.inspect(result)}`) + return h.response().code(Enum.Http.ReturnCodes.OK.CODE) } catch (err) { // something went wrong, use the model to handle the error in a sensible way request.server.log(['error'], `ERROR - PUT /quotes/{id}/error: ${LibUtil.getStackOrInspect(err)}`) - await model.handleException(fspiopSource, quoteId, err, request.headers) - } finally { - // eslint-disable-next-line no-unsafe-finally - return h.response().code(Enum.Http.ReturnCodes.OK.CODE) + const { body, code } = await model.handleException(fspiopSource, quoteId, err, request.headers, span) + return h.response(body).code(code) } } } diff --git a/src/interface/swagger.json b/src/interface/swagger.json index cfc5bb99..7deecbdc 100644 --- a/src/interface/swagger.json +++ b/src/interface/swagger.json @@ -1882,7 +1882,7 @@ "$ref": "#/definitions/Extension" }, "minItems": 1, - "maxItems": 16, + "maxItems": 17, "description": "Number of Extension elements" } }, @@ -2201,15 +2201,21 @@ "properties": { "firstName": { "type": "string", - "description": "Party’s first name." + "pattern": "^(?!\\s*$)[\\w .,'-]{1,128}$", + "description": "Party’s first name.", + "minLength": 1 }, "middleName": { "type": "string", - "description": "Party’s middle name." + "pattern": "^(?!\\s*$)[\\w .,'-]{1,128}$", + "description": "Party’s middle name.", + "minLength": 1 }, "lastName": { "type": "string", - "description": "Party’s last name." + "pattern": "^(?!\\s*$)[\\w .,'-]{1,128}$", + "description": "Party’s last name.", + "minLength": 1 } } }, @@ -2268,7 +2274,7 @@ "description": "First, middle and last name for the Party." }, "dateOfBirth": { - "type": "string", + "$ref": "#/definitions/DateOfBirth", "description": "Date of birth for the Party." } } diff --git a/src/lib/config.js b/src/lib/config.js index 71c0f42b..1ce66e9b 100644 --- a/src/lib/config.js +++ b/src/lib/config.js @@ -49,7 +49,7 @@ class Config { this.listenAddress = RC.LISTEN_ADDRESS this.listenPort = RC.PORT this.simpleRoutingMode = RC.SIMPLE_ROUTING_MODE - this.switchEndpoint = RC.SWITCH_ENDPOINT + this.centralLedgerAdminServiceEndpoint = RC.SWITCH_ENDPOINT this.amount = { precision: RC.AMOUNT.PRECISION ? RC.AMOUNT.PRECISION : 18, scale: RC.AMOUNT.SCALE ? RC.AMOUNT.SCALE : 4 diff --git a/src/model/quotes.js b/src/model/quotes.js index 99f323bb..3ea2f19c 100644 --- a/src/model/quotes.js +++ b/src/model/quotes.js @@ -30,12 +30,15 @@ - Henk Kodde - Matt Kingston - Vassilis Barzokas + - Shashikant Hirugade -------------- ******/ const axios = require('axios') +const crypto = require('crypto') const util = require('util') +const { MojaloopApiErrorCodes } = require('@mojaloop/sdk-standard-components').Errors const ENUM = require('@mojaloop/central-services-shared').Enum const ErrorHandler = require('@mojaloop/central-services-error-handling') const EventSdk = require('@mojaloop/event-sdk') @@ -73,8 +76,8 @@ class QuotesModel { // Collect facts to supply to the rule engine // Get quote participants from central ledger admin - const { switchEndpoint } = new Config() - const url = `${switchEndpoint}/participants` + const { centralLedgerAdminServiceEndpoint } = new Config() + const url = `${centralLedgerAdminServiceEndpoint}/participants` const [payer, payee] = await Promise.all([ axios.request({ url: `${url}/${headers['fspiop-source']}` }), axios.request({ url: `${url}/${headers['fspiop-destination']}` }) @@ -82,16 +85,40 @@ class QuotesModel { this.writeLog(`Got rules engine facts payer ${payer} and payee ${payee}`) + if (payer.data.isActive === 0) { + throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PAYER_FSP_ID_NOT_FOUND, + `Payer FSP ID not found - Unsupported participant '${headers['fspiop-source']}'`, null, headers['fspiop-source']) + } + if (payee.data.isActive === 0) { + throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR, + `Destination FSP Error - '${headers['fspiop-destination']}' is inactive`, null, headers['fspiop-source']) + } + + const payerAccounts = Array.isArray(payer.data.accounts) ? payer.data.accounts : [] + const payeeAccounts = Array.isArray(payee.data.accounts) ? payee.data.accounts : [] + + const activePayerAccounts = payerAccounts.filter(account => account.isActive === 1 && account.ledgerAccountType === 'POSITION') + const activePayeeAccounts = payeeAccounts.filter(account => account.isActive === 1 && account.ledgerAccountType === 'POSITION') + + if (activePayerAccounts.length === 0) { + throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PAYER_ERROR, + 'Payer does not have any active account', null, headers['fspiop-source']) + } + if (activePayeeAccounts.length === 0) { + throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PAYEE_ERROR, + 'Payee does not have any active account', null, headers['fspiop-source']) + } + const facts = { - payer, - payee, + payer: payer.data, + payee: payee.data, payload: quoteRequest, headers } const { events } = await RulesEngine.run(rules, facts) - this.writeLog(`Rules engine returned events ${events}`) + this.writeLog(`Rules engine returned events ${JSON.stringify(events)}`) return events } @@ -136,7 +163,9 @@ class QuotesModel { quoteRequest, headers: { ...headers, - 'fspiop-destination': interceptQuoteEvents[0].params.rerouteToFsp + 'fspiop-destination': interceptQuoteEvents[0].params.rerouteToFsp, + 'fspiop-destinationcurrency': interceptQuoteEvents[0].params.rerouteToFspCurrency, + 'fspiop-sourcecurrency': interceptQuoteEvents[0].params.sourceCurrency } } } @@ -148,6 +177,7 @@ class QuotesModel { * @returns {promise} - promise will reject if request is not valid */ async validateQuoteRequest (fspiopSource, fspiopDestination, quoteRequest) { + const envConfig = new Config() // note that the framework should validate the form of the request // here we can do some hard-coded rule validations to ensure requests // do not lead to unsupported scenarios or use-cases. @@ -162,9 +192,13 @@ class QuotesModel { // internal-error throw ErrorHandler.CreateInternalServerFSPIOPError('Missing quoteRequest', null, fspiopSource) } - - await this.db.getParticipant(fspiopSource, LOCAL_ENUM.PAYER_DFSP, quoteRequest.amount.currency, ENUM.Accounts.LedgerAccountType.POSITION) - await this.db.getParticipant(fspiopDestination, LOCAL_ENUM.PAYEE_DFSP, quoteRequest.amount.currency, ENUM.Accounts.LedgerAccountType.POSITION) + if (!envConfig.simpleRoutingMode) { + await this.db.getParticipant(fspiopSource, LOCAL_ENUM.PAYER_DFSP, quoteRequest.amount.currency, ENUM.Accounts.LedgerAccountType.POSITION) + await this.db.getParticipant(fspiopDestination, LOCAL_ENUM.PAYEE_DFSP, quoteRequest.amount.currency, ENUM.Accounts.LedgerAccountType.POSITION) + } else { + await this.db.getParticipant(fspiopSource, LOCAL_ENUM.PAYER_DFSP) + await this.db.getParticipant(fspiopDestination, LOCAL_ENUM.PAYEE_DFSP) + } } /** @@ -240,8 +274,10 @@ class QuotesModel { await this.db.createQuoteDuplicateCheck(txn, quoteRequest.quoteId, hash) // create a txn reference + this.writeLog(`Creating transactionReference for quoteId: ${quoteRequest.quoteId} and transactionId: ${quoteRequest.transactionId}`) refs.transactionReferenceId = await this.db.createTransactionReference(txn, quoteRequest.quoteId, quoteRequest.transactionId) + this.writeLog(`transactionReference created transactionReferenceId: ${refs.transactionReferenceId}`) // get the initiator type refs.transactionInitiatorTypeId = await this.db.getInitiatorType(quoteRequest.transactionType.initiatorType) @@ -363,7 +399,7 @@ class QuotesModel { let endpoint const fspiopSource = headers[ENUM.Http.Headers.FSPIOP.SOURCE] const fspiopDest = headers[ENUM.Http.Headers.FSPIOP.DESTINATION] - const envConfig = new Config() + // const envConfig = new Config() try { if (!originalQuoteRequest) { @@ -374,13 +410,14 @@ class QuotesModel { // lookup payee dfsp callback endpoint // TODO: for MVP we assume initiator is always payer dfsp! this may not always be the // case if a xfer is requested by payee - if (envConfig.simpleRoutingMode) { - endpoint = await this.db.getParticipantEndpoint(fspiopDest, 'FSPIOP_CALLBACK_URL_QUOTES') - } else { - endpoint = await this.db.getQuotePartyEndpoint(quoteId, 'FSPIOP_CALLBACK_URL_QUOTES', 'PAYEE') - } + // if (envConfig.simpleRoutingMode) { + // endpoint = await this.db.getParticipantEndpoint(fspiopDest, 'FSPIOP_CALLBACK_URL_QUOTES') + // } else { + // endpoint = await this.db.getQuotePartyEndpoint(quoteId, 'FSPIOP_CALLBACK_URL_QUOTES', 'PAYEE') + // } + endpoint = await this.db.getParticipantEndpoint(fspiopDest, 'FSPIOP_CALLBACK_URL_QUOTES') - this.writeLog(`Resolved PAYEE party FSPIOP_CALLBACK_URL_QUOTES endpoint for quote ${quoteId} to: ${util.inspect(endpoint)}`) + this.writeLog(`Resolved PAYEE party FSPIOP_CALLBACK_URL_QUOTES endpoint for quote ${quoteId} to: ${endpoint}, destination: ${fspiopDest}`) if (!endpoint) { // internal-error @@ -600,7 +637,7 @@ class QuotesModel { */ async forwardQuoteUpdate (headers, quoteId, originalQuoteResponse, span) { let endpoint = null - const envConfig = new Config() + // const envConfig = new Config() const fspiopSource = headers[ENUM.Http.Headers.FSPIOP.SOURCE] const fspiopDest = headers[ENUM.Http.Headers.FSPIOP.DESTINATION] @@ -612,12 +649,13 @@ class QuotesModel { } // lookup payer dfsp callback endpoint - if (envConfig.simpleRoutingMode) { - endpoint = await this.db.getParticipantEndpoint(fspiopDest, 'FSPIOP_CALLBACK_URL_QUOTES') - } else { - // todo: for MVP we assume initiator is always payer dfsp! this may not always be the case if a xfer is requested by payee - endpoint = await this.db.getQuotePartyEndpoint(quoteId, 'FSPIOP_CALLBACK_URL_QUOTES', 'PAYER') - } + // if (envConfig.simpleRoutingMode) { + // endpoint = await this.db.getParticipantEndpoint(fspiopDest, 'FSPIOP_CALLBACK_URL_QUOTES') + // } else { + // // todo: for MVP we assume initiator is always payer dfsp! this may not always be the case if a xfer is requested by payee + // endpoint = await this.db.getQuotePartyEndpoint(quoteId, 'FSPIOP_CALLBACK_URL_QUOTES', 'PAYER') + // } + endpoint = await this.db.getParticipantEndpoint(fspiopDest, 'FSPIOP_CALLBACK_URL_QUOTES') this.writeLog(`Resolved PAYER party FSPIOP_CALLBACK_URL_QUOTES endpoint for quote ${quoteId} to: ${util.inspect(endpoint)}`) @@ -632,7 +670,7 @@ class QuotesModel { // we need to strip off the 'accept' header // for all PUT requests as per the API Specification Document // https://github.com/mojaloop/mojaloop-specification/blob/master/API%20Definition%20v1.0.pdf - const newHeaders = generateRequestHeaders(headers, true) + const newHeaders = this.generateRequestHeaders(headers, true) this.writeLog(`Forwarding quote response to endpoint: ${fullCallbackUrl}`) this.writeLog(`Forwarding quote response headers: ${JSON.stringify(newHeaders)}`) @@ -840,7 +878,25 @@ class QuotesModel { const childSpan = span.getChild('qs_quote_sendErrorCallback') try { await childSpan.audit({ headers, params: { quoteId } }, EventSdk.AuditEventAction.start) - return await this.sendErrorCallback(fspiopSource, fspiopError, quoteId, headers, childSpan, true) + const syncErrorCodes = [ + MojaloopApiErrorCodes.MISSING_ELEMENT.code, + MojaloopApiErrorCodes.VALIDATION_ERROR.code, + MojaloopApiErrorCodes.MALFORMED_SYNTAX.code + ] + if (error.name === 'FSPIOPError' && syncErrorCodes.includes(error.apiErrorCode.code)) { + // We should respond synchronously + const envConfig = new Config() + return { + body: error.toApiErrorObject(envConfig.errorHandling), + code: ENUM.Http.ReturnCodes.BADREQUEST.CODE + } + } else { + // We should respond asynchronously + await this.sendErrorCallback(fspiopSource, fspiopError, quoteId, headers, childSpan, true) + return { + code: ENUM.Http.ReturnCodes.ACCEPTED.CODE + } + } } catch (err) { // any-error // not much we can do other than log the error @@ -1063,6 +1119,93 @@ class QuotesModel { } } + /** + * Utility function to remove null and undefined keys from an object. + * This is useful for removing "nulls" that come back from database queries + * when projecting into API spec objects + * + * @returns {object} + */ + removeEmptyKeys (originalObject) { + const obj = { ...originalObject } + Object.keys(obj).forEach(key => { + if (obj[key] && typeof obj[key] === 'object') { + if (Object.keys(obj[key]).length < 1) { + // remove empty object + delete obj[key] + } else { + // recurse + obj[key] = this.removeEmptyKeys(obj[key]) + } + } else if (obj[key] == null) { + // null or undefined, remove it + delete obj[key] + } + }) + return obj + } + + /** + * Returns the SHA-256 hash of the supplied request object + * + * @returns {undefined} + */ + calculateRequestHash (request) { + // calculate a SHA-256 of the request + const requestStr = JSON.stringify(request) + return crypto.createHash('sha256').update(requestStr).digest('hex') + } + + /** + * Generates and returns an object containing API spec compliant HTTP request headers + * + * @returns {object} + */ + generateRequestHeaders (headers, noAccept) { + const ret = { + 'Content-Type': 'application/vnd.interoperability.quotes+json;version=1.0', + Date: headers.date, + 'FSPIOP-Source': headers['fspiop-source'], + 'FSPIOP-SourceCurrency': headers['fspiop-sourcecurrency'], + 'FSPIOP-Destination': headers['fspiop-destination'], + 'FSPIOP-DestinationCurrency': headers['fspiop-destinationcurrency'], + 'FSPIOP-HTTP-Method': headers['fspiop-http-method'], + 'FSPIOP-Signature': headers['fspiop-signature'], + 'FSPIOP-URI': headers['fspiop-uri'], + Accept: null + } + + if (!noAccept) { + ret.Accept = 'application/vnd.interoperability.quotes+json;version=1' + } + + return this.removeEmptyKeys(ret) + } + + /** + * Generates and returns an object containing API spec compliant lowercase HTTP request headers for JWS Signing + * + * @returns {object} + */ + generateRequestHeadersForJWS (headers, noAccept) { + const ret = { + 'Content-Type': 'application/vnd.interoperability.quotes+json;version=1.0', + date: headers.date, + 'fspiop-source': headers['fspiop-source'], + 'fspiop-destination': headers['fspiop-destination'], + 'fspiop-http-method': headers['fspiop-http-method'], + 'fspiop-signature': headers['fspiop-signature'], + 'fspiop-uri': headers['fspiop-uri'], + Accept: null + } + + if (!noAccept) { + ret.Accept = 'application/vnd.interoperability.quotes+json;version=1' + } + + return this.removeEmptyKeys(ret) + } + /** * Writes a formatted message to the console * diff --git a/src/model/rules.js b/src/model/rules.js index aac84e23..c8d0a430 100644 --- a/src/model/rules.js +++ b/src/model/rules.js @@ -65,6 +65,15 @@ const createEngine = () => { engine.addOperator('deepEqual', (factValue, ruleValue) => { return deepEqual(factValue, ruleValue) }) + engine.addOperator('isString', (factValue, ruleValue) => { + return ((typeof factValue === 'string') === ruleValue) + }) + engine.addOperator('isArray', (factValue, ruleValue) => { + return Array.isArray(factValue) === ruleValue + }) + engine.addOperator('isObject', (factValue, ruleValue) => { + return (typeof factValue === 'object' && !Array.isArray(factValue)) === ruleValue + }) return engine } diff --git a/test/unit/handlers/quotes.test.js b/test/unit/handlers/quotes.test.js index 231cfd3c..320d2468 100644 --- a/test/unit/handlers/quotes.test.js +++ b/test/unit/handlers/quotes.test.js @@ -75,7 +75,7 @@ describe('/quotes', () => { it('fails to create a quote', async () => { // Arrange - const handleException = jest.fn() + const handleException = jest.fn(() => ({ code: Enum.Http.ReturnCodes.ACCEPTED.CODE })) QuotesModel.mockImplementationOnce(() => ({ handleQuoteRequest: () => { throw new Error('Create Quote Test Error') diff --git a/test/unit/handlers/quotes/{id}.test.js b/test/unit/handlers/quotes/{id}.test.js index 274a37a2..027c6d5d 100644 --- a/test/unit/handlers/quotes/{id}.test.js +++ b/test/unit/handlers/quotes/{id}.test.js @@ -66,7 +66,7 @@ describe('/quotes/{id}', () => { it('handles an error with the model', async () => { // Arrange - const handleException = jest.fn() + const handleException = jest.fn(() => ({ code: 202 })) QuotesModel.mockImplementationOnce(() => { return { handleQuoteGet: () => { @@ -116,7 +116,7 @@ describe('/quotes/{id}', () => { it('handles an error with the model', async () => { // Arrange - const handleException = jest.fn() + const handleException = jest.fn(() => ({ code: 202 })) QuotesModel.mockImplementationOnce(() => { return { handleQuoteUpdate: () => { diff --git a/test/unit/handlers/quotes/{id}/error.test.js b/test/unit/handlers/quotes/{id}/error.test.js index 76f39734..8ea2a50c 100644 --- a/test/unit/handlers/quotes/{id}/error.test.js +++ b/test/unit/handlers/quotes/{id}/error.test.js @@ -85,7 +85,7 @@ describe('/quotes/{id}', () => { } } } - const handleException = jest.fn() + const handleException = jest.fn(() => ({ code: Enum.Http.ReturnCodes.OK.CODE })) QuotesModel.mockImplementationOnce(() => { return { handleQuoteError: () => { diff --git a/test/unit/model/quotes.test.js b/test/unit/model/quotes.test.js index 6d8911a6..82d7a73b 100644 --- a/test/unit/model/quotes.test.js +++ b/test/unit/model/quotes.test.js @@ -247,7 +247,7 @@ describe('QuotesModel', () => { fact: 'json-path', params: { fact: 'payee', - path: '$.payee.accounts[?(@.ledgerAccountType == "SETTLEMENT")].currency' + path: '$.payee.accounts[?(@.ledgerAccountType == "POSITION" && @.isActive == 1)].currency' } } } @@ -256,7 +256,9 @@ describe('QuotesModel', () => { event: { type: 'INTERCEPT_QUOTE', params: { - rerouteToFsp: 'DFSPEUR' + rerouteToFsp: 'DFSPEUR', + sourceCurrency: 'EUR', + rerouteToFspCurrency: 'XOF' } } }, @@ -280,7 +282,7 @@ describe('QuotesModel', () => { fact: 'json-path', params: { fact: 'payee', - path: '$.payee.accounts[?(@.ledgerAccountType == "SETTLEMENT")].currency' + path: '$.payee.accounts[?(@.ledgerAccountType == "POSITION" && @.isActive == 1)].currency' } } } @@ -411,6 +413,9 @@ describe('QuotesModel', () => { }) it('throws an unhandled exception if `RulesEngine.run` throws an exception', async () => { + axios.request + .mockImplementationOnce(() => { return { data: { accounts: [{ accountId: 1, ledgerAccountType: 'POSITION', isActive: 1 }] } } }) + .mockImplementationOnce(() => { return { data: { accounts: [{ accountId: 2, ledgerAccountType: 'POSITION', isActive: 1 }] } } }) RulesEngine.run.mockImplementation(() => { throw new Error('foo') }) await expect(quotesModel.executeRules(mockData.headers, mockData.quoteRequest)) @@ -445,7 +450,9 @@ describe('QuotesModel', () => { describe('In case a non empty set of rules is loaded', () => { it('returns the result of `RulesEngine.run`', async () => { const expectedEvents = [] - + axios.request + .mockImplementationOnce(() => { return { data: { accounts: [{ accountId: 1, ledgerAccountType: 'POSITION', isActive: 1 }] } } }) + .mockImplementationOnce(() => { return { data: { accounts: [{ accountId: 2, ledgerAccountType: 'POSITION', isActive: 1 }] } } }) expect(rules.length).not.toBe(0) rules.forEach((rule) => { @@ -586,7 +593,9 @@ describe('QuotesModel', () => { quoteRequest: mockData.quoteRequest, headers: { ...mockData.headers, - 'fspiop-destination': mockEvents[0].params.rerouteToFsp + 'fspiop-destination': mockEvents[0].params.rerouteToFsp, + 'fspiop-destinationcurrency': mockEvents[0].params.rerouteToFspCurrency, + 'fspiop-sourcecurrency': mockEvents[0].params.sourceCurrency } }) }) @@ -1194,25 +1203,25 @@ describe('QuotesModel', () => { }) it('should get http status code 202 Accepted in simple routing mode', async () => { - expect.assertions(2) + expect.assertions(1) mockConfig.simpleRoutingMode = true quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) await quotesModel.forwardQuoteRequest(mockData.headers, mockData.quoteRequest.quoteId, mockData.quoteRequest, mockChildSpan) expect(quotesModel.db.getParticipantEndpoint).toBeCalled() - expect(quotesModel.db.getQuotePartyEndpoint).not.toBeCalled() + // expect(quotesModel.db.getQuotePartyEndpoint).not.toBeCalled() }) it('should get http status code 202 Accepted in switch mode', async () => { - expect.assertions(2) + expect.assertions(1) mockConfig.simpleRoutingMode = false - quotesModel.db.getQuotePartyEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) + quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) await quotesModel.forwardQuoteRequest(mockData.headers, mockData.quoteRequest.quoteId, mockData.quoteRequest, mockChildSpan) - expect(quotesModel.db.getParticipantEndpoint).not.toBeCalled() - expect(quotesModel.db.getQuotePartyEndpoint).toBeCalled() + expect(quotesModel.db.getParticipantEndpoint).toBeCalled() + // expect(quotesModel.db.getQuotePartyEndpoint).toBeCalled() }) it('should throw when quoteRequest is undefined', async () => { expect.assertions(1) @@ -1235,7 +1244,7 @@ describe('QuotesModel', () => { it('should not use spans when undefined and should throw when participant endpoint is invalid', async () => { expect.assertions(3) mockConfig.simpleRoutingMode = false - quotesModel.db.getQuotePartyEndpoint.mockReturnValueOnce(mockData.endpoints.invalid) + quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.invalid) Http.httpRequest.mockImplementationOnce(() => { throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_COMMUNICATION_ERROR) }) await expect(quotesModel.forwardQuoteRequest(mockData.headers, mockData.quoteRequest.quoteId, mockData.quoteRequest)) @@ -1248,7 +1257,7 @@ describe('QuotesModel', () => { it('should throw when participant endpoint returns invalid response', async () => { expect.assertions(3) mockConfig.simpleRoutingMode = false - quotesModel.db.getQuotePartyEndpoint.mockReturnValueOnce(mockData.endpoints.invalidResponse) + quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.invalidResponse) Http.httpRequest.mockImplementationOnce(() => { throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_COMMUNICATION_ERROR) }) await expect(quotesModel.forwardQuoteRequest(mockData.headers, mockData.quoteRequest.quoteId, mockData.quoteRequest)) @@ -1264,7 +1273,7 @@ describe('QuotesModel', () => { mockConfig.simpleRoutingMode = false const customErrorNoStack = new Error('Custom error') delete customErrorNoStack.stack - quotesModel.db.getQuotePartyEndpoint.mockRejectedValueOnce(customErrorNoStack) + quotesModel.db.getParticipantEndpoint.mockRejectedValueOnce(customErrorNoStack) await expect(quotesModel.forwardQuoteRequest(mockData.headers, mockData.quoteRequest.quoteId, mockData.quoteRequest)) .rejects @@ -1604,14 +1613,14 @@ describe('QuotesModel', () => { expect.assertions(3) mockConfig.simpleRoutingMode = false - quotesModel.db.getQuotePartyEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) + quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) await expect(quotesModel.forwardQuoteUpdate(mockData.headers, mockData.quoteId, mockData.quoteUpdate, mockChildSpan)) .resolves .toBe(undefined) - expect(quotesModel.db.getParticipantEndpoint).not.toBeCalled() - expect(quotesModel.db.getQuotePartyEndpoint).toBeCalled() + expect(quotesModel.db.getParticipantEndpoint).toBeCalled() + expect(quotesModel.db.getQuotePartyEndpoint).not.toBeCalled() }) it('should throw when quoteUpdate is undefined', async () => { expect.assertions(1) @@ -1636,7 +1645,7 @@ describe('QuotesModel', () => { expect.assertions(3) mockConfig.simpleRoutingMode = false - quotesModel.db.getQuotePartyEndpoint.mockReturnValueOnce(mockData.endpoints.invalid) + quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.invalid) Http.httpRequest.mockImplementationOnce(() => { throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_COMMUNICATION_ERROR) }) await expect(quotesModel.forwardQuoteUpdate(mockData.headers, mockData.quoteId, mockData.quoteUpdate)) @@ -1650,7 +1659,7 @@ describe('QuotesModel', () => { expect.assertions(3) mockConfig.simpleRoutingMode = false - quotesModel.db.getQuotePartyEndpoint.mockReturnValueOnce(mockData.endpoints.invalidResponse) + quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.invalidResponse) Http.httpRequest.mockImplementationOnce(() => { throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_COMMUNICATION_ERROR) }) await expect(quotesModel.forwardQuoteUpdate(mockData.headers, mockData.quoteId, mockData.quoteUpdate)) @@ -1666,7 +1675,7 @@ describe('QuotesModel', () => { mockConfig.simpleRoutingMode = false const customErrorNoStack = new Error('Custom error') delete customErrorNoStack.stack - quotesModel.db.getQuotePartyEndpoint.mockRejectedValueOnce(customErrorNoStack) + quotesModel.db.getParticipantEndpoint.mockRejectedValueOnce(customErrorNoStack) await expect(quotesModel.forwardQuoteUpdate(mockData.headers, mockData.quoteId, mockData.quoteUpdate)) .rejects @@ -1980,7 +1989,7 @@ describe('QuotesModel', () => { // Assert expect(quotesModel.sendErrorCallback).toHaveBeenCalledWith('payeefsp', expectedError, mockData.quoteId, mockData.headers, mockChildSpan, true) - expect(result).toBe(true) + expect(result).toStrictEqual({ code: 202 }) expect(mockChildSpan.finish).toHaveBeenCalledTimes(1) }) diff --git a/test/unit/rules/fx.test.js b/test/unit/rules/fx.test.js index 8651d3dc..9f4cb5e6 100644 --- a/test/unit/rules/fx.test.js +++ b/test/unit/rules/fx.test.js @@ -52,7 +52,7 @@ const fxRules = { operator: 'notIn', value: { fact: 'payee', - path: '$.accounts[?(@.ledgerAccountType == \'SETTLEMENT\')].currency' + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)].currency' } }, { @@ -91,7 +91,7 @@ const fxRules = { operator: 'notIn', value: { fact: 'payer', - path: '$.accounts[?(@.ledgerAccountType == \'SETTLEMENT\')].currency' + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)].currency' } }, { @@ -130,7 +130,7 @@ const fxRules = { operator: 'notIn', value: { fact: 'payee', - path: '$.accounts[?(@.ledgerAccountType == \'SETTLEMENT\')].currency' + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)].currency' } }, { @@ -169,7 +169,7 @@ const fxRules = { operator: 'notIn', value: { fact: 'payer', - path: '$.accounts[?(@.ledgerAccountType == \'SETTLEMENT\')].currency' + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)].currency' } }, { @@ -204,7 +204,7 @@ const fxRules = { operator: 'notIn', value: { fact: 'payer', - path: '$.accounts[?(@.ledgerAccountType == \'SETTLEMENT\')].currency' + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)].currency' } } ] @@ -232,7 +232,7 @@ const fxRules = { operator: 'notIn', value: { fact: 'payee', - path: '$.accounts[?(@.ledgerAccountType == \'SETTLEMENT\')].currency' + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)].currency' } } ] @@ -276,6 +276,129 @@ const fxRules = { message: 'The payer FSP does not match the fspiop-source header' } } + }, + firstNameMissing: { // First Name is missing from the quote request + conditions: { + all: [ + { + any: [ + { + fact: 'payload', + path: '$.amount.currency', + operator: 'notIn', + value: { + fact: 'payee', + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)].currency' + } + }, + { + fact: 'payload', + path: '$.amount.currency', + operator: 'notIn', + value: { + fact: 'payer', + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)].currency' + } + } + ] + }, + { + fact: 'payload', + path: '$.payer.personalInfo.complexName.firstName', + operator: 'isString', + value: false + } + ] + }, + event: { + type: 'INVALID_QUOTE_REQUEST', + params: { + FSPIOPError: 'MISSING_ELEMENT', + message: 'child \'Party\' fails because [child \'PartyPersonalInfo\' fails because [child \'PartyComplexName\' fails because [child \'firstName\' fails because [\'firstName\' is required]]]]' + } + } + }, + payerHasMoreThanOneCurrency: { // Payer has more than one currency + conditions: { + all: [ + { + any: [ + { + fact: 'payload', + path: '$.amount.currency', + operator: 'notIn', + value: { + fact: 'payer', + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)].currency' + } + }, + { + fact: 'payload', + path: '$.amount.currency', + operator: 'notIn', + value: { + fact: 'payee', + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)].currency' + } + } + ] + }, + { + fact: 'payer', + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)]', + operator: 'isArray', + value: true + } + ] + }, + event: { + type: 'INVALID_QUOTE_REQUEST', + params: { + FSPIOPError: 'PAYER_ERROR', + message: 'Payer FSP has more than 1 active currency account. Switch does not support more than 1 active currency account for Forex Requests' + } + } + }, + payeeHasMoreThanOneCurrency: { // Payee has more than one currency + conditions: { + all: [ + { + any: [ + { + fact: 'payload', + path: '$.amount.currency', + operator: 'notIn', + value: { + fact: 'payer', + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)].currency' + } + }, + { + fact: 'payload', + path: '$.amount.currency', + operator: 'notIn', + value: { + fact: 'payee', + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)].currency' + } + } + ] + }, + { + fact: 'payee', + path: '$.accounts[?(@.ledgerAccountType == \'POSITION\' && @.isActive == 1)]', + operator: 'isArray', + value: true + } + ] + }, + event: { + type: 'INVALID_QUOTE_REQUEST', + params: { + FSPIOPError: 'PAYEE_ERROR', + message: 'Payee FSP has more than 1 active currency account. Switch does not support more than 1 active currency account for Forex Requests' + } + } } } @@ -298,7 +421,7 @@ describe('Forex rules', () => { }, payee: { accounts: [ - { ledgerAccountType: 'SETTLEMENT', currency: 'XYZ' } + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'XYZ' } ] } } @@ -324,7 +447,7 @@ describe('Forex rules', () => { }, payer: { accounts: [ - { ledgerAccountType: 'SETTLEMENT', currency: 'xyz' } + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'xyz' } ] } } @@ -350,7 +473,7 @@ describe('Forex rules', () => { }, payee: { accounts: [ - { ledgerAccountType: 'SETTLEMENT', currency: 'EUR' } + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'EUR' } ] } } @@ -376,7 +499,7 @@ describe('Forex rules', () => { }, payer: { accounts: [ - { ledgerAccountType: 'SETTLEMENT', currency: 'xyz' } + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'xyz' } ] } } @@ -385,7 +508,7 @@ describe('Forex rules', () => { }) }) describe('payerUnsupportedCurrency', () => { - it('raises INTERCEPT_QUOTE', async () => { + it('raises INVALID_QUOTE_REQUEST', async () => { const testFacts = { payload: { payer: { @@ -403,7 +526,7 @@ describe('Forex rules', () => { }, payer: { accounts: [ - { ledgerAccountType: 'SETTLEMENT', currency: 'xyz' } + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'xyz' } ] } } @@ -412,7 +535,7 @@ describe('Forex rules', () => { }) }) describe('payeeUnsupportedCurrency', () => { - it('raises INTERCEPT_QUOTE', async () => { + it('raises INVALID_QUOTE_REQUEST', async () => { const testFacts = { payload: { payer: { @@ -430,7 +553,7 @@ describe('Forex rules', () => { }, payee: { accounts: [ - { ledgerAccountType: 'SETTLEMENT', currency: 'xyz' } + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'xyz' } ] } } @@ -439,7 +562,7 @@ describe('Forex rules', () => { }) }) describe('FSPIOPSourceDoesNotMatchPayer', () => { - it('raises INTERCEPT_QUOTE', async () => { + it('raises INVALID_QUOTE_REQUEST', async () => { const testFacts = { payload: { payer: { @@ -457,7 +580,7 @@ describe('Forex rules', () => { }, payee: { accounts: [ - { ledgerAccountType: 'SETTLEMENT', currency: 'xyz' } + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'xyz' } ] } } @@ -465,4 +588,111 @@ describe('Forex rules', () => { expect(events).toEqual([fxRules.FSPIOPSourceDoesNotMatchPayer.event]) }) }) + describe('firstNameMissing', () => { + it('raises INVALID_QUOTE_REQUEST', async () => { + const testFacts = { + payload: { + payer: { + partyIdInfo: { + fspId: 'payerfsp' + } + }, + personalInfo: { + complexName: { + lastName: 'Hagman' + }, + dateOfBirth: '1983-10-25' + }, + amountType: 'RECEIVE', + amount: { + currency: 'XOF' + } + }, + headers: { + 'fspiop-source': 'payerfsp' + }, + payer: { + accounts: [ + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'EUR' } + ] + }, + payee: { + accounts: [ + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'XOF' } + ] + } + + } + const { events } = await RulesEngine.run([fxRules.firstNameMissing], testFacts) + expect(events).toEqual([fxRules.firstNameMissing.event]) + }) + }) + describe('payerHasMoreThanOneCurrency', () => { + it('raises INVALID_QUOTE_REQUEST', async () => { + const testFacts = { + payload: { + payer: { + partyIdInfo: { + fspId: 'payerfsp' + } + }, + amountType: 'RECEIVE', + amount: { + currency: 'XOF' + } + }, + headers: { + 'fspiop-source': 'payerfsp' + }, + payer: { + accounts: [ + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'EUR' }, + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'USD' } + ] + }, + payee: { + accounts: [ + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'XOF' } + ] + } + + } + const { events } = await RulesEngine.run([fxRules.payerHasMoreThanOneCurrency], testFacts) + expect(events).toEqual([fxRules.payerHasMoreThanOneCurrency.event]) + }) + }) + describe('payeeHasMoreThanOneCurrency', () => { + it('raises INVALID_QUOTE_REQUEST', async () => { + const testFacts = { + payload: { + payer: { + partyIdInfo: { + fspId: 'payerfsp' + } + }, + amountType: 'RECEIVE', + amount: { + currency: 'XOF' + } + }, + headers: { + 'fspiop-source': 'payerfsp' + }, + payer: { + accounts: [ + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'EUR' } + ] + }, + payee: { + accounts: [ + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'XOF' }, + { isActive: 1, ledgerAccountType: 'POSITION', currency: 'USD' } + ] + } + + } + const { events } = await RulesEngine.run([fxRules.payeeHasMoreThanOneCurrency], testFacts) + expect(events).toEqual([fxRules.payeeHasMoreThanOneCurrency.event]) + }) + }) })