v0.7.2
This commit is contained in:
André Neves 2019-05-30 21:43:13 -04:00 committed by GitHub
commit fc19baa3ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 408 additions and 134 deletions

View File

@ -5,7 +5,7 @@
"browser": true,
"node": true,
"mocha": true,
"jest/globals": true
"jest": true
},
"plugins": ["flowtype", "jest"],
"settings": {

View File

@ -18,13 +18,14 @@ List of the main open source libraries and technologies used in building **Zepio
- [zcashd](https://github.com/zcash/zcash): Zcash node daemon
- [Electron](https://github.com/electron/electron): Desktop application builder
- [React](https://facebook.github.io/react/): User interface view layer
- [Redux](http://redux.js.org/): Predictable application state container
- [Redux](https://redux.js.org/): Predictable application state container
- [Styled Components](https://www.styled-components.com/): Visual primitives for theming and styling applications
- [webpack](http://webpack.github.io/): Application module bundler (and more)
- [Babel](http://babeljs.io/): ES7/JSX transpilling
- [ESLint](http://eslint.org/): Code linting rules
- [webpack](https://webpack.github.io/): Application module bundler (and more)
- [Babel](https://babeljs.io/): ES7/JSX transpilling
- [ESLint](https://eslint.org/): Code linting rules
- [Flow](https://flow.org): JavaScript static type checker
- [Docz](https://docz.site): Documentation builder
- [BigNumber.js](https://github.com/MikeMcl/bignumber.js#readme): Arbitrary-precision decimal and non-decimal arithmetic with safety
## Installing and Running From Source

View File

@ -5,6 +5,6 @@ module.exports = class {
}
get() {
return 'test value';
return 'TESTNET';
}
};

View File

@ -27,6 +27,7 @@ beforeAll(() => {
});
afterAll(() => {
global.Date = originalDate;
// $FlowFixMe
dateFns.format.mockRestore();
cleanup();
});

View File

@ -27,6 +27,7 @@ beforeAll(() => {
});
afterAll(() => {
global.Date = originalDate;
// $FlowFixMe
dateFns.format.mockRestore();
cleanup();
});

View File

@ -18,15 +18,19 @@ describe('Startup', () => {
expect(app.client.getTitle()).resolves.toEqual('Zepio');
});
test('should show the text "Zepio Starting" in loading screen', async () => expect(app.client.element('#loading-screen:first-child p').getHTML()).resolves.toEqual(
expect.stringContaining('Zepio Starting'),
));
test('should show the text "Zepio Starting" in loading screen', async () => {
expect(
app.client.element('div[data-testid~="LoadingScreen"]:first-child p').getHTML(),
).resolves.toEqual(expect.stringContaining('Zepio Starting'));
});
test('should show the zcash logo in loading screen', () => expect(app.client.getAttribute('#loading-screen:first-child img', 'src')).resolves.toEqual(
expect.stringContaining('/assets/zcash-simple-icon.svg'),
));
test('should show the zcash logo in loading screen', () => expect(
app.client.getAttribute('div[data-testid~="LoadingScreen"]:first-child img', 'src'),
).resolves.toEqual(expect.stringContaining('/assets/zcash-simple-icon.svg')));
test('should show the loading circle in loading screen', () => {
expect(app.client.element('#loading-screen svg').isExisting()).resolves.toEqual(true);
expect(
app.client.element('div[data-testid~="LoadingScreen"] svg').isExisting(),
).resolves.toEqual(true);
});
});

View File

@ -14,6 +14,6 @@ afterAll(() => app.stop());
describe('Status Pill', () => {
test('should show status pill in the header', async () => expect(
app.client.waitUntilTextExists('#status-pill', 'ready').getText('#status-pill'),
).resolves.toEqual(expect.stringContaining('ready')));
app.client.waitUntilTextExists('#status-pill', 'READY', 30000).getText('#status-pill'),
).resolves.toEqual(expect.stringContaining('READY')));
});

View File

@ -21,7 +21,7 @@ const handler = (server) => {
switch (method) {
case 'getinfo':
sleep(1500).then(() => res.send({ result: { version: 1.0 } }));
sleep(500).then(() => res.send({ result: { version: 1.0 } }));
break;
case 'getblockchaininfo':
return res.send({ result: { verificationprogress: 1 } });
@ -43,7 +43,7 @@ const handler = (server) => {
});
case 'z_sendmany':
// eslint-disable-next-line
sleep(2000).then(() => {
sleep(1000).then(() => {
const [, [obj], amount, fee] = req.body.params;
if ((obj.address[0] === 'z' || obj.address[0] === 't') && amount > 0) {
@ -109,6 +109,8 @@ const handler = (server) => {
return res.send({
result: 10,
});
case 'ping':
return res.send(null);
default:
return null;
}

View File

@ -99,12 +99,15 @@ type State = {
showTooltip: boolean,
};
const MINUTE_IN_MILI = 60000;
const INTERVAL_AFTER_READY = 60000;
const INTERVAL_BEFORE_READY = 10000;
class Component extends PureComponent<Props, State> {
timer: ?IntervalID = null;
constructor(props) {
requestOnTheFly: boolean = false;
constructor(props: Props) {
super(props);
this.state = {
@ -113,20 +116,18 @@ class Component extends PureComponent<Props, State> {
}
componentDidMount() {
const { getBlockchainStatus } = this.props;
this.timer = setInterval(() => getBlockchainStatus(), 2000);
this.timer = setInterval(() => this.updateStatus(), INTERVAL_BEFORE_READY);
}
componentDidUpdate(prevProps: Props) {
const { getBlockchainStatus, nodeSyncType } = this.props;
const { nodeSyncType } = this.props;
if (
prevProps.nodeSyncType === NODE_SYNC_TYPES.SYNCING
&& nodeSyncType === NODE_SYNC_TYPES.READY
) {
// if the status is "ready", we can increase the interval to avoid useless rpc calls
this.cleanUpdateInterval();
this.timer = setInterval(() => getBlockchainStatus(), MINUTE_IN_MILI);
this.timer = setInterval(() => this.updateStatus(), INTERVAL_AFTER_READY);
}
}
@ -134,6 +135,22 @@ class Component extends PureComponent<Props, State> {
this.cleanUpdateInterval();
}
updateStatus = () => {
if (this.requestOnTheFly) return;
this.requestOnTheFly = true;
const { getBlockchainStatus } = this.props;
getBlockchainStatus()
.then(() => {
this.requestOnTheFly = false;
})
.catch(() => {
this.requestOnTheFly = false;
});
};
cleanUpdateInterval = () => {
if (this.timer) {
clearInterval(this.timer);

View File

@ -2,6 +2,8 @@
import electron from 'electron'; // eslint-disable-line
import React, { type ComponentType, Component } from 'react';
import store from '../../config/electron-store';
import { LoadingScreen } from './loading-screen';
import rpc from '../../services/api';
@ -20,7 +22,7 @@ export const withDaemonStatusCheck = <PassedProps: {}>(
): ComponentType<$Diff<PassedProps, Props>> => class extends Component<PassedProps, State> {
timer: ?IntervalID = null;
hasDaemonError: boolean = false;
requestOnTheFly: boolean = false;
state = {
isRunning: false,
@ -32,18 +34,25 @@ export const withDaemonStatusCheck = <PassedProps: {}>(
this.runTest();
this.timer = setInterval(this.runTest, 3000);
electron.ipcRenderer.on('zcash-daemon-status', (event: empty, message: Object) => {
this.hasDaemonError = message.error;
electron.ipcRenderer.on(
'zcash-daemon-status',
(
event: empty,
message: {
error: boolean,
status: string,
},
) => {
if (message.error) {
clearInterval(this.timer);
}
if (message.error) {
clearInterval(this.timer);
}
this.setState({
message: message.status,
...(message.error ? { progress: 0, isRunning: false } : {}),
});
});
this.setState({
message: message.status,
...(message.error ? { progress: 0, isRunning: false } : {}),
});
},
);
}
componentWillUnmount() {
@ -54,30 +63,31 @@ export const withDaemonStatusCheck = <PassedProps: {}>(
}
runTest = () => {
if (this.hasDaemonError) return;
const daemonPID: number = store.get('DAEMON_PROCESS_PID');
if (this.requestOnTheFly || !daemonPID) return;
this.requestOnTheFly = true;
rpc
.getinfo()
.then((response) => {
if (this.hasDaemonError) return;
.ping()
.then(() => {
this.requestOnTheFly = false;
if (response) {
setTimeout(() => {
this.setState(() => ({ isRunning: true }));
}, 500);
this.setState(() => ({ progress: 100 }));
setTimeout(() => {
this.setState(() => ({ isRunning: true }));
}, 500);
this.setState(() => ({ progress: 100 }));
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
})
.catch((error) => {
if (this.hasDaemonError) return;
const statusMessage = error.message === 'Something went wrong' ? 'Zepio Starting' : error.message;
this.requestOnTheFly = false;
const statusMessage: string = error.message === 'Something went wrong' ? 'Zepio Starting' : error.message;
const isRpcOff = Math.trunc(error.statusCode / 100) === 5;
this.setState({

View File

@ -5,7 +5,7 @@ import { ThemeProvider } from 'styled-components';
import { appTheme } from './theme';
import { GlobalStyle } from './global';
export const DoczWrapper = ({ children }: { children: () => Node<*> }) => (
export const DoczWrapper = ({ children }: { children: () => Node }) => (
<ThemeProvider theme={appTheme}>
<Fragment>
<GlobalStyle />

View File

@ -2,7 +2,7 @@
import type { AppState } from './app-state';
export type Action = { type: $Subtype<string>, payload: Object };
export type Action = { type: string, payload: Object };
export type GetState = () => AppState;
export type Dispatch = (action: Action) => void;
export type Middleware = ({ dispatch: Dispatch, getState: GetState }) => (

View File

@ -1,4 +1,9 @@
// @flow
import electron from 'electron'; // eslint-disable-line
import { isTestnet } from '../../config/is-testnet';
export const getCoinName = () => (isTestnet() ? 'TAZ' : 'ZEC');
export const getCoinName = () => {
if (electron.remote.process.env.NODE_ENV === 'test' || isTestnet()) return 'TAZ';
return 'ZEC';
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,19 @@
// @flow
import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
import eres from 'eres';
import { getZcashFolder } from './get-zcash-folder';
const ZCASH_LOCK_FILE = '.lock';
export const checkLockFile = async (zcashPath?: string) => {
try {
const myPath = zcashPath || getZcashFolder();
const [cannotAccess] = await eres(promisify(fs.access)(path.join(myPath, ZCASH_LOCK_FILE)));
return !cannotAccess;
} catch (err) {
return false;
}
};

View File

@ -0,0 +1,17 @@
// @flow
import fs from 'fs';
import path from 'path';
import { getZcashFolder } from './get-zcash-folder';
const ZCASH_PID_FILE = 'zcashd.pid';
export const getDaemonProcessId = (zcashPath?: string) => {
try {
const myPath = zcashPath || getZcashFolder();
const buffer = fs.readFileSync(path.join(myPath, ZCASH_PID_FILE));
const pid = Number(buffer.toString().trim());
return pid;
} catch (err) {
return null;
}
};

View File

@ -0,0 +1,18 @@
// @flow
import os from 'os';
import path from 'path';
import electron from 'electron'; // eslint-disable-line
export const getZcashFolder = () => {
const { app } = electron;
if (os.platform() === 'darwin') {
return path.join(app.getPath('appData'), 'Zcash');
}
if (os.platform() === 'linux') {
return path.join(app.getPath('home'), '.zcash');
}
return path.join(app.getPath('appData'), 'Zcash');
};

View File

@ -4,7 +4,6 @@ import cp from 'child_process';
import path from 'path';
import os from 'os';
import fs from 'fs';
import processExists from 'process-exists';
/* eslint-disable import/no-extraneous-dependencies */
import isDev from 'electron-is-dev';
import type { ChildProcess } from 'child_process';
@ -24,6 +23,7 @@ import { log } from './logger';
import store from '../electron-store';
import { parseZcashConf, parseCmdArgs, generateArgsFromConf } from './parse-zcash-conf';
import { isTestnet } from '../is-testnet';
import { getDaemonProcessId } from './get-daemon-process-id';
import {
EMBEDDED_DAEMON,
ZCASH_NETWORK,
@ -46,8 +46,8 @@ const getDaemonOptions = ({
const defaultOptions = [
'-server=1',
'-showmetrics',
'--metricsui=0',
'-showmetrics=1',
'-metricsui=0',
'-metricsrefreshtime=1',
`-rpcuser=${username}`,
`-rpcpassword=${password}`,
@ -64,6 +64,7 @@ const getDaemonOptions = ({
let resolved = false;
const ZCASHD_PROCESS_NAME = getDaemonName();
const DAEMON_PROCESS_PID = 'DAEMON_PROCESS_PID';
let isWindowOpened = false;
@ -93,6 +94,7 @@ const runDaemon: () => Promise<?ChildProcess> = () => new Promise(async (resolve
});
store.delete('rpcconnect');
store.delete('rpcport');
store.delete(DAEMON_PROCESS_PID);
const processName = path.join(getBinariesPath(), getOsFolder(), ZCASHD_PROCESS_NAME);
const isRelaunch = Boolean(process.argv.find(arg => arg === '--relaunch'));
@ -127,8 +129,6 @@ const runDaemon: () => Promise<?ChildProcess> = () => new Promise(async (resolve
await waitForDaemonClose(ZCASHD_PROCESS_NAME);
}
const [, isRunning] = await eres(processExists(ZCASHD_PROCESS_NAME));
// This will parse and save rpcuser and rpcpassword in the store
let [, optionsFromZcashConf] = await eres(parseZcashConf());
@ -153,14 +153,22 @@ const runDaemon: () => Promise<?ChildProcess> = () => new Promise(async (resolve
if (optionsFromZcashConf.rpcuser) store.set('rpcuser', optionsFromZcashConf.rpcuser);
if (optionsFromZcashConf.rpcpassword) store.set('rpcpassword', optionsFromZcashConf.rpcpassword);
if (isRunning) {
log('Already is running!');
log('Searching for zcashd.pid');
const daemonProcessId = getDaemonProcessId(optionsFromZcashConf.datadir);
if (daemonProcessId) {
store.set(EMBEDDED_DAEMON, false);
// We need grab the rpcuser and rpcpassword from either process args or zcash.conf
log(
// eslint-disable-next-line
`A daemon was found running in PID: ${daemonProcessId}. Starting Zepio in external daemon mode.`,
);
// Command line args override zcash.conf
const [{ cmd }] = await findProcess('name', ZCASHD_PROCESS_NAME);
const [{ cmd, pid }] = await findProcess('pid', daemonProcessId);
store.set(DAEMON_PROCESS_PID, pid);
// We need grab the rpcuser and rpcpassword from either process args or zcash.conf
const {
rpcuser, rpcpassword, rpcconnect, rpcport, testnet: isTestnetFromCmd,
} = parseCmdArgs(
@ -180,6 +188,10 @@ const runDaemon: () => Promise<?ChildProcess> = () => new Promise(async (resolve
return resolve();
}
log(
"Zepio couldn't find a `zcashd.pid`, that means there is no instance of zcash running on the machine, trying start built-in daemon",
);
store.set(EMBEDDED_DAEMON, true);
if (!isRelaunch) {
@ -208,6 +220,8 @@ const runDaemon: () => Promise<?ChildProcess> = () => new Promise(async (resolve
},
);
store.set(DAEMON_PROCESS_PID, childProcess.pid);
childProcess.stdout.on('data', (data) => {
sendToRenderer('zcashd-log', data.toString(), false);
if (!resolved) {

View File

@ -0,0 +1,15 @@
declare module 'find-process' {
declare type searchType = 'pid' | 'port' | 'name';
declare type searchValue = string | number;
declare type process = {
pid: number,
ppid: number,
uid: string,
gid: string,
name: string,
bin: string,
cmd: string,
};
declare module.exports: (type: searchType, value: searchValue) => Array<process>;
}

View File

@ -98,7 +98,7 @@ declare module 'styled-components' {
declare type InjectedProps = { theme: Theme | void };
declare export function withTheme<Props: {}, Component: React$ComponentType<Props>>(
WrappedComponent: Component,
): React$ComponentType<$Diff<React$ElementConfig<$Supertype<Component>>, InjectedProps>>;
): React$ComponentType<$Diff<React$ElementConfig<Component>, InjectedProps>>;
// @HACK This is a cheat to hide that the underlying type is "just a string"
// once we know of a better way, we should be able to update this accordingly.
@ -350,7 +350,7 @@ declare module 'styled-components/native' {
declare type InjectedProps = { theme: Theme | void };
declare export function withTheme<Props: {}, Component: React$ComponentType<Props>>(
WrappedComponent: Component,
): React$ComponentType<$Diff<React$ElementConfig<$Supertype<Component>>, InjectedProps>>;
): React$ComponentType<$Diff<React$ElementConfig<Component>, InjectedProps>>;
// @HACK This is a cheat to hide that the underlying type is "just a string"
// once we know of a better way, we should be able to update this accordingly.

View File

@ -1,7 +1,7 @@
{
"name": "zepio",
"productName": "Zepio",
"version": "0.7.1",
"version": "0.7.2",
"description": "Zepio | Cross-platform sapling-enabled full-node Zcash wallet",
"main": "config/main.js",
"homepage": "https://zepiowallet.com",
@ -45,11 +45,12 @@
"e2e:serve": "node -r @babel/register ./__tests__/setup/mockAPI.js",
"e2e:run": "yarn test e2e"
},
"pre-commit": [
"flow:generate-coverage-badge",
"lint:precommit",
"flow:precommit"
],
"husky": {
"hooks": {
"pre-commit": "yarn lint:precommit && yarn flow:precommit",
"pre-push": "yarn flow:generate-coverage-badge && git add ./public/flow-badge.svg ./public/flow-coverage-badge.svg && git commit -m \"type(flow): update flowtype badge\" --no-verify --allow-empty"
}
},
"build": {
"appId": "com.zcashfoundation",
"productName": "Zepio",
@ -68,21 +69,6 @@
"public/",
"build/"
],
"extraFiles": [
{
"from": "bin/",
"to": "resources/bin",
"filter": [
"**/*"
]
}
],
"linux": {
"icon": "./build/icons/png",
"target": [
"deb"
]
},
"deb": {
"depends": [
"gconf2",
@ -93,17 +79,58 @@
"libnss3"
]
},
"linux": {
"icon": "./build/icons/png",
"target": [
"deb"
],
"extraFiles": [
{
"from": "bin/linux",
"to": "resources/bin/linux",
"filter": [
"**/*"
]
},
{
"from": "bin/zcash-fetch-params",
"to": "resources/bin/zcash-fetch-params"
}
]
},
"mac": {
"category": "public.app-category.productivity",
"type": "distribution",
"target": [
"dmg"
],
"icon": "./build/icons/mac/icon.icns"
"icon": "./build/icons/mac/icon.icns",
"extraFiles": [
{
"from": "bin/mac",
"to": "resources/bin/mac",
"filter": [
"**/*"
]
},
{
"from": "bin/zcash-fetch-params",
"to": "resources/bin/zcash-fetch-params"
}
]
},
"win": {
"target": "nsis",
"icon": "./build/icons/win/icon.ico"
"icon": "./build/icons/win/icon.ico",
"extraFiles": [
{
"from": "bin/win",
"to": "resources/bin/win",
"filter": [
"**/*"
]
}
]
},
"protocols": {
"name": "zcash",
@ -145,7 +172,7 @@
"docz": "0.13.4",
"docz-plugin-css": "^0.11.0",
"docz-theme-default": "0.13.4",
"electron": "^4.0.1",
"electron": "^4.2.2",
"electron-builder": "^20.38.4",
"electron-compilers": "^5.9.0",
"electron-icon-maker": "^0.0.4",
@ -159,18 +186,18 @@
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.12.4",
"file-loader": "^2.0.0",
"flow-bin": "^0.95.1",
"flow-bin": "^0.99.1",
"flow-coverage-report": "^0.6.1",
"flow-typed": "^2.5.1",
"glow": "^1.2.2",
"html-webpack-plugin": "^3.1.0",
"husky": "^2.3.0",
"jest": "^24.5.0",
"jest-dom": "^2.1.1",
"jest-extended": "^0.11.0",
"mime-types": "^2.1.22",
"node-sass": "^4.8.3",
"postcss-loader": "^3.0.0",
"pre-commit": "^1.2.2",
"react-testing-library": "^5.3.1",
"redux-logger": "^3.0.6",
"redux-mock-store": "^1.5.3",

View File

@ -8,18 +8,18 @@ import store from '../config/electron-store';
import { isTestnet } from '../config/is-testnet';
const getRPCConfig = () => {
const rpcport = store.get('rpcport');
const rpcconnect = store.get('rpcconnect');
const rpcport: string = store.get('rpcport');
const rpcconnect: string = store.get('rpcconnect');
return {
host: rpcconnect || '127.0.0.1',
port: rpcport || (isTestnet() ? 18232 : 8232),
user: store.get('rpcuser'),
password: store.get('rpcpassword'),
user: (store.get('rpcuser'): string),
password: (store.get('rpcpassword'): string),
};
};
const getMessage = (statusCode, isECONNREFUSED) => {
const getMessage = (statusCode: number, isECONNREFUSED: boolean) => {
if (isECONNREFUSED) {
return 'Zepio could not find a daemon running, please check the logs!';
}
@ -53,7 +53,10 @@ const api: APIMethods = METHODS.reduce(
params: args,
},
})
.then(data => Promise.resolve(data.body && data.body.result))
.then((data) => {
console.log('[RPC CALL SUCCESS] -', method, data.body.result);
return Promise.resolve(data.body && data.body.result);
})
.catch((payload) => {
console.log(
'[RPC CALL ERROR] - ',

192
yarn.lock
View File

@ -1715,6 +1715,11 @@
version "7.10.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.10.2.tgz#a98845168012d7a63a84d50e738829da43bdb0de"
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==
"@types/q@^1.5.1":
version "1.5.1"
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18"
@ -4230,7 +4235,7 @@ concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
concat-stream@1.6.2, concat-stream@^1.4.7, concat-stream@^1.5.0:
concat-stream@1.6.2, concat-stream@^1.5.0:
version "1.6.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
dependencies:
@ -4254,8 +4259,9 @@ concurrently@^4.1.0:
yargs "^12.0.1"
conf@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/conf/-/conf-2.1.0.tgz#43ade5879a82ff23dbeb466995d50209f7dfcd07"
version "2.2.0"
resolved "https://registry.yarnpkg.com/conf/-/conf-2.2.0.tgz#ee282efafc1450b61e205372041ad7d866802d9a"
integrity sha512-93Kz74FOMo6aWRVpAZsonOdl2I57jKtHrNmxhumehFQw4X8Sk37SohNY11PG7Q8Okta+UnrVaI006WLeyp8/XA==
dependencies:
dot-prop "^4.1.0"
env-paths "^1.0.0"
@ -4426,6 +4432,16 @@ cosmiconfig@^5.0.0, cosmiconfig@^5.0.2, cosmiconfig@^5.0.5, cosmiconfig@^5.0.7:
js-yaml "^3.9.0"
parse-json "^4.0.0"
cosmiconfig@^5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
dependencies:
import-fresh "^2.0.0"
is-directory "^0.3.1"
js-yaml "^3.13.1"
parse-json "^4.0.0"
cp-file@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-6.0.0.tgz#f38477ece100b403fcf780fd34d030486beb693e"
@ -5848,6 +5864,7 @@ electron-publish@20.38.3:
electron-store@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/electron-store/-/electron-store-2.0.0.tgz#1035cca2a95409d1f54c7466606345852450d64a"
integrity sha512-1WCFYHsYvZBqDsoaS0Relnz0rd81ZkBAI0Fgx7Nq2UWU77rSNs1qxm4S6uH7TCZ0bV3LQpJFk7id/is/ZgoOPA==
dependencies:
conf "^2.0.0"
@ -5873,9 +5890,10 @@ electron-updater@^4.0.4:
semver "^5.6.0"
source-map-support "^0.5.9"
electron@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/electron/-/electron-4.0.1.tgz#c41eaee9e081c2e5e4a4a4a761b7577a77d2eb18"
electron@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/electron/-/electron-4.2.2.tgz#e8720e68b2ef3dcf4ab721f9546cf436e08576d2"
integrity sha512-SNRr83kbsnNZU9AdYkAJZEW7UH9Q9Fvl0ynuKBXgFFulTX+Gkw5JATl2Tt4OQIKdCGUuBDaw+MEMXlaroNpceA==
dependencies:
"@types/node" "^10.12.18"
electron-download "^4.1.0"
@ -6773,6 +6791,13 @@ find-up@^2.0.0, find-up@^2.1.0:
dependencies:
locate-path "^2.0.0"
find-up@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.0.0.tgz#c367f8024de92efb75f2d4906536d24682065c3a"
integrity sha512-zoH7ZWPkRdgwYCDVoQTzqjG8JSPANhtvLhh4KVUHyKnaUJJrNeFmWIkTcNuJmR3GLMEmGYEf2S2bjgx26JTF+Q==
dependencies:
locate-path "^5.0.0"
flat-cache@^1.2.1:
version "1.3.4"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f"
@ -6795,10 +6820,10 @@ flow-annotation-check@1.8.1:
glob "7.1.1"
load-pkg "^3.0.1"
flow-bin@^0.95.1:
version "0.95.1"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.95.1.tgz#633113831ccff4b7ee70a2730f63fc43b69ba85f"
integrity sha512-06IOC/pqPMNRYtC6AMZEWYR9Fi6UdBC7gImGinPuNUpPZFnP5E9/0cBCl3DWrH4zz/gSM2HdDilU7vPGpYIr2w==
flow-bin@^0.99.1:
version "0.99.1"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.99.1.tgz#0d4f413ca84a3a95d0aa64214178684dd7c6a4c5"
integrity sha512-dipNwJlb4MsVt3IuDgPTymCNL4GFoq3pG+GbY6DmBbl0dJPWFSA383rCTmgbfFhoeJ1XCfYBan0BPryToSxiiQ==
flow-coverage-report@^0.6.1:
version "0.6.1"
@ -7085,6 +7110,11 @@ get-stdin@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
get-stdin@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-7.0.0.tgz#8d5de98f15171a125c5e516643c7a6d0ea8a96f6"
integrity sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==
get-stream@^2.1.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de"
@ -7863,6 +7893,22 @@ humanize-string@^1.0.2:
dependencies:
decamelize "^1.0.0"
husky@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/husky/-/husky-2.3.0.tgz#8b78ed24d763042df7fd899991985d65a976dd13"
integrity sha512-A/ZQSEILoq+mQM3yC3RIBSaw1bYXdkKnyyKVSUiJl+iBjVZc5LQEXdGY1ZjrDxC4IzfRPiJ0IqzEQGCN5TQa/A==
dependencies:
cosmiconfig "^5.2.0"
execa "^1.0.0"
find-up "^3.0.0"
get-stdin "^7.0.0"
is-ci "^2.0.0"
pkg-dir "^4.1.0"
please-upgrade-node "^3.1.1"
read-pkg "^5.1.1"
run-node "^1.0.0"
slash "^3.0.0"
icon-gen@1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/icon-gen/-/icon-gen-1.0.7.tgz#0c710adccbf96e10d05c4595d549df43e423a20a"
@ -9130,6 +9176,14 @@ js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.9.0:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^3.13.1:
version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@~3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
@ -9630,6 +9684,13 @@ locate-path@^3.0.0:
p-locate "^3.0.0"
path-exists "^3.0.0"
locate-path@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
dependencies:
p-locate "^4.1.0"
lodash._getnative@^3.0.0:
version "3.9.1"
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
@ -10630,6 +10691,16 @@ normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-
semver "2 || 3 || 4 || 5"
validate-npm-package-license "^3.0.1"
normalize-package-data@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
dependencies:
hosted-git-info "^2.1.4"
resolve "^1.10.0"
semver "2 || 3 || 4 || 5"
validate-npm-package-license "^3.0.1"
normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
@ -10932,10 +11003,6 @@ os-name@^3.0.0:
macos-release "^2.0.0"
windows-release "^3.1.0"
os-shim@^0.1.2:
version "0.1.3"
resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917"
os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@ -10994,6 +11061,13 @@ p-limit@^2.0.0:
dependencies:
p-try "^2.0.0"
p-limit@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2"
integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==
dependencies:
p-try "^2.0.0"
p-locate@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
@ -11006,6 +11080,13 @@ p-locate@^3.0.0:
dependencies:
p-limit "^2.0.0"
p-locate@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
dependencies:
p-limit "^2.2.0"
p-map@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
@ -11359,6 +11440,13 @@ pkg-dir@^3.0.0:
dependencies:
find-up "^3.0.0"
pkg-dir@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
dependencies:
find-up "^4.0.0"
pkg-up@2.0.0, pkg-up@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
@ -11369,6 +11457,13 @@ pkginfo@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.0.tgz#349dbb7ffd38081fcadc0853df687f0c7744cd65"
please-upgrade-node@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac"
integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ==
dependencies:
semver-compare "^1.0.0"
plist@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c"
@ -11919,14 +12014,6 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.2, postcss@^7.0.5:
source-map "^0.6.1"
supports-color "^5.5.0"
pre-commit@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/pre-commit/-/pre-commit-1.2.2.tgz#dbcee0ee9de7235e57f79c56d7ce94641a69eec6"
dependencies:
cross-spawn "^5.0.1"
spawn-sync "^1.0.15"
which "1.2.x"
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
@ -12689,6 +12776,16 @@ read-pkg@^4.0.1:
parse-json "^4.0.0"
pify "^3.0.0"
read-pkg@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.1.1.tgz#5cf234dde7a405c90c88a519ab73c467e9cb83f5"
integrity sha512-dFcTLQi6BZ+aFUaICg7er+/usEoqFdQxiEBsEMNGoipenihtxxtdrQuBXvyANCEI8VuUIVYFgeHGx9sLLvim4w==
dependencies:
"@types/normalize-package-data" "^2.4.0"
normalize-package-data "^2.5.0"
parse-json "^4.0.0"
type-fest "^0.4.1"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
@ -13288,6 +13385,13 @@ resolve@1.1.7, resolve@1.1.x:
version "1.1.7"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
resolve@^1.10.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232"
integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==
dependencies:
path-parse "^1.0.6"
resolve@^1.2.0, resolve@^1.3.2, resolve@^1.6.0, resolve@^1.7.1, resolve@^1.8.1, resolve@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06"
@ -13369,6 +13473,11 @@ run-async@^2.2.0:
dependencies:
is-promise "^2.1.0"
run-node@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e"
integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==
run-queue@^1.0.0, run-queue@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
@ -13546,6 +13655,11 @@ selfsigned@^1.9.1:
dependencies:
node-forge "0.7.5"
semver-compare@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
semver-diff@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
@ -13738,6 +13852,11 @@ slash@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
slice-ansi@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
@ -13911,13 +14030,6 @@ spawn-rx@^2.0.3:
lodash.assign "^4.2.0"
rxjs "^5.1.1"
spawn-sync@^1.0.15:
version "1.0.15"
resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476"
dependencies:
concat-stream "^1.4.7"
os-shim "^0.1.2"
spawndamnit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/spawndamnit/-/spawndamnit-1.0.0.tgz#b5d4a1a73016dbcca8f8b1e283eee76a649161b8"
@ -14829,6 +14941,11 @@ type-check@~0.3.2:
dependencies:
prelude-ls "~1.1.2"
type-fest@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8"
integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==
type-is@^1.6.16, type-is@~1.6.16:
version "1.6.16"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"
@ -15791,12 +15908,6 @@ which@1, which@^1.1.1, which@^1.2.10, which@^1.2.12, which@^1.2.14, which@^1.2.9
dependencies:
isexe "^2.0.0"
which@1.2.x:
version "1.2.14"
resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
dependencies:
isexe "^2.0.0"
wide-align@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
@ -15883,7 +15994,7 @@ write-file-atomic@2.4.1:
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
write-file-atomic@^2.0.0, write-file-atomic@^2.3.0:
write-file-atomic@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab"
dependencies:
@ -15891,6 +16002,15 @@ write-file-atomic@^2.0.0, write-file-atomic@^2.3.0:
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
write-file-atomic@^2.3.0:
version "2.4.3"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481"
integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==
dependencies:
graceful-fs "^4.1.11"
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
write@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"