diff --git a/package.json b/package.json index 093624ad1e..ad6a728b76 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "productName": "OpenLens", "description": "OpenLens - Open Source IDE for Kubernetes", "homepage": "https://github.com/lensapp/lens", - "version": "5.2.0-beta.3", + "version": "5.2.0-beta.4", "main": "static/build/main.js", "copyright": "© 2021 OpenLens Authors", "license": "MIT", @@ -208,7 +208,7 @@ "immer": "^8.0.1", "joi": "^17.4.2", "js-yaml": "^3.14.0", - "jsdom": "^16.4.0", + "jsdom": "^16.7.0", "jsonpath": "^1.0.2", "lodash": "^4.17.15", "mac-ca": "^1.0.6", @@ -238,7 +238,7 @@ "request": "^2.88.2", "request-promise-native": "^1.0.9", "semver": "^7.3.2", - "serializr": "^2.0.3", + "serializr": "^2.0.5", "shell-env": "^3.0.1", "spdy": "^4.0.2", "tar": "^6.1.10", @@ -284,8 +284,8 @@ "@types/md5-file": "^4.0.2", "@types/mini-css-extract-plugin": "^0.9.1", "@types/mock-fs": "^4.13.1", - "@types/module-alias": "^2.0.0", - "@types/node": "12.20", + "@types/module-alias": "^2.0.1", + "@types/node": "14.17.14", "@types/node-fetch": "^2.5.12", "@types/npm": "^2.0.32", "@types/progress-bar-webpack-plugin": "^2.1.2", @@ -298,7 +298,7 @@ "@types/react-select": "3.1.2", "@types/react-table": "^7.7.0", "@types/react-virtualized-auto-sizer": "^1.0.1", - "@types/react-window": "^1.8.2", + "@types/react-window": "^1.8.5", "@types/readable-stream": "^2.3.9", "@types/request": "^2.48.7", "@types/request-promise-native": "^1.0.17", diff --git a/src/common/catalog/catalog-category-registry.ts b/src/common/catalog/catalog-category-registry.ts index 207dc2af3d..bad1570c9c 100644 --- a/src/common/catalog/catalog-category-registry.ts +++ b/src/common/catalog/catalog-category-registry.ts @@ -76,6 +76,10 @@ export class CatalogCategoryRegistry { return this.getForGroupKind(group, data.kind); } + + getByName(name: string) { + return this.items.find(category => category.metadata?.name == name); + } } export const catalogCategoryRegistry = new CatalogCategoryRegistry(); diff --git a/src/common/ipc/ipc.ts b/src/common/ipc/ipc.ts index f93a9486aa..9ed51b7790 100644 --- a/src/common/ipc/ipc.ts +++ b/src/common/ipc/ipc.ts @@ -28,8 +28,9 @@ import { toJS } from "../utils/toJS"; import logger from "../../main/logger"; import { ClusterFrameInfo, clusterFrameMap } from "../cluster-frames"; import type { Disposer } from "../utils"; +import type remote from "@electron/remote"; -const remote = ipcMain ? null : require("@electron/remote"); +const electronRemote = ipcMain ? null : require("@electron/remote"); const subFramesChannel = "ipc:get-sub-frames"; @@ -48,9 +49,9 @@ function getSubFrames(): ClusterFrameInfo[] { } export function broadcastMessage(channel: string, ...args: any[]) { - const views = (webContents || remote?.webContents)?.getAllWebContents(); + const views: undefined | ReturnType | ReturnType = (webContents || electronRemote?.webContents)?.getAllWebContents(); - if (!views) return; + if (!views || !Array.isArray(views) || views.length === 0) return; args = args.map(sanitizePayload); ipcRenderer?.send(channel, ...args); @@ -63,15 +64,32 @@ export function broadcastMessage(channel: string, ...args: any[]) { subFramesP .then(subFrames => { for (const view of views) { - try { - logger.silly(`[IPC]: broadcasting "${channel}" to ${view.getType()}=${view.id}`, { args }); - view.send(channel, ...args); + let viewType = "unknown"; - for (const frameInfo of subFrames) { - view.sendToFrame([frameInfo.processId, frameInfo.frameId], channel, ...args); - } + // There will be a uncaught exception if the view is destroyed. + try { + viewType = view.getType(); + } catch { + // We can ignore the view destroyed exception as viewType is only used for logging. + } + + // Send message to views. + try { + logger.silly(`[IPC]: broadcasting "${channel}" to ${viewType}=${view.id}`, { args }); + view.send(channel, ...args); } catch (error) { - logger.error("[IPC]: failed to send IPC message", { error: String(error) }); + logger.error(`[IPC]: failed to send IPC message "${channel}" to view "${viewType}=${view.id}"`, { error: String(error) }); + } + + // Send message to subFrames of views. + for (const frameInfo of subFrames) { + logger.silly(`[IPC]: broadcasting "${channel}" to subframe "frameInfo.processId"=${frameInfo.processId} "frameInfo.frameId"=${frameInfo.frameId}`, { args }); + + try { + view.sendToFrame([frameInfo.processId, frameInfo.frameId], channel, ...args); + } catch (error) { + logger.error(`[IPC]: failed to send IPC message "${channel}" to view "${viewType}=${view.id}"'s subframe "frameInfo.processId"=${frameInfo.processId} "frameInfo.frameId"=${frameInfo.frameId}`, { error: String(error) }); + } } } }); diff --git a/src/main/catalog-sources/general.ts b/src/main/catalog-sources/general.ts index 6b16984d1d..a002228274 100644 --- a/src/main/catalog-sources/general.ts +++ b/src/main/catalog-sources/general.ts @@ -21,7 +21,7 @@ import { observable } from "mobx"; import { GeneralEntity } from "../../common/catalog-entities/general"; -import { catalogURL, preferencesURL } from "../../common/routes"; +import { catalogURL, preferencesURL, welcomeURL } from "../../common/routes"; import { catalogEntityRegistry } from "../catalog"; export const catalogEntity = new GeneralEntity({ @@ -62,9 +62,29 @@ const preferencesEntity = new GeneralEntity({ } }); +const welcomePageEntity = new GeneralEntity({ + metadata: { + uid: "welcome-page-entity", + name: "Welcome Page", + source: "app", + labels: {} + }, + spec: { + path: welcomeURL(), + icon: { + material: "meeting_room", + background: "#3d90ce" + } + }, + status: { + phase: "active", + } +}); + const generalEntities = observable([ catalogEntity, - preferencesEntity + preferencesEntity, + welcomePageEntity ]); export function syncGeneralEntities() { diff --git a/src/main/catalog-sources/helpers/general-active-sync.ts b/src/main/catalog-sources/helpers/general-active-sync.ts new file mode 100644 index 0000000000..e46e27f827 --- /dev/null +++ b/src/main/catalog-sources/helpers/general-active-sync.ts @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * 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 { when } from "mobx"; +import { catalogCategoryRegistry } from "../../../common/catalog"; +import { catalogEntityRegistry } from "../../../renderer/api/catalog-entity-registry"; +import { isActiveRoute } from "../../../renderer/navigation"; + +export async function setEntityOnRouteMatch() { + await when(() => catalogEntityRegistry.entities.size > 0); + + const entities = catalogEntityRegistry.getItemsForCategory(catalogCategoryRegistry.getByName("General")); + const activeEntity = entities.find(entity => isActiveRoute(entity.spec.path)); + + if (activeEntity) { + catalogEntityRegistry.activeEntity = activeEntity; + } +} diff --git a/src/main/cluster-detectors/distribution-detector.ts b/src/main/cluster-detectors/distribution-detector.ts index 31f32972de..98173ef81c 100644 --- a/src/main/cluster-detectors/distribution-detector.ts +++ b/src/main/cluster-detectors/distribution-detector.ts @@ -33,6 +33,10 @@ export class DistributionDetector extends BaseClusterDetector { return { value: "rke", accuracy: 80}; } + if (this.isRancherDesktop()) { + return { value: "rancher-desktop", accuracy: 80}; + } + if (this.isK3s()) { return { value: "k3s", accuracy: 80}; } @@ -172,6 +176,10 @@ export class DistributionDetector extends BaseClusterDetector { return this.version.includes("-rancher"); } + protected isRancherDesktop() { + return this.cluster.contextName === "rancher-desktop"; + } + protected isK3s() { return this.version.includes("+k3s"); } diff --git a/src/main/index.ts b/src/main/index.ts index ce3cafd926..3dd478fc76 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -69,6 +69,8 @@ import { kubeApiRequest, shellApiRequest } from "./proxy-functions"; const onCloseCleanup = disposer(); const onQuitCleanup = disposer(); +const workingDir = path.join(app.getPath("appData"), appName); + SentryInit(); app.setName(appName); @@ -83,6 +85,8 @@ if (app.setAsDefaultProtocolClient("lens")) { if (process.env.CICD) { app.setPath("appData", process.env.CICD); app.setPath("userData", path.join(process.env.CICD, appName)); +} else { + app.setPath("userData", workingDir); } if (process.env.LENS_DISABLE_GPU) { diff --git a/src/main/menu.ts b/src/main/menu.ts index 34bd724d0a..92782cd3d0 100644 --- a/src/main/menu.ts +++ b/src/main/menu.ts @@ -188,14 +188,14 @@ export function buildMenu(windowManager: WindowManager) { label: "Back", accelerator: "CmdOrCtrl+[", click() { - webContents.getFocusedWebContents()?.goBack(); + webContents.getAllWebContents().filter(wc => wc.getType() === "window").forEach(wc => wc.goBack()); } }, { label: "Forward", accelerator: "CmdOrCtrl+]", click() { - webContents.getFocusedWebContents()?.goForward(); + webContents.getAllWebContents().filter(wc => wc.getType() === "window").forEach(wc => wc.goForward()); } }, { diff --git a/src/main/window-manager.ts b/src/main/window-manager.ts index 0822ed331a..b0014eac47 100644 --- a/src/main/window-manager.ts +++ b/src/main/window-manager.ts @@ -243,8 +243,10 @@ export class WindowManager extends Singleton { if (frameInfo) { this.sendToView({ channel: IpcRendererNavigationEvents.RELOAD_PAGE, frameInfo }); } else { - webContents.getFocusedWebContents()?.reload(); - webContents.getFocusedWebContents()?.clearHistory(); + webContents.getAllWebContents().filter(wc => wc.getType() === "window").forEach(wc => { + wc.reload(); + wc.clearHistory(); + }); } } diff --git a/src/renderer/components/+catalog/catalog.tsx b/src/renderer/components/+catalog/catalog.tsx index 658c91273f..7f6347f5e3 100644 --- a/src/renderer/components/+catalog/catalog.tsx +++ b/src/renderer/components/+catalog/catalog.tsx @@ -104,7 +104,6 @@ export class Catalog extends React.Component { }, {fireImmediately: true}), ]); } - addToHotbar(item: CatalogEntityItem): void { HotbarStore.getInstance().addToHotbar(item.entity); } diff --git a/src/renderer/components/+preferences/preferences.tsx b/src/renderer/components/+preferences/preferences.tsx index 8cc3120d39..2abed711e6 100644 --- a/src/renderer/components/+preferences/preferences.tsx +++ b/src/renderer/components/+preferences/preferences.tsx @@ -75,7 +75,7 @@ export class Preferences extends React.Component { - {telemetryExtensions.length > 0 || !!sentryDsn && + {(telemetryExtensions.length > 0 || !!sentryDsn) && } {extensions.filter(e => !e.showInPreferencesTab).length > 0 && diff --git a/src/renderer/components/+welcome/__test__/welcome.test.tsx b/src/renderer/components/+welcome/__test__/welcome.test.tsx index d2eda315c4..c0d17faebe 100644 --- a/src/renderer/components/+welcome/__test__/welcome.test.tsx +++ b/src/renderer/components/+welcome/__test__/welcome.test.tsx @@ -32,6 +32,9 @@ jest.mock( ipcRenderer: { on: jest.fn(), }, + app: { + getPath: () => "tmp", + }, }) ); diff --git a/src/renderer/components/+welcome/welcome.tsx b/src/renderer/components/+welcome/welcome.tsx index a4cff08369..f813c957ab 100644 --- a/src/renderer/components/+welcome/welcome.tsx +++ b/src/renderer/components/+welcome/welcome.tsx @@ -58,6 +58,17 @@ export class Welcome extends React.Component { indicators={welcomeBanner.length > 1} autoPlay={true} navButtonsAlwaysInvisible={true} + indicatorIconButtonProps={{ + style: { + color: "var(--iconActiveBackground)" + } + }} + activeIndicatorIconButtonProps={{ + style: { + color: "var(--iconActiveColor)" + } + }} + interval={8000} > {welcomeBanner.map((item, index) => diff --git a/src/renderer/components/cluster-manager/cluster-manager.tsx b/src/renderer/components/cluster-manager/cluster-manager.tsx index 1903625116..687490f94c 100644 --- a/src/renderer/components/cluster-manager/cluster-manager.tsx +++ b/src/renderer/components/cluster-manager/cluster-manager.tsx @@ -23,7 +23,7 @@ import "./cluster-manager.scss"; import React from "react"; import { Redirect, Route, Switch } from "react-router"; -import { observer } from "mobx-react"; +import { disposeOnUnmount, observer } from "mobx-react"; import { BottomBar } from "./bottom-bar"; import { Catalog } from "../+catalog"; import { Preferences } from "../+preferences"; @@ -36,9 +36,18 @@ import { EntitySettings } from "../+entity-settings"; import { Welcome } from "../+welcome"; import * as routes from "../../../common/routes"; import { DeleteClusterDialog } from "../delete-cluster-dialog"; +import { reaction } from "mobx"; +import { navigation } from "../../navigation"; +import { setEntityOnRouteMatch } from "../../../main/catalog-sources/helpers/general-active-sync"; @observer export class ClusterManager extends React.Component { + componentDidMount() { + disposeOnUnmount(this, [ + reaction(() => navigation.location, () => setEntityOnRouteMatch(), { fireImmediately: true }) + ]); + } + render() { return (
diff --git a/src/renderer/components/layout/__tests__/topbar.test.tsx b/src/renderer/components/layout/__tests__/topbar.test.tsx index 499a52bc66..c519d6b881 100644 --- a/src/renderer/components/layout/__tests__/topbar.test.tsx +++ b/src/renderer/components/layout/__tests__/topbar.test.tsx @@ -41,20 +41,28 @@ jest.mock( } ), }, + app: { + getPath: () => "tmp", + }, }) ); +jest.mock("../../+catalog", () => ({ + previousActiveTab: jest.fn() +})); + const goBack = jest.fn(); const goForward = jest.fn(); jest.mock("@electron/remote", () => { return { webContents: { - getFocusedWebContents: () => { - return { + getAllWebContents: () => { + return [{ + getType: () => "window", goBack, goForward - }; + }]; } } }; @@ -75,6 +83,12 @@ describe("", () => { expect(container).toBeInstanceOf(HTMLElement); }); + it("renders home button", async () => { + const { getByTestId } = render(); + + expect(await getByTestId("home-button")).toBeInTheDocument(); + }); + it("renders history arrows", async () => { const { getByTestId } = render(); diff --git a/src/renderer/components/layout/topbar.tsx b/src/renderer/components/layout/topbar.tsx index 2b1c49267a..2783471bb3 100644 --- a/src/renderer/components/layout/topbar.tsx +++ b/src/renderer/components/layout/topbar.tsx @@ -28,6 +28,9 @@ import { webContents } from "@electron/remote"; import { observable } from "mobx"; import { ipcRendererOn } from "../../../common/ipc"; import { watchHistoryState } from "../../remote-helpers/history-updater"; +import { isActiveRoute, navigate } from "../../navigation"; +import { catalogRoute, catalogURL } from "../../../common/routes"; +import { previousActiveTab } from "../+catalog"; interface Props extends React.HTMLAttributes { } @@ -68,12 +71,16 @@ export const TopBar = observer(({ children, ...rest }: Props) => { ); }; + const goHome = () => { + navigate(`${catalogURL()}/${previousActiveTab.get()}`); + }; + const goBack = () => { - webContents.getFocusedWebContents()?.goBack(); + webContents.getAllWebContents().find((webContent) => webContent.getType() === "window")?.goBack(); }; const goForward = () => { - webContents.getFocusedWebContents()?.goForward(); + webContents.getAllWebContents().find((webContent) => webContent.getType() === "window")?.goForward(); }; useEffect(() => { @@ -85,6 +92,13 @@ export const TopBar = observer(({ children, ...rest }: Props) => { return (
+ navigation.location, () => { - broadcastMessage("history:can-go-back", webContents.getFocusedWebContents()?.canGoBack()); - broadcastMessage("history:can-go-forward", webContents.getFocusedWebContents()?.canGoForward()); + const getAllWebContents = webContents.getAllWebContents(); + + const canGoBack = getAllWebContents.some((webContent) => { + if (webContent.getType() === "window") { + return webContent.canGoBack(); + } + + return false; + }); + + const canGoForward = getAllWebContents.some((webContent) => { + if (webContent.getType() === "window") { + return webContent.canGoForward(); + } + + return false; + }); + + broadcastMessage("history:can-go-back", canGoBack); + broadcastMessage("history:can-go-forward", canGoForward); }); } diff --git a/yarn.lock b/yarn.lock index c5a3919b7b..0f6ef99431 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1227,6 +1227,11 @@ "@babel/runtime" "^7.12.5" "@testing-library/dom" "^7.28.1" +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + "@tsconfig/node10@^1.0.7": version "1.0.8" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" @@ -1704,10 +1709,10 @@ dependencies: "@types/node" "*" -"@types/module-alias@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/module-alias/-/module-alias-2.0.0.tgz#882668f8b8cdbda44812c3b592c590909e18849e" - integrity sha512-e3sW4oEH0qS1QxSfX7PT6xIi5qk/YSMsrB9Lq8EtkhQBZB+bKyfkP+jpLJRySanvBhAQPSv2PEBe81M8Iy/7yg== +"@types/module-alias@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/module-alias/-/module-alias-2.0.1.tgz#e5893236ce922152d57c5f3f978f764f4deeb45f" + integrity sha512-DN/CCT1HQG6HquBNJdLkvV+4v5l/oEuwOHUPLxI+Eub0NED+lk0YUfba04WGH90EINiUrNgClkNnwGmbICeWMQ== "@types/node-fetch@^2.5.12": version "2.5.12" @@ -1722,16 +1727,21 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.5.tgz#b59daf6a7ffa461b5648456ca59050ba8e40ed54" integrity sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA== -"@types/node@12.20", "@types/node@^12.0.12": - version "12.20.21" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.21.tgz#575e91f59c2e79318c2d39a48286c6954e484fd5" - integrity sha512-Qk7rOvV2A4vNgXNS88vEvbJE1NDFPCQ8AU+pNElrU2bA4yrRDef3fg3SUe+xkwyin3Bpg/Xh5JkNWTlsOcS2tA== +"@types/node@14.17.14": + version "14.17.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.14.tgz#6fda9785b41570eb628bac27be4b602769a3f938" + integrity sha512-rsAj2u8Xkqfc332iXV12SqIsjVi07H479bOP4q94NAcjzmAvapumEhuVIt53koEf7JFrpjgNKjBga5Pnn/GL8A== "@types/node@^10.12.0": version "10.17.24" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.24.tgz#c57511e3a19c4b5e9692bb2995c40a3a52167944" integrity sha512-5SCfvCxV74kzR3uWgTYiGxrd69TbT1I6+cMx1A5kEly/IVveJBimtAMlXiEyVFn5DvUFewQWxOOiJhlxeQwxgA== +"@types/node@^12.0.12": + version "12.20.21" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.21.tgz#575e91f59c2e79318c2d39a48286c6954e484fd5" + integrity sha512-Qk7rOvV2A4vNgXNS88vEvbJE1NDFPCQ8AU+pNElrU2bA4yrRDef3fg3SUe+xkwyin3Bpg/Xh5JkNWTlsOcS2tA== + "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" @@ -1885,10 +1895,10 @@ dependencies: "@types/react" "*" -"@types/react-window@^1.8.2": - version "1.8.2" - resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.2.tgz#a5a6b2762ce73ffaab7911ee1397cf645f2459fe" - integrity sha512-gP1xam68Wc4ZTAee++zx6pTdDAH08rAkQrWm4B4F/y6hhmlT9Mgx2q8lTCXnrPHXsr15XjRN9+K2DLKcz44qEQ== +"@types/react-window@^1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.5.tgz#285fcc5cea703eef78d90f499e1457e9b5c02fc1" + integrity sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw== dependencies: "@types/react" "*" @@ -2429,10 +2439,10 @@ JSONStream@^1.3.4, JSONStream@^1.3.5: jsonparse "^1.2.0" through ">=2.2.7 <3" -abab@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" - integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== +abab@^2.0.3, abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== abbrev@1, abbrev@~1.1.1: version "1.1.1" @@ -2496,6 +2506,11 @@ acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.2.4: + version "8.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" + integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== + agent-base@4, agent-base@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" @@ -4569,7 +4584,7 @@ cssom@~0.3.6: resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== -cssstyle@^2.2.0: +cssstyle@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== @@ -4671,10 +4686,10 @@ decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= -decimal.js@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.0.tgz#39466113a9e036111d02f82489b5fd6b0b5ed231" - integrity sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw== +decimal.js@^10.2.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== decode-uri-component@^0.2.0: version "0.2.0" @@ -5530,7 +5545,7 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -escodegen@^1.14.1, escodegen@^1.8.1: +escodegen@^1.8.1: version "1.14.2" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.2.tgz#14ab71bf5026c2aa08173afba22c6f3173284a84" integrity sha512-InuOIiKk8wwuOFg6x9BQXbzjrQhtyXh46K9bqVTPzSo2FnyMBaYGBMC6PhQy7yxxil9vIedFBweQBMK74/7o8A== @@ -5542,6 +5557,18 @@ escodegen@^1.14.1, escodegen@^1.8.1: optionalDependencies: source-map "~0.6.1" +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + eslint-plugin-header@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/eslint-plugin-header/-/eslint-plugin-header-3.1.1.tgz#6ce512432d57675265fac47292b50d1eff11acd6" @@ -7189,6 +7216,15 @@ http-proxy-agent@^2.1.0: agent-base "4" debug "3.1.0" +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + http-proxy-middleware@0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" @@ -7890,10 +7926,10 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-potential-custom-element-name@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" - integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== is-redirect@^1.0.0: version "1.0.0" @@ -8585,36 +8621,37 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsdom@^16.4.0: - version "16.4.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.4.0.tgz#36005bde2d136f73eee1a830c6d45e55408edddb" - integrity sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w== +jsdom@^16.4.0, jsdom@^16.7.0: + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== dependencies: - abab "^2.0.3" - acorn "^7.1.1" + abab "^2.0.5" + acorn "^8.2.4" acorn-globals "^6.0.0" cssom "^0.4.4" - cssstyle "^2.2.0" + cssstyle "^2.3.0" data-urls "^2.0.0" - decimal.js "^10.2.0" + decimal.js "^10.2.1" domexception "^2.0.1" - escodegen "^1.14.1" + escodegen "^2.0.0" + form-data "^3.0.0" html-encoding-sniffer "^2.0.1" - is-potential-custom-element-name "^1.0.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" nwsapi "^2.2.0" - parse5 "5.1.1" - request "^2.88.2" - request-promise-native "^1.0.8" - saxes "^5.0.0" + parse5 "6.0.1" + saxes "^5.0.1" symbol-tree "^3.2.4" - tough-cookie "^3.0.1" + tough-cookie "^4.0.0" w3c-hr-time "^1.0.2" w3c-xmlserializer "^2.0.0" webidl-conversions "^6.1.0" whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - ws "^7.2.3" + whatwg-url "^8.5.0" + ws "^7.4.6" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -9261,11 +9298,6 @@ lodash.isequal@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= - lodash.toarray@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" @@ -9291,7 +9323,7 @@ lodash.without@~4.4.0: resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw= -lodash@4.x, lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@~4.17.10: +lodash@4.x, lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0, lodash@~4.17.10: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -11037,10 +11069,10 @@ parse-passwd@^1.0.0: resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= -parse5@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" - integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" @@ -11623,7 +11655,7 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= -psl@^1.1.28: +psl@^1.1.28, psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== @@ -12324,7 +12356,7 @@ request-promise-core@1.1.4: dependencies: lodash "^4.17.19" -request-promise-native@^1.0.8, request-promise-native@^1.0.9: +request-promise-native@^1.0.9: version "1.0.9" resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== @@ -12638,7 +12670,7 @@ sax@^1.2.4, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -saxes@^5.0.0: +saxes@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== @@ -12783,10 +12815,10 @@ serialize-javascript@^3.1.0: dependencies: randombytes "^2.1.0" -serializr@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/serializr/-/serializr-2.0.3.tgz#f163b2b39938e1313beaf8457133713df2a936bb" - integrity sha512-YHDTg+QE//5vESifXc7vvncxIAiUiX04FAy1RmSgACkwhvJ9DivljDEjqs5WJzg5KLokI3x3jh30KEfXq5nDJA== +serializr@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/serializr/-/serializr-2.0.5.tgz#6f1e0d0c9cb95d177e1d41726f0e5cb28292483f" + integrity sha512-tT+S+APvbkXjs+l7E6xEgLhMrfq0DmhoCucB79j9FI781deDndjTEZknzEyzMKeETGyqL0kQprvEMCiCTMUGFQ== serve-index@^1.9.1: version "1.9.1" @@ -14019,19 +14051,19 @@ tough-cookie@^2.3.3, tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" -tough-cookie@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" - integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== dependencies: - ip-regex "^2.1.0" - psl "^1.1.28" + psl "^1.1.33" punycode "^2.1.1" + universalify "^0.1.2" -tr46@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" - integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== dependencies: punycode "^2.1.1" @@ -14400,7 +14432,7 @@ unit-compare@^1.0.1: dependencies: moment "^2.14.1" -universalify@^0.1.0: +universalify@^0.1.0, universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== @@ -14911,14 +14943,14 @@ whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== -whatwg-url@^8.0.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.1.0.tgz#c628acdcf45b82274ce7281ee31dd3c839791771" - integrity sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw== +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== dependencies: - lodash.sortby "^4.7.0" - tr46 "^2.0.2" - webidl-conversions "^5.0.0" + lodash "^4.7.0" + tr46 "^2.1.0" + webidl-conversions "^6.1.0" which-boxed-primitive@^1.0.2: version "1.0.2" @@ -15111,7 +15143,7 @@ ws@^6.2.1: dependencies: async-limiter "~1.0.0" -ws@^7.2.3, ws@^7.3.1, ws@^7.4.6: +ws@^7.3.1, ws@^7.4.6: version "7.4.6" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==