From cd332c4dfd025a132e19bf7fcf82c91ef7c1293a Mon Sep 17 00:00:00 2001 From: Ivan Vandot Date: Fri, 8 Apr 2022 22:23:50 +0200 Subject: [PATCH 1/7] chore: replace REPO_GHA_PAT with GHA_PAT_BASIC (#330) --- .github/workflows/check.yaml | 4 ++-- .github/workflows/release_github.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index e8de8b6a..854f3807 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -65,7 +65,7 @@ jobs: uses: ethersphere/update-supported-bee-action@v1 if: github.ref == 'refs/heads/master' with: - token: ${{ secrets.REPO_GHA_PAT }} + token: ${{ secrets.GHA_PAT_BASIC }} - name: Build run: npm run build @@ -78,7 +78,7 @@ jobs: with: bee-url: https://unlimited.gateway.ethswarm.org preview: 'true' - token: ${{ secrets.REPO_GHA_PAT }} + token: ${{ secrets.GHA_PAT_BASIC }} extra-params: '-H "${{ secrets.GATEWAY_AUTHORIZATION_HEADER }}"' - name: Upload to testnet diff --git a/.github/workflows/release_github.yaml b/.github/workflows/release_github.yaml index 6f490453..b80050d8 100644 --- a/.github/workflows/release_github.yaml +++ b/.github/workflows/release_github.yaml @@ -14,7 +14,7 @@ jobs: - uses: GoogleCloudPlatform/release-please-action@v2 id: release with: - token: ${{ secrets.REPO_GHA_PAT }} + token: ${{ secrets.GHA_PAT_BASIC }} release-type: node package-name: bee-dashboard bump-minor-pre-major: true From 5d0fbf705dfed6738980c751a9654199d60a3787 Mon Sep 17 00:00:00 2001 From: Vojtech Simetka Date: Wed, 13 Apr 2022 18:09:30 +0500 Subject: [PATCH 2/7] feat: optional status checks (e.g. connected peers > 0 or funded chequebook) (#331) * feat: make some check optional (e.g. connected peers > 0 or funded chequebook) * fix: alter setup step text to better describe what needs to be done * refactor: rename isOk from boolean value to checkState enum * fix: add checking for any error --- src/components/SideBarStatus.tsx | 6 +- src/components/StatusIcon.tsx | 23 +++- src/pages/accounting/index.tsx | 4 +- src/pages/feeds/index.tsx | 4 +- src/pages/files/Upload.tsx | 4 +- src/pages/info/index.tsx | 4 +- src/pages/stamps/index.tsx | 4 +- .../SetupSteps/ChequebookDeployFund.tsx | 54 ++++++--- .../SetupSteps/DebugConnectionCheck.tsx | 10 +- .../SetupSteps/EthereumConnectionCheck.tsx | 8 +- .../status/SetupSteps/NodeConnectionCheck.tsx | 10 +- .../status/SetupSteps/PeerConnection.tsx | 26 ++-- src/pages/status/SetupSteps/VersionCheck.tsx | 8 +- src/providers/Bee.tsx | 113 +++++++++++------- src/react-app-env.d.ts | 17 --- src/types.ts | 19 +++ 16 files changed, 190 insertions(+), 124 deletions(-) diff --git a/src/components/SideBarStatus.tsx b/src/components/SideBarStatus.tsx index 46728b51..d2302302 100644 --- a/src/components/SideBarStatus.tsx +++ b/src/components/SideBarStatus.tsx @@ -66,11 +66,9 @@ export default function SideBarItem({ path }: Props): ReactElement { disableRipple > - + - {`Node ${status.all ? 'OK' : 'Error'}`}} - /> + {`Node ${status.all}`}} /> {status.all ? null : } diff --git a/src/components/StatusIcon.tsx b/src/components/StatusIcon.tsx index bab8969d..6d521506 100644 --- a/src/components/StatusIcon.tsx +++ b/src/components/StatusIcon.tsx @@ -1,23 +1,40 @@ import type { ReactElement } from 'react' import { CircularProgress } from '@material-ui/core' +import { CheckState } from '../providers/Bee' interface Props { - isOk: boolean + checkState: CheckState isLoading?: boolean size?: number | string className?: string } -export default function StatusIcon({ isOk, size, className, isLoading }: Props): ReactElement { +export default function StatusIcon({ checkState, size, className, isLoading }: Props): ReactElement { const s = size || '1rem' if (isLoading) return + let backgroundColor: string + switch (checkState) { + case CheckState.OK: + backgroundColor = '#1de600' + break + case CheckState.WARNING: + backgroundColor = 'orange' + break + case CheckState.ERROR: + backgroundColor = '#ff3a52' + break + default: + // Default is error + backgroundColor = '#ff3a52' + } + return ( + if (status.all === CheckState.ERROR) return return (
diff --git a/src/pages/feeds/index.tsx b/src/pages/feeds/index.tsx index 209d9a7c..662fc09b 100644 --- a/src/pages/feeds/index.tsx +++ b/src/pages/feeds/index.tsx @@ -8,7 +8,7 @@ import ExpandableListItemActions from '../../components/ExpandableListItemAction import ExpandableListItemKey from '../../components/ExpandableListItemKey' import { SwarmButton } from '../../components/SwarmButton' import TroubleshootConnectionCard from '../../components/TroubleshootConnectionCard' -import { Context as BeeContext } from '../../providers/Bee' +import { CheckState, Context as BeeContext } from '../../providers/Bee' import { Context as IdentityContext, Identity } from '../../providers/Feeds' import { ROUTES } from '../../routes' import { formatEnum } from '../../utils' @@ -60,7 +60,7 @@ export default function Feeds(): ReactElement { setShowDelete(true) } - if (!status.all) return + if (status.all === CheckState.ERROR) return return (
diff --git a/src/pages/files/Upload.tsx b/src/pages/files/Upload.tsx index 8bad5c77..6d26f4e7 100644 --- a/src/pages/files/Upload.tsx +++ b/src/pages/files/Upload.tsx @@ -6,7 +6,7 @@ import { DocumentationText } from '../../components/DocumentationText' import { HistoryHeader } from '../../components/HistoryHeader' import { ProgressIndicator } from '../../components/ProgressIndicator' import TroubleshootConnectionCard from '../../components/TroubleshootConnectionCard' -import { Context as BeeContext } from '../../providers/Bee' +import { CheckState, Context as BeeContext } from '../../providers/Bee' import { Context as IdentityContext, Identity } from '../../providers/Feeds' import { Context as FileContext } from '../../providers/File' import { Context as SettingsContext } from '../../providers/Settings' @@ -43,7 +43,7 @@ export function Upload(): ReactElement { refresh() }, []) // eslint-disable-line react-hooks/exhaustive-deps - if (!status.all) return + if (status.all === CheckState.ERROR) return if (!files.length) { setFiles([]) diff --git a/src/pages/info/index.tsx b/src/pages/info/index.tsx index fd01a279..4cf64470 100644 --- a/src/pages/info/index.tsx +++ b/src/pages/info/index.tsx @@ -2,7 +2,7 @@ import { ReactElement, useContext } from 'react' import { Button } from '@material-ui/core' import TroubleshootConnectionCard from '../../components/TroubleshootConnectionCard' -import { Context as BeeContext } from '../../providers/Bee' +import { CheckState, Context as BeeContext } from '../../providers/Bee' import ExpandableList from '../../components/ExpandableList' import ExpandableListItem from '../../components/ExpandableListItem' import ExpandableListItemKey from '../../components/ExpandableListItemKey' @@ -20,7 +20,7 @@ export default function Status(): ReactElement { nodeInfo, } = useContext(BeeContext) - if (!status.all) return + if (status.all === CheckState.ERROR) return return (
diff --git a/src/pages/stamps/index.tsx b/src/pages/stamps/index.tsx index 221673e5..a5f449a9 100644 --- a/src/pages/stamps/index.tsx +++ b/src/pages/stamps/index.tsx @@ -5,7 +5,7 @@ import { PlusSquare } from 'react-feather' import { useNavigate } from 'react-router' import { SwarmButton } from '../../components/SwarmButton' import TroubleshootConnectionCard from '../../components/TroubleshootConnectionCard' -import { Context as BeeContext } from '../../providers/Bee' +import { CheckState, Context as BeeContext } from '../../providers/Bee' import { Context as StampsContext } from '../../providers/Stamps' import { ROUTES } from '../../routes' import StampsTable from './StampsTable' @@ -41,7 +41,7 @@ export default function Stamp(): ReactElement { return () => stop() }, [status]) // eslint-disable-line react-hooks/exhaustive-deps - if (!status.all) return + if (status.all === CheckState.ERROR) return function navigateToNewStamp() { navigate(ROUTES.STAMPS_NEW) diff --git a/src/pages/status/SetupSteps/ChequebookDeployFund.tsx b/src/pages/status/SetupSteps/ChequebookDeployFund.tsx index 70610fdd..c3572b84 100644 --- a/src/pages/status/SetupSteps/ChequebookDeployFund.tsx +++ b/src/pages/status/SetupSteps/ChequebookDeployFund.tsx @@ -1,41 +1,59 @@ import { useContext } from 'react' import DepositModal from '../../../containers/DepositModal' -import type { ReactElement } from 'react' +import type { ReactElement, ReactNode } from 'react' import ExpandableList from '../../../components/ExpandableList' import ExpandableListItemKey from '../../../components/ExpandableListItemKey' import ExpandableListItemActions from '../../../components/ExpandableListItemActions' import ExpandableListItemNote from '../../../components/ExpandableListItemNote' import StatusIcon from '../../../components/StatusIcon' -import { Context } from '../../../providers/Bee' +import { CheckState, Context } from '../../../providers/Bee' const ChequebookDeployFund = (): ReactElement | null => { const { status, isLoading, chequebookAddress } = useContext(Context) - const { isOk, isEnabled } = status.chequebook + const { checkState, isEnabled } = status.chequebook if (!isEnabled) return null + let text: ReactNode + + switch (checkState) { + case CheckState.OK: + text = 'Your chequebook is deployed and funded' + break + case CheckState.WARNING: + text = ( + <> + Your chequebook is not funded. Please deposit some xBZZ to your chequebook address. You may need to aquire BZZ + (e.g. bzz.exchange) and bridge it to the xDai network through the{' '} + omni bridge. To pay the transaction fees, you will also need + xDAI token. You can purchase DAI on the network and bridge it to xDai network through the{' '} + xDai Bridge. See the{' '} + official xDai website for more information. + + ) + break + default: + text = ( + <> + Your chequebook is either not deployed nor funded. To run the node you will need xDAI and xBZZ on the xDai + network. You may need to aquire BZZ (e.g. bzz.exchange) and bridge it to + the xDai network through the omni bridge. To pay the + transaction fees, you will also need xDAI token. You can purchase DAI on the network and bridge it to xDai + network through the xDai Bridge. See the{' '} + official xDai website for more information. + + ) + } + return ( - Chequebook Deployment & Funding + Chequebook Deployment & Funding } > - - {isOk ? ( - 'Your chequebook is deployed and funded' - ) : ( - <> - Your chequebook is either not deployed or funded. To run the node you will need xDAI and xBZZ on the xDai - network. You may need to aquire BZZ (e.g. bzz.exchange) and bridge it to - the xDai network through the omni bridge. To pay the - transaction fees, you will also need xDAI token. You can purchase DAI on the network and bridge it to xDai - network through the xDai Bridge. See the{' '} - official xDai website for more information. - - )} - + {text} {chequebookAddress && ( <> diff --git a/src/pages/status/SetupSteps/DebugConnectionCheck.tsx b/src/pages/status/SetupSteps/DebugConnectionCheck.tsx index 1c203ee8..b6d961c5 100644 --- a/src/pages/status/SetupSteps/DebugConnectionCheck.tsx +++ b/src/pages/status/SetupSteps/DebugConnectionCheck.tsx @@ -6,13 +6,13 @@ import ExpandableListItem from '../../../components/ExpandableListItem' import ExpandableListItemInput from '../../../components/ExpandableListItemInput' import ExpandableListItemNote from '../../../components/ExpandableListItemNote' import StatusIcon from '../../../components/StatusIcon' -import { Context } from '../../../providers/Bee' +import { CheckState, Context } from '../../../providers/Bee' import { Context as SettingsContext } from '../../../providers/Settings' export default function NodeConnectionCheck(): ReactElement | null { const { status, isLoading } = useContext(Context) const { setDebugApiUrl, apiDebugUrl } = useContext(SettingsContext) - const { isOk, isEnabled } = status.debugApiConnection + const { checkState, isEnabled } = status.debugApiConnection if (!isEnabled) return null @@ -20,18 +20,18 @@ export default function NodeConnectionCheck(): ReactElement | null { - Connection to Bee Debug API + Connection to Bee Debug API } > - {isOk + {checkState === CheckState.OK ? 'The connection to the Bee nodes debug API has been successful' : 'We cannot connect to your nodes debug API. Please check the following to troubleshoot your issue.'} - {!isOk && ( + {checkState === CheckState.ERROR && ( - Connection to Blockchain + Connection to Blockchain } > - {isOk ? ( + {checkState === CheckState.OK ? ( 'Your node is connected to the xDai blockchain' ) : ( <> diff --git a/src/pages/status/SetupSteps/NodeConnectionCheck.tsx b/src/pages/status/SetupSteps/NodeConnectionCheck.tsx index a8d41d2f..9669c17b 100644 --- a/src/pages/status/SetupSteps/NodeConnectionCheck.tsx +++ b/src/pages/status/SetupSteps/NodeConnectionCheck.tsx @@ -7,12 +7,12 @@ import ExpandableListItem from '../../../components/ExpandableListItem' import ExpandableListItemNote from '../../../components/ExpandableListItemNote' import ExpandableListItemInput from '../../../components/ExpandableListItemInput' import StatusIcon from '../../../components/StatusIcon' -import { Context } from '../../../providers/Bee' +import { CheckState, Context } from '../../../providers/Bee' export default function NodeConnectionCheck(): ReactElement | null { const { setApiUrl, apiUrl } = useContext(SettingsContext) const { status, isLoading } = useContext(Context) - const { isEnabled, isOk } = status.apiConnection + const { isEnabled, checkState } = status.apiConnection if (!isEnabled) return null @@ -20,17 +20,17 @@ export default function NodeConnectionCheck(): ReactElement | null { - Connection to Bee API + Connection to Bee API } > - {isOk + {checkState === CheckState.OK ? 'The connection to the Bee nodes API has been successful' : 'Could not connect to your Bee nodes API. Please check the troubleshoot below on how you may resolve it.'} - {!isOk && ( + {checkState === CheckState.ERROR && ( - Connection to Peers + Connection to Peers } > - - {isOk - ? 'You are connected to other Bee nodes' - : 'Your node is not connected to any peers. Please wait a bit if you just started the node, otherwise review your configuration file.'} - + {text} diff --git a/src/pages/status/SetupSteps/VersionCheck.tsx b/src/pages/status/SetupSteps/VersionCheck.tsx index 7249864a..f1d57dc6 100644 --- a/src/pages/status/SetupSteps/VersionCheck.tsx +++ b/src/pages/status/SetupSteps/VersionCheck.tsx @@ -4,11 +4,11 @@ import ExpandableList from '../../../components/ExpandableList' import ExpandableListItem from '../../../components/ExpandableListItem' import ExpandableListItemNote from '../../../components/ExpandableListItemNote' import StatusIcon from '../../../components/StatusIcon' -import { Context } from '../../../providers/Bee' +import { CheckState, Context } from '../../../providers/Bee' export default function VersionCheck(): ReactElement | null { const { status, isLoading, latestUserVersion, latestPublishedVersion, latestBeeVersionUrl } = useContext(Context) - const { isEnabled, isOk } = status.version + const { isEnabled, checkState } = status.version if (!isEnabled) return null @@ -16,12 +16,12 @@ export default function VersionCheck(): ReactElement | null { - Bee Version + Bee Version } > - {isOk ? ( + {checkState === CheckState.OK ? ( 'You are running the latest version of Bee.' ) : ( <> diff --git a/src/providers/Bee.tsx b/src/providers/Bee.tsx index bf80d3d6..df9a3529 100644 --- a/src/providers/Bee.tsx +++ b/src/providers/Bee.tsx @@ -17,13 +17,19 @@ import { Token } from '../models/Token' import type { Balance, ChequebookBalance, Settlements } from '../types' import { Context as SettingsContext } from './Settings' +export enum CheckState { + OK = 'OK', + WARNING = 'Warning', + ERROR = 'Error', +} + interface StatusItem { isEnabled: boolean - isOk: boolean + checkState: CheckState } interface Status { - all: boolean + all: CheckState version: StatusItem blockchainConnection: StatusItem debugApiConnection: StatusItem @@ -63,13 +69,13 @@ interface ContextInterface { const initialValues: ContextInterface = { status: { - all: false, - version: { isEnabled: false, isOk: false }, - blockchainConnection: { isEnabled: false, isOk: false }, - debugApiConnection: { isEnabled: false, isOk: false }, - apiConnection: { isEnabled: false, isOk: false }, - topology: { isEnabled: false, isOk: false }, - chequebook: { isEnabled: false, isOk: false }, + all: CheckState.ERROR, + version: { isEnabled: false, checkState: CheckState.ERROR }, + blockchainConnection: { isEnabled: false, checkState: CheckState.ERROR }, + debugApiConnection: { isEnabled: false, checkState: CheckState.ERROR }, + apiConnection: { isEnabled: false, checkState: CheckState.ERROR }, + topology: { isEnabled: false, checkState: CheckState.ERROR }, + chequebook: { isEnabled: false, checkState: CheckState.ERROR }, }, latestPublishedVersion: undefined, latestUserVersion: undefined, @@ -115,45 +121,62 @@ function getStatus( chequebookBalance: ChequebookBalance | null, error: Error | null, ): Status { - const status = { - version: { - isEnabled: true, - isOk: Boolean( - debugApiHealth && - semver.satisfies(debugApiHealth.version, engines.bee, { - includePrerelease: true, - }), - ), - }, - blockchainConnection: { - isEnabled: true, - isOk: Boolean(nodeAddresses?.ethereum), - }, - debugApiConnection: { - isEnabled: true, - isOk: Boolean(debugApiHealth?.status === 'ok'), - }, - apiConnection: { - isEnabled: true, - isOk: apiHealth, - }, - topology: { - isEnabled: Boolean(nodeInfo && [BeeModes.FULL, BeeModes.LIGHT, BeeModes.ULTRA_LIGHT].includes(nodeInfo.beeMode)), - isOk: Boolean(topology?.connected && topology?.connected > 0), - }, - chequebook: { - isEnabled: Boolean(nodeInfo && [BeeModes.FULL, BeeModes.LIGHT].includes(nodeInfo.beeMode)), - isOk: - Boolean(chequebookAddress?.chequebookAddress) && - chequebookBalance !== null && - chequebookBalance?.totalBalance.toBigNumber.isGreaterThan(0), - }, + const status: Status = { ...initialValues.status } + + // Version check + status.version.isEnabled = true + status.version.checkState = + debugApiHealth && + semver.satisfies(debugApiHealth.version, engines.bee, { + includePrerelease: true, + }) + ? CheckState.OK + : CheckState.ERROR + + // Blockchain connection check + status.blockchainConnection.isEnabled = true + status.blockchainConnection.checkState = Boolean(debugApiHealth?.status === 'ok') ? CheckState.OK : CheckState.ERROR + + // Debug API connection check + status.debugApiConnection.isEnabled = true + status.debugApiConnection.checkState = Boolean(debugApiHealth?.status === 'ok') ? CheckState.OK : CheckState.ERROR + + // API connection check + status.apiConnection.isEnabled = true + status.apiConnection.checkState = apiHealth ? CheckState.OK : CheckState.ERROR + + // Topology check + if (nodeInfo && [BeeModes.FULL, BeeModes.LIGHT, BeeModes.ULTRA_LIGHT].includes(nodeInfo.beeMode)) { + status.topology.isEnabled = true + status.topology.checkState = topology?.connected && topology?.connected > 0 ? CheckState.OK : CheckState.WARNING } - return { - ...status, - all: !error && Object.values(status).every(({ isEnabled, isOk }) => !isEnabled || (isEnabled && isOk)), + // Chequebook check + if (error || (nodeInfo && [BeeModes.FULL, BeeModes.LIGHT].includes(nodeInfo.beeMode))) { + status.chequebook.isEnabled = true + + if ( + chequebookAddress?.chequebookAddress && + chequebookBalance !== null && + chequebookBalance?.totalBalance.toBigNumber.isGreaterThan(0) + ) { + status.chequebook.checkState = CheckState.OK + } else if (chequebookAddress?.chequebookAddress) status.chequebook.checkState = CheckState.WARNING + else status.chequebook.checkState = CheckState.OK } + + // Determine overall status + if (Object.values(status).some(({ isEnabled, checkState }) => isEnabled && checkState === CheckState.ERROR)) { + status.all = CheckState.ERROR + } else if ( + Object.values(status).some(({ isEnabled, checkState }) => isEnabled && checkState === CheckState.WARNING) + ) { + status.all = CheckState.WARNING + } else { + status.all = CheckState.OK + } + + return status } export function Provider({ children }: Props): ReactElement { diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts index 924899c6..27393685 100644 --- a/src/react-app-env.d.ts +++ b/src/react-app-env.d.ts @@ -5,23 +5,6 @@ interface LatestBeeRelease { html_url: string } -interface StatusHookCommon { - isOk: boolean -} - -interface StatusNodeVersionHook extends StatusHookCommon { - userVersion?: string - latestVersion?: string - latestUrl: string - isLatestBeeVersion: boolean -} -interface StatusEthereumConnectionHook extends StatusHookCommon { - nodeAddresses: NodeAddresses | null -} -interface StatusTopologyHook extends StatusHookCommon { - topology: Topology | null -} - interface SwarmMetadata { size: number name: string diff --git a/src/types.ts b/src/types.ts index 8fd9a7f8..ef872be9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,23 @@ +import type { NodeAddresses, Topology } from '@ethersphere/bee-js' import type { Token } from './models/Token' +import { CheckState } from './providers/Bee' + +export interface StatusHookCommon { + checkState: CheckState +} + +export interface StatusNodeVersionHook extends StatusHookCommon { + userVersion?: string + latestVersion?: string + latestUrl: string + isLatestBeeVersion: boolean +} +export interface StatusEthereumConnectionHook extends StatusHookCommon { + nodeAddresses: NodeAddresses | null +} +export interface StatusTopologyHook extends StatusHookCommon { + topology: Topology | null +} export interface ChequebookBalance { totalBalance: Token From eb9e309c8bc0327d137f190d6873618cb215fece Mon Sep 17 00:00:00 2001 From: Vojtech Simetka Date: Wed, 13 Apr 2022 19:00:37 +0500 Subject: [PATCH 3/7] feat: add hook that detects if the bee-dashboard is run within bee-desktop (#334) * feat: add hook that detects if the bee-dashboard is run withing bee-desktop * chore: make the URL configurable * feat: remove error and instead return false * test: add testing with mockserver --- package-lock.json | 612 ++++++++++++++++++++++++++----------- package.json | 5 + src/config.ts | 2 + src/hooks/apiHooks.test.ts | 73 +++++ src/hooks/apiHooks.tsx | 36 +++ 5 files changed, 552 insertions(+), 176 deletions(-) create mode 100644 src/hooks/apiHooks.test.ts diff --git a/package-lock.json b/package-lock.json index 49e0477d..7d7be9c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,6 +50,9 @@ "@commitlint/config-conventional": "14.1.0", "@testing-library/jest-dom": "5.15.0", "@testing-library/react": "12.1.2", + "@testing-library/react-hooks": "^8.0.0", + "@types/cors": "^2.8.12", + "@types/express": "^4.17.13", "@types/file-saver": "2.0.4", "@types/jest": "27.0.2", "@types/qrcode.react": "1.0.2", @@ -66,6 +69,7 @@ "babel-loader": "8.1.0", "babel-plugin-syntax-dynamic-import": "6.18.0", "babel-plugin-tsconfig-paths": "1.0.2", + "cors": "^2.8.5", "depcheck": "^1.4.3", "eslint": "7.24.0", "eslint-config-prettier": "8.2.0", @@ -78,6 +82,7 @@ "eslint-plugin-react": "7.23.2", "eslint-plugin-react-hooks": "4.2.0", "eslint-plugin-testing-library": "3.10.2", + "express": "^4.17.3", "file-loader": "6.2.0", "prettier": "2.4.1", "react-scripts": "4.0.3", @@ -3820,6 +3825,36 @@ "react-dom": "*" } }, + "node_modules/@testing-library/react-hooks": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.0.tgz", + "integrity": "sha512-uZqcgtcUUtw7Z9N32W13qQhVAD+Xki2hxbTR461MKax8T6Jr8nsUvZB+vcBTkzY2nFvsUet434CsgF0ncW2yFw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "react-error-boundary": "^3.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0", + "react": "^16.9.0 || ^17.0.0", + "react-dom": "^16.9.0 || ^17.0.0", + "react-test-renderer": "^16.9.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-test-renderer": { + "optional": true + } + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -3908,6 +3943,31 @@ "@types/node": "*" } }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", + "dev": true + }, "node_modules/@types/eslint": { "version": "7.28.2", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.2.tgz", @@ -3924,6 +3984,29 @@ "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", "dev": true }, + "node_modules/@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "node_modules/@types/file-saver": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.4.tgz", @@ -4015,6 +4098,12 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, "node_modules/@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -4072,6 +4161,18 @@ "@types/react": "*" } }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, "node_modules/@types/react": { "version": "17.0.34", "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.34.tgz", @@ -4180,6 +4281,16 @@ "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==", "dev": true }, + "node_modules/@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "node_modules/@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -4773,13 +4884,13 @@ } }, "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { "node": ">= 0.6" @@ -6153,30 +6264,30 @@ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, "node_modules/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", "dev": true, "dependencies": { - "bytes": "3.1.0", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", - "http-errors": "1.7.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" }, "engines": { "node": ">= 0.8" } }, "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "engines": { "node": ">= 0.8" @@ -7328,9 +7439,9 @@ } }, "node_modules/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "dev": true, "engines": { "node": ">= 0.6" @@ -7435,6 +7546,19 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cosmiconfig": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", @@ -10455,17 +10579,17 @@ } }, "node_modules/express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", "dev": true, "dependencies": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", + "body-parser": "1.19.2", + "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.0", + "cookie": "0.4.2", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~1.1.2", @@ -10479,13 +10603,13 @@ "on-finished": "~2.3.0", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", + "proxy-addr": "~2.0.7", + "qs": "6.9.7", "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", "statuses": "~1.5.0", "type-is": "~1.6.18", "utils-merge": "1.0.1", @@ -10502,12 +10626,12 @@ "dev": true }, "node_modules/express/node_modules/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "dependencies": { - "safe-buffer": "5.1.2" + "safe-buffer": "5.2.1" }, "engines": { "node": ">= 0.6" @@ -10543,6 +10667,26 @@ "node": ">= 0.6" } }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ext": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", @@ -12085,27 +12229,21 @@ "dev": true }, "node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dev": true, "dependencies": { "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "toidentifier": "1.0.1" }, "engines": { "node": ">= 0.6" } }, - "node_modules/http-errors/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, "node_modules/http-parser-js": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", @@ -16260,21 +16398,21 @@ } }, "node_modules/mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "dependencies": { - "mime-db": "1.50.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -16634,9 +16772,9 @@ "dev": true }, "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, "engines": { "node": ">= 0.6" @@ -21388,12 +21526,15 @@ } }, "node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", "dev": true, "engines": { "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/query-ast": { @@ -21499,13 +21640,13 @@ } }, "node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", "dev": true, "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "bytes": "3.1.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -21514,9 +21655,9 @@ } }, "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "engines": { "node": ">= 0.8" @@ -21851,6 +21992,22 @@ "react": ">= 16.8" } }, + "node_modules/react-error-boundary": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", + "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, "node_modules/react-error-overlay": { "version": "6.0.9", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", @@ -23589,9 +23746,9 @@ "dev": true }, "node_modules/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", "dev": true, "dependencies": { "debug": "2.6.9", @@ -23601,9 +23758,9 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.7.2", + "http-errors": "1.8.1", "mime": "1.6.0", - "ms": "2.1.1", + "ms": "2.1.3", "on-finished": "~2.3.0", "range-parser": "~1.2.1", "statuses": "~1.5.0" @@ -23628,9 +23785,9 @@ "dev": true }, "node_modules/send/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node_modules/send/node_modules/range-parser": { @@ -23751,15 +23908,15 @@ "dev": true }, "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", "dev": true, "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.1" + "send": "0.17.2" }, "engines": { "node": ">= 0.8.0" @@ -23821,9 +23978,9 @@ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, "node_modules/sha.js": { @@ -25581,9 +25738,9 @@ "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" }, "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, "engines": { "node": ">=0.6" @@ -31122,6 +31279,16 @@ "@testing-library/dom": "^8.0.0" } }, + "@testing-library/react-hooks": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.0.tgz", + "integrity": "sha512-uZqcgtcUUtw7Z9N32W13qQhVAD+Xki2hxbTR461MKax8T6Jr8nsUvZB+vcBTkzY2nFvsUet434CsgF0ncW2yFw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "react-error-boundary": "^3.1.0" + } + }, "@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -31207,6 +31374,31 @@ "@types/node": "*" } }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", + "dev": true + }, "@types/eslint": { "version": "7.28.2", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.2.tgz", @@ -31223,6 +31415,29 @@ "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", "dev": true }, + "@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "@types/file-saver": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.4.tgz", @@ -31314,6 +31529,12 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, "@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -31371,6 +31592,18 @@ "@types/react": "*" } }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, "@types/react": { "version": "17.0.34", "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.34.tgz", @@ -31481,6 +31714,16 @@ "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==", "dev": true }, + "@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -31979,13 +32222,13 @@ } }, "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, "acorn": { @@ -33086,27 +33329,27 @@ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", "dev": true, "requires": { - "bytes": "3.1.0", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", - "http-errors": "1.7.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" }, "dependencies": { "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true }, "debug": { @@ -34067,9 +34310,9 @@ } }, "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "dev": true }, "cookie-signature": { @@ -34152,6 +34395,16 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "cosmiconfig": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", @@ -36487,17 +36740,17 @@ } }, "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", "dev": true, "requires": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", + "body-parser": "1.19.2", + "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.0", + "cookie": "0.4.2", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~1.1.2", @@ -36511,13 +36764,13 @@ "on-finished": "~2.3.0", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", + "proxy-addr": "~2.0.7", + "qs": "6.9.7", "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", "statuses": "~1.5.0", "type-is": "~1.6.18", "utils-merge": "1.0.1", @@ -36531,12 +36784,12 @@ "dev": true }, "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "5.2.1" } }, "debug": { @@ -36565,6 +36818,12 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true } } }, @@ -37777,24 +38036,16 @@ "dev": true }, "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dev": true, "requires": { "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } + "toidentifier": "1.0.1" } }, "http-parser-js": { @@ -41063,18 +41314,18 @@ "dev": true }, "mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true }, "mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "requires": { - "mime-db": "1.50.0" + "mime-db": "1.52.0" } }, "mimic-fn": { @@ -41362,9 +41613,9 @@ "dev": true }, "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true }, "neo-async": { @@ -45055,9 +45306,9 @@ } }, "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", "dev": true }, "query-ast": { @@ -45136,21 +45387,21 @@ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" }, "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", "dev": true, "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "bytes": "3.1.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, "dependencies": { "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true } } @@ -45409,6 +45660,15 @@ "prop-types": "^15.7.2" } }, + "react-error-boundary": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", + "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5" + } + }, "react-error-overlay": { "version": "6.0.9", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", @@ -46767,9 +47027,9 @@ "dev": true }, "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", "dev": true, "requires": { "debug": "2.6.9", @@ -46779,9 +47039,9 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.7.2", + "http-errors": "1.8.1", "mime": "1.6.0", - "ms": "2.1.1", + "ms": "2.1.3", "on-finished": "~2.3.0", "range-parser": "~1.2.1", "statuses": "~1.5.0" @@ -46805,9 +47065,9 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "range-parser": { @@ -46919,15 +47179,15 @@ } }, "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", "dev": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.1" + "send": "0.17.2" } }, "set-blocking": { @@ -46976,9 +47236,9 @@ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, "sha.js": { @@ -48399,9 +48659,9 @@ "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" }, "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, "tough-cookie": { diff --git a/package.json b/package.json index 7d275ec0..78156148 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,9 @@ "@commitlint/config-conventional": "14.1.0", "@testing-library/jest-dom": "5.15.0", "@testing-library/react": "12.1.2", + "@testing-library/react-hooks": "^8.0.0", + "@types/cors": "^2.8.12", + "@types/express": "^4.17.13", "@types/file-saver": "2.0.4", "@types/jest": "27.0.2", "@types/qrcode.react": "1.0.2", @@ -80,6 +83,7 @@ "babel-loader": "8.1.0", "babel-plugin-syntax-dynamic-import": "6.18.0", "babel-plugin-tsconfig-paths": "1.0.2", + "cors": "^2.8.5", "depcheck": "^1.4.3", "eslint": "7.24.0", "eslint-config-prettier": "8.2.0", @@ -92,6 +96,7 @@ "eslint-plugin-react": "7.23.2", "eslint-plugin-react-hooks": "4.2.0", "eslint-plugin-testing-library": "3.10.2", + "express": "^4.17.3", "file-loader": "6.2.0", "prettier": "2.4.1", "react-scripts": "4.0.3", diff --git a/src/config.ts b/src/config.ts index fc059a4b..f25e728e 100644 --- a/src/config.ts +++ b/src/config.ts @@ -9,6 +9,7 @@ class Config { public readonly BEE_DOCS_HOST: string public readonly BEE_DISCORD_HOST: string public readonly GITHUB_REPO_URL: string + public readonly BEE_DESKTOP_URL: string constructor() { this.BEE_API_HOST = @@ -21,6 +22,7 @@ class Config { this.BEE_DISCORD_HOST = getProcessEnv('REACT_APP_BEE_DISCORD_HOST') || 'https://discord.gg/eKr9XPv7' this.GITHUB_REPO_URL = getProcessEnv('REACT_APP_BEE_GITHUB_REPO_URL') || 'https://api.github.com/repos/ethersphere/bee' + this.BEE_DESKTOP_URL = getProcessEnv('REACT_APP_BEE_DESKTOP_URL') || window.location.origin } } diff --git a/src/hooks/apiHooks.test.ts b/src/hooks/apiHooks.test.ts new file mode 100644 index 00000000..4995804f --- /dev/null +++ b/src/hooks/apiHooks.test.ts @@ -0,0 +1,73 @@ +import { renderHook } from '@testing-library/react-hooks' +import express from 'express' +import cors from 'cors' +import type { Server } from 'http' +import { useIsBeeDesktop } from './apiHooks' + +interface AddressInfo { + address: string + family: string + port: number +} + +export function mockServer(data: Record): Promise { + const app = express() + app.use(cors()) + + app.get('/info', (req, res) => { + res.send(data) + }) + + return new Promise(resolve => { + const server = app.listen(() => { + resolve(server) + }) + }) +} + +let serverCorrect: Server +let serverWrong: Server + +let serverCorrectURL: string +let serverWrongURL: string + +beforeAll(async () => { + serverCorrect = await mockServer({ name: 'bee-desktop' }) + const portServerCorrect = (serverCorrect.address() as AddressInfo).port + serverCorrectURL = `http://localhost:${portServerCorrect}` + + serverWrong = await mockServer({ foo: 'bar' }) + const portServerWrong = (serverWrong.address() as AddressInfo).port + serverWrongURL = `http://localhost:${portServerWrong}` +}) + +afterAll(async () => { + await new Promise(resolve => serverCorrect.close(resolve)) + await new Promise(resolve => serverWrong.close(resolve)) +}) + +describe('useIsBeeDesktop', () => { + it('should fail when connected to wrong server', async () => { + const { result, waitFor } = renderHook(() => useIsBeeDesktop({ BEE_DESKTOP_URL: serverWrongURL })) + + expect(result.current.isLoading).toBe(true) + expect(result.current.isBeeDesktop).toBe(false) + + await waitFor(() => { + expect(result.current.isLoading).toBe(false) + }) + expect(result.current.isBeeDesktop).toBe(false) + }) + + it('should return isBeeDesktop true when connected to bee-desktop', async () => { + const { result, waitFor } = renderHook(() => useIsBeeDesktop({ BEE_DESKTOP_URL: serverCorrectURL })) + + expect(result.current.isLoading).toBe(true) + expect(result.current.isBeeDesktop).toBe(false) + + await waitFor(() => { + expect(result.current.isLoading).toBe(false) + }) + expect(result.current.isBeeDesktop).toBe(true) + }) +}) diff --git a/src/hooks/apiHooks.tsx b/src/hooks/apiHooks.tsx index 2f288bf2..f6cf7145 100644 --- a/src/hooks/apiHooks.tsx +++ b/src/hooks/apiHooks.tsx @@ -8,6 +8,42 @@ export interface LatestBeeReleaseHook { error: Error | null } +export interface IsBeeDesktopHook { + isBeeDesktop: boolean + isLoading: boolean +} + +interface Config { + BEE_DESKTOP_URL: string +} + +/** + * Detect if the dashboard is run within bee-desktop + * + * @returns isBeeDesktop true if this is run within bee-desktop + */ +export const useIsBeeDesktop = (conf: Config = config): IsBeeDesktopHook => { + const [isBeeDesktop, setIsBeeDesktop] = useState(false) + const [isLoading, setLoading] = useState(true) + + useEffect(() => { + axios + .get(`${conf.BEE_DESKTOP_URL}/info`) + .then(res => { + if (res.data?.name === 'bee-desktop') setIsBeeDesktop(true) + else setIsBeeDesktop(false) + }) + .catch(() => { + setIsBeeDesktop(false) + }) + .finally(() => { + setLoading(false) + }) + }, [conf]) + + return { isBeeDesktop, isLoading } +} + export const useLatestBeeRelease = (): LatestBeeReleaseHook => { const [latestBeeRelease, setLatestBeeRelease] = useState(null) const [isLoadingLatestBeeRelease, setLoading] = useState(false) From 0a31a0414870bf3964d5725131cac6aad11b7e69 Mon Sep 17 00:00:00 2001 From: Vojtech Simetka Date: Thu, 14 Apr 2022 15:30:46 +0500 Subject: [PATCH 4/7] chore(deps): update bee-js to 3.3.4 (#336) --- package-lock.json | 55 +++++++++++------------------------------------ package.json | 2 +- 2 files changed, 13 insertions(+), 44 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7d7be9c7..2a071c3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.13.0", "license": "BSD-3-Clause", "dependencies": { - "@ethersphere/bee-js": "^3.3.3", + "@ethersphere/bee-js": "^3.3.4", "@ethersphere/manifest-js": "1.1.0", "@ethersphere/swarm-cid": "^0.1.0", "@material-ui/core": "4.12.3", @@ -2218,26 +2218,26 @@ } }, "node_modules/@ethersphere/bee-js": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@ethersphere/bee-js/-/bee-js-3.3.3.tgz", - "integrity": "sha512-T/JnAiBBD5bwUcxW9Vg5up9O6yabqWrVqGVdGdb1TjER46gJu2qO7OligwRKR6rUZTS3Vb1eBsHokofP7Wa1GQ==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@ethersphere/bee-js/-/bee-js-3.3.4.tgz", + "integrity": "sha512-uxH0kR31tE8IKVON7jyQHANZ/5edlU8OUCz/qyRft1YeS+L4HzEHAD3bN58iE842nt6Iz/fekrJ7yk1ONIcDBg==", "dependencies": { "@types/readable-stream": "^2.3.13", "bufferutil": "^4.0.6", - "cross-blob": "^2.0.1", "elliptic": "^6.5.4", + "fetch-blob": "2.1.2", "isomorphic-ws": "^4.0.1", "js-sha3": "^0.8.0", "ky": "^0.25.1", "ky-universal": "^0.8.2", "semver": "^7.3.5", "tar-js": "^0.3.0", - "utf-8-validate": "^5.0.8", + "utf-8-validate": "^5.0.9", "web-streams-polyfill": "^4.0.0-beta.1", "ws": "^8.5.0" }, "engines": { - "bee": "1.5.0-dda5606e", + "bee": "1.5.1-d0a77598", "beeApiVersion": "3.0.0", "beeDebugApiVersion": "2.0.0", "node": ">=12.0.0", @@ -6247,11 +6247,6 @@ "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" }, - "node_modules/blob-polyfill": { - "version": "5.0.20210201", - "resolved": "https://registry.npmjs.org/blob-polyfill/-/blob-polyfill-5.0.20210201.tgz", - "integrity": "sha512-SrH6IG6aXL9pCgSysBCiDpGcAJ1j6/c1qCwR3sTEQJhb+MTk6FITNA6eW6WNYQDNZVi4Z9GjxH5v2MMTv59CrQ==" - }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -7616,18 +7611,6 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, - "node_modules/cross-blob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cross-blob/-/cross-blob-2.0.1.tgz", - "integrity": "sha512-ARuKPPo3I6DSqizal4UCyMCiGPQdMpMJS3Owx6Lleuh26vSt2UnfWRwbMLCYqbJUrcol+KzGVSLR91ezSHP80A==", - "dependencies": { - "blob-polyfill": "^5.0.20210201", - "fetch-blob": "^2.1.2" - }, - "engines": { - "node": "^10.17.0 || >=12.3.0" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -30125,21 +30108,21 @@ } }, "@ethersphere/bee-js": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@ethersphere/bee-js/-/bee-js-3.3.3.tgz", - "integrity": "sha512-T/JnAiBBD5bwUcxW9Vg5up9O6yabqWrVqGVdGdb1TjER46gJu2qO7OligwRKR6rUZTS3Vb1eBsHokofP7Wa1GQ==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@ethersphere/bee-js/-/bee-js-3.3.4.tgz", + "integrity": "sha512-uxH0kR31tE8IKVON7jyQHANZ/5edlU8OUCz/qyRft1YeS+L4HzEHAD3bN58iE842nt6Iz/fekrJ7yk1ONIcDBg==", "requires": { "@types/readable-stream": "^2.3.13", "bufferutil": "^4.0.6", - "cross-blob": "^2.0.1", "elliptic": "^6.5.4", + "fetch-blob": "2.1.2", "isomorphic-ws": "^4.0.1", "js-sha3": "^0.8.0", "ky": "^0.25.1", "ky-universal": "^0.8.2", "semver": "^7.3.5", "tar-js": "^0.3.0", - "utf-8-validate": "^5.0.8", + "utf-8-validate": "^5.0.9", "web-streams-polyfill": "^4.0.0-beta.1", "ws": "^8.5.0" }, @@ -33312,11 +33295,6 @@ "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" }, - "blob-polyfill": { - "version": "5.0.20210201", - "resolved": "https://registry.npmjs.org/blob-polyfill/-/blob-polyfill-5.0.20210201.tgz", - "integrity": "sha512-SrH6IG6aXL9pCgSysBCiDpGcAJ1j6/c1qCwR3sTEQJhb+MTk6FITNA6eW6WNYQDNZVi4Z9GjxH5v2MMTv59CrQ==" - }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -34459,15 +34437,6 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, - "cross-blob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cross-blob/-/cross-blob-2.0.1.tgz", - "integrity": "sha512-ARuKPPo3I6DSqizal4UCyMCiGPQdMpMJS3Owx6Lleuh26vSt2UnfWRwbMLCYqbJUrcol+KzGVSLR91ezSHP80A==", - "requires": { - "blob-polyfill": "^5.0.20210201", - "fetch-blob": "^2.1.2" - } - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", diff --git a/package.json b/package.json index 78156148..ebf844a9 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "url": "https://github.com/ethersphere/bee-dashboard.git" }, "dependencies": { - "@ethersphere/bee-js": "^3.3.3", + "@ethersphere/bee-js": "^3.3.4", "@ethersphere/manifest-js": "1.1.0", "@ethersphere/swarm-cid": "^0.1.0", "@material-ui/core": "4.12.3", From 8f51aa9e898672c338d96d94b473da14aafab8a4 Mon Sep 17 00:00:00 2001 From: Vojtech Simetka Date: Thu, 14 Apr 2022 15:31:09 +0500 Subject: [PATCH 5/7] ci: migrate to swarm-actions for PR previews (#310) --- .github/workflows/check.yaml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 854f3807..decb3cda 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -74,15 +74,18 @@ jobs: run: npm run build:component - name: Create preview - uses: ethersphere/beeload-action@v1 + uses: ethersphere/swarm-actions/pr-preview@v0 with: bee-url: https://unlimited.gateway.ethswarm.org - preview: 'true' token: ${{ secrets.GHA_PAT_BASIC }} - extra-params: '-H "${{ secrets.GATEWAY_AUTHORIZATION_HEADER }}"' + error-document: index.html + headers: "${{ secrets.GATEWAY_AUTHORIZATION_HEADER }}" - name: Upload to testnet + uses: ethersphere/swarm-actions/upload-dir@v0 continue-on-error: true - uses: ethersphere/beeload-action@v1 with: + index-document: index.html + error-document: index.html + dir: ./build bee-url: https://api.gateway.testnet.ethswarm.org From 36da804ca427b9f4ca52bb9724f42743d672b165 Mon Sep 17 00:00:00 2001 From: bee-worker <70210089+bee-worker@users.noreply.github.com> Date: Thu, 14 Apr 2022 12:42:02 +0200 Subject: [PATCH 6/7] docs: update supported bee (#337) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4718a9d2..5abc647e 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ **Warning: This project is in alpha state. There might (and most probably will) be changes in the future to its API and working. Also, no guarantees can be made about its stability, efficiency, and security at this stage.** -This project is intended to be used with **Bee version 1.5.0-dda5606e**. +This project is intended to be used with **Bee version 1.5.1-d0a77598**. Using it with older or newer Bee versions is not recommended and may not work. Stay up to date by joining the [official Discord](https://discord.gg/GU22h2utj6) and by keeping an eye on the [releases tab](https://github.com/ethersphere/bee-dashboard/releases). From 9b5b2973cbc1d55ef9fb2facc593e15a4ea50d5e Mon Sep 17 00:00:00 2001 From: bee-worker <70210089+bee-worker@users.noreply.github.com> Date: Thu, 14 Apr 2022 13:03:11 +0200 Subject: [PATCH 7/7] chore: release 0.14.0 (#319) --- CHANGELOG.md | 14 ++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bdde0c06..88aff0f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## [0.14.0](https://www.github.com/ethersphere/bee-dashboard/compare/v0.13.0...v0.14.0) (2022-04-14) + + +### Features + +* add hook that detects if the bee-dashboard is run within bee-desktop ([#334](https://www.github.com/ethersphere/bee-dashboard/issues/334)) ([eb9e309](https://www.github.com/ethersphere/bee-dashboard/commit/eb9e309c8bc0327d137f190d6873618cb215fece)) +* detect bee mode and enable/disable status checks accordingly ([#318](https://www.github.com/ethersphere/bee-dashboard/issues/318)) ([8baecb7](https://www.github.com/ethersphere/bee-dashboard/commit/8baecb783f1574af1cd1f17738efae4b0ac9f0c8)) +* optional status checks (e.g. connected peers > 0 or funded chequebook) ([#331](https://www.github.com/ethersphere/bee-dashboard/issues/331)) ([5d0fbf7](https://www.github.com/ethersphere/bee-dashboard/commit/5d0fbf705dfed6738980c751a9654199d60a3787)) + + +### Bug Fixes + +* postage stamp price and TTL calculation ([#305](https://www.github.com/ethersphere/bee-dashboard/issues/305)) ([d0b3f1a](https://www.github.com/ethersphere/bee-dashboard/commit/d0b3f1abee7ea017bdd05954d5fadafb67365efd)) + ## [0.13.0](https://www.github.com/ethersphere/bee-dashboard/compare/v0.12.0...v0.13.0) (2022-01-28) diff --git a/package-lock.json b/package-lock.json index 2a071c3b..6b5660b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ethersphere/bee-dashboard", - "version": "0.13.0", + "version": "0.14.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ethersphere/bee-dashboard", - "version": "0.13.0", + "version": "0.14.0", "license": "BSD-3-Clause", "dependencies": { "@ethersphere/bee-js": "^3.3.4", diff --git a/package.json b/package.json index ebf844a9..3dd059ab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ethersphere/bee-dashboard", - "version": "0.13.0", + "version": "0.14.0", "description": "An app which helps users to setup their Bee node and do actions like cash out cheques", "keywords": [ "bee",