diff --git a/.eslintrc.js b/.eslintrc.js index dee2f976..5dbae90b 100755 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -21,12 +21,15 @@ module.exports = { 'compat/compat': 'off', 'consistent-return': 'off', 'camelcase': 'off', + 'react/jsx-props-no-spreading': 'off', + 'prefer-object-spread': 'off', 'comma-dangle': 'off', 'no-underscore-dangle': 'off', 'generator-star-spacing': 'off', 'import/no-unresolved': 'error', 'import/no-duplicates': 'off', 'import/no-extraneous-dependencies': 'off', + 'import/prefer-default-export': 'warn', 'no-nested-ternary': 'off', 'no-underscore-dangle': 'off', 'jsx-a11y/anchor-is-valid': 'off', diff --git a/README.md b/README.md index 6cf9880c..a7ef6791 100755 --- a/README.md +++ b/README.md @@ -45,8 +45,7 @@ You can view my presentation in the GreeceJS meetup at http://bit.ly/2RES3AN
- +
diff --git a/app/cli/manager.js b/app/cli/manager.js index ae62cb12..20dd3253 100755 --- a/app/cli/manager.js +++ b/app/cli/manager.js @@ -6,8 +6,6 @@ import cp from 'child_process'; import path from 'path'; import chalk from 'chalk'; -// import log from 'electron-log'; -import lockVerify from 'lock-verify'; import mk from '../mk'; const { spawn } = cp; @@ -32,7 +30,8 @@ const execute = ( manager = defaultManager, commandArgs = [], mode, - directory + directory, + packageJson, ) => { const [operation] = commandArgs; @@ -80,15 +79,13 @@ const execute = ( chalk.greenBright.bold(`finished: ${manager} ${commandArgs.join(' ')}`) ); - const resultString = result.join(''); - const commandResult = { + return resolve({ status: 'close', errors, - data: resultString, - cmd: commandArgs - }; - - return resolve(commandResult); + data: result.join(''), + cmd: commandArgs, + packageJson: Boolean(packageJson) + }); }); }); @@ -98,18 +95,11 @@ const execute = ( /** * npm list * @param {*} options - * @param {*} callback */ -const list = (options, callback) => { +const list = (options) => { const command = ['list']; const { mode, directory, linked } = options || {}; - if (!callback || typeof callback !== 'function') { - return Promise.reject( - 'manager[list]: callback must be given and must be a function' - ); - } - if (!mode || typeof mode !== 'string') { return Promise.reject( 'manager[list]: mode must be given and must be one of "global" or "local"' @@ -125,7 +115,7 @@ const list = (options, callback) => { : command.concat(defaultsArgs.list); // returns a Promise - return execute('npm', run, mode, directory, callback); + return execute('npm', run, mode, directory); } catch (error) { Promise.reject(error); } @@ -134,18 +124,11 @@ const list = (options, callback) => { /** * npm outdated * @param {*} options - * @param {*} callback */ -const outdated = (options, callback) => { +const outdated = (options) => { const command = ['outdated']; const { mode, directory } = options || {}; - if (!callback || typeof callback !== 'function') { - return Promise.reject( - 'manager[outdated]: callback must be given and must be a function' - ); - } - if (!mode || typeof mode !== 'string') { return Promise.reject( 'manager[outdated]: mode must be given and must be one of "global" or "local"' @@ -159,7 +142,7 @@ const outdated = (options, callback) => { : command.concat(defaultsArgs.list); // returns a Promise - return execute('npm', run, mode, directory, callback); + return execute('npm', run, mode, directory); } catch (error) { Promise.reject(error); } @@ -168,9 +151,8 @@ const outdated = (options, callback) => { /** * npm search * @param {*} opts - * @param {*} callback */ -const search = (opts, callback) => { +const search = (opts) => { const command = ['search']; const { directory, mode, pkgName } = opts || {}; const defaults = ['--depth=0', '--json']; @@ -182,7 +164,7 @@ const search = (opts, callback) => { try { const run = command.concat(defaults, pkgName); - return execute('npm', run, mode, directory, callback); + return execute('npm', run, mode, directory); } catch (error) { Promise.reject(error); } @@ -191,17 +173,16 @@ const search = (opts, callback) => { /** * npm install * @param {*} opts - * @param {*} callback * @param {*} idx */ -const install = (opts, callback, idx) => { - const { mode, directory, activeManager = 'npm' } = opts || {}; +const install = (opts, idx) => { + const { mode, directory, packageJson, activeManager = 'npm' } = opts || {}; try { const runInstall = require('./npm/install').default; const run = runInstall(opts, idx); - return execute(activeManager, run, mode, directory, callback); + return execute(activeManager, run, mode, directory, packageJson); } catch (error) { Promise.reject(error); } @@ -210,16 +191,15 @@ const install = (opts, callback, idx) => { /** * npm update * @param {*} opts - * @param {*} callback */ -const update = (opts, callback) => { +const update = (opts) => { const { mode, directory, activeManager = 'npm' } = opts || {}; try { const runUpdate = require('./npm/update').default; const run = runUpdate(opts); - return execute(activeManager, run, mode, directory, callback); + return execute(activeManager, run, mode, directory); } catch (error) { Promise.reject(error); } @@ -228,16 +208,15 @@ const update = (opts, callback) => { /** * npm uninstall * @param {*} opts - * @param {*} callback */ -const uninstall = (opts, callback) => { +const uninstall = (opts) => { const { mode, directory, activeManager = 'npm' } = opts || {}; try { const runUninstall = require('./npm/uninstall').default; const run = runUninstall(opts); - return execute(activeManager, run, mode, directory, callback); + return execute(activeManager, run, mode, directory); } catch (error) { Promise.reject(error); } @@ -246,16 +225,15 @@ const uninstall = (opts, callback) => { /** * npm view * @param {*} opts - * @param {*} callback */ -const view = (opts, callback) => { +const view = (opts) => { const { mode, directory, activeManager = 'npm' } = opts || {}; try { const runView = require('./npm/view').default; const run = runView(opts); - return execute(activeManager, run, mode, directory, callback); + return execute(activeManager, run, mode, directory); } catch (error) { Promise.reject(error); } @@ -264,16 +242,15 @@ const view = (opts, callback) => { /** * npm audit * @param {*} opts - * @param {*} callback */ -const runAudit = (opts, callback) => { +const runAudit = (opts) => { const { activeManager = 'npm', mode, directory, ...options } = opts || {}; try { const audit = require('./npm/audit').default; const run = audit(options); - return execute(activeManager, run, mode, directory, callback); + return execute(activeManager, run, mode, directory); } catch (error) { Promise.reject(error); } @@ -282,34 +259,32 @@ const runAudit = (opts, callback) => { /** * npm doctor * @param {*} opts - * @param {*} callback */ -const runDoctor = (opts, callback) => { +const runDoctor = (opts) => { const { mode, directory, activeManager = 'npm' } = opts || {}; try { const doctor = require('./npm/doctor').default; const run = doctor(opts); - return execute(activeManager, run, mode, directory, callback); + return execute(activeManager, run, mode, directory); } catch (error) { Promise.reject(error); } }; /** - * npm prune + * npm init * @param {*} opts - * @param {*} callback */ -const runPrune = (opts, callback) => { - const { mode, directory, activeManager = 'npm' } = opts || {}; +const runInit = (opts) => { + const { mode, directory, activeManager = 'npm' } = opts; try { - const prune = require('./npm/tooling/prune').default; - const run = prune(opts); + const init = require('./npm/tooling/init').default; + const run = init(opts); - return execute(activeManager, run, mode, directory, callback); + return execute(activeManager, run, mode, directory); } catch (error) { Promise.reject(error); } @@ -318,107 +293,25 @@ const runPrune = (opts, callback) => { /** * npm dedupe * @param {*} opts - * @param {*} callback */ -const runDedupe = (opts, callback) => { - const { mode, directory, activeManager = 'npm' } = opts || {}; +const runDedupe = (opts) => { + const { mode, directory, activeManager = 'npm' } = opts; try { const dedupe = require('./npm/tooling/dedupe').default; const run = dedupe(opts); - return execute(activeManager, run, mode, directory, callback); - } catch (error) { - Promise.reject(error); - } -}; - -/** - * - * @param {*} opts - * @param {*} callback - */ -const runVerify = (opts, callback) => { - const { mode, directory, activeManager = 'npm' } = opts; - - try { - const verify = require('./npm/tooling/verify').default; - const run = verify(opts); - - return execute(activeManager, run, mode, directory, callback); - } catch (error) { - Promise.reject(error); - } -}; - -/** - * npm cache clean - * @param {*} opts - * @param {*} callback - */ -const runClean = (opts, callback) => { - const { mode, directory, activeManager = 'npm' } = opts; - - try { - const clean = require('./npm/tooling/clean').default; - const run = clean(opts); - - return execute(activeManager, run, mode, directory, callback); - } catch (error) { - Promise.reject(error); - } -}; - -/** - * npm init - * @param {*} opts - * @param {*} callback - */ -const runInit = (opts, callback) => { - const { mode, directory, activeManager = 'npm' } = opts; - - try { - const init = require('./npm/tooling/init').default; - const run = init(opts); - - return execute(activeManager, run, mode, directory, callback); + return execute(activeManager, run, mode, directory); } catch (error) { Promise.reject(error); } }; -/** - * - * @param {*} opts - */ -const runLockVerify = opts => { - const { directory } = opts || {}; - - lockVerify(directory).then(result => { - result.warnings.forEach(warning => console.error('Warning:', warning)); - - if (!result.status) { - result.errors.forEach(error => console.error(error)); - } - - return { - status: 'close', - errors: [], - data: result, - cmd: ['lockVerify'] - }; - }); -}; - export default { init: runInit, audit: runAudit, doctor: runDoctor, - prune: runPrune, dedupe: runDedupe, - verify: runVerify, - clean: runClean, - lockVerify: runLockVerify, list, outdated, search, diff --git a/app/cli/npm/audit.js b/app/cli/npm/audit.js index da039557..33f1e03f 100755 --- a/app/cli/npm/audit.js +++ b/app/cli/npm/audit.js @@ -5,7 +5,7 @@ const audit = params => { const command = ['audit']; - const defaults = ['--json', '--verbose']; + const defaults = ['--json']; // '--verbose' const { options: { flag } } = params || {} diff --git a/app/cli/npm/doctor.js b/app/cli/npm/doctor.js index 2e15108e..b39a93e1 100755 --- a/app/cli/npm/doctor.js +++ b/app/cli/npm/doctor.js @@ -5,7 +5,7 @@ const doctor = () => { const command = ['doctor']; - const defaults = ['--json', '--verbose']; + const defaults = ['--json']; // '--verbose' return command.concat(defaults); }; diff --git a/app/cli/npm/install.js b/app/cli/npm/install.js index 33ecb6ee..15dd7a87 100755 --- a/app/cli/npm/install.js +++ b/app/cli/npm/install.js @@ -22,13 +22,13 @@ const install = (options, idx) => { } = options || {}; // '--unsafe-perm' - // '--ignore-scripts - const defaults = ['--verbose', '--no-audit']; + // '--verbose' + const defaults = ['--no-audit', '--ignore-scripts']; // install from package.json file - if (packageJson) { - return command.concat(['--ignore-scripts']); - } + // if (packageJson) { + // return command.concat(['--ignore-scripts']); + // } // create package-lock.json file if (packageLock) { @@ -56,15 +56,13 @@ const install = (options, idx) => { // get installation options const hasOptions = Array.isArray(pkgOptions) && pkgOptions.length; - const commandOptions = - mode === 'local' && hasOptions - ? multiple - ? pkgOptions[idx].map(option => `--${option}`) - : pkgOptions.map(option => `--${option}`) - : ['--save-prod']; + const commandOptions = mode === 'local' && hasOptions ? multiple + ? pkgOptions[idx].map(option => `--${option}`) + : pkgOptions.map(option => `--${option}`) + : ['--save-prod']; // build running command - const run = [] + const run = packageJson ? [].concat(command).concat(commandArgs) : [] .concat(command) .concat(packagesToInstall) .concat(commandOptions) diff --git a/app/cli/npm/tooling/dedupe.js b/app/cli/npm/tooling/dedupe.js old mode 100755 new mode 100644 index 5178ff49..02e22c6f --- a/app/cli/npm/tooling/dedupe.js +++ b/app/cli/npm/tooling/dedupe.js @@ -1,8 +1,14 @@ +/** + * Searches the local package tree and attempts + * to simplify the overall structure by moving dependencies further up the tree + * https://docs.npmjs.com/cli/dedupe + */ + const dedupe = () => { - const command = ['dedupe']; - const defaults = ['--json', '--verbose']; + const command = ['dedupe']; + const defaults = ['--no-audit', '-verbose']; - return command.concat(defaults); + return command.concat(defaults); }; export default dedupe; diff --git a/app/cli/shell.js b/app/cli/shell.js index 863bdf06..668dbc29 100755 --- a/app/cli/shell.js +++ b/app/cli/shell.js @@ -13,24 +13,21 @@ import manager from './manager'; const runCommand = (options, callback) => { const { cmd, ...rest } = options || {}; - // construct an array of promises. Each promise is an npm command const combine = () => cmd.map((command, idx) => { try { const runner = manager[command]; - const result = runner(rest, callback, idx); + const result = runner(rest, idx); - return result; + return result; // returns a promise } catch (error) { log.error(error); throw new Error(error); } }); - // array of promises const tasks = combine(); - // run tasks tasks .reduce( (promiseChain, currentTask) => diff --git a/app/commons/hocs/withErrorBoundary.js b/app/commons/hocs/withErrorBoundary.js index f9ef75b2..d9553ea9 100755 --- a/app/commons/hocs/withErrorBoundary.js +++ b/app/commons/hocs/withErrorBoundary.js @@ -1,4 +1,5 @@ /* eslint-disable object-shorthand */ +/* eslint-disable react/state-in-constructor */ import React, { Component, createFactory } from 'react'; diff --git a/app/commons/utils.js b/app/commons/utils.js index b344e1b0..b6500069 100755 --- a/app/commons/utils.js +++ b/app/commons/utils.js @@ -17,6 +17,11 @@ import { const SEPARATOR = path.sep; +/** + * + * @param {*} handler + * @param {*} options + */ export const showDialog = (handler, options) => { if (!options || typeof options !== 'object') { return; @@ -33,6 +38,12 @@ export const showDialog = (handler, options) => { }); }; +/** + * + * @param {*} type + * @param {*} key + * @param {*} replacements + */ export const iMessage = (type, key, replacements) => { const messageType = switchcase({ confirmation: () => CONFIRMATION_MESSAGES, @@ -49,6 +60,10 @@ export const iMessage = (type, key, replacements) => { : key; }; +/** + * + * @param {*} namespace + */ export const createActionCreator = namespace => actionType => { const type = `${namespace}/${actionType}`; const actionCreator = payload => ({ @@ -90,7 +105,7 @@ export const isUrl = url => { */ export const firstToUpper = str => { return str - .replace(/(?:^\w|[A-Z]|\b\w)/g, function(letter, index) { + .replace(/(?:^\w|[A-Z]|\b\w)/g, function (letter, index) { return index !== 0 ? letter.toLowerCase() : letter.toUpperCase(); }) .replace(/\s+/g, ''); @@ -224,7 +239,7 @@ export const shrinkDirectory = directory => { return `${dirParts[dirParts.length - 2]}${SEPARATOR}${ dirParts[dirParts.length - 1] - }${SEPARATOR}package.json`; + }${SEPARATOR}package.json`; } catch (error) { throw new Error(error); } diff --git a/app/components/common/AppLoader.js b/app/components/common/AppLoader.js index 1ecc8d32..bfcac833 100755 --- a/app/components/common/AppLoader.js +++ b/app/components/common/AppLoader.js @@ -15,11 +15,12 @@ import { Typography } from '@material-ui/core'; import styles from './styles/appLoader'; -const AppLoader = ({ loading, classes, children, message, relative, mini }) => +const AppLoader = ({ loading, classes, className, children, message, relative, mini }) => loading ? (
size={mini ? 20 : 30} /> {message && ( - + {message} )}
) : ( - children - ); + children + ); AppLoader.propTypes = { classes: objectOf(string).isRequired, @@ -43,7 +44,8 @@ AppLoader.propTypes = { children: oneOfType([node, array, symbol]), message: string, relative: bool, - mini: bool + mini: bool, + className: string, }; export default withStyles(styles)(AppLoader); diff --git a/app/components/common/AppLogo.js b/app/components/common/AppLogo.js index df5a799f..d128819d 100755 --- a/app/components/common/AppLogo.js +++ b/app/components/common/AppLogo.js @@ -5,7 +5,7 @@ import anime from 'animejs'; import cn from 'classnames'; import styles from './styles/appLogo'; -const AppLogo = ({ classes }) => { +const AppLogo = ({ classes, className }) => { useEffect(() => { const logoAnimationTL = anime .timeline({ @@ -27,7 +27,9 @@ const AppLogo = ({ classes }) => { }, []); return ( -
+
@@ -38,7 +40,7 @@ const AppLogo = ({ classes }) => { classes.logo_animation__logo_letter_svg, classes.logo_animation__bounce, classes.rot, - classes.primaryColor + classes.errorColor )} viewBox="0 0 150 250" width="20" @@ -56,7 +58,7 @@ const AppLogo = ({ classes }) => { className={cn( classes.logo_animation__bounce, classes.flip, - classes.secondaryColor + classes.primaryColor )} viewBox="0 0 150 250" width="20" @@ -90,7 +92,7 @@ const AppLogo = ({ classes }) => { { }; AppLogo.propTypes = { - classes: PropTypes.objectOf(PropTypes.string).isRequired + classes: PropTypes.objectOf(PropTypes.string).isRequired, + className: PropTypes.string }; export default withStyles(styles)(AppLogo); diff --git a/app/components/common/AppSnackbar.js b/app/components/common/AppSnackbar.js new file mode 100755 index 00000000..709f83a4 --- /dev/null +++ b/app/components/common/AppSnackbar.js @@ -0,0 +1,35 @@ +import React from 'react' +import { objectOf, string, bool, func, oneOfType } from 'prop-types' + +import Snackbar from '@material-ui/core/Snackbar'; +import { SnackbarContent } from 'components/common'; + +const AppSnackbar = ({ snackbar, onClose }) => { + const { open, type, message } = snackbar; + + return + + +} + +AppSnackbar.propTypes = { + onClose: func.isRequired, + snackbar: objectOf(oneOfType([string, bool])), +} + +export default AppSnackbar diff --git a/app/components/common/AppTabs.js b/app/components/common/AppTabs.js index 20587bd2..4f9fd640 100755 --- a/app/components/common/AppTabs.js +++ b/app/components/common/AppTabs.js @@ -1,8 +1,6 @@ -/* eslint-disable react/require-default-props */ - import React, { useState } from 'react'; import { withStyles } from '@material-ui/core/styles'; -import PropTypes from 'prop-types'; +import { bool, node, objectOf, string } from 'prop-types'; import Typography from '@material-ui/core/Typography'; import AppBar from '@material-ui/core/AppBar'; @@ -18,8 +16,8 @@ const TabContainer = ({ children, loading }) => ( ); TabContainer.propTypes = { - children: PropTypes.node.isRequired, - loading: PropTypes.bool + children: node.isRequired, + loading: bool }; const AppTabs = ({ classes, children }) => { @@ -27,14 +25,8 @@ const AppTabs = ({ classes, children }) => { return (
- - setValue(tabValue)} - > + + setValue(tabValue)}> { {React.Children.map(children, (child, idx) => { - if (child.props.loading) { - return null; - } - if (value === idx) { return ( @@ -71,14 +59,16 @@ const AppTabs = ({ classes, children }) => { ); } + + return null; })}
); }; AppTabs.propTypes = { - children: PropTypes.node.isRequired, - classes: PropTypes.objectOf(PropTypes.string).isRequired + children: node.isRequired, + classes: objectOf(string).isRequired }; export default withStyles(styles)(AppTabs); diff --git a/app/components/common/Dot.js b/app/components/common/Dot.js index 5d76745d..db1aff90 100755 --- a/app/components/common/Dot.js +++ b/app/components/common/Dot.js @@ -22,7 +22,7 @@ Dot.propTypes = { size: PropTypes.string, color: PropTypes.string, className: PropTypes.string, - theme: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.array])).isRequired, + theme: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.array, PropTypes.func])).isRequired, } const styles = theme => ({ diff --git a/app/components/views/common/SearchBox.js b/app/components/common/SearchBox.js similarity index 95% rename from app/components/views/common/SearchBox.js rename to app/components/common/SearchBox.js index 3705d93b..29c3ce4d 100755 --- a/app/components/views/common/SearchBox.js +++ b/app/components/common/SearchBox.js @@ -12,7 +12,7 @@ import InputBase from '@material-ui/core/InputBase'; import SearchIcon from '@material-ui/icons/Search'; import ClearIcon from '@material-ui/icons/Clear'; -import { setActivePage, clearFilters } from 'models/ui/actions'; +import { setActivePage, setPage, clearFilters } from 'models/ui/actions'; import { setPackagesSearch } from 'models/packages/actions'; import styles from './styles/searchBox'; @@ -51,6 +51,13 @@ const SearchBox = ({ classes, disabled, onlineStatus }) => { } }); + dispatch({ + type: setPage.type, + payload: { + page: 0 + } + }); + dispatch( setPackagesSearch({ channel: 'npm-search', diff --git a/app/components/common/SnackbarContent.js b/app/components/common/SnackbarContent.js index 689fc2ce..94ea1f2a 100755 --- a/app/components/common/SnackbarContent.js +++ b/app/components/common/SnackbarContent.js @@ -27,13 +27,13 @@ const styles = theme => ({ backgroundColor: theme.palette.error.light }, info: { - backgroundColor: theme.palette.primary.dark + backgroundColor: theme.palette.text.secondary }, secondary: { backgroundColor: theme.palette.secondary.dark }, warning: { - backgroundColor: theme.palette.warning.light + backgroundColor: theme.palette.error.light }, icon: { fontSize: 25 @@ -58,48 +58,48 @@ const AppSnackbarContent = ({ variant, ...other }) => ( - - {variant === 'info' && ( - - )} - {variant === 'error' && ( - - )} - {variant === 'warning' && ( - - )} - {variant === 'success' && ( - - )} - {message} -
- } - action={[ - typeof onClose === 'function' && ( - - - - ) - ]} - {...other} - /> -); + + {variant === 'info' && ( + + )} + {variant === 'error' && ( + + )} + {variant === 'warning' && ( + + )} + {variant === 'success' && ( + + )} + {message} +
+ } + action={[ + typeof onClose === 'function' && ( + + + + ) + ]} + {...other} + /> + ); AppSnackbarContent.defaultProps = { variant: 'info' diff --git a/app/components/common/Terminal.js b/app/components/common/Terminal.js deleted file mode 100755 index 584564f8..00000000 --- a/app/components/common/Terminal.js +++ /dev/null @@ -1,41 +0,0 @@ -/* eslint-disable react/no-array-index-key */ - -import React from 'react'; -import PropTypes from 'prop-types'; -import { withStyles } from '@material-ui/core/styles'; -import cn from 'classnames'; - -import styles from './styles/terminalStyles'; - -const Terminal = ({ classes, commands }) => ( -
-
-
-
- running commands -
-
- {commands && - commands.map((command, idx) => ( - {command.command} - ))} -
-
-); - -Terminal.propTypes = { - classes: PropTypes.objectOf(PropTypes.string).isRequired, - commands: PropTypes.arrayOf(PropTypes.object).isRequired -}; - -const withStylesTerminal = withStyles(styles)(Terminal); -export default withStylesTerminal; diff --git a/app/components/common/Transition.js b/app/components/common/Transition.js index 6de2d33d..d9d41e59 100755 --- a/app/components/common/Transition.js +++ b/app/components/common/Transition.js @@ -9,18 +9,12 @@ const Transitions = { }; class Transition extends React.Component { - static defaultProps = { - type: 'Fade', - direction: 'right', - show: true - }; - render() { const { children, type, direction, show } = this.props; if (type && !Transitions[type]) { console.error(`Transition ${type} is not supported`); - return {children}; + return <>{children}; } return React.createElement( @@ -34,6 +28,12 @@ class Transition extends React.Component { } } +Transition.defaultProps = { + type: 'Fade', + direction: 'right', + show: true +}; + Transition.propTypes = { children: PropTypes.node.isRequired, type: PropTypes.string, diff --git a/app/components/common/Widget.js b/app/components/common/Widget.js index e0376535..4902b0a4 100755 --- a/app/components/common/Widget.js +++ b/app/components/common/Widget.js @@ -26,14 +26,14 @@ const Widget = ({
{!header && title ? ( - + <> {title} - + ) : ( - header - )} + header + )}
{title && }
({ loader: { display: 'flex', @@ -19,6 +21,8 @@ const styles = () => ({ margin: 0 }, message: { + ...defaultFont, + fontSize: 14, padding: 0, margin: 0 } diff --git a/app/components/common/styles/appLogo.js b/app/components/common/styles/appLogo.js index 2f863242..f0868cdf 100755 --- a/app/components/common/styles/appLogo.js +++ b/app/components/common/styles/appLogo.js @@ -6,7 +6,8 @@ const styles = theme => ({ display: 'flex', flexDirection: 'column', width: '100%', - maxWidth: 290 + maxWidth: 290, + padding: theme.spacing(2) }, logo_animation_wrapper: { position: 'relative', @@ -72,7 +73,7 @@ const styles = theme => ({ stroke: lighten(theme.palette.secondary.main, 0.2) }, warningColor: { - stroke: lighten(theme.palette.warning.main, 0.2) + stroke: lighten(theme.palette.error.main, 0.2) }, errorColor: { stroke: lighten(theme.palette.error.main, 0.2) diff --git a/app/components/common/styles/appTabs.js b/app/components/common/styles/appTabs.js index c60d5b53..d87e581d 100755 --- a/app/components/common/styles/appTabs.js +++ b/app/components/common/styles/appTabs.js @@ -10,15 +10,10 @@ const styles = theme => ({ }, tabLabel: { ...defaultFont, - fontSize: 16, - paddingBottom: theme.spacing(1) + fontSize: 16 }, noMargin: { margin: 0 - }, - appBar: { - marginLeft: theme.spacing(0.5), - marginRight: theme.spacing(0.5) } }); diff --git a/app/components/common/styles/installFromSources.js b/app/components/common/styles/installFromSources.js index 2dae38bd..f9b2eeb1 100755 --- a/app/components/common/styles/installFromSources.js +++ b/app/components/common/styles/installFromSources.js @@ -28,7 +28,7 @@ const styles = theme => ({ }, warningColor: { color: theme.palette.common.white, - backgroundColor: theme.palette.warning.light + backgroundColor: theme.palette.error.light }, errorColor: { color: theme.palette.common.white, diff --git a/app/components/views/common/styles/searchBox.js b/app/components/common/styles/searchBox.js similarity index 73% rename from app/components/views/common/styles/searchBox.js rename to app/components/common/styles/searchBox.js index aded36bd..175bed4e 100755 --- a/app/components/views/common/styles/searchBox.js +++ b/app/components/common/styles/searchBox.js @@ -16,31 +16,32 @@ const styles = theme => ({ border: '1px solid' }, searchIcon: { + cursor: 'pointer', width: theme.spacing(1) * 6, height: '100%', position: 'absolute', display: 'flex', alignItems: 'center', justifyContent: 'center', - color: theme.palette.common.white + paddingLeft: theme.spacing(2), + color: theme.palette.common.white, + zIndex: 9999 }, inputRoot: { color: 'inherit', width: '100%', fontFamily: 'inherit', - fontSize: 14, - lineHeight: '1em' + fontSize: 20, + lineHeight: '0.75em' }, inputInput: { - color: '#fff', - paddingTop: theme.spacing(1), - paddingRight: theme.spacing(1), - paddingBottom: theme.spacing(1), - paddingLeft: theme.spacing(1) * 10, + color: theme.palette.common.white, + paddingLeft: theme.spacing(10), + paddingRight: theme.spacing(10), transition: theme.transitions.create('width'), - width: 145, + width: 175, '&:focus': { - width: 275 + width: 220 } } }); diff --git a/app/components/common/styles/terminalStyles.js b/app/components/common/styles/terminalStyles.js deleted file mode 100755 index 18722c55..00000000 --- a/app/components/common/styles/terminalStyles.js +++ /dev/null @@ -1,68 +0,0 @@ -import { defaultFont } from 'styles/variables'; - -const styles = theme => ({ - root: { - width: '100%' - }, - top: { - ...defaultFont, - height: '22px', - background: 'linear-gradient(0deg, #d8d8d8, #ececec)', - borderTop: '1px solid white', - borderBottom: '1px solid #b3b3b3', - borderTopLeftRadius: '5px', - borderTopRightRadius: '5px', - color: 'rgba(0, 0, 0, 0.7)', - fontSize: '13px', - lineHeight: '22px', - textAlign: 'center' - }, - buttons: { - position: 'absolute', - float: 'left', - margin: '0 8px' - }, - button: { - padding: 0, - margin: 0, - marginRight: 4, - width: 12, - height: 12, - backgroundColor: 'transparent', - border: '1px solid rgba(0, 0, 0, 0.2)', - borderRadius: '6px', - color: 'rgba(0, 0, 0, 0.5)' - }, - close: { - backgroundColor: '#ff6159' - }, - maximize: { - backgroundColor: '#25cc3e' - }, - minimize: { - backgroundColor: '#ffbf2f' - }, - terminal: { - display: 'flex', - flexDirection: 'column', - padding: theme.spacing(0.5), - backgroundColor: 'black', - opacity: '0.7', - minHeight: 150, - overflowY: 'scroll', - color: 'white', - fontFamily: "'Source Code Pro', monospace", - fontWeight: '200', - fontSize: '14px', - whiteSpace: '-o-pre-wrap', - wordWrap: 'break-word', - borderBottomLeftRadius: 5, - borderBottomRightRadius: 5, - '& > span': { - width: '100%', - padding: theme.spacing(1) - } - } -}); - -export default styles; diff --git a/app/components/views/audit/components/Advisories.js b/app/components/views/audit/components/Advisories.js index a3d53be7..02fd3366 100755 --- a/app/components/views/audit/components/Advisories.js +++ b/app/components/views/audit/components/Advisories.js @@ -110,7 +110,7 @@ const Advisories = ({ classes, data, handleAudit, vulnerabilities }) => { }; return ( - + { {name}} + title={{name}} className={classes.cardHeader} subheader={ - + {title} } diff --git a/app/components/views/audit/components/ListTypes.js b/app/components/views/audit/components/ListTypes.js index b29d49f9..a66aa689 100755 --- a/app/components/views/audit/components/ListTypes.js +++ b/app/components/views/audit/components/ListTypes.js @@ -1,7 +1,7 @@ /* eslint-disable no-unused-vars */ import React from 'react'; -import { objectOf, oneOfType, string, array, object, number } from 'prop-types'; +import { objectOf, oneOfType, string, array, object, func, number } from 'prop-types'; import { withStyles } from '@material-ui/core'; import { groupBy } from 'ramda'; @@ -57,17 +57,17 @@ const ListTypes = ({ classes, theme, data, vulnerabilities }) => { { value: critical, name: iMessage('label', 'critical'), - color: 'danger' + color: 'error' }, { value: high, name: iMessage('label', 'high'), - color: 'warning' + color: 'secondary' }, { value: moderate, name: iMessage('label', 'moderate'), - color: 'secondary' + color: 'primary' }, { value: low, @@ -77,11 +77,11 @@ const ListTypes = ({ classes, theme, data, vulnerabilities }) => { { value: info, name: iMessage('label', 'info'), - color: 'success' + color: 'secondary' } ]; const totalVulnerabilities = typesData.reduce((acc, type) => acc + type.value, 0); - console.log(theme.palette) + return (
@@ -124,7 +124,7 @@ const ListTypes = ({ classes, theme, data, vulnerabilities }) => { ListTypes.propTypes = { classes: objectOf(string).isRequired, - theme: objectOf(oneOfType([string, object, array])).isRequired, + theme: objectOf(oneOfType([string, object, array, func])).isRequired, data: objectOf(oneOfType([string, array, object])).isRequired, vulnerabilities: objectOf(number).isRequired }; diff --git a/app/components/views/audit/components/Summary.js b/app/components/views/audit/components/Summary.js index 46752af3..49248195 100755 --- a/app/components/views/audit/components/Summary.js +++ b/app/components/views/audit/components/Summary.js @@ -28,7 +28,6 @@ import { iMessage } from 'commons/utils'; import styles from '../styles/summary'; const Summary = ({ classes, data, onClose }) => { - console.log(data); const dataKeys = Object.keys(data); const dataValues = Object.values(data); diff --git a/app/components/views/audit/styles/listTypes.js b/app/components/views/audit/styles/listTypes.js index 2f29973e..b20d8439 100755 --- a/app/components/views/audit/styles/listTypes.js +++ b/app/components/views/audit/styles/listTypes.js @@ -19,7 +19,9 @@ const styles = theme => ({ marginLeft: theme.spacing(1), }, chip: { - fontSize: 20 + fontSize: 20, + color: theme.palette.common.white, + backgroundColor: theme.palette.common.neutral } }); diff --git a/app/components/views/common/Init.js b/app/components/views/common/Init.js index 91f83b53..ffe9218e 100755 --- a/app/components/views/common/Init.js +++ b/app/components/views/common/Init.js @@ -1,125 +1,64 @@ -import React from 'react'; +import React, { useCallback } from 'react'; import PropTypes from 'prop-types'; import { remote } from 'electron'; import { useState } from 'react'; -import { useDispatch } from 'redux-react-hook'; import { withStyles } from '@material-ui/core/styles'; +import { directoryParameters } from 'commons/parameters'; +import { iMessage } from 'commons/utils'; -import Checkbox from '@material-ui/core/Checkbox'; +import Paper from '@material-ui/core/Paper'; import Typography from '@material-ui/core/Typography'; import Button from '@material-ui/core/Button'; -import Divider from '@material-ui/core/Divider'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; - -import { directoryParameters } from 'commons/parameters'; -import { iMessage } from 'commons/utils'; -import { runInit, runLock } from 'models/npm/actions'; import styles from './styles/initForm'; -const InitView = ({ classes, onClose }) => { - const [type, setType] = useState('init'); +const Init = ({ classes, enableInit }) => { const [initOptions, setInitOptions] = useState({ directory: null }); - const dispatch = useDispatch(); + const { directory } = initOptions; - const { directory } = initOptions || {}; - - const startInitFlow = () => + const startInitFlow = useCallback(() => remote.dialog.showOpenDialog( remote.getCurrentWindow(), directoryParameters, - filePath => - filePath && - setInitOptions({ - ...initOptions, - directory: filePath[0] - }) - ); - - const npmLock = () => { - dispatch( - runLock({ - ipcEvent: 'npm-init-lock', - cmd: ['install'], - packageLock: true, - directory - }) - ); - - onClose(); - }; - - const npmInit = () => { - dispatch( - runInit({ - ipcEvent: 'npm-init', - cmd: ['init'], - directory - }) - ); - - onClose(); - }; + filePath => { + if (filePath) { + setInitOptions({ + ...initOptions, + directory: filePath[0] + }) + enableInit(filePath[0]) + } + } + ), [initOptions, enableInit]); - return ( -
- - {iMessage('info', 'createPackageJsonHelperText')} - -
- - setType(type === 'init' ? 'lock' : 'package')} - /> - } - className={classes.formControl} - label="package-lock only" - /> - {directory && ( - - {directory} - - )} + {directory || 'No directory selected'} +
- - - {iMessage('info', 'createPackageJsonNote')} -
-
-
- ); -}; +
+ +} -InitView.propTypes = { +Init.propTypes = { classes: PropTypes.objectOf(PropTypes.string).isRequired, - onClose: PropTypes.func.isRequired + enableInit: PropTypes.func.isRequired }; -export default withStyles(styles)(InitView); +export default withStyles(styles)(Init); diff --git a/app/components/views/common/Settings.js b/app/components/views/common/Settings.js index f39f24f0..45254239 100755 --- a/app/components/views/common/Settings.js +++ b/app/components/views/common/Settings.js @@ -1,37 +1,60 @@ import React from 'react'; +import { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import { withStyles } from '@material-ui/core/styles'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import ListItemText from '@material-ui/core/ListItemText'; +import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import Button from '@material-ui/core/Button' import Typography from '@material-ui/core/Typography'; +import { iMessage } from 'commons/utils'; import styles from './styles/settings'; -const Settings = ({ classes, items }) => ( -
- - {items.map((item, idx) => ( - +const Settings = ({ classes, ...restProps }) => { + const { metricsRegistry, auditLevel, cache } = restProps; + + const [settings, setSettings] = useState({ + metricsRegistry: '', + auditLevel: '', + cache: '' + }); + + useEffect(() => { + setSettings(settingsItems => ({ + ...settingsItems, + metricsRegistry, + auditLevel, + cache + })) + }, [metricsRegistry, auditLevel, cache]) + + return
+ + {Object.keys(settings).map(setting => { + return {item.primaryText} + {settings[setting]} } secondary={ - - {item.secondaryText} + + {setting} } /> + + + - ))} + })} -
-); +
+} Settings.propTypes = { classes: PropTypes.objectOf(PropTypes.string).isRequired, - items: PropTypes.arrayOf(PropTypes.object).isRequired }; export default withStyles(styles)(Settings); diff --git a/app/components/views/common/System.js b/app/components/views/common/System.js deleted file mode 100755 index f39f24f0..00000000 --- a/app/components/views/common/System.js +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { withStyles } from '@material-ui/core/styles'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemText from '@material-ui/core/ListItemText'; -import Typography from '@material-ui/core/Typography'; - -import styles from './styles/settings'; - -const Settings = ({ classes, items }) => ( -
- - {items.map((item, idx) => ( - - {item.primaryText} - } - secondary={ - - {item.secondaryText} - - } - /> - - ))} - -
-); - -Settings.propTypes = { - classes: PropTypes.objectOf(PropTypes.string).isRequired, - items: PropTypes.arrayOf(PropTypes.object).isRequired -}; - -export default withStyles(styles)(Settings); diff --git a/app/components/views/common/index.js b/app/components/views/common/index.js index d8d6789c..536d9052 100755 --- a/app/components/views/common/index.js +++ b/app/components/views/common/index.js @@ -1,5 +1,4 @@ -import Init from "./Init"; -import SearchBox from "./SearchBox"; -import Settings from "./Settings"; +import Init from './Init'; +import Settings from './Settings'; -export { Init, SearchBox, Settings }; +export { Init, Settings }; diff --git a/app/components/views/common/styles/initForm.js b/app/components/views/common/styles/initForm.js index f5dfaafb..63ded553 100755 --- a/app/components/views/common/styles/initForm.js +++ b/app/components/views/common/styles/initForm.js @@ -1,27 +1,46 @@ import { darken } from '@material-ui/core/styles/colorManipulator'; -import { grayColor } from 'styles/variables'; +import { flexContainer, grayColor } from 'styles/variables'; const styles = theme => ({ + root: { + padding: 0, + margin: 0 + }, + content: { + ...flexContainer, + flexDirection: 'column', + alignItems: 'center', + }, actions: { - display: 'flex', - justifyContent: 'space-between', - alignItems: 'flex-start', - marginTop: theme.spacing(1) + padding: 0 }, caption: { color: darken(grayColor, 0.6), - marginTop: theme.spacing(2) + marginTop: theme.spacing(4) }, options: { - marginTop: theme.spacing(1), - marginBottom: theme.spacing(0.5), - padding: theme.spacing(1) + paddingTop: theme.spacing(4) }, formControl: { - marginLeft: theme.spacing(1) + margin: 0 + }, + flexGrow: { + flexGrow: 1 + }, + title: { + padding: theme.spacing(2), + }, + info: { + marginTop: theme.spacing(5) }, directory: { - paddingTop: theme.spacing(1) + padding: theme.spacing(1), + }, + button: { + marginBottom: theme.spacing(8) + }, + paper: { + padding: theme.spacing(1) } }); diff --git a/app/components/views/common/styles/settings.js b/app/components/views/common/styles/settings.js index d394d794..a8c8ba7c 100755 --- a/app/components/views/common/styles/settings.js +++ b/app/components/views/common/styles/settings.js @@ -3,10 +3,7 @@ import { grayColor } from 'styles/variables'; const styles = theme => ({ root: { margin: 0, - padding: theme.spacing(2) - }, - tab: { - backgroundColor: theme.palette.background.paper + padding: 0 }, listItem: { padding: 0, diff --git a/app/components/views/navigationBar/NavigationBar.js b/app/components/views/navigationBar/NavigationBar.js new file mode 100755 index 00000000..3f777c04 --- /dev/null +++ b/app/components/views/navigationBar/NavigationBar.js @@ -0,0 +1,61 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import cn from 'classnames'; +import { withStyles } from '@material-ui/core/styles'; +import Typography from '@material-ui/core/Typography'; +import Tooltip from '@material-ui/core/Tooltip'; +import { IconButton } from '@material-ui/core'; +import ArrowBackIcon from '@material-ui/icons/ArrowBack'; +import { iMessage } from 'commons/utils'; + +import styles from './styles/navigationBar'; + +const NavigationBar = ({ + classes, + mode, + directory, + env, + activePage, + setActivePage +}) => ( +
+ +
+ setActivePage('packages')} + > + + +
+
+
+ + {mode === 'local' + ? iMessage('info', 'workingDirectory') + : iMessage('info', 'showingGlobals')} + + + {mode === 'local' ? directory : env.prefix} + +
+
+); + +NavigationBar.propTypes = { + classes: PropTypes.objectOf(PropTypes.string).isRequired, + mode: PropTypes.string.isRequired, + directory: PropTypes.string, + activePage: PropTypes.string, + setActivePage: PropTypes.func, + env: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.objectOf(PropTypes.string) + ]) +}; + +export default withStyles(styles)(NavigationBar); diff --git a/app/components/views/navigationBar/index.js b/app/components/views/navigationBar/index.js new file mode 100755 index 00000000..91171a18 --- /dev/null +++ b/app/components/views/navigationBar/index.js @@ -0,0 +1,5 @@ +/* eslint-disable import/prefer-default-export */ + +import NavigationBar from './NavigationBar'; + +export { NavigationBar }; diff --git a/app/components/views/navigationBar/styles/navigationBar.js b/app/components/views/navigationBar/styles/navigationBar.js new file mode 100755 index 00000000..e7be28c6 --- /dev/null +++ b/app/components/views/navigationBar/styles/navigationBar.js @@ -0,0 +1,18 @@ +import { flexContainer } from 'styles/variables'; + +const styles = () => ({ + root: { + display: 'flex', + alignItems: 'center' + }, + flexContainer: { + ...flexContainer, + flexDirection: 'column', + justifyContent: 'space-between' + }, + flexGrow: { + flexGrow: 1 + } +}); + +export default styles; diff --git a/app/components/views/notifications/Header.js b/app/components/views/notifications/Header.js new file mode 100755 index 00000000..71137bd7 --- /dev/null +++ b/app/components/views/notifications/Header.js @@ -0,0 +1,62 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { and } from 'ramda'; + +import Hidden from '@material-ui/core/Hidden'; +import TableCell from '@material-ui/core/TableCell'; +import TableHead from '@material-ui/core/TableHead'; +import TableRow from '@material-ui/core/TableRow'; +import Checkbox from '@material-ui/core/Checkbox'; +import TableSortLabel from '@material-ui/core/TableSortLabel'; + +const columnData = [ + { id: 'required', numeric: false, disablePadding: true, label: 'Required', align: 'left' }, + { id: 'version', numeric: false, disablePadding: true, label: 'Version' }, + { id: 'info', numeric: false, disablePadding: true, label: '', align: 'right' }, +]; + + +const TableHeader = ({ selected, total, sortBy, sortDir, handleSelectAll }) => ( + + + + 0 && selected.length < total} + onClick={handleSelectAll} + /> + + {columnData.map(column => { + const needSort = + and(!!sortBy, !!column.id) && and(true, sortBy === column.id); + + return ( + + + {needSort ? ( + + {column.label} + + ) : ( + column.label + )} + + ); + })} + + +); + +TableHeader.propTypes = { + selected: PropTypes.arrayOf(PropTypes.string), + sortBy: PropTypes.string, + sortDir: PropTypes.string, + handleSelectAll: PropTypes.func, + total: PropTypes.number +}; + +export default TableHeader; diff --git a/app/components/views/notifications/List.js b/app/components/views/notifications/List.js deleted file mode 100755 index 3ba21f31..00000000 --- a/app/components/views/notifications/List.js +++ /dev/null @@ -1,118 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { withStyles } from '@material-ui/core/styles'; -import { useDispatch, useMappedState } from 'redux-react-hook'; - -import Paper from '@material-ui/core/Paper'; -import Typography from '@material-ui/core/Typography'; -import Tooltip from '@material-ui/core/Tooltip'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemAvatar from '@material-ui/core/ListItemAvatar'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; -import ListItemText from '@material-ui/core/ListItemText'; -import Avatar from '@material-ui/core/Avatar'; -import IconButton from '@material-ui/core/IconButton'; -import Divider from '@material-ui/core/Divider'; - -import SearchIcon from '@material-ui/icons/Search'; -import NotificationsIcon from '@material-ui/icons/NotificationsActiveTwoTone'; - -import { setActivePage, clearFilters } from 'models/ui/actions'; -import { setPackagesSearch } from 'models/packages/actions'; -import { iMessage } from 'commons/utils'; -import { HelperText } from 'components/common'; - -import styles from './styles/list'; - -const mapState = ({ notifications: { notifications } }) => ({ - notifications -}); - -const NotificationsList = ({ classes }) => { - const { notifications } = useMappedState(mapState); - const dispatch = useDispatch(); - - const onSearchHandler = packageName => { - dispatch(clearFilters()); - - dispatch({ - type: setActivePage.type, - payload: { - page: 'packages', - paused: true - } - }); - - dispatch( - setPackagesSearch({ - channel: 'npm-search', - options: { - cmd: ['search'], - pkgName: packageName, - fromSearch: true - } - }) - ); - }; - - if (!notifications.length) { - return ; - } - - return ( - -
-
-
- - {`Problems ${notifications ? notifications.length : 0}`} - -
-
- - - {notifications.map(({ required, requiredBy, type }) => { - const packageParts = required && required.split('@'); - const [packageName] = packageParts; - - return ( - - - - - - - - - -
- onSearchHandler(packageName)} - > - - -
-
-
-
- ); - })} -
-
-
- ); -}; - -NotificationsList.propTypes = { - classes: PropTypes.objectOf(PropTypes.string).isRequired -}; - -export default withStyles(styles)(NotificationsList); diff --git a/app/components/views/notifications/NotificationItem.js b/app/components/views/notifications/NotificationItem.js new file mode 100755 index 00000000..bf798a4d --- /dev/null +++ b/app/components/views/notifications/NotificationItem.js @@ -0,0 +1,116 @@ +import React from 'react'; +import { useState } from 'react' +import cn from 'classnames'; +import { withStyles } from '@material-ui/core/styles'; +import { arrayOf, objectOf, string, func } from 'prop-types'; +import Typography from '@material-ui/core/Typography'; +import Popover from '@material-ui/core/Popover' +import TableCell from '@material-ui/core/TableCell'; +import TableRow from '@material-ui/core/TableRow'; +import Checkbox from '@material-ui/core/Checkbox'; +import InfoIcon from '@material-ui/icons/InfoTwoTone'; +import { iMessage } from 'commons/utils'; + +import styles from './styles/listItem'; + +const NotificationItem = ({ + classes, + id, + selected, + handleSelectOne, + ...restProps +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const { requiredName, requiredVersion, reason, requiredByName } = restProps; + const isSelected = selected.indexOf(id) !== -1; + const open = Boolean(anchorEl); + + return ( + + + handleSelectOne(e, id)} + /> + + +
+ {requiredName} +
+
+ +
+ {requiredVersion} +
+
+ +
+ setAnchorEl(e.currentTarget)} + onMouseLeave={() => setAnchorEl(null)} + > + + + setAnchorEl(null)} + disableRestoreFocus + > + {iMessage('label', 'reason')}: {reason} + {iMessage('label', 'requiredByName')}:{requiredByName || ' - '} + +
+
+
+ ); +}; + +NotificationItem.propTypes = { + classes: objectOf(string).isRequired, + id: string.isRequired, + reason: string.isRequired, + requiredName: string, + requiredVersion: string, + requiredByName: string, + handleSelectOne: func.isRequired, + selected: arrayOf(string) +}; + +export default withStyles(styles)(NotificationItem); diff --git a/app/components/views/notifications/NotificationsList.js b/app/components/views/notifications/NotificationsList.js new file mode 100755 index 00000000..9d457bb9 --- /dev/null +++ b/app/components/views/notifications/NotificationsList.js @@ -0,0 +1,94 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import cn from 'classnames'; +import { withStyles } from '@material-ui/styles'; +import { Table, TableBody, Grid, Paper, Divider } from '@material-ui/core'; + +import { HelperText } from 'components/common'; +import { iMessage } from 'commons/utils'; +import TableHeader from './Header'; +import NotificationItem from './NotificationItem'; +import ToolbarView from './Toolbar'; + +import styles from './styles/list'; + +const NotificationsList = ({ + classes, + notifications, + selected, + loading, + handleSelectAll, + handleSelectOne, + handleInstall +}) => { + const noNotifications = !notifications || notifications.length === 0; + + return ( + + + {noNotifications && ( + + )} + {!noNotifications && ( + +
+ +
+ +
+ + + + {notifications.slice(0, 10).map(notification => ( + + ))} + +
+
+
+ )} +
+
+ ); +}; + +NotificationsList.propTypes = { + classes: PropTypes.objectOf(PropTypes.string).isRequired, + notifications: PropTypes.arrayOf(PropTypes.object).isRequired, + selected: PropTypes.arrayOf(PropTypes.string).isRequired, + handleSelectAll: PropTypes.func.isRequired, + handleSelectOne: PropTypes.func.isRequired, + handleInstall: PropTypes.func.isRequired, + loading: PropTypes.bool +}; + +export default withStyles(styles)(NotificationsList); diff --git a/app/components/views/notifications/Toolbar.js b/app/components/views/notifications/Toolbar.js new file mode 100755 index 00000000..a0f44339 --- /dev/null +++ b/app/components/views/notifications/Toolbar.js @@ -0,0 +1,63 @@ +import React from 'react'; +import cn from 'classnames'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; + +import Toolbar from '@material-ui/core/Toolbar'; +import IconButton from '@material-ui/core/IconButton'; +import Tooltip from '@material-ui/core/Tooltip'; +import Typography from '@material-ui/core/Typography'; + +import AddIcon from '@material-ui/icons/Add'; +import { iMessage } from 'commons/utils'; +import styles from './styles/toolbar'; + +const ToolbarView = ({ classes, total, title, selected, handleInstall }) => { + const hasNotificationsSelected = selected && selected.length > 0; + + return ( +
+ +
+ + {!hasNotificationsSelected + ? `${title} ${total}` + : `${selected.length} notification(s) selected`} + +
+
+
+ +
+ + + +
+
+
+ +
+ ); +}; + +ToolbarView.propTypes = { + classes: PropTypes.objectOf(PropTypes.string).isRequired, + selected: PropTypes.arrayOf(PropTypes.string).isRequired, + title: PropTypes.string.isRequired, + handleInstall: PropTypes.func.isRequired, + total: PropTypes.number +}; + +export default withStyles(styles)(ToolbarView); diff --git a/app/components/views/notifications/index.js b/app/components/views/notifications/index.js index 8c69ee6f..f864dfd8 100755 --- a/app/components/views/notifications/index.js +++ b/app/components/views/notifications/index.js @@ -1,5 +1,6 @@ /* eslint-disable import/prefer-default-export */ -import Notifications from './List'; +import Notifications from './NotificationsList'; +import ToolbarView from './Toolbar'; -export { Notifications }; +export { Notifications, ToolbarView }; diff --git a/app/components/views/notifications/styles/list.js b/app/components/views/notifications/styles/list.js index 79793001..475aa042 100755 --- a/app/components/views/notifications/styles/list.js +++ b/app/components/views/notifications/styles/list.js @@ -1,64 +1,47 @@ -import { defaultFont, flexContainer, grayColor } from 'styles/variables'; -import { darken, lighten } from '@material-ui/core/styles/colorManipulator'; +import { flexContainer } from 'styles/variables'; const styles = theme => ({ + flexContainer: { + ...flexContainer, + alignItems: 'center', + justifyContent: 'space-between' + }, + transition: { + transition: theme.transitions.create('width', { + duration: theme.transitions.duration.shortest + }) + }, paper: { width: '100%', borderTopLeftRadius: 0, borderTopRightRadius: 0 }, - container: { + toolbar: { width: '100%' }, - title: { - display: 'flex', - color: darken(grayColor, 0.2), - flexDirection: 'column', - justifyContent: 'flex-start' - }, - divider: { - marginLeft: theme.spacing(1), - marginRight: theme.spacing(1), - marginBottom: theme.spacing(1) - }, - list: { + tableWrapper: { whiteSpace: 'nowrap', - overflowY: 'scroll', padding: theme.spacing(1), [theme.breakpoints.up('md')]: { maxHeight: 450 }, [theme.breakpoints.up('lg')]: { - maxHeight: 750 + maxHeight: 650 } }, - flexContainer: { - ...flexContainer, - justifyContent: 'space-between' - }, - header: { - flex: '0 0 auto', - padding: theme.spacing(2) + 4 - }, - item: { - ...defaultFont - }, - containerHolder: { - ...flexContainer, - paddingTop: theme.spacing(2), - flexDirection: 'column', - alignItems: 'center' - }, - helperText: { - ...defaultFont, - color: lighten(grayColor, 0.1), - fontSize: 16 + tableResponsive: { + width: '100%', + marginTop: theme.spacing(3), + overflowX: 'auto' }, - noData: { - ...defaultFont + table: { + width: '100%', + backgroundColor: 'transparent', + borderSpacing: 0, + borderCollapse: 'collapse' }, - withPadding: { - padding: theme.spacing(1) + 4 + hasFilterBlur: { + filter: 'blur(15px)' } }); diff --git a/app/components/views/notifications/styles/listItem.js b/app/components/views/notifications/styles/listItem.js new file mode 100755 index 00000000..93335b9a --- /dev/null +++ b/app/components/views/notifications/styles/listItem.js @@ -0,0 +1,54 @@ +import { flexContainer, defaultFont } from 'styles/variables'; + +const styles = theme => ({ + flexContainerCell: { + ...flexContainer, + flexDirection: 'column', + justifyContent: 'flex-start', + alignItems: 'flex-start' + }, + tableRow: { + border: 'none', + padding: theme.spacing(1), + lineHeight: '1.1', + verticalAlign: 'middle', + '&:hover': { + cursor: 'pointer' + } + }, + tableCell: { + '& p': { + overflowWrap: 'break-word' + } + }, + cellText: { + ...defaultFont, + textAlign: 'left', + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis' + }, + requiredBy: { + [theme.breakpoints.up('lg')]: { + width: 'auto' + }, + [theme.breakpoints.down('md')]: { + width: 200 + }, + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + textAlign: 'left' + }, + span: { + color: '#fff' + }, + popover: { + pointerEvents: 'none', + }, + paper: { + padding: theme.spacing(1), + }, +}); + +export default styles; diff --git a/app/components/views/notifications/styles/toolbar.js b/app/components/views/notifications/styles/toolbar.js new file mode 100755 index 00000000..35bfebdf --- /dev/null +++ b/app/components/views/notifications/styles/toolbar.js @@ -0,0 +1,39 @@ +import { darken, lighten } from '@material-ui/core/styles/colorManipulator'; +import { defaultFont, flexContainer, grayColor } from 'styles/variables'; + +const styles = theme => ({ + root: { + width: '100%' + }, + tableListToolbar: { + paddingRight: 8 + }, + spacer: { + flex: '1 1 100%' + }, + header: { + flex: '0 0 auto', + padding: theme.spacing(2) + 4 + }, + title: { + display: 'flex', + color: darken(grayColor, 0.2), + flexDirection: 'column', + justifyContent: 'flex-start' + }, + directory: { + ...defaultFont, + fontSize: 12 + }, + highlight: { + color: theme.palette.common.white, + backgroundColor: lighten(theme.palette.secondary.light, 0.9) + }, + actions: { + ...flexContainer, + flex: '0 0 auto', + padding: theme.spacing(1) + } +}); + +export default styles; diff --git a/app/components/views/package/PackageInfo.js b/app/components/views/package/PackageInfo.js index 860da0d3..3ecef47b 100755 --- a/app/components/views/package/PackageInfo.js +++ b/app/components/views/package/PackageInfo.js @@ -1,3 +1,5 @@ +/* eslint-disable prefer-object-spread */ + import { shell } from 'electron'; import React from 'react'; import PropTypes from 'prop-types'; @@ -31,9 +33,9 @@ const PackageInfo = ({ classes, active, dependencies, short }) => { const openUrl = link => shell.openExternal(link); return ( - + <> {short ? null : ( - + { } /> - + {versions ? versions.length : 'N/A'} @@ -57,7 +59,7 @@ const PackageInfo = ({ classes, active, dependencies, short }) => { } /> - + {distTags && distTags.latest ? distTags.latest : 'N/A'} @@ -71,7 +73,7 @@ const PackageInfo = ({ classes, active, dependencies, short }) => { } /> - + {distTags && distTags.next ? distTags.next : 'N/A'} @@ -85,7 +87,7 @@ const PackageInfo = ({ classes, active, dependencies, short }) => { } /> - + {dependencies ? dependencies.length : 'N/A'} @@ -166,7 +168,7 @@ const PackageInfo = ({ classes, active, dependencies, short }) => { )} - + ); }; diff --git a/app/components/views/package/styles/packageInfo.js b/app/components/views/package/styles/packageInfo.js index 84c5362e..97f02b45 100755 --- a/app/components/views/package/styles/packageInfo.js +++ b/app/components/views/package/styles/packageInfo.js @@ -17,7 +17,7 @@ const styles = theme => ({ margin: `${theme.spacing(1) * 4}px 0 ${theme.spacing(2)}px` }, listItem: { - padding: theme.spacing(1), + padding: theme.spacing(1) / 2, margin: 0 }, secondaryColor: { @@ -26,7 +26,7 @@ const styles = theme => ({ }, warningColor: { color: theme.palette.common.white, - backgroundColor: theme.palette.warning.light + backgroundColor: theme.palette.error.light }, errorColor: { color: theme.palette.common.white, diff --git a/app/components/views/packages/Header.js b/app/components/views/packages/Header.js index 1bff5114..6c2a910c 100755 --- a/app/components/views/packages/Header.js +++ b/app/components/views/packages/Header.js @@ -1,16 +1,14 @@ import React from "react"; -import { useRef } from "react"; import PropTypes from "prop-types"; -import { and } from "ramda"; +import { useCallback, useRef } from "react"; import { useDispatch } from "redux-react-hook"; import TableCell from "@material-ui/core/TableCell"; import TableHead from "@material-ui/core/TableHead"; import TableRow from "@material-ui/core/TableRow"; import Checkbox from "@material-ui/core/Checkbox"; -import TableSortLabel from "@material-ui/core/TableSortLabel"; -import { addSelected, clearSelected, setSortOptions } from "models/ui/actions"; +import { addSelected } from "models/ui/actions"; const columnData = [ { id: "name", numeric: false, disablePadding: true, label: "Name" }, @@ -23,29 +21,19 @@ const TableHeader = ({ numSelected, rowCount, packages, sortBy, sortDir }) => { const dispatch = useDispatch(); const checkboxAll = useRef(null); - const toggleSort = prop => - dispatch( - setSortOptions({ - sortDir: sortDir === "desc" ? "asc" : "desc", - sortBy: prop - }) - ); - - const handleSelectAll = e => { + const handleSelectAll = useCallback(e => { if (e.target.checked && packages) { packages.forEach(name => dispatch( addSelected({ - name + name, + force: true }) ) ); - - return; } - dispatch(clearSelected()); - }; + }, [dispatch, packages]); return ( @@ -54,37 +42,20 @@ const TableHeader = ({ numSelected, rowCount, packages, sortBy, sortDir }) => { 0 && numSelected < rowCount} checked={numSelected === rowCount} - onChange={handleSelectAll} + onClick={handleSelectAll} inputProps={{ ref: checkboxAll }} /> - {columnData.map(column => { - const needSort = - and(!!sortBy, !!column.id) && and(true, sortBy === column.id); - - return ( - - {needSort ? ( - toggleSort(column.id)} - > - {column.label} - - ) : ( - column.label - )} - - ); - })} + {columnData.map(column => + {column.label} + )} ); diff --git a/app/components/views/packages/PackageItem.js b/app/components/views/packages/PackageItem.js index 5be80216..6adc4dbc 100755 --- a/app/components/views/packages/PackageItem.js +++ b/app/components/views/packages/PackageItem.js @@ -31,7 +31,6 @@ const PackageItem = ({ peerMissing, viewPackage, inOperation, - inPackageJson, hasError }) => { const rowRef = useRef(); @@ -50,9 +49,9 @@ const PackageItem = ({ }} onClick={() => (inOperation ? {} : viewPackage(name, version))} > - + { @@ -85,7 +84,7 @@ const PackageItem = ({ )}
{!extraneous && group && !fromSearch && ( - + {group} )} @@ -134,7 +133,6 @@ PackageItem.propTypes = { isOutdated: bool, inOperation: bool, hasError: bool, - inPackageJson: bool }; export default withStyles(styles)(PackageItem); diff --git a/app/components/views/packages/Toolbar.js b/app/components/views/packages/Toolbar.js index 225b9a1e..6b9d2dcc 100755 --- a/app/components/views/packages/Toolbar.js +++ b/app/components/views/packages/Toolbar.js @@ -55,89 +55,95 @@ const ToolbarView = ({ const dispatch = useDispatch(); const packagesOutdatedNames = outdated.map(pkg => pkg.name); - const openFilters = (e, close) => { - const { target } = e || {}; + const openFilters = useCallback( + (e, close) => { + const { target } = e || {}; - setAnchorEl(close ? null : target); - toggleFilters(!filtersOn); - scrollWrapper(0); - }; + setAnchorEl(close ? null : target); + toggleFilters(!filtersOn); + scrollWrapper(0); + }, + [filtersOn, scrollWrapper] + ); - const clearAllFilters = () => { + const clearAllFilters = useCallback(() => { if (filteredByNamePackages.length) { setFilteredByNamePackages([]); } dispatch(clearFilters()); - }; - - const handleAction = (action, force, latest) => { - let pkgOptions; + }, [filteredByNamePackages, setFilteredByNamePackages, dispatch]); - if (action === 'clearFilters') { - return clearAllFilters(); - } - - if (!selected.length) { - return; - } + const handleAction = useCallback( + (action, force, latest) => { + let pkgOptions; - if (mode === 'local' && action === 'install' && !force) { - return toggleOptions({ - open: true, - single: false - }); - } + if (action === 'clearFilters') { + return clearAllFilters(); + } - if (action === 'install') { - if (mode === 'local') { - pkgOptions = selected.map(packageName => { - const packageDetails = packagesData.find( - packageDataDetails => packageDataDetails.name === packageName - ); - const { __group } = packageDetails; + if (!selected.length) { + return; + } - return [PACKAGE_GROUPS[__group]]; + if (mode === 'local' && action === 'install' && !force) { + return toggleOptions({ + open: true, + single: false }); } - return dispatch( - installMultiplePackages({ - ipcEvent: 'npm-install', - cmd: selected.map(() => 'install'), - multiple: true, - pkgOptions: mode === 'local' ? pkgOptions : null, - packages: latest - ? selected.map(selectedPackage => `${selectedPackage}@latest`) - : selected - }) - ); - } + if (action === 'install') { + if (mode === 'local') { + pkgOptions = selected.map(packageName => { + const packageDetails = packagesData.find( + packageDataDetails => packageDataDetails.name === packageName + ); + const { __group } = packageDetails; - if (action === 'uninstall') { - return dispatch( - uninstallPackages({ - ipcEvent: 'npm-uninstall', - cmd: ['uninstall'], - multiple: true, - packages: selected - }) - ); - } + return [PACKAGE_GROUPS[__group]]; + }); + } - if (action === 'update') { - return dispatch( - updatePackages({ - ipcEvent: 'npm-update', - cmd: ['update'], - multiple: true, - packages: selected - }) - ); - } + return dispatch( + installMultiplePackages({ + ipcEvent: 'npm-install', + cmd: selected.map(() => 'install'), + multiple: true, + pkgOptions: mode === 'local' ? pkgOptions : null, + packages: latest + ? selected.map(selectedPackage => `${selectedPackage}@latest`) + : selected + }) + ); + } + + if (action === 'uninstall') { + return dispatch( + uninstallPackages({ + ipcEvent: 'npm-uninstall', + cmd: ['uninstall'], + multiple: true, + packages: selected + }) + ); + } + + if (action === 'update') { + return dispatch( + updatePackages({ + ipcEvent: 'npm-update', + cmd: ['update'], + multiple: true, + packages: selected + }) + ); + } - return false; - }; + return false; + }, + [selected, packagesData, mode, clearAllFilters, toggleOptions, dispatch] + ); const renderAction = action => switchcase({ @@ -159,13 +165,13 @@ const ToolbarView = ({ })('none')(action); const renderToolbarActions = () => ( - + <> {!fromSearch && total ? ( ) : null} - + ); const hasUpdatedPackages = useCallback( diff --git a/app/components/views/packages/styles/packageItem.js b/app/components/views/packages/styles/packageItem.js index 74b723e2..87214e93 100755 --- a/app/components/views/packages/styles/packageItem.js +++ b/app/components/views/packages/styles/packageItem.js @@ -1,71 +1,68 @@ -import { darken, lighten } from "@material-ui/core/styles/colorManipulator"; -import { flexContainer, defaultFont } from "styles/variables"; +import { flexContainer, defaultFont } from 'styles/variables'; const styles = theme => ({ flexContainer: { ...flexContainer, - alignItems: "center", - justifyContent: "space-between" + alignItems: 'center', + justifyContent: 'space-between' }, flexContainerCell: { ...flexContainer, - flexDirection: "column", - justifyContent: "flex-start", - alignItems: "flex-start" + flexDirection: 'column', + justifyContent: 'flex-start', + alignItems: 'flex-start' }, tableRow: { - border: "none", - padding: 10, - lineHeight: "1.1", - verticalAlign: "middle", - "&:hover": { - cursor: "pointer" + border: 'none', + padding: theme.spacing(1), + lineHeight: '1.1', + verticalAlign: 'middle', + '&:hover': { + cursor: 'pointer' } }, tableCell: { ...defaultFont, - fontSize: "1rem", - textAlign: "center", - "& p": { - overflowWrap: "break-word" + textAlign: 'center', + '& p': { + overflowWrap: 'break-word' } }, loader: { marginLeft: theme.spacing(1) }, name: { - ...defaultFont, - [theme.breakpoints.up("lg")]: { - width: "auto" + [theme.breakpoints.up('lg')]: { + width: 'auto' }, - [theme.breakpoints.down("md")]: { + [theme.breakpoints.down('md')]: { width: 200 }, - whiteSpace: "nowrap", - overflow: "hidden", - textOverflow: "ellipsis", - textAlign: "left" + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + textAlign: 'left' }, group: { - color: darken(theme.palette.secondary.light, 0.3) + color: theme.palette.primary.main }, statusMissing: { - color: darken(theme.palette.secondary.main, 0.1) + color: theme.palette.secondary.main }, statusOK: { - color: lighten("#00b300", 0.3) + color: '#00b300' }, statusPeerMissing: { - color: darken(theme.palette.secondary.main, 0.1) + color: theme.palette.secondary.main }, statusOutdated: { - color: lighten(theme.palette.warning.main, 0.3) + color: theme.palette.error.main }, statusExtraneous: { - color: darken(theme.palette.secondary.main, 0.1) + color: theme.palette.secondary.main }, statusError: { - color: darken(theme.palette.secondary.main, 0.1) + color: theme.palette.secondary.main } }); diff --git a/app/components/views/packages/styles/packages.js b/app/components/views/packages/styles/packages.js index b666059d..78cc8074 100755 --- a/app/components/views/packages/styles/packages.js +++ b/app/components/views/packages/styles/packages.js @@ -2,7 +2,7 @@ import { darken, lighten } from '@material-ui/core/styles/colorManipulator'; import { flexContainer, defaultFont } from 'styles/variables'; const styles = theme => ({ - root: { + paper: { width: '100%', borderTopLeftRadius: 0, borderTopRightRadius: 0, @@ -81,7 +81,6 @@ const styles = theme => ({ }, tableCell: { ...defaultFont, - fontSize: '1rem', textAlign: 'center', '& p': { overflowWrap: 'break-word' @@ -128,7 +127,7 @@ const styles = theme => ({ color: darken(theme.palette.secondary.main, 0.1) }, statusOutdated: { - color: lighten(theme.palette.warning.main, 0.3) + color: lighten(theme.palette.error.main, 0.3) }, statusExtraneous: { color: darken(theme.palette.secondary.main, 0.1) @@ -144,7 +143,6 @@ const styles = theme => ({ }, name: { ...defaultFont, - fontSize: '1rem', [theme.breakpoints.up('md')]: { maxWidth: '100%' }, diff --git a/app/components/views/sidebar/Sidebar.js b/app/components/views/sidebar/Sidebar.js new file mode 100755 index 00000000..13cc908e --- /dev/null +++ b/app/components/views/sidebar/Sidebar.js @@ -0,0 +1,54 @@ +import React from 'react'; +import { string, objectOf, func, bool, object, arrayOf } from 'prop-types'; +import { withStyles } from '@material-ui/styles'; + +import { AppTabs, AppLogo } from 'components/common/'; +import { + PackagesTab, + ActionsTab, + HistoryTab +} from 'components/views/sidebar/tabs'; +import styles from './styles/sidebar'; + +const Sidebar = ({ + classes, + loading, + mode, + history, + loadDirectory, + updatedAt, + tabPackagesData, + installPackagesFromJson, + dedupe +}) => ( +
+ + + + + + +
+ ); + +Sidebar.propTypes = { + classes: objectOf(string).isRequired, + mode: string.isRequired, + loading: bool, + history: arrayOf(object), + loadDirectory: func.isRequired, + installPackagesFromJson: func.isRequired, + dedupe: func.isRequired, + updatedAt: string, + tabPackagesData: arrayOf(object) +}; + +export default withStyles(styles)(Sidebar); diff --git a/app/components/views/sidebar/index.js b/app/components/views/sidebar/index.js new file mode 100755 index 00000000..8f6f607f --- /dev/null +++ b/app/components/views/sidebar/index.js @@ -0,0 +1,5 @@ +/* eslint-disable import/prefer-default-export */ + +import Sidebar from './Sidebar'; + +export { Sidebar }; diff --git a/app/components/views/sidebar/styles/sidebar.js b/app/components/views/sidebar/styles/sidebar.js new file mode 100755 index 00000000..5bb8c1d7 --- /dev/null +++ b/app/components/views/sidebar/styles/sidebar.js @@ -0,0 +1,13 @@ +const styles = theme => ({ + root: { + width: '100%', + height: '100%', + display: 'flex', + flexDirection: 'column' + }, + spacer: { + margin: theme.spacing(1, 0) + } +}); + +export default styles; diff --git a/app/components/views/sidebar/tabs/Actions.js b/app/components/views/sidebar/tabs/Actions.js index 943af1d4..166b8c34 100755 --- a/app/components/views/sidebar/tabs/Actions.js +++ b/app/components/views/sidebar/tabs/Actions.js @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import { withStyles } from '@material-ui/core/styles'; - import Tooltip from '@material-ui/core/Tooltip'; import IconButton from '@material-ui/core/IconButton'; import List from '@material-ui/core/List'; @@ -10,85 +9,87 @@ import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import ArrowRightIcon from '@material-ui/icons/ArrowRightAlt'; import Typography from '@material-ui/core/Typography'; - import { iMessage } from 'commons/utils'; + import styles from './styles/actions'; -const ActionsTab = ({ - classes, - mode, - installPackagesFromJson, - toggleDialog -}) => ( -
- - - - {iMessage('action', 'npmInstall')} - - } - secondary={ - - {iMessage('info', 'npmInstallInfo')} - - } - /> - - -
- - - -
-
-
-
- - - {iMessage('action', 'npmDoctor')} - +const ActionsTab = ({ classes, mode, onInstallPackagesFromJson, onDedupe }) =>
+ + + + {iMessage('action', 'npmInstall')} + + } + secondary={ + + {iMessage('info', 'npmInstallInfo')} + + } + /> + + - {iMessage('info', 'npmDoctorInfo')} - + > +
+ + + +
+
+
+
+ + + {iMessage('action', 'npmDedupe')} + + } + secondary={ + + {iMessage('info', 'npmDedupeInfo')} + + } + /> + + - - -
- toggleDialog(true)} - > - - -
-
-
-
-
-
-); + > +
+ + + +
+ + +
+
+
ActionsTab.propTypes = { classes: PropTypes.objectOf(PropTypes.string).isRequired, - installPackagesFromJson: PropTypes.func.isRequired, - toggleDialog: PropTypes.func, + onInstallPackagesFromJson: PropTypes.func.isRequired, + onDedupe: PropTypes.func.isRequired, mode: PropTypes.string }; diff --git a/app/components/views/sidebar/tabs/History.js b/app/components/views/sidebar/tabs/History.js index 977bd0c5..9f52350c 100755 --- a/app/components/views/sidebar/tabs/History.js +++ b/app/components/views/sidebar/tabs/History.js @@ -10,10 +10,9 @@ import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; import ArrowRightIcon from '@material-ui/icons/ArchiveOutlined'; -import FolderIcon from '@material-ui/icons/FolderOpen'; +import { iMessage } from 'commons/utils' import styles from './styles/history'; @@ -24,7 +23,7 @@ const HistoryTab = ({ classes, directories, onClick }) => ( No history
+ {iMessage('info', 'noHistory')} } /> @@ -37,14 +36,9 @@ const HistoryTab = ({ classes, directories, onClick }) => ( .join('/'); return ( - - -
- - - -
-
+ {dir.name} @@ -56,15 +50,14 @@ const HistoryTab = ({ classes, directories, onClick }) => ( } /> - -
- onClick(dir.directory)} - > - - -
+ + onClick(dir.directory)} + disableRipple + > + +
diff --git a/app/components/views/sidebar/tabs/Packages.js b/app/components/views/sidebar/tabs/Packages.js index 936064ee..d6586158 100755 --- a/app/components/views/sidebar/tabs/Packages.js +++ b/app/components/views/sidebar/tabs/Packages.js @@ -6,39 +6,77 @@ import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; +import Divider from '@material-ui/core/Divider'; +import Card from '@material-ui/core/Card'; +import CardContent from '@material-ui/core/CardContent'; +import CardActions from '@material-ui/core/CardActions'; import Typography from '@material-ui/core/Typography'; +import UpdateIcon from '@material-ui/icons/Update'; +import { AppLoader } from 'components/common'; + +import { iMessage } from "commons/utils"; import styles from './styles/packages'; -const PackagesTab = ({ classes, items }) => ( -
- - {items && - items.map(item => ( - - - - {item.primaryText} - -
- } - /> - - - {item.secondaryText} - - -
- ))} - -
+const PackagesTab = ({ classes, items, loading, updatedAt }) => ( + + + + {iMessage('title', 'overview')} + + +
+ + + {items && + items.map(item => ( + + + + {item.primaryText} + +
+ } + /> + + + {item.secondaryText} + + + + ))} + + +
+ + + +
+ + + {iMessage('info', 'updatedAt')} {updatedAt !== null ? updatedAt : '...'} + +
+
+ ); PackagesTab.propTypes = { classes: PropTypes.objectOf(PropTypes.string).isRequired, - items: PropTypes.arrayOf(PropTypes.object).isRequired + items: PropTypes.arrayOf(PropTypes.object).isRequired, + loading: PropTypes.bool, + updatedAt: PropTypes.string }; export default withStyles(styles)(PackagesTab); diff --git a/app/components/views/sidebar/tabs/index.js b/app/components/views/sidebar/tabs/index.js index 605fa348..7277b9a1 100755 --- a/app/components/views/sidebar/tabs/index.js +++ b/app/components/views/sidebar/tabs/index.js @@ -1,5 +1,3 @@ -/* eslint-disable import/prefer-default-export */ - import PackagesTab from './Packages'; import ActionsTab from './Actions'; import HistoryTab from './History'; diff --git a/app/components/views/sidebar/tabs/styles/actions.js b/app/components/views/sidebar/tabs/styles/actions.js index a9e528dc..58300383 100755 --- a/app/components/views/sidebar/tabs/styles/actions.js +++ b/app/components/views/sidebar/tabs/styles/actions.js @@ -2,10 +2,6 @@ import { defaultFont, grayColor } from 'styles/variables'; import { darken } from '@material-ui/core/styles/colorManipulator'; const styles = theme => ({ - root: { - flexGrow: 1, - maxWidth: 752 - }, tab: { backgroundColor: theme.palette.background.paper }, @@ -20,7 +16,6 @@ const styles = theme => ({ fontSize: 12 }, listItem: { - padding: theme.spacing(1), margin: 0 }, secondaryColor: { @@ -29,7 +24,7 @@ const styles = theme => ({ }, warningColor: { color: theme.palette.common.white, - backgroundColor: theme.palette.warning.light + backgroundColor: theme.palette.error.light }, errorColor: { color: theme.palette.common.white, diff --git a/app/components/views/sidebar/tabs/styles/history.js b/app/components/views/sidebar/tabs/styles/history.js index 1e7342d4..e7035e6d 100755 --- a/app/components/views/sidebar/tabs/styles/history.js +++ b/app/components/views/sidebar/tabs/styles/history.js @@ -11,9 +11,6 @@ const styles = theme => ({ }, label: { ...defaultFont, - width: '100%', - fontSize: 16, - color: darken(grayColor, 0.5) }, directory: { ...defaultFont, @@ -23,7 +20,8 @@ const styles = theme => ({ maxWidth: 150 }, listItem: { - padding: theme.spacing(1), + padding: 0, + paddingLeft: theme.spacing(1) + 4, margin: 0 }, secondaryColor: { @@ -32,7 +30,7 @@ const styles = theme => ({ }, warningColor: { color: theme.palette.common.white, - backgroundColor: theme.palette.warning.light + backgroundColor: theme.palette.error.light }, errorColor: { color: theme.palette.common.white, diff --git a/app/components/views/sidebar/tabs/styles/packages.js b/app/components/views/sidebar/tabs/styles/packages.js index dd53b691..778f2f7f 100755 --- a/app/components/views/sidebar/tabs/styles/packages.js +++ b/app/components/views/sidebar/tabs/styles/packages.js @@ -1,46 +1,60 @@ import { defaultFont, grayColor, flexContainer } from 'styles/variables'; -import { darken } from '@material-ui/core/styles/colorManipulator'; +import { darken, lighten } from '@material-ui/core/styles/colorManipulator'; const styles = theme => ({ - containerHolder: { + flexContainer: { ...flexContainer }, - icon: { - marginRight: theme.spacing(0.5) + card: { + width: 260, }, - avatar: { - padding: theme.spacing(1) + cardTitle: { + ...defaultFont, + fontSize: 20, + paddingBottom: theme.spacing(1) }, - tab: { - backgroundColor: theme.palette.background.paper + cardFlexContainer: { + ...flexContainer, + width: '100%', + justifyContent: 'space-between', + padding: theme.spacing(1), + alignItems: 'center' }, - title: { - ...defaultFont, - fontSize: 18, - color: darken(grayColor, 0.2) + cardFlexContainerInner: { + ...flexContainer, + alignItems: 'center' }, - stats: { + cardLabel: { ...defaultFont, - fontSize: 24, - color: darken(grayColor, 0.2) + fontSize: 12, + color: darken(grayColor, 0.5) + }, + tab: { + width: '100%', + minHeight: 150 }, listItem: { - margin: 0 + margin: 0, + padding: theme.spacing(1) / 2 + }, + loader: { + paddingTop: theme.spacing(1) + }, + updateIcon: { + color: lighten(theme.palette.primary.main, 0.2), + marginRight: theme.spacing(1) }, primaryColor: { - color: darken(theme.palette.primary.main, 0.1) + color: theme.palette.primary.main }, secondaryColor: { color: theme.palette.secondary.main }, warningColor: { - color: theme.palette.warning.light + color: theme.palette.error.light }, errorColor: { - color: darken(theme.palette.secondary.main, 0.1) - }, - withPadding: { - padding: theme.spacing(0.5) + color: theme.palette.error.light } }); diff --git a/app/components/views/topBar/TopBar.js b/app/components/views/topBar/TopBar.js new file mode 100755 index 00000000..dd192be2 --- /dev/null +++ b/app/components/views/topBar/TopBar.js @@ -0,0 +1,145 @@ +import React from 'react'; +import { objectOf, func, bool, arrayOf, object, string } from 'prop-types'; +import { withStyles } from '@material-ui/styles'; +import { AppBar, Toolbar, Tooltip, Badge, IconButton } from '@material-ui/core'; + +import NotificationsActiveIcon from '@material-ui/icons/NotificationsActiveOutlined'; +import NotificationsIcon from '@material-ui/icons/NotificationsOutlined'; +import SettingsIcon from '@material-ui/icons/SettingsOutlined'; +import AddIcon from '@material-ui/icons/AddOutlined'; +import ArchiveIcon from '@material-ui/icons/ArchiveOutlined'; +import SecurityIcon from '@material-ui/icons/SecurityOutlined'; +import LocalHospitalIcon from '@material-ui/icons/LocalHospitalOutlined'; + +import { SearchBox } from 'components/common'; +import { iMessage } from 'commons/utils'; +import styles from './styles/topBar'; + +const Topbar = ({ + classes, + notifications, + mode, + loading, + onLoadDirectory, + onInitFlow, + onShowSettings, + setActivePage +}) => ( + + +
+ + +
+ + + +
+
+ +
+ + + +
+
+ +
+ setActivePage('audit')} + disabled={loading || mode === 'global'} + > + + +
+
+ +
+ setActivePage('doctor')} + > + + +
+
+ +
+ setActivePage('notifications')} + > + + {notifications && notifications.length ? : } + + +
+
+
+
+
+ + + + + + + ); + +Topbar.propTypes = { + classes: objectOf(string).isRequired, + mode: string.isRequired, + loading: bool, + notifications: arrayOf(object), + onLoadDirectory: func, + setActivePage: func, + onInitFlow: func, + onShowSettings: func +}; + +export default withStyles(styles)(Topbar); diff --git a/app/components/views/topBar/index.js b/app/components/views/topBar/index.js new file mode 100755 index 00000000..24b00d84 --- /dev/null +++ b/app/components/views/topBar/index.js @@ -0,0 +1,5 @@ +/* eslint-disable import/prefer-default-export */ + +import TopBar from './TopBar'; + +export { TopBar }; diff --git a/app/components/views/topBar/styles/topBar.js b/app/components/views/topBar/styles/topBar.js new file mode 100755 index 00000000..2789878b --- /dev/null +++ b/app/components/views/topBar/styles/topBar.js @@ -0,0 +1,17 @@ +const styles = theme => ({ + root: { + zIndex: 'auto', + boxShadow: 'none' + }, + actions: { + paddingLeft: theme.spacing(1) / 2 + }, + flexGrow: { + flexGrow: 1 + }, + button: { + marginLeft: theme.spacing(1) + } +}); + +export default styles; diff --git a/app/constants/AppConstants.js b/app/constants/AppConstants.js index 8a2b34dd..c472c205 100755 --- a/app/constants/AppConstants.js +++ b/app/constants/AppConstants.js @@ -19,9 +19,9 @@ export const APP_MODES = { local: 'local' }; -export const DEFAULT_MODE = 'Global mode'; +export const DEFAULT_MODE = 'global'; export const DEFAULT_VERSION = '1.0.0'; -export const ERROR_TYPES = ['WARN', 'ERR']; +export const ERROR_TYPES = ['extraneous', 'peer dep missing', 'missing']; export const FATAL_ERROR = 'Fatal error. Please try again'; export const APP_INFO = { diff --git a/app/constants/AppMessages.js b/app/constants/AppMessages.js index 059194c8..db9dbf4a 100755 --- a/app/constants/AppMessages.js +++ b/app/constants/AppMessages.js @@ -1,23 +1,26 @@ export const INFO_MESSAGES = { + noVulnerabilities: 'No issues found', + noHistory: 'History is empty', loading: 'Loading packages..', loadingPackage: 'Loading package..', - noData: 'No dependencies found.', + noData: 'No dependencies found', loaded: 'Package loaded.', showingGlobals: 'Showing globals', workingDirectory: 'Working directory', installingPackages: 'Please wait. Installing packages..', updating: 'Please wait. Updating packages..', + deduping: 'Please wait. npm dedupe is running..', npmInstallInfo: 'Install all packages from package.json', npmAuditInfo: 'Scan project for vulnerabilities', npmDoctorInfo: 'Run a set of checks to ensure your npm installation', + npmDedupeInfo: 'Simplify the overall structure by moving dependencies further up the tree', npmAuditHelperText: 'Navigate to actions tab and run npm audit', npmDoctorHelperText: 'Navigate to actions tab and run npm doctor', noNotifications: 'No problems', notGlobalModeAvailable: 'Not available in global mode', notificationsHelperText: 'Woohoo! There are not any problems found.', npmAuditVulnerabiliesHelperText: 'Known valnerabilities in your project', - createPackageJsonHelperText: - 'Create a new package.json file in directory and start working.', + createPackageJsonHelperText: 'Create a new package.json file', noPackages: 'No packages found', noAuditData: 'No audit data', noDoctorData: 'No doctor data', @@ -30,13 +33,15 @@ export const INFO_MESSAGES = { auditFix: 'Automatically install any compatible updates to vulnerable dependencies', auditForce: - 'Have audit fix install semver-major updates to toplevel dependencies, not just semver-compatible ones' + 'Have audit fix install semver-major updates to toplevel dependencies, not just semver-compatible ones', + backToPackages: 'Back to packages' }; export const ACTION_MESSAGES = { analyze: 'Analyze', npmInstall: 'npm install', npmDoctor: 'npm doctor', + npmDedupe: 'npm dedupe', install: 'Install', update: 'Update', view: 'View', @@ -46,7 +51,7 @@ export const ACTION_MESSAGES = { filter: 'Filter', close: 'Close', runDoctor: 'Run doctor', - runAudit: 'Run', + runAudit: 'Run audit', runAuditFix: 'Fix', runAuditFixForce: 'Force', runAuditFixProd: 'Fix only prod', @@ -86,10 +91,16 @@ export const LABEL_MESSAGES = { findings: 'Findings', access: 'Access', created: 'Created at', - updated: 'Updated at' + updated: 'Updated at', + reason: 'Reason', + requiredByName: 'Required by', + visitGithub: 'visit', + visitHomepage: 'visit' }; export const TITLE_MESSAGES = { + switchToGlobals: 'Switch to globals', + notifications: 'Notifications', dashboard: 'Dashboard', dependencies: 'Dependencies', devDependencies: 'Development', @@ -105,7 +116,7 @@ export const TITLE_MESSAGES = { loadDirectory: 'Load a directory from a package.json file', selectPackageJson: 'Select package.json file', installationOptions: 'Please select installation options', - system: 'Settings', + settings: 'Settings', switchGlobals: 'Switch to global packages', showFilters: 'Show filters', clearFilters: 'Clear filters', @@ -139,27 +150,27 @@ export const TITLE_MESSAGES = { export const CONFIRMATION_MESSAGES = { actionRun: - '\nDo you want to run %name%?\nNote: This process will take some time', - installAll: `\nDo you want to install all the packages from \n%directory% \nNote: This process will take some time `, - installPackage: '\nDo you want to install %name%?', - installSelected: '\nDo you want to install the selected packages?', - installLatest: '\nDo you want to install %name% latest version?', - installVersion: '\nDo you want to install %name% version %version%?', - updatePackage: '\nDo you want to update %name%?', - uninstallPackage: '\nDo you want to uninstall %name%?', - searchPackage: '\nDo you want to search for %packageName%?', + 'Do you want to run %name%?\nNote: This process will take some time', + installAll: `Do you want to install all the packages from \n%directory% \nNote: This process will take some time `, + installPackage: 'Do you want to install %name%?', + installSelected: 'Do you want to install the selected packages?', + installLatest: 'Do you want to install %name% latest version?', + installVersion: 'Do you want to install %name% version %version%?', + updatePackage: 'Do you want to update %name%?', + uninstallPackage: 'Do you want to uninstall %name%?', + searchPackage: 'Do you want to search for %packageName%?', installLatestSelected: - '\nDo you want to install the latest version of the selected packages?', - updateSelected: '\nDo you want to update the selected packages?', - uninstallSelected: '\nDo you want to uninstall the selected packages?', + 'Do you want to install the latest version of the selected packages?', + updateSelected: 'Do you want to update the selected packages?', + uninstallSelected: 'Do you want to uninstall the selected packages?', auditFix: - '\nDo you want to run npm audit fix? \n\nIt will automatically install any compatible updates to vulnerable dependencies.', + 'Do you want to run npm audit fix? \n\nIt will automatically install any compatible updates to vulnerable dependencies.', auditFixForce: - '\nDo you want to run npm audit fix --force? \n\nInstall semver-major updates to toplevel dependencies, not just semver-compatible ones.', + 'Do you want to run npm audit fix --force? \n\nInstall semver-major updates to toplevel dependencies, not just semver-compatible ones.', auditFixOnlyProd: - '\nDo you want to run npm audit fix --only=prod?\n\nIt will skip updating devDependencies.', + 'Do you want to run npm audit fix --only=prod?\n\nIt will skip updating devDependencies.', auditFixOnlyDev: - '\nDo you want to run npm audit fix --only=dev? \n\nIt will skip updating dependencies.' + 'Do you want to run npm audit fix --only=dev? \n\nIt will skip updating dependencies.' }; export const WARNING_MESSAGES = { @@ -170,10 +181,10 @@ export const WARNING_MESSAGES = { 'Some packages have errors. Check your notifications to fix it.', yarnlock: 'It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. \nTo clear this warning, remove yarn-lock.json.', - newerSelected: - 'A package with the same name and newer version is already selected', - oldorEqualSelected: - 'A package with the same name and same or lower version is already selected' }; -export const ERROR_MESSAGES = {}; +export const ERROR_MESSAGES = { + installationError: 'Installation error', + updateError: 'Update error', + uninstallError: 'Uninstall error', +}; diff --git a/app/containers/App.js b/app/containers/App.js index 8fc85875..588e49c3 100755 --- a/app/containers/App.js +++ b/app/containers/App.js @@ -1,14 +1,11 @@ -/** - * App with error boundary - */ - import { ipcRenderer } from 'electron'; import React, { useEffect } from 'react'; import { useDispatch, useMappedState } from 'redux-react-hook'; +import { MuiThemeProvider } from '@material-ui/core/styles'; + import CssBaseline from '@material-ui/core/CssBaseline'; -import { ThemeProvider } from '@material-ui/styles'; -import { withErrorBoundary } from 'commons/hocs'; +import { withErrorBoundary } from 'commons/hocs'; import { setEnv } from 'models/npm/actions'; import { initActions, updateStatus } from 'models/common/actions'; import { setUIException, setSnackbar } from 'models/ui/actions'; @@ -78,10 +75,10 @@ const App = () => { }, [dispatch]); return ( - + {!uiException ? : uiException} - + ); }; diff --git a/app/containers/AppHeader.js b/app/containers/AppHeader.js deleted file mode 100755 index 2e26e5c1..00000000 --- a/app/containers/AppHeader.js +++ /dev/null @@ -1,259 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { shell } from 'electron'; -import { useState } from 'react'; -import { useMappedState, useDispatch } from 'redux-react-hook'; -import { withStyles } from '@material-ui/core/styles'; - -import AppBar from '@material-ui/core/AppBar'; -import Grid from '@material-ui/core/Grid'; -import Hidden from '@material-ui/core/Hidden'; -import IconButton from '@material-ui/core/IconButton'; -import Tab from '@material-ui/core/Tab'; -import Tabs from '@material-ui/core/Tabs'; -import Toolbar from '@material-ui/core/Toolbar'; -import Tooltip from '@material-ui/core/Tooltip'; -import Typography from '@material-ui/core/Typography'; -import Popover from '@material-ui/core/Popover'; -import Button from '@material-ui/core/Button'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import Dialog from '@material-ui/core/Dialog'; -import DialogContent from '@material-ui/core/DialogContent'; - -import AddIcon from '@material-ui/icons/AddOutlined'; -import MenuIcon from '@material-ui/icons/Menu'; -import SettingsIcon from '@material-ui/icons/Settings'; -import PackagesIcon from '@material-ui/icons/ViewModuleRounded'; -import ErrorIcon from '@material-ui/icons/WarningOutlined'; -import SecurityIcon from '@material-ui/icons/SecurityOutlined'; - -import { Init, SearchBox, Settings } from 'components/views/common'; -import { iMessage } from 'commons/utils'; -import { setActivePage } from 'models/ui/actions'; - -import styles from './styles/appHeader'; - -const GIT_URL = 'https://github.com/rvpanoz/luna'; -const openUrl = url => shell.openExternal(url); - -const mapState = ({ - npm: { env }, - common: { onlineStatus, mode, directory }, - ui: { - activePage, - loaders: { - loader: { loading } - } - } -}) => ({ - mode, - directory, - onlineStatus, - activePage, - loading, - env -}); - -const Header = ({ classes, onDrawerToggle }) => { - const [anchorEl, setAnchorEl] = useState(null); - const [initFlowDialog, setInitFlowDialog] = useState({ - open: false - }); - const { activePage, loading, env, status, mode, directory } = useMappedState( - mapState - ); - const dispatch = useDispatch(); - const settings = [ - { - primaryText: 'Environment', - secondaryText: env.userAgent - }, - { - primaryText: 'Registry', - secondaryText: env.metricsRegistry - }, - { - primaryText: 'Audit level', - secondaryText: env.auditLevel - }, - { - primaryText: 'Cache', - secondaryText: env.cache - } - ]; - - return ( -
- - - - - - - - - - - - - - - - openUrl(GIT_URL)} - > - Github - - - - - setAnchorEl(e.currentTarget)} - > - - - - - - - - - - - - - {iMessage('title', 'dashboard')} - - - {mode === 'local' - ? iMessage('info', 'workingDirectory') - : iMessage('info', 'showingGlobals')} - - - {mode === 'local' ? directory : env.prefix} - - - - -
- -
-
-
-
-
-
- - - dispatch( - setActivePage({ - page: value, - paused: true - }) - ) - } - > - } - /> - } - classes={{ - root: classes.tabLabel - }} - /> - } - classes={{ - root: classes.tabLabel - }} - /> - - - setAnchorEl(null)} - anchorOrigin={{ - vertical: 'bottom', - horizontal: 'center' - }} - transformOrigin={{ - vertical: 'top', - horizontal: 'center' - }} - > - - - setInitFlowDialog({ open: false })} - aria-labelledby="npm-init" - > - {iMessage('title', 'createPackageJson')} - - setInitFlowDialog({ open: false })} /> - - -
- ); -}; - -Header.propTypes = { - classes: PropTypes.objectOf(PropTypes.string).isRequired, - onDrawerToggle: PropTypes.func.isRequired -}; - -export default withStyles(styles)(Header); diff --git a/app/containers/AppLayout.js b/app/containers/AppLayout.js index 992bbd33..5d01fcad 100755 --- a/app/containers/AppLayout.js +++ b/app/containers/AppLayout.js @@ -1,23 +1,26 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { useState } from "react"; -import { useMappedState, useDispatch } from "redux-react-hook"; -import { MuiThemeProvider, withStyles } from "@material-ui/core/styles"; -import Snackbar from "@material-ui/core/Snackbar"; -import theme from "styles/theme"; +import React from 'react'; +import { objectOf, string } from 'prop-types'; +import cn from 'classnames'; -import AppSidebar from "containers/AppSidebar"; -import AppHeader from "containers/AppHeader"; +import { useMappedState, useDispatch } from 'redux-react-hook'; +import { withStyles } from '@material-ui/core/styles'; +import { MuiThemeProvider } from '@material-ui/core/styles'; -import { SnackbarContent } from "components/common"; -import { Notifications } from "components/views/notifications"; -import { setSnackbar } from "models/ui/actions"; -import { switchcase, shrinkDirectory } from "commons/utils"; -import { drawerWidth } from "styles/variables"; +import AppTopBar from 'containers/AppTopBar'; +import AppSidebar from 'containers/AppSidebar'; +import AppNavigationBar from 'containers/AppNavigationBar'; +import AppNotifications from 'containers/AppNotifications'; +import AppSnackbar from 'components/common/AppSnackbar'; +import { Notifications } from 'components/views/notifications'; +import { setSnackbar } from 'models/ui/actions'; +import { switchcase } from 'commons/utils'; +import appTheme from 'styles/theme'; -import Packages from "./Packages"; -import Audit from "./Audit"; -import styles from "./styles/appLayout"; +import Packages from './Packages'; +import Audit from './Audit'; +import Doctor from './Doctor'; + +import styles from './styles/appLayout'; const mapState = ({ common: { mode, directory, onlineStatus }, @@ -31,90 +34,53 @@ const mapState = ({ }); const AppLayout = ({ classes }) => { - const [drawerOpen, toggleDrawer] = useState(false); - const { - activePage, - snackbar, - mode, - directory, - onlineStatus - } = useMappedState(mapState); + const { activePage, snackbar } = useMappedState(mapState); const dispatch = useDispatch(); + const onClose = () => + dispatch( + setSnackbar({ + open: false, + message: null, + type: 'info' + }) + ); return ( - -
- -
- toggleDrawer(!drawerOpen)} /> -
+ +
+
+ +
+
+ + +
{switchcase({ packages: () => , - problems: () => ( - - ), - audit: () => + problems: () => , + audit: () => , + doctor: () => , + notifications: () => })()(activePage)}
-
- {snackbar && snackbar.open && ( - - dispatch( - setSnackbar({ - open: false, - message: null, - type: "info" - }) - ) - } - ClickAwayListenerProps={{ - onClickAway: () => - dispatch( - setSnackbar({ - open: false, - message: null, - type: "info" - }) - ) - }} - > - - dispatch( - setSnackbar({ - open: false, - message: null, - type: "info" - }) - ) - } - /> - - )} + + +
); }; AppLayout.propTypes = { - classes: PropTypes.objectOf(PropTypes.string).isRequired + classes: objectOf(string).isRequired }; -export default withStyles(styles)(AppLayout); +export default withStyles(styles, { + withTheme: true +})(AppLayout); diff --git a/app/containers/AppNavigationBar.js b/app/containers/AppNavigationBar.js new file mode 100755 index 00000000..a56d4033 --- /dev/null +++ b/app/containers/AppNavigationBar.js @@ -0,0 +1,63 @@ +import React from 'react'; +import cn from 'classnames'; +import { withStyles } from '@material-ui/core/styles'; +import { useMappedState, useDispatch } from 'redux-react-hook'; +import { objectOf, string } from 'prop-types'; +import { setActivePage } from 'models/ui/actions'; +import { NavigationBar } from 'components/views/navigationBar'; + +import styles from './styles/appNavigationBar'; + +const mapState = ({ + common: { mode, directory }, + ui: { + activePage, + loaders: { + loader: { loading } + } + }, + npm: { env } +}) => ({ + activePage, + mode, + directory, + env, + loading +}); + +const AppNavigationBar = ({ classes, className }) => { + const { env, mode, directory, activePage } = useMappedState(mapState); + + const dispatch = useDispatch(); + + const setActivePageHandler = page => + dispatch( + setActivePage({ + page, + paused: true + }) + ); + + return ( +
+ +
+ ); +}; + +AppNavigationBar.propTypes = { + classes: objectOf(string).isRequired, + className: string +}; + +export default withStyles(styles)(AppNavigationBar); diff --git a/app/containers/AppNotifications.js b/app/containers/AppNotifications.js new file mode 100755 index 00000000..8aa4b6ba --- /dev/null +++ b/app/containers/AppNotifications.js @@ -0,0 +1,150 @@ +import React from 'react'; +import { useState, useCallback, useEffect } from 'react'; +import { useMappedState, useDispatch } from 'redux-react-hook'; + +import Dialog from '@material-ui/core/Dialog'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogContent from '@material-ui/core/DialogContent'; +import Button from '@material-ui/core/Button'; + +import { Notifications } from 'components/views/notifications'; +import { installMultiplePackages } from 'models/packages/actions'; +import { clearInstallOptions } from 'models/common/actions'; +import { DialogOptionsView } from 'components/views/packages'; +import { iMessage } from 'commons/utils'; + +const mapState = ({ + notifications: { notifications }, + common: { + operations: { packagesInstallOptions } + } }) => ({ + notifications, + packagesInstallOptions + }); + +const AppNotifications = () => { + const [selected, setSelected] = useState([]); + const [selectedPackagesNames, setSelectedPackagesNames] = useState([]); + const [options, toggleOptions] = useState({ + open: false, + single: false, + name: null, + version: null + }); + const { notifications, packagesInstallOptions } = useMappedState(mapState); + const dispatch = useDispatch(); + + const handleSelectAll = useCallback( + e => { + let selectedNotifications; + + if (e.target.checked) { + selectedNotifications = notifications.map( + notification => notification.id + ); + } else { + selectedNotifications = []; + } + + setSelected(selectedNotifications); + }, + [notifications] + ); + + const handleSelectOne = useCallback( + (e, id) => { + const selectedIndex = selected.indexOf(id); + let newSelected = []; + + if (selectedIndex === -1) { + newSelected = newSelected.concat(selected, id); + } else if (selectedIndex === 0) { + newSelected = newSelected.concat(selected.slice(1)); + } else if (selectedIndex === selected.length - 1) { + newSelected = newSelected.concat(selected.slice(0, -1)); + } else if (selectedIndex > 0) { + newSelected = newSelected.concat( + selected.slice(0, selectedIndex), + selected.slice(selectedIndex + 1) + ); + } + + setSelected(newSelected); + }, + [selected] + ); + + const handleCancel = useCallback(() => { + dispatch(clearInstallOptions()); + toggleOptions({ + open: false, + single: false, + name: null, + version: null + }); + }, [dispatch]); + + const handleInstall = useCallback( + () => + dispatch( + installMultiplePackages({ + ipcEvent: 'npm-install', + cmd: selectedPackagesNames.map(() => 'install'), + multiple: true, + packages: selectedPackagesNames.map(pkgName => `${pkgName}@latest`) + }) + ), + [selectedPackagesNames, dispatch] + ); + + useEffect(() => { + const packagesNames = selected.length + ? selected.map(notificationId => { + const { requiredName } = notifications.find( + notification => notification.id === notificationId + ); + + return requiredName; + }) + : []; + + setSelectedPackagesNames(packagesNames); + }, [selected, notifications]); + + return ( + <> + + toggleOptions({ + ...options, + open: true + }) + } + handleSelectAll={handleSelectAll} + handleSelectOne={handleSelectOne} + /> + + + + + + + + + + + ); +}; + +export default AppNotifications; diff --git a/app/containers/AppSidebar.js b/app/containers/AppSidebar.js index a9cfaec1..0a5c0002 100755 --- a/app/containers/AppSidebar.js +++ b/app/containers/AppSidebar.js @@ -1,106 +1,96 @@ import React from 'react'; -import PropTypes from 'prop-types'; -import { useState, useEffect } from 'react'; +import cn from 'classnames'; +import { objectOf, string } from 'prop-types'; +import { useState, useEffect, useCallback } from 'react'; import { useDispatch, useMappedState } from 'redux-react-hook'; import { ipcRenderer } from 'electron'; import { withStyles } from '@material-ui/core/styles'; - -import Tooltip from '@material-ui/core/Tooltip'; import Drawer from '@material-ui/core/Drawer'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemText from '@material-ui/core/ListItemText'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import Button from '@material-ui/core/Button'; -import Divider from '@material-ui/core/Divider'; -import Card from '@material-ui/core/Card'; -import CardContent from '@material-ui/core/CardContent'; -import CardActions from '@material-ui/core/CardActions'; -import Typography from '@material-ui/core/Typography'; -import UpdateIcon from '@material-ui/icons/Update'; - -import { AppTabs, AppLogo } from 'components/common/'; -import { - PackagesTab, - ActionsTab, - HistoryTab -} from 'components/views/sidebar/tabs'; -import { navigatorParameters } from 'commons/parameters'; -import { iMessage, showDialog } from 'commons/utils'; -import { installPackage } from 'models/packages/actions'; +import { Sidebar } from 'components/views/sidebar'; import { setActivePage } from 'models/ui/actions'; +import { installPackageJson } from 'models/packages/actions' import { setMode } from 'models/common/actions'; +import { runDedupe } from 'models/npm/actions'; +import { iMessage, shrinkDirectory, showDialog } from 'commons/utils' -import Doctor from './Doctor'; import styles from './styles/appSidebar'; const mapState = ({ - notifications: { notifications }, + common: { mode, directory }, packages: { packagesData, packagesOutdated, metadata: { lastUpdatedAt } }, + notifications: { + notifications + }, ui: { - activePage, loaders: { loader: { loading } } } }) => ({ - activePage, + mode, + directory, loading, lastUpdatedAt, - notifications, packagesData, - packagesOutdated + packagesOutdated, + notifications }); -const AppSidebar = ({ - classes, - mode, - directory, - fullDirectory, - ...restProps -}) => { - const [openedDirectories, setOpenedDirectories] = useState([]); - const [open, toggleDialog] = useState(false); +const AppSidebar = ({ classes, className }) => { + const [history, updateHistory] = useState([]); + const dispatch = useDispatch(); const { - activePage, - notifications, + mode, + directory, + lastUpdatedAt, + loading, packagesData, packagesOutdated, - lastUpdatedAt, - loading + notifications } = useMappedState(mapState); - const dispatch = useDispatch(); - useEffect(() => { - ipcRenderer.on('loaded-packages-close', (event, directories) => - setOpenedDirectories(directories) - ); - - return () => ipcRenderer.removeAllListeners(['loaded-packages-close']); - }, []); + const packagesItems = [ + { + name: 'total-packages', + primaryText: 'Total', + secondaryText: packagesData.length, + color: 'secondary', + primary: true + }, + { + name: 'outdated-packages', + primaryText: 'Outdated', + secondaryText: packagesOutdated.length, + color: 'warning', + warning: true + }, + { + name: 'notifications', + primaryText: 'Problems', + secondaryText: notifications.length, + color: 'error', + error: true + } + ]; - const loadDirectory = () => { - const dialogHandler = filePath => { - dispatch( - setActivePage({ - page: 'packages', - paused: false - }) - ); - dispatch(setMode({ mode: 'local', directory: filePath.join('') })); - }; + const loadDirectory = useCallback(directoryPath => { + dispatch(setActivePage({ page: 'packages', paused: false })); + dispatch( + setMode({ + mode: 'local', + directory: directoryPath + }) + ); + }, [dispatch]); - return showDialog(dialogHandler, { mode: 'file', ...navigatorParameters }); - }; + const installPackagesFromJson = useCallback(() => { + const shrinkedDirectory = directory && shrinkDirectory(directory); - const installPackagesFromJson = () => { const dialogOptions = { title: 'Confirmation', type: 'question', @@ -112,153 +102,77 @@ const AppSidebar = ({ const dialogHandler = () => dispatch( - installPackage({ + installPackageJson({ ipcEvent: 'install', cmd: ['install'], packageJson: true, + multiple: false, mode, - directory: fullDirectory + directory: shrinkedDirectory }) ); return showDialog(dialogHandler, dialogOptions); - }; + }, [mode, directory, dispatch]); - const packagesItems = [ - { - name: 'total-packages', - primaryText: 'Total', - secondaryText: packagesData.length, - color: 'secondary', - primary: true - }, - { - name: 'outdated-packages', - primaryText: 'Outdated', - secondaryText: packagesOutdated.length, - color: 'warning', - warning: true - }, - { - name: 'problems-packages', - primaryText: 'Problems', - secondaryText: notifications ? notifications.length : 0, - color: 'error', - error: true - } - ]; + const dedupe = useCallback(() => { + const dialogOptions = { + title: 'Confirmation', + type: 'question', + message: iMessage('confirmation', 'actionRun', { + '%name%': 'npm dedupe' + }), + buttons: ['Cancel', 'Run'] + }; + + const dialogHandler = () => + dispatch( + runDedupe({ + ipcEvent: 'dedupe', + cmd: ['dedupe'] + }) + ); + + return showDialog(dialogHandler, dialogOptions); + }, [dispatch]); + + useEffect(() => { + ipcRenderer.on('loaded-packages-close', (event, directories) => + updateHistory(directories) + ); + + return () => ipcRenderer.removeAllListeners(['loaded-packages-close']); + }, []); return ( - <> - - - - - - - - - - -
- -
-
-
-
- - - - - - - {iMessage('title', 'overview')} - - - - - - -
- - - {iMessage('info', 'updatedAt')}  - {lastUpdatedAt !== null ? lastUpdatedAt : '...'} - -
-
-
- - { - dispatch( - setActivePage({ page: 'packages', paused: false }) - ); - dispatch( - setMode({ - mode: 'local', - directory: projectDirectory - }) - ); - }} - loading={loading} - /> -
-
-
-
-
- + - - - - - - - - + + +
); }; AppSidebar.propTypes = { - classes: PropTypes.objectOf(PropTypes.string).isRequired, - mode: PropTypes.string, - loading: PropTypes.bool, - name: PropTypes.string, - version: PropTypes.string, - description: PropTypes.string, - directory: PropTypes.string, - lastUpdatedAt: PropTypes.string, - fullDirectory: PropTypes.string + classes: objectOf(string).isRequired, + className: string }; export default withStyles(styles)(AppSidebar); diff --git a/app/containers/AppTopBar.js b/app/containers/AppTopBar.js new file mode 100755 index 00000000..cd116696 --- /dev/null +++ b/app/containers/AppTopBar.js @@ -0,0 +1,179 @@ +import React from 'react'; +import { useState, useCallback } from 'react'; +import { withStyles } from '@material-ui/core/styles'; +import { objectOf, string } from 'prop-types'; +import { useMappedState, useDispatch } from 'redux-react-hook'; +import cn from 'classnames'; + +import DialogTitle from '@material-ui/core/DialogTitle'; +import Dialog from '@material-ui/core/Dialog'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogActions from '@material-ui/core/DialogActions'; +import Button from '@material-ui/core/Button'; +import Divider from '@material-ui/core/Divider'; + +import { Init, Settings } from 'components/views/common/'; +import { TopBar } from 'components/views/topBar/'; + +import { showDialog } from 'commons/utils'; +import { setActivePage } from 'models/ui/actions'; +import { setMode } from 'models/common/actions'; +import { runInit } from 'models/npm/actions'; +import { navigatorParameters } from 'commons/parameters'; +import { iMessage } from 'commons/utils'; + +import styles from './styles/appTopBar'; + +const mapState = ({ + common: { mode, directory, activePage }, + notifications: { notifications }, + ui: { + loaders: { + loader: { loading } + } + }, + npm: { env: { + metricsRegistry, + auditLevel, + cache + } } +}) => ({ + activePage, + notifications, + mode, + directory, + metricsRegistry, + auditLevel, + cache, + loading +}); + +const AppTopBar = ({ classes, className }) => { + const { + metricsRegistry, + auditLevel, + cache, + mode, + directory, + notifications, + loading, + activePage + } = useMappedState(mapState); + + const [initFlow, toggleInitFlow] = useState({ + show: false, + directory: null + }) + const [dialog, setDialog] = useState({ + open: false, + title: '', + active: null + }); + + const dispatch = useDispatch(); + + const onLoadDirectory = useCallback(() => { + const dialogHandler = filePath => { + dispatch( + setActivePage({ + page: 'packages', + paused: false + }) + ); + dispatch(setMode({ mode: 'local', directory: filePath.join('') })); + }; + + return showDialog(dialogHandler, { mode: 'file', ...navigatorParameters }); + }, [dispatch]); + + const closeDialog = useCallback(() => { + setDialog({ ...dialog, open: false, active: null, title: '' }) + toggleInitFlow({ + ...initFlow, + show: false + }) + }, [dialog, initFlow]) + + const onNpmInit = useCallback(() => { + dispatch( + runInit({ + ipcEvent: 'npm-init', + cmd: ['init'], + directory: initFlow.directory || null + }) + ); + + closeDialog(); + }, [dispatch, closeDialog, initFlow]) + + const setActivePageHandler = page => + dispatch( + setActivePage({ + page, + paused: true + }) + ); + + return ( +
+ setDialog({ ...dialog, open: true, active: 'Init', title: iMessage('title', 'createPackageJson') })} + onShowSettings={() => setDialog({ ...dialog, open: true, active: 'Settings', title: iMessage('title', 'settings') })} + /> + + {dialog.title} + + + {dialog.active === 'Init' && toggleInitFlow({ + ...initFlow, + directory: directoryPath + })} />} + {dialog.active === 'Settings' && } + + + + {dialog.active === 'Init' && } + + +
+ ); +}; + +AppTopBar.propTypes = { + classes: objectOf(string).isRequired, + className: string +}; + +export default withStyles(styles)(AppTopBar); diff --git a/app/containers/Audit.js b/app/containers/Audit.js index 3d4422c8..de8a8dfc 100755 --- a/app/containers/Audit.js +++ b/app/containers/Audit.js @@ -42,13 +42,7 @@ const mapState = ({ }); const Audit = ({ classes }) => { - const dispatch = useDispatch(); const { loading, message, mode, result } = useMappedState(mapState); - const [status, setStatus] = useState({ - type: 'init', - options: {} - }); - const [metadataValues, setMetadata] = useState({ dependencies: 0, devDependencies: 0, @@ -56,8 +50,8 @@ const Audit = ({ classes }) => { vulnerabilities: null, advisories: null }); + const dispatch = useDispatch(); const { content, error } = result || {}; - const defaultOptions = { text: iMessage('info', 'npmAuditInfo') }; const auditRun = option => dispatch( @@ -70,27 +64,46 @@ const Audit = ({ classes }) => { }) ); + const dialogText = mode === 'global' ? iMessage('warning', 'noGlobalAudit') : iMessage('info', 'npmAuditInfo'); + const dialogActionText = iMessage('action', 'runAudit'); + const initOptions = { - ...defaultOptions, - detail: mode === 'global' ? iMessage('warning', 'noGlobalAudit') : null, - actionText: iMessage('action', 'runAudit'), + text: dialogText, + actionText: dialogActionText, actionHandler: () => auditRun(), - actionDisabled: mode === 'global' + actionDisabled: mode === 'global', + color: 'primary' }; + const [status, setStatus] = useState({ + type: 'init', + options: initOptions + }); + // set data useEffect(() => { const { metadata, advisories } = content || {}; - if (!content && !loading) { + if (error) { + const { summary, code } = error || {}; + + const errorOptions = { + text: summary, + code + }; + setStatus({ - type: 'init', - options: initOptions + type: 'error', + options: errorOptions }); return; } + if (!content && !loading) { + return; + } + if (!metadata && !advisories) { setStatus({ type: 'dialog' @@ -114,28 +127,11 @@ const Audit = ({ classes }) => { advisories }); - setStatus({ - type: 'audit' - }); - }, [content, initOptions, loading]); - - // set error - useEffect(() => { - if (error) { - const { summary, code } = error || {}; - - const errorOptions = { - ...initOptions, - text: summary, - code - }; - - setStatus({ - type: 'error', - options: errorOptions - }); - } - }, [error, initOptions]); + setStatus(options => ({ + type: 'audit', + options + })); + }, [content, loading, error]); const { type, options } = status; const { @@ -146,6 +142,8 @@ const Audit = ({ classes }) => { advisories } = metadataValues || {}; + const noVulnerabilities = vulnerabilities && Object.values(vulnerabilities).reduce((total, v) => total + v, 0); + return ( <> @@ -154,7 +152,7 @@ const Audit = ({ classes }) => { {type === 'init' && } {type === 'audit' && ( <> - + { - 0 ? + /> : } )}
setStatus({ type: 'init', @@ -227,4 +225,4 @@ Audit.propTypes = { classes: PropTypes.objectOf(PropTypes.string).isRequired }; -export default withStyles(styles, { withTheme: false })(Audit); +export default withStyles(styles)(Audit); diff --git a/app/containers/Doctor.js b/app/containers/Doctor.js index 22ccd621..930d63e2 100755 --- a/app/containers/Doctor.js +++ b/app/containers/Doctor.js @@ -6,8 +6,6 @@ import { withStyles } from '@material-ui/core/styles'; import { useDispatch, useMappedState } from 'redux-react-hook'; import Grid from '@material-ui/core/Grid'; -import Typography from '@material-ui/core/Typography'; -import Divider from '@material-ui/core/Divider'; import Avatar from '@material-ui/core/Avatar'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; @@ -59,11 +57,11 @@ const renderData = data => ( const Doctor = ({ classes }) => { const { loading, message, result, error } = useMappedState(mapState); const [status, setStatus] = useState({ - type: 'init', + type: result ? 'doctor' : 'init', options: null }); const dispatch = useDispatch(); - const { type, options } = status; + const { type } = status; const handleDoctor = () => dispatch( @@ -76,15 +74,17 @@ const Doctor = ({ classes }) => { const initOptions = { text: iMessage('info', 'npmDoctorInfo'), actionText: iMessage('action', 'runDoctor'), - actionHandler: handleDoctor + actionHandler: handleDoctor, + color: 'primary' }; useEffect(() => { - setStatus({ + setStatus(options => ({ + ...options, type: result ? 'doctor' : 'init', - options: result ? null : initOptions - }); - }, [result, loading, initOptions]); + options: result ? null : options + })); + }, [result, loading]); // set error useEffect(() => { @@ -92,7 +92,6 @@ const Doctor = ({ classes }) => { const { summary, code } = error || {}; const errorOptions = { - ...initOptions, text: summary, code }; @@ -102,23 +101,15 @@ const Doctor = ({ classes }) => { options: errorOptions }); } - }, [error, initOptions]); + }, [error]); return ( - +
- {type === 'init' && } + {type === 'init' && } {type === 'doctor' && ( -
-
- - {iMessage('title', 'doctorReport')} - -
-
-
{renderData(result)}
diff --git a/app/containers/PackageDetails.js b/app/containers/PackageDetails.js index 43599257..6200607c 100755 --- a/app/containers/PackageDetails.js +++ b/app/containers/PackageDetails.js @@ -1,3 +1,5 @@ +/* eslint-disable react/jsx-props-no-spreading */ + import React from 'react'; import semver from 'semver'; import cn from 'classnames'; @@ -22,9 +24,7 @@ import Tooltip from '@material-ui/core/Tooltip'; import Collapse from '@material-ui/core/Collapse'; import Grid from '@material-ui/core/Grid'; import Fade from '@material-ui/core/Fade'; - import CloseIcon from '@material-ui/icons/Close'; - import VersionsIcon from '@material-ui/icons/LabelOutlined'; import DependenciesIcon from '@material-ui/icons/ListOutlined'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; @@ -189,7 +189,7 @@ const PackageDetails = ({ classes, toggleOptions }) => { : false; return ( - + <> {isOutdated && ( )} @@ -197,7 +197,7 @@ const PackageDetails = ({ classes, toggleOptions }) => { packageName={active.name} handler={handleUninstall} /> - + ); }; @@ -244,19 +244,19 @@ const PackageDetails = ({ classes, toggleOptions }) => { variant="h4" >{`${name} v${version}`} } - className={classes.cardHeader} + classes={{ root: classes.cardHeader, subheader: classes.subheader }} subheader={ - - {`License: ${active.license || + <> + {`License: ${active.license || '-'}`} {mode === 'local' && !fromSearch && ( - {`Group: ${group || + {`Group: ${group || '-'}`} )} - + } /> - + {description} @@ -338,11 +338,7 @@ const PackageDetails = ({ classes, toggleOptions }) => { ); useEffect(() => { - if (!active) { - return; - } - - if (active.dependencies) { + if (active && active.dependencies) { const dependenciesNames = Object.keys(active.dependencies); const dependenciesToArray = dependenciesNames.map(dep => ({ name: dep, diff --git a/app/containers/Packages.js b/app/containers/Packages.js index d2ea16b0..67b7e703 100755 --- a/app/containers/Packages.js +++ b/app/containers/Packages.js @@ -1,6 +1,5 @@ import React from 'react'; -import { Fragment } from 'react'; -import { useEffect, useState, useRef } from 'react'; +import { useEffect, useState, useRef, useCallback } from 'react'; import { objectOf, string } from 'prop-types'; import { useMappedState, useDispatch } from 'redux-react-hook'; import { withStyles } from '@material-ui/core/styles'; @@ -114,8 +113,6 @@ const Packages = ({ classes }) => { auditData } = useMappedState(mapState); - /* eslint-disable-next-line */ - const [packagesFromPackageJson, setPackageJsonPackages] = useState([]); const [auditPackages, setAuditPackages] = useState([]); const [options, toggleOptions] = useState({ open: false, @@ -127,7 +124,7 @@ const Packages = ({ classes }) => { const wrapperRef = useRef(null); const dispatch = useDispatch(); - const reload = () => { + const reload = useCallback(() => { dispatch(setActivePage({ page: 'packages', paused: false })); dispatch( setPackagesStart({ @@ -137,9 +134,9 @@ const Packages = ({ classes }) => { } }) ); - }; + }, [dispatch]); - const switchMode = (appMode, appDirectory) => { + const switchMode = useCallback((appMode, appDirectory) => { dispatch(setMode({ mode: appMode, directory: appDirectory })); dispatch(setActivePage({ page: 'packages', paused: false })); @@ -153,9 +150,9 @@ const Packages = ({ classes }) => { }) ); } - }; + }, [dispatch, fromSearch]); - const viewPackageHandler = (name, version) => + const viewPackageHandler = useCallback((name, version) => dispatch( viewPackageStart({ channel: 'npm-view', @@ -165,7 +162,7 @@ const Packages = ({ classes }) => { version: name === 'npm' ? null : version } }) - ); + ), [dispatch]); useEffect(() => { dispatch( @@ -214,12 +211,11 @@ const Packages = ({ classes }) => { const noPackages = !packagesData.length; return ( - + <> { {noPackages && ( switchMode('global')} /> )} {!noPackages && ( - +
{
{ packagesInstallOptions ) ? packagesInstallOptions.find( - installOption => installOption.name === name - ) + installOption => installOption.name === name + ) : {}; const inOperation = @@ -304,16 +299,6 @@ const Packages = ({ classes }) => { operationCommand !== 'install' && operationPackages.indexOf(name) > -1; - const inPackageJson = packagesFromPackageJson.some( - pkg => { - /* eslint-disable-next-line */ - const [pkgGroup, pkgDetails] = pkg; - const [pkgName] = Object.keys(pkgDetails); - - return pkgName === name; - } - ); - return ( { viewPackage={viewPackageHandler} inOperation={inOperation} inAudit={auditPackages.includes(name)} - inPackageJson={inPackageJson} peerMissing={peerMissing} fromSearch={__fromSearch} hasError={__hasError} @@ -451,7 +435,7 @@ const Packages = ({ classes }) => { - + ); }; diff --git a/app/containers/styles/appHeader.js b/app/containers/styles/appHeader.js index 010716d3..a0158e5c 100755 --- a/app/containers/styles/appHeader.js +++ b/app/containers/styles/appHeader.js @@ -7,15 +7,13 @@ const styles = theme => ({ root: { width: '100%' }, - secondaryBar: { - zIndex: 0 + appBar: { + zIndex: 0, + padding: theme.spacing(2) }, menuButton: { marginLeft: -theme.spacing(1) }, - iconButtonAvatar: { - padding: 4 - }, link: { textDecoration: 'none', color: theme.palette.common.white, @@ -27,6 +25,9 @@ const styles = theme => ({ button: { borderColor: lightColor }, + leftIcon: { + marginRight: theme.spacing(1) + }, dialogTitle: { padding: theme.spacing(2) }, @@ -39,10 +40,13 @@ const styles = theme => ({ marginRight: theme.spacing(1) }, workingDir: { - color: '#fff' + color: theme.palette.common.white }, directory: { - color: '#fff' + color: theme.palette.common.white + }, + marRight: { + marginRight: theme.spacing(4) } }); diff --git a/app/containers/styles/appLayout.js b/app/containers/styles/appLayout.js index 808933ff..53ae5fbc 100755 --- a/app/containers/styles/appLayout.js +++ b/app/containers/styles/appLayout.js @@ -1,46 +1,41 @@ -import { lighten } from '@material-ui/core/styles/colorManipulator'; -import { defaultFont, drawerWidth } from 'styles/variables'; +import { drawerWidth } from 'styles/variables'; const styles = theme => ({ root: { + width: '100%', + height: '100%', display: 'flex', - minHeight: '100vh' - }, - drawer: { - [theme.breakpoints.up('sm')]: { - width: drawerWidth, - flexShrink: 0 - } + flexDirection: 'column', + overflow: 'auto' }, - paperDialog: { - minHeight: 475 + shiftContent: { + paddingLeft: 225 }, - appContent: { - flex: 1, + main: { + minHeight: '100vh', display: 'flex', flexDirection: 'column', - overflow: 'hidden' - }, - mainContent: { flex: 1, - padding: theme.spacing(1), - background: lighten('#fff', 0.1), + paddingLeft: theme.spacing(6), + paddingTop: theme.spacing(1) + }, + topBar: { + width: '100%' }, - label: { - ...defaultFont, - fontSize: 20 + navigationBar: { + width: '100%' }, - subheader: { - ...defaultFont, - fontSize: 16 + sidebar: { + flex: 0 }, - value: { - ...defaultFont, - fontSize: 22, - color: theme.palette.secondary.light + content: { + padding: theme.spacing(1) }, - list: { - paddingTop: theme.spacing(2) + drawer: { + [theme.breakpoints.up('sm')]: { + width: drawerWidth, + flexShrink: 0 + } } }); diff --git a/app/containers/styles/appNavigationBar.js b/app/containers/styles/appNavigationBar.js new file mode 100755 index 00000000..f62d9b74 --- /dev/null +++ b/app/containers/styles/appNavigationBar.js @@ -0,0 +1,8 @@ +const styles = theme => ({ + root: { + width: '100%', + paddingTop: theme.spacing(1) + 2 + } +}); + +export default styles; diff --git a/app/containers/styles/appSidebar.js b/app/containers/styles/appSidebar.js index 7ee129b3..efa84690 100755 --- a/app/containers/styles/appSidebar.js +++ b/app/containers/styles/appSidebar.js @@ -1,139 +1,11 @@ -import { grayColor, flexContainer, defaultFont } from 'styles/variables'; -import { darken, lighten } from '@material-ui/core/styles/colorManipulator'; +import { drawerWidth } from 'styles/variables'; -const styles = theme => ({ - flexContainer: { - ...flexContainer, - alignItems: 'center' +const styles = () => ({ + root: { + width: '100%' }, - flexItem: { - padding: theme.spacing(1) - }, - categoryHeader: { - paddingTop: theme.spacing(2), - paddingBottom: theme.spacing(1), - borderBottom: '1px solid #eee' - }, - categoryHeaderPrimary: { - color: grayColor - }, - itemCategory: { - borderBottom: '1px solid #eee', - padding: theme.spacing(0.5) - }, - homeIcon: { - width: 35, - height: 35, - marginLeft: theme.spacing(2), - fill: '#fff' - }, - updateIcon: { - color: lighten(theme.palette.primary.main, 0.2), - marginRight: theme.spacing(0.5) - }, - title: { - ...defaultFont, - color: grayColor, - fontSize: 32, - paddingLeft: theme.spacing(3) - }, - itemActionable: { - '&:hover': { - color: theme.palette.common.white, - backgroundColor: theme.palette.secondary.light - } - }, - itemActiveItem: { - color: theme.palette.primary.light - }, - itemPrimary: { - fontSize: theme.typography.fontSize, - '&$textDense': { - fontSize: theme.typography.fontSize - } - }, - textDense: { - paddingTop: theme.spacing(0.5) - }, - divider: { - marginTop: theme.spacing(2) - }, - margin: { - margin: theme.spacing(1) - }, - extendedIcon: { - marginRight: theme.spacing(1) - }, - button: { - margin: theme.spacing(1) - }, - leftIcon: { - marginRight: theme.spacing(1) - }, - rightIcon: { - marginLeft: theme.spacing(1) - }, - iconSmall: { - fontSize: 20 - }, - historyDirectory: { - wordWrap: 'break-word' - }, - label: { - ...defaultFont, - top: 0, - fontSize: 22, - fontWeight: 400, - display: 'inline-block', - position: 'relative' - }, - listWrapper: { - whiteSpace: 'nowrap', - padding: theme.spacing(1), - overflow: 'hidden', - [theme.breakpoints.up('md')]: { - maxHeight: 500, - overflowY: 'scroll' - }, - [theme.breakpoints.up('lg')]: { - overflowY: 'scroll', - maxHeight: 650 - } - }, - listItem: { - ...defaultFont - }, - listItemHalfPadding: { - ...defaultFont, - padding: theme.spacing(0.5) - }, - card: { - width: 268, - minHeight: 150 - }, - cardTitle: { - ...defaultFont, - fontSize: 20, - paddingBottom: theme.spacing(1) - }, - cardFlexContainer: { - ...flexContainer, - width: '100%', - justifyContent: 'space-between', - padding: theme.spacing(1), - alignItems: 'center' - }, - cardFlexContainerInner: { - ...flexContainer, - alignItems: 'center' - }, - cardLabel: { - ...defaultFont, - fontSize: 12, - color: darken(grayColor, 0.5) - }, - dialog: { - minHeight: 200 + drawer: { + width: drawerWidth } }); diff --git a/app/containers/styles/appTopBar.js b/app/containers/styles/appTopBar.js new file mode 100755 index 00000000..d608ba3f --- /dev/null +++ b/app/containers/styles/appTopBar.js @@ -0,0 +1,16 @@ +import { grayColor } from 'styles/variables'; + +const styles = () => ({ + root: { + width: '100%' + }, + dialogTitle: { + fontSize: 22, + color: grayColor + }, + closeButton: { + textTransform: 'lowercase' + } +}); + +export default styles; diff --git a/app/containers/styles/doctor.js b/app/containers/styles/doctor.js index 9264a682..a650a578 100755 --- a/app/containers/styles/doctor.js +++ b/app/containers/styles/doctor.js @@ -5,11 +5,11 @@ const styles = theme => ({ wrapper: { padding: theme.spacing(1), overflowY: 'scroll', - [theme.breakpoints.down('sm')]: { - maxHeight: 375 + [theme.breakpoints.down('md')]: { + maxHeight: 500 }, [theme.breakpoints.up('md')]: { - maxHeight: 450 + maxHeight: 600 } }, paper: { diff --git a/app/containers/styles/packageDetails.js b/app/containers/styles/packageDetails.js index 70617e23..373e18ba 100755 --- a/app/containers/styles/packageDetails.js +++ b/app/containers/styles/packageDetails.js @@ -9,6 +9,9 @@ const styles = theme => ({ cardHeader: { padding: theme.spacing(1) }, + subheader: { + paddingTop: theme.spacing(1) + }, cardContent: { maxHeight: 375, overflowY: 'scroll', diff --git a/app/containers/styles/packages.js b/app/containers/styles/packages.js index 023947b1..69bf75a5 100755 --- a/app/containers/styles/packages.js +++ b/app/containers/styles/packages.js @@ -6,6 +6,7 @@ const styles = theme => ({ width: '100%', borderTopLeftRadius: 0, borderTopRightRadius: 0, + padding: theme.spacing(1), [theme.breakpoints.up('md')]: { maxWidth: '100%' }, @@ -43,11 +44,11 @@ const styles = theme => ({ whiteSpace: 'nowrap', overflowY: 'scroll', padding: theme.spacing(1), - [theme.breakpoints.up('md')]: { - maxHeight: 450 + [theme.breakpoints.down('md')]: { + maxHeight: 535 }, [theme.breakpoints.up('lg')]: { - maxHeight: 650 + maxHeight: 700 } }, table: { diff --git a/app/main.dev.js b/app/main.dev.js index 0d337048..6075c915 100755 --- a/app/main.dev.js +++ b/app/main.dev.js @@ -23,6 +23,7 @@ import { onNpmUninstall, onNpmAudit, onNpmDoctor, + onNpmDedupe, onNpmInit, onNpmInitLock } from './mainProcess'; @@ -163,6 +164,14 @@ ipcMain.on('npm-audit', (event, options) => onNpmAudit(event, options, Store)); */ ipcMain.on('npm-init', (event, options) => onNpmInit(event, options, Store)); +/** + * Channel: npm-dedupe + * Supports: npm dedupe + * https://docs.npmjs.com/cli/dedupe + * + */ +ipcMain.on('npm-dedupe', (event, options) => onNpmDedupe(event, options, Store)); + /** * Channel: npm-init-lock * Supports: npm i --package-lock-only diff --git a/app/mainProcess/index.js b/app/mainProcess/index.js index ac583b4c..867028db 100755 --- a/app/mainProcess/index.js +++ b/app/mainProcess/index.js @@ -8,6 +8,7 @@ import onNpmAudit from './npmAudit'; import onNpmDoctor from './npmDoctor'; import onNpmInit from './npmInit'; import onNpmInitLock from './npmInitLock'; +import onNpmDedupe from './npmDedupe'; export { onNpmView, @@ -16,6 +17,7 @@ export { onNpmInstall, onNpmUninstall, onNpmUpdate, + onNpmDedupe, onNpmAudit, onNpmDoctor, onNpmInit, diff --git a/app/mainProcess/npmDedupe.js b/app/mainProcess/npmDedupe.js new file mode 100644 index 00000000..ba2bb682 --- /dev/null +++ b/app/mainProcess/npmDedupe.js @@ -0,0 +1,43 @@ +import log from 'electron-log'; +import { merge } from 'ramda'; +import { switchcase } from '../commons/utils'; +import { runCommand } from '../cli'; +import mk from '../mk'; + +const { + defaultSettings: { defaultManager } +} = mk || {}; + +const onNpmDedupe = (event, options, store) => { + const settings = store.get('user_settings'); + const { activeManager = defaultManager, ...rest } = options || {}; + + const onFlow = chunk => event.sender.send('npm-dedupe-flow', chunk); + const onError = error => event.sender.send('npm-dedupe-error', error); + const onComplete = (errors, data) => + event.sender.send('npm-dedupe-completed', data, errors); + + const callback = result => { + const { status, errors, data } = result; + + return switchcase({ + flow: dataChunk => onFlow(dataChunk), + close: () => onComplete(errors, data), + error: error => onError(error) + })(null)(status); + }; + + try { + const params = merge(settings, { + activeManager, + ...rest + }); + + runCommand(params, callback); + } catch (error) { + log.error(error); + event.sender.send('npm-dedupe-error', error && error.message); + } +}; + +export default onNpmDedupe; diff --git a/app/mainProcess/npmInstall.js b/app/mainProcess/npmInstall.js index 97c78d51..bcf65103 100755 --- a/app/mainProcess/npmInstall.js +++ b/app/mainProcess/npmInstall.js @@ -12,27 +12,26 @@ const onNpmInstall = (event, options, store) => { const settings = store.get('user_settings'); const { activeManager = defaultManager, ...rest } = options || {}; const commands = options.cmd; - let runningTimes = 1; const onFlow = chunk => event.sender.send('npm-install-flow', chunk); const onError = error => event.sender.send('npm-install-error', error); - const onComplete = (errors, data, cmd) => { + const onComplete = (errors, data, cmd, packageJson) => { if (commands.length === runningTimes) { runningTimes = 1; - return event.sender.send('npm-install-completed', data, errors, cmd); + return event.sender.send('npm-install-completed', data, errors, cmd, packageJson); } runningTimes += 1; }; const callback = result => { - const { status, errors, data, cmd } = result; + const { status, errors, data, packageJson, cmd } = result; return switchcase({ flow: dataChunk => onFlow(dataChunk), - close: () => onComplete(errors, data, cmd), + close: () => onComplete(errors, data, cmd, packageJson), error: error => onError(error) })(null)(status); }; diff --git a/app/models/common/epics.js b/app/models/common/epics.js index a9ae12b9..262b842f 100755 --- a/app/models/common/epics.js +++ b/app/models/common/epics.js @@ -21,6 +21,8 @@ import { npmAuditListener, npmDoctorListener, npmInitListener, + npmDedupeListener, + runDedupe, runDoctor, runAudit, runInit @@ -65,7 +67,8 @@ const updateCommandEpic = pipe( uninstallPackages.type, runAudit.type, runDoctor.type, - runInit.type + runInit.type, + runDedupe.type ), mergeMap(({ payload }) => { const { packages, cmd } = payload || {}; @@ -98,7 +101,8 @@ const onInitActionsEpic = pipe( uninstallPackagesListener(), npmAuditListener(), npmDoctorListener(), - npmInitListener() + npmInitListener(), + npmDedupeListener() ]) ); diff --git a/app/models/notifications/actions.js b/app/models/notifications/actions.js index 16c71275..77b91d68 100755 --- a/app/models/notifications/actions.js +++ b/app/models/notifications/actions.js @@ -3,7 +3,8 @@ import { createActionCreator } from 'commons/utils'; const ActionCreator = createActionCreator('@@LUNA/NOTIFICATIONS'); const addNotification = ActionCreator('ADD_NOTIFICATION'); +const setActive = ActionCreator('SET_ACTIVE'); const clearNotifications = ActionCreator('CLEAR_NOTIFICATIONS'); const updateNotifications = ActionCreator('UPDATE_NOTIFICATIONS'); -export { updateNotifications, addNotification, clearNotifications }; +export { updateNotifications, addNotification, clearNotifications, setActive }; diff --git a/app/models/notifications/epics.js b/app/models/notifications/epics.js index b68f089d..07dd5bbb 100755 --- a/app/models/notifications/epics.js +++ b/app/models/notifications/epics.js @@ -1,57 +1,56 @@ -import { pipe, from } from 'rxjs'; -import { map, mergeMap } from 'rxjs/operators'; +import { pipe, from, of } from 'rxjs'; +import { + concatMap, + mergeMap, + catchError, +} from 'rxjs/operators'; +import uuid from 'uuid/v1'; import { combineEpics, ofType } from 'redux-observable'; -import { ERROR_TYPES } from 'constants/AppConstants'; -import { parseMessage, switchcase, matchType } from 'commons/utils'; - import { addNotification, updateNotifications } from 'models/notifications/actions'; -/** - * - * @param {*} prefix - * npm ERR!, npm WARN, etc ... - */ -const matchMessageType = prefix => types => - types.find(type => matchType(prefix, type)); - -/** - * - * @param {*} message - */ -const parseNpmMessage = message => { - const prefix = message.slice(0, 8).trim(); - const messageType = matchMessageType(prefix)(ERROR_TYPES); - const [body, required, requiredBy] = parseMessage(message); - - return { - messageType, - payload: { - body, - required, - requiredBy - } - }; -}; - const notificationsEpic = pipe( ofType(updateNotifications.type), mergeMap(({ payload: { notifications } }) => from(notifications)), - map(notification => { - const { messageType = 'ERR', payload } = parseNpmMessage(notification); + concatMap(notification => { + const id = uuid(); + const [reason, details] = notification.split(':'); + const isExtraneous = reason === 'extraneous'; + + let detailsWithTrim = details.trim(); + const isNameSpace = detailsWithTrim.startsWith('@') + + // check for namespace + if (isNameSpace) { + detailsWithTrim = detailsWithTrim.slice(1, detailsWithTrim.length - 1) + } + + const [requiredDetails, requiredByName] = isExtraneous ? detailsWithTrim.split('@') : detailsWithTrim.split(','); + const [requiredName, requiredVersion] = requiredDetails.split('@'); - return switchcase({ - ERR: () => ({ + return [ + { type: addNotification.type, payload: { - ...payload, - type: 'ERROR' + id, + reason, + requiredName: isNameSpace ? `@${requiredName}` : requiredName, + requiredByName: isExtraneous ? '' : requiredByName.replace('required by', ''), + requiredVersion: isExtraneous ? '' : requiredVersion, } - }) - })({ type: addNotification.type, payload: { type: 'ERROR' } })(messageType); + } + ]; + }), + catchError(error => { + console.error(error); + + return of({ + type: '@@LUNA/ERROR/FATAL_NOTIFICATIONS', + error: error.toString() + }) }) ); diff --git a/app/models/npm/actions.js b/app/models/npm/actions.js index 7a44fd1d..bf145d7d 100755 --- a/app/models/npm/actions.js +++ b/app/models/npm/actions.js @@ -26,6 +26,7 @@ const clearDoctorData = ActionCreator('CLEAR_DOCTOR_DATA'); const npmAuditListener = ActionCreator('REGISTER_LISTENER_AUDIT'); const npmDoctorListener = ActionCreator('REGISTER_LISTENER_DOCTOR'); const npmInitListener = ActionCreator('REGISTER_LISTENER_INIT'); +const npmDedupeListener = ActionCreator('REGISTER_LISTENER_DEDUPE'); // operations const runInstall = ActionCreator('RUN_INSTALL'); @@ -37,6 +38,7 @@ const runAudit = ActionCreator('RUN_AUDIT'); const runInit = ActionCreator('RUN_INIT'); const runLock = ActionCreator('RUN_INIT_LOCK'); const runDoctor = ActionCreator('RUN_DOCTOR'); +const runDedupe = ActionCreator('RUN_DEDUPE'); export { addAuditFixOption, @@ -52,12 +54,14 @@ export { runUpdate, runUninstall, runAudit, + runDedupe, runInit, runLock, runDoctor, npmDoctorListener, npmAuditListener, npmInitListener, + npmDedupeListener, clearAuditData, clearDoctorData, parseNpmAuditData, diff --git a/app/models/npm/epics/auditEpics.js b/app/models/npm/epics/auditEpics.js index 96ee8e5e..ee6fb8c5 100755 --- a/app/models/npm/epics/auditEpics.js +++ b/app/models/npm/epics/auditEpics.js @@ -37,6 +37,7 @@ const npmRunAuditEpic = (action$, state$) => const { common: { mode, directory } } = state$.value; + ipcRenderer.send('npm-audit', { ...payload, mode, diff --git a/app/models/npm/epics/dedupeEpics.js b/app/models/npm/epics/dedupeEpics.js new file mode 100644 index 00000000..a0fea37d --- /dev/null +++ b/app/models/npm/epics/dedupeEpics.js @@ -0,0 +1,45 @@ +import { pipe } from 'rxjs'; +import { tap, switchMap, mergeMap } from 'rxjs/operators'; +import { ofType } from 'redux-observable'; +import { ipcRenderer } from 'electron'; +import { toggleLoader } from 'models/ui/actions'; +import { runDedupe, npmDedupeListener } from 'models/npm/actions'; +import { iMessage } from 'commons/utils' +import { onNpmDedupe$ } from '../listeners'; + +const updateLoader = payload => ({ + type: toggleLoader.type, + payload +}); + +/** + * Send ipc event to main process to handle npm-dedupe + */ +const npmRunDedupeEpic = (action$, state$) => + action$.pipe( + ofType(runDedupe.type), + tap(({ payload }) => { + const { + common: { mode, directory } + } = state$.value; + + ipcRenderer.send('npm-dedupe', { + ...payload, + mode, + directory + }); + }), + mergeMap(() => [ + updateLoader({ + loading: true, + message: iMessage('info', 'deduping') + })]), + ); + +// listener epics +const npmRunDedupeListenerEpic = pipe( + ofType(npmDedupeListener.type), + switchMap(() => onNpmDedupe$) +); + +export { npmRunDedupeEpic, npmRunDedupeListenerEpic }; \ No newline at end of file diff --git a/app/models/npm/epics/index.js b/app/models/npm/epics/index.js index 89d78130..0a7a76a4 100755 --- a/app/models/npm/epics/index.js +++ b/app/models/npm/epics/index.js @@ -21,6 +21,11 @@ import { showDoctorLoaderEpic } from './doctorEpics'; +import { + npmRunDedupeEpic, + npmRunDedupeListenerEpic, +} from './dedupeEpics'; + export default combineEpics( npmRunLockEpic, npmRunInitEpic, @@ -33,5 +38,7 @@ export default combineEpics( npmAuditParseFixEpic, npmRunDoctorEpic, npmRunDoctorListenerEpic, - showDoctorLoaderEpic + showDoctorLoaderEpic, + npmRunDedupeEpic, + npmRunDedupeListenerEpic, ); diff --git a/app/models/npm/listeners/index.js b/app/models/npm/listeners/index.js index 9be6584b..89212274 100755 --- a/app/models/npm/listeners/index.js +++ b/app/models/npm/listeners/index.js @@ -2,6 +2,7 @@ import onNpmAudit$ from './npmAudit'; import onNpmDoctor$ from './npmDoctor'; +import onNpmDedupe$ from './npmDedupe'; import onNpmInit$ from './npmInit'; -export { onNpmAudit$, onNpmDoctor$, onNpmInit$ }; +export { onNpmAudit$, onNpmDoctor$, onNpmInit$, onNpmDedupe$ }; diff --git a/app/models/npm/listeners/npmDedupe.js b/app/models/npm/listeners/npmDedupe.js new file mode 100644 index 00000000..7a4c08c0 --- /dev/null +++ b/app/models/npm/listeners/npmDedupe.js @@ -0,0 +1,52 @@ +import { ipcRenderer } from 'electron'; +import { Observable } from 'rxjs'; +import { setRunningCommand } from 'models/npm/actions'; +import { setSnackbar, toggleLoader } from 'models/ui/actions'; + +const updateCommand = ({ + operationStatus, + operationPackages, + operationCommand +}) => ({ + type: setRunningCommand.type, + payload: { + operationStatus, + operationPackages, + operationCommand + } +}); + +const onNpmDedupe$ = new Observable(observer => { + ipcRenderer.removeAllListeners(['npm-dedupe-completed']); + + ipcRenderer.on('npm-dedupe-completed', (event, data) => { + observer.next( + updateCommand({ + operationStatus: 'idle', + operationCommand: null, + operationPackages: [] + }) + ); + + observer.next( + toggleLoader({ + loading: false, + message: null + }) + ); + + observer.next( + setSnackbar({ + open: true, + type: 'info', + message: data + }) + ); + }); + + ipcRenderer.on('npm-dedupe-error', (event, error) => { + observer.error(error); + }); +}); + +export default onNpmDedupe$; diff --git a/app/models/packages/actions.js b/app/models/packages/actions.js index 73e244ae..74b358f1 100755 --- a/app/models/packages/actions.js +++ b/app/models/packages/actions.js @@ -17,6 +17,7 @@ const mapOutdatedPackages = ActionCreator('MAP_OUTDATED_PACKAGES'); const mergePackages = ActionCreator('MERGE_PACKAGES'); const setActive = ActionCreator('SET_ACTIVE'); const installPackage = ActionCreator('INSTALL_PACKAGE'); +const installPackageJson = ActionCreator('INSTALL_PACKAGE_JSON'); const installMultiplePackages = ActionCreator('INSTALL_MULTIPLE_PACKAGES'); const updatePackages = ActionCreator('UPDATE_PACKAGES'); const uninstallPackages = ActionCreator('UNINSTALL_PACKAGES'); @@ -60,6 +61,7 @@ export { mergePackages, uninstallPackages, installPackage, + installPackageJson, installMultiplePackages, updatePackages, clearAll, diff --git a/app/models/packages/epics/index.js b/app/models/packages/epics/index.js index b42272ea..db94aaa9 100755 --- a/app/models/packages/epics/index.js +++ b/app/models/packages/epics/index.js @@ -7,8 +7,9 @@ import { initEpic } from './initEpics'; import { installPackageListenerEpic, installPackageEpic, + installPackageJsonEpic, installMultiplePackagesEpic, - showInstallLoaderEpic + showInstallLoaderEpic, } from './installationEpics'; // uninstall related epics @@ -57,10 +58,11 @@ export default combineEpics( initEpic, installMultiplePackagesEpic, installPackageEpic, + installPackageJsonEpic, showInstallLoaderEpic, showUpdateLoaderEpic, mapPackagesEpic, mapOutdatedPackagesEpic, searchEpic, - updateSearchFlagEpic + updateSearchFlagEpic, ); diff --git a/app/models/packages/epics/installationEpics.js b/app/models/packages/epics/installationEpics.js index 100b8261..e9818adc 100755 --- a/app/models/packages/epics/installationEpics.js +++ b/app/models/packages/epics/installationEpics.js @@ -3,13 +3,14 @@ import { ipcRenderer } from 'electron'; import { ofType } from 'redux-observable'; import { pipe } from 'rxjs'; -import { map, tap, switchMap, ignoreElements } from 'rxjs/operators'; +import { tap, concatMap, switchMap, ignoreElements } from 'rxjs/operators'; -import { toggleLoader } from 'models/ui/actions'; +import { toggleLoader, setActivePage } from 'models/ui/actions'; import { installPackage, + installPackageJson, installMultiplePackages, - installPackageListener + installPackageListener, } from 'models/packages/actions'; import { iMessage } from 'commons/utils'; import { onNpmInstall$ } from '../listeners'; @@ -21,13 +22,44 @@ const updateLoader = payload => ({ const showInstallLoaderEpic = action$ => action$.pipe( - ofType(installPackage.type, installMultiplePackages.type), - map(() => + ofType(installPackage.type, installPackageJson.type, installMultiplePackages.type), + concatMap(() => [ + setActivePage({ + page: 'packages', + paused: true + }), updateLoader({ loading: true, message: iMessage('info', 'installingPackages') }) - ) + ]) + ); + +/** +* Send ipc event to main process to handle npm-install for a single package +* supports global and local mode +*/ +const installPackageJsonEpic = (action$, state$) => + action$.pipe( + ofType(installPackageJson.type), + tap(({ payload }) => { + const { + common: { + mode, + directory, + } + } = state$.value; + + const parameters = { + ...payload, + mode, + directory, + packageJson: true + }; + + ipcRenderer.send('npm-install', parameters); + }), + ignoreElements() ); /** @@ -72,7 +104,7 @@ const installMultiplePackagesEpic = (action$, state$) => action$.pipe( ofType(installMultiplePackages.type), tap(({ payload }) => { - const { pkgOptions } = payload + const { pkgOptions } = payload; const { common: { @@ -88,7 +120,11 @@ const installMultiplePackagesEpic = (action$, state$) => option => option.name === selectedPackage ); - return pkg && pkg.options ? pkg.options : pkgOptions ? pkgOptions[idx] : ['save-prod']; + return pkg && pkg.options + ? pkg.options + : pkgOptions + ? pkgOptions[idx] + : ['save-prod']; }); const parameters = { @@ -103,6 +139,7 @@ const installMultiplePackagesEpic = (action$, state$) => ignoreElements() ); + const installPackageListenerEpic = pipe( ofType(installPackageListener.type), switchMap(() => onNpmInstall$) @@ -110,7 +147,8 @@ const installPackageListenerEpic = pipe( export { installPackageListenerEpic, + installPackageJsonEpic, installPackageEpic, installMultiplePackagesEpic, - showInstallLoaderEpic + showInstallLoaderEpic, }; diff --git a/app/models/packages/index.js b/app/models/packages/index.js index 7bccab52..6f4dfd6f 100755 --- a/app/models/packages/index.js +++ b/app/models/packages/index.js @@ -1,3 +1,5 @@ +/** epics and actions for packages logix */ + import * as actions from './actions'; import epics from './epics'; diff --git a/app/models/packages/listeners/index.js b/app/models/packages/listeners/index.js index bc385835..eb35850f 100755 --- a/app/models/packages/listeners/index.js +++ b/app/models/packages/listeners/index.js @@ -1,5 +1,3 @@ -/* eslint-disable import/prefer-default-export */ - import onListOutdatedPackages$ from './listOutdatedPackages'; import onSearchPackages$ from './npmSearch'; import onViewPackage$ from './npmView'; diff --git a/app/models/packages/listeners/listOutdatedPackages.js b/app/models/packages/listeners/listOutdatedPackages.js index f1d9e1ff..9b88bc04 100755 --- a/app/models/packages/listeners/listOutdatedPackages.js +++ b/app/models/packages/listeners/listOutdatedPackages.js @@ -21,16 +21,17 @@ const onListOutdatedPackages$ = new Observable(observer => { const packageData = JSON.parse(data); const { name, version, description } = packageData || {}; const packages = pick(['dependencies', 'problems'], packageData); - const { dependencies, problems } = packages || {}; + const { dependencies, problems: notifications } = packages || {}; const dataArray = dependencies ? objectEntries(dependencies) : objectEntries(packageData); - if (problems) { + + if (notifications) { observer.next( updateNotifications({ - notifications: problems + notifications }) ); } diff --git a/app/models/packages/listeners/npmInstall.js b/app/models/packages/listeners/npmInstall.js index e3149af9..c320d348 100755 --- a/app/models/packages/listeners/npmInstall.js +++ b/app/models/packages/listeners/npmInstall.js @@ -1,6 +1,5 @@ import { ipcRenderer } from 'electron'; import { Observable } from 'rxjs'; - import { setActivePage } from 'models/ui/actions'; import { setRunningCommand } from 'models/npm/actions'; import { clearInstallOptions } from 'models/common/actions'; @@ -24,6 +23,7 @@ const onNpmInstall$ = new Observable(observer => { ipcRenderer.on('npm-install-completed', () => { try { + observer.next(clearInstallOptions()); observer.next( updateCommand({ operationStatus: 'idle', @@ -32,8 +32,6 @@ const onNpmInstall$ = new Observable(observer => { }) ); - observer.next(clearInstallOptions()); - observer.next( setActivePage({ page: 'packages', @@ -49,10 +47,13 @@ const onNpmInstall$ = new Observable(observer => { } }) ); + } catch (error) { observer.error(error); } }); + + ipcRenderer.on('npm-install-error', (event, error) => observer.error(error)); }); export default onNpmInstall$; diff --git a/app/models/packages/listeners/npmUninstall.js b/app/models/packages/listeners/npmUninstall.js index c61340c0..223927e3 100755 --- a/app/models/packages/listeners/npmUninstall.js +++ b/app/models/packages/listeners/npmUninstall.js @@ -23,34 +23,32 @@ const updateCommand = ({ const onNpmUninstall$ = new Observable(observer => { ipcRenderer.removeAllListeners(['npm-uninstall-completed']); - ipcRenderer.on( - 'npm-uninstall-completed', - (event, resultMessage, errors, packages) => { - observer.next( - setActive({ - active: null - }) - ); - - observer.next( - updateCommand({ - operationStatus: 'idle', - operationCommand: null, - operationPackages: [] - }) - ); - - observer.next(clearNotifications()) - observer.next(removePackages({ removedPackages: packages })); - - observer.next( - setSnackbar({ - open: true, - type: 'info', - message: resultMessage - }) - ); - } + ipcRenderer.on('npm-uninstall-completed', (event, resultMessage, errors, packages) => { + observer.next( + setActive({ + active: null + }) + ); + + observer.next( + updateCommand({ + operationStatus: 'idle', + operationCommand: null, + operationPackages: [] + }) + ); + + observer.next(clearNotifications()) + observer.next(removePackages({ removedPackages: packages })); + + observer.next( + setSnackbar({ + open: true, + type: 'info', + message: resultMessage + }) + ); + } ); ipcRenderer.on('npm-uninstall-error', (event, error) => { diff --git a/app/models/ui/epics.js b/app/models/ui/epics.js index a0253ab1..93a94b42 100755 --- a/app/models/ui/epics.js +++ b/app/models/ui/epics.js @@ -10,7 +10,7 @@ const onlineStatusEpic = pipe( map(({ payload: { status } }) => ({ type: setSnackbar.type, payload: { - type: status === 'online' ? 'success' : 'error', + type: status === 'online' ? 'info' : 'error', open: true, message: `App is now ${status}` } diff --git a/app/reducers/index.js b/app/reducers/index.js index bd95da97..8a26b5b7 100755 --- a/app/reducers/index.js +++ b/app/reducers/index.js @@ -1,5 +1,5 @@ /** - * Root reducer + * Root reducer_ * use combineReducers to combine reducers into one root reducer * */ diff --git a/app/reducers/initialState.js b/app/reducers/initialState.js index d81b6d68..36df59c8 100755 --- a/app/reducers/initialState.js +++ b/app/reducers/initialState.js @@ -12,6 +12,7 @@ const initialState = { packagesInstallOptions: [] }, notifications: { + active: null, notifications: [] }, npm: { diff --git a/app/reducers/notifications.js b/app/reducers/notifications.js index a63ded2b..12743722 100755 --- a/app/reducers/notifications.js +++ b/app/reducers/notifications.js @@ -2,11 +2,11 @@ * Notifications reducer: Handles state management for notifications operations */ -import { prepend, identity, merge, prop, propOr } from 'ramda'; +import { assoc, prepend, identity, merge, prop, propOr } from 'ramda'; import { addNotification, clearNotifications, - updateNotifications + setActive } from 'models/notifications/actions'; import initialState from './initialState'; @@ -17,23 +17,31 @@ const createReducer = (notificationsState, handlers) => ( state = notificationsState, action ) => propOr(identity, prop('type', action), handlers)(state, action); - const handlers = { - [updateNotifications.type]: (state, { payload: { data } }) => - merge(state, { - notifications: data - }), + [setActive.type]: (state, { payload: { active } }) => + assoc('active', active, state), [addNotification.type]: ( state, - { payload: { type, body, required, requiredBy } } + { + payload: { + id, + reason, + requiredName, + requiredVersion, + requiredByName, + requiredByVersion, + } + } ) => merge(state, { notifications: prepend( { - type, - body, - required: required.charAt(0) === '@' ? required.slice(1) : required, - requiredBy + id, + reason, + requiredName, + requiredVersion, + requiredByName, + requiredByVersion }, state.notifications ) diff --git a/app/store/configureStore.dev.js b/app/store/configureStore.dev.js index 63fcdd86..3eb966ca 100755 --- a/app/store/configureStore.dev.js +++ b/app/store/configureStore.dev.js @@ -8,6 +8,8 @@ import { createStore, compose, applyMiddleware } from 'redux'; import { createLogger } from 'redux-logger'; import { createEpicMiddleware } from 'redux-observable'; +import { BehaviorSubject } from 'rxjs'; +import { switchMap } from 'rxjs/operators'; // epics import { epics as packagesEpics } from 'models/packages'; @@ -49,18 +51,27 @@ const configureStore = initialState => { // store creation const store = createStore(rootReducer, initialState, enhancer); - if (module.hot) { - module.hot.accept('../reducers', () => - store.replaceReducer(require('../reducers')) - ); - } + const notificationsEpics$ = new BehaviorSubject(notificationsEpics); + const hotRelNotificationsEpics = (...args) => + notificationsEpics$.pipe(switchMap(epic => epic(...args))); epicMiddleware.run(uiEpics); epicMiddleware.run(packagesEpics); epicMiddleware.run(npmEpics); - epicMiddleware.run(notificationsEpics); + epicMiddleware.run(hotRelNotificationsEpics); epicMiddleware.run(commonEpics); + if (module.hot) { + module.hot.accept('../reducers', () => { + store.replaceReducer(require('../reducers/notifications').default); + }); + + module.hot.accept('../models/notifications/epics', () => { + const nextNotificationsRootEpic = require('models/notifications/epics'); + notificationsEpics$.next(nextNotificationsRootEpic); + }); + } + return store; }; diff --git a/app/styles/common.js b/app/styles/common.js old mode 100644 new mode 100755 diff --git a/app/styles/theme/index.js b/app/styles/theme/index.js old mode 100644 new mode 100755 index 7f2c2a82..3bc3b28c --- a/app/styles/theme/index.js +++ b/app/styles/theme/index.js @@ -1,30 +1,36 @@ import { createMuiTheme } from '@material-ui/core'; - import palette from './palette'; import typography from './typography'; import overrides from './overrides'; +import props from './props'; const theme = createMuiTheme({ palette, typography, overrides, + props, zIndex: { appBar: 1200, drawer: 1100 }, - props: { - MuiTab: { - disableRipple: true + spacing: 8, + breakpoints: { + values: { + xs: 0, + sm: 600, + md: 960, + lg: 1280, + xl: 1440 } }, mixins: { toolbar: { - minHeight: 48 + minHeight: 56 } }, shape: { borderRadius: 8 - }, + } }); export default theme; diff --git a/app/styles/theme/overrides/MuiButton.js b/app/styles/theme/overrides/MuiButton.js old mode 100644 new mode 100755 index 15afb152..3f0f4118 --- a/app/styles/theme/overrides/MuiButton.js +++ b/app/styles/theme/overrides/MuiButton.js @@ -1,10 +1,12 @@ import palette from '../palette'; export default { - outlined: {}, label: { textTransform: 'initial' }, + outlined: { + padding: '3px 16px' + }, contained: { backgroundColor: palette.common.white, '&:hover': { @@ -14,5 +16,6 @@ export default { '&:active': { boxShadow: 'none' } - }, + } + }; diff --git a/app/styles/theme/overrides/MuiChip.js b/app/styles/theme/overrides/MuiChip.js old mode 100644 new mode 100755 diff --git a/app/styles/theme/overrides/MuiLinearProgress.js b/app/styles/theme/overrides/MuiDivider.js old mode 100644 new mode 100755 similarity index 61% rename from app/styles/theme/overrides/MuiLinearProgress.js rename to app/styles/theme/overrides/MuiDivider.js index 55645a4a..038c9517 --- a/app/styles/theme/overrides/MuiLinearProgress.js +++ b/app/styles/theme/overrides/MuiDivider.js @@ -1,12 +1,7 @@ - import palette from '../palette'; export default { root: { - borderRadius: '3px', - overflow: 'hidden' - }, - colorPrimary: { backgroundColor: palette.common.neutral } }; diff --git a/app/styles/theme/overrides/MuiDrawer.js b/app/styles/theme/overrides/MuiDrawer.js new file mode 100755 index 00000000..2db1323e --- /dev/null +++ b/app/styles/theme/overrides/MuiDrawer.js @@ -0,0 +1,7 @@ +import palette from '../palette'; + +export default { + paper: { + backgroundColor: palette.common.white + } +}; diff --git a/app/styles/theme/overrides/MuiFab.js b/app/styles/theme/overrides/MuiFab.js old mode 100644 new mode 100755 diff --git a/app/styles/theme/overrides/MuiFilledInput.js b/app/styles/theme/overrides/MuiFilledInput.js old mode 100644 new mode 100755 diff --git a/app/styles/theme/overrides/MuiIconButton.js b/app/styles/theme/overrides/MuiIconButton.js old mode 100644 new mode 100755 index 69335879..463258bf --- a/app/styles/theme/overrides/MuiIconButton.js +++ b/app/styles/theme/overrides/MuiIconButton.js @@ -2,10 +2,15 @@ import palette from '../palette'; export default { root: { - padding: '10px', + padding: 10, color: palette.text.secondary, '&:hover': { backgroundColor: 'rgba(0, 0, 0, 0.03)' } + }, + sizeSmall: { + marginLeft: 4, + marginRight: 4, + padding: 12 } }; diff --git a/app/styles/theme/overrides/MuiInputBase.js b/app/styles/theme/overrides/MuiInputBase.js old mode 100644 new mode 100755 diff --git a/app/styles/theme/overrides/MuiListItemIcon.js b/app/styles/theme/overrides/MuiListItemIcon.js old mode 100644 new mode 100755 index bdb66b5a..f8002bf7 --- a/app/styles/theme/overrides/MuiListItemIcon.js +++ b/app/styles/theme/overrides/MuiListItemIcon.js @@ -1,8 +1,9 @@ -import palette from '../palette'; - export default { root: { - color: palette.text.secondary, - minWidth: '32px' + color: 'inherit', + marginRight: 0, + '& svg': { + fontSize: 20 + } } }; diff --git a/app/styles/theme/overrides/MuiOutlinedInput.js b/app/styles/theme/overrides/MuiOutlinedInput.js old mode 100644 new mode 100755 index 392fd3ba..94e8394e --- a/app/styles/theme/overrides/MuiOutlinedInput.js +++ b/app/styles/theme/overrides/MuiOutlinedInput.js @@ -3,7 +3,7 @@ import palette from '../palette'; export default { root: { '&:hover:not($disabled)': { - backgroundColor: palette.info.dark + backgroundColor: palette.text.secondary } } }; diff --git a/app/styles/theme/overrides/MuiSvgIcon.js b/app/styles/theme/overrides/MuiSvgIcon.js old mode 100644 new mode 100755 index 9652a7b0..7e67a3ea --- a/app/styles/theme/overrides/MuiSvgIcon.js +++ b/app/styles/theme/overrides/MuiSvgIcon.js @@ -1,7 +1,7 @@ export default { root: { - height: '25px', - width: '25px', - fontSize: '25px' + height: 22, + width: 22, + fontSize: 22 } }; diff --git a/app/styles/theme/overrides/MuiTab.js b/app/styles/theme/overrides/MuiTab.js old mode 100644 new mode 100755 index 002234fa..ce901102 --- a/app/styles/theme/overrides/MuiTab.js +++ b/app/styles/theme/overrides/MuiTab.js @@ -1,12 +1,13 @@ export default { root: { textTransform: 'initial', + margin: 0, minWidth: 0, - height: '50px', + height: 50, fontWeight: 400, - fontSize: '14px', + fontSize: 14, '@media (min-width: 960px)': { - minWidth: '90px' + minWidth: 90 }, '&$selected': { fontWeight: 500 diff --git a/app/styles/theme/overrides/MuiTableCell.js b/app/styles/theme/overrides/MuiTableCell.js old mode 100644 new mode 100755 diff --git a/app/styles/theme/overrides/MuiTableRow.js b/app/styles/theme/overrides/MuiTableRow.js old mode 100644 new mode 100755 index f175e67e..a2934933 --- a/app/styles/theme/overrides/MuiTableRow.js +++ b/app/styles/theme/overrides/MuiTableRow.js @@ -2,13 +2,12 @@ import palette from '../palette'; export default { root: { - height: '46px', '&$selected': { backgroundColor: palette.background.neutral }, '&$hover': { '&:hover': { - backgroundColor: palette.warning.light + backgroundColor: palette.secondary.light } } } diff --git a/app/styles/theme/overrides/MuiTabs.js b/app/styles/theme/overrides/MuiTabs.js old mode 100644 new mode 100755 index d028f01e..aab83fd8 --- a/app/styles/theme/overrides/MuiTabs.js +++ b/app/styles/theme/overrides/MuiTabs.js @@ -1,5 +1,5 @@ export default { indicator: { - height: '3px' + height: 3 } }; diff --git a/app/styles/theme/overrides/index.js b/app/styles/theme/overrides/index.js old mode 100644 new mode 100755 index 6c7e53e9..d5f0a764 --- a/app/styles/theme/overrides/index.js +++ b/app/styles/theme/overrides/index.js @@ -4,7 +4,6 @@ import MuiFab from './MuiFab'; import MuiFilledInput from './MuiFilledInput'; import MuiIconButton from './MuiIconButton'; import MuiInputBase from './MuiInputBase'; -import MuiLinearProgress from './MuiLinearProgress'; import MuiListItemIcon from './MuiListItemIcon'; import MuiOutlinedInput from './MuiOutlinedInput'; import MuiSvgIcon from './MuiSvgIcon'; @@ -12,6 +11,8 @@ import MuiTab from './MuiTab'; import MuiTableCell from './MuiTableCell'; import MuiTableRow from './MuiTableRow'; import MuiTabs from './MuiTabs'; +import MuiDrawer from './MuiDrawer'; +import MuiDivider from './MuiDivider'; export default { MuiButton, @@ -20,12 +21,13 @@ export default { MuiFilledInput, MuiIconButton, MuiInputBase, - MuiLinearProgress, MuiListItemIcon, MuiOutlinedInput, MuiSvgIcon, MuiTab, MuiTableCell, MuiTableRow, - MuiTabs + MuiTabs, + MuiDrawer, + MuiDivider }; diff --git a/app/styles/theme/palette.js b/app/styles/theme/palette.js old mode 100644 new mode 100755 index 3e4b7bcd..5bf4ebdc --- a/app/styles/theme/palette.js +++ b/app/styles/theme/palette.js @@ -1,58 +1,59 @@ +import { lighten, darken } from '@material-ui/core/styles/colorManipulator'; import { whiteColor as white, blackColor as black } from '../variables'; export default { common: { black, white, - neutral: '#E4E7EB', - muted: '#9EA0A4' + neutral: '#e4e5ff', + muted: '#ccceee' }, primary: { contrastText: white, - light: '#63ccff', - main: '#009be5', - dark: '#006db3' + light: lighten('#006db3', 0.1), + main: '#006db3', + dark: darken('#006db3', 0.1) }, secondary: { contrastText: white, - main: '#f11f90', - light: '#e51a90', - dark: '#c00a70' + light: lighten('#f7cac9', 0.8), + main: '#e51a90', + dark: darken('#e51a90', 0.1) }, success: { contrastText: white, - main: '#45B880', - light: '#F1FAF5', - dark: '#00783E' + light: lighten('#4caf50', 0.1), + main: '#4caf50', + dark: darken('#4caf50', 0.1) }, info: { contrastText: white, - main: '#1070CA', - light: '#F1FBFC', - dark: '#007489' + light: lighten('#88ffdd', 0.1), + main: '#88ffdd', + dark: darken('#88ffdd', 0.1) }, warning: { contrastText: white, - main: '#FFB822', - light: '#FDF8F3', - dark: '#95591E' + light: lighten('#ffae42', 0.1), + main: '#ffae42', + dark: darken('#ffae42', 0.1) }, - danger: { + error: { contrastText: white, - main: '#ED4740', - light: '#FEF6F6', - dark: '#BF0E08' + light: lighten('#d8000c', 0.1), + main: '#d8000c', + dark: darken('#d8000c', 0.1) }, text: { - primary: '#12161B', - secondary: '#66788A', - disabled: '#A6B1BB' + primary: '#12161b', + secondary: '#66788a', + disabled: '#a6B1bb' }, background: { - default: '#f8fafc', - dark: '#172B4D', + default: white, + dark: '#172b4d', paper: white }, - border: '#DFE3E8', - divider: '#DFE3E8' + border: '#dfe3e8', + divider: '#ccc' }; diff --git a/app/styles/theme/props.js b/app/styles/theme/props.js new file mode 100755 index 00000000..ee5fa512 --- /dev/null +++ b/app/styles/theme/props.js @@ -0,0 +1,10 @@ +const props = { + MuiTab: { + disableRipple: true + }, + MuiButtonBase: { + disableRipple: true + } +}; + +export default props; diff --git a/app/styles/theme/typography.js b/app/styles/theme/typography.js old mode 100644 new mode 100755 index 9dd8a1b3..8e80c899 --- a/app/styles/theme/typography.js +++ b/app/styles/theme/typography.js @@ -4,80 +4,82 @@ import { defaultFont } from '../variables'; export default { ...defaultFont, useNextVariants: true, + fontFamily: [ + 'Regular', + '-apple-system', + 'BlinkMacSystemFont', + '"Segoe UI"', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + 'sans-serif', + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"' + ].join(','), h1: { color: palette.text.primary, - fontWeight: '500', - fontSize: '35px', - letterSpacing: '-0.24px', - lineHeight: '40px' + fontWeight: 400, + fontSize: 35, + letterSpacing: '-0.24px' }, h2: { color: palette.text.primary, - fontWeight: '500', - fontSize: '29px', - letterSpacing: '-0.24px', - lineHeight: '32px' + fontWeight: 400, + fontSize: 30, + letterSpacing: '-0.24px' }, h3: { color: palette.text.primary, - fontWeight: '500', - fontSize: '24px', - letterSpacing: '-0.06px', - lineHeight: '28px' + fontWeight: 400, + fontSize: 24, + letterSpacing: '-0.06px' }, h4: { color: palette.text.primary, - fontWeight: '500', - fontSize: '20px', - letterSpacing: '-0.06px', - lineHeight: '24px' + fontWeight: 400, + fontSize: 20, + letterSpacing: '-0.06px' }, h5: { color: palette.text.primary, - fontWeight: '500', - fontSize: '16px', - letterSpacing: '-0.05px', - lineHeight: '20px' + fontWeight: 400, + fontSize: 16, + letterSpacing: '-0.05px' }, h6: { color: palette.text.primary, - fontWeight: '500', - fontSize: '14px', - letterSpacing: '-0.05px', - lineHeight: '20px' + fontWeight: 500, + fontSize: 14, + letterSpacing: '-0.05px' }, subtitle1: { color: palette.text.primary, - fontSize: '16px', - letterSpacing: '-0.05px', - lineHeight: '25px' + fontSize: 16, + letterSpacing: '-0.05px' }, subtitle2: { color: palette.text.primary, - fontSize: '14px', - letterSpacing: 0, - lineHeight: '16px' + fontSize: 14, + letterSpacing: 0 }, body1: { color: palette.text.primary, - fontSize: '14px', - letterSpacing: '-0.05px', - lineHeight: '21px' + fontSize: 16, + letterSpacing: '-0.05px' }, body2: { color: palette.text.primary, - fontSize: '12px', - letterSpacing: '-0.04px', - lineHeight: '14px' + fontSize: 14, + letterSpacing: '-0.04px' }, button: { color: palette.text.primary, - fontSize: '14px' + fontSize: 14 }, caption: { color: palette.text.secondary, - fontSize: '12px', - letterSpacing: '0.3px', - lineHeight: '16px' + fontSize: 12, + letterSpacing: 0.3 } }; diff --git a/app/styles/variables.js b/app/styles/variables.js index f7b53fef..ea1de1c6 100755 --- a/app/styles/variables.js +++ b/app/styles/variables.js @@ -4,7 +4,7 @@ * Styles that are used on more than one component */ -const drawerWidth = 285; +const drawerWidth = 275; const transition = { transition: 'all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1)' diff --git a/babel.config.js b/babel.config.js index 41da72eb..64c878f8 100755 --- a/babel.config.js +++ b/babel.config.js @@ -2,7 +2,7 @@ const developmentEnvironments = ['development', 'test']; -const developmentPlugins = [require('react-hot-loader/babel')]; +const developmentPlugins = []; const productionPlugins = [ require('babel-plugin-dev-expression'), diff --git a/configs/webpack.config.renderer.dev.babel.js b/configs/webpack.config.renderer.dev.babel.js index fd490f69..55bc37b5 100755 --- a/configs/webpack.config.renderer.dev.babel.js +++ b/configs/webpack.config.renderer.dev.babel.js @@ -66,7 +66,7 @@ export default merge.smart(baseConfig, { components: path.resolve(path.join(__dirname, '..', 'app', 'components')), containers: path.resolve(path.join(__dirname, '..', 'app', 'containers')), models: path.resolve(path.join(__dirname, '..', 'app', 'models')), - styles: path.resolve(path.join(__dirname, '..', 'app', 'styles')), + styles: path.resolve(path.join(__dirname, '..', 'app', 'styles')) } }, module: { @@ -192,9 +192,7 @@ export default merge.smart(baseConfig, { sourceType: 'var' }), - new webpack.HotModuleReplacementPlugin({ - multiStep: true - }), + new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin(), @@ -232,10 +230,9 @@ export default merge.smart(baseConfig, { stats: 'errors-only', inline: true, lazy: false, - // If you want to refresh on errors too - // hot: true, - // Don't refresh if hot loading fails. - hotOnly: true, + liveReload: false, + hot: false, // if you want to refresh on errors too, + hotOnly: true, // don't refresh if hot loading fails. headers: { 'Access-Control-Allow-Origin': '*' }, contentBase: path.join(__dirname, 'dist'), watchContentBase: true, diff --git a/media/images/luna-1.png b/media/images/luna-1.png index a8a3dbab..d1308425 100755 Binary files a/media/images/luna-1.png and b/media/images/luna-1.png differ diff --git a/media/images/luna-2.png b/media/images/luna-2.png old mode 100755 new mode 100644 index 73f75b34..ef1d785b Binary files a/media/images/luna-2.png and b/media/images/luna-2.png differ diff --git a/media/images/luna-4.png b/media/images/luna-4.png deleted file mode 100755 index 9ac62f99..00000000 Binary files a/media/images/luna-4.png and /dev/null differ diff --git a/media/images/luna-v3.0.0.png b/media/images/luna-v3.0.0.png deleted file mode 100755 index 6a601a18..00000000 Binary files a/media/images/luna-v3.0.0.png and /dev/null differ diff --git a/package-lock.json b/package-lock.json index 535c0f83..77900d50 100755 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", - "dev": true, "requires": { "@babel/highlight": "^7.0.0" } @@ -472,7 +471,6 @@ "version": "7.5.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", @@ -1682,22 +1680,32 @@ "to-fast-properties": "^2.0.0" } }, + "@develar/schema-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.1.0.tgz", + "integrity": "sha512-qjCqB4ctMig9Gz5bd6lkdFr3bO6arOdQqptdBSpF1ZpCnjofieCciEzkoS9ujY9cMGyllYSCSmBJ3x9OKHXzoA==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + } + }, "@emotion/hash": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.7.2.tgz", "integrity": "sha512-RMtr1i6E8MXaBWwhXL3yeOU8JXRnz8GNxHvaUfVvwxokvayUY0zoBeWbKw1S9XkufmGEEdQd228pSZXFkAln8Q==" }, "@material-ui/core": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.2.1.tgz", - "integrity": "sha512-hasPQUFAb9OxKng7UX2+SjUWtVZbnkVJ/jHZWXTivVcU+UzvNIpA9AyRRQvZ8SPV6swP/HD2VzUBzoMEeRR6wg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.3.2.tgz", + "integrity": "sha512-TLKEUw3/R/pOInnJkx0x78zqMos34SPL3HfuRRZMxInRQ6AKUlyglOFyvSwFITknTmc8AGRFknGpZt05g2XFTg==", "requires": { - "@babel/runtime": "^7.2.0", - "@material-ui/styles": "^4.2.0", - "@material-ui/system": "^4.3.0", + "@babel/runtime": "^7.4.4", + "@material-ui/styles": "^4.3.0", + "@material-ui/system": "^4.3.3", "@material-ui/types": "^4.1.1", - "@material-ui/utils": "^4.1.0", - "@types/react-transition-group": "^2.0.16", + "@material-ui/utils": "^4.3.0", + "@types/react-transition-group": "^4.2.0", "clsx": "^1.0.2", "convert-css-length": "^2.0.1", "deepmerge": "^4.0.0", @@ -1724,9 +1732,9 @@ "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==" }, "react-transition-group": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.2.1.tgz", - "integrity": "sha512-IXrPr93VzCPupwm2O6n6C2kJIofJ/Rp5Ltihhm9UfE8lkuVX2ng/SUUl/oWjblybK9Fq2Io7LGa6maVqPB762Q==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.2.2.tgz", + "integrity": "sha512-uP0tjqewtvjb7kGZFpZYPoD/NlVZmIgts9eTt1w35pAaEApPxQGv94lD3VkqyXf2aMqrSGwhs6EV/DLaoKbLSw==", "requires": { "@babel/runtime": "^7.4.5", "dom-helpers": "^3.4.0", @@ -1745,11 +1753,11 @@ } }, "@material-ui/styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.2.1.tgz", - "integrity": "sha512-1KSOZ17LBWBqIyPRsEpyb4snT/wRIfQTPi0x66UvSzznVK9MPAfJx3/s5lVT4vrGFObs/nj6Pet6Nhrdl2WCrg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.3.0.tgz", + "integrity": "sha512-7yOu+IOvbTVM+LfFJ0c7RZKksSpi2PmPwMhVnAKo1Ca3Nadjd950ALL6WG+R/W3C3GqakUvOqA5OLMvN/8N2jg==", "requires": { - "@babel/runtime": "^7.2.0", + "@babel/runtime": "^7.4.4", "@emotion/hash": "^0.7.1", "@material-ui/types": "^4.1.1", "@material-ui/utils": "^4.1.0", @@ -1757,24 +1765,24 @@ "csstype": "^2.5.2", "deepmerge": "^4.0.0", "hoist-non-react-statics": "^3.2.1", - "jss": "10.0.0-alpha.17", - "jss-plugin-camel-case": "10.0.0-alpha.17", - "jss-plugin-default-unit": "10.0.0-alpha.17", - "jss-plugin-global": "10.0.0-alpha.17", - "jss-plugin-nested": "10.0.0-alpha.17", - "jss-plugin-props-sort": "10.0.0-alpha.17", - "jss-plugin-rule-value-function": "10.0.0-alpha.17", - "jss-plugin-vendor-prefixer": "10.0.0-alpha.17", + "jss": "10.0.0-alpha.23", + "jss-plugin-camel-case": "10.0.0-alpha.23", + "jss-plugin-default-unit": "10.0.0-alpha.23", + "jss-plugin-global": "10.0.0-alpha.23", + "jss-plugin-nested": "10.0.0-alpha.23", + "jss-plugin-props-sort": "10.0.0-alpha.23", + "jss-plugin-rule-value-function": "10.0.0-alpha.23", + "jss-plugin-vendor-prefixer": "10.0.0-alpha.23", "prop-types": "^15.7.2", "warning": "^4.0.1" } }, "@material-ui/system": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.3.1.tgz", - "integrity": "sha512-Krrc/p/A3rod4M3FYcsWSqE5KxpoyMzYuUHhs0Pns3KH+5kcFyBU+aYbIzMfUz58rhbHkqrShf1fjj7EKcgY0g==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.3.3.tgz", + "integrity": "sha512-j7JyvlhcTdc1wV6HzrDTU7XXlarxYXEUyzyHawOA0kCGmYVN2uFHENQRARLUdl+mEmuXO4TsAhNAiqiKakkFMg==", "requires": { - "@babel/runtime": "^7.2.0", + "@babel/runtime": "^7.4.4", "deepmerge": "^4.0.0", "prop-types": "^15.7.2", "warning": "^4.0.1" @@ -1789,13 +1797,13 @@ } }, "@material-ui/utils": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.1.0.tgz", - "integrity": "sha512-muwmVU799tzPjzb+Q5E/CTDle0rXwkCAdvMVyU0BfbJhenkUsFmuYiCmbvMVOU1m6F1S5HWfXz8EP4pXwwAvrw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.3.0.tgz", + "integrity": "sha512-tK3Z/ap5ifPQwIryuGQ+AHLh2hEyBLRPj4NCMcqVrQfD+0KH2IP5BXR4A+wGVsyamKfLaOc8tz1fzxZblsztpw==", "requires": { - "@babel/runtime": "^7.2.0", + "@babel/runtime": "^7.4.4", "prop-types": "^15.7.2", - "react-is": "^16.8.0" + "react-is": "^16.8.6" } }, "@mrmlnc/readdir-enhanced": { @@ -1808,12 +1816,40 @@ "glob-to-regexp": "^0.3.0" } }, + "@nodelib/fs.scandir": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.1.tgz", + "integrity": "sha512-NT/skIZjgotDSiXs0WqYhgcuBKhUMgfekCmCGtkUAiLqZdOnrdjmZr9wRl3ll64J9NF79uZ4fk16Dx0yMc/Xbg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.1", + "run-parallel": "^1.1.9" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.1.tgz", + "integrity": "sha512-+RqhBlLn6YRBGOIoVYthsG0J9dfpO79eJyN7BYBkZJtfqrBwf2KK+rD/M/yjZR6WBmIhAgOV7S60eCgaSWtbFw==", + "dev": true + } + } + }, "@nodelib/fs.stat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", "dev": true }, + "@nodelib/fs.walk": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.2.tgz", + "integrity": "sha512-J/DR3+W12uCzAJkw7niXDcqcKBg6+5G5Q/ZpThpGNzAUz70eOR6RV4XnnSN01qHZiVl0eavoxJsBypQoKsV2QQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.1", + "fastq": "^1.6.0" + } + }, "@samverschueren/stream-to-observable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", @@ -1839,9 +1875,9 @@ } }, "@types/debug": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.4.tgz", - "integrity": "sha512-D9MyoQFI7iP5VdpEyPZyjjqIJ8Y8EDNQFIFVLOmeg1rI1xiHOChyUPMPRUVfqFCerxfE+yS3vMyj37F6IdtOoQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz", + "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", "dev": true }, "@types/events": { @@ -1873,12 +1909,6 @@ "integrity": "sha512-QcAKpaO6nhHLlxWBvpc4WeLrTvPqlHOvaj0s5GriKkA1zq+bsFBPpfYCvQhLqLgYlIko8A9YrPdaMHCo5mBcpg==", "dev": true }, - "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", - "dev": true - }, "@types/prop-types": { "version": "15.7.1", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz", @@ -1891,18 +1921,18 @@ "dev": true }, "@types/react": { - "version": "16.8.23", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.23.tgz", - "integrity": "sha512-abkEOIeljniUN9qB5onp++g0EY38h7atnDHxwKUFz1r3VH1+yG1OKi2sNPTyObL40goBmfKFpdii2lEzwLX1cA==", + "version": "16.9.1", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.1.tgz", + "integrity": "sha512-jGM2x8F7m7/r+81N/BOaUKVwbC5Cdw6ExlWEUpr77XPwVeNvAppnPEnMMLMfxRDYL8FPEX8MHjwtD2NQMJ0yyQ==", "requires": { "@types/prop-types": "*", "csstype": "^2.2.0" } }, "@types/react-transition-group": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-2.9.2.tgz", - "integrity": "sha512-5Fv2DQNO+GpdPZcxp2x/OQG/H19A01WlmpjVD9cKvVFmoVLOZ9LvBgSWG6pSXIU4og5fgbvGPaCV5+VGkWAEHA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.2.2.tgz", + "integrity": "sha512-YfoaTNqBwbIqpiJ5NNfxfgg5kyFP1Hqf/jqBtSWNv0E+EkkxmN+3VD6U2fu86tlQvdAc1o0SdWhnWFwcRMTn9A==", "requires": { "@types/react": "*" } @@ -2147,14 +2177,12 @@ "acorn": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.0.tgz", - "integrity": "sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw==", - "dev": true + "integrity": "sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw==" }, "acorn-jsx": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", - "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", - "dev": true + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==" }, "acorn-walk": { "version": "6.2.0", @@ -2204,9 +2232,9 @@ "dev": true }, "animejs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/animejs/-/animejs-3.0.1.tgz", - "integrity": "sha512-7mMoBQScvA7s4zm3EVgnuXXrtOu6TJNAhU+Ajo7HsXYH0NwbuZIcRHMO65a9NyUlmAXz4VPxlK5cENNOQbCi8g==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/animejs/-/animejs-3.1.0.tgz", + "integrity": "sha512-BjnCroPPQPEAngT0M89pz9TBcOGgOFLnVoq3+jV2upl4rn60k57/AXvESTnuILsNgOEjGuhMEOMp7IlQzk40kA==" }, "ansi-align": { "version": "3.0.0", @@ -2341,26 +2369,27 @@ } }, "app-builder-bin": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.4.0.tgz", - "integrity": "sha512-ZyQqfFnyjAmXep29PmuMIu2KvGlfHiziz2/I38zOFe5kqnkMqeNNn/qmnwD6wdCKKeHqBuZtoWQnft8q0YyLpw==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.4.3.tgz", + "integrity": "sha512-qMhayIwi3juerQEVJMQ76trObEbfQT0nhUdxZz9a26/3NLT3pE6awmQ8S1cEnrGugaaM5gYqR8OElcDezfmEsg==", "dev": true }, "app-builder-lib": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-21.1.1.tgz", - "integrity": "sha512-nG5w9xjv4c16ki+pyBPqJvUCtQY97XQNsA4dEBryq6vClwDTkwKrl7aS0cXjo3dsWKsf/5EIcLrV0tfIiXUqJA==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-21.2.0.tgz", + "integrity": "sha512-aOX/nv77/Bti6NymJDg7p9T067xD8m1ipIEJR7B4Mm1GsJWpMm9PZdXtCRiMNRjHtQS5KIljT0g17781y6qn5A==", "dev": true, "requires": { "7zip-bin": "~5.0.3", + "@develar/schema-utils": "~2.1.0", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.9", - "builder-util": "21.1.1", + "builder-util": "21.2.0", "builder-util-runtime": "8.3.0", "chromium-pickle-js": "^0.2.0", "debug": "^4.1.1", "ejs": "^2.6.2", - "electron-publish": "21.1.1", + "electron-publish": "21.2.0", "fs-extra": "^8.1.0", "hosted-git-info": "^2.7.1", "is-ci": "^2.0.0", @@ -2369,9 +2398,9 @@ "lazy-val": "^1.0.4", "minimatch": "^3.0.4", "normalize-package-data": "^2.5.0", - "read-config-file": "4.0.1", - "sanitize-filename": "^1.6.1", - "semver": "^6.2.0", + "read-config-file": "5.0.0", + "sanitize-filename": "^1.6.2", + "semver": "^6.3.0", "temp-file": "^3.3.4" }, "dependencies": { @@ -2400,6 +2429,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -2558,7 +2593,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -2726,8 +2760,7 @@ "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" }, "async": { "version": "2.6.3", @@ -2757,9 +2790,9 @@ "dev": true }, "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", "dev": true }, "asynckit": { @@ -3024,7 +3057,8 @@ "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true }, "binary-extensions": { "version": "1.13.1", @@ -3212,7 +3246,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3221,8 +3254,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" } } }, @@ -3408,14 +3440,14 @@ "dev": true }, "builder-util": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-21.1.1.tgz", - "integrity": "sha512-+t6pbMo/COTYDfqfRDrWDi9tuPxBctb0S9PVt8Kgd+K0eqD1lvbF05rrkiQpXIrhb6cndXgcl3FG18Oqgy5YPg==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-21.2.0.tgz", + "integrity": "sha512-Nd6CUb6YgDY8EXAXEIegx+1kzKqyFQ5ZM5BoYkeunAlwz/zDJoH1UCyULjoS5wQe5czNClFQy07zz2bzYD0Z4A==", "dev": true, "requires": { "7zip-bin": "~5.0.3", "@types/debug": "^4.1.4", - "app-builder-bin": "3.4.0", + "app-builder-bin": "3.4.3", "bluebird-lst": "^1.0.9", "builder-util-runtime": "8.3.0", "chalk": "^2.4.2", @@ -3423,7 +3455,7 @@ "fs-extra": "^8.1.0", "is-ci": "^2.0.0", "js-yaml": "^3.13.1", - "source-map-support": "^0.5.12", + "source-map-support": "^0.5.13", "stat-mode": "^0.3.0", "temp-file": "^3.3.4" }, @@ -3453,6 +3485,16 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } } } }, @@ -3501,9 +3543,9 @@ "dev": true }, "cacache": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", - "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.2.tgz", + "integrity": "sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg==", "dev": true, "requires": { "bluebird": "^3.5.5", @@ -3511,6 +3553,7 @@ "figgy-pudding": "^3.5.1", "glob": "^7.1.4", "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", "lru-cache": "^5.1.1", "mississippi": "^3.0.0", "mkdirp": "^0.5.1", @@ -3623,8 +3666,7 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "camelcase": { "version": "5.3.1", @@ -3723,8 +3765,7 @@ "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, "check-types": { "version": "8.0.3", @@ -3888,8 +3929,7 @@ "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" }, "cliui": { "version": "4.1.0", @@ -3903,15 +3943,14 @@ } }, "clone-deep": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz", - "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, "requires": { - "for-own": "^1.0.0", "is-plain-object": "^2.0.4", - "kind-of": "^6.0.0", - "shallow-clone": "^1.0.0" + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" } }, "clone-regexp": { @@ -4132,8 +4171,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.2", @@ -4285,9 +4323,9 @@ } }, "confusing-browser-globals": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.7.tgz", - "integrity": "sha512-cgHI1azax5ATrZ8rJ+ODDML9Fvu67PimB6aNxBrc/QwSaDaM9eTfIEUHx3bBLJJ82ioSb+/5zfsMCCEJax3ByQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.8.tgz", + "integrity": "sha512-lI7asCibVJ6Qd3FGU7mu4sfG4try4LX3+GVS+Gv8UlrEf2AeW57piecapnog2UHZSbcX/P/1UDWVaTsblowlZg==", "dev": true }, "connect-history-api-fallback": { @@ -4385,9 +4423,9 @@ "dev": true }, "core-js": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.4.tgz", - "integrity": "sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.2.0.tgz", + "integrity": "sha512-gybgLzmr7SQRSF6UzGYXducx4eE10ONQlyEnQoqiGPbmbn7zLkb73tPfc4YbZN0lvcTQwoLNPjq4RuCaCumGyQ==" }, "core-js-compat": { "version": "3.1.4", @@ -4556,7 +4594,6 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -4568,8 +4605,7 @@ "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" } } }, @@ -4641,9 +4677,9 @@ } }, "css-loader": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.1.0.tgz", - "integrity": "sha512-MuL8WsF/KSrHCBCYaozBKlx+r7vIfUaDTEreo7wR7Vv3J6N0z6fqWjRk3e/6wjneitXN1r/Y9FTK1psYNOBdJQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.2.0.tgz", + "integrity": "sha512-QTF3Ud5H7DaZotgdcJjGMvyDj5F3Pn1j/sC6VBEOVp94cbwqyIBdcs/quzj4MC1BKQSrTpQznegH/5giYbhnCQ==", "dev": true, "requires": { "camelcase": "^5.3.1", @@ -4661,9 +4697,9 @@ }, "dependencies": { "schema-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.0.1.tgz", - "integrity": "sha512-HJFKJ4JixDpRur06QHwi8uu2kZbng318ahWEKgBjc0ZklcE4FDvmm2wghb448q0IRaABxIESt8vqPFvwgMB80A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.1.0.tgz", + "integrity": "sha512-g6SViEZAfGNrToD82ZPUjq52KUPDYc+fN5+g6Euo5mLokl/9Yx14z0Cu4RR1m55HtBXejO0sBt+qw79axN+Fiw==", "dev": true, "requires": { "ajv": "^6.1.0", @@ -4891,9 +4927,9 @@ "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" }, "d3-color": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.8.tgz", - "integrity": "sha512-yeANXzP37PHk0DbSTMNPhnJD+Nn4G//O5E825bR6fAfHH43hobSBpgB9G9oWVl9+XgUaQ4yCnsX1H+l8DoaL9A==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.3.0.tgz", + "integrity": "sha512-NHODMBlj59xPAwl2BDiO2Mog6V+PrGRtBfWKqKRrs9MCqlSkIEb0Z/SfY7jW29ReHTDC/j+vwXhnZcXI3+3fbg==" }, "d3-format": { "version": "1.3.2", @@ -4909,9 +4945,9 @@ } }, "d3-path": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.7.tgz", - "integrity": "sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.8.tgz", + "integrity": "sha512-J6EfUNwcMQ+aM5YPOB8ZbgAZu6wc82f/0WFxrxwV6Ll8wBwLaHLKCqQ5Imub02JriCVVdPjgI+6P3a4EWJCxAg==" }, "d3-scale": { "version": "2.2.2", @@ -5044,8 +5080,7 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "deepmerge": { "version": "4.0.0", @@ -5244,19 +5279,18 @@ } }, "dmg-builder": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-21.1.1.tgz", - "integrity": "sha512-WsafJ+LkG20ddVfKfNlJC6AMRKTvLMJhAwAmBHzb+KWhMZVs9/3QY2yd2BIpvWYRfUD/lWd+LmclTNWw7540Cw==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-21.2.0.tgz", + "integrity": "sha512-9cJEclnGy7EyKFCoHDYDf54pub/t92CQapyiUxU0w9Bj2vUvfoDagP1PMiX4XD5rPp96141h9A+QN0OB4VgvQg==", "dev": true, "requires": { - "app-builder-lib": "~21.1.1", + "app-builder-lib": "~21.2.0", "bluebird-lst": "^1.0.9", - "builder-util": "~21.1.1", + "builder-util": "~21.2.0", "fs-extra": "^8.1.0", "iconv-lite": "^0.5.0", "js-yaml": "^3.13.1", - "parse-color": "^1.0.0", - "sanitize-filename": "^1.6.1" + "sanitize-filename": "^1.6.2" }, "dependencies": { "fs-extra": { @@ -5310,7 +5344,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, "requires": { "esutils": "^2.0.2" } @@ -5333,11 +5366,6 @@ "entities": "^1.1.1" } }, - "dom-walk": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" - }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", @@ -5479,22 +5507,22 @@ } }, "electron-builder": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-21.1.1.tgz", - "integrity": "sha512-4A3h0dhqSranoX7cM0eqkzABeHABH9Nch12003XIZ9MUPV4jL97nK5WBbbVG06qglYTV9x62XAqPPDS+KBOsEg==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-21.2.0.tgz", + "integrity": "sha512-x8EXrqFbAb2L3N22YlGar3dGh8vwptbB3ovo3OF6K7NTpcsmM2zEoJv7GhFyX73rNzSG2HaWpXwGAtOp2JWiEw==", "dev": true, "requires": { - "app-builder-lib": "21.1.1", + "app-builder-lib": "21.2.0", "bluebird-lst": "^1.0.9", - "builder-util": "21.1.1", + "builder-util": "21.2.0", "builder-util-runtime": "8.3.0", "chalk": "^2.4.2", - "dmg-builder": "21.1.1", + "dmg-builder": "21.2.0", "fs-extra": "^8.1.0", "is-ci": "^2.0.0", "lazy-val": "^1.0.4", - "read-config-file": "4.0.1", - "sanitize-filename": "^1.6.1", + "read-config-file": "5.0.0", + "sanitize-filename": "^1.6.2", "update-notifier": "^3.0.1", "yargs": "^13.3.0" }, @@ -5707,18 +5735,18 @@ } }, "electron-log": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-3.0.6.tgz", - "integrity": "sha512-osPLk8m9+Ylo0k/okevdHUGsKpCNGxg206TxG2Ch8slGvlTZLI0955Ig4e+nJ6fHVDxFMv5dWkn2y8hwi0aENg==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-3.0.7.tgz", + "integrity": "sha512-W5pjj9DtXjSHaJWH1VWSgBweJxeZ6OEBAIOzSbu6coKFYxXPGRyg9FAILYbnDt0iJT8r6YQqjEnYgmGJn/LoAg==" }, "electron-publish": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-21.1.1.tgz", - "integrity": "sha512-cM5XLFolIB5NnVpBKewcUM3Ggg+wm+LeKRYHjcB9ri58cbPKxaN+fRUXAZs3m1U9t7SIgjZy83sUSi3asxMXgQ==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-21.2.0.tgz", + "integrity": "sha512-mWavuoWJe87iaeKd0I24dNWIaR+0yRzshjNVqGyK019H766fsPWl3caQJnVKFaEyrZRP397v4JZVG0e7s16AxA==", "dev": true, "requires": { "bluebird-lst": "^1.0.9", - "builder-util": "~21.1.1", + "builder-util": "~21.2.0", "builder-util-runtime": "8.3.0", "chalk": "^2.4.2", "fs-extra": "^8.1.0", @@ -5740,12 +5768,113 @@ } }, "electron-reload": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/electron-reload/-/electron-reload-1.4.1.tgz", - "integrity": "sha512-DnQGcSUEfrrxImNymxJRQcJCYFIJgiO82tLL86NKwMIz5bLolpIZA7L4PwEjeSHnO3jTQgOTxA9dV76TkAvVcg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/electron-reload/-/electron-reload-1.5.0.tgz", + "integrity": "sha512-L9X6LzsL3Bt2j0eJ4/MBrI9Vt902KvVUtBB7J4qrL1A9sXqC2fE0lpvUAlOThpJYh6zWO1l86U/YiEN9bDURHw==", "dev": true, "requires": { - "chokidar": "^2.0.4" + "chokidar": "^3.0.2" + }, + "dependencies": { + "anymatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.0.3.tgz", + "integrity": "sha512-c6IvoeBECQlMVuYUjSwimnhmztImpErfxJzWZhIQinIvQWoGOnB0dLIgifbPHQt5heS6mNlaZG16f06H3C8t1g==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.0.2.tgz", + "integrity": "sha512-c4PR2egjNjI1um6bamCQ6bUNPDiyofNQruHvKgHQ4gDUP/ITSVSzNsiI5OWtHOsX323i5ha/kk4YmOZ1Ktg7KA==", + "dev": true, + "requires": { + "anymatch": "^3.0.1", + "braces": "^3.0.2", + "fsevents": "^2.0.6", + "glob-parent": "^5.0.0", + "is-binary-path": "^2.1.0", + "is-glob": "^4.0.1", + "normalize-path": "^3.0.0", + "readdirp": "^3.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.0.7.tgz", + "integrity": "sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "readdirp": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.1.1.tgz", + "integrity": "sha512-XXdSXZrQuvqoETj50+JAitxz1UPdt5dupjT6T5nVB+WvjMv2XKYj+s7hPeAVCXvmJrL36O4YYyWlIC3an2ePiQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.4" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } } }, "electron-store": { @@ -5787,13 +5916,13 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true }, "encodeurl": { "version": "1.0.2", @@ -5890,7 +6019,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz", "integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "ajv": "^6.10.0", @@ -5934,14 +6062,12 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -5950,7 +6076,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", - "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" @@ -5960,7 +6085,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", - "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -5968,14 +6092,12 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -5983,29 +6105,28 @@ "strip-json-comments": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", - "dev": true + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==" } } }, "eslint-config-airbnb": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-17.1.1.tgz", - "integrity": "sha512-xCu//8a/aWqagKljt+1/qAM62BYZeNq04HmdevG5yUGWpja0I/xhqd6GdLRch5oetEGFiJAnvtGuTEAese53Qg==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.0.0.tgz", + "integrity": "sha512-C9p7TGMuefhUWPuiObkfF9pytgAA2293bk1n0h7FdazazHNtzATTGkVv7V0gZt1/FTzdCfwWhjGSbRz/KR89og==", "dev": true, "requires": { - "eslint-config-airbnb-base": "^13.2.0", + "eslint-config-airbnb-base": "^14.0.0", "object.assign": "^4.1.0", "object.entries": "^1.1.0" } }, "eslint-config-airbnb-base": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.2.0.tgz", - "integrity": "sha512-1mg/7eoB4AUeB0X1c/ho4vb2gYkNH8Trr/EgCT/aGmKhhG+F6vF5s8+iRBlWAzFIAphxIdp3YfEKgEl0f9Xg+w==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz", + "integrity": "sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==", "dev": true, "requires": { - "confusing-browser-globals": "^1.0.5", + "confusing-browser-globals": "^1.0.7", "object.assign": "^4.1.0", "object.entries": "^1.1.0" } @@ -6333,9 +6454,9 @@ "dev": true }, "eslint-plugin-react": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.2.tgz", - "integrity": "sha512-jZdnKe3ip7FQOdjxks9XPN0pjUKZYq48OggNMd16Sk+8VXx6JOvXmlElxROCgp7tiUsTsze3jd78s/9AFJP2mA==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz", + "integrity": "sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==", "dev": true, "requires": { "array-includes": "^3.0.3", @@ -6361,9 +6482,9 @@ } }, "eslint-plugin-react-hooks": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.1.tgz", - "integrity": "sha512-wHhmGJyVuijnYIJXZJHDUF2WM+rJYTjulUTqF9k61d3BTk8etydz+M4dXUVH7M76ZRS85rqBTCx0Es/lLsrjnA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz", + "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==", "dev": true }, "eslint-rule-docs": { @@ -6386,7 +6507,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.0.tgz", "integrity": "sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==", - "dev": true, "requires": { "eslint-visitor-keys": "^1.0.0" } @@ -6394,14 +6514,12 @@ "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", - "dev": true + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==" }, "espree": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz", "integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==", - "dev": true, "requires": { "acorn": "^6.0.7", "acorn-jsx": "^5.0.0", @@ -6411,14 +6529,12 @@ "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, "requires": { "estraverse": "^4.0.0" } @@ -6427,7 +6543,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, "requires": { "estraverse": "^4.1.0" } @@ -6435,14 +6550,12 @@ "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, "etag": { "version": "1.8.1", @@ -6626,7 +6739,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, "requires": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -6763,6 +6875,15 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fastq": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", + "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "dev": true, + "requires": { + "reusify": "^1.0.0" + } + }, "faye-websocket": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", @@ -6889,15 +7010,14 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, "requires": { "flat-cache": "^2.0.1" } }, "file-loader": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.1.0.tgz", - "integrity": "sha512-ajDk1nlByoalZAGR4b0H6oD+EGlWnyW1qbSxzaUc7RFiqmn+RbXQQRbTc72jsiUIlVusJ4Et58ltds8ZwTfnAw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.2.0.tgz", + "integrity": "sha512-+xZnaK5R8kBJrHK0/6HRlrKNamvVS5rjyuju+rnyxRGuwUJwpAMsVzUl5dz6rK8brkzjV6JpcFNjp6NqV0g1OQ==", "dev": true, "requires": { "loader-utils": "^1.2.3", @@ -6905,9 +7025,9 @@ }, "dependencies": { "schema-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.0.1.tgz", - "integrity": "sha512-HJFKJ4JixDpRur06QHwi8uu2kZbng318ahWEKgBjc0ZklcE4FDvmm2wghb448q0IRaABxIESt8vqPFvwgMB80A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.1.0.tgz", + "integrity": "sha512-g6SViEZAfGNrToD82ZPUjq52KUPDYc+fN5+g6Euo5mLokl/9Yx14z0Cu4RR1m55HtBXejO0sBt+qw79axN+Fiw==", "dev": true, "requires": { "ajv": "^6.1.0", @@ -7019,7 +7139,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, "requires": { "flatted": "^2.0.0", "rimraf": "2.6.3", @@ -7029,8 +7148,7 @@ "flatted": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", - "dev": true + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==" }, "flush-write-stream": { "version": "1.1.1", @@ -7106,15 +7224,6 @@ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -7227,8 +7336,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "1.2.9", @@ -7865,8 +7973,7 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, "gauge": { "version": "2.7.4", @@ -7976,7 +8083,6 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -8013,15 +8119,6 @@ "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", "dev": true }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "global-dirs": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", @@ -8054,8 +8151,7 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "globby": { "version": "6.1.0", @@ -8528,124 +8624,23 @@ "integrity": "sha1-pls0RZrWNnrbs3B6gqPJ+RYWcDA=", "dev": true }, - "husky": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/husky/-/husky-3.0.1.tgz", - "integrity": "sha512-PXBv+iGKw23GHUlgELRlVX9932feFL407/wHFwtsGeArp0dDM4u+/QusSQwPKxmNgjpSL+ustbOdQ2jetgAZbA==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "cosmiconfig": "^5.2.1", - "execa": "^1.0.0", - "get-stdin": "^7.0.0", - "is-ci": "^2.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^4.2.0", - "please-upgrade-node": "^3.1.1", - "read-pkg": "^5.1.1", - "run-node": "^1.0.0", - "slash": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "get-stdin": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", - "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - } - }, - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "hyphenate-style-name": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz", - "integrity": "sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ==" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "hyphenate-style-name": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz", + "integrity": "sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", "dev": true, "requires": { "postcss": "^7.0.14" @@ -8675,14 +8670,12 @@ "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, "import-fresh": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", - "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -8730,11 +8723,16 @@ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", "dev": true }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -8743,8 +8741,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.5", @@ -8753,37 +8750,105 @@ "dev": true }, "inquirer": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", - "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", - "dev": true, + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.1.tgz", + "integrity": "sha512-uxNHBeQhRXIoHWTSNYUFhQVrHYFThIt6IVo2fFmSe8aBwdR3/w6b58hJpiL/fMukFkvGzjg+hSxFtwvVmKZmXw==", "requires": { - "ansi-escapes": "^3.2.0", + "ansi-escapes": "^4.2.1", "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", + "cli-cursor": "^3.1.0", "cli-width": "^2.0.0", "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", "run-async": "^2.2.0", "rxjs": "^6.4.0", - "string-width": "^2.1.0", + "string-width": "^4.1.0", "strip-ansi": "^5.1.0", "through": "^2.3.6" }, "dependencies": { + "ansi-escapes": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz", + "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==", + "requires": { + "type-fest": "^0.5.2" + } + }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "figures": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.0.0.tgz", + "integrity": "sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g==", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "string-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz", + "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^5.2.0" + } }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -9008,8 +9073,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-finite": { "version": "1.0.2", @@ -9023,14 +9087,12 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -9149,8 +9211,7 @@ "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" }, "is-regex": { "version": "1.0.4", @@ -9253,8 +9314,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { "version": "3.0.1", @@ -9289,7 +9349,6 @@ "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -9338,8 +9397,7 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" }, "json-stringify-safe": { "version": "5.0.1", @@ -9357,6 +9415,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, "requires": { "minimist": "^1.2.0" } @@ -9383,79 +9442,80 @@ } }, "jss": { - "version": "10.0.0-alpha.17", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.17.tgz", - "integrity": "sha512-egGIUg+YRu0+U+XXlD0gmVtU/gW5sn7+qmDv7opwK5s8emZBE/VoN55X6CaMrAa0kLeGMldnI43KOWea6M9/mA==", + "version": "10.0.0-alpha.23", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.23.tgz", + "integrity": "sha512-r3fg6nrNdqxhaE4s3ZkyEmpVTb2UUmSu0uhKrvfSAy+N45MmlLmhgyFFaUyJOvFJzm69XYXM2Q62VhGccV6qMA==", "requires": { "@babel/runtime": "^7.3.1", + "csstype": "^2.6.5", "is-in-browser": "^1.1.3", "tiny-warning": "^1.0.2" } }, "jss-plugin-camel-case": { - "version": "10.0.0-alpha.17", - "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.0.0-alpha.17.tgz", - "integrity": "sha512-aPY4kr6MwliH7KToLRzeSk1NxXUo9n7MQsAa0Hghwj01x9UnMkDkGAKENMKUtPjGkQZfiJpB9tTLFrSJ/6VrIQ==", + "version": "10.0.0-alpha.23", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.0.0-alpha.23.tgz", + "integrity": "sha512-QaXi/t4Efx0BhwbVf6GCcpn/IDAP9cK/GJoWBoAIVM9BAj7RXBU0UifFojRbeDGDtpf5djDWCOMviydYiWYYWg==", "requires": { "@babel/runtime": "^7.3.1", "hyphenate-style-name": "^1.0.3", - "jss": "10.0.0-alpha.17" + "jss": "10.0.0-alpha.23" } }, "jss-plugin-default-unit": { - "version": "10.0.0-alpha.17", - "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.0.0-alpha.17.tgz", - "integrity": "sha512-KQgiXczvzJ9AlFdD8NS7FZLub0NSctSrCA9Yi/GqdsfJg4ZCriU4DzIybCZBHCi/INFGJmLIESYWSxnuhAzgSQ==", + "version": "10.0.0-alpha.23", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.0.0-alpha.23.tgz", + "integrity": "sha512-XE4CcrQMF2rI6TL+/bJUDVlmgIqOax8uCPLZxZnqUFTbH0cM9f66OhRIe51yECfAb1nAiHalZtkUv2kfycLVjQ==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.0.0-alpha.17" + "jss": "10.0.0-alpha.23" } }, "jss-plugin-global": { - "version": "10.0.0-alpha.17", - "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.0.0-alpha.17.tgz", - "integrity": "sha512-WYxiwwI+CLk0ozW8loeceqXBAZXBMsLBEZeRwVf9WX+FljdJkGwVZpRCk6LBX4aXnqAGyKqCxIAIJ3KP2yBdEg==", + "version": "10.0.0-alpha.23", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.0.0-alpha.23.tgz", + "integrity": "sha512-uaoO4yp24dtvKiMd8fLzy2Of3rDSzA9e1y8mHw4vNDTPDSF39pYfpAxxnGnvRadsAVlZGgj4Ro+LveLz8ZUHgw==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.0.0-alpha.17" + "jss": "10.0.0-alpha.23" } }, "jss-plugin-nested": { - "version": "10.0.0-alpha.17", - "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.0.0-alpha.17.tgz", - "integrity": "sha512-onpFqv904KCujryf2t6IIV1/QoB7cSF7ojrd4UujcN5TPvYOvXF5bchi7jnHG5U0SLlRSDGMLJ9fhtoCknhEbw==", + "version": "10.0.0-alpha.23", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.0.0-alpha.23.tgz", + "integrity": "sha512-xHoBBUz9U8INvizthl0k9u79z+ObzY0HvzPy7+BKxySQzHSTLG40iRYizJo7Antq7uH8i8uI/5RgS/7dy+YVSQ==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.0.0-alpha.17", + "jss": "10.0.0-alpha.23", "tiny-warning": "^1.0.2" } }, "jss-plugin-props-sort": { - "version": "10.0.0-alpha.17", - "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.0.0-alpha.17.tgz", - "integrity": "sha512-KnbyrxCbtQTqpDx2mSZU/r/E5QnDPIVfIxRi8K+W/q4gZpomBvqWC+xgvAk9hbpmA6QBoQaOilV8o12w2IZ6fg==", + "version": "10.0.0-alpha.23", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.0.0-alpha.23.tgz", + "integrity": "sha512-/h6epoQ/ta61e6rG3/Pq47qPlg9YX5t2rSKJBLzaASEe/KfxjVvnbJKC8tE27lG6TjwbeWpKONuJfZxjWKLnDg==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.0.0-alpha.17" + "jss": "10.0.0-alpha.23" } }, "jss-plugin-rule-value-function": { - "version": "10.0.0-alpha.17", - "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.0.0-alpha.17.tgz", - "integrity": "sha512-8AuJB44Q+ehfkWVRi2XlRbUf6SrLmrHTa5EXd6dgQRCCRuvGmqX8Dl4fZvNeKRFjTLPZgzg9+31rqeOMhKa2vA==", + "version": "10.0.0-alpha.23", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.0.0-alpha.23.tgz", + "integrity": "sha512-N0g7x6RzeEj+GI5303JOUTyo5x7/F+0SRJv3R0lAUSS782mZipcvpFzHlEz3q5g+0t/bhbOLT6i0RYAhN3IW7g==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.0.0-alpha.17" + "jss": "10.0.0-alpha.23" } }, "jss-plugin-vendor-prefixer": { - "version": "10.0.0-alpha.17", - "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.0.0-alpha.17.tgz", - "integrity": "sha512-wDq9EL0QaoMGSGifPEBb+/SA9LBcqPEW0jpL9ht+Z2t+lV7NNz0j7uCEOuE6FvNWqHzUKTsiATs1rTHPkzNBEQ==", + "version": "10.0.0-alpha.23", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.0.0-alpha.23.tgz", + "integrity": "sha512-WtTXR+H1tGGhmEP3kqDawxnV1tbXboxtJ93A1O9p+7OLseafIaQoPkMPKEh5a+P4jzETIqmQoJJoG5KmT/Tgsg==", "requires": { "@babel/runtime": "^7.3.1", - "css-vendor": "^2.0.1", - "jss": "10.0.0-alpha.17" + "css-vendor": "^2.0.5", + "jss": "10.0.0-alpha.23" } }, "jsx-ast-utils": { @@ -9590,22 +9650,15 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" } }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, "lint-staged": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.2.0.tgz", - "integrity": "sha512-K/CQWcxYunc8lGMNTFvtI4+ybJcHW3K4Ghudz2OrJhIWdW/i1WWu9rGiVj4yJ0+D/xh8a08kp5slt89VZC9Eqg==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.2.1.tgz", + "integrity": "sha512-3lGgJfBddCy/WndKdNko+uJbwyYjBD1k+V+SA+phBYWzH265S95KQya/Wln/UL+hOjc7NcjtFYVCUWuAcqYHhg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -9613,8 +9666,8 @@ "cosmiconfig": "^5.2.1", "debug": "^4.1.1", "dedent": "^0.7.0", - "del": "^4.1.1", - "execa": "^2.0.1", + "del": "^5.0.0", + "execa": "^2.0.3", "listr": "^0.14.3", "log-symbols": "^3.0.0", "micromatch": "^4.0.2", @@ -9623,6 +9676,18 @@ "stringify-object": "^3.3.0" }, "dependencies": { + "@nodelib/fs.stat": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.1.tgz", + "integrity": "sha512-+RqhBlLn6YRBGOIoVYthsG0J9dfpO79eJyN7BYBkZJtfqrBwf2KK+rD/M/yjZR6WBmIhAgOV7S60eCgaSWtbFw==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -9641,6 +9706,28 @@ "ms": "^2.1.1" } }, + "del": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-5.0.0.tgz", + "integrity": "sha512-TfU3nUY0WDIhN18eq+pgpbLY9AfL5RfiE9czKaTSolc6aK7qASXfDErvYgjV1UqCR4sNXDoxO0/idPmhDUt2Sg==", + "dev": true, + "requires": { + "globby": "^10.0.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "rimraf": "^2.6.3" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, "execa": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/execa/-/execa-2.0.3.tgz", @@ -9658,6 +9745,20 @@ "strip-final-newline": "^2.0.0" } }, + "fast-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.0.4.tgz", + "integrity": "sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.1", + "@nodelib/fs.walk": "^1.2.1", + "glob-parent": "^5.0.0", + "is-glob": "^4.0.1", + "merge2": "^1.2.3", + "micromatch": "^4.0.2" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -9676,6 +9777,37 @@ "pump": "^3.0.0" } }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz", + "integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -9743,6 +9875,12 @@ "integrity": "sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg==", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -9912,6 +10050,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, "requires": { "big.js": "^5.2.2", "emojis-list": "^2.0.0", @@ -9959,12 +10098,6 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, - "lodash.tail": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", - "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=", - "dev": true - }, "lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", @@ -10281,8 +10414,7 @@ "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "mimic-response": { "version": "1.0.1", @@ -10290,14 +10422,6 @@ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "requires": { - "dom-walk": "^0.1.0" - } - }, "mini-css-extract-plugin": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz", @@ -10346,7 +10470,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -10354,7 +10477,8 @@ "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true }, "minimist-options": { "version": "3.0.2", @@ -10453,29 +10577,10 @@ } } }, - "mixin-object": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", - "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", - "dev": true, - "requires": { - "for-in": "^0.1.3", - "is-extendable": "^0.1.1" - }, - "dependencies": { - "for-in": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", - "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=", - "dev": true - } - } - }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" }, @@ -10483,8 +10588,7 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" } } }, @@ -10557,8 +10661,7 @@ "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, "negotiator": { "version": "0.6.2", @@ -10575,8 +10678,7 @@ "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node-forge": { "version": "0.7.5", @@ -11080,7 +11182,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -11102,12 +11203,6 @@ } } }, - "opencollective-postinstall": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", - "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", - "dev": true - }, "opener": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", @@ -11161,7 +11256,6 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", @@ -11277,15 +11371,15 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "package-json": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.4.0.tgz", - "integrity": "sha512-bd1T8OBG7hcvMd9c/udgv6u5v9wISP3Oyl9Cm7Weop8EFwrtcQDnS2sb6zhwqus2WslSr5wSTIPiTTpxxmPm7Q==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", "dev": true, "requires": { "got": "^9.6.0", - "registry-auth-token": "^3.4.0", + "registry-auth-token": "^4.0.0", "registry-url": "^5.0.0", - "semver": "^6.1.1" + "semver": "^6.2.0" } }, "pako": { @@ -11341,7 +11435,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "requires": { "callsites": "^3.0.0" } @@ -11360,23 +11453,6 @@ "safe-buffer": "^5.1.1" } }, - "parse-color": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz", - "integrity": "sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=", - "dev": true, - "requires": { - "color-convert": "~0.5.0" - }, - "dependencies": { - "color-convert": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", - "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=", - "dev": true - } - } - }, "parse-entities": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", @@ -11445,8 +11521,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { "version": "1.0.2", @@ -11457,8 +11532,7 @@ "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { "version": "1.0.6", @@ -12371,8 +12445,7 @@ "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, "prepend-http": { "version": "2.0.0", @@ -12414,7 +12487,8 @@ "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true }, "process-nextick-args": { "version": "2.0.1", @@ -12425,8 +12499,7 @@ "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" }, "progress-stream": { "version": "1.2.0", @@ -12643,40 +12716,35 @@ } }, "react": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", - "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.9.0.tgz", + "integrity": "sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.6" + "prop-types": "^15.6.2" } }, "react-dom": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", - "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==", + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.9.0.tgz", + "integrity": "sha512-YFT2rxO9hM70ewk9jq0y6sQk8cL02xm4+IzYBz75CQGlClQQ1Bxq0nhHF6OtSbit+AIahujJgb/CPRibFkMNJQ==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "scheduler": "^0.13.6" - } - }, - "react-hot-loader": { - "version": "4.12.8", - "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.12.8.tgz", - "integrity": "sha512-/Df2J3znMHzRzI6CW0dTOIWD2sjkVHxv56XCqujAo9mR+k2PVTiGjUgYBiGPGsix9zQzgCRfOKca93o9Zdj2vQ==", - "requires": { - "fast-levenshtein": "^2.0.6", - "global": "^4.3.0", - "hoist-non-react-statics": "^3.3.0", - "loader-utils": "^1.1.0", - "prop-types": "^15.6.1", - "react-lifecycles-compat": "^3.0.4", - "shallowequal": "^1.0.2", - "source-map": "^0.7.3" + "scheduler": "^0.15.0" + }, + "dependencies": { + "scheduler": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", + "integrity": "sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + } } }, "react-is": { @@ -12725,15 +12793,23 @@ } }, "react-test-renderer": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.8.6.tgz", - "integrity": "sha512-H2srzU5IWYT6cZXof6AhUcx/wEyJddQ8l7cLM/F7gDXYyPr4oq+vCIxJYXVGhId1J706sqziAjuOEjyNkfgoEw==", + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.9.0.tgz", + "integrity": "sha512-R62stB73qZyhrJo7wmCW9jgl/07ai+YzvouvCXIJLBkRlRqLx4j9RqcLEAfNfU3OxTGucqR2Whmn3/Aad6L3hQ==", "dev": true, "requires": { "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "react-is": "^16.8.6", - "scheduler": "^0.13.6" + "react-is": "^16.9.0", + "scheduler": "^0.15.0" + }, + "dependencies": { + "react-is": { + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz", + "integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==", + "dev": true + } } }, "react-transition-group": { @@ -12748,13 +12824,11 @@ } }, "read-config-file": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-4.0.1.tgz", - "integrity": "sha512-5caED3uo2IAZMPcbh/9hx/O29s2430RLxtnFDdzxpH/epEpawOrQnGBHueotIXUrGPPIgdNQN+S/CIp2WmiSfw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-5.0.0.tgz", + "integrity": "sha512-jIKUu+C84bfnKxyJ5j30CxCqgXWYjZLXuVE/NYlMEpeni+dhESgAeZOZd0JZbg1xTkMmnCdxksDoarkOyfEsOg==", "dev": true, "requires": { - "ajv": "^6.10.1", - "ajv-keywords": "^3.4.1", "dotenv": "^8.0.0", "dotenv-expand": "^5.1.0", "fs-extra": "^8.1.0", @@ -12902,9 +12976,9 @@ } }, "recharts": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-1.6.2.tgz", - "integrity": "sha512-NqVN8Hq5wrrBthTxQB+iCnZjup1dc+AYRIB6Q9ck9UjdSJTt4PbLepGpudQEYJEN5iIpP/I2vThC4uiTJa7xUQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-1.7.0.tgz", + "integrity": "sha512-rtP2Vg1/MCSK2UtE4aNFeG8qkl8V3N924dx3CJ3dYSzi/fYx2MTL1deCPqlH6i9rUuBQTDKGgWXtHazicMOptA==", "requires": { "classnames": "^2.2.5", "core-js": "^2.5.1", @@ -13038,8 +13112,7 @@ "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" }, "regexpu-core": { "version": "4.5.4", @@ -13056,12 +13129,12 @@ } }, "registry-auth-token": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", - "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.0.0.tgz", + "integrity": "sha512-lpQkHxd9UL6tb3k/aHAVfnVtn+Bcs9ob5InuFLLEDqSqeq+AljB8GZW9xY0x7F+xYwEcjKe07nyoxzEYz6yvkw==", "dev": true, "requires": { - "rc": "^1.1.6", + "rc": "^1.2.8", "safe-buffer": "^5.0.1" } }, @@ -13318,8 +13391,7 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, "resolve-url": { "version": "0.2.1", @@ -13358,6 +13430,12 @@ "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rgb-regex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", @@ -13380,7 +13458,6 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -13399,15 +13476,14 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, "requires": { "is-promise": "^2.1.0" } }, - "run-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", - "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", "dev": true }, "run-queue": { @@ -13460,13 +13536,12 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sanitize-filename": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.1.tgz", - "integrity": "sha1-YS2hyWRz+gLczaktzVtKsWSmdyo=", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.2.tgz", + "integrity": "sha512-cmTzND7RMxUB+f7gI+4+KAVHWEg0lfXvQJdko+FXDP5bNbGIdx4KMP5pX6lv5jfT9jSf6OBbjyxjFtZQwYA/ig==", "dev": true, "requires": { "truncate-utf8-bytes": "^1.0.0" @@ -13605,25 +13680,18 @@ } }, "sass-loader": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.1.0.tgz", - "integrity": "sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.2.0.tgz", + "integrity": "sha512-h8yUWaWtsbuIiOCgR9fd9c2lRXZ2uG+h8Dzg/AGNj+Hg/3TO8+BBAW9mEP+mh8ei+qBKqSJ0F1FLlYjNBc61OA==", "dev": true, "requires": { - "clone-deep": "^2.0.1", + "clone-deep": "^4.0.1", "loader-utils": "^1.0.1", - "lodash.tail": "^4.1.1", "neo-async": "^2.5.0", - "pify": "^3.0.0", + "pify": "^4.0.1", "semver": "^5.5.0" }, "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", @@ -13639,9 +13707,10 @@ "dev": true }, "scheduler": { - "version": "0.13.6", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", - "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", + "integrity": "sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg==", + "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -13695,9 +13764,9 @@ } }, "semver": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz", - "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "semver-compare": { "version": "1.0.0", @@ -13868,34 +13937,18 @@ } }, "shallow-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", - "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, "requires": { - "is-extendable": "^0.1.1", - "kind-of": "^5.0.0", - "mixin-object": "^2.0.1" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "kind-of": "^6.0.2" } }, - "shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, "requires": { "shebang-regex": "^1.0.0" } @@ -13903,8 +13956,7 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, "signal-exit": { "version": "3.0.2", @@ -13984,7 +14036,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", @@ -14170,9 +14221,9 @@ "dev": true }, "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-resolve": { "version": "0.5.2", @@ -14188,19 +14239,12 @@ } }, "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } } }, "source-map-url": { @@ -14248,9 +14292,9 @@ "dev": true }, "spdy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", - "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", + "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", "dev": true, "requires": { "debug": "^4.1.0", @@ -14317,13 +14361,19 @@ "util-deprecate": "^1.0.1" } }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + }, "string_decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "~5.2.0" } } } @@ -14374,8 +14424,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { "version": "1.16.1", @@ -14703,13 +14752,25 @@ "dev": true }, "style-loader": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", - "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.0.0.tgz", + "integrity": "sha512-B0dOCFwv7/eY31a5PCieNwMgMhVGFe9w+rh7s/Bx8kfFkrth9zfTZquoYvdw8URgiqxObQKcpW51Ugz1HjfdZw==", "dev": true, "requires": { - "loader-utils": "^1.1.0", - "schema-utils": "^1.0.0" + "loader-utils": "^1.2.3", + "schema-utils": "^2.0.1" + }, + "dependencies": { + "schema-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.1.0.tgz", + "integrity": "sha512-g6SViEZAfGNrToD82ZPUjq52KUPDYc+fN5+g6Euo5mLokl/9Yx14z0Cu4RR1m55HtBXejO0sBt+qw79axN+Fiw==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + } + } } }, "style-search": { @@ -15297,7 +15358,6 @@ "version": "5.4.1", "resolved": "https://registry.npmjs.org/table/-/table-5.4.1.tgz", "integrity": "sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w==", - "dev": true, "requires": { "ajv": "^6.9.1", "lodash": "^4.17.11", @@ -15308,14 +15368,12 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -15326,7 +15384,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -15470,55 +15527,49 @@ } }, "terser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.1.2.tgz", - "integrity": "sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.1.4.tgz", + "integrity": "sha512-+ZwXJvdSwbd60jG0Illav0F06GDJF0R4ydZ21Q3wGAFKoBGyJGo34F63vzJHgvYxc1ukOtIjvwEvl9MkjzM6Pg==", "dev": true, "requires": { "commander": "^2.20.0", "source-map": "~0.6.1", "source-map-support": "~0.5.12" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "terser-webpack-plugin": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz", - "integrity": "sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz", + "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==", "dev": true, "requires": { - "cacache": "^11.3.2", - "find-cache-dir": "^2.0.0", + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", "is-wsl": "^1.1.0", - "loader-utils": "^1.2.3", "schema-utils": "^1.0.0", "serialize-javascript": "^1.7.0", "source-map": "^0.6.1", - "terser": "^4.0.0", - "webpack-sources": "^1.3.0", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", "worker-farm": "^1.7.0" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } } } }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, "throttleit": { "version": "0.0.2", @@ -15529,8 +15580,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "0.2.3", @@ -15578,7 +15628,6 @@ "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, "requires": { "os-tmpdir": "~1.0.2" } @@ -15763,7 +15812,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, "requires": { "prelude-ls": "~1.1.2" } @@ -16181,14 +16229,12 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "v8-compile-cache": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", - "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", - "dev": true + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==" }, "validate-npm-package-license": { "version": "3.0.4", @@ -16405,36 +16451,42 @@ } }, "webpack": { - "version": "4.36.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.36.1.tgz", - "integrity": "sha512-Ej01/N9W8DVyhEpeQnbUdGvOECw0L46FxS12cCOs8gSK7bhUlrbHRnWkjiXckGlHjUrmL89kDpTRIkUk6Y+fKg==", + "version": "4.39.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.1.tgz", + "integrity": "sha512-/LAb2TJ2z+eVwisldp3dqTEoNhzp/TLCZlmZm3GGGAlnfIWDgOEE758j/9atklNLfRyhKbZTCOIoPqLJXeBLbQ==", "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", "@webassemblyjs/helper-module-context": "1.8.5", "@webassemblyjs/wasm-edit": "1.8.5", "@webassemblyjs/wasm-parser": "1.8.5", - "acorn": "^6.2.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", + "eslint-scope": "^4.0.3", "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", "schema-utils": "^1.0.0", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.1", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" }, "dependencies": { + "acorn": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", + "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==", + "dev": true + }, "enhanced-resolve": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", @@ -16501,13 +16553,23 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "dev": true + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } } } }, "webpack-bundle-analyzer": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.3.2.tgz", - "integrity": "sha512-7qvJLPKB4rRWZGjVp5U1KEjwutbDHSKboAl0IfafnrdXMrgC0tOtZbQD6Rw0u4cmpgRN4O02Fc0t8eAT+FgGzA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.4.1.tgz", + "integrity": "sha512-Bs8D/1zF+17lhqj2OYmzi7HEVYqEVxu7lCO9Ff8BwajenOU0vAwEoV8e4ICCPNZAcqR1PCR/7o2SkW+cnCmF0A==", "dev": true, "requires": { "acorn": "^6.0.7", @@ -16519,10 +16581,18 @@ "express": "^4.16.3", "filesize": "^3.6.1", "gzip-size": "^5.0.0", - "lodash": "^4.17.10", + "lodash": "^4.17.15", "mkdirp": "^0.5.1", "opener": "^1.5.1", "ws": "^6.0.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + } } }, "webpack-cli": { @@ -16756,9 +16826,9 @@ } }, "webpack-dev-server": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.7.2.tgz", - "integrity": "sha512-mjWtrKJW2T9SsjJ4/dxDC2fkFVUw8jlpemDERqV0ZJIkjjjamR2AbQlr3oz+j4JLhYCHImHnXZK5H06P2wvUew==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.8.0.tgz", + "integrity": "sha512-Hs8K9yI6pyMvGkaPTeTonhD6JXVsigXDApYk9JLW4M7viVBspQvb1WdAcWxqtmttxNW4zf2UFLsLNe0y87pIGQ==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -16774,23 +16844,25 @@ "import-local": "^2.0.0", "internal-ip": "^4.3.0", "ip": "^1.1.5", + "is-absolute-url": "^3.0.0", "killable": "^1.0.1", "loglevel": "^1.6.3", "opn": "^5.5.0", "p-retry": "^3.0.1", - "portfinder": "^1.0.20", + "portfinder": "^1.0.21", "schema-utils": "^1.0.0", "selfsigned": "^1.10.4", - "semver": "^6.1.1", + "semver": "^6.3.0", "serve-index": "^1.9.1", "sockjs": "0.3.19", "sockjs-client": "1.3.0", - "spdy": "^4.0.0", + "spdy": "^4.0.1", "strip-ansi": "^3.0.1", "supports-color": "^6.1.0", "url": "^0.11.0", "webpack-dev-middleware": "^3.7.0", "webpack-log": "^2.0.0", + "ws": "^6.2.1", "yargs": "12.0.5" }, "dependencies": { @@ -16809,6 +16881,12 @@ "ms": "^2.1.1" } }, + "is-absolute-url": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.0.tgz", + "integrity": "sha512-3OkP8XrM2Xq4/IxsJnClfMp3OaM3TAatLPLKPeWcxLBTrpe6hihwtX+XZfJTcXg/FTRi4qjy0y/C5qiyNxY24g==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -16907,7 +16985,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -16939,8 +17016,7 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, "worker-farm": { "version": "1.7.0", @@ -17001,14 +17077,12 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, "requires": { "mkdirp": "^0.5.1" } diff --git a/package.json b/package.json index f54a3293..7d89f61f 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "luna", "productName": "luna", - "version": "3.2.5", + "version": "3.3.0", "description": "npm desktop manager for handling npm dependencies. Supported platforms: OS X Windows and Linux. Build on Electron", "scripts": { "build": "concurrently \"npm run build-main\" \"npm run build-renderer\"", @@ -24,7 +24,7 @@ "prestart": "npm run build", "start": "cross-env NODE_ENV=production electron ./app/main.prod.js", "start-main-dev": "cross-env HOT=1 NODE_ENV=development electron -r @babel/register ./app/main.dev.js", - "start-renderer-dev": "cross-env NODE_ENV=development webpack-dev-server --client-log-level error --config ./configs/webpack.config.renderer.dev.babel.js", + "start-renderer-dev": "cross-env NODE_ENV=development webpack-dev-server --config configs/webpack.config.renderer.dev.babel.js", "test": "cross-env NODE_ENV=test BABEL_DISABLE_CACHE=1 jest" }, "lint-staged": { @@ -102,22 +102,10 @@ "type": "git", "url": "git+https://github.com/rvpanoz/luna.git" }, - "author": { - "name": "rvpanoz", - "email": "rvpanoz@gmail.com", - "url": "https://github.com/rvpanoz" - }, + "author": "rvpanoz (https://github.com/rvpanoz)", "contributors": [ - { - "name": "Arvanitis Panagiotis", - "email": "rvpanoz@gmail.com", - "url": "https://github.com/rvpanoz" - }, - { - "name": "Livas Dimitris", - "email": "dlivas@agileactors.com", - "url": "https://github.com/dlivas" - } + "Arvanitis Panagiotis (https://github.com/rvpanoz)", + "Livas Dimitris (https://github.com/dlivas)" ], "license": "GPL-3.0", "bugs": { @@ -164,15 +152,14 @@ "concurrently": "^4.1.0", "cross-env": "^5.2.0", "cross-spawn": "^6.0.5", - "css-loader": "^3.1.0", + "css-loader": "^3.2.0", "detect-port": "^1.3.0", "devtron": "^1.4.0", "electron": "^4.2.6", - "electron-builder": "^21.1.1", + "electron-builder": "^21.2.0", "electron-devtools-installer": "^2.2.4", - "electron-reload": "^1.4.0", - "eslint": "^6.1.0", - "eslint-config-airbnb": "^17.1.0", + "electron-reload": "^1.5.0", + "eslint-config-airbnb": "^18.0.0", "eslint-config-prettier": "^6.0.0", "eslint-formatter-pretty": "^2.1.1", "eslint-import-resolver-webpack": "^0.11.1", @@ -181,61 +168,62 @@ "eslint-plugin-jsx-a11y": "^6.2.1", "eslint-plugin-prettier": "^3.1.0", "eslint-plugin-promise": "^4.1.1", - "eslint-plugin-react": "^7.13.0", - "eslint-plugin-react-hooks": "^1.6.0", + "eslint-plugin-react": "^7.14.3", + "eslint-plugin-react-hooks": "^1.7.0", "fbjs-scripts": "^1.2.0", - "file-loader": "^4.1.0", - "husky": "^3.0.1", + "file-loader": "^4.2.0", + "husky": "^3.0.3", "identity-obj-proxy": "^3.0.0", - "lint-staged": "^9.2.0", + "lint-staged": "^9.2.1", "mini-css-extract-plugin": "^0.8.0", "node-sass": "^4.10.0", "optimize-css-assets-webpack-plugin": "^5.0.1", "prettier": "^1.16.4", - "react-test-renderer": "^16.8.6", + "react-test-renderer": "^16.9.0", "redux-logger": "^3.0.6", "rimraf": "^2.6.3", - "sass-loader": "^7.1.0", + "sass-loader": "^7.2.0", "spectron": "^7.0.0", - "style-loader": "^0.23.1", + "style-loader": "^1.0.0", "stylelint": "^10.1.0", "stylelint-config-prettier": "^5.2.0", "stylelint-config-standard": "^18.3.0", - "terser-webpack-plugin": "^1.2.3", + "terser-webpack-plugin": "^1.4.1", "url-loader": "^2.1.0", - "webpack": "^4.36.1", - "webpack-bundle-analyzer": "^3.1.0", + "webpack": "^4.39.1", + "webpack-bundle-analyzer": "^3.4.1", "webpack-cli": "^3.3.4", - "webpack-dev-server": "^3.7.1", + "webpack-dev-server": "^3.8.0", "webpack-merge": "^4.2.1" }, "dependencies": { - "@material-ui/core": "^4.2.1", + "@material-ui/core": "^4.3.2", "@material-ui/icons": "^4.2.1", - "animejs": "^3.0.1", + "animejs": "^3.1.0", "chalk": "^2.4.2", "classnames": "^2.2.6", - "core-js": "^3.1.4", + "core-js": "^3.2.0", "date-fns": "^1.30.1", "electron-debug": "^3.0.1", - "electron-log": "^3.0.6", + "electron-log": "^3.0.7", "electron-store": "^4.0.0", + "eslint": "^6.1.0", "lock-verify": "^2.1.0", "material-design-icons": "^3.0.1", "prop-types": "^15.7.2", "ramda": "^0.26.1", - "react": "^16.8.6", - "react-dom": "^16.8.6", - "react-hot-loader": "^4.12.8", + "react": "^16.9.0", + "react-dom": "^16.9.0", "react-redux": "^7.1.0", - "recharts": "^1.6.2", + "recharts": "^1.7.0", "redux": "^4.0.4", "redux-observable": "^1.1.0", "redux-react-hook": "^3.3.2", "rxjs": "^6.4.0", - "semver": "^6.2.0", - "source-map-support": "^0.5.12", - "typeface-roboto": "0.0.75" + "semver": "^6.3.0", + "source-map-support": "^0.5.13", + "typeface-roboto": "0.0.75", + "uuid": "^3.3.2" }, "devEngines": { "node": ">=8.x",