diff options
| author | Andrej Mihajlov <and@codeispoetry.ru> | 2017-07-03 12:06:05 +0300 |
|---|---|---|
| committer | Andrej Mihajlov <and@codeispoetry.ru> | 2017-07-03 12:06:05 +0300 |
| commit | 4e8f44c7ef6ffee09d9d3abd70bfd093f87d6b18 (patch) | |
| tree | a0b84c64f77fb3316f33bc031760172fce0fd0cc | |
| parent | ab9d8b2471dbcd54bb882b3b6722626f81b71053 (diff) | |
| parent | 5b5c897152a2208e546e56d6bdd731e2bb04ae80 (diff) | |
| download | mullvadvpn-4e8f44c7ef6ffee09d9d3abd70bfd093f87d6b18.tar.xz mullvadvpn-4e8f44c7ef6ffee09d9d3abd70bfd093f87d6b18.zip | |
Merge branch 'feature/flow-typed/components'
| -rw-r--r-- | app/app.js | 2 | ||||
| -rw-r--r-- | app/components/Account.js | 47 | ||||
| -rw-r--r-- | app/components/AccountInput.js | 187 | ||||
| -rw-r--r-- | app/components/Connect.js | 52 | ||||
| -rw-r--r-- | app/components/CustomScrollbars.js | 23 | ||||
| -rw-r--r-- | app/components/HeaderBar.js | 21 | ||||
| -rw-r--r-- | app/components/Layout.js | 69 | ||||
| -rw-r--r-- | app/components/Login.js | 140 | ||||
| -rw-r--r-- | app/components/SelectLocation.js | 39 | ||||
| -rw-r--r-- | app/components/Settings.js | 45 | ||||
| -rw-r--r-- | app/components/Switch.js | 89 | ||||
| -rw-r--r-- | app/components/WindowChrome.js | 18 | ||||
| -rw-r--r-- | app/containers/SettingsPage.js | 5 | ||||
| -rw-r--r-- | app/types.js | 4 | ||||
| -rw-r--r-- | package.json | 8 | ||||
| -rw-r--r-- | yarn.lock | 472 |
16 files changed, 492 insertions, 729 deletions
diff --git a/app/app.js b/app/app.js index f63a24733f..ee59f1c0f4 100644 --- a/app/app.js +++ b/app/app.js @@ -102,7 +102,7 @@ if(!rootElement) { ReactDOM.render( <Provider store={ store }> <ConnectedRouter history={ memoryHistory }> - { makeRoutes(store.getState, { backend }) } + { makeRoutes(store.getState, { backend }) } </ConnectedRouter> </Provider>, rootElement diff --git a/app/components/Account.js b/app/components/Account.js index 7aaec4f2e6..e817baa280 100644 --- a/app/components/Account.js +++ b/app/components/Account.js @@ -1,43 +1,40 @@ +// @flow import moment from 'moment'; import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import { If, Then, Else } from 'react-if'; import { Layout, Container, Header } from './Layout'; import { formatAccount } from '../lib/formatters'; import ExternalLinkSVG from '../assets/images/icon-extLink.svg'; -export default class Account extends Component { - - static propTypes = { - onLogout: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - onExternalLink: PropTypes.func.isRequired - } +import type { UserReduxState } from '../reducers/user'; - onClose() { - this.props.onClose(); - } +export type AccountProps = { + user: UserReduxState; + onLogout: () => void; + onClose: () => void; + onExternalLink: (type: string) => void; +}; - onExternalLink(type) { - this.props.onExternalLink(type); - } +export default class Account extends Component { + props: AccountProps; - onLogout() { - this.props.onLogout(); - } + onBuyMore = () => this.props.onExternalLink('purchase'); + onClose = () => this.props.onClose(); + onLogout = () => this.props.onLogout(); - render() { - let paidUntil = moment(this.props.user.paidUntil); - let formattedAccountId = formatAccount(this.props.user.account); - let formattedPaidUntil = paidUntil.format('hA, D MMMM YYYY').toUpperCase(); - let isOutOfTime = paidUntil.isSameOrBefore(moment()); + render(): React.Element<*> { + const user = this.props.user; + const paidUntil = moment(user.paidUntil); + const formattedAccountId = formatAccount(user.account || ''); + const formattedPaidUntil = paidUntil.format('hA, D MMMM YYYY').toUpperCase(); + const isOutOfTime = paidUntil.isSameOrBefore(moment()); return ( <Layout> <Header hidden={ true } style={ 'defaultDark' } /> <Container> <div className="account"> - <div className="account__close" onClick={ ::this.onClose }> + <div className="account__close" onClick={ this.onClose }> <img className="account__close-icon" src="./assets/images/icon-back.svg" /> <span className="account__close-title">Settings</span> </div> @@ -68,11 +65,11 @@ export default class Account extends Component { </div> <div className="account__footer"> - <button className="button button--positive" onClick={ this.onExternalLink.bind(this, 'purchase') }> + <button className="button button--positive" onClick={ this.onBuyMore }> <span className="button-label">Buy more time</span> <ExternalLinkSVG className="button-icon button-icon--16" /> </button> - <button className="button button--negative" onClick={ ::this.onLogout }>Logout</button> + <button className="button button--negative" onClick={ this.onLogout }>Logout</button> </div> </div> diff --git a/app/components/AccountInput.js b/app/components/AccountInput.js index 3e6993a9bb..0aeed76551 100644 --- a/app/components/AccountInput.js +++ b/app/components/AccountInput.js @@ -1,56 +1,57 @@ +// @flow import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import { formatAccount } from '../lib/formatters'; -/** - * Account input field with automatic formatting - * - * @export - * @class AccountInput - * @extends {React.Component} - */ +// @TODO: move it into types.js + +// ESLint issue: https://github.com/babel/babel-eslint/issues/445 +/* eslint-disable no-unused-vars */ +declare class ClipboardData { + setData(type: string, data: string): void; + getData(type: string): string; +} + +declare class ClipboardEvent extends Event { + clipboardData: ClipboardData; +} + +type AccountInputProps = { + value: string; + onEnter: () => void; + onChange: (newValue: string) => void; +}; + +type AccountInputState = { + value: string; + selectionRange: SelectionRange; +}; + +type SelectionRange = [number, number]; + export default class AccountInput extends Component { + props: AccountInputProps; + state: AccountInputState = { + value: '', + selectionRange: [0, 0] + }; - /** - * Prop types - * @static - * - * @memberOf AccountInput - */ - static propTypes = { - value: PropTypes.string, - onEnter: PropTypes.func, - onChange: PropTypes.func - } + _ref: ?HTMLInputElement; + _ignoreSelect = false; - /** - * Creates an instance of AccountInput. - * @param {object} props - * - * @memberOf AccountInput - */ - constructor(props) { + constructor(props: AccountInputProps) { super(props); // selection range holds selection converted from DOM selection range to // internal unformatted representation of account number const val = this.sanitize(props.value); - /** - * @type {object} - * @property {string} value - raw text value - * @property {number[]} selectionRange - raw text mapped selection range [start, end] - */ this.state = { value: val, selectionRange: [val.length, val.length] }; } - /** - * @override - */ - componentWillReceiveProps(nextProps) { + componentWillReceiveProps(nextProps: AccountInputProps) { const nextVal = this.sanitize(nextProps.value); if(nextVal !== this.state.value) { const len = nextVal.length; @@ -58,10 +59,7 @@ export default class AccountInput extends Component { } } - /** - * @override - */ - shouldComponentUpdate(nextProps, nextState) { + shouldComponentUpdate(nextProps: AccountInputProps, nextState: AccountInputState) { return (this.props.value !== nextProps.value || this.props.onEnter !== nextProps.onEnter || this.props.onChange !== nextProps.onChange || @@ -70,31 +68,20 @@ export default class AccountInput extends Component { this.state.selectionRange[1] !== nextState.selectionRange[1]); } - /** - * @override - */ - render() { + render(): React.Element<*> { const displayString = formatAccount(this.state.value || ''); - const props = Object.assign({}, this.props); - - // exclude built-in props - for(let key of Object.keys(AccountInput.propTypes)) { - if(props.hasOwnProperty(key)) { - delete props[key]; - } - } - + const { value, onChange, onEnter, ...otherProps } = this.props; return ( - <input type="text" + <input { ...otherProps } + type="text" value={ displayString } onChange={ () => {} } - onSelect={ ::this.onSelect } - onKeyUp={ ::this.onKeyUp } - onKeyDown={ ::this.onKeyDown } - onPaste={ ::this.onPaste } - onCut={ ::this.onCut } - ref={ ::this.onRef } - { ...props } /> + onSelect={ this.onSelect } + onKeyUp={ this.onKeyUp } + onKeyDown={ this.onKeyDown } + onPaste={ this.onPaste } + onCut={ this.onCut } + ref={ this.onRef } /> ); } @@ -102,14 +89,8 @@ export default class AccountInput extends Component { /** * Modify original string inserting substring using selection range - * - * @private - * @param {String?} val string - * @returns {String} - * - * @memberOf AccountInput */ - sanitize(val) { + sanitize(val: ?string): string { return (val || '').replace(/[^0-9]/g, ''); } @@ -121,10 +102,8 @@ export default class AccountInput extends Component { * @param {String} insert insertion string * @param {Array} selRange selection range ([x,y]) * @returns {Object} - * - * @memberOf AccountInput */ - insert(val, insert, selRange) { + insert(val: string, insert: string, selRange: SelectionRange): AccountInputState { const head = val.slice(0, selRange[0]); const tail = val.slice(selRange[1], val.length); const newVal = head + insert + tail; @@ -144,7 +123,7 @@ export default class AccountInput extends Component { * * @memberOf AccountInput */ - remove(val, selRange) { + remove(val: string, selRange: SelectionRange): AccountInputState { let newVal, selectionOffset; if(selRange[0] === selRange[1]) { @@ -174,7 +153,7 @@ export default class AccountInput extends Component { * * @memberOf AccountInput */ - toInternalSelectionRange(val, domRange) { + toInternalSelectionRange(val: string, domRange: SelectionRange): SelectionRange { const countSpaces = (val) => { return (val.match(/\s/g) || []).length; }; @@ -202,7 +181,7 @@ export default class AccountInput extends Component { * * @memberOf AccountInput */ - toDomSelection(val, selRange) { + toDomSelection(val: string, selRange: SelectionRange): SelectionRange { const countSpaces = (val, untilIndex) => { if(val.length > 12) { return 0; } return Math.floor(untilIndex / 4); // groups of 4 digits @@ -221,13 +200,7 @@ export default class AccountInput extends Component { // Events - /** - * Key down handler - * @private - * @param {event} e - * @memberOf AccountInput - */ - onKeyDown(e) { + onKeyDown = (e: KeyboardEvent) => { const { value, selectionRange } = this.state; if(e.which === 8) { // backspace @@ -255,13 +228,7 @@ export default class AccountInput extends Component { } } - /** - * Key up handler - * @private - * @param {event} e - * @memberOf AccountInput - */ - onKeyUp(e) { + onKeyUp = (e: KeyboardEvent) => { this._ignoreSelect = false; if(e.which === 13 && this.props.onEnter) { @@ -269,14 +236,11 @@ export default class AccountInput extends Component { } } - /** - * Select handler - * @private - * @param {event} e - * @memberOf AccountInput - */ - onSelect(e) { + onSelect = (e: Event) => { const ref = e.target; + if(!(ref instanceof HTMLInputElement)) { + throw new Error('ref must be an instance of HTMLInputElement'); + } if(this._ignoreSelect) { return; @@ -288,13 +252,7 @@ export default class AccountInput extends Component { this.setState({ selectionRange: selRange }); } - /** - * Paste handler - * @private - * @param {event} e - * @memberOf AccountInput - */ - onPaste(e) { + onPaste = (e: ClipboardEvent) => { const { value, selectionRange } = this.state; const pastedData = e.clipboardData.getData('text'); const filteredData = this.sanitize(pastedData); @@ -307,13 +265,12 @@ export default class AccountInput extends Component { }); } - /** - * Cut handler - * @private - * @param {event} e - * @memberOf AccountInput - */ - onCut(e) { + onCut = (e: ClipboardEvent) => { + const target = e.target; + if(!(target instanceof HTMLInputElement)) { + throw new Error('ref must be an instance of HTMLInputElement'); + } + const { value, selectionRange } = this.state; e.preventDefault(); @@ -322,7 +279,7 @@ export default class AccountInput extends Component { if(selectionRange[0] !== selectionRange[1]) { const result = this.remove(value, selectionRange); const domSelectionRange = this.toDomSelection(value, selectionRange); - const slice = e.target.value.slice(domSelectionRange[0], domSelectionRange[1]); + const slice = target.value.slice(domSelectionRange[0], domSelectionRange[1]); e.clipboardData.setData('text', slice); @@ -334,13 +291,7 @@ export default class AccountInput extends Component { } } - /** - * Reference handler - * @private - * @param {DOMElement} ref - * @memberOf AccountInput - */ - onRef(ref) { + onRef = (ref: HTMLInputElement) => { this._ref = ref; if(!ref) { return; } @@ -351,10 +302,6 @@ export default class AccountInput extends Component { ref.selectionEnd = domRange[1]; } - /** - * Focus on text field - * @memberOf AccountInput - */ focus() { if(this._ref) { this._ref.focus(); diff --git a/app/components/Connect.js b/app/components/Connect.js index 6ffb516ec6..7ad0d4cc8b 100644 --- a/app/components/Connect.js +++ b/app/components/Connect.js @@ -22,21 +22,21 @@ type DisplayLocation = { city: ?string; }; -export default class Connect extends Component { - - props: { - user: UserReduxState, - connect: ConnectReduxState, - settings: SettingsReduxState, - onSettings: () => void, - onSelectLocation: () => void, - onConnect: (address: string) => void, - onCopyIP: () => void, - onDisconnect: () => void, - onExternalLink: (type: string) => void, - getServerInfo: (identifier: string) => ?ServerInfo - }; +export type ConnectProps = { + user: UserReduxState, + connect: ConnectReduxState, + settings: SettingsReduxState, + onSettings: () => void, + onSelectLocation: () => void, + onConnect: (address: string) => void, + onCopyIP: () => void, + onDisconnect: () => void, + onExternalLink: (type: string) => void, + getServerInfo: (identifier: string) => ?ServerInfo +}; +export default class Connect extends Component { + props: ConnectProps; state = { isFirstPass: true, showCopyIPMessage: false @@ -89,12 +89,12 @@ export default class Connect extends Component { </div> <If condition={ error.type === 'NO_CREDIT' }> <Then> - <div> - <button className="button button--positive" onClick={ this.onExternalLink.bind(this, 'purchase') }> - <span className="button-label">Buy more time</span> - <ExternalLinkSVG className="button-icon button-icon--16" /> - </button> - </div> + <div> + <button className="button button--positive" onClick={ this.onExternalLink.bind(this, 'purchase') }> + <span className="button-label">Buy more time</span> + <ExternalLinkSVG className="button-icon button-icon--16" /> + </button> + </div> </Then> </If> </div> @@ -129,12 +129,12 @@ export default class Connect extends Component { <div className="connect"> <div className="connect__map"> <ReactMapboxGl - style={ mapboxConfig.styleURL } - accessToken={ mapboxConfig.accessToken } - containerStyle={{ height: '100%' }} - interactive={ false } - fitBounds={ mapBounds } - fitBoundsOptions={ mapBoundsOptions }> + style={ mapboxConfig.styleURL } + accessToken={ mapboxConfig.accessToken } + containerStyle={{ height: '100%' }} + interactive={ false } + fitBounds={ mapBounds } + fitBoundsOptions={ mapBoundsOptions }> <If condition={ isConnected }> <Then> <Marker coordinates={ serverLocation } offset={ [0, -10] }> diff --git a/app/components/CustomScrollbars.js b/app/components/CustomScrollbars.js index e74cbd7c65..4a0899c1be 100644 --- a/app/components/CustomScrollbars.js +++ b/app/components/CustomScrollbars.js @@ -1,28 +1,13 @@ +// @flow import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import { Scrollbars } from 'react-custom-scrollbars'; -/** - * Custom scrollbars component - * - * @export - * @class CustomScrollbars - * @extends {React.Component} - */ export default class CustomScrollbars extends Component { - /** - * PropTypes - * @static - * @memberOf CustomScrollbars - */ - static propTypes = { - children: PropTypes.element + props: { + children: ?React.Element<*> } - /** - * @override - */ - render() { + render(): React.Element<*> { return ( <Scrollbars { ...this.props } diff --git a/app/components/HeaderBar.js b/app/components/HeaderBar.js index 5574951a06..bae3c4fddf 100644 --- a/app/components/HeaderBar.js +++ b/app/components/HeaderBar.js @@ -3,20 +3,21 @@ import React, { Component } from 'react'; import { If, Then } from 'react-if'; export type HeaderBarStyle = 'default' | 'defaultDark' | 'error' | 'success'; +export type HeaderBarProps = { + style: HeaderBarStyle; + hidden: boolean; + showSettings: boolean; + onSettings: ?(() => void); +}; -/** - * Header bar component - */ export default class HeaderBar extends Component { - - props: { - style: HeaderBarStyle, - hidden: boolean, - showSettings: boolean, - onSettings: () => void + props: HeaderBarProps; + static defaultProps: $Shape<HeaderBarProps> = { + hidden: false, + showSettings: false }; - render() { + render(): React.Element<*> { let containerClass = [ 'headerbar', 'headerbar--' + process.platform, diff --git a/app/components/Layout.js b/app/components/Layout.js index 58af3d0813..5c0e1f5bcb 100644 --- a/app/components/Layout.js +++ b/app/components/Layout.js @@ -1,20 +1,14 @@ +// @flow import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import HeaderBar from './HeaderBar'; -/** - * Layout header - * - * @export - * @class Header - * @extends {React.Component} - */ +import type { HeaderBarProps } from './HeaderBar'; + export class Header extends Component { + props: HeaderBarProps; + static defaultProps = HeaderBar.defaultProps; - /** - * @override - */ - render() { + render(): React.Element<*> { return ( <div className="layout__header"> <HeaderBar { ...this.props } /> @@ -23,28 +17,12 @@ export class Header extends Component { } } -/** - * Content container - * - * @export - * @class Container - * @extends {React.Component} - */ export class Container extends Component { + props: { + children: React.Element<*> + } - /** - * PropTypes - * @static - * @memberOf Container - */ - static propTypes = { - children: PropTypes.element.isRequired - }; - - /** - * @override - */ - render() { + render(): React.Element<*> { return ( <div className="layout__container"> { this.props.children } @@ -53,31 +31,12 @@ export class Container extends Component { } } -/** - * Layout container - * - * @export - * @class Layout - * @extends {React.Component} - */ export class Layout extends Component { + props: { + children: Array<React.Element<*>> | React.Element<*> + } - /** - * PropTypes - * @static - * @memberOf Container - */ - static propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.element), - PropTypes.element, - ]) - }; - - /** - * @override - */ - render() { + render(): React.Element<*> { return ( <div className="layout"> { this.props.children } diff --git a/app/components/Login.js b/app/components/Login.js index 72ef933082..9daa3f7e78 100644 --- a/app/components/Login.js +++ b/app/components/Login.js @@ -1,58 +1,41 @@ +// @flow import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import { If, Then } from 'react-if'; import { Layout, Container, Header } from './Layout'; import AccountInput from './AccountInput'; import ExternalLinkSVG from '../assets/images/icon-extLink.svg'; import LoginArrowSVG from '../assets/images/icon-arrow.svg'; -export default class Login extends Component { - static propTypes = { - user: PropTypes.object.isRequired, - onLogin: PropTypes.func.isRequired, - onSettings: PropTypes.func.isRequired, - onChange: PropTypes.func.isRequired, - onFirstChangeAfterFailure: PropTypes.func.isRequired, - onExternalLink: PropTypes.func.isRequired, - }; +import type { LoginState } from '../enums'; +import type { UserReduxState } from '../reducers/user'; - constructor(props) { - super(props); - this.state = { - notifyOnFirstChangeAfterFailure: false, - isActive: false - }; - } +export type LoginPropTypes = { + user: UserReduxState, + onLogin: (accountNumber: string) => void, + onSettings: ?(() => void), + onChange: (input: string) => void, + onFirstChangeAfterFailure: () => void, + onExternalLink: (type: string) => void, +}; - componentWillReceiveProps(nextProps) { - const prev = this.props.user || {}; - const next = nextProps.user || {}; - - if(prev.status !== next.status && next.status === 'failed') { - this.setState({ notifyOnFirstChangeAfterFailure: true }); - } +export default class Login extends Component { + props: LoginPropTypes; + state = { + notifyOnFirstChangeAfterFailure: false, + isActive: false } - onLogin() { + onCreateAccount = () => this.props.onExternalLink('createAccount'); + onFocus = () => this.setState({ isActive: true }); + onBlur = () => this.setState({ isActive: false }); + onLogin = () => { const { account } = this.props.user; - if(account.length > 0) { + if(account && account.length > 0) { this.props.onLogin(account); } } - onCreateAccount() { - this.props.onExternalLink('createAccount'); - } - - onFocus() { - this.setState({ isActive: true }); - } - - onBlur() { - this.setState({ isActive: false }); - } - - onInputChange(val) { + onInputChange = (val: string) => { // notify delegate on first change after login failure if(this.state.notifyOnFirstChangeAfterFailure) { this.setState({ notifyOnFirstChangeAfterFailure: false }); @@ -61,7 +44,7 @@ export default class Login extends Component { this.props.onChange(val); } - formTitle(s) { + formTitle(s: LoginState): string { switch(s) { case 'connecting': return 'Logging in...'; case 'failed': return 'Login failed'; @@ -70,22 +53,22 @@ export default class Login extends Component { } } - formSubtitle(s, e) { + formSubtitle(s: LoginState, e: ?Error): string { switch(s) { - case 'failed': return e.message; + case 'failed': return (e && e.message) || 'Unknown error'; case 'connecting': return 'Checking account number'; default: return 'Enter your account number'; } } - inputWrapClass(user) { + inputWrapClass(s: LoginState): string { const classes = ['login-form__input-wrap']; if(this.state.isActive) { classes.push('login-form__input-wrap--active'); } - switch(user.status) { + switch(s) { case 'connecting': classes.push('login-form__input-wrap--inactive'); break; @@ -97,9 +80,9 @@ export default class Login extends Component { return classes.join(' '); } - footerClass(user) { + footerClass(s: LoginState): string { const classes = ['login-footer']; - switch(user.status) { + switch(s) { case 'ok': case 'connecting': classes.push('login-footer--invisible'); @@ -108,31 +91,46 @@ export default class Login extends Component { return classes.join(' '); } - submitClass(user) { + submitClass(s: LoginState, account: ?string): string { const classes = ['login-form__submit']; - if(typeof(user.account) === 'string' && user.account.length > 0) { + if(account && account.length > 0) { classes.push('login-form__submit--active'); } - if(user.status === 'connecting') { + if(s === 'connecting') { classes.push('login-form__submit--invisible'); } return classes.join(' '); } - render() { + componentWillReceiveProps(nextProps: LoginPropTypes) { + const prev = this.props.user || {}; + const next = nextProps.user || {}; + + if(prev.status !== next.status && next.status === 'failed') { + this.setState({ notifyOnFirstChangeAfterFailure: true }); + } + } + + render(): React.Element<*> { const { account, status, error } = this.props.user; const title = this.formTitle(status); const subtitle = this.formSubtitle(status, error); - const isConnecting = status === 'connecting'; - const isFailed = status === 'failed'; - const isLoggedIn = status === 'ok'; - const inputWrapClass = this.inputWrapClass(this.props.user); - const footerClass = this.footerClass(this.props.user); - const submitClass = this.submitClass(this.props.user); + let isConnecting = false; + let isFailed = false; + let isLoggedIn = false; + switch(status) { + case 'connecting': isConnecting = true; break; + case 'failed': isFailed = true; break; + case 'ok': isLoggedIn = true; break; + } + + const inputWrapClass = this.inputWrapClass(status); + const footerClass = this.footerClass(status); + const submitClass = this.submitClass(status, account); const autoFocusRef = input => { if(isFailed && input) { @@ -178,25 +176,25 @@ export default class Login extends Component { <div className="login-form__subtitle">{ subtitle }</div> <div className={ inputWrapClass }> <AccountInput className="login-form__input-field" - type="text" - placeholder="e.g 0000 0000 0000" - onFocus={ ::this.onFocus } - onBlur={ ::this.onBlur } - onChange={ ::this.onInputChange } - onEnter={ ::this.onLogin } - value={ account } - disabled={ isConnecting } - autoFocus={ true } - ref={ autoFocusRef } /> - <button className={ submitClass } onClick={ ::this.onLogin }> - <LoginArrowSVG className="login-form__submit-icon" /> - </button> + type="text" + placeholder="e.g 0000 0000 0000" + onFocus={ this.onFocus } + onBlur={ this.onBlur } + onChange={ this.onInputChange } + onEnter={ this.onLogin } + value={ account || '' } + disabled={ isConnecting } + autoFocus={ true } + ref={ autoFocusRef } /> + <button className={ submitClass } onClick={ this.onLogin }> + <LoginArrowSVG className="login-form__submit-icon" /> + </button> </div> </div> </div> <div className={ footerClass }> - <div className="login-footer__prompt">Don't have an account number?</div> - <button className="button button--primary" onClick={ ::this.onCreateAccount }> + <div className="login-footer__prompt">{ 'Don\'t have an account number?' }</div> + <button className="button button--primary" onClick={ this.onCreateAccount }> <span className="button-label">Create account</span> <ExternalLinkSVG className="button-icon button-icon--16" /> </button> diff --git a/app/components/SelectLocation.js b/app/components/SelectLocation.js index 0dd52ab2bb..c94df2a11d 100644 --- a/app/components/SelectLocation.js +++ b/app/components/SelectLocation.js @@ -1,26 +1,31 @@ +// @flow import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import { If, Then } from 'react-if'; import { Layout, Container, Header } from './Layout'; import { servers } from '../config'; import CustomScrollbars from './CustomScrollbars'; -export default class SelectLocation extends Component { +import type { SettingsReduxState } from '../reducers/settings'; - static propTypes = { - onClose: PropTypes.func.isRequired, - onSelect: PropTypes.func.isRequired - } +export type SelectLocationProps = { + settings: SettingsReduxState, + onClose: () => void; + onSelect: (server: string) => void; +}; + +export default class SelectLocation extends Component { + props: SelectLocationProps; + _selectedCell: ?HTMLElement; - onSelect(name) { + onSelect(name: string) { this.props.onSelect(name); } - isSelected(key) { - return key === this.props.settings.preferredServer; + isSelected(server: string) { + return server === this.props.settings.preferredServer; } - drawCell(key, name, icon, onClick) { + drawCell(key: string, name: string, icon: ?string, onClick: (e: Event) => void): React.Element<*> { const classes = ['select-location__cell']; const selected = this.isSelected(key); @@ -51,7 +56,7 @@ export default class SelectLocation extends Component { ); } - onCellRef(key, element) { + onCellRef(key: string, element: HTMLElement) { // save reference to selected cell if(this.isSelected(key)) { this._selectedCell = element; @@ -60,12 +65,18 @@ export default class SelectLocation extends Component { componentDidMount() { // restore scroll to selected cell - if(this._selectedCell) { - this._selectedCell.scrollIntoViewIfNeeded(true); + const cell = this._selectedCell; + if(cell) { + // this is non-standard webkit method but it works great! + if(typeof(cell.scrollIntoViewIfNeeded) !== 'function') { + console.warn('HTMLElement.scrollIntoViewIfNeeded() is not available anymore! Please replace it with viable alternative.'); + return; + } + cell.scrollIntoViewIfNeeded(true); } } - render() { + render(): React.Element<*> { return ( <Layout> <Header hidden={ true } style={ 'defaultDark' } /> diff --git a/app/components/Settings.js b/app/components/Settings.js index eaec0355f2..9b8eff5321 100644 --- a/app/components/Settings.js +++ b/app/components/Settings.js @@ -1,39 +1,36 @@ +// @flow import moment from 'moment'; import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import { If, Then, Else } from 'react-if'; import { Layout, Container, Header } from './Layout'; import Switch from './Switch'; import CustomScrollbars from './CustomScrollbars'; -export default class Settings extends Component { +import type { UserReduxState } from '../reducers/user'; +import type { SettingsReduxState } from '../reducers/settings'; - static propTypes = { - onQuit: PropTypes.func.isRequired, - onLogout: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - onViewAccount: PropTypes.func.isRequired, - onExternalLink: PropTypes.func.isRequired, - onUpdateSettings: PropTypes.func.isRequired - } +export type SettingsProps = { + user: UserReduxState, + settings: SettingsReduxState, + onQuit: () => void, + onClose: () => void, + onViewAccount: () => void, + onExternalLink: (type: string) => void, + onUpdateSettings: (update: $Shape<SettingsReduxState>) => void +}; - onClose() { - this.props.onClose(); - } +export default class Settings extends Component { - onAutoSecure(isOn) { - this.props.onUpdateSettings({ autoSecure: isOn }); - } + props: SettingsProps; - onExternalLink(type) { - this.props.onExternalLink(type); - } + onClose = () => this.props.onClose(); + onAutoSecure = (autoSecure: boolean) => this.props.onUpdateSettings({ autoSecure }); - onLogout() { - this.props.onLogout(); + onExternalLink(type: string) { + this.props.onExternalLink(type); } - render() { + render(): React.Element<*> { const isLoggedIn = this.props.user.status === 'ok'; let isOutOfTime = false, formattedPaidUntil = ''; let paidUntilIso = this.props.user.paidUntil; @@ -49,7 +46,7 @@ export default class Settings extends Component { <Header hidden={ true } style={ 'defaultDark' } /> <Container> <div className="settings"> - <button className="settings__close" onClick={ ::this.onClose } /> + <button className="settings__close" onClick={ this.onClose } /> <div className="settings__container"> <div className="settings__header"> <h2 className="settings__title">Settings</h2> @@ -82,7 +79,7 @@ export default class Settings extends Component { <div className="settings__cell"> <div className="settings__cell-label">Auto-connect</div> <div className="settings__cell-value"> - <Switch onChange={ ::this.onAutoSecure } isOn={ this.props.settings.autoSecure } /> + <Switch onChange={ this.onAutoSecure } isOn={ this.props.settings.autoSecure } /> </div> </div> <div className="settings__cell-footer"> diff --git a/app/components/Switch.js b/app/components/Switch.js index 4cb0ea34c3..46baeb8b22 100644 --- a/app/components/Switch.js +++ b/app/components/Switch.js @@ -1,27 +1,32 @@ +// @flow import React, { Component } from 'react'; -import PropTypes from 'prop-types'; + +import type { Point2d } from '../types'; const CLICK_TIMEOUT = 1000; const MOVE_THRESHOLD = 10; export default class Switch extends Component { + props: { + isOn: boolean; + onChange: ?((isOn: boolean) => void); + } - static propTypes = { - isOn: PropTypes.bool, - onChange: PropTypes.func + defaultProps = { + isOn: false } - constructor(props) { - super(props); - this.state = { - isTracking: false, - ignoreChange: false, - initialPos: null, - startTime: null - }; + ref: ?HTMLInputElement; + onRef = (e: HTMLInputElement) => this.ref = e; + + state = { + isTracking: false, + ignoreChange: false, + initialPos: (null: ?Point2d), + startTime: (null: ?number) } - handleMouseDown(e) { + handleMouseDown = (e: MouseEvent) => { const { pageX: x, pageY: y } = e; this.setState({ isTracking: true, @@ -30,14 +35,19 @@ export default class Switch extends Component { }); } - handleMouseMove(e) { - if(!this.state.isTracking) { return; } + handleMouseMove = (e: MouseEvent) => { + if(!this.state.isTracking) { + return; + } + const inputElement = this.ref; const { x: x0 } = this.state.initialPos; const { pageX: x, pageY: y } = e; const dx = Math.abs(x0 - x); - if(dx < MOVE_THRESHOLD) { return; } + if(dx < MOVE_THRESHOLD) { + return; + } const isOn = !!this.props.isOn; let nextOn = isOn; @@ -53,12 +63,16 @@ export default class Switch extends Component { initialPos: { x, y }, ignoreChange: true }); - this.refs.input.checked = nextOn; + + if(inputElement) { + inputElement.checked = nextOn; + } + this.notify(nextOn); } } - handleMouseUp() { + handleMouseUp = () => { if(this.state.isTracking) { this.setState({ isTracking: false, @@ -67,8 +81,19 @@ export default class Switch extends Component { } } - handleChange(e) { - const dt = e.timeStamp - this.state.startTime; + handleChange = (e: Event) => { + const startTime = this.state.startTime; + const eventTarget = e.target; + + if(typeof(startTime) !== 'number') { + throw new Error('startTime must be a number.'); + } + + if(!(eventTarget instanceof HTMLInputElement)) { + throw new Error('e.target must be an instance of HTMLInputElement.'); + } + + const dt = e.timeStamp - startTime; if(this.state.ignoreChange) { this.setState({ ignoreChange: false }); @@ -76,30 +101,32 @@ export default class Switch extends Component { } else if(dt > CLICK_TIMEOUT) { e.preventDefault(); } else { - this.notify(e.target.checked); + this.notify(eventTarget.checked); } } - notify(isOn) { - if(this.props.onChange) { - this.props.onChange(isOn); + notify(isOn: boolean) { + const onChange = this.props.onChange; + if(onChange) { + onChange(isOn); } } componentDidMount() { - document.addEventListener('mousemove', ::this.handleMouseMove); - document.addEventListener('mouseup', ::this.handleMouseUp); + document.addEventListener('mousemove', this.handleMouseMove); + document.addEventListener('mouseup', this.handleMouseUp); } componentWillUnmount() { - document.removeEventListener('mousemove', ::this.handleMouseMove); - document.removeEventListener('mouseup', ::this.handleMouseUp); + document.removeEventListener('mousemove', this.handleMouseMove); + document.removeEventListener('mouseup', this.handleMouseUp); } - render() { + render(): React.Element<*> { return ( - <input type="checkbox" ref="input" className="switch" checked={ this.props.isOn } - onMouseDown={ ::this.handleMouseDown } onChange={ ::this.handleChange } /> + <input type="checkbox" ref={ this.onRef } className="switch" checked={ this.props.isOn } + onMouseDown={ this.handleMouseDown } + onChange={ this.handleChange } /> ); } } diff --git a/app/components/WindowChrome.js b/app/components/WindowChrome.js index 16bdb70e28..141c99fdb4 100644 --- a/app/components/WindowChrome.js +++ b/app/components/WindowChrome.js @@ -1,20 +1,10 @@ +// @flow import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -/** - * A component used to chip out arrow in the app header using CSS mask - * - * @export - * @class WindowChrome - * @extends {Component} - */ export default class WindowChrome extends Component { - static propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.element), - PropTypes.element, - ]) - }; + props: { + children: Array<React.Element<*>> | React.Element<*> + } render() { const chromeClass = ['window-chrome', 'window-chrome--' + process.platform]; diff --git a/app/containers/SettingsPage.js b/app/containers/SettingsPage.js index b0bc7868b0..b6807a0a22 100644 --- a/app/containers/SettingsPage.js +++ b/app/containers/SettingsPage.js @@ -2,7 +2,6 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { push } from 'react-router-redux'; import Settings from '../components/Settings'; -import userActions from '../actions/user'; import settingsActions from '../actions/settings'; import { remote, shell } from 'electron'; import { links } from '../config'; @@ -11,12 +10,10 @@ const mapStateToProps = (state) => { return state; }; -const mapDispatchToProps = (dispatch, props) => { - const { logout } = bindActionCreators(userActions, dispatch); +const mapDispatchToProps = (dispatch, _props) => { const { updateSettings } = bindActionCreators(settingsActions, dispatch); return { onQuit: () => remote.app.quit(), - onLogout: () => logout(props.backend), onClose: () => dispatch(push('/connect')), onViewAccount: () => dispatch(push('/settings/account')), onExternalLink: (type) => shell.openExternal(links[type]), diff --git a/app/types.js b/app/types.js index a18b4c21da..3e247a875a 100644 --- a/app/types.js +++ b/app/types.js @@ -1,2 +1,6 @@ // @flow +export type Point2d = { + x: number; + y: number; +}; export type Coordinate2d = [number, number]; diff --git a/package.json b/package.json index 46b06539f1..c4888aa2ad 100644 --- a/package.json +++ b/package.json @@ -54,10 +54,10 @@ "electron-devtools-installer": "^2.1.0", "electron-mocha": "^3.3.0", "esdoc": "^0.5.2", - "eslint": "^3.14.1", - "eslint-plugin-flowtype": "^2.34.0", - "eslint-plugin-react": "^6.9.0", - "flow-bin": "^0.48.0", + "eslint": "^4.1.1", + "eslint-plugin-flowtype": "^2.34.1", + "eslint-plugin-react": "^7.1.0", + "flow-bin": "^0.49.1", "flow-typed": "^2.1.2", "isomorphic-fetch": "^2.2.1", "jsdom": "^9.11.0", @@ -159,9 +159,9 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" -ansi-escapes@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" ansi-regex@^2.0.0: version "2.1.1" @@ -239,13 +239,6 @@ array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" -array.prototype.find@^2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.0.4.tgz#556a5c5362c08648323ddaeb9de9d14bc1864c90" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.7.0" - arraybuffer.slice@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca" @@ -319,7 +312,7 @@ babel-cli@^6.22.2: optionalDependencies: chokidar "^1.6.1" -babel-code-frame@^6.16.0, babel-code-frame@^6.22.0, babel-code-frame@^6.8.0: +babel-code-frame@^6.22.0, babel-code-frame@^6.8.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" dependencies: @@ -327,31 +320,7 @@ babel-code-frame@^6.16.0, babel-code-frame@^6.22.0, babel-code-frame@^6.8.0: esutils "^2.0.2" js-tokens "^3.0.0" -babel-core@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.1.tgz#8c428564dce1e1f41fb337ec34f4c3b022b5ad83" - dependencies: - babel-code-frame "^6.22.0" - babel-generator "^6.24.1" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babylon "^6.11.0" - convert-source-map "^1.1.0" - debug "^2.1.1" - json5 "^0.5.0" - lodash "^4.2.0" - minimatch "^3.0.2" - path-is-absolute "^1.0.0" - private "^0.1.6" - slash "^1.0.0" - source-map "^0.5.0" - -babel-core@^6.25.0: +babel-core@^6.24.1, babel-core@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729" dependencies: @@ -395,19 +364,6 @@ babel-generator@6.11.4: lodash "^4.2.0" source-map "^0.5.0" -babel-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.2.0" - source-map "^0.5.0" - trim-right "^1.0.1" - babel-generator@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc" @@ -1043,17 +999,7 @@ babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtim core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-template@^6.15.0, babel-template@^6.24.1, babel-template@^6.3.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babylon "^6.11.0" - lodash "^4.2.0" - -babel-template@^6.25.0: +babel-template@^6.15.0, babel-template@^6.24.1, babel-template@^6.25.0, babel-template@^6.3.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071" dependencies: @@ -1077,21 +1023,7 @@ babel-traverse@6.12.0: invariant "^2.2.0" lodash "^4.2.0" -babel-traverse@^6.15.0, babel-traverse@^6.23.1, babel-traverse@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695" - dependencies: - babel-code-frame "^6.22.0" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - babylon "^6.15.0" - debug "^2.2.0" - globals "^9.0.0" - invariant "^2.2.0" - lodash "^4.2.0" - -babel-traverse@^6.25.0: +babel-traverse@^6.15.0, babel-traverse@^6.23.1, babel-traverse@^6.24.1, babel-traverse@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1" dependencies: @@ -1105,16 +1037,7 @@ babel-traverse@^6.25.0: invariant "^2.2.0" lodash "^4.2.0" -babel-types@^6.10.2, babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.9.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975" - dependencies: - babel-runtime "^6.22.0" - esutils "^2.0.2" - lodash "^4.2.0" - to-fast-properties "^1.0.1" - -babel-types@^6.25.0: +babel-types@^6.10.2, babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.25.0, babel-types@^6.9.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" dependencies: @@ -1127,7 +1050,7 @@ babylon@6.14.1: version "6.14.1" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.14.1.tgz#956275fab72753ad9b3435d7afe58f8bf0a29815" -babylon@^6.10.0, babylon@^6.11.0, babylon@^6.15.0, babylon@^6.17.0, babylon@^6.17.2, babylon@^6.7.0: +babylon@^6.10.0, babylon@^6.15.0, babylon@^6.17.0, babylon@^6.17.2, babylon@^6.7.0: version "6.17.2" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.2.tgz#201d25ef5f892c41bae49488b08db0dd476e9f5c" @@ -1534,11 +1457,11 @@ cli-boxes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" -cli-cursor@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" dependencies: - restore-cursor "^1.0.1" + restore-cursor "^2.0.0" cli-width@^2.0.0: version "2.1.0" @@ -1614,7 +1537,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.0, concat-stream@^1.5.2, concat-stream@~1.6.0: +concat-stream@1.6.0, concat-stream@^1.6.0, concat-stream@~1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -1779,12 +1702,6 @@ custom-error-instance@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/custom-error-instance/-/custom-error-instance-2.1.1.tgz#3cf6391487a6629a6247eb0ca0ce00081b7e361a" -d@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" - dependencies: - es5-ext "^0.10.9" - dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -1821,7 +1738,7 @@ debug@2.6.4: dependencies: ms "0.7.3" -debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.6.0, debug@^2.6.1: +debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.6.0, debug@^2.6.1, debug@^2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: @@ -1906,13 +1823,6 @@ diff@3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" -doctrine@^1.2.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - doctrine@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" @@ -2226,7 +2136,7 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.4.3, es-abstract@^1.7.0: +es-abstract@^1.4.3: version "1.7.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c" dependencies: @@ -2243,62 +2153,10 @@ es-to-primitive@^1.1.1: is-date-object "^1.0.1" is-symbol "^1.0.1" -es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: - version "0.10.23" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.23.tgz#7578b51be974207a5487821b56538c224e4e7b38" - dependencies: - es6-iterator "2" - es6-symbol "~3.1" - -es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" - dependencies: - d "1" - es5-ext "^0.10.14" - es6-symbol "^3.1" - -es6-map@^0.1.3: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-set "~0.1.5" - es6-symbol "~3.1.1" - event-emitter "~0.3.5" - es6-promise@^4.0.5: version "4.1.0" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.0.tgz#dda03ca8f9f89bc597e689842929de7ba8cebdf0" -es6-set@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-symbol "3.1.1" - event-emitter "~0.3.5" - -es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" - dependencies: - d "1" - es5-ext "~0.10.14" - -es6-weak-map@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" - dependencies: - d "1" - es5-ext "^0.10.14" - es6-iterator "^2.0.1" - es6-symbol "^3.1.1" - escape-html@1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2337,15 +2195,6 @@ escodegen@~1.3.2: optionalDependencies: source-map "~0.1.33" -escope@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" - dependencies: - es6-map "^0.1.3" - es6-weak-map "^2.0.1" - esrecurse "^4.1.0" - estraverse "^4.1.1" - esdoc@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/esdoc/-/esdoc-0.5.2.tgz#cbfd0b20e3d1cacc23c93c328eed987e21ba0067" @@ -2362,63 +2211,66 @@ esdoc@^0.5.2: minimist "1.2.0" taffydb "2.7.2" -eslint-plugin-flowtype@^2.34.0: - version "2.34.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.34.0.tgz#b9875f314652e5081623c9d2b18a346bbb759c09" +eslint-plugin-flowtype@^2.34.1: + version "2.34.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.34.1.tgz#ea109175645b05d37baeac53b9b65066d79b9446" dependencies: lodash "^4.15.0" -eslint-plugin-react@^6.9.0: - version "6.10.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz#c5435beb06774e12c7db2f6abaddcbf900cd3f78" +eslint-plugin-react@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.1.0.tgz#27770acf39f5fd49cd0af4083ce58104eb390d4c" dependencies: - array.prototype.find "^2.0.1" - doctrine "^1.2.2" + doctrine "^2.0.0" has "^1.0.1" - jsx-ast-utils "^1.3.4" - object.assign "^4.0.4" + jsx-ast-utils "^1.4.1" + +eslint-scope@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" -eslint@^3.14.1: - version "3.19.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" +eslint@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.1.1.tgz#facbdfcfe3e0facd3a8b80dc98c4e6c13ae582df" dependencies: - babel-code-frame "^6.16.0" + babel-code-frame "^6.22.0" chalk "^1.1.3" - concat-stream "^1.5.2" - debug "^2.1.1" + concat-stream "^1.6.0" + debug "^2.6.8" doctrine "^2.0.0" - escope "^3.6.0" - espree "^3.4.0" + eslint-scope "^3.7.1" + espree "^3.4.3" esquery "^1.0.0" estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" - glob "^7.0.3" - globals "^9.14.0" - ignore "^3.2.0" + glob "^7.1.2" + globals "^9.17.0" + ignore "^3.3.3" imurmurhash "^0.1.4" - inquirer "^0.12.0" - is-my-json-valid "^2.10.0" + inquirer "^3.0.6" + is-my-json-valid "^2.16.0" is-resolvable "^1.0.0" - js-yaml "^3.5.1" - json-stable-stringify "^1.0.0" + js-yaml "^3.8.4" + json-stable-stringify "^1.0.1" levn "^0.3.0" - lodash "^4.0.0" - mkdirp "^0.5.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" - path-is-inside "^1.0.1" - pluralize "^1.2.1" - progress "^1.1.8" - require-uncached "^1.0.2" - shelljs "^0.7.5" - strip-bom "^3.0.0" + path-is-inside "^1.0.2" + pluralize "^4.0.0" + progress "^2.0.0" + require-uncached "^1.0.3" strip-json-comments "~2.0.1" - table "^3.7.8" + table "^4.0.1" text-table "~0.2.0" - user-home "^2.0.0" -espree@^3.4.0: +espree@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.3.tgz#2910b5ccd49ce893c2ffffaab4fd8b3a31b82374" dependencies: @@ -2492,13 +2344,6 @@ etag@^1.7.0, etag@~1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.0.tgz#6f631aef336d6c46362b51764044ce216be3c051" -event-emitter@~0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - dependencies: - d "1" - es5-ext "~0.10.14" - event-stream@~3.3.0: version "3.3.4" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" @@ -2526,10 +2371,6 @@ execa@^0.4.0: path-key "^1.0.0" strip-eof "^1.0.0" -exit-hook@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" - expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -2555,6 +2396,14 @@ extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" +external-editor@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972" + dependencies: + iconv-lite "^0.4.17" + jschardet "^1.4.2" + tmp "^0.0.31" + extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" @@ -2605,12 +2454,11 @@ fd-slicer@~1.0.1: dependencies: pend "~1.2.0" -figures@^1.3.5: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" dependencies: escape-string-regexp "^1.0.5" - object-assign "^4.1.0" file-entry-cache@^2.0.0: version "2.0.0" @@ -2659,9 +2507,9 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -flow-bin@^0.48.0: - version "0.48.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.48.0.tgz#72d075143524358db8901525e3c784dc13a7c7ee" +flow-bin@^0.49.1: + version "0.49.1" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.49.1.tgz#c9e456b3173a7535a4ffaf28956352c63bb8e3e9" flow-remove-types@^1.1.2: version "1.2.1" @@ -2906,7 +2754,7 @@ glob@7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6: +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -2921,7 +2769,7 @@ globals@^8.3.0: version "8.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-8.18.0.tgz#93d4a62bdcac38cfafafc47d6b034768cb0ffcb4" -globals@^9.0.0, globals@^9.14.0: +globals@^9.0.0, globals@^9.17.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -3142,11 +2990,15 @@ iconv-lite@0.4.13, iconv-lite@~0.4.13: version "0.4.13" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" +iconv-lite@^0.4.17: + version "0.4.18" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2" + ieee754@^1.1.6: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" -ignore@^3.2.0: +ignore@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" @@ -3187,28 +3039,25 @@ ini@^1.3.4, ini@~1.3.0: version "1.3.4" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" -inquirer@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" +inquirer@^3.0.6: + version "3.1.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.1.1.tgz#87621c4fba4072f48a8dd71c9f9df6f100b2d534" dependencies: - ansi-escapes "^1.1.0" - ansi-regex "^2.0.0" + ansi-escapes "^2.0.0" chalk "^1.0.0" - cli-cursor "^1.0.1" + cli-cursor "^2.1.0" cli-width "^2.0.0" - figures "^1.3.5" + external-editor "^2.0.4" + figures "^2.0.0" lodash "^4.3.0" - readline2 "^1.0.1" - run-async "^0.1.0" - rx-lite "^3.1.2" - string-width "^1.0.1" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.0.0" strip-ansi "^3.0.0" through "^2.3.6" -interpret@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90" - invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" @@ -3297,7 +3146,7 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" -is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: +is-my-json-valid@^2.12.4, is-my-json-valid@^2.16.0: version "2.16.0" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" dependencies: @@ -3351,6 +3200,10 @@ is-primitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + is-property@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" @@ -3428,7 +3281,7 @@ js-tokens@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" -js-yaml@^3.5.1, js-yaml@^3.8.2: +js-yaml@^3.8.2, js-yaml@^3.8.4: version "3.8.4" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6" dependencies: @@ -3446,6 +3299,10 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" +jschardet@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.4.2.tgz#2aa107f142af4121d145659d44f50830961e699a" + jsdom@^7.0.2: version "7.2.2" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-7.2.2.tgz#40b402770c2bda23469096bee91ab675e3b1fc6e" @@ -3502,7 +3359,7 @@ json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" -json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: +json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" dependencies: @@ -3553,7 +3410,7 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.3.6" -jsx-ast-utils@^1.3.4: +jsx-ast-utils@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz#3867213e8dd79bf1e8f2300c0cfc1efb182c0df1" @@ -3743,7 +3600,7 @@ lodash@^3.10.1: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0: +lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -3901,6 +3758,10 @@ mime@1.3.4: version "1.3.6" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0" +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -3923,7 +3784,7 @@ mkdirp@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" -mkdirp@0.5, mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@0.5, mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -3981,9 +3842,9 @@ multi-stage-sourcemap@^0.2.1: dependencies: source-map "^0.1.34" -mute-stream@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" nan@^2.3.0: version "2.6.2" @@ -4143,7 +4004,7 @@ object-inspect@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-0.4.0.tgz#f5157c116c1455b243b06ee97703392c5ad89fec" -object-keys@^1.0.10, object-keys@^1.0.6, object-keys@^1.0.8: +object-keys@^1.0.6, object-keys@^1.0.8: version "1.0.11" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" @@ -4155,14 +4016,6 @@ object-path@^0.9.0: version "0.9.2" resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.9.2.tgz#0fd9a74fc5fad1ae3968b586bda5c632bd6c05a5" -object.assign@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.0.4.tgz#b1c9cc044ef1b9fe63606fc141abbb32e14730cc" - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.0" - object-keys "^1.0.10" - object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -4182,9 +4035,11 @@ once@^1.3.0, once@^1.3.3: dependencies: wrappy "1" -onetime@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" openurl@1.1.0: version "1.1.0" @@ -4222,7 +4077,7 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -4321,7 +4176,7 @@ path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" @@ -4400,9 +4255,9 @@ plist@^2.0.1: xmlbuilder "8.2.2" xmldom "0.1.x" -pluralize@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" +pluralize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-4.0.0.tgz#59b708c1c0190a2f692f1c7618c446b052fd1762" point-geometry@0.0.0, point-geometry@^0.0.0: version "0.0.0" @@ -4457,9 +4312,9 @@ progress-stream@^1.1.0: speedometer "~0.1.2" through2 "~0.2.3" -progress@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" +progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" promise@^7.1.1: version "7.1.1" @@ -4711,20 +4566,6 @@ readdirp@^2.0.0: readable-stream "^2.0.2" set-immediate-shim "^1.0.1" -readline2@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - mute-stream "0.0.5" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - dependencies: - resolve "^1.1.6" - redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" @@ -4910,7 +4751,7 @@ require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" -require-uncached@^1.0.2: +require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" dependencies: @@ -4939,7 +4780,7 @@ resolve-protobuf-schema@^2.0.0: dependencies: protocol-buffers-schema "^2.0.2" -resolve@^1.1.5, resolve@^1.1.6: +resolve@^1.1.5: version "1.3.3" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" dependencies: @@ -4952,12 +4793,12 @@ resp-modifier@6.0.2: debug "^2.2.0" minimatch "^3.0.2" -restore-cursor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" dependencies: - exit-hook "^1.0.0" - onetime "^1.0.0" + onetime "^2.0.0" + signal-exit "^3.0.2" rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1: version "2.6.1" @@ -4965,15 +4806,21 @@ rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2. dependencies: glob "^7.0.5" -run-async@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" dependencies: - once "^1.3.0" + is-promise "^2.1.0" -rx-lite@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" rx@4.1.0: version "4.1.0" @@ -5093,15 +4940,7 @@ shell-quote@^1.6.1: array-reduce "~0.0.0" jsonify "~0.0.0" -shelljs@^0.7.5: - version "0.7.8" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -signal-exit@^3.0.0: +signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -5421,6 +5260,17 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" +table@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.1.tgz#a8116c133fac2c61f4a420ab6cdf5c4d61f0e435" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + taffydb@2.7.2: version "2.7.2" resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.7.2.tgz#7bf8106a5c1a48251b3e3bc0a0e1732489fd0dc8" @@ -5500,6 +5350,12 @@ tinyqueue@^1.1.0: version "1.2.2" resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-1.2.2.tgz#947229e5e4197aba988acd27751dcc582e6728ff" +tmp@^0.0.31: + version "0.0.31" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" + dependencies: + os-tmpdir "~1.0.1" + to-array@0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" @@ -5690,12 +5546,6 @@ user-home@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" -user-home@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" - dependencies: - os-homedir "^1.0.0" - utf8-byte-length@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" |
