diff --git a/.babelrc b/.babelrc index facd1809..5ae6451c 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,3 @@ { - "presets": ["es2015", "react"] -} \ No newline at end of file + "presets": ["react", "latest", "stage-2"] +} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..91f52e05 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,25 @@ +module.exports = { + "env": { + "es6": true, + "browser": true + }, + "extends": "airbnb", + "parserOptions": { + "ecmaVersion": 7, + "ecmaFeatures": { + "experimentalObjectRestSpread": true, + "jsx": true + }, + "sourceType": "module" + }, + "parser": "babel-eslint", + rules: { + "comma-dangle": [2, "only-multiline"], + "max-len": [1, {"code": 140}], + "no-continue": [0], + "no-plusplus": [0], + "space-before-function-paren": [2, "always"], + "import/no-extraneous-dependencies": [2, {"devDependencies": true}], + "react/jsx-filename-extension": ["error", {"extensions": [".js"]}] + }, +}; diff --git a/.travis.yml b/.travis.yml index 29a568b7..c61ae35d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,3 +7,5 @@ node_js: before_script: - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start +script: npm run test:full +cache: yarn diff --git a/eslint.json b/eslint.json deleted file mode 100644 index 2035fb08..00000000 --- a/eslint.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "env": { - "browser": true, - "node": true - }, - "rules": { - "quotes": 0, - "no-comma-dangle": 2, - "no-underscore-dangle": 0, - "curly": 0, - "strict": 0, - "no-use-before-define": 0, - "no-cond-assign": 0, - "consistent-return": 0, - "new-cap": 0, - "no-unused-vars": 0 - } -} diff --git a/lib/components/Modal.js b/lib/components/Modal.js index 61e6de59..2545c4fc 100644 --- a/lib/components/Modal.js +++ b/lib/components/Modal.js @@ -1,34 +1,22 @@ -var React = require('react'); -var ReactDOM = require('react-dom'); -var ExecutionEnvironment = require('exenv'); -var ModalPortal = React.createFactory(require('./ModalPortal')); -var ariaAppHider = require('../helpers/ariaAppHider'); -var elementClass = require('element-class'); -var renderSubtreeIntoContainer = require("react-dom").unstable_renderSubtreeIntoContainer; -var Assign = require('lodash.assign'); - -var SafeHTMLElement = ExecutionEnvironment.canUseDOM ? window.HTMLElement : {}; -var AppElement = ExecutionEnvironment.canUseDOM ? document.body : {appendChild: function() {}}; - -function getParentElement(parentSelector) { +import React, { Component } from 'react'; +import ReactDOM from 'react-dom'; +import ExecutionEnvironment from 'exenv'; +import elementClass from 'element-class'; +import ModalPortal from './ModalPortal'; +import ariaAppHider from '../helpers/ariaAppHider'; + +const renderSubtreeIntoContainer = ReactDOM.unstable_renderSubtreeIntoContainer; + +const SafeHTMLElement = ExecutionEnvironment.canUseDOM ? window.HTMLElement : {}; + +function getParentElement (parentSelector) { return parentSelector(); } -var Modal = React.createClass({ - - displayName: 'Modal', - statics: { - setAppElement: function(element) { - AppElement = ariaAppHider.setElement(element); - }, - injectCSS: function() { - "production" !== process.env.NODE_ENV - && console.warn('React-Modal: injectCSS has been deprecated ' + - 'and no longer has any effect. It will be removed in a later version'); - } - }, +export default class Modal extends Component { - propTypes: { + /* eslint-disable react/no-unused-prop-types */ + static propTypes = { isOpen: React.PropTypes.bool.isRequired, style: React.PropTypes.shape({ content: React.PropTypes.object, @@ -44,52 +32,86 @@ var Modal = React.createClass({ parentSelector: React.PropTypes.func, role: React.PropTypes.string, contentLabel: React.PropTypes.string.isRequired - }, - - getDefaultProps: function () { - return { - isOpen: false, - portalClassName: 'ReactModalPortal', - ariaHideApp: true, - closeTimeoutMS: 0, - shouldCloseOnOverlayClick: true, - parentSelector: function () { return document.body; } - }; - }, - - componentDidMount: function() { + }; + /* eslint-enable react/no-unused-prop-types */ + + static defaultProps = { + isOpen: false, + portalClassName: 'ReactModalPortal', + ariaHideApp: true, + closeTimeoutMS: 0, + shouldCloseOnOverlayClick: true, + parentSelector () { return document.body; } + }; + + static defaultStyles = { + overlay: { + position: 'fixed', + top: 0, + left: 0, + right: 0, + bottom: 0, + backgroundColor: 'rgba(255, 255, 255, 0.75)' + }, + content: { + position: 'absolute', + top: '40px', + left: '40px', + right: '40px', + bottom: '40px', + border: '1px solid #ccc', + background: '#fff', + overflow: 'auto', + WebkitOverflowScrolling: 'touch', + borderRadius: '4px', + outline: 'none', + padding: '20px' + } + }; + + static setAppElement (element) { + ariaAppHider.setElement(element); + } + + static injectCSS () { + return process.env.NODE_ENV !== 'production' + && console.warn('React-Modal: injectCSS has been deprecated ' + + 'and no longer has any effect. It will be removed in a later version'); + } + + componentDidMount () { this.node = document.createElement('div'); this.node.className = this.props.portalClassName; - var parent = getParentElement(this.props.parentSelector); + const parent = getParentElement(this.props.parentSelector); parent.appendChild(this.node); this.renderPortal(this.props); - }, + } - componentWillReceiveProps: function(newProps) { - var currentParent = getParentElement(this.props.parentSelector); - var newParent = getParentElement(newProps.parentSelector); + componentWillReceiveProps (newProps) { + const currentParent = getParentElement(this.props.parentSelector); + const newParent = getParentElement(newProps.parentSelector); - if(newParent !== currentParent) { + if (newParent !== currentParent) { currentParent.removeChild(this.node); newParent.appendChild(this.node); } this.renderPortal(newProps); - }, + } - componentWillUnmount: function() { + componentWillUnmount () { if (this.props.ariaHideApp) { ariaAppHider.show(this.props.appElement); } ReactDOM.unmountComponentAtNode(this.node); - var parent = getParentElement(this.props.parentSelector); + const parent = getParentElement(this.props.parentSelector); parent.removeChild(this.node); elementClass(document.body).remove('ReactModal__Body--open'); - }, + } - renderPortal: function(props) { + renderPortal (props) { if (props.isOpen) { elementClass(document.body).add('ReactModal__Body--open'); } else { @@ -100,37 +122,14 @@ var Modal = React.createClass({ ariaAppHider.toggle(props.isOpen, props.appElement); } - this.portal = renderSubtreeIntoContainer(this, ModalPortal(Assign({}, props, {defaultStyles: Modal.defaultStyles})), this.node); - }, - - render: function () { - return React.DOM.noscript(); + this.portal = renderSubtreeIntoContainer(this, + , this.node); } -}); - -Modal.defaultStyles = { - overlay: { - position : 'fixed', - top : 0, - left : 0, - right : 0, - bottom : 0, - backgroundColor : 'rgba(255, 255, 255, 0.75)' - }, - content: { - position : 'absolute', - top : '40px', - left : '40px', - right : '40px', - bottom : '40px', - border : '1px solid #ccc', - background : '#fff', - overflow : 'auto', - WebkitOverflowScrolling : 'touch', - borderRadius : '4px', - outline : 'none', - padding : '20px' + + render () { + return null; } } - -module.exports = Modal diff --git a/lib/components/ModalPortal.js b/lib/components/ModalPortal.js index e7d056a0..750b95dd 100644 --- a/lib/components/ModalPortal.js +++ b/lib/components/ModalPortal.js @@ -1,11 +1,16 @@ -var React = require('react'); -var div = React.DOM.div; -var focusManager = require('../helpers/focusManager'); -var scopeTab = require('../helpers/scopeTab'); -var Assign = require('lodash.assign'); +import React, { Component, PropTypes } from 'react'; +import Assign from 'lodash.assign'; +import scopeTab from '../helpers/scopeTab'; +import { + returnFocus, + setupScopedFocus, + teardownScopedFocus, + markForFocusLater +} from '../helpers/focusManager'; + // so that our CSS is statically analyzable -var CLASS_NAMES = { +const CLASS_NAMES = { overlay: { base: 'ReactModal__Overlay', afterOpen: 'ReactModal__Overlay--after-open', @@ -18,40 +23,58 @@ var CLASS_NAMES = { } }; -var ModalPortal = module.exports = React.createClass({ - - displayName: 'ModalPortal', - shouldClose: null, +export default class ModalPortal extends Component { + static propTypes = { + isOpen: PropTypes.bool.isRequired, + onAfterOpen: PropTypes.func, + closeTimeoutMS: PropTypes.number, + shouldCloseOnOverlayClick: PropTypes.bool, + onRequestClose: PropTypes.func, + className: PropTypes.string, + overlayClassName: PropTypes.string, + defaultStyles: PropTypes.shape({ + content: PropTypes.object, + overlay: PropTypes.object + }), + style: PropTypes.shape({ + content: PropTypes.object, + overlay: PropTypes.object + }), + role: PropTypes.string, + children: PropTypes.node, + contentLabel: PropTypes.string + }; + + static defaultProps = { + style: { + overlay: {}, + content: {} + } + }; - getDefaultProps: function() { - return { - style: { - overlay: {}, - content: {} - } - }; - }, + static afterClose () { + returnFocus(); + teardownScopedFocus(); + } - getInitialState: function() { - return { + constructor () { + super(); + this.state = { afterOpen: false, beforeClose: false }; - }, + this.shouldClose = null; + } - componentDidMount: function() { + componentDidMount () { // Focus needs to be set when mounting and already open if (this.props.isOpen) { this.setFocusAfterRender(true); this.open(); } - }, - - componentWillUnmount: function() { - clearTimeout(this.closeTimer); - }, + } - componentWillReceiveProps: function(newProps) { + componentWillReceiveProps (newProps) { // Focus only needs to be set once when the modal is being opened if (!this.props.isOpen && newProps.isOpen) { this.setFocusAfterRender(true); @@ -59,153 +82,159 @@ var ModalPortal = module.exports = React.createClass({ } else if (this.props.isOpen && !newProps.isOpen) { this.close(); } - }, + } - componentDidUpdate: function () { + componentDidUpdate () { if (this.focusAfterRender) { this.focusContent(); this.setFocusAfterRender(false); } - }, + } + + componentWillUnmount () { + clearTimeout(this.closeTimer); + } - setFocusAfterRender: function (focus) { + setFocusAfterRender (focus) { this.focusAfterRender = focus; - }, + } - open: function() { + open () { if (this.state.afterOpen && this.state.beforeClose) { clearTimeout(this.closeTimer); this.setState({ beforeClose: false }); } else { - focusManager.setupScopedFocus(this.node); - focusManager.markForFocusLater(); - this.setState({isOpen: true}, function() { - this.setState({afterOpen: true}); + setupScopedFocus(this.node); + markForFocusLater(); + this.setState({ isOpen: true }, () => { + this.setState({ afterOpen: true }); if (this.props.isOpen && this.props.onAfterOpen) { this.props.onAfterOpen(); } - }.bind(this)); + }); } - }, + } - close: function() { - if (this.props.closeTimeoutMS > 0) + close () { + if (this.props.closeTimeoutMS > 0) { this.closeWithTimeout(); - else + } else { this.closeWithoutTimeout(); - }, + } + } - focusContent: function() { + focusContent () { // Don't steal focus from inner elements if (!this.contentHasFocus()) { - this.refs.content.focus(); + this.content.focus(); } - }, + } - closeWithTimeout: function() { - this.setState({beforeClose: true}, function() { + closeWithTimeout () { + this.setState({ beforeClose: true }, () => { this.closeTimer = setTimeout(this.closeWithoutTimeout, this.props.closeTimeoutMS); - }.bind(this)); - }, + }); + } - closeWithoutTimeout: function() { + closeWithoutTimeout () { this.setState({ beforeClose: false, isOpen: false, afterOpen: false, }, this.afterClose); - }, - - afterClose: function() { - focusManager.returnFocus(); - focusManager.teardownScopedFocus(); - }, + } - handleKeyDown: function(event) { - if (event.keyCode == 9 /*tab*/) scopeTab(this.refs.content, event); - if (event.keyCode == 27 /*esc*/) { + handleKeyDown = (event) => { + if (event.keyCode === 9 /* tab*/) scopeTab(this.content, event); + if (event.keyCode === 27 /* esc*/) { event.preventDefault(); this.requestClose(event); } - }, + } - handleOverlayMouseDown: function(event) { + handleOverlayMouseDown = () => { if (this.shouldClose === null) { this.shouldClose = true; } - }, + } - handleOverlayMouseUp: function(event) { + handleOverlayMouseUp = (event) => { if (this.shouldClose && this.props.shouldCloseOnOverlayClick) { - if (this.ownerHandlesClose()) + if (this.ownerHandlesClose()) { this.requestClose(event); - else + } else { this.focusContent(); + } } this.shouldClose = null; - }, + } - handleContentMouseDown: function(event) { + handleContentMouseDown = () => { this.shouldClose = false; - }, + } - handleContentMouseUp: function(event) { + handleContentMouseUp = () => { this.shouldClose = false; - }, + } - requestClose: function(event) { - if (this.ownerHandlesClose()) + requestClose (event) { + if (this.ownerHandlesClose()) { this.props.onRequestClose(event); - }, + } + } - ownerHandlesClose: function() { + ownerHandlesClose () { return this.props.onRequestClose; - }, + } - shouldBeClosed: function() { + shouldBeClosed () { return !this.props.isOpen && !this.state.beforeClose; - }, + } - contentHasFocus: function() { - return document.activeElement === this.refs.content || this.refs.content.contains(document.activeElement); - }, + contentHasFocus () { + return document.activeElement === this.content || this.content.contains(document.activeElement); + } - buildClassName: function(which, additional) { - var className = CLASS_NAMES[which].base; - if (this.state.afterOpen) - className += ' '+CLASS_NAMES[which].afterOpen; - if (this.state.beforeClose) - className += ' '+CLASS_NAMES[which].beforeClose; - return additional ? className + ' ' + additional : className; - }, + buildClassName (which, additional) { + let className = CLASS_NAMES[which].base; + if (this.state.afterOpen) { className += ` ${CLASS_NAMES[which].afterOpen}`; } + if (this.state.beforeClose) { + className += ` ${CLASS_NAMES[which].beforeClose}`; + } + return additional ? `${className} ${additional}` : className; + } - render: function() { - var contentStyles = (this.props.className) ? {} : this.props.defaultStyles.content; - var overlayStyles = (this.props.overlayClassName) ? {} : this.props.defaultStyles.overlay; - - return this.shouldBeClosed() ? div() : ( - div({ - ref: "overlay", - className: this.buildClassName('overlay', this.props.overlayClassName), - style: Assign({}, overlayStyles, this.props.style.overlay || {}), - onMouseDown: this.handleOverlayMouseDown, - onMouseUp: this.handleOverlayMouseUp - }, - div({ - ref: "content", - style: Assign({}, contentStyles, this.props.style.content || {}), - className: this.buildClassName('content', this.props.className), - tabIndex: "-1", - onKeyDown: this.handleKeyDown, - onMouseDown: this.handleContentMouseDown, - onMouseUp: this.handleContentMouseUp, - role: this.props.role, - "aria-label": this.props.contentLabel - }, - this.props.children - ) - ) + render () { + const contentStyles = (this.props.className) ? {} : this.props.defaultStyles.content; + const overlayStyles = (this.props.overlayClassName) ? {} : this.props.defaultStyles.overlay; + + // Disabling this rule is okay, since we know what is going on here, that being said + // longterm we should probably do this better. + /* eslint-disable jsx-a11y/no-static-element-interactions */ + return this.shouldBeClosed() ?
: ( +
{ this.overlay = c; }} + className={this.buildClassName('overlay', this.props.overlayClassName)} + style={Assign({}, overlayStyles, this.props.style.overlay || {})} + onMouseDown={this.handleOverlayMouseDown} + onMouseUp={this.handleOverlayMouseUp} + > +
{ this.content = c; }} + style={Assign({}, contentStyles, this.props.style.content || {})} + className={this.buildClassName('content', this.props.className)} + tabIndex={-1} + onKeyDown={this.handleKeyDown} + onMouseDown={this.handleContentMouseDown} + onMouseUp={this.handleContentMouseUp} + role={this.props.role} + aria-label={this.props.contentLabel} + > + {this.props.children} +
+
); + /* eslint-enable jsx-a11y/no-static-element-interactions */ } -}); +} diff --git a/lib/helpers/ariaAppHider.js b/lib/helpers/ariaAppHider.js index 05b4c128..80557064 100644 --- a/lib/helpers/ariaAppHider.js +++ b/lib/helpers/ariaAppHider.js @@ -1,38 +1,39 @@ -var _element = typeof document !== 'undefined' ? document.body : null; +let globalElement = typeof document !== 'undefined' ? document.body : null; -function setElement(element) { - if (typeof element === 'string') { - var el = document.querySelectorAll(element); - element = 'length' in el ? el[0] : el; +function setElement (element) { + let newElement = element; + if (typeof newElement === 'string') { + const el = document.querySelectorAll(element); + newElement = 'length' in el ? el[0] : el; } - _element = element || _element; - return _element; + globalElement = newElement || globalElement; + return globalElement; } -function hide(appElement) { - validateElement(appElement); - (appElement || _element).setAttribute('aria-hidden', 'true'); +function validateElement (appElement) { + if (!appElement && !globalElement) { + throw new Error('react-modal: You must set an element with `Modal.setAppElement(el)` to make this accessible'); + } } -function show(appElement) { +function hide (appElement) { validateElement(appElement); - (appElement || _element).removeAttribute('aria-hidden'); + (appElement || globalElement).setAttribute('aria-hidden', 'true'); } -function toggle(shouldHide, appElement) { - if (shouldHide) - hide(appElement); - else - show(appElement); +function show (appElement) { + validateElement(appElement); + (appElement || globalElement).removeAttribute('aria-hidden'); } -function validateElement(appElement) { - if (!appElement && !_element) - throw new Error('react-modal: You must set an element with `Modal.setAppElement(el)` to make this accessible'); +function toggle (shouldHide, appElement) { + if (shouldHide) { + hide(appElement); + } else { show(appElement); } } -function resetForTesting() { - _element = document.body; +function resetForTesting () { + globalElement = document.body; } exports.toggle = toggle; diff --git a/lib/helpers/focusManager.js b/lib/helpers/focusManager.js index 548f69db..8d711d21 100644 --- a/lib/helpers/focusManager.js +++ b/lib/helpers/focusManager.js @@ -1,13 +1,14 @@ -var findTabbable = require('../helpers/tabbable'); -var modalElement = null; -var focusLaterElement = null; -var needToFocus = false; +import findTabbable from './tabbable'; -function handleBlur(event) { +let modalElement = null; +let focusLaterElement = null; +let needToFocus = false; + +function handleBlur () { needToFocus = true; } -function handleFocus(event) { +function handleFocus () { if (needToFocus) { needToFocus = false; if (!modalElement) { @@ -15,33 +16,33 @@ function handleFocus(event) { } // need to see how jQuery shims document.on('focusin') so we don't need the // setTimeout, firefox doesn't support focusin, if it did, we could focus - // the element outside of a setTimeout. Side-effect of this implementation - // is that the document.body gets focus, and then we focus our element right + // the element outside of a setTimeout. Side-effect of this implementation + // is that the document.body gets focus, and then we focus our element right // after, seems fine. - setTimeout(function() { - if (modalElement.contains(document.activeElement)) + setTimeout(() => { + if (modalElement.contains(document.activeElement)) { return; - var el = (findTabbable(modalElement)[0] || modalElement); + } + const el = (findTabbable(modalElement)[0] || modalElement); el.focus(); }, 0); } } -exports.markForFocusLater = function() { +export function markForFocusLater () { focusLaterElement = document.activeElement; -}; +} -exports.returnFocus = function() { +export function returnFocus () { try { focusLaterElement.focus(); - } - catch (e) { - console.warn('You tried to return focus to '+focusLaterElement+' but it is not in the DOM anymore'); + } catch (e) { + console.warn(`You tried to return focus to ${focusLaterElement} but it is not in the DOM anymore`); } focusLaterElement = null; -}; +} -exports.setupScopedFocus = function(element) { +export function setupScopedFocus (element) { modalElement = element; if (window.addEventListener) { @@ -51,9 +52,9 @@ exports.setupScopedFocus = function(element) { window.attachEvent('onBlur', handleBlur); document.attachEvent('onFocus', handleFocus); } -}; +} -exports.teardownScopedFocus = function() { +export function teardownScopedFocus () { modalElement = null; if (window.addEventListener) { @@ -63,6 +64,4 @@ exports.teardownScopedFocus = function() { window.detachEvent('onBlur', handleBlur); document.detachEvent('onFocus', handleFocus); } -}; - - +} diff --git a/lib/helpers/scopeTab.js b/lib/helpers/scopeTab.js index d368bd8f..8df67faf 100644 --- a/lib/helpers/scopeTab.js +++ b/lib/helpers/scopeTab.js @@ -1,19 +1,19 @@ -var findTabbable = require('../helpers/tabbable'); +import findTabbable from './tabbable'; -module.exports = function(node, event) { - var tabbable = findTabbable(node); +export default function scopeTab (node, event) { + const tabbable = findTabbable(node); if (!tabbable.length) { - event.preventDefault(); - return; + event.preventDefault(); + return; } - var finalTabbable = tabbable[event.shiftKey ? 0 : tabbable.length - 1]; - var leavingFinalTabbable = ( + const finalTabbable = tabbable[event.shiftKey ? 0 : tabbable.length - 1]; + const leavingFinalTabbable = ( finalTabbable === document.activeElement || // handle immediate shift+tab after opening with mouse node === document.activeElement ); if (!leavingFinalTabbable) return; event.preventDefault(); - var target = tabbable[event.shiftKey ? tabbable.length - 1 : 0]; + const target = tabbable[event.shiftKey ? tabbable.length - 1 : 0]; target.focus(); -}; +} diff --git a/lib/helpers/tabbable.js b/lib/helpers/tabbable.js index 4b04f88b..4bd57559 100644 --- a/lib/helpers/tabbable.js +++ b/lib/helpers/tabbable.js @@ -10,41 +10,40 @@ * http://api.jqueryui.com/category/ui-core/ */ -function focusable(element, isTabIndexNotNaN) { - var nodeName = element.nodeName.toLowerCase(); - return (/input|select|textarea|button|object/.test(nodeName) ? - !element.disabled : - "a" === nodeName ? - element.href || isTabIndexNotNaN : - isTabIndexNotNaN) && visible(element); -} + function hidden (el) { + return (el.offsetWidth <= 0 && el.offsetHeight <= 0) || + el.style.display === 'none'; + } -function hidden(el) { - return (el.offsetWidth <= 0 && el.offsetHeight <= 0) || - el.style.display === 'none'; -} + function visible (element) { + let ourElement = element; + while (ourElement) { + if (ourElement === document.body) break; + if (hidden(ourElement)) return false; + ourElement = element.parentNode; + } + return true; + } -function visible(element) { - while (element) { - if (element === document.body) break; - if (hidden(element)) return false; - element = element.parentNode; - } - return true; -} + function focusable (element, isTabIndexNotNaN) { + const nodeName = element.nodeName.toLowerCase(); + const isFocusableLink = nodeName === 'a' ? + element.href || isTabIndexNotNaN : isTabIndexNotNaN; + return (/input|select|textarea|button|object/.test(nodeName) ? + !element.disabled : isFocusableLink + ) && visible(element); + } -function tabbable(element) { - var tabIndex = element.getAttribute('tabindex'); - if (tabIndex === null) tabIndex = undefined; - var isTabIndexNaN = isNaN(tabIndex); - return (isTabIndexNaN || tabIndex >= 0) && focusable(element, !isTabIndexNaN); -} -function findTabbableDescendants(element) { - return [].slice.call(element.querySelectorAll('*'), 0).filter(function(el) { - return tabbable(el); - }); -} + function tabbable (element) { + let tabIndex = element.getAttribute('tabindex'); + if (tabIndex === null) tabIndex = undefined; + const isTabIndexNaN = isNaN(tabIndex); + return (isTabIndexNaN || tabIndex >= 0) && focusable(element, !isTabIndexNaN); + } -module.exports = findTabbableDescendants; + function findTabbableDescendants (element) { + return [].slice.call(element.querySelectorAll('*'), 0).filter(el => tabbable(el)); + } + export default findTabbableDescendants; diff --git a/package.json b/package.json index ff86d105..78e2c84c 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ }, "scripts": { "test": "NODE_ENV=test karma start", + "test:full": "npm-run-all -p 'test -- --single-run' lint", "start": "scripts/dev-examples", "docs": "npm-run-all docs:*", "docs-dev": "npm-run-all docs:clean docs:prepare docs:build:watch", @@ -21,7 +22,8 @@ "docs:prepare": "gitbook install", "docs:build": "gitbook build -g reactjs/react-modal", "docs:build:watch": "gitbook serve", - "docs:publish": "cd _book && git init && git commit --allow-empty -m 'update book' && git checkout -b gh-pages && touch .nojekyll && git add . && git commit -am 'update book' && git push git@github.com:reactjs/react-modal gh-pages --force" + "docs:publish": "cd _book && git init && git commit --allow-empty -m 'update book' && git checkout -b gh-pages && touch .nojekyll && git add . && git commit -am 'update book' && git push git@github.com:reactjs/react-modal gh-pages --force", + "lint": "eslint lib/ specs/" }, "authors": [ "Ryan Florence" @@ -29,11 +31,19 @@ "license": "MIT", "devDependencies": { "babel-core": "^6.7.4", + "babel-eslint": "^7.1.1", "babel-loader": "^6.2.4", "babel-preset-es2015": "^6.6.0", + "babel-preset-latest": "^6.16.0", "babel-preset-react": "^6.5.0", + "babel-preset-stage-2": "^6.18.0", "envify": "^3.4.1", - "expect": "^1.20.2", + "eslint": "^3.9.1", + "eslint-config-airbnb": "latest", + "eslint-plugin-import": "^2.1.0", + "eslint-plugin-jsx-a11y": "^2.2.3", + "eslint-plugin-react": "^6.6.0", + "expect": "1.10.0", "gitbook-cli": "^2.3.0", "karma": "^1.3.0", "karma-chrome-launcher": "2.0.0", diff --git a/specs/Modal.spec.js b/specs/Modal.spec.js index c4003609..99159f2e 100644 --- a/specs/Modal.spec.js +++ b/specs/Modal.spec.js @@ -1,38 +1,44 @@ /* eslint-env mocha */ -import { renderModal, unmountModal } from './helper'; + +// The following eslint overrides should be removed when refactoring can occur + +/* eslint react/no-find-dom-node: "warn", + react/no-render-return-value: "warn" +*/ import TestUtils from 'react-addons-test-utils'; import React from 'react'; +import sinon from 'sinon'; +import expect from 'expect'; import ReactDOM from 'react-dom'; import Modal from '../lib/components/Modal'; import ariaAppHider from '../lib/helpers/ariaAppHider'; +import { renderModal, unmountModal } from './helper'; + const Simulate = TestUtils.Simulate; -import sinon from 'sinon'; -import expect from 'expect'; -describe('Modal', function () { +describe('Modal', () => { it('scopes tab navigation to the modal'); it('focuses the last focused element when tabbing in from browser chrome'); - - it('can be open initially', function() { - var component = renderModal({isOpen: true}, 'hello'); - expect(component.portal.refs.content.innerHTML.trim()).toEqual('hello'); + it('can be open initially', () => { + const component = renderModal({ isOpen: true }, 'hello'); + expect(component.portal.content.innerHTML.trim()).toEqual('hello'); unmountModal(); }); - it('can be closed initially', function() { - var component = renderModal({}, 'hello'); + it('can be closed initially', () => { + const component = renderModal({}, 'hello'); expect(ReactDOM.findDOMNode(component.portal).innerHTML.trim()).toEqual(''); unmountModal(); }); - it('accepts appElement as a prop', function() { - var el = document.createElement('div'); - var node = document.createElement('div'); + it('accepts appElement as a prop', () => { + const el = document.createElement('div'); + const node = document.createElement('div'); ReactDOM.render( , node); @@ -40,52 +46,48 @@ describe('Modal', function () { ReactDOM.unmountComponentAtNode(node); }); - it('renders into the body, not in context', function() { - var node = document.createElement('div'); - var App = React.createClass({ - render() { - return ( -
- - hello - -
- ); - } - }); + it('renders into the body, not in context', () => { + const node = document.createElement('div'); + const App = () => ( +
+ + hello + +
+ ); Modal.setAppElement(node); ReactDOM.render(, node); - var modalParent = document.body.querySelector('.ReactModalPortal').parentNode; + const modalParent = document.body.querySelector('.ReactModalPortal').parentNode; expect(modalParent).toEqual(document.body); ReactDOM.unmountComponentAtNode(node); }); - it('renders children', function() { - var child = 'I am a child of Modal, and he has sent me here...'; - var component = renderModal({isOpen: true}, child); - expect(component.portal.refs.content.innerHTML).toEqual(child); + it('renders children', () => { + const child = 'I am a child of Modal, and he has sent me here...'; + const component = renderModal({ isOpen: true }, child); + expect(component.portal.content.innerHTML).toEqual(child); unmountModal(); }); - it('renders the modal content with a dialog aria role when provided ', function () { - var child = 'I am a child of Modal, and he has sent me here...'; - var component = renderModal({isOpen: true, role: 'dialog'}, child); - expect(component.portal.refs.content.getAttribute('role')).toEqual('dialog'); + it('renders the modal content with a dialog aria role when provided ', () => { + const child = 'I am a child of Modal, and he has sent me here...'; + const component = renderModal({ isOpen: true, role: 'dialog' }, child); + expect(component.portal.content.getAttribute('role')).toEqual('dialog'); unmountModal(); }); - it('renders the modal with a aria-label based on the contentLabel prop', function () { - var child = 'I am a child of Modal, and he has sent me here...'; - var component = renderModal({isOpen: true, contentLabel: 'Special Modal'}, child); - expect(component.portal.refs.content.getAttribute('aria-label')).toEqual('Special Modal'); + it('renders the modal with a aria-label based on the contentLabel prop', () => { + const child = 'I am a child of Modal, and he has sent me here...'; + const component = renderModal({ isOpen: true, contentLabel: 'Special Modal' }, child); + expect(component.portal.content.getAttribute('aria-label')).toEqual('Special Modal'); unmountModal(); }); - it('has default props', function() { - var node = document.createElement('div'); + it('has default props', () => { + const node = document.createElement('div'); Modal.setAppElement(document.createElement('div')); - var component = ReactDOM.render(, node); - var props = component.props; + const component = ReactDOM.render(, node); + const props = component.props; expect(props.isOpen).toBe(false); expect(props.ariaHideApp).toBe(true); expect(props.closeTimeoutMS).toBe(0); @@ -95,136 +97,136 @@ describe('Modal', function () { Modal.setAppElement(document.body); // restore default }); - it('removes the portal node', function() { - var component = renderModal({isOpen: true}, 'hello'); - expect(component.portal.refs.content.innerHTML.trim()).toEqual('hello'); + it('removes the portal node', () => { + const component = renderModal({ isOpen: true }, 'hello'); + expect(component.portal.content.innerHTML.trim()).toEqual('hello'); unmountModal(); expect(!document.querySelector('.ReactModalPortal')).toExist(); }); - it('focuses the modal content', function() { - renderModal({isOpen: true}, null, function () { - expect(document.activeElement).toEqual(this.portal.refs.content); + it('focuses the modal content', () => { + renderModal({ isOpen: true }, null, function checkModalContentFocus () { + expect(document.activeElement).toEqual(this.portal.content); unmountModal(); }); }); - it('does not focus the modal content when a descendent is already focused', function() { - var input = ( + it('does not focus the modal content when a descendent is already focused', () => { + const input = ( { el && el.focus(); }} + ref={el => (el && el.focus())} /> ); - renderModal({isOpen: true}, input, function () { + renderModal({ isOpen: true }, input, () => { expect(document.activeElement).toEqual(document.querySelector('.focus_input')); unmountModal(); }); }); - it('handles case when child has no tabbable elements', function() { - var component = renderModal({isOpen: true}, 'hello'); - expect(function() { - Simulate.keyDown(component.portal.refs.content, {key: "Tab", keyCode: 9, which: 9}) - }).toNotThrow; + it('handles case when child has no tabbable elements', () => { + const component = renderModal({ isOpen: true }, 'hello'); + expect(() => { + Simulate.keyDown(component.portal.content, { key: 'Tab', keyCode: 9, which: 9 }); + }).toNotThrow(); unmountModal(); }); - it('keeps focus inside the modal when child has no tabbable elements', function() { - var tabPrevented = false; - var modal = renderModal({isOpen: true}, 'hello'); - expect(document.activeElement).toEqual(modal.portal.refs.content); - Simulate.keyDown(modal.portal.refs.content, { - key: "Tab", - keyCode: 9, - which: 9, - preventDefault: function() { tabPrevented = true; } + it('keeps focus inside the modal when child has no tabbable elements', () => { + let tabPrevented = false; + const modal = renderModal({ isOpen: true }, 'hello'); + expect(document.activeElement).toEqual(modal.portal.content); + Simulate.keyDown(modal.portal.content, { + key: 'Tab', + keyCode: 9, + which: 9, + preventDefault () { tabPrevented = true; } }); expect(tabPrevented).toEqual(true); }); - it('supports portalClassName', function () { - var modal = renderModal({isOpen: true, portalClassName: 'myPortalClass'}); + it('supports portalClassName', () => { + const modal = renderModal({ isOpen: true, portalClassName: 'myPortalClass' }); expect(modal.node.className).toEqual('myPortalClass'); unmountModal(); }); - it('supports custom className', function() { - var modal = renderModal({isOpen: true, className: 'myClass'}); - expect(modal.portal.refs.content.className.indexOf('myClass')).toNotEqual(-1); + it('supports custom className', () => { + const modal = renderModal({ isOpen: true, className: 'myClass' }); + expect(modal.portal.content.className.indexOf('myClass')).toNotEqual(-1); unmountModal(); }); - it('supports overlayClassName', function () { - var modal = renderModal({isOpen: true, overlayClassName: 'myOverlayClass'}); - expect(modal.portal.refs.overlay.className.indexOf('myOverlayClass')).toNotEqual(-1); + it('supports overlayClassName', () => { + const modal = renderModal({ isOpen: true, overlayClassName: 'myOverlayClass' }); + expect(modal.portal.overlay.className.indexOf('myOverlayClass')).toNotEqual(-1); unmountModal(); }); - it('overrides the default styles when a custom classname is used', function () { - var modal = renderModal({isOpen: true, className: 'myClass'}); - expect(modal.portal.refs.content.style.top).toEqual(''); + it('overrides the default styles when a custom classname is used', () => { + const modal = renderModal({ isOpen: true, className: 'myClass' }); + expect(modal.portal.content.style.top).toEqual(''); unmountModal(); }); - it('overrides the default styles when a custom overlayClassName is used', function () { - var modal = renderModal({isOpen: true, overlayClassName: 'myOverlayClass'}); - expect(modal.portal.refs.overlay.style.backgroundColor).toEqual(''); + it('overrides the default styles when a custom overlayClassName is used', () => { + const modal = renderModal({ isOpen: true, overlayClassName: 'myOverlayClass' }); + expect(modal.portal.overlay.style.backgroundColor).toEqual(''); }); - it('supports adding style to the modal contents', function () { - var modal = renderModal({isOpen: true, style: {content: {width: '20px'}}}); - expect(modal.portal.refs.content.style.width).toEqual('20px'); + it('supports adding style to the modal contents', () => { + const modal = renderModal({ isOpen: true, style: { content: { width: '20px' } } }); + expect(modal.portal.content.style.width).toEqual('20px'); }); - it('supports overriding style on the modal contents', function() { - var modal = renderModal({isOpen: true, style: {content: {position: 'static'}}}); - expect(modal.portal.refs.content.style.position).toEqual('static'); + it('supports overriding style on the modal contents', () => { + const modal = renderModal({ isOpen: true, style: { content: { position: 'static' } } }); + expect(modal.portal.content.style.position).toEqual('static'); }); - it('supports adding style on the modal overlay', function() { - var modal = renderModal({isOpen: true, style: {overlay: {width: '75px'}}}); - expect(modal.portal.refs.overlay.style.width).toEqual('75px'); + it('supports adding style on the modal overlay', () => { + const modal = renderModal({ isOpen: true, style: { overlay: { width: '75px' } } }); + expect(modal.portal.overlay.style.width).toEqual('75px'); }); - it('supports overriding style on the modal overlay', function() { - var modal = renderModal({isOpen: true, style: {overlay: {position: 'static'}}}); - expect(modal.portal.refs.overlay.style.position).toEqual('static'); + it('supports overriding style on the modal overlay', () => { + const modal = renderModal({ isOpen: true, style: { overlay: { position: 'static' } } }); + expect(modal.portal.overlay.style.position).toEqual('static'); }); - it('supports overriding the default styles', function() { - var previousStyle = Modal.defaultStyles.content.position - //Just in case the default style is already relative, check that we can change it - var newStyle = previousStyle === 'relative' ? 'static': 'relative' - Modal.defaultStyles.content.position = newStyle - var modal = renderModal({isOpen: true}); - expect(modal.portal.refs.content.style.position).toEqual(newStyle); - Modal.defaultStyles.content.position = previousStyle + it('supports overriding the default styles', () => { + const previousStyle = Modal.defaultStyles.content.position; + // Just in case the default style is already relative, check that we can change it + const newStyle = previousStyle === 'relative' ? 'static' : 'relative'; + Modal.defaultStyles.content.position = newStyle; + const modal = renderModal({ isOpen: true }); + expect(modal.portal.content.style.position).toEqual(newStyle); + Modal.defaultStyles.content.position = previousStyle; }); - it('adds class to body when open', function() { - renderModal({isOpen: false}); + it('adds class to body when open', () => { + renderModal({ isOpen: false }); expect(document.body.className.indexOf('ReactModal__Body--open') !== -1).toEqual(false); - renderModal({isOpen: true}); - expect(document.body.className.indexOf('ReactModal__Body--open') !== -1).toEqual(true); + renderModal({ isOpen: true }); + expect(document.body.className.indexOf('ReactModal__Body--open') !== -1).toEqual(true); - renderModal({isOpen: false}); - expect(document.body.className.indexOf('ReactModal__Body--open') !== -1).toEqual(false); + renderModal({ isOpen: false }); + expect(document.body.className.indexOf('ReactModal__Body--open') !== -1).toEqual(false); unmountModal(); }); - it('removes class from body when unmounted without closing', function() { - renderModal({isOpen: true}); - expect(document.body.className.indexOf('ReactModal__Body--open') !== -1).toEqual(true); + it('removes class from body when unmounted without closing', () => { + renderModal({ isOpen: true }); + expect(document.body.className.indexOf('ReactModal__Body--open') !== -1).toEqual(true); unmountModal(); - expect(document.body.className.indexOf('ReactModal__Body--open') !== -1).toEqual(false); + expect(document.body.className.indexOf('ReactModal__Body--open') !== -1).toEqual(false); }); - it('removes aria-hidden from appElement when unmounted without closing', function() { - var el = document.createElement('div'); - var node = document.createElement('div'); + it('removes aria-hidden from appElement when unmounted without closing', () => { + const el = document.createElement('div'); + const node = document.createElement('div'); ReactDOM.render(React.createElement(Modal, { isOpen: true, appElement: el @@ -234,20 +236,20 @@ describe('Modal', function () { expect(el.getAttribute('aria-hidden')).toEqual(null); }); - it('adds --after-open for animations', function() { - renderModal({isOpen: true}); - var overlay = document.querySelector('.ReactModal__Overlay'); - var content = document.querySelector('.ReactModal__Content'); + it('adds --after-open for animations', () => { + renderModal({ isOpen: true }); + const overlay = document.querySelector('.ReactModal__Overlay'); + const content = document.querySelector('.ReactModal__Content'); expect(overlay.className.match(/ReactModal__Overlay--after-open/)).toExist(); expect(content.className.match(/ReactModal__Content--after-open/)).toExist(); unmountModal(); }); - it('should trigger the onAfterOpen callback', function() { - var afterOpenCallback = sinon.spy(); + it('should trigger the onAfterOpen callback', () => { + const afterOpenCallback = sinon.spy(); renderModal({ isOpen: true, - onAfterOpen: function() { + onAfterOpen () { afterOpenCallback(); } }); @@ -255,11 +257,11 @@ describe('Modal', function () { unmountModal(); }); - it('check the state of the modal after close with time out and reopen it', function() { - var modal = renderModal({ + it('check the state of the modal after close with time out and reopen it', () => { + const modal = renderModal({ isOpen: true, closeTimeoutMS: 2000, - onRequestClose: function() {} + onRequestClose () {} }); modal.portal.closeWithTimeout(); modal.portal.open(); @@ -268,67 +270,67 @@ describe('Modal', function () { unmountModal(); }); - describe('should close on overlay click', function() { - afterEach('Unmount modal', function() { + describe('should close on overlay click', () => { + afterEach('Unmount modal', () => { unmountModal(); }); - describe('verify props', function() { - it('verify default prop of shouldCloseOnOverlayClick', function () { - var modal = renderModal({isOpen: true}); + describe('verify props', () => { + it('verify default prop of shouldCloseOnOverlayClick', () => { + const modal = renderModal({ isOpen: true }); expect(modal.props.shouldCloseOnOverlayClick).toEqual(true); }); - it('verify prop of shouldCloseOnOverlayClick', function () { - var modal = renderModal({isOpen: true, shouldCloseOnOverlayClick: false}); + it('verify prop of shouldCloseOnOverlayClick', () => { + const modal = renderModal({ isOpen: true, shouldCloseOnOverlayClick: false }); expect(modal.props.shouldCloseOnOverlayClick).toEqual(false); }); }); - describe('verify clicks', function() { - it('verify overlay click when shouldCloseOnOverlayClick sets to false', function () { - var requestCloseCallback = sinon.spy(); - var modal = renderModal({ + describe('verify clicks', () => { + it('verify overlay click when shouldCloseOnOverlayClick sets to false', () => { + const requestCloseCallback = sinon.spy(); + const modal = renderModal({ isOpen: true, shouldCloseOnOverlayClick: false }); expect(modal.props.isOpen).toEqual(true); - var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay'); + const overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay'); expect(overlay.length).toEqual(1); Simulate.mouseDown(overlay[0]); // click the overlay Simulate.mouseUp(overlay[0]); expect(!requestCloseCallback.called).toBeTruthy(); }); - it('verify overlay click when shouldCloseOnOverlayClick sets to true', function() { - var requestCloseCallback = sinon.spy(); - var modal = renderModal({ + it('verify overlay click when shouldCloseOnOverlayClick sets to true', () => { + const requestCloseCallback = sinon.spy(); + const modal = renderModal({ isOpen: true, shouldCloseOnOverlayClick: true, - onRequestClose: function() { + onRequestClose () { requestCloseCallback(); } }); expect(modal.props.isOpen).toEqual(true); - var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay'); + const overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay'); expect(overlay.length).toEqual(1); Simulate.mouseDown(overlay[0]); // click the overlay Simulate.mouseUp(overlay[0]); expect(requestCloseCallback.called).toBeTruthy(); }); - it('verify overlay mouse down and content mouse up when shouldCloseOnOverlayClick sets to true', function() { - var requestCloseCallback = sinon.spy(); - var modal = renderModal({ - isOpen: true, - shouldCloseOnOverlayClick: true, - onRequestClose: function() { - requestCloseCallback(); - } - }); + it('verify overlay mouse down and content mouse up when shouldCloseOnOverlayClick sets to true', () => { + const requestCloseCallback = sinon.spy(); + const modal = renderModal({ + isOpen: true, + shouldCloseOnOverlayClick: true, + onRequestClose () { + requestCloseCallback(); + } + }); expect(modal.props.isOpen).toEqual(true); - var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay'); - var content = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Content'); + const overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay'); + const content = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Content'); expect(overlay.length).toEqual(1); expect(content.length).toEqual(1); Simulate.mouseDown(overlay[0]); // click the overlay @@ -336,18 +338,18 @@ describe('Modal', function () { expect(!requestCloseCallback.called).toBeTruthy(); }); - it('verify content mouse down and overlay mouse up when shouldCloseOnOverlayClick sets to true', function() { - var requestCloseCallback = sinon.spy(); - var modal = renderModal({ - isOpen: true, - shouldCloseOnOverlayClick: true, - onRequestClose: function() { - requestCloseCallback(); - } - }); + it('verify content mouse down and overlay mouse up when shouldCloseOnOverlayClick sets to true', () => { + const requestCloseCallback = sinon.spy(); + const modal = renderModal({ + isOpen: true, + shouldCloseOnOverlayClick: true, + onRequestClose () { + requestCloseCallback(); + } + }); expect(modal.props.isOpen).toEqual(true); - var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay'); - var content = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Content'); + const overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay'); + const content = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Content'); expect(content.length).toEqual(1); expect(overlay.length).toEqual(1); Simulate.mouseDown(content[0]); // click the overlay @@ -355,79 +357,79 @@ describe('Modal', function () { expect(!requestCloseCallback.called).toBeTruthy(); }); - it('should not stop event propagation', function() { - var hasPropagated = false - var modal = renderModal({ + it('should not stop event propagation', () => { + let hasPropagated = false; + const modal = renderModal({ isOpen: true, shouldCloseOnOverlayClick: true }); - var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay'); - window.addEventListener('click', function () { hasPropagated = true }) - overlay[0].dispatchEvent(new MouseEvent('click', { bubbles: true })) + const overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay'); + window.addEventListener('click', () => { hasPropagated = true; }); + overlay[0].dispatchEvent(new MouseEvent('click', { bubbles: true })); expect(hasPropagated).toBeTruthy(); }); }); - it('verify event passing on overlay click', function() { - var requestCloseCallback = sinon.spy(); - var modal = renderModal({ + it('verify event passing on overlay click', () => { + const requestCloseCallback = sinon.spy(); + const modal = renderModal({ isOpen: true, shouldCloseOnOverlayClick: true, onRequestClose: requestCloseCallback }); expect(modal.props.isOpen).toEqual(true); - var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay'); + const overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay'); expect(overlay.length).toEqual(1); Simulate.mouseDown(overlay[0]); // click the overlay Simulate.mouseUp(overlay[0]); expect(requestCloseCallback.called).toBeTruthy(); // Check if event is passed to onRequestClose callback. - var event = requestCloseCallback.getCall(0).args[0]; + const event = requestCloseCallback.getCall(0).args[0]; expect(event).toBeTruthy(); expect(event.constructor).toBeTruthy(); expect(event.constructor.name).toEqual('SyntheticEvent'); }); }); - it('should close on Esc key event', function() { - var requestCloseCallback = sinon.spy(); - var modal = renderModal({ + it('should close on Esc key event', () => { + const requestCloseCallback = sinon.spy(); + const modal = renderModal({ isOpen: true, shouldCloseOnOverlayClick: true, onRequestClose: requestCloseCallback }); expect(modal.props.isOpen).toEqual(true); - expect(function() { - Simulate.keyDown(modal.portal.refs.content, {key: "Esc", keyCode: 27, which: 27}) + expect(() => { + Simulate.keyDown(modal.portal.content, { key: 'Esc', keyCode: 27, which: 27 }); }).toNotThrow(); expect(requestCloseCallback.called).toBeTruthy(); // Check if event is passed to onRequestClose callback. - var event = requestCloseCallback.getCall(0).args[0]; + const event = requestCloseCallback.getCall(0).args[0]; expect(event).toBeTruthy(); expect(event.constructor).toBeTruthy(); expect(event.constructor.name).toEqual('SyntheticEvent'); }); - //it('adds --before-close for animations', function() { - //var node = document.createElement('div'); + // it('adds --before-close for animations', function() { + // var node = document.createElement('div'); - //var component = ReactDOM.render(React.createElement(Modal, { - //isOpen: true, - //ariaHideApp: false, - //closeTimeoutMS: 50, - //}), node); + // var component = ReactDOM.render(React.createElement(Modal, { + // isOpen: true, + // ariaHideApp: false, + // closeTimeoutMS: 50, + // }), node); - //component = ReactDOM.render(React.createElement(Modal, { - //isOpen: false, - //ariaHideApp: false, - //closeTimeoutMS: 50, - //}), node); + // component = ReactDOM.render(React.createElement(Modal, { + // isOpen: false, + // ariaHideApp: false, + // closeTimeoutMS: 50, + // }), node); // It can't find these nodes, I didn't spend much time on this - //var overlay = document.querySelector('.ReactModal__Overlay'); - //var content = document.querySelector('.ReactModal__Content'); - //ok(overlay.className.match(/ReactModal__Overlay--before-close/)); - //ok(content.className.match(/ReactModal__Content--before-close/)); - //unmountModal(); - //}); + // var overlay = document.querySelector('.ReactModal__Overlay'); + // var content = document.querySelector('.ReactModal__Content'); + // ok(overlay.className.match(/ReactModal__Overlay--before-close/)); + // ok(content.className.match(/ReactModal__Content--before-close/)); + // unmountModal(); + // }); }); diff --git a/specs/helper.js b/specs/helper.js index a53709ae..846266bc 100644 --- a/specs/helper.js +++ b/specs/helper.js @@ -1,20 +1,26 @@ +// The following eslint overrides should be removed when refactoring can occur + +/* eslint react/no-render-return-value: "warn" */ import React from 'react'; import ReactDOM from 'react-dom'; import Modal from '../lib/components/Modal'; -let _currentDiv = null; +let currentDiv = null; -export const renderModal = function(props, children, callback) { - props.ariaHideApp = false; - _currentDiv = document.createElement('div'); - document.body.appendChild(_currentDiv); +export function renderModal (props, children, callback) { + const myProps = { + ariaHideApp: false, + ...props + }; + currentDiv = document.createElement('div'); + document.body.appendChild(currentDiv); return ReactDOM.render( - {children} - , _currentDiv, callback); -}; + {children} + , currentDiv, callback); +} -export const unmountModal = function() { - ReactDOM.unmountComponentAtNode(_currentDiv); - document.body.removeChild(_currentDiv); - _currentDiv = null; +export const unmountModal = () => { + ReactDOM.unmountComponentAtNode(currentDiv); + document.body.removeChild(currentDiv); + currentDiv = null; }; diff --git a/specs/spec_index.js b/specs/spec_index.js index bfd7c264..6ed23aec 100644 --- a/specs/spec_index.js +++ b/specs/spec_index.js @@ -1,10 +1,9 @@ const testsContext = require.context('.', true, /spec$/); -testsContext.keys().forEach(function(path) { - try { - testsContext(path); - } catch(err) { - debugger - console.error(`[ERROR] WITH SPEC FILE: ${path}`); - console.error(err); - } +testsContext.keys().forEach((path) => { + try { + testsContext(path); + } catch (err) { + console.error(`[ERROR] WITH SPEC FILE: ${path}`); + console.error(err); + } }); diff --git a/webpack.test.config.js b/webpack.test.config.js index 6fd71d36..d690759a 100644 --- a/webpack.test.config.js +++ b/webpack.test.config.js @@ -1,7 +1,8 @@ -var commonConfig = require('./webpack.config'); +const commonConfig = require('./webpack.config'); commonConfig.plugins = []; commonConfig.entry = undefined; commonConfig.debug = true; +commonConfig.devtool = 'inline-source-map'; module.exports = commonConfig; diff --git a/yarn.lock b/yarn.lock index 8356e784..432162bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20,10 +20,20 @@ accepts@~1.3.3: mime-types "~2.1.11" negotiator "0.6.1" -acorn@^3.0.0, acorn@^3.1.0: +acorn-jsx@^3.0.0, acorn-jsx@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.0, acorn@^3.0.4, acorn@^3.1.0: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" +acorn@^4.0.1: + version "4.0.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.4.tgz#17a8d6a7a6c4ef538b814ec9abac2779293bf30a" + after@0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/after/-/after-0.8.1.tgz#ab5d4fb883f596816d3515f8f791c0af486dd627" @@ -32,6 +42,17 @@ after@0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" +ajv-keywords@^1.0.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.0.tgz#c11e6859eafff83e0dafc416929472eca946aa2c" + +ajv@^4.7.0: + version "4.10.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.10.3.tgz#3e4fea9675b157de7888b80dd0ed735b83f28e11" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -44,7 +65,11 @@ amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" -ansi-regex@*, ansi-regex@^2.0.0: +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + +ansi-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.0.0.tgz#c5061b6e0ef8a81775e50f5d66151bf6bf371107" @@ -86,6 +111,12 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.0 || ^1.1.13" +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + arr-diff@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" @@ -123,6 +154,16 @@ array-slice@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" @@ -205,7 +246,7 @@ aws4@^1.2.1: version "1.5.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755" -babel-code-frame@^6.20.0: +babel-code-frame@^6.16.0, babel-code-frame@^6.20.0: version "6.20.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.20.0.tgz#b968f839090f9a8bc6d41938fb96cb84f7387b26" dependencies: @@ -237,6 +278,16 @@ babel-core@^6.18.0, babel-core@^6.7.4: slash "^1.0.0" source-map "^0.5.0" +babel-eslint@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-7.1.1.tgz#8a6a884f085aa7060af69cfc77341c2f99370fb2" + dependencies: + babel-code-frame "^6.16.0" + babel-traverse "^6.15.0" + babel-types "^6.15.0" + babylon "^6.13.0" + lodash.pickby "^4.6.0" + babel-generator@^6.21.0: version "6.21.0" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.21.0.tgz#605f1269c489a1c75deeca7ea16d43d4656c8494" @@ -249,6 +300,22 @@ babel-generator@^6.21.0: lodash "^4.2.0" source-map "^0.5.0" +babel-helper-bindify-decorators@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.18.0.tgz#fc00c573676a6e702fffa00019580892ec8780a5" + dependencies: + babel-runtime "^6.0.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + +babel-helper-builder-binary-assignment-operator-visitor@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.18.0.tgz#8ae814989f7a53682152e3401a04fabd0bb333a6" + dependencies: + babel-helper-explode-assignable-expression "^6.18.0" + babel-runtime "^6.0.0" + babel-types "^6.18.0" + babel-helper-builder-react-jsx@^6.8.0: version "6.21.1" resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.21.1.tgz#c4a24208655be9dc1cccf14d366da176f20645e4" @@ -276,6 +343,23 @@ babel-helper-define-map@^6.18.0, babel-helper-define-map@^6.8.0: babel-types "^6.18.0" lodash "^4.2.0" +babel-helper-explode-assignable-expression@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.18.0.tgz#14b8e8c2d03ad735d4b20f1840b24cd1f65239fe" + dependencies: + babel-runtime "^6.0.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + +babel-helper-explode-class@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.18.0.tgz#c44f76f4fa23b9c5d607cbac5d4115e7a76f62cb" + dependencies: + babel-helper-bindify-decorators "^6.18.0" + babel-runtime "^6.0.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babel-helper-function-name@^6.18.0, babel-helper-function-name@^6.8.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.18.0.tgz#68ec71aeba1f3e28b2a6f0730190b754a9bf30e6" @@ -315,6 +399,16 @@ babel-helper-regex@^6.8.0: babel-types "^6.18.0" lodash "^4.2.0" +babel-helper-remap-async-to-generator@^6.16.0, babel-helper-remap-async-to-generator@^6.16.2: + version "6.20.3" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.20.3.tgz#9dd3b396f13e35ef63e538098500adc24c63c4e7" + dependencies: + babel-helper-function-name "^6.18.0" + babel-runtime "^6.20.0" + babel-template "^6.16.0" + babel-traverse "^6.20.0" + babel-types "^6.20.0" + babel-helper-replace-supers@^6.18.0, babel-helper-replace-supers@^6.8.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.18.0.tgz#28ec69877be4144dbd64f4cc3a337e89f29a924e" @@ -354,6 +448,30 @@ babel-plugin-check-es2015-constants@^6.3.13: dependencies: babel-runtime "^6.0.0" +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-async-generators@^6.5.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + +babel-plugin-syntax-class-properties@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + +babel-plugin-syntax-decorators@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + +babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.3.13: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" @@ -362,6 +480,50 @@ babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-plugin-syntax-trailing-function-commas@^6.3.13, babel-plugin-syntax-trailing-function-commas@^6.8.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.20.0.tgz#442835e19179f45b87e92d477d70b9f1f18b5c4f" + +babel-plugin-transform-async-generator-functions@^6.17.0: + version "6.17.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.17.0.tgz#d0b5a2b2f0940f2b245fa20a00519ed7bc6cae54" + dependencies: + babel-helper-remap-async-to-generator "^6.16.2" + babel-plugin-syntax-async-generators "^6.5.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-async-to-generator@^6.16.0: + version "6.16.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.16.0.tgz#19ec36cb1486b59f9f468adfa42ce13908ca2999" + dependencies: + babel-helper-remap-async-to-generator "^6.16.0" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-class-properties@^6.18.0: + version "6.19.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.19.0.tgz#1274b349abaadc835164e2004f4a2444a2788d5f" + dependencies: + babel-helper-function-name "^6.18.0" + babel-plugin-syntax-class-properties "^6.8.0" + babel-runtime "^6.9.1" + babel-template "^6.15.0" + +babel-plugin-transform-decorators@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.13.0.tgz#82d65c1470ae83e2d13eebecb0a1c2476d62da9d" + dependencies: + babel-helper-define-map "^6.8.0" + babel-helper-explode-class "^6.8.0" + babel-plugin-syntax-decorators "^6.13.0" + babel-runtime "^6.0.0" + babel-template "^6.8.0" + babel-types "^6.13.0" + babel-plugin-transform-es2015-arrow-functions@^6.3.13: version "6.8.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.8.0.tgz#5b63afc3181bdc9a8c4d481b5a4f3f7d7fef3d9d" @@ -531,6 +693,14 @@ babel-plugin-transform-es2015-unicode-regex@^6.3.13: babel-runtime "^6.0.0" regexpu-core "^2.0.0" +babel-plugin-transform-exponentiation-operator@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.8.0.tgz#db25742e9339eade676ca9acec46f955599a68a4" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.8.0" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.0.0" + babel-plugin-transform-flow-strip-types@^6.3.13: version "6.21.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.21.0.tgz#2eea3f8b5bb234339b47283feac155cfb237b948" @@ -538,6 +708,13 @@ babel-plugin-transform-flow-strip-types@^6.3.13: babel-plugin-syntax-flow "^6.18.0" babel-runtime "^6.0.0" +babel-plugin-transform-object-rest-spread@^6.16.0: + version "6.20.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.20.2.tgz#e816c55bba77b14c16365d87e2ae48c8fd18fc2e" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.20.0" + babel-plugin-transform-react-display-name@^6.3.13: version "6.8.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.8.0.tgz#f7a084977383d728bdbdc2835bba0159577f660e" @@ -579,7 +756,7 @@ babel-plugin-transform-strict-mode@^6.18.0: babel-runtime "^6.0.0" babel-types "^6.18.0" -babel-preset-es2015@^6.6.0: +babel-preset-es2015@^6.16.0, babel-preset-es2015@^6.6.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.18.0.tgz#b8c70df84ec948c43dcf2bf770e988eb7da88312" dependencies: @@ -608,6 +785,27 @@ babel-preset-es2015@^6.6.0: babel-plugin-transform-es2015-unicode-regex "^6.3.13" babel-plugin-transform-regenerator "^6.16.0" +babel-preset-es2016@^6.16.0: + version "6.16.0" + resolved "https://registry.yarnpkg.com/babel-preset-es2016/-/babel-preset-es2016-6.16.0.tgz#c7daf5feedeee99c867813bdf0d573d94ca12812" + dependencies: + babel-plugin-transform-exponentiation-operator "^6.3.13" + +babel-preset-es2017@^6.16.0: + version "6.16.0" + resolved "https://registry.yarnpkg.com/babel-preset-es2017/-/babel-preset-es2017-6.16.0.tgz#536c6287778a758948ddd092b466b6ef50b786fa" + dependencies: + babel-plugin-syntax-trailing-function-commas "^6.8.0" + babel-plugin-transform-async-to-generator "^6.16.0" + +babel-preset-latest@^6.16.0: + version "6.16.0" + resolved "https://registry.yarnpkg.com/babel-preset-latest/-/babel-preset-latest-6.16.0.tgz#5b87e19e250bb1213f13af4ec9dc7a51d53f388d" + dependencies: + babel-preset-es2015 "^6.16.0" + babel-preset-es2016 "^6.16.0" + babel-preset-es2017 "^6.16.0" + babel-preset-react@^6.5.0: version "6.16.0" resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.16.0.tgz#aa117d60de0928607e343c4828906e4661824316" @@ -620,6 +818,25 @@ babel-preset-react@^6.5.0: babel-plugin-transform-react-jsx-self "^6.11.0" babel-plugin-transform-react-jsx-source "^6.3.13" +babel-preset-stage-2@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.18.0.tgz#9eb7bf9a8e91c68260d5ba7500493caaada4b5b5" + dependencies: + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-plugin-transform-class-properties "^6.18.0" + babel-plugin-transform-decorators "^6.13.0" + babel-preset-stage-3 "^6.17.0" + +babel-preset-stage-3@^6.17.0: + version "6.17.0" + resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.17.0.tgz#b6638e46db6e91e3f889013d8ce143917c685e39" + dependencies: + babel-plugin-syntax-trailing-function-commas "^6.3.13" + babel-plugin-transform-async-generator-functions "^6.17.0" + babel-plugin-transform-async-to-generator "^6.16.0" + babel-plugin-transform-exponentiation-operator "^6.3.13" + babel-plugin-transform-object-rest-spread "^6.16.0" + babel-register@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.18.0.tgz#892e2e03865078dd90ad2c715111ec4449b32a68" @@ -632,7 +849,7 @@ babel-register@^6.18.0: mkdirp "^0.5.1" source-map-support "^0.4.2" -babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.20.0, babel-runtime@^6.9.0: +babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.20.0, babel-runtime@^6.9.0, babel-runtime@^6.9.1: version "6.20.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.20.0.tgz#87300bdcf4cd770f09bf0048c64204e17806d16f" dependencies: @@ -649,7 +866,7 @@ babel-template@^6.14.0, babel-template@^6.15.0, babel-template@^6.16.0, babel-te babylon "^6.11.0" lodash "^4.2.0" -babel-traverse@^6.16.0, babel-traverse@^6.18.0, babel-traverse@^6.21.0: +babel-traverse@^6.15.0, babel-traverse@^6.16.0, babel-traverse@^6.18.0, babel-traverse@^6.20.0, babel-traverse@^6.21.0: version "6.21.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.21.0.tgz#69c6365804f1a4f69eb1213f85b00a818b8c21ad" dependencies: @@ -663,7 +880,7 @@ babel-traverse@^6.16.0, babel-traverse@^6.18.0, babel-traverse@^6.21.0: invariant "^2.2.0" lodash "^4.2.0" -babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.21.0, babel-types@^6.8.0, babel-types@^6.9.0: +babel-types@^6.13.0, babel-types@^6.15.0, babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.20.0, babel-types@^6.21.0, babel-types@^6.8.0, babel-types@^6.9.0: version "6.21.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.21.0.tgz#314b92168891ef6d3806b7f7a917fdf87c11a4b2" dependencies: @@ -672,7 +889,7 @@ babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.21 lodash "^4.2.0" to-fast-properties "^1.0.1" -babylon@^6.11.0: +babylon@^6.11.0, babylon@^6.13.0: version "6.14.1" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.14.1.tgz#956275fab72753ad9b3435d7afe58f8bf0a29815" @@ -832,7 +1049,7 @@ buffer@^4.9.0: ieee754 "^1.1.4" isarray "^1.0.0" -builtin-modules@^1.0.0: +builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -848,10 +1065,20 @@ bytes@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + callsite@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + camelcase@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" @@ -867,7 +1094,7 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" -chalk@1.1.3, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: +chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -904,6 +1131,10 @@ chownr@^1.0.1, chownr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" +circular-json@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" + cli-color@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-0.2.3.tgz#0a25ceae5a6a1602be7f77d28563c36700274e88" @@ -911,6 +1142,16 @@ cli-color@0.2.3: es5-ext "~0.9.2" memoizee "~0.2.5" +cli-cursor@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-width@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" + cliui@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" @@ -930,6 +1171,10 @@ cmd-shim@~2.0.2: graceful-fs "^4.1.2" mkdirp "~0.5.0" +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -938,7 +1183,7 @@ colors@0.x.x: version "0.6.2" resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc" -colors@^1.1.0: +colors@^1.1.0, colors@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" @@ -1055,6 +1300,10 @@ constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + content-disposition@0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.1.tgz#87476c6a67c8daa87e32e87616df883ba7fb071b" @@ -1123,6 +1372,10 @@ d@^0.1.1, d@~0.1.1: dependencies: es5-ext "~0.10.2" +damerau-levenshtein@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.3.tgz#ae4f4ce0b62acae10ff63a01bb08f652f5213af2" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -1150,12 +1403,12 @@ debug@2.3.3: ms "0.7.2" debug@^2.1.1, debug@^2.2.0: - version "2.5.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.5.2.tgz#50c295a53dbf1657146e0c1b21307275e90d49cb" + version "2.6.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b" dependencies: ms "0.7.2" -debuglog@*, debuglog@^1.0.1: +debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -1163,7 +1416,7 @@ decamelize@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" -deep-equal@*: +deep-equal@*, deep-equal@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" @@ -1171,13 +1424,17 @@ deep-extend@~0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + defaults@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" dependencies: clone "^1.0.2" -define-properties@^1.1.2, define-properties@~1.1.2: +define-properties@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" dependencies: @@ -1188,6 +1445,18 @@ defined@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1232,6 +1501,17 @@ diff@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" +diff@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" + +doctrine@1.5.0, doctrine@^1.2.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + dom-serialize@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" @@ -1378,7 +1658,7 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.4.3, es-abstract@^1.6.1: +es-abstract@^1.4.3: version "1.6.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.6.1.tgz#bb8a2064120abcf928a086ea3d9043114285ec99" dependencies: @@ -1395,7 +1675,7 @@ es-to-primitive@^1.1.1: is-date-object "^1.0.1" is-symbol "^1.0.1" -es5-ext@^0.10.7, es5-ext@~0.10.11, es5-ext@~0.10.2: +es5-ext@^0.10.7, es5-ext@^0.10.8, es5-ext@~0.10.11, es5-ext@~0.10.2, es5-ext@~0.10.7: version "0.10.12" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047" dependencies: @@ -1414,29 +1694,188 @@ es6-iterator@2: es5-ext "^0.10.7" es6-symbol "3" -es6-symbol@3, es6-symbol@^3.0.2, es6-symbol@~3.1: +es6-map@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.4.tgz#a34b147be224773a4d7da8072794cefa3632b897" + dependencies: + d "~0.1.1" + es5-ext "~0.10.11" + es6-iterator "2" + es6-set "~0.1.3" + es6-symbol "~3.1.0" + event-emitter "~0.3.4" + +es6-set@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.4.tgz#9516b6761c2964b92ff479456233a247dc707ce8" + dependencies: + d "~0.1.1" + es5-ext "~0.10.11" + es6-iterator "2" + es6-symbol "3" + event-emitter "~0.3.4" + +es6-symbol@3, es6-symbol@^3.0.2, es6-symbol@~3.1, es6-symbol@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.0.tgz#94481c655e7a7cad82eba832d97d5433496d7ffa" dependencies: d "~0.1.1" es5-ext "~0.10.11" +es6-weak-map@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.1.tgz#0d2bbd8827eb5fb4ba8f97fbfea50d43db21ea81" + dependencies: + d "^0.1.1" + es5-ext "^0.10.8" + es6-iterator "2" + es6-symbol "3" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-config-airbnb-base@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-10.0.1.tgz#f17d4e52992c1d45d1b7713efbcd5ecd0e7e0506" + +eslint-config-airbnb@latest: + version "13.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-13.0.0.tgz#688d15d3c276c0c753ae538c92a44397d76ae46e" + dependencies: + eslint-config-airbnb-base "^10.0.0" + +eslint-import-resolver-node@^0.2.0: + version "0.2.3" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz#5add8106e8c928db2cba232bcd9efa846e3da16c" + dependencies: + debug "^2.2.0" + object-assign "^4.0.1" + resolve "^1.1.6" + +eslint-module-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.0.0.tgz#a6f8c21d901358759cdc35dbac1982ae1ee58bce" + dependencies: + debug "2.2.0" + pkg-dir "^1.0.0" + +eslint-plugin-import@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz#72ba306fad305d67c4816348a4699a4229ac8b4e" + dependencies: + builtin-modules "^1.1.1" + contains-path "^0.1.0" + debug "^2.2.0" + doctrine "1.5.0" + eslint-import-resolver-node "^0.2.0" + eslint-module-utils "^2.0.0" + has "^1.0.1" + lodash.cond "^4.3.0" + minimatch "^3.0.3" + pkg-up "^1.0.0" + +eslint-plugin-jsx-a11y@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-2.2.3.tgz#4e35cb71b8a7db702ac415c806eb8e8d9ea6c65d" + dependencies: + damerau-levenshtein "^1.0.0" + jsx-ast-utils "^1.0.0" + object-assign "^4.0.1" + +eslint-plugin-react@^6.6.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.8.0.tgz#741ab5438a094532e5ce1bbb935d6832356f492d" + dependencies: + doctrine "^1.2.2" + jsx-ast-utils "^1.3.4" + +eslint@^3.9.1: + version "3.12.2" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.12.2.tgz#6be5a9aa29658252abd7f91e9132bab1f26f3c34" + dependencies: + babel-code-frame "^6.16.0" + chalk "^1.1.3" + concat-stream "^1.4.6" + debug "^2.1.1" + doctrine "^1.2.2" + escope "^3.6.0" + espree "^3.3.1" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + glob "^7.0.3" + globals "^9.14.0" + ignore "^3.2.0" + imurmurhash "^0.1.4" + inquirer "^0.12.0" + is-my-json-valid "^2.10.0" + is-resolvable "^1.0.0" + js-yaml "^3.5.1" + json-stable-stringify "^1.0.0" + levn "^0.3.0" + lodash "^4.0.0" + mkdirp "^0.5.0" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.1" + pluralize "^1.2.1" + progress "^1.1.8" + require-uncached "^1.0.2" + shelljs "^0.7.5" + strip-bom "^3.0.0" + strip-json-comments "~1.0.1" + table "^3.7.8" + text-table "~0.2.0" + user-home "^2.0.0" + +espree@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.3.2.tgz#dbf3fadeb4ecb4d4778303e50103b3d36c88b89c" + dependencies: + acorn "^4.0.1" + acorn-jsx "^3.0.0" + esprima-fb@^15001.1.0-dev-harmony-fb: version "15001.1.0-dev-harmony-fb" resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-15001.1.0-dev-harmony-fb.tgz#30a947303c6b8d5e955bee2b99b1d233206a6901" +esprima@^2.6.0: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + esprima@~3.1.0: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" +esrecurse@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220" + dependencies: + estraverse "~4.1.0" + object-assign "^4.0.1" + +estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +estraverse@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2" + esutils@^2.0.0, esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -1451,6 +1890,13 @@ event-emitter@~0.2.2: dependencies: es5-ext "~0.9.2" +event-emitter@~0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.4.tgz#8d63ddfb4cfe1fae3b32ca265c4c720222080bb5" + dependencies: + d "~0.1.1" + es5-ext "~0.10.7" + event-stream@~3.3.0: version "3.3.4" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" @@ -1475,6 +1921,10 @@ exenv@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.0.tgz#3835f127abf075bfe082d0aed4484057c78e3c89" +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + expand-braces@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea" @@ -1502,17 +1952,13 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -expect@^1.20.2: - version "1.20.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-1.20.2.tgz#d458fe4c56004036bae3232416a3f6361f04f965" +expect@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-1.10.0.tgz#d69fe0afe369cb096682a8ca2684eb7363681e07" dependencies: - define-properties "~1.1.2" - has "^1.0.1" - is-equal "^1.5.1" - is-regex "^1.0.3" - object-inspect "^1.1.0" - object-keys "^1.0.9" - tmatch "^2.0.1" + deep-equal "^1.0.1" + is-regexp "^1.0.0" + object-inspect "^1.0.2" express@^4.13.3: version "4.14.0" @@ -1563,6 +2009,10 @@ eyes@0.1.x: version "0.1.8" resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + fbjs@^0.8.1, fbjs@^0.8.4: version "0.8.8" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.8.tgz#02f1b6e0ea0d46c24e0b51a2d24df069563a5ad6" @@ -1575,6 +2025,20 @@ fbjs@^0.8.1, fbjs@^0.8.4: setimmediate "^1.0.5" ua-parser-js "^0.7.9" +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + filename-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" @@ -1614,6 +2078,15 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" +flat-cache@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + for-in@^0.1.5: version "0.1.6" resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.6.tgz#c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8" @@ -1862,7 +2335,7 @@ glob@^6.0.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.3, glob@^7.0.5: +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: version "7.1.1" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" dependencies: @@ -1884,10 +2357,21 @@ glob@~7.0.6: once "^1.3.0" path-is-absolute "^1.0.0" -globals@^9.0.0: +globals@^9.0.0, globals@^9.14.0: version "9.14.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.14.0.tgz#8859936af0038741263053b39d0e76ca241e4034" +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@~4.1.3, graceful-fs@~4.1.6: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -2012,7 +2496,11 @@ iferr@^0.1.5, iferr@~0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" -imurmurhash@*, imurmurhash@^0.1.4: +ignore@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.0.tgz#8d88f03c3002a0ac52114db25d2c673b0bf1e435" + +imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -2052,10 +2540,32 @@ init-package-json@~1.9.3, init-package-json@~1.9.4: validate-npm-package-license "^3.0.1" validate-npm-package-name "^2.0.1" +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + interpret@^0.6.4: version "0.6.6" resolved "https://registry.yarnpkg.com/interpret/-/interpret-0.6.6.tgz#fecd7a18e7ce5ca6abfb953e1f86213a49f1625b" +interpret@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" + invariant@^2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" @@ -2070,22 +2580,12 @@ is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" -is-arrow-function@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-arrow-function/-/is-arrow-function-2.0.3.tgz#29be2c2d8d9450852b8bbafb635ba7b8d8e87ec2" - dependencies: - is-callable "^1.0.4" - is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" dependencies: binary-extensions "^1.0.0" -is-boolean-object@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93" - is-buffer@^1.0.2: version "1.1.4" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" @@ -2096,7 +2596,7 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" -is-callable@^1.0.4, is-callable@^1.1.1, is-callable@^1.1.3: +is-callable@^1.1.1, is-callable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" @@ -2114,22 +2614,6 @@ is-equal-shallow@^0.1.3: dependencies: is-primitive "^2.0.0" -is-equal@^1.5.1: - version "1.5.3" - resolved "https://registry.yarnpkg.com/is-equal/-/is-equal-1.5.3.tgz#05b7fa3a1122cbc71c1ef41ce0142d5532013b29" - dependencies: - has "^1.0.1" - is-arrow-function "^2.0.3" - is-boolean-object "^1.0.0" - is-callable "^1.1.3" - is-date-object "^1.0.1" - is-generator-function "^1.0.3" - is-number-object "^1.0.3" - is-regex "^1.0.3" - is-string "^1.0.4" - is-symbol "^1.0.1" - object.entries "^1.0.3" - is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -2150,9 +2634,9 @@ is-fullwidth-code-point@^1.0.0: dependencies: number-is-nan "^1.0.0" -is-generator-function@^1.0.3: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.6.tgz#9e71653cd15fff341c79c4151460a131d31e9fc4" +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" @@ -2160,7 +2644,7 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" -is-my-json-valid@^2.12.4: +is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: version "2.15.0" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz#936edda3ca3c211fd98f3b2d3e08da43f7b2915b" dependencies: @@ -2169,10 +2653,6 @@ is-my-json-valid@^2.12.4: jsonpointer "^4.0.0" xtend "^4.0.0" -is-number-object@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799" - is-number@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806" @@ -2183,6 +2663,22 @@ is-number@^2.0.2, is-number@^2.1.0: dependencies: kind-of "^3.0.2" +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + dependencies: + path-is-inside "^1.0.1" + is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" @@ -2199,14 +2695,20 @@ is-regex@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.3.tgz#0d55182bddf9f2fde278220aec3a75642c908637" +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + +is-resolvable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" + dependencies: + tryit "^1.0.1" + is-stream@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" -is-string@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64" - is-symbol@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" @@ -2266,6 +2768,13 @@ js-tokens@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-2.0.0.tgz#79903f5563ee778cc1162e6dcf1a0027c97f9cb5" +js-yaml@^3.5.1: + version "3.7.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" + dependencies: + argparse "^1.0.7" + esprima "^2.6.0" + jsbn@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.0.tgz#650987da0dd74f4ebf5a11377a2aa2d273e97dfd" @@ -2288,6 +2797,12 @@ json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -2336,6 +2851,13 @@ jstransform@^11.0.3: object-assign "^2.0.0" source-map "^0.4.2" +jsx-ast-utils@^1.0.0, jsx-ast-utils@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.3.5.tgz#9ba6297198d9f754594d62e59496ffb923778dd4" + dependencies: + acorn-jsx "^3.0.1" + object-assign "^4.1.0" + karma-chrome-launcher@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-2.0.0.tgz#c2790c5a32b15577d0fff5a4d5a2703b3b439c25" @@ -2428,6 +2950,13 @@ lazy-cache@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -2480,10 +3009,6 @@ lodash._baseflatten@~4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash._baseflatten/-/lodash._baseflatten-4.1.1.tgz#5c87403b88f3687a88d26424faadf3aa054aab0d" -lodash._baseindexof@*: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" - lodash._baseuniq@~4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.4.0.tgz#a445294347a2f5311f585fe3225644530b9b8fae" @@ -2498,25 +3023,11 @@ lodash._baseuniq@~4.5.0: lodash._createset "~4.0.0" lodash._setcache "~4.1.0" -lodash._bindcallback@*: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" - -lodash._cacheindexof@*: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" - -lodash._createcache@*: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" - dependencies: - lodash._getnative "^3.0.0" - lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" -lodash._getnative@*, lodash._getnative@^3.0.0: +lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" @@ -2542,6 +3053,10 @@ lodash.clonedeep@~4.3.0: dependencies: lodash._baseclone "~4.5.0" +lodash.cond@^4.3.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" + lodash.create@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" @@ -2586,14 +3101,14 @@ lodash.padstart@^4.1.0: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" +lodash.pickby@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.pickby/-/lodash.pickby-4.6.0.tgz#7dea21d8c18d7703a27c704c15d3b84a67e33aff" + lodash.rest@^4.0.0: version "4.0.5" resolved "https://registry.yarnpkg.com/lodash.rest/-/lodash.rest-4.0.5.tgz#954ef75049262038c96d1fc98b28fdaf9f0772aa" -lodash.restparam@*: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - lodash.union@~4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.2.1.tgz#6871017b9b1ff71952c1e2bb2e25b1046a7e2842" @@ -2623,7 +3138,7 @@ lodash@^3.8.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@^4.14.0, lodash@^4.2.0, lodash@^4.5.0: +lodash@^4.0.0, lodash@^4.14.0, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.5.0: version "4.17.3" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.3.tgz#557ed7d2a9438cac5fd5a43043ca60cb455e01f7" @@ -2750,7 +3265,7 @@ minimatch@1: lru-cache "2" sigmund "~1.0.0" -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@~3.0.3: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@~3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" dependencies: @@ -2800,14 +3315,22 @@ ms@0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" -mute-stream@~0.0.4: - version "0.0.6" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db" +mute-stream@0.0.5, mute-stream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" nan@^2.3.0: version "2.5.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.0.tgz#aa8f1e34531d807e9e27755b234b4a6ec0c152a8" +native-promise-only@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/native-promise-only/-/native-promise-only-0.8.1.tgz#20a318c30cb45f71fe7adfbf7b21c99c1472ef11" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + ncp@0.4.x: version "0.4.2" resolved "https://registry.yarnpkg.com/ncp/-/ncp-0.4.2.tgz#abcc6cbd3ec2ed2a729ff6e7c1fa8f01784a8574" @@ -3216,23 +3739,14 @@ object-component@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" -object-inspect@^1.1.0: +object-inspect@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.2.1.tgz#3b62226eb8f6d441751c7d8f22a20ff80ac9dc3f" -object-keys@^1.0.8, object-keys@^1.0.9: +object-keys@^1.0.8: version "1.0.11" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" -object.entries@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.6.1" - function-bind "^1.1.0" - has "^1.0.1" - object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -3258,6 +3772,10 @@ once@~1.3.3: dependencies: wrappy "1" +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + opener@~1.4.1: version "1.4.2" resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.2.tgz#b32582080042af8680c389a499175b4c54fff523" @@ -3269,6 +3787,17 @@ optimist@0.6.1, optimist@^0.6.1, optimist@~0.6.0: minimist "~0.0.1" wordwrap "~0.0.2" +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + options@>=0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" @@ -3379,6 +3908,12 @@ path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" +path-to-regexp@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + dependencies: + isarray "0.0.1" + path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -3417,6 +3952,12 @@ pkg-dir@^1.0.0: dependencies: find-up "^1.0.0" +pkg-up@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26" + dependencies: + find-up "^1.0.0" + pkginfo@0.2.x: version "0.2.3" resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.2.3.tgz#7239c42a5ef6c30b8f328439d9b9ff71042490f8" @@ -3425,6 +3966,14 @@ pkginfo@0.x.x: version "0.4.0" resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.0.tgz#349dbb7ffd38081fcadc0853df687f0c7744cd65" +pluralize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" @@ -3441,6 +3990,10 @@ process@^0.11.0: version "0.11.9" resolved "https://registry.yarnpkg.com/process/-/process-0.11.9.tgz#7bd5ad21aa6253e7da8682264f1e11d11c0318c1" +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + promise@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf" @@ -3676,7 +4229,7 @@ readable-stream@~2.1.4, readable-stream@~2.1.5: string_decoder "~0.10.x" util-deprecate "~1.0.1" -readdir-scoped-modules@*, readdir-scoped-modules@^1.0.0: +readdir-scoped-modules@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" dependencies: @@ -3694,6 +4247,14 @@ readdirp@^2.0.0: readable-stream "^2.0.2" set-immediate-shim "^1.0.1" +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + realize-package-specifier@~3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/realize-package-specifier/-/realize-package-specifier-3.0.3.tgz#d0def882952b8de3f67eba5e91199661271f41f4" @@ -3710,6 +4271,12 @@ recast@^0.11.17: private "~0.1.5" source-map "~0.5.0" +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + regenerate@^1.2.1: version "1.3.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" @@ -3769,47 +4336,48 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@2, request@^2.47.0, request@^2.74.0, request@~2.74.0: - version "2.74.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.74.0.tgz#7693ca768bbb0ea5c8ce08c084a45efa05b892ab" +request@2, request@^2.47.0, request@~2.69.0: + version "2.69.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.69.0.tgz#cf91d2e000752b1217155c005241911991a2346a" dependencies: aws-sign2 "~0.6.0" aws4 "^1.2.1" - bl "~1.1.2" + bl "~1.0.0" caseless "~0.11.0" combined-stream "~1.0.5" extend "~3.0.0" forever-agent "~0.6.1" - form-data "~1.0.0-rc4" + form-data "~1.0.0-rc3" har-validator "~2.0.6" - hawk "~3.1.3" + hawk "~3.1.0" http-signature "~1.1.0" is-typedarray "~1.0.0" isstream "~0.1.2" json-stringify-safe "~5.0.1" mime-types "~2.1.7" node-uuid "~1.4.7" - oauth-sign "~0.8.1" - qs "~6.2.0" + oauth-sign "~0.8.0" + qs "~6.0.2" stringstream "~0.0.4" - tough-cookie "~2.3.0" + tough-cookie "~2.2.0" tunnel-agent "~0.4.1" request@2.9.x: version "2.9.203" resolved "https://registry.yarnpkg.com/request/-/request-2.9.203.tgz#6c1711a5407fb94a114219563e44145bcbf4723a" -request@^2.79.0: - version "2.79.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" +request@^2.74.0, request@~2.74.0: + version "2.74.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.74.0.tgz#7693ca768bbb0ea5c8ce08c084a45efa05b892ab" dependencies: aws-sign2 "~0.6.0" aws4 "^1.2.1" + bl "~1.1.2" caseless "~0.11.0" combined-stream "~1.0.5" extend "~3.0.0" forever-agent "~0.6.1" - form-data "~2.1.1" + form-data "~1.0.0-rc4" har-validator "~2.0.6" hawk "~3.1.3" http-signature "~1.1.0" @@ -3817,47 +4385,64 @@ request@^2.79.0: isstream "~0.1.2" json-stringify-safe "~5.0.1" mime-types "~2.1.7" + node-uuid "~1.4.7" oauth-sign "~0.8.1" - qs "~6.3.0" + qs "~6.2.0" stringstream "~0.0.4" tough-cookie "~2.3.0" tunnel-agent "~0.4.1" - uuid "^3.0.0" -request@~2.69.0: - version "2.69.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.69.0.tgz#cf91d2e000752b1217155c005241911991a2346a" +request@^2.79.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" dependencies: aws-sign2 "~0.6.0" aws4 "^1.2.1" - bl "~1.0.0" caseless "~0.11.0" combined-stream "~1.0.5" extend "~3.0.0" forever-agent "~0.6.1" - form-data "~1.0.0-rc3" + form-data "~2.1.1" har-validator "~2.0.6" - hawk "~3.1.0" + hawk "~3.1.3" http-signature "~1.1.0" is-typedarray "~1.0.0" isstream "~0.1.2" json-stringify-safe "~5.0.1" mime-types "~2.1.7" - node-uuid "~1.4.7" - oauth-sign "~0.8.0" - qs "~6.0.2" + oauth-sign "~0.8.1" + qs "~6.3.0" stringstream "~0.0.4" - tough-cookie "~2.2.0" + tough-cookie "~2.3.0" tunnel-agent "~0.4.1" + uuid "^3.0.0" + +require-uncached@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" requires-port@1.x.x: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + resolve@^1.1.6: version "1.2.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.2.0.tgz#9589c3f2f6149d1417a40becc1663db6ec6bc26c" +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + retry@^0.10.0, retry@~0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" @@ -3904,6 +4489,16 @@ ripemd160@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-0.2.0.tgz#2bf198bde167cacfa51c0a928e84b68bbe171fce" +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + dependencies: + once "^1.3.0" + +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + samsam@^1.1.3: version "1.2.1" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.2.1.tgz#edd39093a3184370cb859243b2bdf255e7d8ea67" @@ -3999,6 +4594,14 @@ shell-quote@^1.6.1: array-reduce "~0.0.0" jsonify "~0.0.0" +shelljs@^0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.5.tgz#2eef7a50a21e1ccf37da00df767ec69e30ad0675" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + sigmund@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" @@ -4008,18 +4611,26 @@ signal-exit@^3.0.0: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" sinon@next: - version "2.0.0-pre.4" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.0.0-pre.4.tgz#f29fbcca8d2fa73b633a3b0c0e4e3c78f2360c2c" + version "2.0.0-pre.5" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.0.0-pre.5.tgz#d87357f93ba0404c89b9d50e29e4681382f766d6" dependencies: + colors "^1.1.2" + diff "^3.1.0" formatio "1.1.1" lolex "^1.4.0" + native-promise-only "^0.8.1" + path-to-regexp "^1.7.0" samsam "^1.1.3" - text-encoding "0.5.2" + text-encoding "0.6.2" slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + slide@^1.1.3, slide@^1.1.5, slide@~1.1.3, slide@~1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" @@ -4169,6 +4780,10 @@ split@0.3: dependencies: through "2" +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + sshpk@^1.7.0: version "1.10.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.10.1.tgz#30e1a5d329244974a1af61511339d595af6638b0" @@ -4227,6 +4842,13 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" +string-width@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^3.0.0" + string.prototype.padend@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0" @@ -4243,7 +4865,7 @@ stringstream@~0.0.4: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" -strip-ansi@*, strip-ansi@^3.0.0, strip-ansi@^3.0.1, strip-ansi@~3.0.1: +strip-ansi@^3.0.0, strip-ansi@^3.0.1, strip-ansi@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" dependencies: @@ -4255,7 +4877,11 @@ strip-bom@^2.0.0: dependencies: is-utf8 "^0.2.0" -strip-json-comments@~1.0.4: +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-json-comments@~1.0.1, strip-json-comments@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" @@ -4273,6 +4899,17 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" +table@^3.7.8: + version "3.8.3" + resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + tapable@^0.1.8, tapable@~0.1.8: version "0.1.10" resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4" @@ -4298,15 +4935,15 @@ tar@^2.0.0, tar@~2.2.1: fstream "^1.0.2" inherits "2" -text-encoding@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.5.2.tgz#85b4660819f088777609465551690fea137d824a" +text-encoding@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.2.tgz#111e648e757bea92d34ef0019d9fdb06ebb9f53e" text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" -through@2, through@~2.3, through@~2.3.1, through@~2.3.4: +through@2, through@^2.3.6, through@~2.3, through@~2.3.1, through@~2.3.4: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -4316,10 +4953,6 @@ timers-browserify@^2.0.2: dependencies: setimmediate "^1.0.4" -tmatch@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/tmatch/-/tmatch-2.0.1.tgz#0c56246f33f30da1b8d3d72895abaf16660f38cf" - tmp@0.0.28: version "0.0.28" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" @@ -4348,6 +4981,10 @@ tough-cookie@~2.3.0: dependencies: punycode "^1.4.1" +tryit@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" + tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -4360,6 +4997,12 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + type-is@~1.6.13: version "1.6.14" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.14.tgz#e219639c17ded1ca0789092dd54a03826b817cb2" @@ -4432,7 +5075,7 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" -user-home@2.0.0: +user-home@2.0.0, user-home@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" dependencies: @@ -4481,7 +5124,7 @@ uuid@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" -validate-npm-package-license@*, validate-npm-package-license@^3.0.1, validate-npm-package-license@~3.0.1: +validate-npm-package-license@^3.0.1, validate-npm-package-license@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" dependencies: @@ -4612,13 +5255,13 @@ winston@0.6.x: request "2.9.x" stack-trace "0.0.x" -wordwrap@0.0.2: +wordwrap@0.0.2, wordwrap@~0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" wrappy@1, wrappy@~1.0.1, wrappy@~1.0.2: version "1.0.2" @@ -4632,6 +5275,12 @@ write-file-atomic@~1.1.4: imurmurhash "^0.1.4" slide "^1.1.5" +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + ws@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ws/-/ws-1.0.1.tgz#7d0b2a2e58cddd819039c29c9de65045e1b310e9"