[Reporting] Upgrade Puppeteer dependency to 10.2.0 (#115682)

* [Reporting] Upgrade Puppeteer dependency to 10.2.0

* Update x-pack/plugins/reporting/server/browsers/chromium/paths.ts

* self-edit

* Apply suggestions from code review

Co-authored-by: Michael Dokolin <dokmic@gmail.com>

* fix lint

Co-authored-by: Michael Dokolin <dokmic@gmail.com>
This commit is contained in:
Tim Sullivan 2021-10-20 13:22:44 -07:00 committed by GitHub
parent e258e143e9
commit e3f4107d90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 165 additions and 96 deletions

View file

@ -309,7 +309,7 @@
"prop-types": "^15.7.2",
"proxy-from-env": "1.0.0",
"puid": "1.0.7",
"puppeteer": "^8.0.0",
"puppeteer": "^10.2.0",
"query-string": "^6.13.2",
"random-word-slugs": "^0.0.5",
"raw-loader": "^3.1.0",

View file

@ -99,7 +99,15 @@ are created in x64 using cross-compiling. CentOS is not supported for building C
## Artifacts
After the build completes, there will be a .zip file and a .md5 file in `~/chromium/chromium/src/out/headless`. These are named like so: `chromium-{first_7_of_SHA}-{platform}-{arch}`, for example: `chromium-4747cc2-linux-x64`.
The zip files and md5 files are copied to a staging bucket in GCP storage.
The zip files and md5 files are copied to a **staging** bucket in GCP storage.
To publish the built artifacts for bunding in Kibana, copy the files from the `headless_shell_staging` bucket to the `headless_shell` bucket.
```
gsutil cp gs://headless_shell_staging/chromium-d163fd7-linux_arm64.md5 gs://headless_shell/
gsutil cp gs://headless_shell_staging/chromium-d163fd7-linux_arm64.zip gs://headless_shell/
```
IMPORTANT: Do not replace builds in the `headless_shell` bucket that are referenced in an active Kibana branch. CI tests on that branch will fail since the archive checksum no longer matches the original version.
## Testing
Search the Puppeteer Github repo for known issues that could affect our use case, and make sure to test anywhere that is affected.

View file

@ -265,7 +265,7 @@ export class HeadlessChromiumDriver {
}
// @ts-ignore
// FIXME: use `await page.target().createCDPSession();`
// FIXME: retrieve the client in open() and pass in the client
const client = this.page._client;
// We have to reach into the Chrome Devtools Protocol to apply headers as using
@ -372,7 +372,6 @@ export class HeadlessChromiumDriver {
await client.send('Debugger.enable');
await client.send('Debugger.pause');
// @ts-ignore
const targetId = target._targetId;
const wsEndpoint = this.page.browser().wsEndpoint();
const { port } = parseUrl(wsEndpoint);

View file

@ -25,18 +25,6 @@ import { HeadlessChromiumDriver } from '../driver';
import { args } from './args';
import { getMetrics, Metrics } from './metrics';
// Puppeteer type definitions do not match the documentation.
// See https://pptr.dev/#?product=Puppeteer&version=v8.0.0&show=api-puppeteerlaunchoptions
interface ReportingLaunchOptions extends puppeteer.LaunchOptions {
userDataDir?: string;
ignoreHTTPSErrors?: boolean;
args?: string[];
}
declare module 'puppeteer' {
function launch(options: ReportingLaunchOptions): Promise<puppeteer.Browser>;
}
type BrowserConfig = CaptureConfig['browser']['chromium'];
export class HeadlessChromiumDriverFactory {

View file

@ -14,6 +14,7 @@ interface PackageInfo {
archiveChecksum: string;
binaryChecksum: string;
binaryRelativePath: string;
revision: number;
}
enum BaseUrl {
@ -32,8 +33,6 @@ interface CommonPackageInfo extends PackageInfo {
}
export class ChromiumArchivePaths {
public readonly revision = '856583';
public readonly packages: Array<CustomPackageInfo | CommonPackageInfo> = [
{
platform: 'darwin',
@ -43,34 +42,38 @@ export class ChromiumArchivePaths {
binaryChecksum: 'dfcd6e007214175997663c50c8d871ea',
binaryRelativePath: 'headless_shell-darwin_x64/headless_shell',
location: 'custom',
revision: 856583,
},
{
platform: 'linux',
architecture: 'x64',
archiveFilename: 'chromium-d163fd7-linux_x64.zip',
archiveChecksum: 'fba0a240d409228a3494aef415c300fc',
binaryChecksum: '99cfab472d516038b94ef86649e52871',
archiveFilename: 'chromium-70f5d88-linux_x64.zip',
archiveChecksum: '7b1c9c2fb613444fbdf004a3b75a58df',
binaryChecksum: '82e80f9727a88ba3836ce230134bd126',
binaryRelativePath: 'headless_shell-linux_x64/headless_shell',
location: 'custom',
revision: 901912,
},
{
platform: 'linux',
architecture: 'arm64',
archiveFilename: 'chromium-d163fd7-linux_arm64.zip',
archiveChecksum: '29834735bc2f0e0d9134c33bc0580fb6',
binaryChecksum: '13baccf2e5c8385cb9d9588db6a9e2c2',
archiveFilename: 'chromium-70f5d88-linux_arm64.zip',
archiveChecksum: '4a0217cfe7da86ad1e3d0e9e5895ddb5',
binaryChecksum: '29e943fbee6d87a217abd6cb6747058e',
binaryRelativePath: 'headless_shell-linux_arm64/headless_shell',
location: 'custom',
revision: 901912,
},
{
platform: 'win32',
architecture: 'x64',
archiveFilename: 'chrome-win.zip',
archiveChecksum: '64999a384bfb6c96c50c4cb6810dbc05',
binaryChecksum: '13b8bbb4a12f9036b8cc3b57b3a71fec',
archiveChecksum: '861bb8b7b8406a6934a87d3cbbce61d9',
binaryChecksum: 'ffa0949471e1b9a57bc8f8633fca9c7b',
binaryRelativePath: 'chrome-win\\chrome.exe',
location: 'common',
archivePath: 'Win',
revision: 901912,
},
];
@ -82,7 +85,8 @@ export class ChromiumArchivePaths {
}
public resolvePath(p: PackageInfo) {
return path.resolve(this.archivesPath, p.archiveFilename);
// adding architecture to the path allows it to download two binaries that have the same name, but are different architecture
return path.resolve(this.archivesPath, p.architecture, p.archiveFilename);
}
public getAllArchiveFilenames(): string[] {
@ -91,9 +95,9 @@ export class ChromiumArchivePaths {
public getDownloadUrl(p: CustomPackageInfo | CommonPackageInfo) {
if (p.location === 'common') {
return `${BaseUrl.common}/${p.archivePath}/${this.revision}/${p.archiveFilename}`;
return `${BaseUrl.common}/${p.archivePath}/${p.revision}/${p.archiveFilename}`;
}
return BaseUrl.custom + '/' + p.archiveFilename;
return BaseUrl.custom + '/' + p.archiveFilename; // revision is not used for URL if package is a custom build
}
public getBinaryPath(p: PackageInfo) {

View file

@ -49,6 +49,8 @@ export async function download(
resolve();
});
});
} catch (err) {
throw new Error(`Unable to download ${url}: ${err}`);
} finally {
closeSync(handle);
}

View file

@ -5,6 +5,7 @@
* 2.0.
*/
import path from 'path';
import mockFs from 'mock-fs';
import { existsSync, readdirSync } from 'fs';
import { chromium } from '../chromium';
@ -27,16 +28,16 @@ describe('ensureBrowserDownloaded', () => {
} as unknown as typeof logger;
(md5 as jest.MockedFunction<typeof md5>).mockImplementation(
async (path) =>
async (packagePath) =>
chromium.paths.packages.find(
(packageInfo) => chromium.paths.resolvePath(packageInfo) === path
(packageInfo) => chromium.paths.resolvePath(packageInfo) === packagePath
)?.archiveChecksum ?? 'some-md5'
);
(download as jest.MockedFunction<typeof download>).mockImplementation(
async (_url, path) =>
async (_url, packagePath) =>
chromium.paths.packages.find(
(packageInfo) => chromium.paths.resolvePath(packageInfo) === path
(packageInfo) => chromium.paths.resolvePath(packageInfo) === packagePath
)?.archiveChecksum ?? 'some-md5'
);
@ -93,11 +94,19 @@ describe('ensureBrowserDownloaded', () => {
await ensureBrowserDownloaded(logger);
expect(download).not.toHaveBeenCalled();
expect(readdirSync(chromium.paths.archivesPath)).toEqual(
expect.arrayContaining(
chromium.paths.packages.map(({ archiveFilename }) => archiveFilename)
)
);
const paths = [
readdirSync(path.resolve(chromium.paths.archivesPath + '/x64')),
readdirSync(path.resolve(chromium.paths.archivesPath + '/arm64')),
];
expect(paths).toEqual([
expect.arrayContaining([
'chrome-win.zip',
'chromium-70f5d88-linux_x64.zip',
'chromium-d163fd7-darwin_x64.zip',
]),
expect.arrayContaining(['chromium-70f5d88-linux_arm64.zip']),
]);
});
it('should download again if md5 hash different', async () => {

View file

@ -15,7 +15,6 @@ import { download } from './download';
/**
* Check for the downloaded archive of each requested browser type and
* download them if they are missing or their checksum is invalid
* @return {Promise<undefined>}
*/
export async function ensureBrowserDownloaded(logger: GenericLevelLogger) {
await ensureDownloaded([chromium], logger);
@ -25,18 +24,19 @@ export async function ensureBrowserDownloaded(logger: GenericLevelLogger) {
* Clears the unexpected files in the browsers archivesPath
* and ensures that all packages/archives are downloaded and
* that their checksums match the declared value
* @param {BrowserSpec} browsers
* @return {Promise<undefined>}
*/
async function ensureDownloaded(browsers: BrowserDownload[], logger: GenericLevelLogger) {
await Promise.all(
browsers.map(async ({ paths: pSet }) => {
(
await del(`${pSet.archivesPath}/**/*`, {
force: true,
ignore: pSet.getAllArchiveFilenames(),
})
).forEach((path) => logger.warning(`Deleting unexpected file ${path}`));
const removedFiles = await del(`${pSet.archivesPath}/**/*`, {
force: true,
onlyFiles: true,
ignore: pSet.getAllArchiveFilenames(),
});
removedFiles.forEach((path) => {
logger.warning(`Deleting unexpected file ${path}`);
});
const invalidChecksums: string[] = [];
await Promise.all(
@ -44,22 +44,44 @@ async function ensureDownloaded(browsers: BrowserDownload[], logger: GenericLeve
const { archiveFilename, archiveChecksum } = p;
if (archiveFilename && archiveChecksum) {
const path = pSet.resolvePath(p);
const pathExists = existsSync(path);
if (existsSync(path) && (await md5(path)) === archiveChecksum) {
logger.debug(`Browser archive exists in ${path}`);
let foundChecksum: string;
try {
foundChecksum = await md5(path).catch();
} catch {
foundChecksum = 'MISSING';
}
if (pathExists && foundChecksum === archiveChecksum) {
logger.debug(`Browser archive for ${p.platform}/${p.architecture} found in ${path} `);
return;
}
if (!pathExists) {
logger.warning(
`Browser archive for ${p.platform}/${p.architecture} not found in ${path}.`
);
}
if (foundChecksum !== archiveChecksum) {
logger.warning(
`Browser archive checksum for ${p.platform}/${p.architecture} ` +
`is ${foundChecksum} but ${archiveChecksum} was expected.`
);
}
const url = pSet.getDownloadUrl(p);
try {
const downloadedChecksum = await download(url, path, logger);
if (downloadedChecksum !== archiveChecksum) {
logger.warning(
`Invalid checksum for ${p.platform}/${p.architecture}: ` +
`expected ${archiveChecksum} got ${downloadedChecksum}`
);
invalidChecksums.push(`${url} => ${path}`);
}
} catch (err) {
const message = new Error(`Failed to download ${url}`);
logger.error(err);
throw message;
throw new Error(`Failed to download ${url}: ${err}`);
}
}
})

View file

@ -28,7 +28,8 @@ export interface BrowserDownload {
}
export const initializeBrowserDriverFactory = async (core: ReportingCore, logger: LevelLogger) => {
const { binaryPath$ } = installBrowser(logger);
const chromiumLogger = logger.clone(['chromium']);
const { binaryPath$ } = installBrowser(chromiumLogger);
const binaryPath = await binaryPath$.pipe(first()).toPromise();
return chromium.createDriverFactory(core, binaryPath, logger);
return chromium.createDriverFactory(core, binaryPath, chromiumLogger);
};

View file

@ -39,15 +39,28 @@ export function installBrowser(
const binaryChecksum = await md5(binaryPath).catch(() => '');
if (binaryChecksum !== pkg.binaryChecksum) {
await ensureBrowserDownloaded(logger);
await del(chromiumPath);
logger.warning(
`Found browser binary checksum for ${pkg.platform}/${pkg.architecture} ` +
`is ${binaryChecksum} but ${pkg.binaryChecksum} was expected. Re-installing...`
);
try {
await del(chromiumPath);
} catch (err) {
logger.error(err);
}
const archive = path.join(paths.archivesPath, pkg.archiveFilename);
logger.info(`Extracting [${archive}] to [${chromiumPath}]`);
await extract(archive, chromiumPath);
try {
await ensureBrowserDownloaded(logger);
const archive = path.join(paths.archivesPath, pkg.architecture, pkg.archiveFilename);
logger.info(`Extracting [${archive}] to [${chromiumPath}]`);
await extract(archive, chromiumPath);
} catch (err) {
logger.error(err);
}
}
logger.info(`Browser executable: ${binaryPath}`);
binaryPath$.next(binaryPath); // subscribers wait for download and extract to complete
};

View file

@ -12243,7 +12243,7 @@ debug@3.X, debug@^3.0.0, debug@^3.0.1, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5,
dependencies:
ms "^2.1.1"
debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1:
debug@4, debug@4.3.1, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
@ -12693,10 +12693,10 @@ devtools-protocol@0.0.818844:
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.818844.tgz#d1947278ec85b53e4c8ca598f607a28fa785ba9e"
integrity sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg==
devtools-protocol@0.0.854822:
version "0.0.854822"
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.854822.tgz#eac3a5260a6b3b4e729a09fdc0c77b0d322e777b"
integrity sha512-xd4D8kHQtB0KtWW0c9xBZD5LVtm9chkMOfs/3Yn01RhT/sFIsVtzTtypfKoFfWBaL+7xCYLxjOLkhwPXaX/Kcg==
devtools-protocol@0.0.901419:
version "0.0.901419"
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.901419.tgz#79b5459c48fe7e1c5563c02bd72f8fec3e0cebcd"
integrity sha512-4INMPwNm9XRpBukhNbF7OB6fNTTCaI8pzy/fXg0xQzAy5h3zL1P8xT3QazgKqBrb/hAYwIBizqDBZ7GtJE74QQ==
dezalgo@^1.0.0:
version "1.0.3"
@ -20993,7 +20993,7 @@ node-emoji@^1.10.0:
dependencies:
lodash.toarray "^4.4.0"
node-fetch@^1.0.1, node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1:
node-fetch@2.6.1, node-fetch@^1.0.1, node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
@ -22441,6 +22441,13 @@ pixelmatch@^5.1.0:
dependencies:
pngjs "^3.4.0"
pkg-dir@4.2.0, pkg-dir@^4.1.0, pkg-dir@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
dependencies:
find-up "^4.0.0"
pkg-dir@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
@ -22455,13 +22462,6 @@ pkg-dir@^3.0.0:
dependencies:
find-up "^3.0.0"
pkg-dir@^4.1.0, pkg-dir@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
dependencies:
find-up "^4.0.0"
pkg-up@3.1.0, pkg-up@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5"
@ -23186,6 +23186,11 @@ process@~0.5.1:
resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=
progress@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31"
integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==
progress@^1.1.8:
version "1.1.8"
resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"
@ -23330,7 +23335,7 @@ proxy-from-env@1.0.0:
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee"
integrity sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=
proxy-from-env@^1.0.0, proxy-from-env@^1.1.0:
proxy-from-env@1.1.0, proxy-from-env@^1.0.0, proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
@ -23425,6 +23430,24 @@ pupa@^2.1.1:
dependencies:
escape-goat "^2.0.0"
puppeteer@^10.2.0:
version "10.4.0"
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-10.4.0.tgz#a6465ff97fda0576c4ac29601406f67e6fea3dc7"
integrity sha512-2cP8mBoqnu5gzAVpbZ0fRaobBWZM8GEUF4I1F6WbgHrKV/rz7SX8PG2wMymZgD0wo0UBlg2FBPNxlF/xlqW6+w==
dependencies:
debug "4.3.1"
devtools-protocol "0.0.901419"
extract-zip "2.0.1"
https-proxy-agent "5.0.0"
node-fetch "2.6.1"
pkg-dir "4.2.0"
progress "2.0.1"
proxy-from-env "1.1.0"
rimraf "3.0.2"
tar-fs "2.0.0"
unbzip2-stream "1.3.3"
ws "7.4.6"
puppeteer@^5.3.1:
version "5.5.0"
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-5.5.0.tgz#331a7edd212ca06b4a556156435f58cbae08af00"
@ -23443,24 +23466,6 @@ puppeteer@^5.3.1:
unbzip2-stream "^1.3.3"
ws "^7.2.3"
puppeteer@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-8.0.0.tgz#a236669118aa795331c2d0ca19877159e7664705"
integrity sha512-D0RzSWlepeWkxPPdK3xhTcefj8rjah1791GE82Pdjsri49sy11ci/JQsAO8K2NRukqvwEtcI+ImP5F4ZiMvtIQ==
dependencies:
debug "^4.1.0"
devtools-protocol "0.0.854822"
extract-zip "^2.0.0"
https-proxy-agent "^5.0.0"
node-fetch "^2.6.1"
pkg-dir "^4.2.0"
progress "^2.0.1"
proxy-from-env "^1.1.0"
rimraf "^3.0.2"
tar-fs "^2.0.0"
unbzip2-stream "^1.3.3"
ws "^7.2.3"
q@^1.1.2, q@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
@ -27468,6 +27473,16 @@ tape@^5.0.1:
string.prototype.trim "^1.2.1"
through "^2.3.8"
tar-fs@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.0.tgz#677700fc0c8b337a78bee3623fdc235f21d7afad"
integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==
dependencies:
chownr "^1.1.1"
mkdirp "^0.5.1"
pump "^3.0.0"
tar-stream "^2.0.0"
tar-fs@^2.0.0, tar-fs@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784"
@ -28433,6 +28448,14 @@ unbox-primitive@^1.0.1:
has-symbols "^1.0.2"
which-boxed-primitive "^1.0.2"
unbzip2-stream@1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz#d156d205e670d8d8c393e1c02ebd506422873f6a"
integrity sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==
dependencies:
buffer "^5.2.1"
through "^2.3.8"
unbzip2-stream@^1.3.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7"
@ -30276,6 +30299,11 @@ write-pkg@^4.0.0:
type-fest "^0.4.1"
write-json-file "^3.2.0"
ws@7.4.6, ws@^7.2.3:
version "7.4.6"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
ws@>=7.4.6, ws@^7.4.6:
version "7.5.5"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881"
@ -30288,11 +30316,6 @@ ws@^6.1.2, ws@^6.2.1:
dependencies:
async-limiter "~1.0.0"
ws@^7.2.3:
version "7.4.6"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
x-is-function@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/x-is-function/-/x-is-function-1.0.4.tgz#5d294dc3d268cbdd062580e0c5df77a391d1fa1e"