diff --git a/README.md b/README.md index 34e9ab29..cdd445d2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# fusion-plugin-universal-events + # fusion-plugin-universal-events [![Build status](https://badge.buildkite.com/de4e30ddb9d019f5a8e3a2519bc0a5cccab25247809cd10c99.svg?branch=master)](https://buildkite.com/uberopensource/fusion-plugin-universal-events) @@ -24,47 +24,36 @@ yarn add fusion-plugin-universal-events // main.js import React from 'react'; import App from 'fusion-react'; -import universalEvents from 'fusion-plugin-universal-events'; -import Root from './components/root'; -import analytics from './plugins/analytics'; +import UniversalEvents, {UniversalEventsToken} from 'fusion-plugin-universal-events'; +import {FetchToken} from 'fusion-tokens'; export default function() { - const app = new App(); - const UniversalEvents = app.plugin(universalEvents); - const Analytics = app.plugin(analytics, {UniversalEvents}); + const app = new App(); + app.register(UniversalEventsToken, UniversalEvents); + __BROWSER__ && app.configure(FetchToken, window.fetch); + app.middleware({events: UniversalEventsToken}, ({events}) => { + events.on('some-event', (payload) => {}); + events.on('some-scoped-event', (payload, ctx) => {}); + events.emit('some-event', {some: 'payload'}); + return (ctx, next) => { + const scoped = events.from(ctx); + scoped.on('some-scoped-event', (payload, ctx) => {}); + scoped.emit('some-scoped-event', {some: 'payload'}); + }; + }); return app; } +``` -// components/root.js -export default ({}, {universalEvents}) => { - function trackSignUp() { - universalEvents.emit('user-action', { - action: 'click', - target: 'sign up button', - }); - } - return ; -} +### UniversalEvents vs Standard Event Emitter -// plugins/analytics.js -export default function({UniversalEvents}) => (ctx, next) => { - UniversalEvents.of(ctx).on('user-action', ({action, target}) => { - // logs `User did a click on sign up button` both in client and server - console.log(`User did a ${action} on ${target}!`); - if (__NODE__) { - // save data - } - }); - return next(); -} -``` +The `UniversalEvents` abstraction was designed to allow you to emit and react to events without worrying about whether you are on the server or the browser. It also provides the ability for observers to map event payloads to new ones. For example, you might want to add the some piece of context such as a session id to every event of a certain type. If you just want a standard event emitter, this might not be the package for you. ### Event transformation It's possible to transform event data with a mapping function, for example to attach a timestamp to all actions of a type. ```js -const events = UniversalEvents.of(); events.map('user-action', payload => { return {...payload, time: new Date().getTime()}; }); @@ -89,10 +78,13 @@ events.on('type', (payload, ctx) => { This parameter will be present when events are emitted from the `ctx` scoped EventsEmitter instance. For example: ```js -const eventsWithoutCtx = EventEmitter.of(); -(ctx, next) => { - const eventsWithCtx = EventEmitter.of(ctx); -} +app.middleware({events: UniversalEventsToken}, ({events}) => { + events.on('some-scoped-event', (payload, ctx) => {}); + return (ctx, next) => { + const scoped = events.from(ctx); + scoped.emit('some-scoped-event', {some: 'payload'}); + }; +}); ``` ### * event type @@ -109,25 +101,24 @@ events.map('*', payload => { ### API -#### `universalEvents` - -`universalEvents` - A plugin that creates a UniversalEvents class when passed to `app.plugin` +#### Plugin registration ```js -import App from 'fusion-react'; -import universalEvents from 'fusion-plugin-universal-events'; - -const UniversalEvents = app.plugin(universalEvents); +import UniversalEvents, {UniversalEventsToken} from 'fusion-plugin-universal-events'; +app.register(UniversalEventsToken, UniversalEvents); ``` -#### `UniversalEvents.of` +#### Dependencies + +##### `FetchToken` + +- `fetch` - UniversalEvents in the browser depends on an implementation of `fetch` registered on the standard `FetchToken` exported from `fusion-tokens`. ```js -const events = UniversalEvents.of(ctx) -``` -Returns an event emitter +import {FetchToken} from 'fetch-tokens'; +__BROWSER__ && app.configure(FetchToken, window.fetch); -- `ctx: Object` - A memoization key +#### Instance API #### `events.on` @@ -182,4 +173,14 @@ Sets the frequency at which data is flushed to the server. Resets the interval t events.teardown() ``` -Stops the interval timer, clears the data queue and prevents any further data from being flushed to the server. +Stops the interval timer, clears the data queue and prevents any further data from being flushed to the server. Useful for testing + +#### `events.from` + +```js +const scoped = events.from(ctx); +``` + +Returns a scoped version of the events api. + +- `ctx: FusionContext` - Required. See [FusionContext](https://github.com/fusionjs/fusion-core#context) diff --git a/package.json b/package.json index cc358d38..f2fdd585 100644 --- a/package.json +++ b/package.json @@ -6,46 +6,47 @@ "keywords": [], "license": "MIT", "files": [ - "dist" + "dist", + "src" ], - "main": "./dist/node.cjs.js", - "module": "./dist/node.es.js", + "main": "./dist/index.js", + "module": "./dist/index.es.js", "browser": { - "./dist/node.cjs.js": "./dist/browser.es5.cjs.js", - "./dist/node.es.js": "./dist/browser.es5.es.js" + "./dist/index.js": "./dist/browser.es5.js", + "./dist/index.es.js": "./dist/browser.es5.es.js" }, "es2015": { - "./dist/browser.es5.cjs.js": "./dist/browser.es2015.cjs.js", "./dist/browser.es5.es.js": "./dist/browser.es2015.es.js" }, "es2017": { - "./dist/browser.es5.cjs.js": "./dist/browser.es2017.cjs.js", "./dist/browser.es5.es.js": "./dist/browser.es2017.es.js", - "./dist/browser.es2015.cjs.js": "./dist/browser.es2017.cjs.js", "./dist/browser.es2015.es.js": "./dist/browser.es2017.es.js" }, "dependencies": { "koa-bodyparser": "4.2.0" }, "devDependencies": { - "babel-eslint": "^8.0.2", - "create-universal-package": "^2.0.1", - "eslint": "^4.11.0", - "eslint-config-fusion": "^0.1.2", + "babel-eslint": "^8.2.1", + "create-universal-package": "^3.2.4", + "eslint": "^4.15.0", + "eslint-config-fusion": "^0.2.1", "eslint-plugin-cup": "^1.0.0", - "eslint-plugin-flowtype": "^2.39.1", - "eslint-plugin-prettier": "^2.3.1", - "eslint-plugin-react": "^7.4.0", - "flow-bin": "^0.59.0", - "fusion-core": "^0.2.3", - "fusion-test-utils": "^0.2.1", - "nyc": "^11.3.0", - "prettier": "1.8.2", + "eslint-plugin-flowtype": "^2.41.0", + "eslint-plugin-import": "^2.8.0", + "eslint-plugin-prettier": "^2.4.0", + "eslint-plugin-react": "^7.5.1", + "flow-bin": "^0.63.1", + "fusion-core": "^0.3.0-2", + "fusion-test-utils": "^0.3.0", + "fusion-tokens": "^0.0.4", + "nyc": "^11.4.1", + "prettier": "1.10.2", "tape-cup": "^4.7.1", "unitest": "^2.1.1" }, "peerDependencies": { - "fusion-core": "^0.2.3" + "fusion-core": "^0.3.0-2", + "fusion-tokens": "^0.0.4" }, "scripts": { "clean": "rm -rf dist", diff --git a/src/__tests__/__node__/index.js b/src/__tests__/__node__/index.js deleted file mode 100644 index fbc834af..00000000 --- a/src/__tests__/__node__/index.js +++ /dev/null @@ -1,212 +0,0 @@ -// MIT License - -// Copyright (c) 2017 Uber Technologies, Inc. - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -import test from 'tape-cup'; -import App from 'fusion-core'; -import {request} from 'fusion-test-utils'; -import plugin from '../../server.js'; - -test('Instantiation', t => { - const a = {}; - const b = {}; - const Emitter = plugin(); - t.notEqual(Emitter.of(a), Emitter.of(b)); - t.notEqual(Emitter.of(a), Emitter.of()); - t.end(); -}); - -test('Server EventEmitter - events from browser', async t => { - let called = false; - let globalCalled = false; - const mockCtx = { - method: 'POST', - path: '/_events', - request: { - body: { - items: [{type: 'a', payload: {x: 1}}], - }, - }, - timing: { - end: Promise.resolve(5), - }, - }; - const Emitter = plugin(); - const globalEmitter = Emitter.of(); - globalEmitter.on('a', ({x}, ctx) => { - t.equals(x, 1, 'payload is correct'); - t.equals(ctx, mockCtx, 'ctx is correct'); - globalCalled = true; - }); - const emitter = Emitter.of(mockCtx); - emitter.on('a', ({x}, ctx) => { - t.equals(x, 1, 'payload is correct'); - t.equals(ctx, mockCtx, 'ctx is correct'); - called = true; - }); - await Emitter.middleware(mockCtx, () => Promise.resolve()); - t.ok(called, 'called'); - t.ok(globalCalled, 'called global handler'); - t.end(); -}); - -test('Server EventEmitter - events with ctx', async t => { - let globalCalled = false; - const mockCtx = {mock: true}; - const Emitter = plugin(); - const globalEmitter = Emitter.of(); - globalEmitter.on('b', ({x}, ctx) => { - t.equals(x, 1, 'payload is correct'); - t.equals(ctx, mockCtx, 'ctx is correct'); - globalCalled = true; - }); - globalEmitter.emit('b', {x: 1}, mockCtx); - t.ok(globalCalled, 'called global handler'); - t.end(); -}); - -test('Server EventEmitter - mapping', async t => { - let called = false; - let globalCalled = false; - const ctx = { - method: 'POST', - path: '/lol', - timing: { - end: Promise.resolve(5), - }, - }; - const Emitter = plugin(); - const globalEmitter = Emitter.of(); - globalEmitter.on('a', (payload, c) => { - t.equal(c, ctx, 'ctx is passed to global handlers'); - t.deepLooseEqual( - payload, - {x: true, b: true, global: true}, - 'payload is correct for global' - ); - globalCalled = true; - }); - globalEmitter.map('a', (payload, c) => { - t.equal(c, ctx, 'ctx is passed to global mappers'); - return {...payload, global: true}; - }); - const emitter = Emitter.of(ctx); - emitter.on('a', (payload, c) => { - t.equal(c, ctx, 'ctx is passed to scoped handlers'); - t.deepLooseEqual( - payload, - {x: true, b: true, global: true}, - 'payload is correct' - ); - called = true; - }); - emitter.map('a', (payload, c) => { - t.equal(c, ctx, 'ctx is passed to scoped mappers'); - return {...payload, b: true}; - }); - emitter.emit('a', {x: 1}); - await Emitter.middleware(ctx, () => Promise.resolve()); - t.ok(called, 'called'); - t.ok(globalCalled, 'called global handler'); - t.end(); -}); - -test('Server EventEmitter batching', async t => { - const app = new App('fake-element', el => el); - const flags = { - preawait: false, - postawait: false, - postend: false, - timeout: false, - }; - const Emitter = app.plugin(plugin); - app.plugin(() => async (ctx, next) => { - const emitter = Emitter.of(ctx); - emitter.on('test-pre-await', ({x}) => { - t.equals(x, 1, 'payload is correct'); - flags.preawait = true; - }); - emitter.emit('test-pre-await', {x: 1}); - t.notOk(flags.preawait, 'batches pre await next events'); - t.notOk(emitter.flushed, 'waits to flush'); - return next(); - }); - - app.plugin(() => async (ctx, next) => { - const emitter = Emitter.of(ctx); - emitter.on('test-post-await', ({x, lol}) => { - t.equals(x, 1, 'payload is correct'); - t.ok(lol, 'runs mappers'); - flags.postawait = true; - }); - await next(); - emitter.emit('test-post-await', {x: 1}); - emitter.map(payload => { - return { - ...payload, - lol: true, - }; - }); - t.notOk(emitter.flushed, 'waits to flush'); - t.notOk(flags.postawait, 'batches post await next events'); - }); - - app.plugin(() => async (ctx, next) => { - const emitter = Emitter.of(ctx); - emitter.on('test-post-end', ({x, lol}) => { - t.equals(x, 1, 'payload is correct'); - t.ok(lol, 'runs mappers'); - flags.postend = true; - }); - ctx.timing.end.then(() => { - t.notOk(emitter.flushed, 'waits to flush'); - emitter.emit('test-post-end', {x: 1}); - t.notOk(flags.postend, 'batches post-end events'); - }); - return next(); - }); - - app.plugin(() => async (ctx, next) => { - const emitter = Emitter.of(ctx); - emitter.on('test-timeout', ({x, lol}) => { - t.equals(x, 1, 'payload is correct'); - t.ok(lol, 'runs mappers'); - flags.timeout = true; - }); - setTimeout(() => { - t.ok(emitter.flushed, 'has flushed events'); - emitter.emit('test-timeout', {x: 1}); - t.ok(flags.timeout, 'emits events immediately after flushing'); - }, 100); - return next(); - }); - - await request(app, '/lol', {method: 'POST'}); - - t.ok(flags.preawait, 'flushes batch from pre-await emitted events'); - t.ok(flags.postawait, 'flushes batch from post-await emitted events'); - t.ok(flags.postend, 'flushes batch from post-end emitted events'); - - setTimeout(() => { - t.ok(flags.timeout, 'supports emitting events after batch has flushed'); - t.end(); - }, 150); -}); diff --git a/src/__tests__/__browser__/index.js b/src/__tests__/test.browser.js similarity index 65% rename from src/__tests__/__browser__/index.js rename to src/__tests__/test.browser.js index b7d01794..1e8fac86 100644 --- a/src/__tests__/__browser__/index.js +++ b/src/__tests__/test.browser.js @@ -21,12 +21,22 @@ // SOFTWARE. import test from 'tape-cup'; -import plugin from '../../browser.js'; +import App from 'fusion-core'; +import {FetchToken} from 'fusion-tokens'; +import {render} from 'fusion-test-utils'; +import plugin from '../browser.js'; +import {UniversalEventsToken} from '../index'; -test('Browser EventEmitter', t => { +function getApp(fetch) { + const app = new App('el', el => el); + app.register(FetchToken, () => fetch); + app.register(UniversalEventsToken, plugin); + return app; +} + +test('Browser EventEmitter', async t => { let fetched = false; let emitted = false; - const ctx = {}; const fetch = (url, {method, headers, body}) => { t.equals(url, '/_events', 'url is ok'); t.equals(method, 'POST', 'method is ok'); @@ -41,21 +51,26 @@ test('Browser EventEmitter', t => { fetched = true; return Promise.resolve(); }; - const global = { - setInterval: () => {}, - clearInterval: () => {}, - addEventListener: () => {}, - removeEventListener: () => {}, - }; - const Emitter = plugin({fetch, global}); - const emitter = Emitter.of(ctx); - emitter.on('a', ({x}) => { - t.equals(x, 1, 'payload is correct'); - emitted = true; + const app = getApp(fetch); + app.middleware({events: UniversalEventsToken}, ({events}) => { + return (ctx, next) => { + const emitter = events.from(ctx); + t.equal(emitter, events); + emitter.on('a', ({x}) => { + t.equals(x, 1, 'payload is correct'); + emitted = true; + }); + emitter.emit('a', {x: 1}); + emitter.flush(); + emitter.teardown(); + return next(); + }; }); - emitter.emit('a', {x: 1}); - emitter.flush(); - emitter.teardown(); + + await render(app, '/'); + + await new Promise(resolve => setTimeout(resolve, 100)); + t.equals(emitted, true, 'emitted'); t.equals(fetched, true, 'fetched'); t.end(); diff --git a/src/__tests__/index.js b/src/__tests__/test.js similarity index 100% rename from src/__tests__/index.js rename to src/__tests__/test.js diff --git a/src/__tests__/test.node.js b/src/__tests__/test.node.js new file mode 100644 index 00000000..8be335ed --- /dev/null +++ b/src/__tests__/test.node.js @@ -0,0 +1,251 @@ +// MIT License + +// Copyright (c) 2017 Uber Technologies, Inc. + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import test from 'tape-cup'; +import App, {withDependencies, compose} from 'fusion-core'; +import {request} from 'fusion-test-utils'; +import UniversalEventsPlugin, {GlobalEmitter} from '../server.js'; +import {UniversalEventsToken} from '../index'; + +test('Instantiation', t => { + const a = { + memoized: new Map(), + }; + const b = { + memoized: new Map(), + }; + const Emitter = new GlobalEmitter(); + t.notEqual(Emitter.from(a), Emitter.from(b)); + t.notEqual(Emitter.from(a), Emitter); + t.end(); +}); + +test('Server EventEmitter - events from browser', async t => { + let called = false; + let globalCalled = false; + const mockCtx = { + headers: {}, + method: 'POST', + path: '/_events', + request: { + body: { + items: [{type: 'a', payload: {x: 1}}], + }, + }, + timing: { + end: Promise.resolve(5), + }, + }; + const app = new App('el', el => el); + app.register(UniversalEventsToken, UniversalEventsPlugin); + app.middleware({events: UniversalEventsToken}, ({events}) => { + events.on('a', ({x}, ctx) => { + t.equals(x, 1, 'payload is correct'); + t.ok(ctx); + globalCalled = true; + }); + return (ctx, next) => { + const ctxEmitter = events.from(ctx); + ctxEmitter.on('a', ({x}, ctx) => { + t.equals(x, 1, 'payload is correct'); + t.ok(ctx); + called = true; + }); + return next(); + }; + }); + app.resolve(); + try { + await compose(app.plugins)(mockCtx, () => Promise.resolve()); + t.ok(called, 'called'); + t.ok(globalCalled, 'called global handler'); + } catch (e) { + t.ifErr(e); + } + t.end(); +}); + +test('Server EventEmitter - events with ctx', async t => { + let globalCalled = false; + const mockCtx = {mock: true}; + const app = new App('el', el => el); + app.register(UniversalEventsToken, UniversalEventsPlugin); + app.register( + withDependencies({events: UniversalEventsToken})(({events}) => { + events.on('b', ({x}, ctx) => { + t.equals(x, 1, 'payload is correct'); + t.equals(ctx, mockCtx, 'ctx is correct'); + globalCalled = true; + }); + events.emit('b', {x: 1}, mockCtx); + t.ok(globalCalled, 'called global handler'); + t.end(); + }) + ); + app.resolve(); +}); + +test('Server EventEmitter - mapping', async t => { + let called = false; + let globalCalled = false; + const mockCtx = { + headers: {}, + method: 'POST', + path: '/lol', + timing: { + end: Promise.resolve(5), + }, + }; + const app = new App('fake-element', el => el); + app.register(UniversalEventsToken, UniversalEventsPlugin); + app.middleware({events: UniversalEventsToken}, ({events}) => { + events.on('a', (payload, c) => { + t.equal(c, mockCtx, 'ctx is passed to global handlers'); + t.deepLooseEqual( + payload, + {x: true, b: true, global: true}, + 'payload is correct for global' + ); + globalCalled = true; + }); + events.map('a', (payload, c) => { + t.equal(c, mockCtx, 'ctx is passed to global mappers'); + return {...payload, global: true}; + }); + return (ctx, next) => { + const emitter = events.from(ctx); + emitter.on('a', (payload, c) => { + t.equal(c, ctx, 'ctx is passed to scoped handlers'); + t.deepLooseEqual( + payload, + {x: true, b: true, global: true}, + 'payload is correct' + ); + called = true; + }); + emitter.map('a', (payload, c) => { + t.equal(c, ctx, 'ctx is passed to scoped mappers'); + return {...payload, b: true}; + }); + emitter.emit('a', {x: 1}); + return next(); + }; + }); + app.resolve(); + try { + await compose(app.plugins)(mockCtx, () => Promise.resolve()); + t.ok(called, 'called'); + t.ok(globalCalled, 'called global handler'); + } catch (e) { + t.ifErr(e); + } + t.end(); +}); + +test('Server EventEmitter batching', async t => { + const app = new App('fake-element', el => el); + const flags = { + preawait: false, + postawait: false, + postend: false, + timeout: false, + }; + app.register(UniversalEventsToken, UniversalEventsPlugin); + app.middleware({events: UniversalEventsToken}, ({events}) => { + return async (ctx, next) => { + const emitter = events.from(ctx); + emitter.on('test-pre-await', ({x}) => { + t.equals(x, 1, 'payload is correct'); + flags.preawait = true; + }); + emitter.emit('test-pre-await', {x: 1}); + t.notOk(flags.preawait, 'batches pre await next events'); + t.notOk(emitter.flushed, 'waits to flush'); + return next(); + }; + }); + + app.middleware({events: UniversalEventsToken}, ({events}) => { + return async (ctx, next) => { + const emitter = events.from(ctx); + emitter.on('test-post-await', ({x, lol}) => { + t.equals(x, 1, 'payload is correct'); + t.ok(lol, 'runs mappers'); + flags.postawait = true; + }); + await next(); + emitter.emit('test-post-await', {x: 1}); + emitter.map(payload => { + return { + ...payload, + lol: true, + }; + }); + t.notOk(emitter.flushed, 'waits to flush'); + t.notOk(flags.postawait, 'batches post await next events'); + }; + }); + + app.middleware({events: UniversalEventsToken}, ({events}) => { + return async (ctx, next) => { + const emitter = events.from(ctx); + emitter.on('test-post-end', ({x, lol}) => { + t.equals(x, 1, 'payload is correct'); + t.ok(lol, 'runs mappers'); + flags.postend = true; + }); + ctx.timing.end.then(() => { + t.notOk(emitter.flushed, 'waits to flush'); + emitter.emit('test-post-end', {x: 1}); + t.notOk(flags.postend, 'batches post-end events'); + }); + return next(); + }; + }); + + app.middleware({events: UniversalEventsToken}, ({events}) => { + return async (ctx, next) => { + const emitter = events.from(ctx); + emitter.on('test-timeout', ({x, lol}) => { + t.equals(x, 1, 'payload is correct'); + t.ok(lol, 'runs mappers'); + flags.timeout = true; + }); + setTimeout(() => { + t.ok(emitter.flushed, 'has flushed events'); + emitter.emit('test-timeout', {x: 1}); + t.ok(flags.timeout, 'emits events immediately after flushing'); + }, 100); + return next(); + }; + }); + + await request(app, '/lol', {method: 'POST'}); + + setTimeout(() => { + t.ok(flags.preawait, 'flushes batch from pre-await emitted events'); + t.ok(flags.postawait, 'flushes batch from post-await emitted events'); + t.ok(flags.postend, 'flushes batch from post-end emitted events'); + t.ok(flags.timeout, 'supports emitting events after batch has flushed'); + t.end(); + }, 150); +}); diff --git a/src/browser.js b/src/browser.js index 28a32d14..6c9455fc 100644 --- a/src/browser.js +++ b/src/browser.js @@ -21,47 +21,55 @@ // SOFTWARE. /* eslint-env browser */ -import {SingletonPlugin} from 'fusion-core'; +import {withDependencies} from 'fusion-core'; +import {FetchToken} from 'fusion-tokens'; import Emitter from './emitter'; -export default function({fetch = window.fetch, global = window} = {}) { - return new SingletonPlugin({ - Service: class UniversalEmitter extends Emitter { - constructor() { - super(); - //privates - this.batch = []; - this.flush = this.flush.bind(this); - this.setFrequency(5000); - global.addEventListener('beforeunload', this.flush); - } - setFrequency(frequency) { - global.clearInterval(this.interval); - this.interval = global.setInterval(this.flush, frequency); - } - emit(type, payload) { - payload = super.mapEvent(type, payload); - super.handleEvent(type, payload); - this.batch.push({type, payload}); - } - flush() { - if (this.batch.length > 0) { - fetch('/_events', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({items: this.batch} || []), - }).catch(() => {}); - } - this.batch = []; - } - teardown() { - global.removeEventListener('beforeunload', this.flush); - global.clearInterval(this.interval); - this.interval = null; - this.batch = []; - } - }, - }); +class UniversalEmitter extends Emitter { + constructor(fetch) { + super(); + //privates + this.batch = []; + this.flush = this.flush.bind(this); + this.fetch = fetch; + this.setFrequency(5000); + addEventListener('beforeunload', this.flush); + } + setFrequency(frequency) { + clearInterval(this.interval); + this.interval = setInterval(this.flush, frequency); + } + emit(type, payload) { + payload = super.mapEvent(type, payload); + super.handleEvent(type, payload); + this.batch.push({type, payload}); + } + // match server api + from() { + return this; + } + flush() { + if (this.batch.length > 0) { + this.fetch('/_events', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({items: this.batch} || []), + }).catch(() => {}); + } + this.batch = []; + } + teardown() { + removeEventListener('beforeunload', this.flush); + clearInterval(this.interval); + this.interval = null; + this.batch = []; + } } + +const plugin = withDependencies({fetch: FetchToken})(({fetch}) => { + return new UniversalEmitter(fetch); +}); + +export default plugin; diff --git a/src/index.js b/src/index.js index 66d5b678..a8540b2e 100644 --- a/src/index.js +++ b/src/index.js @@ -20,9 +20,12 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +import {createToken} from 'fusion-tokens'; import ServerEvents from './server.js'; import BrowserEvents from './browser.js'; const UniversalEvents = __BROWSER__ ? BrowserEvents : ServerEvents; export default UniversalEvents; + +export const UniversalEventsToken = createToken(UniversalEvents); diff --git a/src/server.js b/src/server.js index 29d7965b..4d1e7aa0 100644 --- a/src/server.js +++ b/src/server.js @@ -21,81 +21,86 @@ // SOFTWARE. /* eslint-env node */ -import {Plugin} from 'fusion-core'; +import {withMiddleware, memoize} from 'fusion-core'; import Emitter from './emitter'; +export class GlobalEmitter extends Emitter { + constructor() { + super(); + this.from = memoize(ctx => { + return new ScopedEmitter(ctx, this); + }); + } + emit(type, payload, ctx) { + payload = super.mapEvent(type, payload, this.ctx); + super.handleEvent(type, payload, ctx); + } + // mirror browser api + setFrequency() {} + teardown() {} +} + +class ScopedEmitter extends Emitter { + constructor(ctx, parent) { + super(); + this.ctx = ctx; + this.parent = parent; + this.batch = []; + this.flushed = false; + } + emit(type, payload) { + // this logic exists to manage ensuring we send events after the batch + if (this.flushed) { + this.handleBatchedEvent({type, payload}); + } else { + this.batch.push({type, payload}); + } + } + handleBatchedEvent({type, payload}) { + payload = super.mapEvent(type, payload, this.ctx); + payload = this.parent.mapEvent(type, payload, this.ctx); + super.handleEvent(type, payload, this.ctx); + this.parent.handleEvent(type, payload, this.ctx); + } + flush() { + for (let index = 0; index < this.batch.length; index++) { + this.handleBatchedEvent(this.batch[index]); + } + this.batch = []; + this.flushed = true; + } + // mirror browser api + setFrequency() {} + teardown() {} +} + export default function() { const bodyParser = require('koa-bodyparser'); const parseBody = bodyParser(); - const plugin = new Plugin({ - Service: class UniversalEmitter extends Emitter { - constructor(ctx) { - super(); - this.ctx = ctx; - if (this.ctx) { - this.parent = plugin.of(); - this.batch = []; - this.flushed = false; - } - } - emit(type, payload, ctx) { - if (!this.ctx) { - payload = super.mapEvent(type, payload, this.ctx); - super.handleEvent(type, payload, ctx); - } else { - // this logic exists to manage ensuring we send events after the batch - if (this.flushed) { - this.handleBatchedEvent({type, payload}); - } else { - this.batch.push({type, payload}); - } - } - } - handleBatchedEvent({type, payload}) { - payload = super.mapEvent(type, payload, this.ctx); - payload = this.parent.mapEvent(type, payload, this.ctx); - super.handleEvent(type, payload, this.ctx); - this.parent.handleEvent(type, payload, this.ctx); - } - flush() { - if (!this.ctx) { - throw new Error( - 'Cannot call flush from the global instance of UniversalEmitter. Try using `UniversalEmitter.of(ctx)`' - ); - } - for (let index = 0; index < this.batch.length; index++) { - this.handleBatchedEvent(this.batch[index]); - } - this.batch = []; - this.flushed = true; - } - // mirror browser api - setFrequency() {} - teardown() {} - }, - async middleware(ctx, next) { - const emitter = this.of(ctx); - if (!ctx.body && ctx.method === 'POST' && ctx.path === '/_events') { - await parseBody(ctx, async () => {}); - const {items} = ctx.request.body; - if (items) { - for (let index = 0; index < items.length; index++) { - const {type, payload} = items[index]; - emitter.emit(type, payload); - } - ctx.status = 200; - } else { - ctx.status = 400; + const globalEmitter = new GlobalEmitter(); + + async function universalEventsMiddleware(ctx, next) { + const emitter = globalEmitter.from(ctx); + if (ctx.method === 'POST' && ctx.path === '/_events') { + await parseBody(ctx, async () => {}); + const {items} = ctx.request.body; + if (items) { + for (let index = 0; index < items.length; index++) { + const {type, payload} = items[index]; + emitter.emit(type, payload); } + ctx.status = 200; + } else { + ctx.status = 400; } - // awaiting next before registering `then` on ctx.timing.end to try and get as much as possible - // into the event batch flush. - await next(); - ctx.timing.end.then(() => { - emitter.flush(); - }); - }, - }); - return plugin; + } + // awaiting next before registering `then` on ctx.timing.end to try and get as much as possible + // into the event batch flush. + await next(); + ctx.timing.end.then(() => { + emitter.flush(); + }); + } + return withMiddleware(globalEmitter, universalEventsMiddleware); } diff --git a/yarn.lock b/yarn.lock index 64e3b449..6c8857a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,25 +10,33 @@ esutils "^2.0.2" js-tokens "^3.0.0" -"@babel/code-frame@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.34.tgz#e8e81e37ee65a35cedc8a22a11a51d792bdc651c" +"@babel/code-frame@7.0.0-beta.36": + version "7.0.0-beta.36" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.36.tgz#2349d7ec04b3a06945ae173280ef8579b63728e4" dependencies: chalk "^2.0.0" esutils "^2.0.2" js-tokens "^3.0.0" -"@babel/core@^7.0.0-beta.31": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.34.tgz#576863223bcb4d003e9450b2a4c5076a626be966" - dependencies: - "@babel/code-frame" "7.0.0-beta.34" - "@babel/generator" "7.0.0-beta.34" - "@babel/helpers" "7.0.0-beta.34" - "@babel/template" "7.0.0-beta.34" - "@babel/traverse" "7.0.0-beta.34" - "@babel/types" "7.0.0-beta.34" - babylon "7.0.0-beta.34" +"@babel/code-frame@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.37.tgz#2da1dd3b1b57bfdea777ddc378df7cd12fe40171" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +"@babel/core@^7.0.0-beta.36": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.37.tgz#a6291a7892643e36b721e56bcf132d9cc1b65b08" + dependencies: + "@babel/code-frame" "7.0.0-beta.37" + "@babel/generator" "7.0.0-beta.37" + "@babel/helpers" "7.0.0-beta.37" + "@babel/template" "7.0.0-beta.37" + "@babel/traverse" "7.0.0-beta.37" + "@babel/types" "7.0.0-beta.37" + babylon "7.0.0-beta.37" convert-source-map "^1.1.0" debug "^3.0.1" json5 "^0.5.0" @@ -37,11 +45,11 @@ resolve "^1.3.2" source-map "^0.5.0" -"@babel/generator@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.34.tgz#1a98992f3ef9e61a6007830883dfa2dbb26c622d" +"@babel/generator@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.37.tgz#df5183995f20af4afe3bd5499a4c1336355fc163" dependencies: - "@babel/types" "7.0.0-beta.34" + "@babel/types" "7.0.0-beta.37" jsesc "^2.5.1" lodash "^4.2.0" source-map "^0.5.0" @@ -53,11 +61,11 @@ dependencies: "@babel/types" "7.0.0-beta.31" -"@babel/helper-annotate-as-pure@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.34.tgz#f3c8951dc87f5700d6cc41cae8fa0db43393bc4e" +"@babel/helper-annotate-as-pure@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.37.tgz#9c10fb9c17d36837c9d29a5d5de6fee963402b71" dependencies: - "@babel/types" "7.0.0-beta.34" + "@babel/types" "7.0.0-beta.37" "@babel/helper-builder-binary-assignment-operator-visitor@7.0.0-beta.31": version "7.0.0-beta.31" @@ -98,13 +106,21 @@ "@babel/traverse" "7.0.0-beta.31" "@babel/types" "7.0.0-beta.31" -"@babel/helper-function-name@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.34.tgz#eb27e7ebc299b66981100005642bf50946cb14f9" +"@babel/helper-function-name@7.0.0-beta.36": + version "7.0.0-beta.36" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.36.tgz#366e3bc35147721b69009f803907c4d53212e88d" + dependencies: + "@babel/helper-get-function-arity" "7.0.0-beta.36" + "@babel/template" "7.0.0-beta.36" + "@babel/types" "7.0.0-beta.36" + +"@babel/helper-function-name@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.37.tgz#add0b76b2947b495a95498de9f2096808c29d2d7" dependencies: - "@babel/helper-get-function-arity" "7.0.0-beta.34" - "@babel/template" "7.0.0-beta.34" - "@babel/types" "7.0.0-beta.34" + "@babel/helper-get-function-arity" "7.0.0-beta.37" + "@babel/template" "7.0.0-beta.37" + "@babel/types" "7.0.0-beta.37" "@babel/helper-get-function-arity@7.0.0-beta.31": version "7.0.0-beta.31" @@ -112,11 +128,17 @@ dependencies: "@babel/types" "7.0.0-beta.31" -"@babel/helper-get-function-arity@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.34.tgz#e3dd0a72086a739c587424abd26fd3012a8b1eec" +"@babel/helper-get-function-arity@7.0.0-beta.36": + version "7.0.0-beta.36" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.36.tgz#f5383bac9a96b274828b10d98900e84ee43e32b8" dependencies: - "@babel/types" "7.0.0-beta.34" + "@babel/types" "7.0.0-beta.36" + +"@babel/helper-get-function-arity@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.37.tgz#430fec8d4bc804f20c84ee0ba63a807edf1fb0c1" + dependencies: + "@babel/types" "7.0.0-beta.37" "@babel/helper-hoist-variables@7.0.0-beta.31": version "7.0.0-beta.31" @@ -153,9 +175,9 @@ dependencies: lodash "^4.2.0" -"@babel/helper-regex@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0-beta.34.tgz#761224365616ef0652491920848fd27cf65f85d2" +"@babel/helper-regex@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0-beta.37.tgz#5bd439b6c22817c1afe4a9f6442c65ca79cfcef1" dependencies: lodash "^4.2.0" @@ -168,15 +190,15 @@ "@babel/traverse" "7.0.0-beta.31" "@babel/types" "7.0.0-beta.31" -"@babel/helper-remap-async-to-generator@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.34.tgz#30d0ecc53e203a0d029ebc056726c3a07d545443" +"@babel/helper-remap-async-to-generator@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.37.tgz#812827a4dd35ded898dbab9e8d72ce4fe72881d7" dependencies: - "@babel/helper-annotate-as-pure" "7.0.0-beta.34" - "@babel/helper-wrap-function" "7.0.0-beta.34" - "@babel/template" "7.0.0-beta.34" - "@babel/traverse" "7.0.0-beta.34" - "@babel/types" "7.0.0-beta.34" + "@babel/helper-annotate-as-pure" "7.0.0-beta.37" + "@babel/helper-wrap-function" "7.0.0-beta.37" + "@babel/template" "7.0.0-beta.37" + "@babel/traverse" "7.0.0-beta.37" + "@babel/types" "7.0.0-beta.37" "@babel/helper-replace-supers@7.0.0-beta.31": version "7.0.0-beta.31" @@ -204,22 +226,22 @@ "@babel/traverse" "7.0.0-beta.31" "@babel/types" "7.0.0-beta.31" -"@babel/helper-wrap-function@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.34.tgz#dd17517c73c3ded126d295d848af93aa3ca8f316" +"@babel/helper-wrap-function@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.37.tgz#2a20694049099ea6a1762db46ee3817bd1f63256" dependencies: - "@babel/helper-function-name" "7.0.0-beta.34" - "@babel/template" "7.0.0-beta.34" - "@babel/traverse" "7.0.0-beta.34" - "@babel/types" "7.0.0-beta.34" + "@babel/helper-function-name" "7.0.0-beta.37" + "@babel/template" "7.0.0-beta.37" + "@babel/traverse" "7.0.0-beta.37" + "@babel/types" "7.0.0-beta.37" -"@babel/helpers@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.0.0-beta.34.tgz#899dbe0a01c7a93a342860736ecf6419e2cc8591" +"@babel/helpers@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.0.0-beta.37.tgz#d811eef60749883b0249f48a00d681b8b3344a92" dependencies: - "@babel/template" "7.0.0-beta.34" - "@babel/traverse" "7.0.0-beta.34" - "@babel/types" "7.0.0-beta.34" + "@babel/template" "7.0.0-beta.37" + "@babel/traverse" "7.0.0-beta.37" + "@babel/types" "7.0.0-beta.37" "@babel/plugin-check-constants@7.0.0-beta.31": version "7.0.0-beta.31" @@ -232,19 +254,19 @@ "@babel/helper-remap-async-to-generator" "7.0.0-beta.31" "@babel/plugin-syntax-async-generators" "7.0.0-beta.31" -"@babel/plugin-proposal-async-generator-functions@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-beta.34.tgz#0a7b6385653b0df8b082d7f28ab4d1be05332386" +"@babel/plugin-proposal-async-generator-functions@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-beta.37.tgz#4c1f5635a06c84c6f1c880bb10f23ce4ae6f8d58" dependencies: - "@babel/helper-remap-async-to-generator" "7.0.0-beta.34" - "@babel/plugin-syntax-async-generators" "7.0.0-beta.34" + "@babel/helper-remap-async-to-generator" "7.0.0-beta.37" + "@babel/plugin-syntax-async-generators" "7.0.0-beta.37" -"@babel/plugin-proposal-class-properties@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-beta.34.tgz#3008cbe8d48f36a0610eebf78ef64dc3029a7f87" +"@babel/plugin-proposal-class-properties@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-beta.37.tgz#0991e720ed24fa452b02e86183aca8e890a8d2cf" dependencies: - "@babel/helper-function-name" "7.0.0-beta.34" - "@babel/plugin-syntax-class-properties" "7.0.0-beta.34" + "@babel/helper-function-name" "7.0.0-beta.37" + "@babel/plugin-syntax-class-properties" "7.0.0-beta.37" "@babel/plugin-proposal-object-rest-spread@7.0.0-beta.31": version "7.0.0-beta.31" @@ -252,11 +274,11 @@ dependencies: "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.31" -"@babel/plugin-proposal-object-rest-spread@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.34.tgz#46720e93548d7504a11933b720bd3784426a9026" +"@babel/plugin-proposal-object-rest-spread@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.37.tgz#627d5c17f08c8c1878ff9dd5b46cbe1868ca2305" dependencies: - "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.34" + "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.37" "@babel/plugin-proposal-optional-catch-binding@7.0.0-beta.31": version "7.0.0-beta.31" @@ -264,11 +286,11 @@ dependencies: "@babel/plugin-syntax-optional-catch-binding" "7.0.0-beta.31" -"@babel/plugin-proposal-optional-catch-binding@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0-beta.34.tgz#c38835ef180116d05ed57e4a6db6e77c97177fdc" +"@babel/plugin-proposal-optional-catch-binding@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0-beta.37.tgz#f00ed3ca6df309ab62d5dd414ec3e170945a85a2" dependencies: - "@babel/plugin-syntax-optional-catch-binding" "7.0.0-beta.34" + "@babel/plugin-syntax-optional-catch-binding" "7.0.0-beta.37" "@babel/plugin-proposal-unicode-property-regex@7.0.0-beta.31": version "7.0.0-beta.31" @@ -277,44 +299,52 @@ "@babel/helper-regex" "7.0.0-beta.31" regexpu-core "^4.1.3" -"@babel/plugin-proposal-unicode-property-regex@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0-beta.34.tgz#7f22b2ec60e79b0394bf2a4e396eee1ef677db5b" +"@babel/plugin-proposal-unicode-property-regex@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0-beta.37.tgz#836f7df7571cee11cf749ed3c0e989a70570d14a" dependencies: - "@babel/helper-regex" "7.0.0-beta.34" + "@babel/helper-regex" "7.0.0-beta.37" regexpu-core "^4.1.3" "@babel/plugin-syntax-async-generators@7.0.0-beta.31": version "7.0.0-beta.31" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.31.tgz#f7347f918941c2106b246adfa87bdc439d797e01" -"@babel/plugin-syntax-async-generators@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.34.tgz#8f3990ec7f98ded0ede1edc65a636bebc63fa34b" +"@babel/plugin-syntax-async-generators@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.37.tgz#6c5d102534a9e7c0fa1af9b751756a1866b5d01a" + +"@babel/plugin-syntax-class-properties@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-beta.37.tgz#5d4e4712ee57815ebe59e63fb084353a27e2671d" -"@babel/plugin-syntax-class-properties@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-beta.34.tgz#d345b262622ff9500d9ad039aa0b77a94b4b8dd5" +"@babel/plugin-syntax-dynamic-import@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.0.0-beta.37.tgz#cac79651c3ab6b3cd9c0898c801b2518dd9379aa" -"@babel/plugin-syntax-dynamic-import@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.0.0-beta.34.tgz#05b1e58e4c3f412edb28aa0346c14c5f13c41b46" +"@babel/plugin-syntax-flow@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0-beta.37.tgz#e6467f3cc3b56806c300a1cd4fea37c5ab8020c6" + +"@babel/plugin-syntax-import-meta@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.0.0-beta.37.tgz#3ccd614cc8d49a324298cd26f7f2f2f7f1651949" "@babel/plugin-syntax-object-rest-spread@7.0.0-beta.31": version "7.0.0-beta.31" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.31.tgz#bd0f67210b3022182dc50d155393ccec720ca039" -"@babel/plugin-syntax-object-rest-spread@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.34.tgz#01883a3e6e29d842e88c54d146addd88eedbe0e8" +"@babel/plugin-syntax-object-rest-spread@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.37.tgz#52a6cac2234ff859e21a8ced4d794bbe43210561" "@babel/plugin-syntax-optional-catch-binding@7.0.0-beta.31": version "7.0.0-beta.31" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0-beta.31.tgz#9a999ecc49c6c55bd040622bcf6661824bdaa088" -"@babel/plugin-syntax-optional-catch-binding@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0-beta.34.tgz#b677c0863cd2373b46fc57728277212f331d6c2e" +"@babel/plugin-syntax-optional-catch-binding@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0-beta.37.tgz#d0fe8d2d8d301eb677696eecf159a3089d57b23a" "@babel/plugin-transform-arrow-functions@7.0.0-beta.31": version "7.0.0-beta.31" @@ -375,6 +405,12 @@ dependencies: "@babel/helper-builder-binary-assignment-operator-visitor" "7.0.0-beta.31" +"@babel/plugin-transform-flow-strip-types@^7.0.0-beta.36": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.0.0-beta.37.tgz#749b005300334fa474e18b82b22b869fdfe68fed" + dependencies: + "@babel/plugin-syntax-flow" "7.0.0-beta.37" + "@babel/plugin-transform-for-of@7.0.0-beta.31": version "7.0.0-beta.31" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0-beta.31.tgz#238c3157eb95859bf3fc35fe12b92869264f4fdf" @@ -477,16 +513,17 @@ "@babel/helper-regex" "7.0.0-beta.31" regexpu-core "^4.1.3" -"@babel/preset-stage-3@^7.0.0-beta.31": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/preset-stage-3/-/preset-stage-3-7.0.0-beta.34.tgz#0de1c1833f337c29ab4e7547fbd1d0005b726fd1" +"@babel/preset-stage-3@^7.0.0-beta.36": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/preset-stage-3/-/preset-stage-3-7.0.0-beta.37.tgz#c92b9becd08177fcb03e342d4de68f70df1d84af" dependencies: - "@babel/plugin-proposal-async-generator-functions" "7.0.0-beta.34" - "@babel/plugin-proposal-class-properties" "7.0.0-beta.34" - "@babel/plugin-proposal-object-rest-spread" "7.0.0-beta.34" - "@babel/plugin-proposal-optional-catch-binding" "7.0.0-beta.34" - "@babel/plugin-proposal-unicode-property-regex" "7.0.0-beta.34" - "@babel/plugin-syntax-dynamic-import" "7.0.0-beta.34" + "@babel/plugin-proposal-async-generator-functions" "7.0.0-beta.37" + "@babel/plugin-proposal-class-properties" "7.0.0-beta.37" + "@babel/plugin-proposal-object-rest-spread" "7.0.0-beta.37" + "@babel/plugin-proposal-optional-catch-binding" "7.0.0-beta.37" + "@babel/plugin-proposal-unicode-property-regex" "7.0.0-beta.37" + "@babel/plugin-syntax-dynamic-import" "7.0.0-beta.37" + "@babel/plugin-syntax-import-meta" "7.0.0-beta.37" "@babel/template@7.0.0-beta.31": version "7.0.0-beta.31" @@ -497,13 +534,22 @@ babylon "7.0.0-beta.31" lodash "^4.2.0" -"@babel/template@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.34.tgz#35fa7eb6c540f4619927ec1c1b113719ecc59446" +"@babel/template@7.0.0-beta.36": + version "7.0.0-beta.36" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.36.tgz#02e903de5d68bd7899bce3c5b5447e59529abb00" dependencies: - "@babel/code-frame" "7.0.0-beta.34" - "@babel/types" "7.0.0-beta.34" - babylon "7.0.0-beta.34" + "@babel/code-frame" "7.0.0-beta.36" + "@babel/types" "7.0.0-beta.36" + babylon "7.0.0-beta.36" + lodash "^4.2.0" + +"@babel/template@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.37.tgz#d51a5c8c7bfc1ff08f3623231b7d388a9e9b3570" + dependencies: + "@babel/code-frame" "7.0.0-beta.37" + "@babel/types" "7.0.0-beta.37" + babylon "7.0.0-beta.37" lodash "^4.2.0" "@babel/traverse@7.0.0-beta.31": @@ -519,16 +565,29 @@ invariant "^2.2.0" lodash "^4.2.0" -"@babel/traverse@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.34.tgz#c352fc560e1c78198ee52252c780fe848235fdfe" +"@babel/traverse@7.0.0-beta.36": + version "7.0.0-beta.36" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.36.tgz#1dc6f8750e89b6b979de5fe44aa993b1a2192261" dependencies: - "@babel/code-frame" "7.0.0-beta.34" - "@babel/helper-function-name" "7.0.0-beta.34" - "@babel/types" "7.0.0-beta.34" - babylon "7.0.0-beta.34" + "@babel/code-frame" "7.0.0-beta.36" + "@babel/helper-function-name" "7.0.0-beta.36" + "@babel/types" "7.0.0-beta.36" + babylon "7.0.0-beta.36" debug "^3.0.1" - globals "^10.0.0" + globals "^11.1.0" + invariant "^2.2.0" + lodash "^4.2.0" + +"@babel/traverse@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.37.tgz#50fe6d841521cebb1486cf5e398f34b007a86812" + dependencies: + "@babel/code-frame" "7.0.0-beta.37" + "@babel/helper-function-name" "7.0.0-beta.37" + "@babel/types" "7.0.0-beta.37" + babylon "7.0.0-beta.37" + debug "^3.0.1" + globals "^11.1.0" invariant "^2.2.0" lodash "^4.2.0" @@ -540,9 +599,17 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" -"@babel/types@7.0.0-beta.34": - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.34.tgz#ce8da730b834c782ec64a2baf3ac0200dd328816" +"@babel/types@7.0.0-beta.36": + version "7.0.0-beta.36" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.36.tgz#64f2004353de42adb72f9ebb4665fc35b5499d23" + dependencies: + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^2.0.0" + +"@babel/types@7.0.0-beta.37": + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.37.tgz#fa93af9aa9d85c331729bb923495af04d9b0617d" dependencies: esutils "^2.0.2" lodash "^4.2.0" @@ -634,8 +701,8 @@ acorn-jsx@^3.0.0: acorn "^3.0.4" acorn@>=2.5.2, acorn@^5.0.0, acorn@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" + version "5.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.3.0.tgz#7446d39459c54fb49a80e6ee6478149b940ec822" acorn@^3.0.4: version "3.3.0" @@ -657,8 +724,8 @@ ajv@^4.9.1: json-stable-stringify "^1.0.1" ajv@^5.1.5, ajv@^5.2.3, ajv@^5.3.0: - version "5.5.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.1.tgz#b38bb8876d9e86bee994956a04e721e88b248eb2" + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" @@ -737,7 +804,7 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -args@^3.0.7: +args@^3.0.8: version "3.0.8" resolved "https://registry.yarnpkg.com/args/-/args-3.0.8.tgz#2f425ab639c69d74ff728f3d7c6e93b97b91af7c" dependencies: @@ -810,7 +877,7 @@ assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" -assert@^1.1.1: +assert@^1.1.1, assert@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" dependencies: @@ -858,14 +925,16 @@ babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: esutils "^2.0.2" js-tokens "^3.0.2" -babel-eslint@^8.0.2: - version "8.0.3" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.0.3.tgz#f29ecf02336be438195325cd47c468da81ee4e98" +babel-eslint@^8.2.1: + version "8.2.1" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.1.tgz#136888f3c109edc65376c23ebf494f36a3e03951" dependencies: - "@babel/code-frame" "7.0.0-beta.31" - "@babel/traverse" "7.0.0-beta.31" - "@babel/types" "7.0.0-beta.31" - babylon "7.0.0-beta.31" + "@babel/code-frame" "7.0.0-beta.36" + "@babel/traverse" "7.0.0-beta.36" + "@babel/types" "7.0.0-beta.36" + babylon "7.0.0-beta.36" + eslint-scope "~3.7.1" + eslint-visitor-keys "^1.0.0" babel-generator@^6.18.0: version "6.26.0" @@ -950,9 +1019,13 @@ babylon@7.0.0-beta.31: version "7.0.0-beta.31" resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.31.tgz#7ec10f81e0e456fd0f855ad60fa30c2ac454283f" -babylon@7.0.0-beta.34: - version "7.0.0-beta.34" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.34.tgz#2ccdf97bb4fbc1617619a030a6c0390b2c8f16d6" +babylon@7.0.0-beta.36: + version "7.0.0-beta.36" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.36.tgz#3a3683ba6a9a1e02b0aa507c8e63435e39305b9e" + +babylon@7.0.0-beta.37: + version "7.0.0-beta.37" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.37.tgz#55a9eacab576c2d5e2832bc7b49a567e7c64bbc9" babylon@^6.18.0: version "6.18.0" @@ -1068,11 +1141,11 @@ browserify-zlib@^0.2.0: pako "~1.0.5" browserslist@^2.4.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.10.0.tgz#bac5ee1cc69ca9d96403ffb8a3abdc5b6aed6346" + version "2.11.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.1.tgz#02fda29d9a2164b879100126e7b0d0b57e43a7bb" dependencies: - caniuse-lite "^1.0.30000780" - electron-to-chromium "^1.3.28" + caniuse-lite "^1.0.30000789" + electron-to-chromium "^1.3.30" buffer-xor@^1.0.3: version "1.0.3" @@ -1086,7 +1159,7 @@ buffer@^4.3.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" @@ -1124,9 +1197,9 @@ camelcase@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" -caniuse-lite@^1.0.30000780: - version "1.0.30000782" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000782.tgz#5b82b8c385f25348745c471ca51320afb1b7f254" +caniuse-lite@^1.0.30000789: + version "1.0.30000791" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000791.tgz#8e35745efd483a3e23bb7d350990326d2319fc16" caseless@~0.12.0: version "0.12.0" @@ -1241,6 +1314,14 @@ cliui@^3.2.0: strip-ansi "^3.0.1" wrap-ansi "^2.0.0" +cliui@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc" + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + co-body@^5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/co-body/-/co-body-5.1.1.tgz#d97781d1e3344ba4a820fd1806bddf8341505236" @@ -1308,6 +1389,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.0: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" @@ -1370,29 +1455,30 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" -create-universal-package@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/create-universal-package/-/create-universal-package-2.1.1.tgz#170877cb6725d8494efb757005eb5aca9ee5edde" +create-universal-package@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/create-universal-package/-/create-universal-package-3.2.4.tgz#3cb03ce00a04d3e9bba5bf64dd272da5185a3b6b" dependencies: - "@babel/core" "^7.0.0-beta.31" - "@babel/preset-stage-3" "^7.0.0-beta.31" + "@babel/core" "^7.0.0-beta.36" + "@babel/plugin-transform-flow-strip-types" "^7.0.0-beta.36" + "@babel/preset-stage-3" "^7.0.0-beta.36" "@rtsao/babel-preset-env" "^7.0.0-beta.31" - args "^3.0.7" + args "^3.0.8" babel-plugin-istanbul "^4.1.5" babel-plugin-transform-cup-globals "^1.0.0" chalk "^2.3.0" draftlog "^1.0.12" fast-async "^6.3.0" import-lazy "^3.1.0" - jest-worker "^21.3.0-beta.8" + jest-worker "^22.0.3" loader-utils "^1.1.0" multi-entry-loader "^1.1.2" rimraf "^2.6.2" - rollup "^0.51.1" + rollup "^0.53.2" rollup-plugin-memory "^2.0.0" rollup-plugin-multi-entry "^2.0.2" rollup-pluginutils "^2.0.1" - webpack "^3.8.1" + webpack "^3.10.0" cross-spawn@^4: version "4.0.2" @@ -1457,7 +1543,7 @@ debug@*, debug@^3.0.1, debug@^3.1.0: dependencies: ms "2.0.0" -debug@^2.2.0, debug@^2.6.8: +debug@^2.2.0, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: @@ -1516,10 +1602,14 @@ delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" -depd@1.1.1, depd@^1.1.0, depd@~1.1.1: +depd@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" +depd@^1.1.0, depd@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + des.js@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" @@ -1549,9 +1639,16 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + doctrine@^2.0.0, doctrine@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075" + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" dependencies: esutils "^2.0.2" @@ -1573,9 +1670,15 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -electron-to-chromium@^1.3.28: - version "1.3.28" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.28.tgz#8dd4e6458086644e9f9f0a1cf32e2a1f9dffd9ee" +electron-releases@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/electron-releases/-/electron-releases-2.1.0.tgz#c5614bf811f176ce3c836e368a0625782341fd4e" + +electron-to-chromium@^1.3.30: + version "1.3.30" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz#9666f532a64586651fc56a72513692e820d06a80" + dependencies: + electron-releases "^2.1.0" elliptic@^6.0.0: version "6.4.0" @@ -1715,11 +1818,11 @@ eslint-config-cup@^1.0.0-rc.4: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-config-cup/-/eslint-config-cup-1.0.0.tgz#0fcdb787fe254fc9458ec5258143cb0d47052896" -eslint-config-fusion@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/eslint-config-fusion/-/eslint-config-fusion-0.1.2.tgz#cf380a75090d3cee0c9c086165b86fd60619e0aa" +eslint-config-fusion@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/eslint-config-fusion/-/eslint-config-fusion-0.2.1.tgz#39db6979719dab00953e561b2ff0af66981397bb" dependencies: - eslint-config-uber-universal-stage-3 "^1.0.0-rc.6" + eslint-config-uber-universal-stage-3 "^1.0.0-rc.7" eslint-config-prettier@^2.0.0: version "2.9.0" @@ -1739,33 +1842,62 @@ eslint-config-uber-base@^1.0.0-rc.7: dependencies: eslint-config-prettier "^2.0.0" -eslint-config-uber-universal-stage-3@^1.0.0-rc.6: +eslint-config-uber-universal-stage-3@^1.0.0-rc.7: version "1.0.0-rc.7" resolved "https://registry.yarnpkg.com/eslint-config-uber-universal-stage-3/-/eslint-config-uber-universal-stage-3-1.0.0-rc.7.tgz#bd4de38543d3c27cf48d82925bfccb5efb5b541f" dependencies: eslint-config-cup "^1.0.0-rc.4" eslint-config-uber-base-stage-3 "^1.0.0-rc.7" +eslint-import-resolver-node@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-module-utils@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" + dependencies: + debug "^2.6.8" + pkg-dir "^1.0.0" + eslint-plugin-cup@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-cup/-/eslint-plugin-cup-1.0.0.tgz#6ceced9a06d29e6e7bdc76ca9e398c9bf53072be" dependencies: globals "^10.0.0" -eslint-plugin-flowtype@^2.39.1: - version "2.40.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.40.1.tgz#f78a8e6a4cc6da831dd541eb61e803ff0279b796" +eslint-plugin-flowtype@^2.41.0: + version "2.41.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.41.0.tgz#fd5221c60ba917c059d7ef69686a99cca09fd871" dependencies: lodash "^4.15.0" -eslint-plugin-prettier@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.3.1.tgz#e7a746c67e716f335274b88295a9ead9f544e44d" +eslint-plugin-import@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz#fa1b6ef31fcb3c501c09859c1b86f1fc5b986894" + dependencies: + builtin-modules "^1.1.1" + contains-path "^0.1.0" + debug "^2.6.8" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.1.1" + has "^1.0.1" + lodash.cond "^4.3.0" + minimatch "^3.0.3" + read-pkg-up "^2.0.0" + +eslint-plugin-prettier@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.4.0.tgz#85cab0775c6d5e3344ef01e78d960f166fb93aae" dependencies: fast-diff "^1.1.1" jest-docblock "^21.0.0" -eslint-plugin-react@^7.4.0: +eslint-plugin-react@^7.5.1: version "7.5.1" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz#52e56e8d80c810de158859ef07b880d2f56ee30b" dependencies: @@ -1774,28 +1906,32 @@ eslint-plugin-react@^7.4.0: jsx-ast-utils "^2.0.0" prop-types "^15.6.0" -eslint-scope@^3.7.1: +eslint-scope@^3.7.1, eslint-scope@~3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint@^4.11.0: - version "4.13.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.13.1.tgz#0055e0014464c7eb7878caf549ef2941992b444f" +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + +eslint@^4.15.0: + version "4.15.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.15.0.tgz#89ab38c12713eec3d13afac14e4a89e75ef08145" dependencies: ajv "^5.3.0" babel-code-frame "^6.22.0" chalk "^2.1.0" concat-stream "^1.6.0" cross-spawn "^5.1.0" - debug "^3.0.1" + debug "^3.1.0" doctrine "^2.0.2" eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" espree "^3.5.2" esquery "^1.0.0" - estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" functional-red-black-tree "^1.0.1" @@ -1847,7 +1983,7 @@ esrecurse@^4.1.0: estraverse "^4.1.0" object-assign "^4.0.1" -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -2031,9 +2167,9 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -flow-bin@^0.59.0: - version "0.59.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.59.0.tgz#8c151ee7f09f1deed9bf0b9d1f2e8ab9d470f1bb" +flow-bin@^0.63.1: + version "0.63.1" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.63.1.tgz#ab00067c197169a5fb5b4996c8f6927b06694828" for-each@~0.3.2: version "0.3.2" @@ -2118,21 +2254,27 @@ functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" -fusion-core@^0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/fusion-core/-/fusion-core-0.2.6.tgz#d65610327153bebed7162e5823fcda10ddb40366" +fusion-core@^0.3.0-2: + version "0.3.0-2" + resolved "https://registry.yarnpkg.com/fusion-core/-/fusion-core-0.3.0-2.tgz#cbbe19f688d00b8a2ee948293e6098dbd1a10988" dependencies: koa "^2.3.0" koa-compose "^4.0.0" node-mocks-http "^1.6.6" + toposort "^1.0.6" -fusion-test-utils@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fusion-test-utils/-/fusion-test-utils-0.2.1.tgz#b8bde8bf0facaf3b9038d0dfb4bd5e96a30b7ed4" +fusion-test-utils@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/fusion-test-utils/-/fusion-test-utils-0.3.0.tgz#dd96be1272458146b1d4c878ead322099e93f3b5" dependencies: + assert "^1.4.1" koa "^2.4.1" node-mocks-http "^1.6.6" +fusion-tokens@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/fusion-tokens/-/fusion-tokens-0.0.4.tgz#b84c58e2de8e06d3e63c2c182da7e023ccfb50ec" + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -2219,7 +2361,7 @@ globals@^10.0.0: version "10.4.0" resolved "https://registry.yarnpkg.com/globals/-/globals-10.4.0.tgz#5c477388b128a9e4c5c5d01c7a2aca68c68b2da7" -globals@^11.0.1: +globals@^11.0.1, globals@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.1.0.tgz#632644457f5f0e3ae711807183700ebf2e4633e4" @@ -2533,8 +2675,8 @@ is-function@~1.0.0: resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" 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" + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" @@ -2595,10 +2737,8 @@ is-regex@^1.0.4: has "^1.0.1" 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" + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4" is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" @@ -2704,9 +2844,9 @@ jest-docblock@^21.0.0: version "21.2.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" -jest-worker@^21.3.0-beta.8: - version "21.3.0-beta.14" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-21.3.0-beta.14.tgz#4247db4f55903612eb41b609d16663c864946e74" +jest-worker@^22.0.3: + version "22.0.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-22.0.6.tgz#1998ac7ab24a6eee4deddec76efe7742f2651504" dependencies: merge-stream "^1.0.1" @@ -2926,6 +3066,10 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.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@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -3000,10 +3144,10 @@ merge-descriptors@^1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" merge-source-map@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.4.tgz#a5de46538dae84d4114cc5ea02b4772a6346701f" + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" dependencies: - source-map "^0.5.6" + source-map "^0.6.1" merge-stream@^1.0.1: version "1.0.1" @@ -3070,7 +3214,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -3256,9 +3400,9 @@ number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" -nyc@^11.3.0: - version "11.3.0" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.3.0.tgz#a42bc17b3cfa41f7b15eb602bc98b2633ddd76f0" +nyc@^11.4.1: + version "11.4.1" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.4.1.tgz#13fdf7e7ef22d027c61d174758f6978a68f4f5e5" dependencies: archy "^1.0.0" arrify "^1.0.1" @@ -3283,7 +3427,7 @@ nyc@^11.3.0: resolve-from "^2.0.0" rimraf "^2.5.4" signal-exit "^3.0.1" - spawn-wrap "=1.3.8" + spawn-wrap "^1.4.2" test-exclude "^4.1.1" yargs "^10.0.3" yargs-parser "^8.0.0" @@ -3383,8 +3527,10 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" p-limit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" + dependencies: + p-try "^1.0.0" p-locate@^2.0.0: version "2.0.0" @@ -3392,6 +3538,10 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" @@ -3527,9 +3677,9 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.8.2.tgz#bff83e7fd573933c607875e5ba3abbdffb96aeb8" +prettier@1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.10.2.tgz#1af8356d1842276a99a5b5529c82dd9e9ad3cc93" private@^0.1.6: version "0.1.8" @@ -3611,8 +3761,8 @@ randomatic@^1.1.3: kind-of "^4.0.0" randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79" + version "2.0.6" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" dependencies: safe-buffer "^5.1.0" @@ -3637,8 +3787,8 @@ raw-body@^2.2.0: unpipe "1.0.0" rc@^1.1.7: - version "1.2.2" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077" + version "1.2.3" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.3.tgz#51575a900f8dd68381c710b4712c2154c3e2035b" dependencies: deep-extend "~0.4.0" ini "~1.3.0" @@ -3819,7 +3969,7 @@ resolve-from@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" -resolve@^1.3.2: +resolve@^1.3.2, resolve@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" dependencies: @@ -3850,7 +4000,7 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: @@ -3880,9 +4030,9 @@ rollup-pluginutils@^2.0.1: estree-walker "^0.3.0" micromatch "^2.3.11" -rollup@^0.51.1: - version "0.51.8" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.51.8.tgz#58bd0b642885f4770b5f93cc64f14e4233c2236d" +rollup@^0.53.2: + version "0.53.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.53.4.tgz#f92ce56ee1d097ad5b6f13951bc80db5fef18113" run-async@^2.2.0: version "2.3.0" @@ -3985,20 +4135,20 @@ source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" -source-map@~0.6.1: +source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" -spawn-wrap@=1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.8.tgz#fa2a79b990cbb0bb0018dca6748d88367b19ec31" +spawn-wrap@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c" dependencies: foreground-child "^1.5.6" mkdirp "^0.5.0" os-homedir "^1.0.1" - rimraf "^2.3.3" + rimraf "^2.6.2" signal-exit "^3.0.2" - which "^1.2.4" + which "^1.3.0" spdx-correct@~1.0.0: version "1.0.2" @@ -4275,6 +4425,10 @@ to-object-path@^0.3.0: dependencies: kind-of "^3.0.2" +toposort@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.6.tgz#c31748e55d210effc00fdcdc7d6e68d7d7bb9cec" + tough-cookie@~2.3.0: version "2.3.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" @@ -4285,10 +4439,6 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" -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" @@ -4453,7 +4603,7 @@ webpack-sources@^1.0.1: source-list-map "^2.0.0" source-map "~0.6.1" -webpack@^3.8.1: +webpack@^3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.10.0.tgz#5291b875078cf2abf42bdd23afe3f8f96c17d725" dependencies: @@ -4488,7 +4638,7 @@ which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" -which@^1.2.12, which@^1.2.4, which@^1.2.9: +which@^1.2.12, which@^1.2.9, which@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: @@ -4567,17 +4717,17 @@ yargs-parser@^7.0.0: dependencies: camelcase "^4.1.0" -yargs-parser@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.0.0.tgz#21d476330e5a82279a4b881345bf066102e219c6" +yargs-parser@^8.0.0, yargs-parser@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" dependencies: camelcase "^4.1.0" yargs@^10.0.3: - version "10.0.3" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.0.3.tgz#6542debd9080ad517ec5048fb454efe9e4d4aaae" + version "10.1.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.1.tgz#5fe1ea306985a099b33492001fa19a1e61efe285" dependencies: - cliui "^3.2.0" + cliui "^4.0.0" decamelize "^1.1.1" find-up "^2.1.0" get-caller-file "^1.0.1" @@ -4588,7 +4738,7 @@ yargs@^10.0.3: string-width "^2.0.0" which-module "^2.0.0" y18n "^3.2.1" - yargs-parser "^8.0.0" + yargs-parser "^8.1.0" yargs@^8.0.2: version "8.0.2"