feat: add ipcRenderer.invoke() (#18449)

This commit is contained in:
Jeremy Apthorp 2019-05-31 10:25:19 -07:00 committed by GitHub
parent b180fb376c
commit c436997840
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 389 additions and 20 deletions

View file

@ -924,6 +924,14 @@ void WebContents::Message(bool internal,
internal, channel, std::move(arguments)); internal, channel, std::move(arguments));
} }
void WebContents::Invoke(const std::string& channel,
base::Value arguments,
InvokeCallback callback) {
// webContents.emit('-ipc-invoke', new Event(), channel, arguments);
EmitWithSender("-ipc-invoke", bindings_.dispatch_context(),
std::move(callback), channel, std::move(arguments));
}
void WebContents::MessageSync(bool internal, void WebContents::MessageSync(bool internal,
const std::string& channel, const std::string& channel,
base::Value arguments, base::Value arguments,

View file

@ -492,6 +492,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
void Message(bool internal, void Message(bool internal,
const std::string& channel, const std::string& channel,
base::Value arguments) override; base::Value arguments) override;
void Invoke(const std::string& channel,
base::Value arguments,
InvokeCallback callback) override;
void MessageSync(bool internal, void MessageSync(bool internal,
const std::string& channel, const std::string& channel,
base::Value arguments, base::Value arguments,

View file

@ -58,7 +58,7 @@ void Event::PreventDefault(v8::Isolate* isolate) {
.Check(); .Check();
} }
bool Event::SendReply(const base::ListValue& result) { bool Event::SendReply(const base::Value& result) {
if (!callback_ || sender_ == nullptr) if (!callback_ || sender_ == nullptr)
return false; return false;

View file

@ -32,8 +32,9 @@ class Event : public Wrappable<Event>, public content::WebContentsObserver {
// event.PreventDefault(). // event.PreventDefault().
void PreventDefault(v8::Isolate* isolate); void PreventDefault(v8::Isolate* isolate);
// event.sendReply(array), used for replying synchronous message. // event.sendReply(value), used for replying to synchronous messages and
bool SendReply(const base::ListValue& result); // `invoke` calls.
bool SendReply(const base::Value& result);
protected: protected:
explicit Event(v8::Isolate* isolate); explicit Event(v8::Isolate* isolate);

View file

@ -21,6 +21,12 @@ interface ElectronBrowser {
string channel, string channel,
mojo_base.mojom.ListValue arguments); mojo_base.mojom.ListValue arguments);
// Emits an event on |channel| from the ipcMain JavaScript object in the main
// process, and returns the response.
Invoke(
string channel,
mojo_base.mojom.ListValue arguments) => (mojo_base.mojom.Value result);
// Emits an event on |channel| from the ipcMain JavaScript object in the main // Emits an event on |channel| from the ipcMain JavaScript object in the main
// process, and waits synchronously for a response. // process, and waits synchronously for a response.
// //

View file

@ -8,6 +8,7 @@
#include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_bindings.h" #include "atom/common/node_bindings.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
#include "atom/common/promise_util.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/values.h" #include "base/values.h"
#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame.h"
@ -41,6 +42,8 @@ class IPCRenderer : public mate::Wrappable<IPCRenderer> {
DCHECK(render_frame); DCHECK(render_frame);
render_frame->GetRemoteInterfaces()->GetInterface( render_frame->GetRemoteInterfaces()->GetInterface(
mojo::MakeRequest(&electron_browser_ptr_)); mojo::MakeRequest(&electron_browser_ptr_));
render_frame->GetRemoteInterfaces()->GetInterface(
mojo::MakeRequest(&electron_browser_sync_ptr_));
} }
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) { v8::Local<v8::FunctionTemplate> prototype) {
@ -49,7 +52,8 @@ class IPCRenderer : public mate::Wrappable<IPCRenderer> {
.SetMethod("send", &IPCRenderer::Send) .SetMethod("send", &IPCRenderer::Send)
.SetMethod("sendSync", &IPCRenderer::SendSync) .SetMethod("sendSync", &IPCRenderer::SendSync)
.SetMethod("sendTo", &IPCRenderer::SendTo) .SetMethod("sendTo", &IPCRenderer::SendTo)
.SetMethod("sendToHost", &IPCRenderer::SendToHost); .SetMethod("sendToHost", &IPCRenderer::SendToHost)
.SetMethod("invoke", &IPCRenderer::Invoke);
} }
static mate::Handle<IPCRenderer> Create(v8::Isolate* isolate) { static mate::Handle<IPCRenderer> Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new IPCRenderer(isolate)); return mate::CreateHandle(isolate, new IPCRenderer(isolate));
@ -62,6 +66,20 @@ class IPCRenderer : public mate::Wrappable<IPCRenderer> {
electron_browser_ptr_->Message(internal, channel, arguments.Clone()); electron_browser_ptr_->Message(internal, channel, arguments.Clone());
} }
v8::Local<v8::Promise> Invoke(mate::Arguments* args,
const std::string& channel,
const base::Value& arguments) {
atom::util::Promise p(args->isolate());
auto handle = p.GetHandle();
electron_browser_ptr_->Invoke(
channel, arguments.Clone(),
base::BindOnce(
[](atom::util::Promise p, base::Value value) { p.Resolve(value); },
std::move(p)));
return handle;
}
void SendTo(mate::Arguments* args, void SendTo(mate::Arguments* args,
bool internal, bool internal,
bool send_to_all, bool send_to_all,
@ -82,6 +100,52 @@ class IPCRenderer : public mate::Wrappable<IPCRenderer> {
bool internal, bool internal,
const std::string& channel, const std::string& channel,
const base::ListValue& arguments) { const base::ListValue& arguments) {
// We aren't using a true synchronous mojo call here. We're calling an
// asynchronous method and blocking on the result. The reason we're doing
// this is a little complicated, so buckle up.
//
// Mojo has a concept of synchronous calls. However, synchronous calls are
// dangerous. In particular, it's quite possible for two processes to call
// synchronous methods on each other and cause a deadlock. Mojo has a
// mechanism to avoid this kind of deadlock: if a process is waiting on the
// result of a synchronous call, and it receives an incoming call for a
// synchronous method, it will process that request immediately, even
// though it's currently blocking. However, if it receives an incoming
// request for an _asynchronous_ method, that can't cause a deadlock, so it
// stashes the request on a queue to be processed once the synchronous
// thing it's waiting on returns.
//
// This behavior is useful for preventing deadlocks, but it is inconvenient
// here because it can result in messages being reordered. If the main
// process is awaiting the result of a synchronous call (which it does only
// very rarely, since it's bad to block the main process), and we send
// first an asynchronous message to the main process, followed by a
// synchronous message, then the main process will process the synchronous
// one first.
//
// It turns out, Electron has some dependency on message ordering,
// especially during window shutdown, and getting messages out of order can
// result in, for example, remote objects disappearing unexpectedly. To
// avoid these issues and guarantee consistent message ordering, we send
// all messages to the main process as asynchronous messages. This causes
// them to always be queued and processed in the same order they were
// received, even if they were received while the main process was waiting
// on a synchronous call.
//
// However, in the calling process, we still need to block on the result,
// because the caller is expecting a result synchronously. So we do a bit
// of a trick: we pass the Mojo handle over to a new thread, send the
// asynchronous message from that thread, and then block on the result.
// It's important that we pass the handle over to the new thread, because
// that allows Mojo to process incoming messages (most importantly, the
// response to our request) on the new thread. If we didn't pass it to a
// new thread, and instead sent the call from the main thread, we would
// never receive a response because Mojo wouldn't be able to run its
// message handling code, because the main thread would be tied up blocking
// on the WaitableEvent.
//
// Phew. If you got this far, here's a gold star: ⭐️
base::Value result; base::Value result;
// A task is posted to a separate thread to execute the request so that // A task is posted to a separate thread to execute the request so that
@ -96,7 +160,7 @@ class IPCRenderer : public mate::Wrappable<IPCRenderer> {
// We unbind the interface from this thread to pass it over to the worker // We unbind the interface from this thread to pass it over to the worker
// thread temporarily. This requires that no callbacks be pending for this // thread temporarily. This requires that no callbacks be pending for this
// interface. // interface.
auto interface_info = electron_browser_ptr_.PassInterface(); auto interface_info = electron_browser_sync_ptr_.PassInterface();
task_runner->PostTask( task_runner->PostTask(
FROM_HERE, base::BindOnce(&IPCRenderer::SendMessageSyncOnWorkerThread, FROM_HERE, base::BindOnce(&IPCRenderer::SendMessageSyncOnWorkerThread,
base::Unretained(&interface_info), base::Unretained(&interface_info),
@ -104,7 +168,7 @@ class IPCRenderer : public mate::Wrappable<IPCRenderer> {
base::Unretained(&result), internal, channel, base::Unretained(&result), internal, channel,
base::Unretained(&arguments))); base::Unretained(&arguments)));
response_received_event.Wait(); response_received_event.Wait();
electron_browser_ptr_.Bind(std::move(interface_info)); electron_browser_sync_ptr_.Bind(std::move(interface_info));
return result; return result;
} }
@ -135,6 +199,10 @@ class IPCRenderer : public mate::Wrappable<IPCRenderer> {
} }
atom::mojom::ElectronBrowserPtr electron_browser_ptr_; atom::mojom::ElectronBrowserPtr electron_browser_ptr_;
// We execute all synchronous calls on a separate mojo pipe, because
// of the way that we block on the result of synchronous calls.
atom::mojom::ElectronBrowserPtr electron_browser_sync_ptr_;
}; };
void Initialize(v8::Local<v8::Object> exports, void Initialize(v8::Local<v8::Object> exports,

View file

@ -88,7 +88,61 @@ Removes the specified `listener` from the listener array for the specified
Removes listeners of the specified `channel`. Removes listeners of the specified `channel`.
## Event object ### `ipcMain.handle(channel, listener)`
* `channel` String
* `listener` Function<Promise> | Function<any>
* `event` IpcMainInvokeEvent
* `...args` any[]
Adds a handler for an `invoke`able IPC. This handler will be called whenever a
renderer calls `ipcRenderer.invoke(channel, ...args)`.
If `listener` returns a Promise, the eventual result of the promise will be
returned as a reply to the remote caller. Otherwise, the return value of the
listener will be used as the value of the reply.
```js
// Main process
ipcMain.handle('my-invokable-ipc', async (event, ...args) => {
const result = await somePromise(...args)
return result
})
// Renderer process
async () => {
const result = await ipcRenderer.invoke('my-invokable-ipc', arg1, arg2)
// ...
}
```
The `event` that is passed as the first argument to the handler is the same as
that passed to a regular event listener. It includes information about which
WebContents is the source of the invoke request.
### `ipcMain.handleOnce(channel, listener)`
* `channel` String
* `listener` Function<Promise> | Function<any>
* `event` IpcMainInvokeEvent
* `...args` any[]
Handles a single `invoke`able IPC message, then removes the listener. See
`ipcMain.handle(channel, listener)`.
### `ipcMain.removeHandler(channel)`
* `channel` String
Removes any handler for `channel`, if present.
## IpcMainEvent object
The documentation for the `event` object passed to the `callback` can be found The documentation for the `event` object passed to the `callback` can be found
in the [`ipc-main-event`](structures/ipc-main-event.md) structure docs. in the [`ipc-main-event`](structures/ipc-main-event.md) structure docs.
## IpcMainInvokeEvent object
The documentation for the `event` object passed to `handle` callbacks can be
found in the [`ipc-main-invoke-event`](structures/ipc-main-invoke-event.md)
structure docs.

View file

@ -57,10 +57,39 @@ Removes all listeners, or those of the specified `channel`.
* `...args` any[] * `...args` any[]
Send a message to the main process asynchronously via `channel`, you can also Send a message to the main process asynchronously via `channel`, you can also
send arbitrary arguments. Arguments will be serialized in JSON internally and send arbitrary arguments. Arguments will be serialized as JSON internally and
hence no functions or prototype chain will be included. hence no functions or prototype chain will be included.
The main process handles it by listening for `channel` with [`ipcMain`](ipc-main.md) module. The main process handles it by listening for `channel` with the
[`ipcMain`](ipc-main.md) module.
### `ipcRenderer.invoke(channel[, arg1][, arg2][, ...])`
* `channel` String
* `...args` any[]
Returns `Promise<any>` - Resolves with the response from the main process.
Send a message to the main process asynchronously via `channel` and expect an
asynchronous result. Arguments will be serialized as JSON internally and
hence no functions or prototype chain will be included.
The main process should listen for `channel` with
[`ipcMain.handle()`](ipc-main.md#ipcmainhandlechannel-listener).
For example:
```javascript
// Renderer process
ipcRenderer.invoke('some-name', someArgument).then((result) => {
// ...
})
// Main process
ipcMain.handle('some-name', async (event, someArgument) => {
const result = await doSomeWork(someArgument)
return result
})
```
### `ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])` ### `ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])`

View file

@ -5,4 +5,3 @@
* `sender` WebContents - Returns the `webContents` that sent the message * `sender` WebContents - Returns the `webContents` that sent the message
* `reply` Function - A function that will send an IPC message to the renderer frame that sent the original message that you are currently handling. You should use this method to "reply" to the sent message in order to guaruntee the reply will go to the correct process and frame. * `reply` Function - A function that will send an IPC message to the renderer frame that sent the original message that you are currently handling. You should use this method to "reply" to the sent message in order to guaruntee the reply will go to the correct process and frame.
* `...args` any[] * `...args` any[]
IpcRenderer

View file

@ -0,0 +1,4 @@
# IpcMainInvokeEvent Object extends `Event`
* `frameId` Integer - The ID of the renderer frame that sent this message
* `sender` WebContents - Returns the `webContents` that sent the message

View file

@ -78,6 +78,7 @@ auto_filenames = {
"docs/api/structures/gpu-feature-status.md", "docs/api/structures/gpu-feature-status.md",
"docs/api/structures/io-counters.md", "docs/api/structures/io-counters.md",
"docs/api/structures/ipc-main-event.md", "docs/api/structures/ipc-main-event.md",
"docs/api/structures/ipc-main-invoke-event.md",
"docs/api/structures/ipc-renderer-event.md", "docs/api/structures/ipc-renderer-event.md",
"docs/api/structures/jump-list-category.md", "docs/api/structures/jump-list-category.md",
"docs/api/structures/jump-list-item.md", "docs/api/structures/jump-list-item.md",

View file

@ -1,8 +1,40 @@
import { EventEmitter } from 'events' import { EventEmitter } from 'events'
import { IpcMainInvokeEvent } from 'electron'
const emitter = new EventEmitter() class IpcMain extends EventEmitter {
private _invokeHandlers: Map<string, (e: IpcMainInvokeEvent, ...args: any[]) => void> = new Map();
handle: Electron.IpcMain['handle'] = (method, fn) => {
if (this._invokeHandlers.has(method)) {
throw new Error(`Attempted to register a second handler for '${method}'`)
}
if (typeof fn !== 'function') {
throw new Error(`Expected handler to be a function, but found type '${typeof fn}'`)
}
this._invokeHandlers.set(method, async (e, ...args) => {
try {
(e as any)._reply(await Promise.resolve(fn(e, ...args)))
} catch (err) {
(e as any)._throw(err)
}
})
}
handleOnce: Electron.IpcMain['handleOnce'] = (method, fn) => {
this.handle(method, (e, ...args) => {
this.removeHandler(method)
return fn(e, ...args)
})
}
removeHandler (method: string) {
this._invokeHandlers.delete(method)
}
}
const ipcMain = new IpcMain()
// Do not throw exception when channel name is "error". // Do not throw exception when channel name is "error".
emitter.on('error', () => {}) ipcMain.on('error', () => {})
export default emitter export default ipcMain

View file

@ -326,6 +326,19 @@ WebContents.prototype._init = function () {
} }
}) })
this.on('-ipc-invoke', function (event, channel, args) {
event._reply = (result) => event.sendReply({ result })
event._throw = (error) => {
console.error(`Error occurred in handler for '${channel}':`, error)
event.sendReply({ error: error.toString() })
}
if (ipcMain._invokeHandlers.has(channel)) {
ipcMain._invokeHandlers.get(channel)(event, ...args)
} else {
event._throw(`No handler registered for '${channel}'`)
}
})
this.on('-ipc-message-sync', function (event, internal, channel, args) { this.on('-ipc-message-sync', function (event, internal, channel, args) {
addReturnValueToEvent(event) addReturnValueToEvent(event)
if (internal) { if (internal) {

View file

@ -27,4 +27,11 @@ ipcRenderer.sendToAll = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, true, webContentsId, channel, args) return ipc.sendTo(internal, true, webContentsId, channel, args)
} }
ipcRenderer.invoke = function (channel, ...args) {
return ipc.invoke(channel, args).then(({ error, result }) => {
if (error) { throw new Error(`Error invoking remote method '${channel}': ${error}`) }
return result
})
}
module.exports = ipcRenderer module.exports = ipcRenderer

109
spec-main/api-ipc-spec.ts Normal file
View file

@ -0,0 +1,109 @@
import * as chai from 'chai'
import * as chaiAsPromised from 'chai-as-promised'
import { BrowserWindow, ipcMain, IpcMainInvokeEvent } from 'electron'
const { expect } = chai
chai.use(chaiAsPromised)
describe('ipc module', () => {
describe('invoke', () => {
let w = (null as unknown as BrowserWindow);
before(async () => {
w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true } })
await w.loadURL('about:blank')
})
after(async () => {
w.destroy()
})
async function rendererInvoke(...args: any[]) {
const {ipcRenderer} = require('electron')
try {
const result = await ipcRenderer.invoke('test', ...args)
ipcRenderer.send('result', {result})
} catch (e) {
ipcRenderer.send('result', {error: e.message})
}
}
it('receives a response from a synchronous handler', async () => {
ipcMain.handleOnce('test', (e: IpcMainInvokeEvent, arg: number) => {
expect(arg).to.equal(123)
return 3
})
const done = new Promise(resolve => ipcMain.once('result', (e, arg) => {
expect(arg).to.deep.equal({result: 3})
resolve()
}))
await w.webContents.executeJavaScript(`(${rendererInvoke})(123)`)
await done
})
it('receives a response from an asynchronous handler', async () => {
ipcMain.handleOnce('test', async (e: IpcMainInvokeEvent, arg: number) => {
expect(arg).to.equal(123)
await new Promise(resolve => setImmediate(resolve))
return 3
})
const done = new Promise(resolve => ipcMain.once('result', (e, arg) => {
expect(arg).to.deep.equal({result: 3})
resolve()
}))
await w.webContents.executeJavaScript(`(${rendererInvoke})(123)`)
await done
})
it('receives an error from a synchronous handler', async () => {
ipcMain.handleOnce('test', () => {
throw new Error('some error')
})
const done = new Promise(resolve => ipcMain.once('result', (e, arg) => {
expect(arg.error).to.match(/some error/)
resolve()
}))
await w.webContents.executeJavaScript(`(${rendererInvoke})()`)
await done
})
it('receives an error from an asynchronous handler', async () => {
ipcMain.handleOnce('test', async () => {
await new Promise(resolve => setImmediate(resolve))
throw new Error('some error')
})
const done = new Promise(resolve => ipcMain.once('result', (e, arg) => {
expect(arg.error).to.match(/some error/)
resolve()
}))
await w.webContents.executeJavaScript(`(${rendererInvoke})()`)
await done
})
it('throws an error if no handler is registered', async () => {
const done = new Promise(resolve => ipcMain.once('result', (e, arg) => {
expect(arg.error).to.match(/No handler registered/)
resolve()
}))
await w.webContents.executeJavaScript(`(${rendererInvoke})()`)
await done
})
it('throws an error when invoking a handler that was removed', async () => {
ipcMain.handle('test', () => {})
ipcMain.removeHandler('test')
const done = new Promise(resolve => ipcMain.once('result', (e, arg) => {
expect(arg.error).to.match(/No handler registered/)
resolve()
}))
await w.webContents.executeJavaScript(`(${rendererInvoke})()`)
await done
})
it('forbids multiple handlers', async () => {
ipcMain.handle('test', () => {})
expect(() => { ipcMain.handle('test', () => {}) }).to.throw(/second handler/)
ipcMain.removeHandler('test')
})
})
})

View file

@ -23,8 +23,9 @@
regenerator-runtime "^0.12.0" regenerator-runtime "^0.12.0"
"@electron/docs-parser@^0.1.1": "@electron/docs-parser@^0.1.1":
version "0.1.5" version "0.1.6"
resolved "https://registry.yarnpkg.com/@electron/docs-parser/-/docs-parser-0.1.5.tgz#e6c05ed200b4c155986fb0f46178dede71a5e078" resolved "https://registry.yarnpkg.com/@electron/docs-parser/-/docs-parser-0.1.6.tgz#7ed86586e0ebc4a5c63e7c112264357adc61d334"
integrity sha512-WAV0xHx1HIflqvb6G01LLnpS9n3VzNF0vyfxYhbP3Ev2p+m8CODc2+9pCdzCmH457UYi8GsX/jnB23djTCxt7Q==
dependencies: dependencies:
"@types/markdown-it" "^0.0.7" "@types/markdown-it" "^0.0.7"
chai "^4.2.0" chai "^4.2.0"
@ -156,10 +157,12 @@
"@types/linkify-it@*": "@types/linkify-it@*":
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-2.1.0.tgz#ea3dd64c4805597311790b61e872cbd1ed2cd806" resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-2.1.0.tgz#ea3dd64c4805597311790b61e872cbd1ed2cd806"
integrity sha512-Q7DYAOi9O/+cLLhdaSvKdaumWyHbm7HAk/bFwwyTuU0arR5yyCeW5GOoqt4tJTpDRxhpx9Q8kQL6vMpuw9hDSw==
"@types/markdown-it@^0.0.7": "@types/markdown-it@^0.0.7":
version "0.0.7" version "0.0.7"
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.7.tgz#75070485a3d8ad11e7deb8287f4430be15bf4d39" resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.7.tgz#75070485a3d8ad11e7deb8287f4430be15bf4d39"
integrity sha512-WyL6pa76ollQFQNEaLVa41ZUUvDvPY+qAUmlsphnrpL6I9p1m868b26FyeoOmo7X3/Ta/S9WKXcEYXUSHnxoVQ==
dependencies: dependencies:
"@types/linkify-it" "*" "@types/linkify-it" "*"
@ -319,6 +322,7 @@ ansi-regex@^3.0.0:
ansi-regex@^4.1.0: ansi-regex@^4.1.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
ansi-styles@^2.2.1: ansi-styles@^2.2.1:
version "2.2.1" version "2.2.1"
@ -327,6 +331,7 @@ ansi-styles@^2.2.1:
ansi-styles@^3.2.0, ansi-styles@^3.2.1: ansi-styles@^3.2.0, ansi-styles@^3.2.1:
version "3.2.1" version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
dependencies: dependencies:
color-convert "^1.9.0" color-convert "^1.9.0"
@ -359,6 +364,7 @@ are-we-there-yet@~1.1.2:
argparse@^1.0.7: argparse@^1.0.7:
version "1.0.10" version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
dependencies: dependencies:
sprintf-js "~1.0.2" sprintf-js "~1.0.2"
@ -469,6 +475,7 @@ assert@^1.4.0:
assertion-error@^1.1.0: assertion-error@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==
assign-symbols@^1.0.0: assign-symbols@^1.0.0:
version "1.0.0" version "1.0.0"
@ -876,6 +883,7 @@ ccount@^1.0.0:
chai@^4.2.0: chai@^4.2.0:
version "4.2.0" version "4.2.0"
resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5"
integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==
dependencies: dependencies:
assertion-error "^1.1.0" assertion-error "^1.1.0"
check-error "^1.0.2" check-error "^1.0.2"
@ -897,6 +905,7 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1, chalk@^2.4.2: chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2" version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies: dependencies:
ansi-styles "^3.2.1" ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5" escape-string-regexp "^1.0.5"
@ -929,6 +938,7 @@ chardet@^0.7.0:
check-error@^1.0.2: check-error@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=
check-for-leaks@^1.0.2: check-for-leaks@^1.0.2:
version "1.2.0" version "1.2.0"
@ -1010,6 +1020,7 @@ cli-cursor@^1.0.2:
cli-cursor@^2.0.0, cli-cursor@^2.1.0: cli-cursor@^2.0.0, cli-cursor@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=
dependencies: dependencies:
restore-cursor "^2.0.0" restore-cursor "^2.0.0"
@ -1020,6 +1031,7 @@ cli-spinners@^0.1.2:
cli-spinners@^2.0.0: cli-spinners@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.1.0.tgz#22c34b4d51f573240885b201efda4e4ec9fff3c7" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.1.0.tgz#22c34b4d51f573240885b201efda4e4ec9fff3c7"
integrity sha512-8B00fJOEh1HPrx4fo5eW16XmE1PcL1tGpGrxy63CXGP9nHdPBN63X75hA1zhvQuhVztJWLqV58Roj2qlNM7cAA==
cli-truncate@^0.2.1: cli-truncate@^0.2.1:
version "0.2.1" version "0.2.1"
@ -1035,6 +1047,7 @@ cli-width@^2.0.0:
clone@^1.0.2: clone@^1.0.2:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
co@3.1.0: co@3.1.0:
version "3.1.0" version "3.1.0"
@ -1058,12 +1071,14 @@ collection-visit@^1.0.0:
color-convert@^1.9.0: color-convert@^1.9.0:
version "1.9.3" version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
dependencies: dependencies:
color-name "1.1.3" color-name "1.1.3"
color-name@1.1.3: color-name@1.1.3:
version "1.1.3" version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
colors@^1.1.2: colors@^1.1.2:
version "1.3.3" version "1.3.3"
@ -1291,6 +1306,7 @@ dedent@^0.7.0:
deep-eql@^3.0.1: deep-eql@^3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df"
integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==
dependencies: dependencies:
type-detect "^4.0.0" type-detect "^4.0.0"
@ -1309,6 +1325,7 @@ deepmerge@3.2.0:
defaults@^1.0.3: defaults@^1.0.3:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=
dependencies: dependencies:
clone "^1.0.2" clone "^1.0.2"
@ -1554,6 +1571,7 @@ ensure-posix-path@^1.0.0:
entities@~1.1.1: entities@~1.1.1:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
error-ex@^1.2.0, error-ex@^1.3.1: error-ex@^1.2.0, error-ex@^1.3.1:
version "1.3.2" version "1.3.2"
@ -2262,6 +2280,7 @@ get-assigned-identifiers@^1.2.0:
get-func-name@^2.0.0: get-func-name@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
get-own-enumerable-property-symbols@^3.0.0: get-own-enumerable-property-symbols@^3.0.0:
version "3.0.0" version "3.0.0"
@ -2416,6 +2435,7 @@ has-flag@^2.0.0:
has-flag@^3.0.0: has-flag@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
has-symbols@^1.0.0: has-symbols@^1.0.0:
version "1.0.0" version "1.0.0"
@ -3117,6 +3137,7 @@ levn@^0.3.0, levn@~0.3.0:
linkify-it@^2.0.0: linkify-it@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.1.0.tgz#c4caf38a6cd7ac2212ef3c7d2bde30a91561f9db" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.1.0.tgz#c4caf38a6cd7ac2212ef3c7d2bde30a91561f9db"
integrity sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==
dependencies: dependencies:
uc.micro "^1.0.1" uc.micro "^1.0.1"
@ -3247,6 +3268,7 @@ locate-path@^3.0.0:
lodash.camelcase@^4.3.0: lodash.camelcase@^4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY=
lodash.flatten@^4.4.0: lodash.flatten@^4.4.0:
version "4.4.0" version "4.4.0"
@ -3289,6 +3311,7 @@ log-symbols@^1.0.2:
log-symbols@^2.2.0: log-symbols@^2.2.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==
dependencies: dependencies:
chalk "^2.0.1" chalk "^2.0.1"
@ -3354,6 +3377,7 @@ markdown-extensions@^1.1.0:
markdown-it@^8.4.2: markdown-it@^8.4.2:
version "8.4.2" version "8.4.2"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54" resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54"
integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==
dependencies: dependencies:
argparse "^1.0.7" argparse "^1.0.7"
entities "~1.1.1" entities "~1.1.1"
@ -3410,6 +3434,7 @@ mdast-util-to-string@^1.0.2:
mdurl@^1.0.1: mdurl@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
media-typer@0.3.0: media-typer@0.3.0:
version "0.3.0" version "0.3.0"
@ -3502,6 +3527,7 @@ mime@1.4.1:
mimic-fn@^1.0.0: mimic-fn@^1.0.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1" version "1.0.1"
@ -3806,6 +3832,7 @@ onetime@^1.0.0:
onetime@^2.0.0: onetime@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=
dependencies: dependencies:
mimic-fn "^1.0.0" mimic-fn "^1.0.0"
@ -3838,6 +3865,7 @@ ora@^0.2.3:
ora@^3.0.0, ora@^3.4.0: ora@^3.0.0, ora@^3.4.0:
version "3.4.0" version "3.4.0"
resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318"
integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==
dependencies: dependencies:
chalk "^2.4.2" chalk "^2.4.2"
cli-cursor "^2.1.0" cli-cursor "^2.1.0"
@ -3993,6 +4021,7 @@ parse-json@^4.0.0:
parse-ms@^2.1.0: parse-ms@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-2.1.0.tgz#348565a753d4391fa524029956b172cb7753097d" resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-2.1.0.tgz#348565a753d4391fa524029956b172cb7753097d"
integrity sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==
parseurl@~1.3.2: parseurl@~1.3.2:
version "1.3.3" version "1.3.3"
@ -4067,6 +4096,7 @@ path-type@^3.0.0:
pathval@^1.1.0: pathval@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0"
integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA=
pbkdf2@^3.0.3: pbkdf2@^3.0.3:
version "3.0.17" version "3.0.17"
@ -4198,6 +4228,7 @@ pretty-bytes@^1.0.2:
pretty-ms@^5.0.0: pretty-ms@^5.0.0:
version "5.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-5.0.0.tgz#6133a8f55804b208e4728f6aa7bf01085e951e24" resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-5.0.0.tgz#6133a8f55804b208e4728f6aa7bf01085e951e24"
integrity sha512-94VRYjL9k33RzfKiGokPBPpsmloBYSf5Ri+Pq19zlsEcUKFob+admeXr5eFDRuPjFmEOcjJvPGdillYOJyvZ7Q==
dependencies: dependencies:
parse-ms "^2.1.0" parse-ms "^2.1.0"
@ -5069,6 +5100,7 @@ restore-cursor@^1.0.1:
restore-cursor@^2.0.0: restore-cursor@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368=
dependencies: dependencies:
onetime "^2.0.0" onetime "^2.0.0"
signal-exit "^3.0.2" signal-exit "^3.0.2"
@ -5260,6 +5292,7 @@ shx@^0.3.2:
signal-exit@^3.0.0, signal-exit@^3.0.2: signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
simple-concat@^1.0.0: simple-concat@^1.0.0:
version "1.0.0" version "1.0.0"
@ -5399,6 +5432,7 @@ split-string@^3.0.1, split-string@^3.0.2:
sprintf-js@~1.0.2: sprintf-js@~1.0.2:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
sshpk@^1.7.0: sshpk@^1.7.0:
version "1.16.1" version "1.16.1"
@ -5581,6 +5615,7 @@ strip-ansi@^4.0.0:
strip-ansi@^5.1.0, strip-ansi@^5.2.0: strip-ansi@^5.1.0, strip-ansi@^5.2.0:
version "5.2.0" version "5.2.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
dependencies: dependencies:
ansi-regex "^4.1.0" ansi-regex "^4.1.0"
@ -5604,10 +5639,6 @@ strip-indent@^1.0.1:
dependencies: dependencies:
get-stdin "^4.0.1" get-stdin "^4.0.1"
strip-indent@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68"
strip-json-comments@^2.0.0, strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: strip-json-comments@^2.0.0, strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
@ -5637,6 +5668,7 @@ supports-color@^4.1.0:
supports-color@^5.3.0: supports-color@^5.3.0:
version "5.5.0" version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
dependencies: dependencies:
has-flag "^3.0.0" has-flag "^3.0.0"
@ -5898,6 +5930,7 @@ type-check@~0.3.2:
type-detect@^4.0.0, type-detect@^4.0.5: type-detect@^4.0.0, type-detect@^4.0.5:
version "4.0.8" version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
type-fest@^0.4.1: type-fest@^0.4.1:
version "0.4.1" version "0.4.1"
@ -5926,6 +5959,7 @@ typescript@~3.3.3333:
uc.micro@^1.0.1, uc.micro@^1.0.5: uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6" version "1.0.6"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
umd@^3.0.0: umd@^3.0.0:
version "3.0.3" version "3.0.3"
@ -6207,6 +6241,7 @@ walk-sync@^0.3.2:
wcwidth@^1.0.1: wcwidth@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=
dependencies: dependencies:
defaults "^1.0.3" defaults "^1.0.3"