diff --git a/.ncurc.json b/.ncurc.json index 5031238e..080f3aa7 100644 --- a/.ncurc.json +++ b/.ncurc.json @@ -1,5 +1,6 @@ { "reject": [ - "json-rules-engine" + "json-rules-engine", + "@mojaloop/sdk-standard-components" ] } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index db1cf74d..bcba2c20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "quoting-service", - "version": "10.5.5", + "version": "10.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -36,49 +36,31 @@ "call-me-maybe": "^1.0.1", "openapi-types": "^1.3.5", "z-schema": "^4.2.2" - }, - "dependencies": { - "validator": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-12.2.0.tgz", - "integrity": "sha512-jJfE/DW6tIK1Ek8nCfNFqt8Wb3nzMoAbocBF6/Icgg1ZFSBpObdnwVY2jQj6qUqzhx5jc71fpvBWyLGO7Xl+nQ==" - }, - "z-schema": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-4.2.3.tgz", - "integrity": "sha512-zkvK/9TC6p38IwcrbnT3ul9in1UX4cm1y/VZSs4GHKIiDCrlafc+YQBgQBUdDXLAoZHf2qvQ7gJJOo6yT1LH6A==", - "requires": { - "commander": "^2.7.1", - "lodash.get": "^4.4.2", - "lodash.isequal": "^4.5.0", - "validator": "^12.0.0" - } - } } }, "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "dev": true, "requires": { - "@babel/highlight": "^7.8.3" + "@babel/highlight": "^7.10.4" } }, "@babel/core": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.0", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helpers": "^7.9.0", - "@babel/parser": "^7.9.0", - "@babel/template": "^7.8.6", - "@babel/traverse": "^7.9.0", - "@babel/types": "^7.9.0", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.4.tgz", + "integrity": "sha512-3A0tS0HWpy4XujGc7QtOIHTeNwUgWaZc/WuS5YQrfhU67jnVmsD6OGPc1AKHH0LJHQICGncy3+YUjIhVlfDdcA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.4", + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -101,96 +83,77 @@ } }, "@babel/generator": { - "version": "7.9.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.4.tgz", - "integrity": "sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", + "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", "dev": true, "requires": { - "@babel/types": "^7.9.0", + "@babel/types": "^7.10.4", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", - "dev": true - }, - "@babel/types": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", - "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.4" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", - "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz", + "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.4" } }, "@babel/helper-module-imports": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", - "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.4" } }, "@babel/helper-module-transforms": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", - "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz", + "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-simple-access": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/template": "^7.8.6", - "@babel/types": "^7.9.0", + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4", "lodash": "^4.17.13" } }, "@babel/helper-optimise-call-expression": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", - "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.4" } }, "@babel/helper-plugin-utils": { @@ -200,68 +163,68 @@ "dev": true }, "@babel/helper-replace-supers": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz", - "integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/traverse": "^7.8.6", - "@babel/types": "^7.8.6" + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-simple-access": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", - "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.4" } }, "@babel/helper-validator-identifier": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", - "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, "@babel/helpers": { - "version": "7.9.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz", - "integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.9.0", - "@babel/types": "^7.9.0" + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/highlight": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", - "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.9.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", - "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", + "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -363,29 +326,39 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/runtime-corejs3": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.4.tgz", + "integrity": "sha512-BFlgP2SoLO9HJX9WBwN67gHWMBhDX/eDz64Jajd6mR/UAUzqrNMm99d4qHnVaKscAElZoFiPv+JpR/Siud5lXw==", + "dev": true, + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + } + }, "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/traverse": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", - "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", + "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.0", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.0", - "@babel/types": "^7.9.0", + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.4", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" @@ -409,12 +382,12 @@ } }, "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", + "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -435,6 +408,16 @@ "minimist": "^1.2.0" } }, + "@dabh/diagnostics": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", + "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", + "requires": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "@grpc/proto-loader": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.4.tgz", @@ -454,9 +437,9 @@ } }, "@hapi/address": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.0.1.tgz", - "integrity": "sha512-0oEP5UiyV4f3d6cBL8F3Z5S7iWSX39Knnl0lY8i+6gfmmIBj44JCBNtcMgwyS+5v7j3VYavNay0NFHDS+UGQcw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.1.0.tgz", + "integrity": "sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ==", "requires": { "@hapi/hoek": "^9.0.0" } @@ -495,9 +478,9 @@ } }, "@hapi/bourne": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", - "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz", + "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==" }, "@hapi/call": { "version": "8.0.0", @@ -616,13 +599,6 @@ "@hapi/bourne": "2.x.x", "@hapi/cryptiles": "5.x.x", "@hapi/hoek": "9.x.x" - }, - "dependencies": { - "@hapi/bourne": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz", - "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==" - } } }, "@hapi/joi": { @@ -647,12 +623,12 @@ } }, "@hapi/nigel": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@hapi/nigel/-/nigel-4.0.0.tgz", - "integrity": "sha512-Bqs1pjcDnDQo/XGoiCCNHWTFcMzPbz3L4KU04njeFQMzzEmsojMRX7TX+PezQYCMKtHJOtMg0bHxZyMGqYtbSA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@hapi/nigel/-/nigel-4.0.2.tgz", + "integrity": "sha512-ht2KoEsDW22BxQOEkLEJaqfpoKPXxi7tvabXy7B/77eFtOyG5ZEstfZwxHQcqAiZhp58Ae5vkhEqI03kawkYNw==", "requires": { - "@hapi/hoek": "9.x.x", - "@hapi/vise": "4.x.x" + "@hapi/hoek": "^9.0.4", + "@hapi/vise": "^4.0.0" } }, "@hapi/oppsy": { @@ -720,13 +696,6 @@ "@hapi/hoek": "9.x.x", "@hapi/iron": "6.x.x", "@hapi/joi": "17.x.x" - }, - "dependencies": { - "@hapi/bourne": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz", - "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==" - } } }, "@hapi/subtext": { @@ -741,13 +710,6 @@ "@hapi/hoek": "9.x.x", "@hapi/pez": "^5.0.1", "@hapi/wreck": "17.x.x" - }, - "dependencies": { - "@hapi/bourne": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz", - "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==" - } } }, "@hapi/teamwork": { @@ -779,23 +741,17 @@ "@hapi/boom": "9.x.x", "@hapi/bourne": "2.x.x", "@hapi/hoek": "9.x.x" - }, - "dependencies": { - "@hapi/bourne": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz", - "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==" - } } }, "@istanbuljs/load-nyc-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", - "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "requires": { "camelcase": "^5.3.1", "find-up": "^4.1.0", + "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" }, @@ -988,12 +944,6 @@ "to-regex-range": "^5.0.1" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -1301,30 +1251,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1344,12 +1270,6 @@ "source-map": "^0.6.0" }, "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1430,14 +1350,6 @@ "jest-haste-map": "^26.1.0", "jest-runner": "^26.1.0", "jest-runtime": "^26.1.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "@jest/transform": { @@ -1528,12 +1440,6 @@ "to-regex-range": "^5.0.1" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -1617,9 +1523,9 @@ } }, "@jsdevtools/ono": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.2.tgz", - "integrity": "sha512-qS/a24RA5FEoiJS9wiv6Pwg2c/kiUo3IVUQcfeM9JvsR6pM8Yx+yl/6xWYLckZCT5jpLNhslgjiA8p/XcGyMRQ==" + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" }, "@korzio/djv-draft-04": { "version": "2.0.1", @@ -1629,22 +1535,36 @@ "optional": true }, "@mojaloop/central-services-error-handling": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@mojaloop/central-services-error-handling/-/central-services-error-handling-10.4.1.tgz", - "integrity": "sha512-WGhZC+L5va4XwA2jFi7+1S1DrnpRE7Vdefu6u676d2AH1SvMx2ZM8e5943+1Y1T/xlF1ngXYrP7HSMaQG4g+GA==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/@mojaloop/central-services-error-handling/-/central-services-error-handling-10.6.0.tgz", + "integrity": "sha512-93Jbz/CWNxMiA6/x+KmQezf7C/K3etIAwmXdeAjR9BBDM9xJt1nGfRDovXJZzqV5pTgh9ytGen7A3ub6oVqcQA==", "requires": { "@mojaloop/sdk-standard-components": "10.3.2", - "lodash": "4.17.15" + "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": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@mojaloop/central-services-logger/-/central-services-logger-10.4.0.tgz", - "integrity": "sha512-vndjDG6klX7cGF8+5KrlmwDtav+2rCL5Ntpfd5NG9FqxluFcUkj9d2BUUs99CzG+qkkJZNITvfL8uBooSdYiJg==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/@mojaloop/central-services-logger/-/central-services-logger-10.6.0.tgz", + "integrity": "sha512-fvZVCtquX+QR+kuKhx/jiyf+B5E7zXYi1HfgaLWR/5+wqdopMltxRGYyRZJyJ1uqdstm+/HOSFvWjqv3JXZ1hw==", "requires": { "parse-strings-in-object": "2.0.0", "rc": "1.2.8", - "winston": "3.2.1" + "winston": "3.3.3" } }, "@mojaloop/central-services-metrics": { @@ -1656,54 +1576,41 @@ } }, "@mojaloop/central-services-shared": { - "version": "10.5.3", - "resolved": "https://registry.npmjs.org/@mojaloop/central-services-shared/-/central-services-shared-10.5.3.tgz", - "integrity": "sha512-RG91BLBTgui51NAsEogtxY6Stq9ic2OmfRe5qpSgQze4HM6+ziEMBVyxeVSM+43FbwXE3RKCJFHe77akba+xew==", + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/@mojaloop/central-services-shared/-/central-services-shared-10.6.2.tgz", + "integrity": "sha512-16fEcpaB0dYt+2acYJOtm95IQEtkXDgZSucHAYgZcqrpH6C7Tx9SmMJ/smXR6fDg88uIB6Hs9J4zE/61BhlFlw==", "requires": { "@hapi/catbox": "11.1.0", "@hapi/catbox-memory": "5.0.0", - "@mojaloop/central-services-error-handling": "10.4.1", - "@mojaloop/central-services-logger": "10.4.0", + "@mojaloop/central-services-error-handling": "10.6.0", + "@mojaloop/central-services-logger": "10.6.0", "@mojaloop/central-services-metrics": "9.5.0", - "@mojaloop/event-sdk": "10.4.0", - "ajv": "6.12.2", - "ajv-keywords": "3.5.0", + "@mojaloop/event-sdk": "10.6.0", + "ajv": "6.12.3", + "ajv-keywords": "3.5.1", "axios": "0.19.2", "base64url": "3.0.1", "clone": "2.1.2", "data-urls": "2.0.0", "immutable": "3.8.2", - "lodash": "4.17.15", + "lodash": "4.17.19", "mustache": "4.0.1", "openapi-backend": "3.5.1", "raw-body": "2.4.1" - }, - "dependencies": { - "ajv": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", - "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - } } }, "@mojaloop/event-sdk": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@mojaloop/event-sdk/-/event-sdk-10.4.0.tgz", - "integrity": "sha512-F6ceYlFR7gd3IUvUmJnE5aqKX5+1gsV+KdudFtWzOjjuP9dtuKtkAtVUP934ijvlGKF6vZPGheiwgnqGUh1cTA==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/@mojaloop/event-sdk/-/event-sdk-10.6.0.tgz", + "integrity": "sha512-mDVow/3WDILDUF2v32fqcOZAoRQCOZX8D2fJF3kHvZLGthU9ydNPHK118aVibw76XAyq6E6UbxHMXg3ZUPBlhg==", "requires": { "@grpc/proto-loader": "0.5.4", - "@mojaloop/central-services-logger": "10.4.0", + "@mojaloop/central-services-logger": "10.6.0", "brototype": "0.0.6", "error-callsites": "2.0.3", "grpc": "1.24.3", - "lodash": "4.17.15", - "moment": "2.26.0", + "lodash": "4.17.19", + "moment": "2.27.0", "parse-strings-in-object": "2.0.0", "protobufjs": "6.9.0", "rc": "1.2.8", @@ -1711,20 +1618,8 @@ "sinon": "9.0.2", "traceparent": "1.0.0", "tslib": "2.0.0", - "uuid4": "1.1.4", - "winston": "3.2.1" - }, - "dependencies": { - "moment": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz", - "integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==" - }, - "tslib": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", - "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" - } + "uuid4": "2.0.2", + "winston": "3.3.3" } }, "@mojaloop/ml-number": { @@ -1911,9 +1806,9 @@ "dev": true }, "@sinonjs/commons": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.1.tgz", - "integrity": "sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", + "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", "requires": { "type-detect": "4.0.8" } @@ -1998,9 +1893,9 @@ } }, "@types/babel__traverse": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.12.tgz", - "integrity": "sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA==", + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", + "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -2056,9 +1951,9 @@ } }, "@types/jest": { - "version": "26.0.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.3.tgz", - "integrity": "sha512-v89ga1clpVL/Y1+YI0eIu1VMW+KU7Xl8PhylVtDKVWaSUHBHYPLXMQGBdrpHewaKoTvlXkksbYqPgz8b4cmRZg==", + "version": "26.0.4", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.4.tgz", + "integrity": "sha512-4fQNItvelbNA9+sFgU+fhJo8ZFF+AS4Egk3GWwCW2jFtViukXbnztccafAdLhzE/0EiCogljtQQXP8aQ9J7sFg==", "dev": true, "requires": { "jest-diff": "^25.2.1", @@ -2071,9 +1966,9 @@ "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" }, "@types/node": { - "version": "10.17.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.21.tgz", - "integrity": "sha512-PQKsydPxYxF1DsAFWmunaxd3sOi3iMt6Zmx/tgaagHYmwJ/9cRH91hQkeJZaUGWbvn0K5HlSVEXkn5U/llWPpQ==" + "version": "13.13.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.13.tgz", + "integrity": "sha512-UfvBE9oRCAJVzfR+3eWm/sdLFe/qroAPEXP3GPJ1SehQiEVgZT6NQZWYbPMiJ3UdcKM06v4j+S1lTcdWCmw+3g==" }, "@types/normalize-package-data": { "version": "2.4.0", @@ -2082,9 +1977,9 @@ "dev": true }, "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.2.tgz", + "integrity": "sha512-IkVfat549ggtkZUthUzEX49562eGikhSYeVGX97SkMFn+sTZrgRewXjQ4tPKFPCykZHkX1Zfd9OoELGqKU2jJA==", "dev": true }, "@types/stack-utils": { @@ -2119,9 +2014,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", "dev": true }, "acorn-globals": { @@ -2147,9 +2042,9 @@ "dev": true }, "agent-base": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz", - "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz", + "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==", "dev": true, "requires": { "debug": "4" @@ -2167,9 +2062,9 @@ } }, "agentkeepalive": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.2.tgz", - "integrity": "sha512-waNHE7tQBBn+2qXucI8HY0o2Y0OBPWldWOWsZwY71JcCm4SvrPnWdceFfB5NIXSqE8Ewq6VR/Qt5b1i69P6KCQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.3.tgz", + "integrity": "sha512-wn8fw19xKZwdGPO47jivonaHRTd+nGOMP1z11sgGeQzDy2xd5FG0R67dIMcKHDE2cJ5y+YXV30XVGUBPRSY7Hg==", "dev": true, "requires": { "debug": "^4.1.0", @@ -2199,9 +2094,9 @@ } }, "ajv": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", - "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2210,9 +2105,9 @@ } }, "ajv-keywords": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.0.tgz", - "integrity": "sha512-eyoaac3btgU8eJlvh01En8OCKzRqlLe2G5jDsCr3RiE2uLGMEEB1aaGwVVpwR8M95956tGH6R+9edC++OvzaVw==" + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.1.tgz", + "integrity": "sha512-KWcq3xN8fDjSB+IMoh2VaXVhRI0BBGxoYp3rx7Pkb6z0cFjYR9Q9l4yZqqals0/zsioCmocC5H6UvsGD4MoIBA==" }, "ansi-align": { "version": "3.0.0", @@ -2229,12 +2124,6 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -2264,9 +2153,9 @@ } }, "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, "ansi-escapes": { @@ -2429,12 +2318,9 @@ "dev": true }, "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "requires": { - "lodash": "^4.17.14" - } + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" }, "asynckit": { "version": "0.4.0", @@ -2448,24 +2334,18 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "audit-resolve-core": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/audit-resolve-core/-/audit-resolve-core-1.1.7.tgz", - "integrity": "sha512-9nLm9SgyMbMv86X5a/E6spcu3V+suceHF6Pg4BwjPqfxWBKDvISagJH9Ji592KihqBev4guKFO3BiNEVNnqh3A==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/audit-resolve-core/-/audit-resolve-core-1.1.8.tgz", + "integrity": "sha512-F3IWaxu1Xw4OokmtG9hkmsKoJt8DQS7RZvot52zXHsANKvzFRMKVNTP1DAz1ztlRGmJx1XV16PcE+6m35bYoTA==", "dev": true, "requires": { "concat-stream": "^1.6.2", "debug": "^4.1.1", "djv": "^2.1.2", "spawn-shell": "^2.1.0", - "yargs-parser": "^10.1.0" + "yargs-parser": "^18.1.3" }, "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -2474,15 +2354,6 @@ "requires": { "ms": "^2.1.1" } - }, - "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } } } }, @@ -2493,9 +2364,9 @@ "dev": true }, "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", "dev": true }, "axios": { @@ -2568,12 +2439,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true } } }, @@ -2731,6 +2596,11 @@ "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==" }, + "@hapi/bourne": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", + "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==" + }, "@hapi/hoek": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", @@ -2820,6 +2690,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -2965,6 +2841,40 @@ "unique-filename": "^1.1.1" }, "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", + "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -2979,6 +2889,26 @@ "requires": { "glob": "^7.1.3" } + }, + "tar": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz", + "integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.0", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -3109,9 +3039,9 @@ } }, "chance": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chance/-/chance-1.1.4.tgz", - "integrity": "sha512-pXPDSu3knKlb6H7ahQfpq//J9mSOxYK8SMtp8MV/nRJh8aLRDIl0ipLH8At8+nVogVwtvPZzyIzY/EbcY/cLuQ==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/chance/-/chance-1.1.6.tgz", + "integrity": "sha512-DXLzaGjasDWbvlFAJyQBIwlzdQZuPdz4of9TTTxmHTjja88ZU/vBwUwxxjalSt43zWTPrhiJT0z0N4bZqfZS9w==", "dev": true }, "char-regex": { @@ -3127,10 +3057,9 @@ "dev": true }, "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "ci-info": { "version": "2.0.0", @@ -3204,9 +3133,9 @@ } }, "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true }, "cliui": { @@ -3291,14 +3220,9 @@ } }, "colorette": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.1.0.tgz", - "integrity": "sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg==" - }, - "colornames": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz", - "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", + "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==" }, "colors": { "version": "1.4.0", @@ -3412,22 +3336,37 @@ "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", "dev": true }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "crypto-random-string": { @@ -3484,18 +3423,11 @@ } }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } + "ms": "^2.1.1" } }, "debug-log": { @@ -3651,9 +3583,9 @@ }, "dependencies": { "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true } } @@ -3700,16 +3632,6 @@ "wrappy": "1" } }, - "diagnostics": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz", - "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==", - "requires": { - "colorspace": "1.1.x", - "enabled": "1.0.x", - "kuler": "1.0.x" - } - }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -3815,18 +3737,15 @@ } }, "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, "enabled": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", - "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=", - "requires": { - "env-variable": "0.0.x" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" }, "encoding": { "version": "0.1.12", @@ -3847,12 +3766,12 @@ } }, "enquirer": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.5.tgz", - "integrity": "sha512-BNT1C08P9XD0vNg3J475yIUG+mVdp9T6towYFHUv897X0KoHBjB1shyrNmhmtHWKP17iSWgo7Gqh7BBuzLZMSA==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, "requires": { - "ansi-colors": "^3.2.1" + "ansi-colors": "^4.1.1" } }, "env-paths": { @@ -3861,11 +3780,6 @@ "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", "dev": true }, - "env-variable": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.6.tgz", - "integrity": "sha512-bHz59NlBbtS0NhftmR8+ExBEekE7br0e01jw+kk0NDro7TtZzBYZ5ScGPs3OmwnpyfHTHOtr1Y6uedCdrIldtg==" - }, "err-code": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", @@ -3895,22 +3809,22 @@ } }, "es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" } }, "es-to-primitive": { @@ -3960,19 +3874,58 @@ "source-map": "~0.6.1" }, "dependencies": { + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } } } }, "eslint": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.3.1.tgz", - "integrity": "sha512-cQC/xj9bhWUcyi/RuMbRtC3I0eW8MH0jhRELSvpKYkWep3C6YZ2OkvcvJVUeO6gcunABmzptbXBuDoXsjHmfTA==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.4.0.tgz", + "integrity": "sha512-gU+lxhlPHu45H3JkEGgYhWhkR9wLHHEXC9FbWFnTlEkbKyZKWgWRLgf61E8zWmBuI6g5xKBph9ltg3NtZMVF8g==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -4013,12 +3966,6 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { - "acorn": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", - "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", - "dev": true - }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -4060,17 +4007,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -4080,105 +4016,12 @@ "ms": "^2.1.1" } }, - "eslint-scope": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", - "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - }, - "espree": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", - "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", - "dev": true, - "requires": { - "acorn": "^7.2.0", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.2.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true - }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -4193,24 +4036,6 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, @@ -4226,9 +4051,9 @@ "dev": true }, "eslint-import-resolver-node": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", - "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", "dev": true, "requires": { "debug": "^2.6.9", @@ -4347,11 +4172,14 @@ "regexpp": "^3.0.0" }, "dependencies": { - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } } } }, @@ -4393,11 +4221,81 @@ "isarray": "^1.0.0" } }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } } } }, @@ -4415,10 +4313,19 @@ "semver": "^6.1.0" }, "dependencies": { + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true }, "semver": { @@ -4470,9 +4377,9 @@ "dev": true }, "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -4480,18 +4387,18 @@ } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, "esm": { @@ -4500,14 +4407,14 @@ "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==" }, "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", + "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", "dev": true, "requires": { - "acorn": "^7.1.1", + "acorn": "^7.2.0", "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^1.2.0" } }, "esprima": { @@ -4516,18 +4423,18 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.2.0.tgz", - "integrity": "sha512-weltsSqdeWIX9G2qQZz7KlTRJdkkOCTPgLYJUz1Hacf48R4YOwGPHO3+ORfWedqJKbq5WQmsgK90n+pFLIKt/Q==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "dev": true, "requires": { - "estraverse": "^5.0.0" + "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.0.0.tgz", - "integrity": "sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", + "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", "dev": true } } @@ -4577,6 +4484,48 @@ "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + } } }, "exit": { @@ -4813,9 +4762,9 @@ "dev": true }, "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-json-stable-stringify": { "version": "2.1.0", @@ -4843,9 +4792,9 @@ } }, "fecha": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", - "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz", + "integrity": "sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg==" }, "figgy-pudding": { "version": "3.5.2", @@ -4983,6 +4932,17 @@ "flatted": "^2.0.0", "rimraf": "2.6.3", "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "flatted": { @@ -4991,12 +4951,32 @@ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, + "fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "follow-redirects": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", "requires": { "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "for-in": { @@ -5020,49 +5000,6 @@ "requires": { "cross-spawn": "^7.0.0", "signal-exit": "^3.0.2" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } } }, "forever-agent": { @@ -5103,12 +5040,11 @@ "dev": true }, "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", "requires": { - "minipass": "^3.0.0" + "minipass": "^2.6.0" } }, "fs.realpath": { @@ -5169,9 +5105,9 @@ "dev": true }, "get-stdin": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", - "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", "dev": true }, "get-stream": { @@ -5331,9 +5267,9 @@ } }, "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, "growly": { @@ -5463,12 +5399,6 @@ "type-fest": "^0.8.0" }, "dependencies": { - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", @@ -5491,13 +5421,10 @@ } }, "hosted-git-info": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz", - "integrity": "sha512-4oT62d2jwSDBbLLFLZE+1vPuQ1h8p9wjrJ8Mqx5TjsyWmBMV5B13eJqn8pvluqubLf3cJPTfiYCIwNwDNmzScQ==", - "dev": true, - "requires": { - "lru-cache": "^5.1.1" - } + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true }, "html-encoding-sniffer": { "version": "2.0.1", @@ -5703,21 +5630,21 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.0.tgz", + "integrity": "sha512-K+LZp6L/6eE5swqIcVXrxl21aGDU4S50gKH0/d96OMQnSBCyGyZl/oZhbkVmdp5sBoINHd4xZvFSARh2dk6DWA==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", + "chalk": "^4.1.0", "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", + "cli-width": "^3.0.0", "external-editor": "^3.0.3", "figures": "^3.0.0", "lodash": "^4.17.15", "mute-stream": "0.0.8", "run-async": "^2.4.0", - "rxjs": "^6.5.3", + "rxjs": "^6.6.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", "through": "^2.3.6" @@ -5740,9 +5667,9 @@ } }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -5764,6 +5691,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -5793,9 +5726,9 @@ } }, "interpret": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.0.0.tgz", - "integrity": "sha512-e0/LknJ8wpMMhTiWcjivB+ESwIuvHnBSlBbmP/pSb8CQJldoj1p2qv7xGZ/+BtbTziYRFSz8OsvdbiX45LtYQA==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==" }, "invert-kv": { "version": "1.0.0", @@ -5852,9 +5785,9 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-ci": { @@ -6024,19 +5957,13 @@ "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", "dev": true }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "has": "^1.0.3" + "has-symbols": "^1.0.1" } }, "is-relative": { @@ -6048,9 +5975,9 @@ } }, "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" }, "is-string": { "version": "1.0.5", @@ -6147,15 +6074,12 @@ } }, "istanbul-lib-instrument": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz", - "integrity": "sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", "dev": true, "requires": { "@babel/core": "^7.7.5", - "@babel/parser": "^7.7.5", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.0.0", "semver": "^6.3.0" @@ -6184,17 +6108,6 @@ "uuid": "^3.3.3" }, "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, "p-map": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", @@ -6204,12 +6117,6 @@ "aggregate-error": "^3.0.0" } }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -6219,29 +6126,11 @@ "glob": "^7.1.3" } }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, @@ -6369,10 +6258,19 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "decamelize": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-3.2.0.tgz", + "integrity": "sha512-4TgkVUsmmu7oCSyGBm5FvfMoACuoh9EOidm7V5/J2X2djAwwt57qb3F2KMP2ITqODTCSwb+YRV+0Zqrv18k/hw==", + "dev": true, + "requires": { + "xregexp": "^4.2.4" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "is-fullwidth-code-point": { @@ -6440,13 +6338,13 @@ "dev": true }, "yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.0.tgz", + "integrity": "sha512-D3fRFnZwLWp8jVAAhPZBsmeIHY8tTsb8ItV9KaAaopmC6wde2u6Yw29JBIZHXw14kgkRnYmDgmQU4FVMDlIsWw==", "dev": true, "requires": { "cliui": "^6.0.0", - "decamelize": "^1.2.0", + "decamelize": "^3.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", @@ -6455,7 +6353,7 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" + "yargs-parser": "^18.1.2" } } } @@ -6518,21 +6416,10 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, "execa": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", - "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", + "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -6555,12 +6442,6 @@ "pump": "^3.0.0" } }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -6570,12 +6451,6 @@ "path-key": "^3.0.0" } }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -6585,30 +6460,6 @@ "end-of-stream": "^1.1.0", "once": "^1.3.1" } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, @@ -6709,12 +6560,6 @@ "to-regex-range": "^5.0.1" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -7121,12 +6966,6 @@ "to-regex-range": "^5.0.1" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -7287,6 +7126,12 @@ "requires": { "ansi-regex": "^4.1.0" } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true } } }, @@ -7557,12 +7402,6 @@ "to-regex-range": "^5.0.1" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -7722,70 +7561,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true } } }, @@ -7922,12 +7697,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true } } }, @@ -8029,10 +7798,19 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "decamelize": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-3.2.0.tgz", + "integrity": "sha512-4TgkVUsmmu7oCSyGBm5FvfMoACuoh9EOidm7V5/J2X2djAwwt57qb3F2KMP2ITqODTCSwb+YRV+0Zqrv18k/hw==", + "dev": true, + "requires": { + "xregexp": "^4.2.4" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "is-fullwidth-code-point": { @@ -8079,13 +7857,13 @@ "dev": true }, "yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.0.tgz", + "integrity": "sha512-D3fRFnZwLWp8jVAAhPZBsmeIHY8tTsb8ItV9KaAaopmC6wde2u6Yw29JBIZHXw14kgkRnYmDgmQU4FVMDlIsWw==", "dev": true, "requires": { "cliui": "^6.0.0", - "decamelize": "^1.2.0", + "decamelize": "^3.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", @@ -8094,7 +7872,7 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" + "yargs-parser": "^18.1.2" } } } @@ -8106,14 +7884,6 @@ "dev": true, "requires": { "graceful-fs": "^4.2.4" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "jest-snapshot": { @@ -8198,12 +7968,6 @@ "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-diff": { "version": "26.1.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.1.0.tgz", @@ -8320,12 +8084,6 @@ "to-regex-range": "^5.0.1" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -8542,9 +8300,9 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -8590,17 +8348,6 @@ "xml-name-validator": "^3.0.0" }, "dependencies": { - "tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", - "dev": true, - "requires": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, "webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", @@ -8660,6 +8407,48 @@ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true }, + "json-schema-ref-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-1.4.1.tgz", + "integrity": "sha1-wMLkOL8HlnI7AkUbrovH3Qs3/tA=", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "debug": "^2.2.0", + "es6-promise": "^3.0.2", + "js-yaml": "^3.4.6", + "ono": "^2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "ono": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/ono/-/ono-2.2.5.tgz", + "integrity": "sha1-2vCUiLURdNp6fkJ136sxtDj/oOM=", + "dev": true + } + } + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -8753,12 +8542,12 @@ } }, "jsx-ast-utils": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz", - "integrity": "sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", + "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", "dev": true, "requires": { - "array-includes": "^3.0.3", + "array-includes": "^3.1.1", "object.assign": "^4.1.0" } }, @@ -8819,25 +8608,25 @@ "dev": true }, "knex": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.21.1.tgz", - "integrity": "sha512-uWszXC2DPaLn/YznGT9wFTWUG9+kqbL4DMz+hCH789GLcLuYzq8werHPDKBJxtKvxrW/S1XIXgrTWdMypiVvsw==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/knex/-/knex-0.21.2.tgz", + "integrity": "sha512-hNp9f3yXCHtMrhV2pVsuCNYmPlgXhyqviMQGLBd9zdF03ZqCO9MPng0oYhNMgIs+vDr55VC6tjEbF1OQ1La7Kg==", "requires": { - "colorette": "1.1.0", + "colorette": "1.2.1", "commander": "^5.1.0", "debug": "4.1.1", "esm": "^3.2.25", "getopts": "2.2.5", "inherits": "~2.0.4", - "interpret": "^2.0.0", + "interpret": "^2.2.0", "liftoff": "3.1.0", - "lodash": "^4.17.15", + "lodash": "^4.17.19", "mkdirp": "^1.0.4", - "pg-connection-string": "2.2.0", + "pg-connection-string": "2.3.0", "tarn": "^3.0.0", "tildify": "2.0.0", "uuid": "^7.0.3", - "v8flags": "^3.1.3" + "v8flags": "^3.2.0" }, "dependencies": { "commander": { @@ -8857,21 +8646,13 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==" } } }, "kuler": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", - "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==", - "requires": { - "colornames": "^1.1.1" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" }, "latest-version": { "version": "5.1.0", @@ -8897,13 +8678,13 @@ "dev": true }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "libnpmconfig": { @@ -8986,6 +8767,15 @@ "strip-bom": "^3.0.0" }, "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -9004,9 +8794,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" }, "lodash.camelcase": { "version": "4.3.0", @@ -9080,13 +8870,13 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" }, "logform": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz", - "integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", + "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", "requires": { "colors": "^1.2.1", "fast-safe-stringify": "^2.0.4", - "fecha": "^2.3.3", + "fecha": "^4.2.0", "ms": "^2.1.1", "triple-beam": "^1.3.0" } @@ -9121,9 +8911,9 @@ } }, "make-dir": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", - "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { "semver": "^6.0.0" @@ -9158,6 +8948,23 @@ "promise-retry": "^1.1.1", "socks-proxy-agent": "^5.0.0", "ssri": "^8.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "make-iterator": { @@ -9237,17 +9044,17 @@ } }, "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" }, "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", "dev": true, "requires": { - "mime-db": "1.43.0" + "mime-db": "1.44.0" } }, "mimic-fn": { @@ -9276,20 +9083,12 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "dev": true, + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" } }, "minipass-collect": { @@ -9299,6 +9098,23 @@ "dev": true, "requires": { "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "minipass-fetch": { @@ -9314,6 +9130,15 @@ "minizlib": "^2.0.0" }, "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "minizlib": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", @@ -9339,6 +9164,23 @@ "dev": true, "requires": { "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "minipass-json-stream": { @@ -9349,6 +9191,23 @@ "requires": { "jsonparse": "^1.3.1", "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "minipass-pipeline": { @@ -9358,6 +9217,23 @@ "dev": true, "requires": { "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "minipass-sized": { @@ -9367,27 +9243,33 @@ "dev": true, "requires": { "minipass": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "requires": { - "minipass": "^2.9.0" }, "dependencies": { "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "yallist": "^4.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } + }, "mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", @@ -9431,9 +9313,9 @@ "dev": true }, "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz", + "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==" }, "ms": { "version": "2.1.2", @@ -9506,16 +9388,6 @@ "debug": "^3.2.6", "iconv-lite": "^0.4.4", "sax": "^1.2.4" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - } } }, "nested-error-stacks": { @@ -9531,9 +9403,9 @@ "dev": true }, "nise": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.3.tgz", - "integrity": "sha512-EGlhjm7/4KvmmE6B/UFsKh7eHykRl9VH+au8dduHLCyWUO/hr7+N+WtTvDUwc9zHuM1IaIJs/0lQ6Ag1jDkQSg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", + "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", "requires": { "@sinonjs/commons": "^1.7.0", "@sinonjs/fake-timers": "^6.0.0", @@ -9564,48 +9436,6 @@ "semver": "^5.7.1", "tar": "^4.4.12", "which": "^1.3.1" - }, - "dependencies": { - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "dev": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - } } }, "node-int64": { @@ -9642,13 +9472,6 @@ "dev": true, "optional": true }, - "uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", - "dev": true, - "optional": true - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -9676,54 +9499,6 @@ "rimraf": "^2.6.1", "semver": "^5.3.0", "tar": "^4.4.2" - }, - "dependencies": { - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "requires": { - "minipass": "^2.6.0" - } - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "npm-packlist": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - } } }, "node-preload": { @@ -9754,14 +9529,6 @@ "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", - "dev": true - } } }, "normalize-path": { @@ -9777,37 +9544,19 @@ "dev": true }, "npm-audit-resolver": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/npm-audit-resolver/-/npm-audit-resolver-2.2.0.tgz", - "integrity": "sha512-nBhxrc0Y34vIFl38G42PkWSBEbOAL3Gg6aRxm1hYzM4Vm+Rv0ozALj2LixdeytkUC2OGWP4QqCF0fKAb14NnPQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/npm-audit-resolver/-/npm-audit-resolver-2.2.1.tgz", + "integrity": "sha512-9Jo5EdxREaXRrFm7eiuT1qu7fXKDfO+oiu+EgvJ/JCd2PIAgzVGF+xFoNK9AnyUsMFvSTdJM6+YlgUgF/N86GA==", "dev": true, "requires": { - "audit-resolve-core": "^1.1.7", + "audit-resolve-core": "^1.1.8", "chalk": "^2.4.2", "djv": "^2.1.2", "jsonlines": "^0.1.1", "read": "^1.0.7", "spawn-shell": "^2.1.0", - "yargs-parser": "^13.1.1", - "yargs-unparser": "^1.5.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } + "yargs-parser": "^18.1.3", + "yargs-unparser": "^1.6.3" } }, "npm-bundled": { @@ -9886,12 +9635,6 @@ "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "dev": true }, - "get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true - }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", @@ -9933,6 +9676,15 @@ "validate-npm-package-name": "^3.0.0" }, "dependencies": { + "hosted-git-info": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz", + "integrity": "sha512-4oT62d2jwSDBbLLFLZE+1vPuQ1h8p9wjrJ8Mqx5TjsyWmBMV5B13eJqn8pvluqubLf3cJPTfiYCIwNwDNmzScQ==", + "dev": true, + "requires": { + "lru-cache": "^5.1.1" + } + }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", @@ -9942,14 +9694,12 @@ } }, "npm-packlist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-2.1.2.tgz", - "integrity": "sha512-eByPaP+wsKai0BJX5pmb58d3mfR0zUATcnyuvSxIudTEn+swCPFLxh7srCmqB4hr7i9V24/DPjjq5b2qUtbgXQ==", - "dev": true, + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", "requires": { - "glob": "^7.1.6", - "ignore-walk": "^3.0.3", - "npm-bundled": "^1.1.1", + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", "npm-normalize-package-bin": "^1.0.1" } }, @@ -9973,9 +9723,9 @@ } }, "npm-registry-fetch": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-8.1.0.tgz", - "integrity": "sha512-RkcugRDye2j6yEiHGMyAdKQoipgp8VToSIjm+TFLhVraXOkC/WU2kjE2URcYBpcJ4hs++VFBKo6+Zg4wmrS+Qw==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-8.1.1.tgz", + "integrity": "sha512-3FCYb/YO6k9vfPMSU6H1CbixQAzoLuBqTTpjcks2PHlN59c0ENTYrDF8lCRvgLm1iAhwhwZg7pRq2VOTw3Yfaw==", "dev": true, "requires": { "@npmcli/ci-detect": "^1.0.0", @@ -9988,6 +9738,15 @@ "npm-package-arg": "^8.0.0" }, "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "minizlib": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", @@ -10013,6 +9772,14 @@ "dev": true, "requires": { "path-key": "^2.0.0" + }, + "dependencies": { + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + } } }, "npmlog": { @@ -10114,6 +9881,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -10182,13 +9955,13 @@ "dev": true }, "yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.0.tgz", + "integrity": "sha512-D3fRFnZwLWp8jVAAhPZBsmeIHY8tTsb8ItV9KaAaopmC6wde2u6Yw29JBIZHXw14kgkRnYmDgmQU4FVMDlIsWw==", "dev": true, "requires": { "cliui": "^6.0.0", - "decamelize": "^1.2.0", + "decamelize": "^3.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", @@ -10197,7 +9970,18 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" + "yargs-parser": "^18.1.2" + }, + "dependencies": { + "decamelize": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-3.2.0.tgz", + "integrity": "sha512-4TgkVUsmmu7oCSyGBm5FvfMoACuoh9EOidm7V5/J2X2djAwwt57qb3F2KMP2ITqODTCSwb+YRV+0Zqrv18k/hw==", + "dev": true, + "requires": { + "xregexp": "^4.2.4" + } + } } } } @@ -10242,9 +10026,9 @@ } }, "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", "dev": true }, "object-keys": { @@ -10285,14 +10069,13 @@ } }, "object.entries": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", - "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", "dev": true, "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", + "es-abstract": "^1.17.5", "has": "^1.0.3" } }, @@ -10351,9 +10134,12 @@ } }, "one-time": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", - "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "requires": { + "fn.name": "1.x.x" + } }, "onetime": { "version": "5.1.0", @@ -10387,13 +10173,6 @@ "openapi-types": "^1.3.4", "qs": "^6.9.3", "swagger-parser": "^9.0.1" - }, - "dependencies": { - "qs": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" - } } }, "openapi-schema-validation": { @@ -10412,17 +10191,17 @@ "integrity": "sha512-11oi4zYorsgvg5yBarZplAqbpev5HkuVNPlZaPTknPDzAynq+lnJdXAmruGWP0s+dNYZS7bjM+xrTpJw7184Fg==" }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, "optjs": { @@ -10573,12 +10352,58 @@ "tar": "^6.0.1" }, "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", + "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, + "npm-packlist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-2.1.2.tgz", + "integrity": "sha512-eByPaP+wsKai0BJX5pmb58d3mfR0zUATcnyuvSxIudTEn+swCPFLxh7srCmqB4hr7i9V24/DPjjq5b2qUtbgXQ==", + "dev": true, + "requires": { + "glob": "^7.1.6", + "ignore-walk": "^3.0.3", + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -10587,6 +10412,26 @@ "requires": { "glob": "^7.1.3" } + }, + "tar": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz", + "integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.0", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -10610,12 +10455,15 @@ } }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", "dev": true, "requires": { - "error-ex": "^1.2.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" } }, "parse-passwd": { @@ -10651,9 +10499,9 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { @@ -10705,9 +10553,9 @@ "dev": true }, "pg-connection-string": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.2.0.tgz", - "integrity": "sha512-xB/+wxcpFipUZOQcSzcgkjcNOosGhEoPSjz06jC89lv1dj7mc9bZv6wLVy8M2fVjP0a/xN0N988YDq1L0FhK3A==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.3.0.tgz", + "integrity": "sha512-ukMTJXLI7/hZIwTW7hGMZJ0Lj0S2XQBCJ4Shv4y1zgQ/vqVea+FLhzywvPj0ujSuofu+yA4MYHGZPTsgjBgJ+w==" }, "picomatch": { "version": "2.2.2", @@ -10868,6 +10716,21 @@ "yallist": "^2.1.2" } }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "which": { "version": "1.2.14", "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", @@ -10886,9 +10749,9 @@ } }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prepend-http": { @@ -11027,11 +10890,6 @@ "long": "^4.0.0" }, "dependencies": { - "@types/node": { - "version": "13.13.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.12.tgz", - "integrity": "sha512-zWz/8NEPxoXNT9YyF2osqyA9WjssZukYpgI4UYZpOjcyqwIUqWGkcCionaEb9Ki+FULyPyvNFpg/329Kd2/pbw==" - }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -11096,10 +10954,9 @@ } }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" }, "randexp": { "version": "0.4.9", @@ -11195,73 +11052,40 @@ } }, "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } } }, "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true } } @@ -11300,6 +11124,12 @@ "resolve": "^1.1.6" } }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -11310,9 +11140,9 @@ } }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true }, "registry-auth-token": { @@ -11384,6 +11214,30 @@ "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } } }, "request-promise-core": { @@ -11404,6 +11258,18 @@ "request-promise-core": "1.1.3", "stealthy-require": "^1.1.1", "tough-cookie": "^2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } } }, "require-directory": { @@ -11447,9 +11313,9 @@ } }, "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "requires": { "path-parse": "^1.0.6" } @@ -11522,9 +11388,9 @@ "dev": true }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "requires": { "glob": "^7.1.3" } @@ -11536,13 +11402,10 @@ "dev": true }, "run-async": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", - "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true }, "run-parallel": { "version": "1.1.9", @@ -11551,12 +11414,20 @@ "dev": true }, "rxjs": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", - "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", + "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", "dev": true, "requires": { "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } } }, "safe-buffer": { @@ -11697,18 +11568,18 @@ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "shellwords": { @@ -11743,16 +11614,6 @@ "diff": "^4.0.2", "nise": "^4.0.1", "supports-color": "^7.1.0" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz", - "integrity": "sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw==", - "requires": { - "type-detect": "4.0.8" - } - } } }, "sisteransi": { @@ -11903,9 +11764,9 @@ } }, "socks": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.3.tgz", - "integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.4.1.tgz", + "integrity": "sha512-8mWHeYC1OA0500qzb+sqwm0Hzi8oBpeuI1JugoBVMEJtJvxSgco8xFSK+NRnZcHeeWjTbF82KUDo5sXH22TY5A==", "dev": true, "requires": { "ip": "1.1.5", @@ -12036,9 +11897,9 @@ } }, "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -12046,15 +11907,15 @@ } }, "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -12109,6 +11970,23 @@ "dev": true, "requires": { "minipass": "^3.1.1" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "stack-trace": { @@ -12156,6 +12034,27 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -12210,12 +12109,89 @@ "v8-compile-cache": "^2.0.3" } }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -12230,19 +12206,36 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } } } }, "standard-engine": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-12.0.1.tgz", - "integrity": "sha512-XtR9NfoTqvHkWQCwL1aLMwXw1Qxy5s4rdSIqetgBNw+8faNbQ+BbB49hPhKXjxxfC4yg+fpH0lx/T5fuUbpDcQ==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-12.1.0.tgz", + "integrity": "sha512-DVJnWM1CGkag4ucFLGdiYWa5/kJURPONmMmk17p8FT5NE4UnPZB1vxWnXnRo2sPSL78pWJG8xEM+1Tu19z0deg==", "dev": true, "requires": { "deglob": "^4.0.1", "get-stdin": "^7.0.0", "minimist": "^1.2.5", "pkg-conf": "^3.1.0" + }, + "dependencies": { + "get-stdin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "dev": true + } } }, "static-extend": { @@ -12327,28 +12320,6 @@ "es-abstract": "^1.17.5" } }, - "string.prototype.trimleft": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", - "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimstart": "^1.0.0" - } - }, - "string.prototype.trimright": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", - "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimend": "^1.0.0" - } - }, "string.prototype.trimstart": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", @@ -12448,48 +12419,6 @@ "swagger-parser": "^3.4.1" }, "dependencies": { - "json-schema-ref-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-1.4.1.tgz", - "integrity": "sha1-wMLkOL8HlnI7AkUbrovH3Qs3/tA=", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "debug": "^2.2.0", - "es6-promise": "^3.0.2", - "js-yaml": "^3.4.6", - "ono": "^2.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=", - "dev": true - }, - "ono": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/ono/-/ono-2.2.5.tgz", - "integrity": "sha1-2vCUiLURdNp6fkJ136sxtDj/oOM=", - "dev": true - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, "swagger-parser": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-3.4.2.tgz", @@ -12505,6 +12434,25 @@ "swagger-schema-official": "2.0.0-bab6bed", "z-schema": "^3.16.1" } + }, + "validator": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==", + "dev": true + }, + "z-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.25.1.tgz", + "integrity": "sha512-7tDlwhrBG+oYFdXNOjILSurpfQyuVgkRe3hB2q8TEssamDHB7BbLWYkYO98nTn0FibfdFroFKDjndbgufAgS/Q==", + "dev": true, + "requires": { + "commander": "^2.7.1", + "core-js": "^2.5.7", + "lodash.get": "^4.0.0", + "lodash.isequal": "^4.0.0", + "validator": "^10.0.0" + } } } }, @@ -12532,12 +12480,6 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -12567,41 +12509,17 @@ } }, "tar": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz", - "integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.0", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "dependencies": { - "minizlib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", - "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" } }, "tarn": { @@ -12751,11 +12669,12 @@ } }, "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", "dev": true, "requires": { + "ip-regex": "^2.1.0", "psl": "^1.1.28", "punycode": "^2.1.1" } @@ -12782,10 +12701,9 @@ "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, "tslib": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" }, "tunnel-agent": { "version": "0.6.0", @@ -12803,12 +12721,12 @@ "dev": true }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-detect": { @@ -13017,20 +12935,19 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==" }, "uuid4": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/uuid4/-/uuid4-1.1.4.tgz", - "integrity": "sha512-Gr1q2k40LpF8CokcnQFjPDsdslzJbTCTBG5xQIEflUov431gFkY5KduiGIeKYAamkQnNn4IfdHJbLnl9Bib8TQ==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/uuid4/-/uuid4-2.0.2.tgz", + "integrity": "sha512-TzsQS8sN1B2m9WojyNp0X/3JL8J2RScnrAJnooNPL6lq3lA02/XdoWysyUgI6rAif0DzkkWk51N6OggujPy2RA==" }, "v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", "dev": true }, "v8-to-istanbul": { @@ -13053,9 +12970,9 @@ } }, "v8flags": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", - "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", "requires": { "homedir-polyfill": "^1.0.1" } @@ -13080,10 +12997,9 @@ } }, "validator": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", - "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==", - "dev": true + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-12.2.0.tgz", + "integrity": "sha512-jJfE/DW6tIK1Ek8nCfNFqt8Wb3nzMoAbocBF6/Icgg1ZFSBpObdnwVY2jQj6qUqzhx5jc71fpvBWyLGO7Xl+nQ==" }, "verror": { "version": "1.10.0", @@ -13198,6 +13114,12 @@ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -13232,19 +13154,19 @@ "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" }, "winston": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz", - "integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", + "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", "requires": { - "async": "^2.6.1", - "diagnostics": "^1.1.1", - "is-stream": "^1.1.0", - "logform": "^2.1.1", - "one-time": "0.0.4", - "readable-stream": "^3.1.1", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.1.0", + "is-stream": "^2.0.0", + "logform": "^2.2.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.3.0" + "winston-transport": "^4.4.0" }, "dependencies": { "readable-stream": { @@ -13260,11 +13182,11 @@ } }, "winston-transport": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz", - "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", + "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", "requires": { - "readable-stream": "^2.3.6", + "readable-stream": "^2.3.7", "triple-beam": "^1.2.0" } }, @@ -13310,9 +13232,9 @@ } }, "ws": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", - "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", "dev": true }, "xdg-basedir": { @@ -13339,6 +13261,15 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xregexp": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", + "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", + "dev": true, + "requires": { + "@babel/runtime-corejs3": "^7.8.3" + } + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -13370,9 +13301,9 @@ } }, "yargs-parser": { - "version": "18.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.2.tgz", - "integrity": "sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -13388,14 +13319,16 @@ } }, "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.3.tgz", + "integrity": "sha512-xI32EGCq5mJiSCsQaEPLljD+R3Hq/VG08YGoLTOqu/gHAtCa2S4qPMG20ol4TpKWgSU7j3KMZHvSirNPK0DSjA==", "dev": true, "requires": { + "camelcase": "^5.3.1", + "decamelize": "^1.2.0", "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "is-plain-obj": "^1.1.0", + "yargs": "^14.2.3" }, "dependencies": { "ansi-regex": { @@ -13421,12 +13354,6 @@ "wrap-ansi": "^5.1.0" } }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -13505,12 +13432,13 @@ "dev": true }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", + "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", "dev": true, "requires": { "cliui": "^5.0.0", + "decamelize": "^1.2.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", @@ -13519,13 +13447,13 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "yargs-parser": "^15.0.1" } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", + "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -13535,16 +13463,14 @@ } }, "z-schema": { - "version": "3.25.1", - "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.25.1.tgz", - "integrity": "sha512-7tDlwhrBG+oYFdXNOjILSurpfQyuVgkRe3hB2q8TEssamDHB7BbLWYkYO98nTn0FibfdFroFKDjndbgufAgS/Q==", - "dev": true, + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-4.2.3.tgz", + "integrity": "sha512-zkvK/9TC6p38IwcrbnT3ul9in1UX4cm1y/VZSs4GHKIiDCrlafc+YQBgQBUdDXLAoZHf2qvQ7gJJOo6yT1LH6A==", "requires": { "commander": "^2.7.1", - "core-js": "^2.5.7", - "lodash.get": "^4.0.0", - "lodash.isequal": "^4.0.0", - "validator": "^10.0.0" + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^12.0.0" } } } diff --git a/package.json b/package.json index 7f0b6d61..c3c53c94 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": "10.5.5", + "version": "10.6.0", "author": "ModusBox", "contributors": [ "James Bush ", @@ -60,10 +60,10 @@ "dependencies": { "@hapi/good": "9.0.0", "@hapi/hapi": "19.1.1", - "@mojaloop/central-services-error-handling": "10.4.1", - "@mojaloop/central-services-logger": "10.4.0", - "@mojaloop/central-services-shared": "10.5.3", - "@mojaloop/event-sdk": "10.4.0", + "@mojaloop/central-services-error-handling": "10.6.0", + "@mojaloop/central-services-logger": "10.6.0", + "@mojaloop/central-services-shared": "10.6.2", + "@mojaloop/event-sdk": "10.6.0", "@mojaloop/ml-number": "8.2.0", "@mojaloop/sdk-standard-components": "10.3.2", "axios": "0.19.2", @@ -72,7 +72,7 @@ "good-console": "8.0.0", "good-squeeze": "5.1.0", "json-rules-engine": "5.0.2", - "knex": "0.21.1", + "knex": "0.21.2", "memory-cache": "0.2.0", "minimist": "1.2.5", "mysql": "2.18.1", @@ -81,11 +81,11 @@ "rc": "1.2.8" }, "devDependencies": { - "@types/jest": "26.0.3", - "eslint": "7.3.1", + "@types/jest": "26.0.4", + "eslint": "7.4.0", "jest": "26.1.0", "jest-junit": "11.0.1", - "npm-audit-resolver": "2.2.0", + "npm-audit-resolver": "2.2.1", "npm-check-updates": "7.0.1", "nyc": "15.1.0", "pre-commit": "1.2.2", diff --git a/src/handlers/bulkQuotes.js b/src/handlers/bulkQuotes.js index 37a09ccb..04e93ec2 100644 --- a/src/handlers/bulkQuotes.js +++ b/src/handlers/bulkQuotes.js @@ -27,12 +27,18 @@ * Henk Kodde * Georgi Georgiev + * Rajiv Mothilal -------------- ******/ 'use strict' +const util = require('util') +const Enum = require('@mojaloop/central-services-shared').Enum const ErrorHandler = require('@mojaloop/central-services-error-handling') +const EventSdk = require('@mojaloop/event-sdk') +const LibUtil = require('../lib/util') +const BulkQuotesModel = require('../model/bulkQuotes') /** * Operations on /bulkQuotes @@ -45,7 +51,40 @@ module.exports = { * produces: application/json * responses: 202, 400, 401, 403, 404, 405, 406, 501, 503 */ - post: function BulkQuotes (context, request, h) { - throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.NOT_IMPLEMENTED, 'Bulk quotes not implemented') + post: async function BulkQuotes (context, request, h) { + // log request + request.server.log(['info'], `got a POST /bulkQuotes request: ${util.inspect(request.payload)}`) + + // instantiate a new quote model + const model = new BulkQuotesModel({ + db: request.server.app.database, + requestId: request.info.id + }) + + // extract some things from the request we may need if we have to deal with an error e.g. the + // originator and quoteId + const bulkQuoteId = request.payload.bulkQuoteId + const fspiopSource = request.headers[Enum.Http.Headers.FSPIOP.SOURCE] + + const span = request.span + try { + const spanTags = LibUtil.getSpanTags(request, Enum.Events.Event.Type.BULK_QUOTE, Enum.Events.Event.Action.PREPARE) + span.setTags(spanTags) + await span.audit({ + headers: request.headers, + payload: request.payload + }, EventSdk.AuditEventAction.start) + + // call the quote request handler in the model + model.handleBulkQuoteRequest(request.headers, request.payload, span) + } catch (err) { + // something went wrong, use the model to handle the error in a sensible way + request.server.log(['error'], `ERROR - POST /bulkQuotes: ${LibUtil.getStackOrInspect(err)}`) + const fspiopError = ErrorHandler.ReformatFSPIOPError(err) + model.handleException(fspiopSource, bulkQuoteId, fspiopError, request.headers, span) + } finally { + // eslint-disable-next-line no-unsafe-finally + return h.response().code(Enum.Http.ReturnCodes.ACCEPTED.CODE) + } } } diff --git a/src/handlers/bulkQuotes/{id}.js b/src/handlers/bulkQuotes/{id}.js index 6a005cb9..4e29eb33 100644 --- a/src/handlers/bulkQuotes/{id}.js +++ b/src/handlers/bulkQuotes/{id}.js @@ -32,30 +32,97 @@ 'use strict' -const ErrorHandler = require('@mojaloop/central-services-error-handling') - +const util = require('util') +const Enum = require('@mojaloop/central-services-shared').Enum +const EventSdk = require('@mojaloop/event-sdk') +const LibUtil = require('../../lib/util') +const BulkQuotesModel = require('../../model/bulkQuotes.js') /** * Operations on /bulkQuotes/{id} */ module.exports = { /** - * summary: BulkQuotesById + * summary: getBulkQuotesById * description: The HTTP request GET /bulkQuotes/<id> is used to get information regarding an earlier created or requested bulk quote. The <id> in the URI should contain the bulkQuoteId that was used for the creation of the bulk quote. * parameters: Accept * produces: application/json * responses: 202, 400, 401, 403, 404, 405, 406, 501, 503 */ - get: function BulkQuotesById (context, request, h) { - throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.NOT_IMPLEMENTED, 'Bulk quotes not implemented') + get: async function getBulkQuotesById (context, request, h) { + // log request + request.server.log(['info'], `got a GET /bulkQuotes/{id} request for bulkQuoteId ${request.params.id}`) + + // instantiate a new quote model + const model = new BulkQuotesModel({ + db: request.server.app.database, + requestId: request.info.id + }) + + // extract some things from the request we may need if we have to deal with an error e.g. the + // originator and quoteId + const bulkQuoteId = request.params.id + const fspiopSource = request.headers[Enum.Http.Headers.FSPIOP.SOURCE] + + const span = request.span + try { + const spanTags = LibUtil.getSpanTags(request, Enum.Events.Event.Type.BULK_QUOTE, Enum.Events.Event.Action.GET) + span.setTags(spanTags) + await span.audit({ + headers: request.headers, + payload: request.payload + }, EventSdk.AuditEventAction.start) + // call the model to re-forward the quote update to the correct party + // note that we do not check if our caller is the correct party, but we + // will send the callback to the correct party regardless. + model.handleBulkQuoteGet(request.headers, bulkQuoteId, span) + } catch (err) { + // something went wrong, use the model to handle the error in a sensible way + request.server.log(['error'], `ERROR - GET /bulkQuotes/{id}: ${LibUtil.getStackOrInspect(err)}`) + model.handleException(fspiopSource, bulkQuoteId, err, request.headers, span) + } finally { + // eslint-disable-next-line no-unsafe-finally + return h.response().code(Enum.Http.ReturnCodes.ACCEPTED.CODE) + } }, /** - * summary: BulkQuotesById + * summary: putBulkQuotesById * description: The callback PUT /bulkQuotes/<id> is used to inform the client of a requested or created bulk quote. The <id> in the URI should contain the bulkQuoteId that was used for the creation of the bulk quote, or the <id> that was used in the GET /bulkQuotes/<id>. * parameters: body, Content-Length * produces: application/json * responses: 200, 400, 401, 403, 404, 405, 406, 501, 503 */ - put: function BulkQuotesById1 (context, request, h) { - throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.NOT_IMPLEMENTED, 'Bulk quotes not implemented') + put: async function putBulkQuotesById (context, request, h) { + // log request + request.server.log(['info'], `got a PUT /bulkQuotes/{id} request: ${util.inspect(request.payload)}`) + + // instantiate a new quote model + const model = new BulkQuotesModel({ + db: request.server.app.database, + requestId: request.info.id + }) + + // extract some things from the request we may need if we have to deal with an error e.g. the + // originator and quoteId + const bulkQuoteId = request.params.id + const fspiopSource = request.headers[Enum.Http.Headers.FSPIOP.SOURCE] + + const span = request.span + try { + const spanTags = LibUtil.getSpanTags(request, Enum.Events.Event.Type.BULK_QUOTE, Enum.Events.Event.Action.FULFIL) + span.setTags(spanTags) + await span.audit({ + headers: request.headers, + payload: request.payload + }, EventSdk.AuditEventAction.start) + // call the quote update handler in the model + model.handleBulkQuoteUpdate(request.headers, bulkQuoteId, request.payload, span) + } catch (err) { + // something went wrong, use the model to handle the error in a sensible way + request.server.log(['error'], `ERROR - PUT /bulkQuotes/{id}: ${LibUtil.getStackOrInspect(err)}`) + model.handleException(fspiopSource, bulkQuoteId, err, request.headers, span) + } finally { + // eslint-disable-next-line no-unsafe-finally + return h.response().code(Enum.Http.ReturnCodes.OK.CODE) + } } } diff --git a/src/handlers/bulkQuotes/{id}/error.js b/src/handlers/bulkQuotes/{id}/error.js index 0832c1f5..8f3b63ed 100644 --- a/src/handlers/bulkQuotes/{id}/error.js +++ b/src/handlers/bulkQuotes/{id}/error.js @@ -32,8 +32,11 @@ 'use strict' -const ErrorHandler = require('@mojaloop/central-services-error-handling') - +const util = require('util') +const Enum = require('@mojaloop/central-services-shared').Enum +const EventSdk = require('@mojaloop/event-sdk') +const LibUtil = require('../../../lib/util') +const BulkQuotesModel = require('../../../model/bulkQuotes') /** * Operations on /bulkQuotes/{id}/error */ @@ -45,7 +48,38 @@ module.exports = { * produces: application/json * responses: 200, 400, 401, 403, 404, 405, 406, 501, 503 */ - put: function BulkQuotesErrorById (context, request, h) { - throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.NOT_IMPLEMENTED, 'Bulk quotes not implemented') + put: async function BulkQuotesErrorById (context, request, h) { + // log request + request.server.log(['info'], `got a PUT /bulkQuotes/{id}/error request: ${util.inspect(request.payload)}`) + + // instantiate a new quote model + const model = new BulkQuotesModel({ + db: request.server.app.database, + requestId: request.info.id + }) + + // extract some things from the request we may need if we have to deal with an error e.g. the + // originator and quoteId + const bulkQuoteId = request.params.id + const fspiopSource = request.headers[Enum.Http.Headers.FSPIOP.SOURCE] + + const span = request.span + try { + const spanTags = LibUtil.getSpanTags(request, Enum.Events.Event.Type.BULK_QUOTE, Enum.Events.Event.Action.ABORT) + span.setTags(spanTags) + await span.audit({ + headers: request.headers, + payload: request.payload + }, EventSdk.AuditEventAction.start) + // call the quote error handler in the model + model.handleBulkQuoteError(request.headers, bulkQuoteId, request.payload.errorInformation, span) + } catch (err) { + // something went wrong, use the model to handle the error in a sensible way + request.server.log(['error'], `ERROR - PUT /bulkQuotes/{id}/error: ${LibUtil.getStackOrInspect(err)}`) + model.handleException(fspiopSource, bulkQuoteId, err, request.headers) + } finally { + // eslint-disable-next-line no-unsafe-finally + return h.response().code(Enum.Http.ReturnCodes.OK.CODE) + } } } diff --git a/src/lib/util.js b/src/lib/util.js index 21442bc9..67c93c66 100644 --- a/src/lib/util.js +++ b/src/lib/util.js @@ -33,6 +33,7 @@ 'use strict' const util = require('util') +const crypto = require('crypto') const Enum = require('@mojaloop/central-services-shared').Enum const Logger = require('@mojaloop/central-services-logger') @@ -92,9 +93,98 @@ function getSafe (path, obj) { return path.reduce((xs, x) => (xs && xs[x]) ? xs[x] : undefined, obj) } +/** + * 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} + */ +function 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] = removeEmptyKeys(obj[key]) + } + } else if (obj[key] == null) { + // null or undefined, remove it + delete obj[key] + } + }) + return obj +} + +/** + * Generates and returns an object containing API spec compliant HTTP request headers + * + * @returns {object} + */ +function generateRequestHeaders (headers, noAccept) { + const ret = { + 'Content-Type': headers['content-type'] || headers['Content-Type'], + 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 = headers.accept || headers.Accept + } + + return removeEmptyKeys(ret) +} + +/** + * Generates and returns an object containing API spec compliant lowercase HTTP request headers for JWS Signing + * + * @returns {object} + */ +function generateRequestHeadersForJWS (headers, noAccept) { + const ret = { + 'Content-Type': headers['content-type'] || headers['Content-Type'], + 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 = headers.accept || headers.Accept + } + + return removeEmptyKeys(ret) +} + +/** + * Returns the SHA-256 hash of the supplied request object + * + * @returns {undefined} + */ +function calculateRequestHash (request) { + // calculate a SHA-256 of the request + const requestStr = JSON.stringify(request) + return crypto.createHash('sha256').update(requestStr).digest('hex') +} + module.exports = { failActionHandler, getSafe, getSpanTags, - getStackOrInspect + getStackOrInspect, + generateRequestHeaders, + generateRequestHeadersForJWS, + calculateRequestHash, + removeEmptyKeys } diff --git a/src/model/bulkQuotes.js b/src/model/bulkQuotes.js new file mode 100644 index 00000000..679fbdef --- /dev/null +++ b/src/model/bulkQuotes.js @@ -0,0 +1,501 @@ +// (C)2018 ModusBox Inc. +/***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + Initial contribution + -------------------- + The initial functionality and code base was donated by the Mowali project working in conjunction with MTN and Orange as service provides. + * Project: Mowali + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * ModusBox + - Rajiv Mothilal + -------------- + ******/ + +const axios = require('axios') +const util = require('util') + +const ENUM = require('@mojaloop/central-services-shared').Enum +const ErrorHandler = require('@mojaloop/central-services-error-handling') +const EventSdk = require('@mojaloop/event-sdk') +const LibUtil = require('@mojaloop/central-services-shared').Util +const Logger = require('@mojaloop/central-services-logger') +const JwsSigner = require('@mojaloop/sdk-standard-components').Jws.signer + +const Config = require('../lib/config') +const { httpRequest } = require('../lib/http') +const { getStackOrInspect, generateRequestHeadersForJWS, generateRequestHeaders } = require('../lib/util') +const LOCAL_ENUM = require('../lib/enum') + +delete axios.defaults.headers.common.Accept +delete axios.defaults.headers.common['Content-Type'] + +/** + * Encapsulates operations on the bulkQuotes domain model + * + * @returns {undefined} + */ + +class BulkQuotesModel { + constructor (config) { + this.config = config + this.db = config.db + this.requestId = config.requestId + } + + /** + * Validates the quote request object + * + * @returns {promise} - promise will reject if request is not valid + */ + async validateBulkQuoteRequest (fspiopSource, fspiopDestination, bulkQuoteRequest) { + await this.db.getParticipant(fspiopSource, LOCAL_ENUM.PAYER_DFSP, bulkQuoteRequest.individualQuotes[0].amount.currency, ENUM.Accounts.LedgerAccountType.POSITION) + await this.db.getParticipant(fspiopDestination, LOCAL_ENUM.PAYEE_DFSP, bulkQuoteRequest.individualQuotes[0].amount.currency, ENUM.Accounts.LedgerAccountType.POSITION) + } + + /** + * Logic for creating and handling quote requests + * + * @returns {object} - returns object containing keys for created database entities + */ + async handleBulkQuoteRequest (headers, bulkQuoteRequest, span) { + // accumulate enum ids + const refs = {} + let fspiopSource + let childSpan + try { + fspiopSource = headers[ENUM.Http.Headers.FSPIOP.SOURCE] + const fspiopDestination = headers[ENUM.Http.Headers.FSPIOP.DESTINATION] + + // validate - this will throw if the request is invalid + await this.validateBulkQuoteRequest(fspiopSource, fspiopDestination, bulkQuoteRequest) + childSpan = span.getChild('qs_bulkquote_forwardBulkQuoteRequest') + // if we got here rules passed, so we can forward the quote on to the recipient dfsp + await childSpan.audit({ headers, payload: bulkQuoteRequest }, EventSdk.AuditEventAction.start) + await this.forwardBulkQuoteRequest(headers, bulkQuoteRequest.bulkQuoteId, bulkQuoteRequest, childSpan) + } catch (err) { + // any-error + // as we are on our own in this context, dont just rethrow the error, instead... + // get the model to handle it + this.writeLog(`Error forwarding quote request: ${getStackOrInspect(err)}. Attempting to send error callback to ${fspiopSource}`) + await this.handleException(fspiopSource, bulkQuoteRequest.bulkQuoteId, err, headers, childSpan) + } finally { + if (childSpan && !childSpan.isFinished) { + await childSpan.finish() + } + } + + // all ok, return refs + return refs + } + + /** + * Forwards a quote request to a payee DFSP for processing + * + * @returns {undefined} + */ + async forwardBulkQuoteRequest (headers, bulkQuoteId, originalBulkQuoteRequest, span) { + let endpoint + const fspiopSource = headers[ENUM.Http.Headers.FSPIOP.SOURCE] + const fspiopDest = headers[ENUM.Http.Headers.FSPIOP.DESTINATION] + + try { + // 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 + endpoint = await this.db.getParticipantEndpoint(fspiopDest, ENUM.EndPoints.FspEndpointTypes.FSPIOP_CALLBACK_URL_BULK_QUOTES) + + this.writeLog(`Resolved FSPIOP_CALLBACK_URL_BULK_QUOTES endpoint for bulkQuote ${bulkQuoteId} to: ${util.inspect(endpoint)}`) + + if (!endpoint) { + // internal-error + // we didnt get an endpoint for the payee dfsp! + // make an error callback to the initiator + throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR, `No FSPIOP_CALLBACK_URL_BULK_QUOTES found for quote ${bulkQuoteId} PAYEE party`, null, fspiopSource) + } + + const fullCallbackUrl = `${endpoint}${ENUM.EndPoints.FspEndpointTemplates.BULK_QUOTES_POST}` + const newHeaders = generateRequestHeaders(headers) + + this.writeLog(`Forwarding quote request to endpoint: ${fullCallbackUrl}`) + this.writeLog(`Forwarding quote request headers: ${JSON.stringify(newHeaders)}`) + this.writeLog(`Forwarding quote request body: ${JSON.stringify(originalBulkQuoteRequest)}`) + + let opts = { + method: ENUM.Http.RestMethods.POST, + url: fullCallbackUrl, + data: JSON.stringify(originalBulkQuoteRequest), + headers: newHeaders + } + + if (span) { + opts = span.injectContextToHttpRequest(opts) + span.audit(opts, EventSdk.AuditEventAction.egress) + } + + this.writeLog(`Forwarding request : ${util.inspect(opts)}`) + await httpRequest(opts, fspiopSource) + } catch (err) { + // any-error + this.writeLog(`Error forwarding bulkQuote request to endpoint ${endpoint}: ${getStackOrInspect(err)}`) + throw ErrorHandler.ReformatFSPIOPError(err) + } + } + + /** + * Logic for handling quote update requests e.g. PUT /bulkQuotes/{id} requests + * + * @returns {object} - object containing updated entities + */ + async handleBulkQuoteUpdate (headers, bulkQuoteId, bulkQuoteUpdateRequest, span) { + // ensure no 'accept' header is present in the request headers. + if ('accept' in headers) { + // internal-error + throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.VALIDATION_ERROR, + `Update for bulk quote ${bulkQuoteId} failed: "accept" header should not be sent in callbacks.`, null, headers['fspiop-source']) + } + // if we got here rules passed, so we can forward the quote on to the recipient dfsp + const childSpan = span.getChild('qs_quote_forwardBulkQuoteUpdate') + try { + await childSpan.audit({ headers, params: { bulkQuoteId }, payload: bulkQuoteUpdateRequest }, EventSdk.AuditEventAction.start) + await this.forwardBulkQuoteUpdate(headers, bulkQuoteId, bulkQuoteUpdateRequest, childSpan) + } catch (err) { + // any-error + // as we are on our own in this context, dont just rethrow the error, instead... + // get the model to handle it + const fspiopSource = headers[ENUM.Http.Headers.FSPIOP.SOURCE] + this.writeLog(`Error forwarding bulk quote update: ${getStackOrInspect(err)}. Attempting to send error callback to ${fspiopSource}`) + await this.handleException(fspiopSource, bulkQuoteId, err, headers, childSpan) + } finally { + if (childSpan && !childSpan.isFinished) { + await childSpan.finish() + } + } + } + + /** + * Forwards a bulk quote response to a payer DFSP for processing + * + * @returns {undefined} + */ + async forwardBulkQuoteUpdate (headers, bulkQuoteId, originalBulkQuoteResponse, span) { + let endpoint = null + const fspiopSource = headers[ENUM.Http.Headers.FSPIOP.SOURCE] + const fspiopDest = headers[ENUM.Http.Headers.FSPIOP.DESTINATION] + + try { + // lookup payer dfsp callback endpoint + endpoint = await this.db.getParticipantEndpoint(fspiopDest, 'FSPIOP_CALLBACK_URL_BULK_QUOTES') + this.writeLog(`Resolved PAYER party FSPIOP_CALLBACK_URL_BULK_QUOTES endpoint for bulk quote ${bulkQuoteId} to: ${util.inspect(endpoint)}`) + + if (!endpoint) { + // we didnt get an endpoint for the payee dfsp! + // make an error callback to the initiator + const fspiopError = ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR, `No FSPIOP_CALLBACK_URL_BULK_QUOTES found for quote ${bulkQuoteId} PAYER party`, null, fspiopSource) + return this.sendErrorCallback(fspiopSource, fspiopError, bulkQuoteId, headers, true) + } + + const fullCallbackUrl = `${endpoint}/bulkQuotes/${bulkQuoteId}` + // 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) + + this.writeLog(`Forwarding bulk quote response to endpoint: ${fullCallbackUrl}`) + this.writeLog(`Forwarding bulk quote response headers: ${JSON.stringify(newHeaders)}`) + this.writeLog(`Forwarding bulk quote response body: ${JSON.stringify(originalBulkQuoteResponse)}`) + + let opts = { + method: ENUM.Http.RestMethods.PUT, + url: fullCallbackUrl, + data: JSON.stringify(originalBulkQuoteResponse), + headers: newHeaders + } + + if (span) { + opts = span.injectContextToHttpRequest(opts) + span.audit(opts, EventSdk.AuditEventAction.egress) + } + + await httpRequest(opts, fspiopSource) + } catch (err) { + // any-error + this.writeLog(`Error forwarding bulk quote response to endpoint ${endpoint}: ${getStackOrInspect(err)}`) + throw ErrorHandler.ReformatFSPIOPError(err) + } + } + + /** + * Attempts to handle a bulk quote GET request by forwarding it to the destination DFSP + * + * @returns {undefined} + */ + async handleBulkQuoteGet (headers, bulkQuoteId, span) { + const fspiopSource = headers[ENUM.Http.Headers.FSPIOP.SOURCE] + const childSpan = span.getChild('qs_quote_forwardBulkQuoteGet') + try { + await childSpan.audit({ headers, params: { bulkQuoteId } }, EventSdk.AuditEventAction.start) + await this.forwardBulkQuoteGet(headers, bulkQuoteId, childSpan) + } catch (err) { + // any-error + // as we are on our own in this context, dont just rethrow the error, instead... + // get the model to handle it + this.writeLog(`Error forwarding bulk quote get: ${getStackOrInspect(err)}. Attempting to send error callback to ${fspiopSource}`) + await this.handleException(fspiopSource, bulkQuoteId, err, headers, childSpan) + } finally { + if (childSpan && !childSpan.isFinished) { + await childSpan.finish() + } + } + } + + /** + * Attempts to forward a bulk quote GET request + * + * @returns {undefined} + */ + async forwardBulkQuoteGet (headers, bulkQuoteId, span) { + let endpoint + try { + // 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 + const fspiopSource = headers[ENUM.Http.Headers.FSPIOP.SOURCE] + const fspiopDest = headers[ENUM.Http.Headers.FSPIOP.DESTINATION] + endpoint = await this.db.getParticipantEndpoint(fspiopDest, 'FSPIOP_CALLBACK_URL_BULK_QUOTES') + + this.writeLog(`Resolved ${fspiopDest} FSPIOP_CALLBACK_URL_BULK_QUOTES endpoint for bulk quote GET ${bulkQuoteId} to: ${util.inspect(endpoint)}`) + + if (!endpoint) { + // we didnt get an endpoint for the payee dfsp! + // make an error callback to the initiator + // internal-error + throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR, `No FSPIOP_CALLBACK_URL_BULK_QUOTES found for bulk quote GET ${bulkQuoteId}`, null, fspiopSource) + } + + const fullCallbackUrl = `${endpoint}/bulkQuotes/${bulkQuoteId}` + const newHeaders = generateRequestHeaders(headers) + + this.writeLog(`Forwarding quote get request to endpoint: ${fullCallbackUrl}`) + + let opts = { + method: ENUM.Http.RestMethods.GET, + url: fullCallbackUrl, + headers: newHeaders + } + + if (span) { + opts = span.injectContextToHttpRequest(opts) + span.audit(opts, EventSdk.AuditEventAction.egress) + } + + await httpRequest(opts, fspiopSource) + } catch (err) { + // any-error + this.writeLog(`Error forwarding quote get request: ${getStackOrInspect(err)}`) + throw ErrorHandler.ReformatFSPIOPError(err) + } + } + + /** + * Handles error reports from clients e.g. POST bulkQuotes/{id}/error + * + * @returns {undefined} + */ + async handleBulkQuoteError (headers, bulkQuoteId, error, span) { + let newError + const fspiopSource = headers[ENUM.Http.Headers.FSPIOP.SOURCE] + const childSpan = span.getChild('qs_quote_forwardBulkQuoteError') + try { + // create a new object to represent the error + const fspiopError = ErrorHandler.CreateFSPIOPErrorFromErrorInformation(error) + await childSpan.audit({ headers, params: { bulkQuoteId } }, EventSdk.AuditEventAction.start) + // Needed to add await here to prevent 'span already finished' bug + await this.sendErrorCallback(headers[ENUM.Http.Headers.FSPIOP.DESTINATION], fspiopError, bulkQuoteId, headers, childSpan, false) + return newError + } catch (err) { + // internal-error + this.writeLog(`Error in handleBulkQuoteError: ${getStackOrInspect(err)}`) + await this.handleException(fspiopSource, bulkQuoteId, err, headers, childSpan) + } finally { + if (childSpan && !childSpan.isFinished) { + await childSpan.finish() + } + } + } + + /** + * Attempts to handle an exception in a sensible manner by forwarding it on to the + * source of the request that caused the error. + */ + async handleException (fspiopSource, bulkQuoteId, error, headers, span) { + // is this exception already wrapped as an API spec compatible type? + const fspiopError = ErrorHandler.ReformatFSPIOPError(error) + + const childSpan = span.getChild('qs_bulkQuote_sendErrorCallback') + try { + await childSpan.audit({ headers, params: { bulkQuoteId } }, EventSdk.AuditEventAction.start) + return await this.sendErrorCallback(fspiopSource, fspiopError, bulkQuoteId, headers, childSpan, true) + } catch (err) { + // any-error + // not much we can do other than log the error + this.writeLog(`Error occurred while handling error. Check service logs as this error may not have been propagated successfully to any other party: ${getStackOrInspect(err)}`) + } finally { + if (!childSpan.isFinished) { + await childSpan.finish() + } + } + } + + /** + * Makes an error callback. Callback is sent to the FSPIOP_CALLBACK_URL_QUOTES endpoint of the replyTo participant in the + * supplied fspiopErr object. This should be the participantId for the error callback recipient e.g. value from the + * FSPIOP-Source header of the original request that caused the error. + * + * @returns {promise} + */ + async sendErrorCallback (fspiopSource, fspiopError, bulkQuoteId, headers, span, modifyHeaders = true) { + const envConfig = new Config() + const fspiopDest = headers[ENUM.Http.Headers.FSPIOP.DESTINATION] + try { + // look up the callback base url + const endpoint = await this.db.getParticipantEndpoint(fspiopSource, ENUM.EndPoints.FspEndpointTypes.FSPIOP_CALLBACK_URL_BULK_QUOTES) + + this.writeLog(`Resolved participant '${fspiopSource}' '${ENUM.EndPoints.FspEndpointTypes.FSPIOP_CALLBACK_URL_BULK_QUOTES}' to: '${endpoint}'`) + + if (!endpoint) { + // oops, we cant make an error callback if we dont have an endpoint to call! + // internal-error + throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PARTY_NOT_FOUND, `No FSPIOP_CALLBACK_URL_BULK_QUOTES found for ${fspiopSource} unable to make error callback`, null, fspiopSource) + } + + const fspiopUri = `/bulkQuotes/${bulkQuoteId}/error` + const fullCallbackUrl = `${endpoint}${fspiopUri}` + + // log the original error + this.writeLog(`Making error callback to participant '${fspiopSource}' for bulkQuoteId '${bulkQuoteId}' to ${fullCallbackUrl} for error: ${util.inspect(fspiopError.toFullErrorObject())}`) + + // make an error callback + let fromSwitchHeaders + let formattedHeaders + + // modify/set the headers only in case it is explicitly requested to do so + // as this part needs to cover two different cases: + // 1. (do not modify them) when the Switch needs to relay an error, e.g. from a DFSP to another + // 2. (modify/set them) when the Switch needs send errors that are originating in the Switch, e.g. to send an error back to the caller + if (modifyHeaders === true) { + // Should not forward 'fspiop-signature' header for switch generated messages + delete headers['fspiop-signature'] + fromSwitchHeaders = Object.assign({}, headers, { + 'fspiop-destination': fspiopSource, + 'fspiop-source': ENUM.Http.Headers.FSPIOP.SWITCH.value, + 'fspiop-http-method': ENUM.Http.RestMethods.PUT, + 'fspiop-uri': fspiopUri + }) + } else { + fromSwitchHeaders = Object.assign({}, headers) + } + + // JWS Signer expects headers in lowercase + if (envConfig.jws && envConfig.jws.jwsSign && fromSwitchHeaders['fspiop-source'] === envConfig.jws.fspiopSourceToSign) { + formattedHeaders = generateRequestHeadersForJWS(fromSwitchHeaders, true) + } else { + formattedHeaders = generateRequestHeaders(fromSwitchHeaders, true) + } + + let opts = { + method: ENUM.Http.RestMethods.PUT, + url: fullCallbackUrl, + data: JSON.stringify(fspiopError.toApiErrorObject(envConfig.errorHandling), LibUtil.getCircularReplacer()), + // use headers of the error object if they are there... + // otherwise use sensible defaults + headers: formattedHeaders + } + + if (span) { + opts = span.injectContextToHttpRequest(opts) + span.audit(opts, EventSdk.AuditEventAction.egress) + } + + let res + try { + // If JWS is enabled and the 'fspiop-source' matches the configured jws header value('switch') + // that means it's a switch generated message and we need to sign it + if (envConfig.jws && envConfig.jws.jwsSign && opts.headers['fspiop-source'] === envConfig.jws.fspiopSourceToSign) { + const logger = Logger + logger.log = logger.info + this.writeLog('Getting the JWS Signer to sign the switch generated message') + const jwsSigner = new JwsSigner({ + logger, + signingKey: envConfig.jws.jwsSigningKey + }) + opts.headers['fspiop-signature'] = jwsSigner.getSignature(opts) + } + + res = await axios.request(opts) + } catch (err) { + // external-error + throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_COMMUNICATION_ERROR, `network error in sendErrorCallback: ${err.message}`, { + error: err, + url: fullCallbackUrl, + sourceFsp: fspiopSource, + destinationFsp: fspiopDest, + method: opts && opts.method, + request: JSON.stringify(opts, LibUtil.getCircularReplacer()) + }, fspiopSource) + } + this.writeLog(`Error callback got response ${res.status} ${res.statusText}`) + + if (res.status !== ENUM.Http.ReturnCodes.OK.CODE) { + // external-error + throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_COMMUNICATION_ERROR, 'Got non-success response sending error callback', { + url: fullCallbackUrl, + sourceFsp: fspiopSource, + destinationFsp: fspiopDest, + method: opts && opts.method, + request: JSON.stringify(opts, LibUtil.getCircularReplacer()), + response: JSON.stringify(res, LibUtil.getCircularReplacer()) + }, fspiopSource) + } + } catch (err) { + // any-error + this.writeLog(`Error in sendErrorCallback: ${getStackOrInspect(err)}`) + const fspiopError = ErrorHandler.ReformatFSPIOPError(err) + const state = new EventSdk.EventStateMetadata(EventSdk.EventStatusType.failed, fspiopError.apiErrorCode.code, fspiopError.apiErrorCode.message) + if (span) { + await span.error(fspiopError, state) + await span.finish(fspiopError.message, state) + } + throw fspiopError + } + } + + /** + * Writes a formatted message to the console + * + * @returns {undefined} + */ + // eslint-disable-next-line no-unused-vars + writeLog (message) { + Logger.info(`${new Date().toISOString()}, (${this.requestId}) [bulkQuotesModel]: ${message}`) + } +} + +module.exports = BulkQuotesModel diff --git a/src/model/quotes.js b/src/model/quotes.js index 56796e76..99f323bb 100644 --- a/src/model/quotes.js +++ b/src/model/quotes.js @@ -34,7 +34,6 @@ ******/ const axios = require('axios') -const crypto = require('crypto') const util = require('util') const ENUM = require('@mojaloop/central-services-shared').Enum @@ -47,7 +46,7 @@ const JwsSigner = require('@mojaloop/sdk-standard-components').Jws.signer const Config = require('../lib/config') const { httpRequest } = require('../lib/http') -const { getStackOrInspect } = require('../lib/util') +const { getStackOrInspect, generateRequestHeadersForJWS, generateRequestHeaders, calculateRequestHash } = require('../lib/util') const LOCAL_ENUM = require('../lib/enum') const rules = require('../../config/rules.json') const RulesEngine = require('./rules.js') @@ -237,7 +236,7 @@ class QuotesModel { // todo: validation // if we get here we need to create a duplicate check row - const hash = this.calculateRequestHash(quoteRequest) + const hash = calculateRequestHash(quoteRequest) await this.db.createQuoteDuplicateCheck(txn, quoteRequest.quoteId, hash) // create a txn reference @@ -391,7 +390,7 @@ class QuotesModel { } const fullCallbackUrl = `${endpoint}/quotes` - const newHeaders = this.generateRequestHeaders(headers) + const newHeaders = generateRequestHeaders(headers) this.writeLog(`Forwarding quote request to endpoint: ${fullCallbackUrl}`) this.writeLog(`Forwarding quote request headers: ${JSON.stringify(newHeaders)}`) @@ -511,7 +510,7 @@ class QuotesModel { refs.quoteResponseId = newQuoteResponse.quoteResponseId // if we get here we need to create a duplicate check row - const hash = this.calculateRequestHash(quoteUpdateRequest) + const hash = calculateRequestHash(quoteUpdateRequest) await this.db.createQuoteUpdateDuplicateCheck(txn, quoteId, refs.quoteResponseId, hash) // create ilp packet in the db @@ -633,7 +632,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 = this.generateRequestHeaders(headers, true) + const newHeaders = generateRequestHeaders(headers, true) this.writeLog(`Forwarding quote response to endpoint: ${fullCallbackUrl}`) this.writeLog(`Forwarding quote response headers: ${JSON.stringify(newHeaders)}`) @@ -807,7 +806,7 @@ class QuotesModel { } const fullCallbackUrl = `${endpoint}/quotes/${quoteId}` - const newHeaders = this.generateRequestHeaders(headers) + const newHeaders = generateRequestHeaders(headers) this.writeLog(`Forwarding quote get request to endpoint: ${fullCallbackUrl}`) @@ -904,9 +903,9 @@ class QuotesModel { // JWS Signer expects headers in lowercase if (envConfig.jws && envConfig.jws.jwsSign && fromSwitchHeaders['fspiop-source'] === envConfig.jws.fspiopSourceToSign) { - formattedHeaders = this.generateRequestHeadersForJWS(fromSwitchHeaders, true) + formattedHeaders = generateRequestHeadersForJWS(fromSwitchHeaders, true) } else { - formattedHeaders = this.generateRequestHeaders(fromSwitchHeaders, true) + formattedHeaders = generateRequestHeaders(fromSwitchHeaders, true) } let opts = { @@ -986,7 +985,7 @@ class QuotesModel { async checkDuplicateQuoteRequest (quoteRequest) { try { // calculate a SHA-256 of the request - const hash = this.calculateRequestHash(quoteRequest) + const hash = calculateRequestHash(quoteRequest) this.writeLog(`Calculated sha256 hash of quote request with id ${quoteRequest.quoteId} as: ${hash}`) const dupchk = await this.db.getQuoteDuplicateCheck(quoteRequest.quoteId) @@ -1030,7 +1029,7 @@ class QuotesModel { async checkDuplicateQuoteResponse (quoteId, quoteResponse) { try { // calculate a SHA-256 of the request - const hash = this.calculateRequestHash(quoteResponse) + const hash = calculateRequestHash(quoteResponse) this.writeLog(`Calculated sha256 hash of quote response with id ${quoteId} as: ${hash}`) const dupchk = await this.db.getQuoteResponseDuplicateCheck(quoteId) @@ -1064,91 +1063,6 @@ 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': headers['content-type'] || headers['Content-Type'], - 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 = headers.accept || headers.Accept - } - - 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': headers['content-type'] || headers['Content-Type'], - 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 = headers.accept || headers.Accept - } - - return this.removeEmptyKeys(ret) - } - /** * Writes a formatted message to the console * diff --git a/test/unit/handlers/bulkQuotes.test.js b/test/unit/handlers/bulkQuotes.test.js index 60c48270..94f236d2 100644 --- a/test/unit/handlers/bulkQuotes.test.js +++ b/test/unit/handlers/bulkQuotes.test.js @@ -26,20 +26,87 @@ * Crosslake - Lewis Daly + + * Modusbox + - Rajiv Mothilal -------------- ******/ +jest.mock('../../../src/model/bulkQuotes') + +const Enum = require('@mojaloop/central-services-shared').Enum +const BulkQuotesModel = require('../../../src/model/bulkQuotes') const BulkQuotesHandler = require('../../../src/handlers/bulkQuotes') +const { baseMockRequest } = require('../../util/helper') + +const mockContext = jest.fn() describe('/bulkQuotes', () => { describe('POST', () => { - it('throws NOT IMPLEMENTED error', async () => { + beforeEach(() => { + BulkQuotesModel.mockClear() + }) + + it('creates a bulkQuote', async () => { // Arrange + const code = jest.fn() + const handler = { + response: jest.fn(() => ({ + code + })) + } + const mockRequest = { + ...baseMockRequest, + payload: { + quoteId: '12345' + }, + span: { + audit: jest.fn(), + setTags: jest.fn() + } + } + + // Act + await BulkQuotesHandler.post(mockContext, mockRequest, handler) + + // Assert + expect(code).toHaveBeenCalledWith(Enum.Http.ReturnCodes.ACCEPTED.CODE) + const mockQuoteInstance = BulkQuotesModel.mock.instances[0] + expect(mockQuoteInstance.handleBulkQuoteRequest).toHaveBeenCalledTimes(1) + }) + + it('fails to create a quote', async () => { + // Arrange + const handleException = jest.fn() + BulkQuotesModel.mockImplementationOnce(() => ({ + handleBulkQuoteRequest: () => { + throw new Error('Create Quote Test Error') + }, + handleException + })) + const code = jest.fn() + const handler = { + response: jest.fn(() => ({ + code + })) + } + const mockRequest = { + ...baseMockRequest, + payload: { + bulkQuoteId: '12345' + }, + span: { + audit: jest.fn(), + setTags: jest.fn() + } + } + // Act - const action = () => BulkQuotesHandler.post() + await BulkQuotesHandler.post(mockContext, mockRequest, handler) // Assert - expect(action).toThrowError('Bulk quotes not implemented') + expect(code).toHaveBeenCalledWith(Enum.Http.ReturnCodes.ACCEPTED.CODE) + expect(handleException).toHaveBeenCalledTimes(1) }) }) }) diff --git a/test/unit/handlers/bulkQuotes/{id}.test.js b/test/unit/handlers/bulkQuotes/{id}.test.js index 85d4e3e4..b75b261a 100644 --- a/test/unit/handlers/bulkQuotes/{id}.test.js +++ b/test/unit/handlers/bulkQuotes/{id}.test.js @@ -26,31 +26,122 @@ * Crosslake - Lewis Daly + + * Modusbox + - Rajiv Mothilal -------------- ******/ +jest.mock('@mojaloop/central-services-logger') +jest.mock('../../../../src/model/bulkQuotes') + +const Enum = require('@mojaloop/central-services-shared').Enum const BulkQuotesHandler = require('../../../../src/handlers/bulkQuotes/{id}') +const BulkQuotesModel = require('../../../../src/model/bulkQuotes') +const { baseMockRequest } = require('../../../util/helper') + +const mockContext = jest.fn() describe('/bulkQuotes/{id}', () => { + beforeEach(() => { + BulkQuotesModel.mockClear() + }) + describe('GET', () => { - it('throws NOT IMPLEMENTED error', async () => { + it('gets a bulk quote by id', async () => { + // Arrange + const code = jest.fn() + const handler = { + response: jest.fn(() => ({ + code + })) + } + + // Act + await BulkQuotesHandler.get(mockContext, { ...baseMockRequest }, handler) + + // Assert + expect(BulkQuotesModel).toHaveBeenCalledTimes(1) + const mockQuoteInstance = BulkQuotesModel.mock.instances[0] + expect(mockQuoteInstance.handleBulkQuoteGet).toHaveBeenCalledTimes(1) + expect(code).toHaveBeenCalledWith(Enum.Http.ReturnCodes.ACCEPTED.CODE) + }) + + it('handles an error with the model', async () => { // Arrange + const handleException = jest.fn() + BulkQuotesModel.mockImplementationOnce(() => { + return { + handleBulkQuoteGet: () => { + throw new Error('Test error') + }, + handleException + } + }) + const code = jest.fn() + const handler = { + response: jest.fn(() => ({ + code + })) + } + // Act - const action = () => BulkQuotesHandler.get() + await BulkQuotesHandler.get(mockContext, { ...baseMockRequest }, handler) // Assert - expect(action).toThrowError('Bulk quotes not implemented') + expect(BulkQuotesModel).toHaveBeenCalledTimes(1) + expect(handleException).toHaveBeenCalledTimes(1) + expect(code).toHaveBeenCalledWith(Enum.Http.ReturnCodes.ACCEPTED.CODE) }) }) describe('PUT', () => { - it('throws NOT IMPLEMENTED error', async () => { + it('puts a bulk quote by id', async () => { + BulkQuotesModel.mockClear() + // Arrange + const code = jest.fn() + const handler = { + response: jest.fn(() => ({ + code + })) + } + + // Act + await BulkQuotesHandler.put(mockContext, { ...baseMockRequest }, handler) + + // Assert + expect(BulkQuotesModel).toHaveBeenCalledTimes(1) + const mockQuoteInstance = BulkQuotesModel.mock.instances[0] + expect(mockQuoteInstance.handleBulkQuoteUpdate).toHaveBeenCalledTimes(1) + expect(code).toHaveBeenCalledWith(Enum.Http.ReturnCodes.OK.CODE) + }) + + it('handles an error with the model', async () => { + // Arrange + const handleException = jest.fn() + BulkQuotesModel.mockImplementationOnce(() => { + return { + handleBulkQuoteUpdate: () => { + throw new Error('Test error') + }, + handleException + } + }) + const code = jest.fn() + const handler = { + response: jest.fn(() => ({ + code + })) + } + // Act - const action = () => BulkQuotesHandler.put() + await BulkQuotesHandler.put(mockContext, { ...baseMockRequest }, handler) // Assert - expect(action).toThrowError('Bulk quotes not implemented') + expect(BulkQuotesModel).toHaveBeenCalledTimes(1) + expect(handleException).toHaveBeenCalledTimes(1) + expect(code).toHaveBeenCalledWith(Enum.Http.ReturnCodes.OK.CODE) }) }) }) diff --git a/test/unit/handlers/bulkQuotes/{id}/error.test.js b/test/unit/handlers/bulkQuotes/{id}/error.test.js index 73037b8b..d68c3cad 100644 --- a/test/unit/handlers/bulkQuotes/{id}/error.test.js +++ b/test/unit/handlers/bulkQuotes/{id}/error.test.js @@ -29,18 +29,85 @@ -------------- ******/ +const Enum = require('@mojaloop/central-services-shared').Enum + +jest.mock('@mojaloop/central-services-logger') +jest.mock('../../../../../src/model/bulkQuotes') + const BulkQuotesErrorHandler = require('../../../../../src/handlers/bulkQuotes/{id}/error') +const BulkQuotesModel = require('../../../../../src/model/bulkQuotes') +const { baseMockRequest } = require('../../../../util/helper') + +const mockContext = jest.fn() + +describe('/bulkQuotes/{id}/error', () => { + beforeEach(() => { + BulkQuotesModel.mockClear() + }) -describe('/bulkQuotes/error/{id}', () => { describe('PUT', () => { - it('throws NOT IMPLEMENTED error', async () => { + it('handles an error', async () => { + // Arrange + const request = { + ...baseMockRequest, + payload: { + errorInformation: { + errorCode: '2201', + errorDescription: 'Test Error' + } + } + } + const code = jest.fn() + const handler = { + response: jest.fn(() => ({ + code + })) + } + + // Act + await BulkQuotesErrorHandler.put(mockContext, request, handler) + + // Assert + expect(BulkQuotesModel).toHaveBeenCalledTimes(1) + const mockQuoteInstance = BulkQuotesModel.mock.instances[0] + expect(mockQuoteInstance.handleBulkQuoteError).toHaveBeenCalledTimes(1) + expect(code).toHaveBeenCalledWith(Enum.Http.ReturnCodes.OK.CODE) + }) + + it('handles an error with the model', async () => { // Arrange + const request = { + ...baseMockRequest, + payload: { + errorInformation: { + errorCode: '2201', + errorDescription: 'Test Error' + } + } + } + const handleException = jest.fn() + BulkQuotesModel.mockImplementationOnce(() => { + return { + handleBulkQuoteError: () => { + throw new Error('Test error') + }, + handleException + } + }) + const code = jest.fn() + const handler = { + response: jest.fn(() => ({ + code + })) + } // Act - const action = () => BulkQuotesErrorHandler.put() + await BulkQuotesErrorHandler.put(mockContext, request, handler) // Assert - expect(action).toThrowError('Bulk quotes not implemented') + expect(BulkQuotesModel).toHaveBeenCalledTimes(1) + expect(handleException).toHaveBeenCalledTimes(1) + expect(code).toHaveBeenCalledWith(Enum.Http.ReturnCodes.OK.CODE) }) }) }) diff --git a/test/unit/lib/util.test.js b/test/unit/lib/util.test.js index e565c577..b97ca138 100644 --- a/test/unit/lib/util.test.js +++ b/test/unit/lib/util.test.js @@ -26,9 +26,175 @@ const Enum = require('@mojaloop/central-services-shared').Enum -const { failActionHandler, getStackOrInspect, getSpanTags } = require('../../../src/lib/util') +const { failActionHandler, getStackOrInspect, getSpanTags, generateRequestHeaders, generateRequestHeadersForJWS, removeEmptyKeys } = require('../../../src/lib/util') describe('util', () => { + const mockData = { + amountTypeId: 'fakeAmountTypeId', + endpoints: { + payerfsp: 'http://localhost:8444/payerfsp', + payeefsp: 'http://localhost:8444/payeefsp', + invalid: 'http://invalid.com/', + invalidResponse: 'http://invalid-response.com/' + }, + geoCode: { + latitude: '42.69751', + longitude: '23.32415' + }, + headers: { + Accept: 'application/vnd.interoperability.quotes+json;version=1.0', + 'Content-Type': 'application/vnd.interoperability.quotes+json;version=1.0', + 'fspiop-source': 'dfsp1', + 'fspiop-destination': 'dfsp2' + }, + initiatorType: 'fakeInitiatorType', + initiator: 'fakeInitiator', + quoteId: 'test123', + quoteRequest: { + quoteId: 'test123', + transactionId: 'abc123', + payee: { + partyIdInfo: { + partyIdType: 'MSISDN', + partyIdentifier: '27824592509', + fspId: 'dfsp2' + } + }, + payer: { + partyIdInfo: { + partyIdType: 'MSISDN', + partyIdentifier: '27713803905', + fspId: 'dfsp1' + } + }, + amountType: 'SEND', + amount: { + amount: 100, + currency: 'USD' + }, + transactionType: { + scenario: 'TRANSFER', + initiator: 'PAYER', + initiatorType: 'CONSUMER' + }, + geoCode: { + latitude: '43.69751', + longitude: '24.32415' + }, + extensionList: { + extension: [{ + key: 'key1', + value: 'value1' + }] + } + }, + quoteUpdate: { + transferAmount: { + amount: '100', + currency: 'USD' + }, + payeeReceiveAmount: { + amount: '95', + currency: 'USD' + }, + payeeFspFee: { + amount: '3', + currency: 'USD' + }, + payeeFspCommission: { + amount: '2', + currency: 'USD' + }, + expiration: '2019-10-30T10:30:19.899Z', + geoCode: { + latitude: '42.69751', + longitude: '23.32415' + }, + ilpPacket: '', + condition: 'HOr22-H3AfTDHrSkPjJtVPRdKouuMkDXTR4ejlQa8Ks', + extensionList: { + extension: [{ + key: 'key1', + value: 'value1' + }] + } + }, + quoteResponse: { + quoteId: 'test123' + }, + rules: [ + { + conditions: { + all: [ + { + fact: 'json-path', + params: { + fact: 'payload', + path: '$.payload.extensionList[?(@.key == "KYCPayerTier")].value' + }, + operator: 'deepEqual', + value: ['1'] + }, + { + fact: 'payload', + path: '.amount.currency', + operator: 'notIn', + value: { + fact: 'json-path', + params: { + fact: 'payee', + path: '$.payee.accounts[?(@.ledgerAccountType == "SETTLEMENT")].currency' + } + } + } + ] + }, + event: { + type: 'INTERCEPT_QUOTE', + params: { + rerouteToFsp: 'DFSPEUR' + } + } + }, + { + conditions: { + all: [ + { + fact: 'json-path', + params: { + fact: 'payload', + path: '$.payload.extensionList[?(@.key == "KYCPayerTier")].value' + }, + operator: 'notDeepEqual', + value: ['1'] + }, + { + fact: 'payload', + path: '.amount.currency', + operator: 'notIn', + value: { + fact: 'json-path', + params: { + fact: 'payee', + path: '$.payee.accounts[?(@.ledgerAccountType == "SETTLEMENT")].currency' + } + } + } + ] + }, + event: { + type: 'INVALID_QUOTE_REQUEST', + params: { + FSPIOPError: 'PAYEE_UNSUPPORTED_CURRENCY', + message: 'The requested payee does not support the payment currency' + } + } + } + ], + scenario: 'fakeScenario', + subScenario: 'fakeSubScenario', + transactionReference: 'fakeTxRef' + } describe('failActionHandler', () => { it('throws the reformatted error', async () => { // Arrange @@ -130,4 +296,156 @@ describe('util', () => { expect(output).toBe(expected) }) }) + + describe('removeEmptyKeys', () => { + it('removes nothing if there are no empty keys', () => { + // Arrange + const input = { + a: 1, + b: 2, + c: 3 + } + const expected = { + a: 1, + b: 2, + c: 3 + } + + // Act + const result = removeEmptyKeys(input) + + // Assert + expect(result).toStrictEqual(expected) + }) + + it('removes a key and if it is undefined', () => { + // Arrange + const input = { + a: 1, + b: 2, + c: undefined + } + const expected = { + a: 1, + b: 2 + } + + // Act + const result = removeEmptyKeys(input) + + // Assert + expect(result).toStrictEqual(expected) + }) + + it('removes an empty key', () => { + // Arrange + const input = { + a: 1, + b: 2, + c: { + + } + } + const expected = { + a: 1, + b: 2 + } + + // Act + const result = removeEmptyKeys(input) + + // Assert + expect(result).toStrictEqual(expected) + }) + + it('removes a nested empty key', () => { + // Arrange + const input = { + a: 1, + b: 2, + c: { + d: { + + } + } + } + const expected = { + a: 1, + b: 2, + c: {} + } + + // Act + const result = removeEmptyKeys(input) + + // Assert + expect(result).toStrictEqual(expected) + }) + }) + + describe('generateRequestHeaders', () => { + it('generates the default request headers', () => { + // Arrange + const expected = { + 'Content-Type': 'application/vnd.interoperability.quotes+json;version=1.0', + 'FSPIOP-Destination': 'dfsp2', + 'FSPIOP-Source': 'dfsp1' + } + + // Act + const result = generateRequestHeaders(mockData.headers, true) + + // Assert + expect(result).toStrictEqual(expected) + }) + + it('generates default request headers, including the Accept', () => { + // Arrange + const expected = { + Accept: 'application/vnd.interoperability.quotes+json;version=1.0', + 'Content-Type': 'application/vnd.interoperability.quotes+json;version=1.0', + 'FSPIOP-Destination': 'dfsp2', + 'FSPIOP-Source': 'dfsp1' + } + + // Act + const result = generateRequestHeaders(mockData.headers, false) + + // Assert + expect(result).toStrictEqual(expected) + }) + }) + + describe('generateRequestHeadersForJWS', () => { + it('generates the default request headers', () => { + // Arrange + const expected = { + 'Content-Type': 'application/vnd.interoperability.quotes+json;version=1.0', + 'fspiop-destination': 'dfsp2', + 'fspiop-source': 'dfsp1' + } + + // Act + const result = generateRequestHeadersForJWS(mockData.headers, true) + + // Assert + expect(result).toStrictEqual(expected) + }) + + it('generates default request headers, including the Accept', () => { + // Arrange + const expected = { + Accept: 'application/vnd.interoperability.quotes+json;version=1.0', + 'Content-Type': 'application/vnd.interoperability.quotes+json;version=1.0', + 'fspiop-destination': 'dfsp2', + 'fspiop-source': 'dfsp1' + } + + // Act + const result = generateRequestHeadersForJWS(mockData.headers, false) + + // Assert + expect(result).toStrictEqual(expected) + }) + }) }) diff --git a/test/unit/model/bulkQuotes.test.js b/test/unit/model/bulkQuotes.test.js new file mode 100644 index 00000000..f3f78095 --- /dev/null +++ b/test/unit/model/bulkQuotes.test.js @@ -0,0 +1,1022 @@ +/***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the 'License') and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + Initial contribution + -------------------- + The initial functionality and code base was donated by the Mowali project working in conjunction with MTN and Orange as service provides. + * Project: Mowali + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * ModusBox + - Rajiv Mothilal + -------------- + ******/ +'use strict' + +// jest has a buggy system for mocking dependencies that can be overcome by mocking +// the target module before requiring it. +// more info on https://github.com/facebook/jest/issues/2582#issuecomment-321607875 +let mockConfig + +jest.mock('axios') +jest.mock('@mojaloop/central-services-logger') +jest.mock('../../../src/data/database') +jest.mock('../../../src/lib/config', () => { + return jest.fn().mockImplementation(() => mockConfig) +}) +jest.mock('../../../src/lib/util') +jest.mock('../../../src/lib/http') + +const axios = require('axios') + +const Enum = require('@mojaloop/central-services-shared').Enum +const LibUtil = require('@mojaloop/central-services-shared').Util +const ErrorHandler = require('@mojaloop/central-services-error-handling') +const EventSdk = require('@mojaloop/event-sdk') +const Logger = require('@mojaloop/central-services-logger') +const JwsSigner = require('@mojaloop/sdk-standard-components').Jws.signer + +const Db = require('../../../src/data/database') +const Config = jest.requireActual('../../../src/lib/config') +const BulkQuotesModel = require('../../../src/model/bulkQuotes') +const Http = require('../../../src/lib/http') +const Util = require('../../../src/lib/util') + +const jwsSigningKey = `-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA0eJEh3Op5p6x137lRkAsvmEBbd32dbRChrCUItZbtxjf/qfB +yD5k8Hn4n4vbqzP8XSGS0f6KmNC+iRaP74HVgzAqc4Uid4J8dtSBq3VmucYQYzLc +101QjuvD+SKmZwlw/q0PtulmqlASI2SbMfwcAraMi6ab7v5W4EGNeIPLEIo3BXsQ +DTCWqiZb7aXkHkcY7sOjAzK/2bNGYFmAthdYrHzvCkqnJ7LAHX3Oj7rJea5MqtuN +B9POZYaD10n9JuYWdwPqLrw6/hVgPSFEy+ulrVbXf54ZH0dfMThAYRvFrT81yulk +H95JhXWGdi6cTp6t8LVOKFhnNfxjWw0Jayj9xwIDAQABAoIBADB2u/Y/CgNbr5sg +DRccqHhJdAgHkep59kadrYch0knEL6zg1clERxCUSYmlxNKSjXp/zyQ4T46b3PNQ +x2m5pDDHxXWpT10jP1Q9G7gYwuCw0IXnb8EzdB+cZ0M28g+myXW1RoSo/nDjTlzn +1UJEgb9Kocd5cFZOWocr+9vRKumlZULMsA8yiNwlAfJHcMBM7acsa3myCqVhLyWt +4BQylVuLFa+A6QzpMXEwFCq8EOXf07gl1XVzC6LJ1fTa9gVM3N+YE+oEXKrsHCxG +/ACgKsjepL27QjJ7qvecWPP0F2LxEZYOm5tbXaKJTobzQUJHgUokanZMhjYprDsZ +zumLw9kCgYEA/DUWcnLeImlfq/EYdhejkl3J+WX3vhS23OqVgY1amu7CZzaai6vt +H0TRc8Zsbi4jgmFDU8PFzytP6qz6Tgom4R736z6oBi7bjnGyN17/NSbf+DaRVcM6 +vnZr7jNC2FJlECmIN+dkwUA/YCr2SA7hxZXM9mIYSc+6+glDiIO5Cf0CgYEA1Qo/ +uQbVHhW+Cp8H0kdMuhwUbkBquRrxRZlXS1Vrf3f9me9JLUy9UPWb3y3sKVurG5+O +SIlr4hDcZyXdE198MtDMhBIGqU9ORSjppJDNDVvtt+n2FD4XmWIU70vKBJBivX0+ +Bow6yduis+p12fuvpvpnKCz8UjOgOQJhLZ4GQBMCgYBP6gpozVjxkm4ML2LO2IKt ++CXtbo/nnOysZ3BkEoQpH4pd5gFmTF3gUJAFnVPyPZBm2abZvejJ0jGKbLELVVAo +eQWZdssK2oIbSo9r2CAJmX3SSogWorvUafWdDoUZwlHfoylUfW+BhHgQYsyS3JRR +ZTwCveZwTPA0FgdeFE7niQKBgQCHaD8+ZFhbCejDqXb4MXdUJ3rY5Lqwsq491YwF +huKPn32iNNQnJcqCxclv3iln1Cr6oLx34Fig1KSyLv/IS32OcuY635Y6UPznumxe +u+aJIjADIILXNOwdAplZy6s4oWkRFaSx1rmbCa3tew2zImTv1eJxR76MpOGmupt3 +uiQw3wKBgFjBT/aVKdBeHeP1rIHHldQV5QQxZNkc6D3qn/oAFcwpj9vcGfRjQWjO +ARzXM2vUWEet4OVn3DXyOdaWFR1ppehz7rAWBiPgsMg4fjAusYb9Mft1GMxMzuwT +Oyqsp6pzAWFrCD3JAoTLxClV+j5m+SXZ/ItD6ziGpl/h7DyayrFZ +-----END RSA PRIVATE KEY-----` + +describe('BulkQuotesModel', () => { + let mockData + let mockTransaction + let mockChildSpan + let mockSpan + let bulkQuotesModel + + mockConfig = new Config() + + beforeEach(() => { + axios.request.mockImplementation((opts) => { + if (opts.url.search('http://invalid.com') === 0) { + return Promise.reject(new Error('Unable to reach host')) + } else if (opts.url.search('http://invalid-response.com') === 0) { + return Promise.resolve({ status: 400 }) + } + if (opts.method === 'POST') { + return Promise.resolve({ status: 202 }) + } else { + return Promise.resolve({ status: 200 }) + } + }) + mockTransaction = { + commit: jest.fn(), + rollback: jest.fn() + } + mockChildSpan = { + injectContextToHttpRequest: jest.fn(opts => opts), + audit: jest.fn(), + isFinished: undefined, + finish: jest.fn() + } + mockSpan = { + getChild: jest.fn(() => mockChildSpan), + error: jest.fn(), + finish: jest.fn() + } + mockData = { + amountTypeId: 'fakeAmountTypeId', + endpoints: { + payerfsp: 'http://localhost:8444/payerfsp', + payeefsp: 'http://localhost:8444/payeefsp', + invalid: 'http://invalid.com/', + invalidResponse: 'http://invalid-response.com/' + }, + geoCode: { + latitude: '42.69751', + longitude: '23.32415' + }, + headers: { + Accept: 'application/vnd.interoperability.quotes+json;version=1.0', + 'Content-Type': 'application/vnd.interoperability.quotes+json;version=1.0', + 'fspiop-source': 'dfsp1', + 'fspiop-destination': 'dfsp2' + }, + initiatorType: 'fakeInitiatorType', + initiator: 'fakeInitiator', + bulkQuoteId: 'test123', + bulkQuotePostRequest: { + bulkQuoteId: 'test123', + payer: { + partyIdInfo: { + partyIdType: 'MSISDN', + partyIdentifier: '27713803905', + fspId: 'dfsp1' + } + }, + individualQuotes: [ + { + quoteId: 'test123', + transactionId: 'abc123', + payee: { + partyIdInfo: { + partyIdType: 'MSISDN', + partyIdentifier: '27824592509', + fspId: 'dfsp2' + } + }, + amountType: 'SEND', + amount: { + amount: 100, + currency: 'USD' + }, + transactionType: { + scenario: 'TRANSFER', + initiator: 'PAYER', + initiatorType: 'CONSUMER' + }, + extensionList: { + extension: [{ + key: 'key1', + value: 'value1' + }] + } + } + ], + geoCode: { + latitude: '43.69751', + longitude: '24.32415' + }, + expiration: '2019-10-30T10:30:19.899Z', + extensionList: { + extension: [{ + key: 'key1', + value: 'value1' + }] + } + }, + bulkQuoteUpdate: { + individualQuotesResults: [{ + bulkQuoteId: 'test123', + payee: { + partyIdInfo: { + partyIdType: 'MSISDN', + partyIdentifier: '27713803905', + fspId: 'dfsp2' + } + }, + transferAmount: { + amount: '100', + currency: 'USD' + }, + payeeReceiveAmount: { + amount: '95', + currency: 'USD' + }, + payeeFspFee: { + amount: '3', + currency: 'USD' + }, + payeeFspCommission: { + amount: '2', + currency: 'USD' + }, + expiration: '2019-10-30T10:30:19.899Z', + ilpPacket: '', + condition: 'HOr22-H3AfTDHrSkPjJtVPRdKouuMkDXTR4ejlQa8Ks', + extensionList: { + extension: [{ + key: 'key1', + value: 'value1' + }] + } + }], + expiration: '2019-10-30T10:30:19.899Z', + extensionList: { + extension: [{ + key: 'key1', + value: 'value1' + }] + } + }, + bulkQuoteResponse: { + bulkQuoteId: 'test123' + }, + scenario: 'fakeScenario', + subScenario: 'fakeSubScenario', + transactionReference: 'fakeTxRef' + } + + bulkQuotesModel = new BulkQuotesModel({ + db: new Db(), + requestId: mockData.bulkQuotePostRequest.bulkQuoteId + }) + bulkQuotesModel.db.newTransaction.mockImplementation(() => mockTransaction) + + bulkQuotesModel.db.createTransactionReference.mockImplementation(() => mockData.transactionReference) + bulkQuotesModel.db.getInitiatorType.mockImplementation(() => mockData.initiatorType) + bulkQuotesModel.db.getInitiator.mockImplementation(() => mockData.initiator) + bulkQuotesModel.db.getScenario.mockImplementation(() => mockData.scenario) + bulkQuotesModel.db.getSubScenario.mockImplementation(() => mockData.subScenario) + bulkQuotesModel.db.getAmountType.mockImplementation(() => mockData.amountTypeId) + bulkQuotesModel.db.createQuote.mockImplementation(() => mockData.bulkQuotePostRequest.quoteId) + bulkQuotesModel.db.createQuoteError.mockImplementation(() => mockData.bulkQuotePostRequest.quoteId) + bulkQuotesModel.db.createPayerQuoteParty.mockImplementation(() => mockData.bulkQuotePostRequest.payer.partyIdInfo.fspId) + bulkQuotesModel.db.createPayeeQuoteParty.mockImplementation(() => mockData.bulkQuotePostRequest.payee.partyIdInfo.fspId) + bulkQuotesModel.db.createGeoCode.mockImplementation(() => mockData.geoCode) + bulkQuotesModel.db.createQuoteExtensions.mockImplementation(() => mockData.bulkQuotePostRequest.extensionList.extension) + + // make all methods of the quotesModel instance be a mock. This helps us re-mock in every + // method's test suite. + const propertyNames = Object.getOwnPropertyNames(BulkQuotesModel.prototype) + propertyNames.forEach((methodName) => { + jest.spyOn(bulkQuotesModel, methodName).mockImplementation(() => { + return {} + }) + }) + }) + afterEach(() => { + // Clears the mock.calls and mock.instances properties of all mocks. + // Equivalent to calling .mockClear() on every mocked function. + jest.clearAllMocks() + + // reset the configuration values to their initials + mockConfig = new Config() + }) + + describe('validateBulkQuoteRequest', () => { + beforeEach(() => { + // restore the current method in test to its original implementation + bulkQuotesModel.validateBulkQuoteRequest.mockRestore() + }) + + it('should validate fspiopSource and fspiopDestination', async () => { + expect.assertions(5) + + const fspiopSource = 'dfsp1' + const fspiopDestination = 'dfsp2' + + expect(bulkQuotesModel.db.getParticipant).not.toHaveBeenCalled() // Validates mockClear() + + await bulkQuotesModel.validateBulkQuoteRequest(fspiopSource, fspiopDestination, mockData.bulkQuotePostRequest) + + expect(bulkQuotesModel.db).toBeTruthy() // Constructor should have been called + expect(bulkQuotesModel.db.getParticipant).toHaveBeenCalledTimes(2) + expect(bulkQuotesModel.db.getParticipant.mock.calls[0][0]).toBe(fspiopSource) + expect(bulkQuotesModel.db.getParticipant.mock.calls[1][0]).toBe(fspiopDestination) + }) + }) + + describe('handleBulkQuoteRequest', () => { + beforeEach(() => { + // restore the current method in test to its original implementation + bulkQuotesModel.handleBulkQuoteRequest.mockRestore() + }) + + describe('Failures:', () => { + describe('Before forwarding the request:', () => { + it('throws an exception if `validateQuoteRequest` fails', async () => { + expect.assertions(1) + + const fspiopError = ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR) + + bulkQuotesModel.validateBulkQuoteRequest = jest.fn(() => { throw fspiopError }) + + await bulkQuotesModel.handleBulkQuoteRequest(mockData.headers, mockData.bulkQuotePostRequest, mockSpan) + expect(bulkQuotesModel.handleException).toHaveBeenCalledTimes(1) + }) + it('throws an exception if `span.getChild` fails', async () => { + expect.assertions(2) + + const spanError = new Error('foo') + mockSpan.getChild = jest.fn(() => { throw spanError }) + mockSpan.isFinished = false + await bulkQuotesModel.handleBulkQuoteRequest(mockData.headers, mockData.bulkQuotePostRequest, mockSpan) + expect(bulkQuotesModel.handleException).toHaveBeenCalledTimes(1) + expect(mockSpan.getChild.mock.calls.length).toBe(1) + }) + }) + describe('While forwarding the request:', () => { + describe('In case environment is configured for simple routing mode', () => { + beforeEach(() => { + mockConfig.simpleRoutingMode = true + }) + + it('calls `handleException` with the proper arguments if `span.audit` fails', async () => { + expect.assertions(4) + + const spanError = new Error('foo') + const fspiopError = ErrorHandler.ReformatFSPIOPError(spanError) + mockChildSpan.audit = jest.fn(() => { throw spanError }) + + const expectedHandleExceptionArgs = [mockData.headers['fspiop-source'], mockData.bulkQuoteId, fspiopError, mockData.headers, + mockChildSpan] + + const result = await bulkQuotesModel.handleBulkQuoteRequest(mockData.headers, mockData.bulkQuotePostRequest, mockSpan) + + expect(mockChildSpan.audit.mock.calls.length).toBe(1) + expect(bulkQuotesModel.handleException).toBeCalledWith(...expectedHandleExceptionArgs) + expect(bulkQuotesModel.handleException.mock.calls.length).toBe(1) + expect(result).toEqual({}) + }) + + it('calls `handleException` with the proper arguments if `forwardBulkQuoteRequest` fails', async () => { + expect.assertions(6) + + const fspiopError = ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR) + + bulkQuotesModel.forwardBulkQuoteRequest = jest.fn(() => { throw fspiopError }) + + const expectedHandleExceptionArgs = [mockData.headers['fspiop-source'], mockData.bulkQuoteId, fspiopError, mockData.headers, + mockChildSpan] + const expectedForwardQuoteRequestArgs = [mockData.headers, mockData.bulkQuotePostRequest.bulkQuoteId, mockData.bulkQuotePostRequest, mockChildSpan] + + const result = await bulkQuotesModel.handleBulkQuoteRequest(mockData.headers, mockData.bulkQuotePostRequest, mockSpan) + + expect(mockChildSpan.audit.mock.calls.length).toBe(1) + expect(bulkQuotesModel.forwardBulkQuoteRequest.mock.calls.length).toBe(1) + expect(bulkQuotesModel.forwardBulkQuoteRequest).toBeCalledWith(...expectedForwardQuoteRequestArgs) + expect(bulkQuotesModel.handleException).toBeCalledWith(...expectedHandleExceptionArgs) + expect(bulkQuotesModel.handleException.mock.calls.length).toBe(1) + expect(result).toEqual({}) + }) + }) + }) + }) + describe('Success:', () => { + describe('While forwarding the request:', () => { + describe('In case environment is configured for simple routing mode', () => { + it('forwards the bulk quote request properly', async () => { + expect.assertions(5) + + mockChildSpan.isFinished = false + + const result = await bulkQuotesModel.handleBulkQuoteRequest(mockData.headers, mockData.bulkQuotePostRequest, mockSpan) + + const expectedValidateQuoteRequestArgs = [mockData.headers['fspiop-source'], mockData.headers['fspiop-destination'], mockData.bulkQuotePostRequest] + expect(bulkQuotesModel.validateBulkQuoteRequest).toBeCalledWith(...expectedValidateQuoteRequestArgs) + expect(mockSpan.getChild.mock.calls.length).toBe(1) + + const expectedAuditArgs = [{ headers: mockData.headers, payload: mockData.bulkQuotePostRequest }, EventSdk.AuditEventAction.start] + expect(mockChildSpan.audit).toBeCalledWith(...expectedAuditArgs) + + const expectedForwardRequestArgs = [mockData.headers, mockData.bulkQuotePostRequest.bulkQuoteId, mockData.bulkQuotePostRequest, mockChildSpan] + expect(bulkQuotesModel.forwardBulkQuoteRequest).toBeCalledWith(...expectedForwardRequestArgs) + expect(result).toEqual({}) + }) + }) + }) + }) + }) + + describe('forwardBulkQuoteRequest', () => { + beforeEach(() => { + // restore the current method in test to its original implementation + bulkQuotesModel.forwardBulkQuoteRequest.mockRestore() + }) + + it('should get http status code 202 Accepted in simple routing mode', async () => { + expect.assertions(2) + mockConfig.simpleRoutingMode = true + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) + + await bulkQuotesModel.forwardBulkQuoteRequest(mockData.headers, mockData.bulkQuotePostRequest.bulkQuoteId, mockData.bulkQuotePostRequest, mockChildSpan) + + expect(bulkQuotesModel.db.getParticipantEndpoint).toBeCalled() + expect(bulkQuotesModel.db.getQuotePartyEndpoint).not.toBeCalled() + }) + it('should throw when participant endpoint is not found', async () => { + expect.assertions(1) + + mockConfig.simpleRoutingMode = false + + bulkQuotesModel.db.getQuotePartyEndpoint.mockReturnValueOnce(undefined) + + await expect(bulkQuotesModel.forwardBulkQuoteRequest(mockData.headers, mockData.bulkQuotePostRequest.bulkQuoteId, mockData.bulkQuotePostRequest)) + .rejects + .toHaveProperty('apiErrorCode.code', ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR.code) + }) + }) + + describe('handleBulkQuoteUpdate', () => { + beforeEach(() => { + // restore the current method in test to its original implementation + bulkQuotesModel.handleBulkQuoteUpdate.mockRestore() + }) + + it('should forward quote update in simple routing mode', async () => { + expect.assertions(3) + mockChildSpan.isFinished = false + await bulkQuotesModel.handleBulkQuoteUpdate(mockData.headers, mockData.bulkQuoteId, mockData.bulkQuoteUpdate, mockSpan) + expect(mockSpan.getChild.mock.calls.length).toBe(1) + let args = [{ headers: mockData.headers, params: { bulkQuoteId: mockData.bulkQuotePostRequest.bulkQuoteId }, payload: mockData.bulkQuoteUpdate }, EventSdk.AuditEventAction.start] + expect(mockChildSpan.audit).toBeCalledWith(...args) + args = [mockData.headers, mockData.bulkQuoteId, mockData.bulkQuoteUpdate, mockChildSpan] + expect(bulkQuotesModel.forwardBulkQuoteUpdate).toBeCalledWith(...args) + }) + it('should handle exception', async () => { + expect.assertions(5) + + const fspiopError = ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR) + bulkQuotesModel.forwardBulkQuoteUpdate = jest.fn(() => { throw fspiopError }) + mockChildSpan.isFinished = false + await bulkQuotesModel.handleBulkQuoteUpdate(mockData.headers, mockData.bulkQuoteId, mockData.bulkQuoteUpdate, mockSpan) + expect(mockSpan.getChild.mock.calls.length).toBe(1) + let args = [{ headers: mockData.headers, params: { bulkQuoteId: mockData.bulkQuotePostRequest.bulkQuoteId }, payload: mockData.bulkQuoteUpdate }, EventSdk.AuditEventAction.start] + expect(mockChildSpan.audit).toBeCalledWith(...args) + args = [mockData.headers, mockData.bulkQuoteId, mockData.bulkQuoteUpdate, mockChildSpan] + expect(bulkQuotesModel.forwardBulkQuoteUpdate).toBeCalledWith(...args) + args = [mockData.headers['fspiop-source'], mockData.bulkQuoteId, fspiopError, mockData.headers, mockChildSpan] + expect(bulkQuotesModel.handleException).toBeCalledWith(...args) + expect(bulkQuotesModel.handleException.mock.calls.length).toBe(1) + }) + it('should throw validationError when headers contains accept', async () => { + expect.assertions(3) + + const localHeaders = LibUtil.clone(mockData.headers) + localHeaders.accept = 'application/vnd.interoperability.quotes+json;version=1.0' + + await expect(bulkQuotesModel.handleBulkQuoteUpdate(localHeaders, mockData.bulkQuoteId, mockData.bulkQuoteUpdate)) + .rejects + .toHaveProperty('apiErrorCode.code', ErrorHandler.Enums.FSPIOPErrorCodes.VALIDATION_ERROR.code) + + expect(bulkQuotesModel.db.newTransaction.mock.calls.length).toBe(0) + expect(mockTransaction.rollback.mock.calls.length).toBe(0) + }) + }) + + describe('forwardQuoteUpdate', () => { + beforeEach(() => { + // restore the current method in test to its original implementation + bulkQuotesModel.forwardBulkQuoteUpdate.mockRestore() + }) + + it('should get http status code 200 OK in simple routing mode', async () => { + expect.assertions(2) + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) + + await expect(bulkQuotesModel.forwardBulkQuoteUpdate(mockData.headers, mockData.bulkQuoteId, mockData.bulkQuoteUpdate, mockChildSpan)) + .resolves + .toBe(undefined) + + expect(bulkQuotesModel.db.getParticipantEndpoint).toBeCalled() + }) + it('should throw when participant endpoint is not found', async () => { + expect.assertions(1) + + const endpoint = undefined + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(endpoint) + bulkQuotesModel.sendErrorCallback = jest.fn((_, fspiopError) => { throw fspiopError }) + + await expect(bulkQuotesModel.forwardBulkQuoteUpdate(mockData.headers, mockData.bulkQuoteId, mockData.bulkQuoteUpdate, mockChildSpan)) + .rejects + .toHaveProperty('apiErrorCode.code', ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR.code) + }) + it('should not use spans when undefined and should throw when participant endpoint is invalid', async () => { + expect.assertions(3) + + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.invalid) + Http.httpRequest.mockImplementationOnce(() => { throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_COMMUNICATION_ERROR) }) + + await expect(bulkQuotesModel.forwardBulkQuoteUpdate(mockData.headers, mockData.bulkQuoteId, mockData.bulkQuoteUpdate)) + .rejects + .toHaveProperty('apiErrorCode.code', ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_COMMUNICATION_ERROR.code) + + expect(mockChildSpan.injectContextToHttpRequest).not.toHaveBeenCalled() + expect(mockChildSpan.audit).not.toHaveBeenCalled() + }) + it('should throw when participant endpoint returns invalid response', async () => { + expect.assertions(3) + + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.invalidResponse) + Http.httpRequest.mockImplementationOnce(() => { throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_COMMUNICATION_ERROR) }) + + await expect(bulkQuotesModel.forwardBulkQuoteUpdate(mockData.headers, mockData.bulkQuoteId, mockData.bulkQuoteUpdate)) + .rejects + .toHaveProperty('apiErrorCode.code', ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_COMMUNICATION_ERROR.code) + + expect(mockChildSpan.injectContextToHttpRequest).not.toHaveBeenCalled() + expect(mockChildSpan.audit).not.toHaveBeenCalled() + }) + it('should inspect and throw custom error as FSPIOPerror', async () => { + expect.assertions(3) + + const customErrorNoStack = new Error('Custom error') + delete customErrorNoStack.stack + bulkQuotesModel.db.getParticipantEndpoint.mockRejectedValueOnce(customErrorNoStack) + + await expect(bulkQuotesModel.forwardBulkQuoteUpdate(mockData.headers, mockData.bulkQuoteId, mockData.bulkQuoteUpdate)) + .rejects + .toHaveProperty('apiErrorCode.code', ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR.code) + + expect(mockChildSpan.injectContextToHttpRequest).not.toHaveBeenCalled() + expect(mockChildSpan.audit).not.toHaveBeenCalled() + }) + }) + + describe('handleBulkQuoteGet', () => { + beforeEach(() => { + // restore the current method in test to its original implementation + bulkQuotesModel.handleBulkQuoteGet.mockRestore() + }) + + it('handles the bulk quote get with a child span', async () => { + // Arrange + expect.assertions(3) + + // Act + await bulkQuotesModel.handleBulkQuoteGet(mockData.headers, mockData.bulkQuoteId, mockSpan) + + // Assert + expect(mockChildSpan.audit.mock.calls.length).toBe(1) + expect(mockChildSpan.finish.mock.calls.length).toBe(1) + expect(bulkQuotesModel.forwardBulkQuoteGet.mock.calls.length).toBe(1) + }) + + it('handles an exception on `span.getChild`', async () => { + // Arrange + expect.assertions(1) + mockSpan.getChild = jest.fn(() => { throw new Error('Test Error') }) + + // Act + const action = async () => bulkQuotesModel.handleBulkQuoteGet(mockData.headers, mockData.bulkQuoteId, mockSpan) + + // Assert + await expect(action()).rejects.toThrowError('Test Error') + }) + + it('handles an exception on `childSpan.audit`', async () => { + // Arrange + expect.assertions(2) + mockChildSpan.audit = jest.fn(() => { throw new Error('Test Error') }) + + // Act + await bulkQuotesModel.handleBulkQuoteGet(mockData.headers, mockData.bulkQuoteId, mockSpan) + + // Assert + expect(mockChildSpan.finish.mock.calls.length).toBe(1) + expect(bulkQuotesModel.handleException.mock.calls.length).toBe(1) + }) + }) + + describe('forwardQuoteGet', () => { + beforeEach(() => { + // restore the current method in test to its original implementation + bulkQuotesModel.forwardBulkQuoteGet.mockRestore() + }) + + it('fails to forward if the database has no endpoint for the dfsp', async () => { + // Arrange + expect.assertions(1) + bulkQuotesModel.db.getParticipantEndpoint.mockImplementation(() => null) + + // Act + const action = async () => bulkQuotesModel.forwardBulkQuoteGet(mockData.headers, mockData.bulkQuoteId, mockSpan) + + // Assert + await expect(action()).rejects.toThrowError('No FSPIOP_CALLBACK_URL_BULK_QUOTES found for bulk quote GET test123') + }) + + it('forwards the request to the payee dfsp without a span', async () => { + // Arrange + // expect.assertions(2) + bulkQuotesModel.db.getParticipantEndpoint.mockImplementation(() => 'http://localhost:3333') + const expectedOptions = { + headers: {}, + method: 'GET', + url: 'http://localhost:3333/bulkQuotes/test123' + } + Util.generateRequestHeaders.mockImplementationOnce(() => { + return {} + }) + // Act + await bulkQuotesModel.forwardBulkQuoteGet(mockData.headers, mockData.bulkQuoteId) + + // Assert + expect(Http.httpRequest).toBeCalledTimes(1) + expect(Http.httpRequest).toBeCalledWith(expectedOptions, mockData.headers[Enum.Http.Headers.FSPIOP.SOURCE]) + }) + + it('forwards the request to the payee dfsp', async () => { + // Arrange + expect.assertions(4) + bulkQuotesModel.db.getParticipantEndpoint.mockImplementation(() => 'http://localhost:3333') + mockSpan.injectContextToHttpRequest = jest.fn().mockImplementation(() => ({ + headers: { + spanHeaders: '12345' + } + })) + mockSpan.audit = jest.fn() + const expectedOptions = { + headers: { + spanHeaders: '12345' + } + } + + // Act + await bulkQuotesModel.forwardBulkQuoteGet(mockData.headers, mockData.bulkQuoteId, mockSpan) + + // Assert + expect(mockSpan.injectContextToHttpRequest).toBeCalledTimes(1) + expect(mockSpan.audit).toBeCalledTimes(1) + expect(Http.httpRequest).toBeCalledTimes(1) + expect(Http.httpRequest).toBeCalledWith(expectedOptions, mockData.headers[Enum.Http.Headers.FSPIOP.SOURCE]) + }) + + it('handles a http error', async () => { + // Arrange + expect.assertions(1) + bulkQuotesModel.db.getParticipantEndpoint.mockImplementation(() => 'http://localhost:3333') + Http.httpRequest.mockImplementationOnce(() => { throw new Error('Test HTTP Error') }) + + // Act + const action = async () => bulkQuotesModel.forwardBulkQuoteGet(mockData.headers, mockData.bulkQuoteId) + + // Assert + await expect(action()).rejects.toThrowError('Test HTTP Error') + }) + }) + + describe('handleBulkQuoteError', () => { + beforeEach(() => { + // restore the current method in test to its original implementation + bulkQuotesModel.handleBulkQuoteError.mockRestore() + }) + + it('handles the quote error', async () => { + // Arrange + expect.assertions(2) + const error = { + errorCode: 2001, + errorDescription: 'Test Error' + } + + // Act + const result = await bulkQuotesModel.handleBulkQuoteError(mockData.headers, mockData.bulkQuoteId, error, mockSpan) + + // Assert + // For `handleQuoteError` response is undefined + expect(result).toBe(undefined) + expect(bulkQuotesModel.sendErrorCallback).toHaveBeenCalledTimes(1) + }) + + it('sends the error callback to the correct destination', async () => { + // Arrange + expect.assertions(3) + const error = { + errorCode: 2001, + errorDescription: 'Test Error' + } + bulkQuotesModel.sendErrorCallback = jest.fn() + + // Act + const result = await bulkQuotesModel.handleBulkQuoteError(mockData.headers, mockData.bulkQuoteId, error, mockSpan) + + // Assert + // For `handleQuoteError` response is undefined + expect(result).toBe(undefined) + expect(bulkQuotesModel.sendErrorCallback).toHaveBeenCalledTimes(1) + expect(bulkQuotesModel.sendErrorCallback.mock.calls[0][0]) + .toEqual(mockData.headers[Enum.Http.Headers.FSPIOP.DESTINATION]) + }) + + it('handles bad error input', async () => { + // Arrange + expect.assertions(1) + const error = { + errorDescription: 'Test Error' + } + + // Act + const action = async () => bulkQuotesModel.handleBulkQuoteError(mockData.headers, mockData.bulkQuoteId, error, mockSpan) + await action() + // const es = 'Factory function createFSPIOPError failed due to apiErrorCode being invalid' + // Assert + expect(bulkQuotesModel.handleException).toHaveBeenCalledTimes(1) + }) + }) + + describe('handleException', () => { + beforeEach(() => { + // restore the current method in test to its original implementation + bulkQuotesModel.handleException.mockRestore() + }) + + it('handles the error and finishes the child span', async () => { + // Arrange + expect.assertions(3) + const error = new Error('Test Error') + const expectedError = ErrorHandler.ReformatFSPIOPError(error) + bulkQuotesModel.sendErrorCallback.mockImplementationOnce(() => true) + + // Act + const result = await bulkQuotesModel.handleException('payeefsp', mockData.bulkQuoteId, error, mockData.headers, mockSpan) + + // Assert + expect(bulkQuotesModel.sendErrorCallback).toHaveBeenCalledWith('payeefsp', expectedError, mockData.bulkQuoteId, mockData.headers, mockChildSpan, true) + expect(result).toBe(true) + expect(mockChildSpan.finish).toHaveBeenCalledTimes(1) + }) + + it('handles an error in sendErrorCallback', async () => { + // Arrange + expect.assertions(3) + const error = new Error('Test Error') + const expectedError = ErrorHandler.ReformatFSPIOPError(error) + bulkQuotesModel.sendErrorCallback.mockImplementationOnce(() => { throw new Error('Error sending callback.') }) + + // Act + await bulkQuotesModel.handleException('payeefsp', mockData.bulkQuoteId, error, mockData.headers, mockSpan) + + // Assert + expect(bulkQuotesModel.sendErrorCallback).toHaveBeenCalledWith('payeefsp', expectedError, mockData.bulkQuoteId, mockData.headers, mockChildSpan, true) + expect(bulkQuotesModel.writeLog).toHaveBeenCalledTimes(1) + expect(mockChildSpan.finish).toHaveBeenCalledTimes(1) + }) + }) + + describe('sendErrorCallback', () => { + beforeEach(() => { + // restore the current method in test to its original implementation + bulkQuotesModel.sendErrorCallback.mockRestore() + }) + + it('sends the error callback without a span', async () => { + // Arrange + expect.assertions(1) + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) + Util.generateRequestHeaders.mockReturnValueOnce({}) + const error = new Error('Test Error') + const fspiopError = ErrorHandler.ReformatFSPIOPError(error) + const expectedOptions = { + method: Enum.Http.RestMethods.PUT, + url: 'http://localhost:8444/payeefsp/bulkQuotes/test123/error', + data: JSON.stringify(fspiopError.toApiErrorObject(mockConfig.errorHandling), LibUtil.getCircularReplacer()), + headers: {} + } + + // Act + await bulkQuotesModel.sendErrorCallback('payeefsp', fspiopError, mockData.bulkQuoteId, mockData.headers) + + // Assert + expect(axios.request).toBeCalledWith(expectedOptions) + }) + + it('sends the error callback and handles the span', async () => { + // Arrange + expect.assertions(3) + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) + Util.generateRequestHeaders.mockReturnValueOnce({}) + const error = new Error('Test Error') + const fspiopError = ErrorHandler.ReformatFSPIOPError(error) + mockSpan.injectContextToHttpRequest = jest.fn().mockImplementation(() => ({ + headers: { + spanHeaders: '12345' + }, + method: Enum.Http.RestMethods.PUT, + url: 'http://localhost:8444/payeefsp/quotes/test123/error', + data: {} + })) + mockSpan.audit = jest.fn() + const expectedOptions = { + method: Enum.Http.RestMethods.PUT, + url: 'http://localhost:8444/payeefsp/quotes/test123/error', + data: {}, + headers: { + spanHeaders: '12345' + } + } + + // Act + await bulkQuotesModel.sendErrorCallback('payeefsp', fspiopError, mockData.bulkQuoteId, mockData.headers, mockSpan) + + // Assert + expect(mockSpan.injectContextToHttpRequest).toBeCalledTimes(1) + expect(mockSpan.audit).toBeCalledTimes(1) + expect(axios.request).toBeCalledWith(expectedOptions) + }) + + it('sends the error callback JWS signed', async () => { + // Arrange + const jwsSignSpy = jest.spyOn(JwsSigner.prototype, 'getSignature') + // expect.assertions(6) + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) + Util.generateRequestHeaders.mockReturnValueOnce({}) + const error = new Error('Test Error') + const fspiopError = ErrorHandler.ReformatFSPIOPError(error) + mockSpan.injectContextToHttpRequest = jest.fn().mockImplementation(() => ({ + headers: { + spanHeaders: '12345', + 'fspiop-source': 'switch', + 'fspiop-destination': 'dfsp2' + }, + method: Enum.Http.RestMethods.PUT, + url: 'http://localhost:8444/payeefsp/quotes/test123/error', + data: {} + })) + mockSpan.audit = jest.fn() + mockConfig.jws.jwsSign = true + mockConfig.jws.jwsSigningKey = jwsSigningKey + // Act + await bulkQuotesModel.sendErrorCallback('payeefsp', fspiopError, mockData.bulkQuoteId, mockData.headers, mockSpan, true) + // Assert + expect(mockSpan.injectContextToHttpRequest).toBeCalledTimes(1) + expect(mockSpan.audit).toBeCalledTimes(1) + expect(jwsSignSpy).toBeCalledTimes(1) + expect(axios.request.mock.calls[0][0].headers).toHaveProperty('fspiop-signature') + expect(axios.request.mock.calls[0][0].headers['fspiop-signature']).toEqual(expect.stringContaining('signature')) + expect(axios.request.mock.calls[0][0].headers['fspiop-signature']).toEqual(expect.stringContaining('protectedHeader')) + jwsSignSpy.mockRestore() + }) + + it('sends the error callback NOT JWS signed', async () => { + // Arrange + const jwsSignSpy = jest.spyOn(JwsSigner.prototype, 'getSignature') + expect.assertions(5) + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) + Util.generateRequestHeaders.mockReturnValueOnce({}) + const error = new Error('Test Error') + const fspiopError = ErrorHandler.ReformatFSPIOPError(error) + mockSpan.injectContextToHttpRequest = jest.fn().mockImplementation(() => ({ + headers: { + spanHeaders: '12345', + 'fspiop-source': 'switch', + 'fspiop-destination': 'dfsp2' + }, + method: Enum.Http.RestMethods.PUT, + url: 'http://localhost:8444/payeefsp/quotes/test123/error', + data: {} + })) + mockSpan.audit = jest.fn() + const expectedOptions = { + method: Enum.Http.RestMethods.PUT, + url: 'http://localhost:8444/payeefsp/quotes/test123/error', + data: {}, + headers: { + spanHeaders: '12345', + 'fspiop-source': 'switch', + 'fspiop-destination': 'dfsp2' + } + } + mockConfig.jws.jwsSign = false + // Act + await bulkQuotesModel.sendErrorCallback('payeefsp', fspiopError, mockData.bulkQuoteId, mockData.headers, mockSpan, true) + // Assert + expect(mockSpan.injectContextToHttpRequest).toBeCalledTimes(1) + expect(mockSpan.audit).toBeCalledTimes(1) + expect(jwsSignSpy).not.toHaveBeenCalled() + expect(axios.request.mock.calls[0][0].headers).not.toHaveProperty('fspiop-signature') + expect(axios.request).toBeCalledWith(expectedOptions) + jwsSignSpy.mockRestore() + }) + + it('sends the error callback NOT JWS signed', async () => { + // Arrange + const jwsSignSpy = jest.spyOn(JwsSigner.prototype, 'getSignature') + expect.assertions(5) + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) + Util.generateRequestHeaders.mockReturnValueOnce({}) + const error = new Error('Test Error') + const fspiopError = ErrorHandler.ReformatFSPIOPError(error) + mockSpan.injectContextToHttpRequest = jest.fn().mockImplementation(() => ({ + headers: { + spanHeaders: '12345', + 'fspiop-source': 'switch', + 'fspiop-destination': 'dfsp2' + }, + method: Enum.Http.RestMethods.PUT, + url: 'http://localhost:8444/payeefsp/quotes/test123/error', + data: {} + })) + mockSpan.audit = jest.fn() + const expectedOptions = { + method: Enum.Http.RestMethods.PUT, + url: 'http://localhost:8444/payeefsp/quotes/test123/error', + data: {}, + headers: { + spanHeaders: '12345', + 'fspiop-source': 'switch', + 'fspiop-destination': 'dfsp2' + } + } + mockConfig.jws.jwsSign = false + // Act + await bulkQuotesModel.sendErrorCallback('payeefsp', fspiopError, mockData.bulkQuoteId, mockData.headers, mockSpan, false) + // Assert + expect(mockSpan.injectContextToHttpRequest).toBeCalledTimes(1) + expect(mockSpan.audit).toBeCalledTimes(1) + expect(jwsSignSpy).not.toHaveBeenCalled() + expect(axios.request.mock.calls[0][0].headers).not.toHaveProperty('fspiop-signature') + expect(axios.request).toBeCalledWith(expectedOptions) + jwsSignSpy.mockRestore() + }) + + it('handles when the endpoint could not be found', async () => { + // Arrange + expect.assertions(2) + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(undefined) + Util.generateRequestHeaders.mockReturnValueOnce({}) + const error = new Error('Test Error') + const fspiopError = ErrorHandler.ReformatFSPIOPError(error) + + // Act + const action = async () => bulkQuotesModel.sendErrorCallback('payeefsp', fspiopError, mockData.bulkQuoteId, mockData.headers, mockSpan) + + // Assert + await expect(action()).rejects.toThrow('No FSPIOP_CALLBACK_URL_BULK_QUOTES found for payeefsp unable to make error callback') + expect(axios.request).not.toHaveBeenCalled() + }) + + it('handles a http exception', async () => { + // Arrange + expect.assertions(2) + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) + Util.generateRequestHeaders.mockReturnValueOnce({}) + const error = new Error('Test Error') + const fspiopError = ErrorHandler.ReformatFSPIOPError(error) + axios.request.mockImplementationOnce(() => { throw new Error('HTTP test error') }) + + // Act + const action = async () => bulkQuotesModel.sendErrorCallback('payeefsp', fspiopError, mockData.bulkQuoteId, mockData.headers) + + // Assert + await expect(action()).rejects.toThrow('network error in sendErrorCallback: HTTP test error') + expect(axios.request).toHaveBeenCalledTimes(1) + }) + + it('handles a http bad status code', async () => { + // Arrange + expect.assertions(2) + bulkQuotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) + Util.generateRequestHeaders.mockReturnValueOnce({}) + const error = new Error('Test Error') + const fspiopError = ErrorHandler.ReformatFSPIOPError(error) + axios.request.mockReturnValueOnce({ + status: Enum.Http.ReturnCodes.BADREQUEST.CODE + }) + + // Act + const action = async () => bulkQuotesModel.sendErrorCallback('payeefsp', fspiopError, mockData.bulkQuoteId, mockData.headers) + + // Assert + await expect(action()).rejects.toThrow('Got non-success response sending error callback') + expect(axios.request).toHaveBeenCalledTimes(1) + }) + }) + + describe('writeLog', () => { + beforeEach(() => { + // restore the current method in test to its original implementation + bulkQuotesModel.writeLog.mockRestore() + }) + + it('writes to the log', () => { + // Arrange + // Act + bulkQuotesModel.writeLog('test message') + + // Assert + expect(Logger.info).toBeCalledTimes(1) + }) + }) +}) diff --git a/test/unit/model/quotes.test.js b/test/unit/model/quotes.test.js index ff06a83b..6d8911a6 100644 --- a/test/unit/model/quotes.test.js +++ b/test/unit/model/quotes.test.js @@ -47,6 +47,7 @@ jest.mock('../../../src/model/rules') jest.mock('../../../src/lib/config', () => { return jest.fn().mockImplementation(() => mockConfig) }) +jest.mock('../../../src/lib/util') jest.mock('../../../src/lib/http') const axios = require('axios') @@ -65,6 +66,7 @@ const QuotesModel = require('../../../src/model/quotes') const rules = require('../../../config/rules') const RulesEngine = require('../../../src/model/rules') const Http = require('../../../src/lib/http') +const Util = require('../../../src/lib/util') const jwsSigningKey = `-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEA0eJEh3Op5p6x137lRkAsvmEBbd32dbRChrCUItZbtxjf/qfB @@ -116,7 +118,6 @@ describe('QuotesModel', () => { return Promise.resolve({ status: 200 }) } }) - mockTransaction = { commit: jest.fn(), rollback: jest.fn() @@ -744,7 +745,7 @@ describe('QuotesModel', () => { const fspiopError = ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR) - quotesModel.calculateRequestHash = jest.fn(() => { throw fspiopError }) + Util.calculateRequestHash.mockImplementationOnce(() => { throw fspiopError }) await expect(quotesModel.handleQuoteRequest(mockData.headers, mockData.quoteRequest, mockSpan)) .rejects @@ -1114,7 +1115,7 @@ describe('QuotesModel', () => { it('calls all database create entity methods with correct arguments', async () => { expect.assertions(8) - const expectedHash = quotesModel.calculateRequestHash(mockData.quoteRequest) + const expectedHash = Util.calculateRequestHash(mockData.quoteRequest) const mockCreateQuoteDuplicateCheckArgs = [mockTransaction, mockData.quoteRequest.quoteId, expectedHash] const mockCreateTransactionReferenceArgs = [mockTransaction, mockData.quoteRequest.quoteId, @@ -1428,7 +1429,7 @@ describe('QuotesModel', () => { mockConfig.simpleRoutingMode = false quotesModel.checkDuplicateQuoteResponse = jest.fn(() => { return { isDuplicateId: false, isResend: false } }) - quotesModel.calculateRequestHash = jest.fn(() => 'hash') + Util.calculateRequestHash = jest.fn(() => 'hash') const mockQuoteResponseId = 'resp123' @@ -1472,7 +1473,7 @@ describe('QuotesModel', () => { mockConfig.simpleRoutingMode = false quotesModel.checkDuplicateQuoteResponse = jest.fn(() => { return { isDuplicateId: false, isResend: false } }) - quotesModel.calculateRequestHash = jest.fn(() => 'hash') + Util.calculateRequestHash = jest.fn(() => 'hash') const expected = { quoteResponseId: 'resp123', geoCodeId: 'geoCodeId', @@ -1502,7 +1503,7 @@ describe('QuotesModel', () => { mockConfig.simpleRoutingMode = false quotesModel.checkDuplicateQuoteResponse = jest.fn(() => { return { isDuplicateId: false, isResend: false } }) - quotesModel.calculateRequestHash = jest.fn(() => 'hash') + Util.calculateRequestHash = jest.fn(() => 'hash') const expected = { quoteResponseId: 'resp123', geoCodeId: 'geoCodeId', @@ -1533,7 +1534,7 @@ describe('QuotesModel', () => { mockConfig.simpleRoutingMode = false quotesModel.checkDuplicateQuoteResponse = jest.fn(() => { return { isDuplicateId: false, isResend: false } }) - quotesModel.calculateRequestHash = jest.fn(() => 'hash') + Util.calculateRequestHash = jest.fn(() => 'hash') const expected = { quoteResponseId: 'resp123', geoCodeId: 'geoCodeId' @@ -1910,7 +1911,9 @@ describe('QuotesModel', () => { method: 'GET', url: 'http://localhost:3333/quotes/test123' } - + Util.generateRequestHeaders.mockImplementationOnce(() => { + return {} + }) // Act await quotesModel.forwardQuoteGet(mockData.headers, mockData.quoteId) @@ -2008,7 +2011,7 @@ describe('QuotesModel', () => { // Arrange expect.assertions(1) quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) - quotesModel.generateRequestHeaders.mockReturnValueOnce({}) + Util.generateRequestHeaders.mockReturnValueOnce({}) const error = new Error('Test Error') const fspiopError = ErrorHandler.ReformatFSPIOPError(error) const expectedOptions = { @@ -2029,7 +2032,7 @@ describe('QuotesModel', () => { // Arrange expect.assertions(3) quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) - quotesModel.generateRequestHeaders.mockReturnValueOnce({}) + Util.generateRequestHeaders.mockReturnValueOnce({}) const error = new Error('Test Error') const fspiopError = ErrorHandler.ReformatFSPIOPError(error) mockSpan.injectContextToHttpRequest = jest.fn().mockImplementation(() => ({ @@ -2064,7 +2067,7 @@ describe('QuotesModel', () => { const jwsSignSpy = jest.spyOn(JwsSigner.prototype, 'getSignature') // expect.assertions(6) quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) - quotesModel.generateRequestHeaders.mockReturnValueOnce({}) + Util.generateRequestHeaders.mockReturnValueOnce({}) const error = new Error('Test Error') const fspiopError = ErrorHandler.ReformatFSPIOPError(error) mockSpan.injectContextToHttpRequest = jest.fn().mockImplementation(() => ({ @@ -2097,7 +2100,7 @@ describe('QuotesModel', () => { const jwsSignSpy = jest.spyOn(JwsSigner.prototype, 'getSignature') expect.assertions(5) quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) - quotesModel.generateRequestHeaders.mockReturnValueOnce({}) + Util.generateRequestHeaders.mockReturnValueOnce({}) const error = new Error('Test Error') const fspiopError = ErrorHandler.ReformatFSPIOPError(error) mockSpan.injectContextToHttpRequest = jest.fn().mockImplementation(() => ({ @@ -2138,7 +2141,7 @@ describe('QuotesModel', () => { const jwsSignSpy = jest.spyOn(JwsSigner.prototype, 'getSignature') expect.assertions(5) quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) - quotesModel.generateRequestHeaders.mockReturnValueOnce({}) + Util.generateRequestHeaders.mockReturnValueOnce({}) const error = new Error('Test Error') const fspiopError = ErrorHandler.ReformatFSPIOPError(error) mockSpan.injectContextToHttpRequest = jest.fn().mockImplementation(() => ({ @@ -2178,7 +2181,7 @@ describe('QuotesModel', () => { // Arrange expect.assertions(2) quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(undefined) - quotesModel.generateRequestHeaders.mockReturnValueOnce({}) + Util.generateRequestHeaders.mockReturnValueOnce({}) const error = new Error('Test Error') const fspiopError = ErrorHandler.ReformatFSPIOPError(error) @@ -2194,7 +2197,7 @@ describe('QuotesModel', () => { // Arrange expect.assertions(2) quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) - quotesModel.generateRequestHeaders.mockReturnValueOnce({}) + Util.generateRequestHeaders.mockReturnValueOnce({}) const error = new Error('Test Error') const fspiopError = ErrorHandler.ReformatFSPIOPError(error) axios.request.mockImplementationOnce(() => { throw new Error('HTTP test error') }) @@ -2211,7 +2214,7 @@ describe('QuotesModel', () => { // Arrange expect.assertions(2) quotesModel.db.getParticipantEndpoint.mockReturnValueOnce(mockData.endpoints.payeefsp) - quotesModel.generateRequestHeaders.mockReturnValueOnce({}) + Util.generateRequestHeaders.mockReturnValueOnce({}) const error = new Error('Test Error') const fspiopError = ErrorHandler.ReformatFSPIOPError(error) axios.request.mockReturnValueOnce({ @@ -2231,7 +2234,7 @@ describe('QuotesModel', () => { beforeEach(() => { // restore the current method in test to its original implementation quotesModel.checkDuplicateQuoteRequest.mockRestore() - quotesModel.calculateRequestHash.mockRestore() + Util.calculateRequestHash.mockRestore() }) it('handles a non-duplicate request', async () => { @@ -2274,7 +2277,7 @@ describe('QuotesModel', () => { // Arrange expect.assertions(2) quotesModel.db.getQuoteDuplicateCheck.mockReturnValueOnce({ - hash: quotesModel.calculateRequestHash(mockData.quoteRequest) + hash: Util.calculateRequestHash(mockData.quoteRequest) }) const expected = { isResend: true, @@ -2307,7 +2310,7 @@ describe('QuotesModel', () => { beforeEach(() => { // restore the current method in test to its original implementation quotesModel.checkDuplicateQuoteResponse.mockRestore() - quotesModel.calculateRequestHash.mockRestore() + Util.calculateRequestHash.mockRestore() }) it('handles a non-duplicate request', async () => { @@ -2350,7 +2353,7 @@ describe('QuotesModel', () => { // Arrange expect.assertions(2) quotesModel.db.getQuoteResponseDuplicateCheck.mockReturnValueOnce({ - hash: quotesModel.calculateRequestHash(mockData.quoteResponse) + hash: Util.calculateRequestHash(mockData.quoteResponse) }) const expected = { isResend: true, @@ -2379,175 +2382,6 @@ describe('QuotesModel', () => { }) }) - describe('removeEmptyKeys', () => { - beforeEach(() => { - // restore the current method in test to its original implementation - quotesModel.removeEmptyKeys.mockRestore() - }) - - it('removes nothing if there are no empty keys', () => { - // Arrange - const input = { - a: 1, - b: 2, - c: 3 - } - const expected = { - a: 1, - b: 2, - c: 3 - } - - // Act - const result = quotesModel.removeEmptyKeys(input) - - // Assert - expect(result).toStrictEqual(expected) - }) - - it('removes a key and if it is undefined', () => { - // Arrange - const input = { - a: 1, - b: 2, - c: undefined - } - const expected = { - a: 1, - b: 2 - } - - // Act - const result = quotesModel.removeEmptyKeys(input) - - // Assert - expect(result).toStrictEqual(expected) - }) - - it('removes an empty key', () => { - // Arrange - const input = { - a: 1, - b: 2, - c: { - - } - } - const expected = { - a: 1, - b: 2 - } - - // Act - const result = quotesModel.removeEmptyKeys(input) - - // Assert - expect(result).toStrictEqual(expected) - }) - - it('removes a nested empty key', () => { - // Arrange - const input = { - a: 1, - b: 2, - c: { - d: { - - } - } - } - const expected = { - a: 1, - b: 2, - c: {} - } - - // Act - const result = quotesModel.removeEmptyKeys(input) - - // Assert - expect(result).toStrictEqual(expected) - }) - }) - - describe('generateRequestHeaders', () => { - beforeEach(() => { - // restore the current method in test to its original implementation - quotesModel.generateRequestHeaders.mockRestore() - quotesModel.removeEmptyKeys.mockRestore() - }) - - it('generates the default request headers', () => { - // Arrange - const expected = { - 'Content-Type': 'application/vnd.interoperability.quotes+json;version=1.0', - 'FSPIOP-Destination': 'dfsp2', - 'FSPIOP-Source': 'dfsp1' - } - - // Act - const result = quotesModel.generateRequestHeaders(mockData.headers, true) - - // Assert - expect(result).toStrictEqual(expected) - }) - - it('generates default request headers, including the Accept', () => { - // Arrange - const expected = { - Accept: 'application/vnd.interoperability.quotes+json;version=1.0', - 'Content-Type': 'application/vnd.interoperability.quotes+json;version=1.0', - 'FSPIOP-Destination': 'dfsp2', - 'FSPIOP-Source': 'dfsp1' - } - - // Act - const result = quotesModel.generateRequestHeaders(mockData.headers, false) - - // Assert - expect(result).toStrictEqual(expected) - }) - }) - - describe('generateRequestHeadersForJWS', () => { - beforeEach(() => { - // restore the current method in test to its original implementation - quotesModel.generateRequestHeadersForJWS.mockRestore() - quotesModel.removeEmptyKeys.mockRestore() - }) - - it('generates the default request headers', () => { - // Arrange - const expected = { - 'Content-Type': 'application/vnd.interoperability.quotes+json;version=1.0', - 'fspiop-destination': 'dfsp2', - 'fspiop-source': 'dfsp1' - } - - // Act - const result = quotesModel.generateRequestHeadersForJWS(mockData.headers, true) - - // Assert - expect(result).toStrictEqual(expected) - }) - - it('generates default request headers, including the Accept', () => { - // Arrange - const expected = { - Accept: 'application/vnd.interoperability.quotes+json;version=1.0', - 'Content-Type': 'application/vnd.interoperability.quotes+json;version=1.0', - 'fspiop-destination': 'dfsp2', - 'fspiop-source': 'dfsp1' - } - - // Act - const result = quotesModel.generateRequestHeadersForJWS(mockData.headers, false) - - // Assert - expect(result).toStrictEqual(expected) - }) - }) - describe('writeLog', () => { beforeEach(() => { // restore the current method in test to its original implementation