Merge remote-tracking branch 'origin/main' into add-scope-header

This commit is contained in:
Susmitha Girumala committed 2020-11-10 16:52:24 -05:00
commit 88ec06624e
11 files changed
+401 -80

No files matched your search

+15
View File
@@ -1,8 +1,23 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default class IndexRoute extends Route {
// =services
@service ipc;
// =methods
/**
* Invokes an IPC method and returns the result.
* @return {Promise}
*/
model() {
return this.ipc.invoke('getFoobars', {
id: '1'
});
}
/**
* Redirects to scopes route for further processing.
*/
+150
View File
@@ -0,0 +1,150 @@
import Service from '@ember/service';
import { getOwner } from '@ember/application';
import { Promise } from 'rsvp';
import config from '../config/environment';
/**
* An IPC request is a promise-like object that issues a request via
* `window.postMessage` and resolves to a response received via a response
* port. IPC requests are used by an Electron renderer process to communicate
* with the main process when the renderer is fully isolated.
*
* Some of the design goals of this "safe IPC" are to respect the confines
* of process isolation and security, without using node integration, while
* retaining the ability to run the Ember application within a browser
* (sans main process) by using only APIs available in a standard
* (non-Electron) browser. This is achieved by posting messages to the
* renderer's `window.postMessage` interface. Thus, the renderer requires no
* knowledge of the main process or the Electron context. In fact a main
* process and Electron context are not even required.
*
* In an Electron context, the `preload.js` script sets up a `window.postMessge`
* listener which acts as proxy layer between the main and renderer processes.
* It waits for incoming requests from the renderer and forwards them to main.
* Responses from the main process are forwarded back via a response port
* (sent with the original request).
*
* Local development in a non-Electron browser context or test context should
* mock up IPC requests. See the ipc service test for an example of mocking.
*
* TODO: add utilities for quickly mocking IPC responses (like Mirage)
*
*/
export class IPCRequest {
// =attributes
/**
* @type {?MessageChannel}
* @private
*/
#channel = null;
/**
* @type {?Promise}
* @private
*/
#promise = null;
// =methods
/**
* Posts a message to the window object, along with a MessagePort
* with which to receive a response. An internal promise is generated which
* resolves to the response.
* @param {string} method
* @param {object} payload
* @param {Window} window - A reference to the window object
* @param {?string} origin
*/
constructor(method, payload, window, origin=config.ipc.defaultOrigin) {
this.method = method;
this.payload = payload;
this.origin = origin;
this.#channel = new MessageChannel();
this.#promise = new Promise((resolve/*, reject*/) => {
this.#channel.port1.onmessage = (event) => {
this.close();
resolve(event.data);
}
});
window.postMessage({
method: this.method,
payload: this.payload
}, origin, [ this.#channel.port2 ]);
}
/**
* Closes the message ports and drops the channel reference.
* This is called upon receiving a response for cleanup purposes.
*/
close() {
this.#channel.port1.close();
this.#channel.port2.close();
this.#channel = null;
}
/**
* Proxies to the underlying promise.
*/
then() {
return this.#promise.then(...arguments);
}
/**
* Proxies to the underlying promise.
*/
catch() {
return this.#promise.catch(...arguments);
}
/**
* Proxies to the underlying promise.
*/
finally() {
return this.#promise.finally(...arguments);
}
}
/**
* A simple factory for generating IPCRequests in Ember.
* @example
*
* class MyClass {
* @service ipc;
*
* makeRequest {
* return this.ipc.invoke('getFoobars', { hello: 'world' });
* }
* }
*/
export default class IpcService extends Service {
// =attributes
/**
* Looks up the window object indirectly.
* @type {Window}
*/
get window() {
// The Ember way of accessing globals...
const document = getOwner(this).lookup('service:-document').documentElement;
// defaultView === window, but without using globals directly
return document.parentNode.defaultView;
}
// =methods
/**
* Creates a new IPC request and returns it.
* @param {string} method
* @param {object} payload
* @param {object} origin
* @return {IPCRequest}
*/
invoke(method, payload, origin) {
return new IPCRequest(method, payload, this.window, origin);
}
}
+2 -1
View File
@@ -1 +1,2 @@
{{outlet}}
{{outlet}}
{{@model.message}}
+6
View File
@@ -31,6 +31,12 @@ module.exports = function (environment) {
namespace: 'v1',
},
ipc: {
defaultOrigin: process.env.EMBER_CLI_ELECTRON
? 'serve://boundary'
: 'http://localhost:4200'
},
appName: APP_NAME,
};
@@ -1,42 +0,0 @@
const { fileURLToPath } = require('url');
const path = require('path');
const fs = require('fs');
const { promisify } = require('util');
const access = promisify(fs.access);
//
// Patch asset loading -- Ember apps use absolute paths to reference their
// assets, e.g. `<img src="/images/foo.jpg">`. When the current URL is a `file:`
// URL, that ends up resolving to the absolute filesystem path `/images/foo.jpg`
// rather than being relative to the root of the Ember app. So, we intercept
// `file:` URL request and look to see if they point to an asset when
// interpreted as being relative to the root of the Ember app. If so, we return
// that path, and if not we leave them as-is, as their absolute path.
//
async function getAssetPath(emberAppDir, url) {
let urlPath = fileURLToPath(url);
// Get the root of the path -- should be '/' on MacOS or something like
// 'C:\' on Windows
let { root } = path.parse(urlPath);
// Get the relative path from the root to the full path
let relPath = path.relative(root, urlPath);
// Join the relative path with the Ember app directory
let appPath = path.join(emberAppDir, relPath);
try {
await access(appPath);
return appPath;
} catch (e) {
return urlPath;
}
}
module.exports = function handleFileURLs(emberAppDir) {
const { protocol } = require('electron');
protocol.interceptFileProtocol('file', async ({ url }, callback) => {
callback(await getAssetPath(emberAppDir, url));
});
};
module.exports.getAssetPath = getAssetPath;
+17
View File
@@ -0,0 +1,17 @@
const { ipcMain } = require('electron');
const isDev = require('electron-is-dev');
const log = (method, request) => {
if (isDev) console.log(`[ipc-main](${method}): `, request);
}
/**
* A demonstration method `getFoobars` which returns an object with a message.
*/
ipcMain.handle('getFoobars', async (event, request) => {
log('getFoobars', request);
return {
message: 'this is a response from an ipcMain handler'
};
});
+47 -19
View File
@@ -1,25 +1,28 @@
/* eslint-disable no-console */
const { default: installExtension, EMBER_INSPECTOR } = require('electron-devtools-installer');
const { pathToFileURL } = require('url');
const { app, BrowserWindow } = require('electron');
const path = require('path');
const isDev = require('electron-is-dev');
const handleFileUrls = require('./handle-file-urls');
const { default: installExtension, EMBER_INSPECTOR } = require('electron-devtools-installer');
const { session, app, protocol, BrowserWindow, ipcMain } = require('electron');
require('./handlers.js');
const isDev = require('electron-is-dev');
// Register the custom file protocol
const emberAppProtocol = 'serve';
const emberAppName = 'boundary';
const emberAppURL = `${emberAppProtocol}://${emberAppName}`;
const emberAppDir = path.resolve(__dirname, '..', 'ember-dist');
const emberAppURL = pathToFileURL(path.join(emberAppDir, 'index.html')).toString();
const preloadPath = path.resolve(__dirname, 'preload.js');
protocol.registerSchemesAsPrivileged([{
scheme: emberAppProtocol,
privileges: {
secure: true,
standard: true
}
}]);
let mainWindow = null;
// Uncomment the lines below to enable Electron's crash reporter
// For more information, see http://electron.atom.io/docs/api/crash-reporter/
// electron.crashReporter.start({
// productName: 'YourName',
// companyName: 'YourCompany',
// submitURL: 'https://your-domain.com/url-to-submit',
// autoSubmit: true
// });
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
@@ -27,6 +30,23 @@ app.on('window-all-closed', () => {
});
app.on('ready', async () => {
// Register custom protocol
const partition = emberAppName;
const ses = session.fromPartition(partition);
ses.protocol.registerFileProtocol(emberAppProtocol, (request, callback) => {
const isDir = request.url.endsWith('/');
const absolutePath = request.url.substr(emberAppURL.length);
const normalizedPath = isDir
? path.normalize(`${emberAppDir}/index.html`)
: path.normalize(`${emberAppDir}${absolutePath}`);
if (isDev) console.log('[serving]', request.url);
callback({ path: normalizedPath });
});
if (isDev) {
try {
require('devtron').install();
@@ -40,11 +60,19 @@ app.on('ready', async () => {
}
}
await handleFileUrls(emberAppDir);
mainWindow = new BrowserWindow({
width: 800,
height: 600,
width: 1024,
height: 768,
webPreferences: {
partition,
sandbox: true,
webSecurity: true,
contextIsolation: true,
nodeIntegration: false,
enableRemoteModule: false,
allowRunningInsecureContent: false,
preload: preloadPath
}
});
// If you want to open up dev tools programmatically, call
+24
View File
@@ -0,0 +1,24 @@
const { ipcRenderer } = require('electron');
const emberAppOrigin = 'serve://boundary';
process.once('loaded', () => {
/**
* Ember-land has no access to the renderer or node modules, and thus
* cannot call into the main process or make invocations directly.
* In order to communicate with the main process, the Ember app uses
* the `postMessage` interface to send messages to its browser window.
* These messages include message ports with which to receive responses from
* the main process.
*
* This preload script simply wires up the forwarding of
* messages received on the window and responses received from main.
*/
window.addEventListener('message', async function (event) {
if (event.origin !== emberAppOrigin) return;
const response =
await ipcRenderer.invoke(event.data.method, event.data.payload);
event.ports[0].postMessage(response);
});
});
+2 -1
View File
@@ -78,7 +78,8 @@
"prettier": "^2.1.2",
"qunit-dom": "^1.2.0",
"rose": "*",
"sass": "^1.29.0"
"sass": "^1.29.0",
"sinon": "^9.2.1"
},
"engines": {
"node": "10.* || >= 12"
@@ -0,0 +1,57 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { IPCRequest } from 'desktop/services/ipc';
import sinon from 'sinon';
module('Unit | Service | ipc', function(hooks) {
setupTest(hooks);
hooks.beforeEach(() => {
// IPC requests talk to the main process indirectly via window.postMessage
// proxy layer (mediated by preload.js).
// But we don't want to send these for real in tests.
sinon.stub(window, 'postMessage');
});
hooks.afterEach(() => {
sinon.restore();
});
test('it creates new IPCRequest objects', function(assert) {
assert.expect(1);
const service = this.owner.lookup('service:ipc');
const request = service.invoke('hello', 'world', 'http://localhost:4200');
assert.equal(request.constructor, IPCRequest);
});
test('IPCRequest objects post messages on their window objects', function(assert) {
assert.expect(2);
const myWindow = {
postMessage(request) {
assert.equal(request.method, 'hello');
assert.equal(request.payload, 'world');
}
};
const request = new IPCRequest('hello', 'world', myWindow);
});
test('IPCRequest objects resolve to the value posted via a response message port', async function(assert) {
assert.expect(1);
const myWindow = {
postMessage(request, origin, [ port ]) {
// Post back a message on the response port
port.postMessage({
foo: 'bar',
test: 42
});
}
};
const request = new IPCRequest('hello', 'world', myWindow);
const response = await request;
assert.deepEqual(response, {
foo: 'bar',
test: 42
});
});
});
+81 -17
View File
@@ -6341,9 +6341,9 @@ caseless@~0.11.0:
integrity sha1-cVuW6phBWTzDMGeSP17GDr2k99c=
ccount@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043"
integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==
version "1.0.5"
resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.5.tgz#ac82a944905a65ce204eb03023157edf29425c17"
integrity sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw==
chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2"
@@ -6420,7 +6420,7 @@ cheerio@^1.0.0-rc.2:
lodash "^4.15.0"
parse5 "^3.0.1"
"chokidar@>=2.0.0 <4.0.0", chokidar@^3.3.0, chokidar@^3.4.1:
"chokidar@>=2.0.0 <4.0.0":
version "3.4.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b"
integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==
@@ -6454,6 +6454,21 @@ chokidar@^2.1.8:
optionalDependencies:
fsevents "^1.2.7"
chokidar@^3.3.0, chokidar@^3.4.1:
version "3.4.2"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d"
integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==
dependencies:
anymatch "~3.1.1"
braces "~3.0.2"
glob-parent "~5.1.0"
is-binary-path "~2.1.0"
is-glob "~4.0.1"
normalize-path "~3.0.0"
readdirp "~3.4.0"
optionalDependencies:
fsevents "~2.1.2"
chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.3, chownr@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
@@ -11880,7 +11895,14 @@ hosted-git-info@^2.1.4, hosted-git-info@^2.7.1, hosted-git-info@^2.8.8:
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
hosted-git-info@^3.0.2, hosted-git-info@^3.0.6:
hosted-git-info@^3.0.2:
version "3.0.5"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.5.tgz#bea87905ef7317442e8df3087faa3c842397df03"
integrity sha512-i4dpK6xj9BIpVOTboXIlKG9+8HMKggcrMX7WA24xZtKwX0TPelq/rbaS5rCKeNX8sJXZJGdSxpnEGtta+wismQ==
dependencies:
lru-cache "^6.0.0"
hosted-git-info@^3.0.6:
version "3.0.7"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.7.tgz#a30727385ea85acfcee94e0aad9e368c792e036c"
integrity sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==
@@ -12530,7 +12552,12 @@ is-buffer@^2.0.0:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
is-callable@^1.1.4, is-callable@^1.2.2:
is-callable@^1.1.4:
version "1.1.5"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==
is-callable@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9"
integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==
@@ -15433,7 +15460,7 @@ npm-package-arg@^7.0.0:
semver "^5.6.0"
validate-npm-package-name "^3.0.0"
npm-package-arg@^8.0.0, npm-package-arg@^8.0.1:
npm-package-arg@^8.0.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.0.tgz#b5f6319418c3246a1c38e1a8fbaa06231bc5308f"
integrity sha512-/ep6QDxBkm9HvOhOg0heitSd7JHA1U7y1qhhlRlteYYAi9Pdb/ZV7FW5aHpkrpM8+P+4p/jjR8zCyKPBMBjSig==
@@ -15442,6 +15469,15 @@ npm-package-arg@^8.0.0, npm-package-arg@^8.0.1:
semver "^7.0.0"
validate-npm-package-name "^3.0.0"
npm-package-arg@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.0.1.tgz#9d76f8d7667b2373ffda60bb801a27ef71e3e270"
integrity sha512-/h5Fm6a/exByzFSTm7jAyHbgOqErl9qSNJDQF32Si/ZzgwT2TERVxRxn3Jurw1wflgyVVAxnFR4fRHPM7y1ClQ==
dependencies:
hosted-git-info "^3.0.2"
semver "^7.0.0"
validate-npm-package-name "^3.0.0"
npm-packlist@^1.1.12, npm-packlist@^1.1.6, npm-packlist@^1.4.6, npm-packlist@^1.4.8:
version "1.4.8"
resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
@@ -15863,7 +15899,7 @@ onetime@^5.1.0:
dependencies:
mimic-fn "^2.1.0"
open@^7.0.0, open@^7.0.2, open@^7.0.3, open@^7.2.0:
open@^7.0.0, open@^7.2.0:
version "7.3.0"
resolved "https://registry.yarnpkg.com/open/-/open-7.3.0.tgz#45461fdee46444f3645b6e14eb3ca94b82e1be69"
integrity sha512-mgLwQIx2F/ye9SmbrUkurZCnkoXyXyu9EbHtJZrICjVAJfyMArdHp3KkixGdZx1ZHFPNIwl0DDM1dFFqXbTLZw==
@@ -15871,6 +15907,22 @@ open@^7.0.0, open@^7.0.2, open@^7.0.3, open@^7.2.0:
is-docker "^2.0.0"
is-wsl "^2.1.1"
open@^7.0.2:
version "7.2.1"
resolved "https://registry.yarnpkg.com/open/-/open-7.2.1.tgz#07b0ade11a43f2a8ce718480bdf3d7563a095195"
integrity sha512-xbYCJib4spUdmcs0g/2mK1nKo/jO2T7INClWd/beL7PFkXRWgr8B23ssDHX/USPn2M2IjDR5UdpYs6I67SnTSA==
dependencies:
is-docker "^2.0.0"
is-wsl "^2.1.1"
open@^7.0.3:
version "7.0.4"
resolved "https://registry.yarnpkg.com/open/-/open-7.0.4.tgz#c28a9d315e5c98340bf979fdcb2e58664aa10d83"
integrity sha512-brSA+/yq+b08Hsr4c8fsEW2CRzk1BmfN3SAK/5VCHQ9bdoZJ4qa/+AfR0xHjlbbZUyPkUHs1b8x1RqdyZdkVqQ==
dependencies:
is-docker "^2.0.0"
is-wsl "^2.1.1"
opener@^1.5.1:
version "1.5.2"
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
@@ -17382,7 +17434,7 @@ read-package-json-fast@^1.0.3:
json-parse-even-better-errors "^2.3.0"
npm-normalize-package-bin "^1.0.1"
"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@^2.0.13, read-package-json@^2.1.1:
"read-package-json@1 || 2", read-package-json@^2.0.13, read-package-json@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.2.tgz#6992b2b66c7177259feb8eaac73c3acd28b9222a"
integrity sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==
@@ -17392,6 +17444,18 @@ read-package-json-fast@^1.0.3:
normalize-package-data "^2.0.0"
npm-normalize-package-bin "^1.0.0"
read-package-json@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.1.tgz#16aa66c59e7d4dad6288f179dd9295fd59bb98f1"
integrity sha512-dAiqGtVc/q5doFz6096CcnXhpYk0ZN8dEKVkGLU0CsASt8SrgF6SF7OTKAYubfvFhWaqofl+Y8HK19GR8jwW+A==
dependencies:
glob "^7.1.1"
json-parse-better-errors "^1.0.1"
normalize-package-data "^2.0.0"
npm-normalize-package-bin "^1.0.0"
optionalDependencies:
graceful-fs "^4.1.2"
read-package-tree@^5.3.1:
version "5.3.1"
resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.3.1.tgz#a32cb64c7f31eb8a6f31ef06f9cedf74068fe636"
@@ -17512,6 +17576,13 @@ readdirp@^2.2.1:
micromatch "^3.1.10"
readable-stream "^2.0.2"
readdirp@~3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada"
integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==
dependencies:
picomatch "^2.2.1"
readdirp@~3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e"
@@ -18600,7 +18671,7 @@ single-line-log@^1.1.2:
dependencies:
string-width "^1.0.1"
sinon@^9.1.0:
sinon@^9.1.0, sinon@^9.2.1:
version "9.2.1"
resolved "https://registry.yarnpkg.com/sinon/-/sinon-9.2.1.tgz#64cc88beac718557055bd8caa526b34a2231be6d"
integrity sha512-naPfsamB5KEE1aiioaoqJ6MEhdUs/2vtI5w1hPAXX/UwvoPjXcwh1m5HiKx0HGgKR8lQSoFIgY5jM6KK8VrS9w==
@@ -20543,13 +20614,6 @@ util-extend@^1.0.1:
resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f"
integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=
util-promisify@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/util-promisify/-/util-promisify-2.1.0.tgz#3c2236476c4d32c5ff3c47002add7c13b9a82a53"
integrity sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=
dependencies:
object.getownpropertydescriptors "^2.0.3"
util.promisify@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030"