diff --git a/Dockerfile.e2e b/Dockerfile.e2e index f612fc24..bc9ae1a3 100644 --- a/Dockerfile.e2e +++ b/Dockerfile.e2e @@ -3,6 +3,7 @@ FROM node:10 WORKDIR /mono COPY package.json . COPY oracle-e2e/package.json ./oracle-e2e/ +COPY monitor-e2e/package.json ./monitor-e2e/ COPY contracts/package.json ./contracts/ COPY yarn.lock . diff --git a/e2e-commons/constants.json b/e2e-commons/constants.json index 332111c9..246cd20a 100644 --- a/e2e-commons/constants.json +++ b/e2e-commons/constants.json @@ -19,20 +19,23 @@ "home": "0x32198D570fffC7033641F8A9094FFDCaAEF42624", "foreign": "0x2B6871b9B02F73fa24F4864322CdC78604207769", "foreignToken": "0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B", - "ui": "http://localhost:3000" + "ui": "http://localhost:3000", + "monitor": "http://monitor:3010" }, "ercToErcBridge": { "home": "0x1feB40aD9420b186F019A717c37f5546165d411E", "foreign": "0x4a58D6d8D416a5fBCAcf3dC52eb8bE8948E25127", "homeToken": "0x792455a6bCb62Ed4C4362D323E0590654CA4765c", "foreignToken": "0x3C665A31199694Bf723fD08844AD290207B5797f", - "ui": "http://localhost:3001" + "ui": "http://localhost:3001", + "monitor": "http://monitor-erc20:3011" }, "ercToNativeBridge": { "home": "0x488Af810997eD1730cB3a3918cD83b3216E6eAda", "foreign": "0x488Af810997eD1730cB3a3918cD83b3216E6eAda", "foreignToken": "0x3C665A31199694Bf723fD08844AD290207B5797f", - "ui": "http://localhost:3002" + "ui": "http://localhost:3002", + "monitor": "http://monitor-erc20-native:3012" }, "homeRPC": { "URL": "http://parity1:8545", diff --git a/e2e-commons/docker-compose.yml b/e2e-commons/docker-compose.yml index 0f22b360..d5ab143d 100644 --- a/e2e-commons/docker-compose.yml +++ b/e2e-commons/docker-compose.yml @@ -239,7 +239,7 @@ services: - FOREIGN_GAS_PRICE_FACTOR=1 - LEFT_TX_THRESHOLD=100 - PORT=3010 - entrypoint: yarn start + entrypoint: yarn check-and-start ports: - "3010:3010" networks: @@ -267,7 +267,7 @@ services: - FOREIGN_GAS_PRICE_FACTOR=1 - LEFT_TX_THRESHOLD=100 - PORT=3011 - entrypoint: yarn start + entrypoint: yarn check-and-start ports: - "3011:3011" networks: @@ -295,7 +295,7 @@ services: - FOREIGN_GAS_PRICE_FACTOR=1 - LEFT_TX_THRESHOLD=100 - PORT=3012 - entrypoint: yarn start + entrypoint: yarn check-and-start ports: - "3012:3012" networks: diff --git a/monitor-e2e/.eslintrc b/monitor-e2e/.eslintrc new file mode 100644 index 00000000..1bc0d9f3 --- /dev/null +++ b/monitor-e2e/.eslintrc @@ -0,0 +1,16 @@ +{ + "extends": [ + "plugin:node/recommended", + "airbnb-base", + "../.eslintrc" + ], + "plugins": ["node"], + "rules": { + "node/no-unpublished-require": "off", + "node/no-extraneous-require": "off", + "import/no-extraneous-dependencies": "off" + }, + "env": { + "mocha": true + } +} diff --git a/monitor-e2e/erc-to-erc.sh b/monitor-e2e/erc-to-erc.sh deleted file mode 100755 index eab3e13c..00000000 --- a/monitor-e2e/erc-to-erc.sh +++ /dev/null @@ -1,26 +0,0 @@ -set -e # exit when any command fails - -echo "MONITOR E2E - ERC TO ERC" -export URL=localhost:3011 - -echo "Test case - Web Interface should return balances" -OUTPUT=$(curl -s http://$URL/) -grep -q home <<< "$OUTPUT" -grep -q foreign <<< "$OUTPUT" -(! grep -q error <<< "$OUTPUT") - -echo "Test case - Web Interface should return validators" -OUTPUT=$(curl -s http://$URL/validators) -grep -q home <<< "$OUTPUT" -grep -q foreign <<< "$OUTPUT" -(! grep -q error <<< "$OUTPUT") - -echo "Test case - Web Interface should return eventsStats" -OUTPUT=$(curl -s http://$URL/eventsStats) -grep -q lastChecked <<< "$OUTPUT" -(! grep -q error <<< "$OUTPUT") - -echo "Test case - Web Interface should return alerts" -OUTPUT=$(curl -s http://$URL/alerts) -grep -q lastChecked <<< "$OUTPUT" -(! grep -q error <<< "$OUTPUT") diff --git a/monitor-e2e/erc-to-native.sh b/monitor-e2e/erc-to-native.sh deleted file mode 100755 index 62abe5fa..00000000 --- a/monitor-e2e/erc-to-native.sh +++ /dev/null @@ -1,26 +0,0 @@ -set -e # exit when any command fails - -echo "MONITOR E2E - ERC TO NATIVE" -export URL=localhost:3012 - -echo "Test case - Web Interface should return balances" -OUTPUT=$(curl -s http://$URL/) -grep -q home <<< "$OUTPUT" -grep -q foreign <<< "$OUTPUT" -(! grep -q error <<< "$OUTPUT") - -echo "Test case - Web Interface should return validators" -OUTPUT=$(curl -s http://$URL/validators) -grep -q home <<< "$OUTPUT" -grep -q foreign <<< "$OUTPUT" -(! grep -q error <<< "$OUTPUT") - -echo "Test case - Web Interface should return eventsStats" -OUTPUT=$(curl -s http://$URL/eventsStats) -grep -q lastChecked <<< "$OUTPUT" -(! grep -q error <<< "$OUTPUT") - -echo "Test case - Web Interface should return alerts" -OUTPUT=$(curl -s http://$URL/alerts) -grep -q lastChecked <<< "$OUTPUT" -(! grep -q error <<< "$OUTPUT") diff --git a/monitor-e2e/native-to-erc.sh b/monitor-e2e/native-to-erc.sh deleted file mode 100755 index 16c2c1bc..00000000 --- a/monitor-e2e/native-to-erc.sh +++ /dev/null @@ -1,26 +0,0 @@ -set -e # exit when any command fails - -echo "MONITOR E2E - NATIVE TO ERC" -export URL="localhost:3010" - -echo "Test case - Web Interface should return balances" -OUTPUT=$(curl -s http://$URL/) -grep -q home <<< "$OUTPUT" -grep -q foreign <<< "$OUTPUT" -(! grep -q error <<< "$OUTPUT") - -echo "Test case - Web Interface should return validators" -OUTPUT=$(curl -s http://$URL/validators) -grep -q home <<< "$OUTPUT" -grep -q foreign <<< "$OUTPUT" -(! grep -q error <<< "$OUTPUT") - -echo "Test case - Web Interface should return eventsStats" -OUTPUT=$(curl -s http://$URL/eventsStats) -grep -q lastChecked <<< "$OUTPUT" -(! grep -q error <<< "$OUTPUT") - -echo "Test case - Web Interface should return alerts" -OUTPUT=$(curl -s http://$URL/alerts) -grep -q lastChecked <<< "$OUTPUT" -(! grep -q error <<< "$OUTPUT") diff --git a/monitor-e2e/package.json b/monitor-e2e/package.json new file mode 100644 index 00000000..41b20be5 --- /dev/null +++ b/monitor-e2e/package.json @@ -0,0 +1,19 @@ +{ + "name": "monitor-e2e", + "version": "0.0.1", + "description": "", + "main": "index.js", + "scripts": { + "start": "mocha --timeout 30000", + "lint": "eslint . --ignore-path ../.eslintignore" + }, + "author": "", + "license": "ISC", + "dependencies": {}, + "engines": { + "node": ">= 8.9" + }, + "devDependencies": { + "axios": "0.19.0" + } +} diff --git a/monitor-e2e/periodically-check-all.sh b/monitor-e2e/periodically-check-all.sh new file mode 100755 index 00000000..6ec79044 --- /dev/null +++ b/monitor-e2e/periodically-check-all.sh @@ -0,0 +1,6 @@ +while true; do + sleep 3 + docker-compose -f ../e2e-commons/docker-compose.yml exec monitor yarn check-all + docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-erc20 yarn check-all + docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-erc20-native yarn check-all +done diff --git a/monitor-e2e/run-tests.sh b/monitor-e2e/run-tests.sh index eb7b5179..d7ef80f9 100755 --- a/monitor-e2e/run-tests.sh +++ b/monitor-e2e/run-tests.sh @@ -1,51 +1,14 @@ -#!/usr/bin/env bash cd $(dirname $0) -set -e # exit when any command fails +../e2e-commons/up.sh deploy monitor -##### Helper Functions ##### +./wait-for-monitor.sh +nohup ./periodically-check-all.sh < /dev/null > /dev/null 2>&1 & +checkPID=$! -function cleanup { - ../e2e-commons/down.sh -} -trap cleanup EXIT +docker-compose -f ../e2e-commons/docker-compose.yml run e2e yarn workspace monitor-e2e run start +rc=$? -FILES=(getBalances.json validators.json eventsStats.json alerts.json) - -check_files_exist() { - rc=0 - for f in "${FILES[@]}"; do - command="test -f responses/$f" - (docker-compose -f ../e2e-commons/docker-compose.yml exec monitor /bin/bash -c "$command") || rc=1 - (docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-erc20 /bin/bash -c "$command") || rc=1 - (docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-erc20-native /bin/bash -c "$command") || rc=1 - done - return $rc -} - - -##### Initialization ##### - -../e2e-commons/up.sh deploy oracle monitor - - -##### Initial checks ##### - -docker-compose -f ../e2e-commons/docker-compose.yml exec monitor /bin/bash -c "yarn check-all" -docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-erc20 /bin/bash -c "yarn check-all" -docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-erc20-native /bin/bash -c "yarn check-all" -check_files_exist - - -##### Test cases ##### - -./native-to-erc.sh - -./erc-to-erc.sh - -./erc-to-native.sh - - -##### Cleanup ##### - -cleanup +../e2e-commons/down.sh +kill $checkPID +exit $rc diff --git a/monitor-e2e/test/common.js b/monitor-e2e/test/common.js new file mode 100644 index 00000000..1a60bc0d --- /dev/null +++ b/monitor-e2e/test/common.js @@ -0,0 +1,99 @@ +const assert = require('assert') +const axios = require('axios') +const { nativeToErcBridge, ercToErcBridge, ercToNativeBridge, validator } = require('../../e2e-commons/constants.json') + +const types = [ + { description: 'NATIVE TO ERC', baseUrl: nativeToErcBridge.monitor }, + { description: 'ERC TO ERC', baseUrl: ercToErcBridge.monitor }, + { description: 'ERC TO NATIVE', baseUrl: ercToNativeBridge.monitor } +] + +types.forEach(type => { + describe(type.description, () => { + describe('balances', async () => { + let data + + before(async () => { + ;({ data } = await axios.get(`${type.baseUrl}`)) + }) + + describe('home', async () => { + it('should contain deposits:', () => assert(data.home.deposits === 0)) + it('should contain withdrawals', () => assert(data.home.withdrawals === 0)) + }) + + describe('foreign', async () => { + it('should contain deposits:', () => assert(data.foreign.deposits === 0)) + it('should contain withdrawals', () => assert(data.foreign.withdrawals === 0)) + }) + + describe('general', async () => { + it('should contain balanceDiff', () => assert(data.balanceDiff === 0)) + it('should contain depositsDiff', () => assert(data.depositsDiff === 0)) + it('should contain withdrawalDiff', () => assert(data.withdrawalDiff === 0)) + it('should contain timeDiff', () => assert(data.timeDiff >= 0)) + it('should contain lastChecked', () => assert(data.lastChecked >= 0)) + }) + }) + + describe('validators', async () => { + let data + + before(async () => { + ;({ data } = await axios.get(`${type.baseUrl}/validators`)) + }) + + it('home', () => { + assert(typeof data.home.validators === 'object') + assert(data.home.validators[validator.address].balance > 0) + assert(data.home.validators[validator.address].leftTx > 0) + assert(data.home.validators[validator.address].gasPrice > 0) + }) + + it('foreign', () => { + assert(typeof data.foreign.validators === 'object') + assert(data.foreign.validators[validator.address].balance > 0) + assert(data.foreign.validators[validator.address].leftTx > 0) + assert(data.foreign.validators[validator.address].gasPrice > 0) + }) + + it('requiredSignaturesMatch', () => assert(data.requiredSignaturesMatch, 1)) + it('validatorsMatch', () => assert(data.validatorsMatch)) + it('lastChecked', () => assert(data.lastChecked >= 0)) + it('timeDiff', () => assert(data.timeDiff >= 0)) + it('homeOk', () => assert(data.homeOk)) + it('foreignOk', () => assert(data.foreignOk)) + it('ok', () => assert(data.ok)) + }) + + describe('eventsStats', async () => { + let data + + before(async () => { + ;({ data } = await axios.get(`${type.baseUrl}/eventsStats`)) + }) + + it('ok', () => assert(data.ok)) + it('lastChecked', () => assert(data.lastChecked >= 0)) + it('timeDiff', () => assert(data.timeDiff >= 0)) + it('onlyInHomeDeposits', () => assert(typeof data.onlyInHomeDeposits === 'object')) + it('onlyInForeignDeposits', () => assert(typeof data.onlyInForeignDeposits === 'object')) + it('onlyInHomeWithdrawals', () => assert(typeof data.onlyInHomeWithdrawals === 'object')) + it('onlyInForeignWithdrawals', () => assert(typeof data.onlyInForeignWithdrawals === 'object')) + }) + + describe('alerts', async () => { + let data + + before(async () => { + ;({ data } = await axios.get(`${type.baseUrl}/alerts`)) + }) + + it('ok', () => assert(data.ok)) + it('lastChecked', () => assert(data.lastChecked >= 0)) + it('timeDiff', () => assert(data.timeDiff >= 0)) + it('executeSignatures', () => assert(typeof data.executeSignatures === 'object')) + it('executeAffirmations', () => assert(typeof data.executeAffirmations === 'object')) + }) + }) +}) diff --git a/monitor-e2e/test/ercToErc.js b/monitor-e2e/test/ercToErc.js new file mode 100644 index 00000000..a644ac70 --- /dev/null +++ b/monitor-e2e/test/ercToErc.js @@ -0,0 +1,43 @@ +const assert = require('assert') +const axios = require('axios') +const { ercToErcBridge, user, foreignRPC, validator } = require('../../e2e-commons/constants.json') +const { waitUntil, sendTokens, addValidator } = require('../utils') + +const baseUrl = ercToErcBridge.monitor + +describe('ERC TO ERC', () => { + let data + + before(async () => { + ;({ data } = await axios.get(`${baseUrl}`)) + }) + + it('balance', () => assert(parseInt(data.foreign.erc20Balance, 10) >= 0)) + it('should contain totalSupply', () => assert(data.home.totalSupply === '0')) +}) + +describe('ERC TO ERC with changing state of contracts', () => { + let data + + before(async () => { + assert((await axios.get(`${baseUrl}`)).data.balanceDiff === 0) + assert((await axios.get(`${baseUrl}/validators`)).data.validatorsMatch === true) + }) + + it('should change balanceDiff', async () => { + await sendTokens(foreignRPC.URL, user, ercToErcBridge.foreignToken, ercToErcBridge.foreign) + + await waitUntil(async () => { + ;({ data } = await axios.get(`${baseUrl}`)) + return data.balanceDiff !== 0 + }) + }) + + it('should change validatorsMatch', async () => { + await addValidator(foreignRPC.URL, validator, ercToErcBridge.foreign) + await waitUntil(async () => { + ;({ data } = await axios.get(`${baseUrl}/validators`)) + return data.validatorsMatch === false + }) + }) +}) diff --git a/monitor-e2e/test/ercToNative.js b/monitor-e2e/test/ercToNative.js new file mode 100644 index 00000000..61a996a8 --- /dev/null +++ b/monitor-e2e/test/ercToNative.js @@ -0,0 +1,43 @@ +const assert = require('assert') +const axios = require('axios') +const { ercToNativeBridge, user, foreignRPC, validator } = require('../../e2e-commons/constants.json') +const { waitUntil, sendTokens, addValidator } = require('../utils') + +const baseUrl = ercToNativeBridge.monitor + +describe('ERC TO NATIVE', () => { + let data + + before(async () => { + ;({ data } = await axios.get(`${baseUrl}`)) + }) + + it('balance', () => assert(parseInt(data.foreign.erc20Balance, 10) >= 0)) + it('should contain totalSupply', () => assert(data.home.totalSupply === '0')) +}) + +describe('ERC TO NATIVE with changing state of contracts', () => { + let data + + before(async () => { + assert((await axios.get(`${baseUrl}`)).data.balanceDiff === 0) + assert((await axios.get(`${baseUrl}/validators`)).data.validatorsMatch === true) + }) + + it('should change balanceDiff', async () => { + await sendTokens(foreignRPC.URL, user, ercToNativeBridge.foreignToken, ercToNativeBridge.foreign) + + await waitUntil(async () => { + ;({ data } = await axios.get(`${baseUrl}`)) + return data.balanceDiff !== 0 + }) + }) + + it('should change validatorsMatch', async () => { + await addValidator(foreignRPC.URL, validator, ercToNativeBridge.foreign) + await waitUntil(async () => { + ;({ data } = await axios.get(`${baseUrl}/validators`)) + return data.validatorsMatch === false + }) + }) +}) diff --git a/monitor-e2e/test/nativeToErc.js b/monitor-e2e/test/nativeToErc.js new file mode 100644 index 00000000..7cf4cee3 --- /dev/null +++ b/monitor-e2e/test/nativeToErc.js @@ -0,0 +1,43 @@ +const assert = require('assert') +const axios = require('axios') +const { nativeToErcBridge, user, homeRPC, foreignRPC, validator } = require('../../e2e-commons/constants.json') +const { waitUntil, sendEther, addValidator } = require('../utils') + +const baseUrl = nativeToErcBridge.monitor + +describe('NATIVE TO ERC', () => { + let data + + before(async () => { + ;({ data } = await axios.get(`${baseUrl}`)) + }) + + it('balance', () => assert(parseInt(data.home.balance, 10) >= 0)) + it('should contain totalSupply', () => assert(data.foreign.totalSupply === '0')) +}) + +describe('NATIVE TO ERC with changing state of contracts', () => { + let data + + before(async () => { + assert((await axios.get(`${baseUrl}`)).data.balanceDiff === 0) + assert((await axios.get(`${baseUrl}/validators`)).data.validatorsMatch === true) + }) + + it('should change balanceDiff', async () => { + await sendEther(homeRPC.URL, user, nativeToErcBridge.home) + + await waitUntil(async () => { + ;({ data } = await axios.get(`${baseUrl}`)) + return data.balanceDiff !== 0 + }) + }) + + it('should change validatorsMatch', async () => { + await addValidator(foreignRPC.URL, validator, nativeToErcBridge.foreign) + await waitUntil(async () => { + ;({ data } = await axios.get(`${baseUrl}/validators`)) + return data.validatorsMatch === false + }) + }) +}) diff --git a/monitor-e2e/utils.js b/monitor-e2e/utils.js new file mode 100644 index 00000000..eaa0d8b0 --- /dev/null +++ b/monitor-e2e/utils.js @@ -0,0 +1,57 @@ +const Web3 = require('web3') +const { ERC677_BRIDGE_TOKEN_ABI, BRIDGE_VALIDATORS_ABI, FOREIGN_NATIVE_TO_ERC_ABI } = require('../commons') + +const waitUntil = async (predicate, step = 100, timeout = 10000) => { + const stopTime = Date.now() + timeout + while (Date.now() <= stopTime) { + const result = await predicate() + if (result) { + return result + } + await new Promise(resolve => setTimeout(resolve, step)) // sleep + } + throw new Error(`waitUntil timed out after ${timeout} ms`) +} + +const sendEther = async (rpcUrl, account, to) => { + const web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl)) + web3.eth.accounts.wallet.add(account.privateKey) + + await web3.eth.sendTransaction({ + from: account.address, + to, + gasPrice: '1', + gas: '50000', + value: '1000000000000000000' + }) +} + +const sendTokens = async (rpcUrl, account, tokenAddress, recipientAddress) => { + const web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl)) + web3.eth.accounts.wallet.add(account.privateKey) + const erc20Token = new web3.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, tokenAddress) + + await erc20Token.methods.transfer(recipientAddress, web3.utils.toWei('0.01')).send({ + from: account.address, + gas: '1000000' + }) +} + +const addValidator = async (rpcUrl, account, bridgeAddress) => { + const web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl)) + web3.eth.accounts.wallet.add(account.privateKey) + const bridgeContract = new web3.eth.Contract(FOREIGN_NATIVE_TO_ERC_ABI, bridgeAddress) + const foreignValidatorsAddress = await bridgeContract.methods.validatorContract().call() + const foreignBridgeValidators = new web3.eth.Contract(BRIDGE_VALIDATORS_ABI, foreignValidatorsAddress) + await foreignBridgeValidators.methods.addValidator('0xE71FBa5db00172bb0C93d649362B006300000935').send({ + from: account.address, + gas: '5000000' + }) +} + +module.exports = { + waitUntil, + sendEther, + sendTokens, + addValidator +} diff --git a/monitor-e2e/wait-for-monitor.sh b/monitor-e2e/wait-for-monitor.sh new file mode 100755 index 00000000..52810e81 --- /dev/null +++ b/monitor-e2e/wait-for-monitor.sh @@ -0,0 +1,27 @@ +FILES=(getBalances.json validators.json eventsStats.json alerts.json) + +check_files_exist() { + rc=0 + for f in "${FILES[@]}"; do + command="test -f responses/$f" + (docker-compose -f ../e2e-commons/docker-compose.yml exec monitor /bin/bash -c "$command") || rc=1 + (docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-erc20 /bin/bash -c "$command") || rc=1 + (docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-erc20-native /bin/bash -c "$command") || rc=1 + done + return $rc +} + +i=0 +until check_files_exist +do + ((i++)) + if [ "$i" -gt 30 ] + then + exit -1 + fi + + echo "Waiting for monitor to start..." + sleep 3 +done + +echo "Monitor started" diff --git a/package.json b/package.json index 28ac76e0..faaeefa1 100644 --- a/package.json +++ b/package.json @@ -29,13 +29,14 @@ "ui", "ui-e2e", "monitor", + "monitor-e2e", "contracts" ], "scripts": { "initialize": "yarn clean && git submodule update --init && yarn install --unsafe-perm --frozen-lockfile && yarn install:deploy && yarn compile:contracts", "build": "yarn workspace ui run build", "lint": "yarn wsrun --exclude token-bridge-contracts lint", - "test": "yarn wsrun --exclude monitor --exclude oracle-e2e --exclude ui-e2e test", + "test": "yarn wsrun --exclude monitor --exclude oracle-e2e --exclude ui-e2e --exclude monitor-e2e test", "oracle-e2e": "./oracle-e2e/run-tests.sh", "ui-e2e": "./ui-e2e/run-tests.sh", "clean": "rm -rf ./node_modules ./**/node_modules ./**/**/node_modules ./**/build", diff --git a/yarn.lock b/yarn.lock index 4d99b955..f02730ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2783,6 +2783,14 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== +axios@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" + integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== + dependencies: + follow-redirects "1.5.10" + is-buffer "^2.0.2" + axobject-query@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9" @@ -5441,7 +5449,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6. dependencies: ms "2.0.0" -debug@3.1.0: +debug@3.1.0, debug@=3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== @@ -5469,7 +5477,7 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "^2.1.1" -debuglog@*, debuglog@^1.0.1: +debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -7648,6 +7656,13 @@ flush-write-stream@^1.0.0, flush-write-stream@^1.0.2: inherits "^2.0.3" readable-stream "^2.3.6" +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + follow-redirects@^1.0.0: version "1.7.0" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76" @@ -8989,7 +9004,7 @@ import-local@^2.0.0: pkg-dir "^3.0.0" resolve-cwd "^2.0.0" -imurmurhash@*, imurmurhash@^0.1.4: +imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -9241,7 +9256,7 @@ is-buffer@^1.0.2, is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@^2.0.0: +is-buffer@^2.0.0, is-buffer@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== @@ -11064,11 +11079,6 @@ lockfile@^1.0.4: dependencies: signal-exit "^3.0.2" -lodash._baseindexof@*: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" - integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw= - lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -11077,33 +11087,11 @@ lodash._baseuniq@~4.6.0: lodash._createset "~4.0.0" lodash._root "~3.0.0" -lodash._bindcallback@*: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" - integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4= - -lodash._cacheindexof@*: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" - integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI= - -lodash._createcache@*: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" - integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM= - dependencies: - lodash._getnative "^3.0.0" - lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= -lodash._getnative@*, lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= - lodash._reinterpolate@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" @@ -11194,11 +11182,6 @@ lodash.pick@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= -lodash.restparam@*: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= - lodash.sample@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/lodash.sample/-/lodash.sample-4.2.1.tgz#5e4291b0c753fa1abeb0aab8fb29df1b66f07f6d"