1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Merge pull request #4217 from lensapp/release/v5.2.6-beta.1

Release/v5.2.6 beta.1
This commit is contained in:
Jim Ehrismann 2021-11-02 10:40:13 -04:00 committed by GitHub
commit 96223a49fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 127 additions and 177 deletions

View File

@ -1,3 +1,3 @@
disturl "https://atom.io/download/electron"
target "13.4.0"
target "12.2.1"
runtime "electron"

View File

@ -3,7 +3,7 @@
"productName": "OpenLens",
"description": "OpenLens - Open Source IDE for Kubernetes",
"homepage": "https://github.com/lensapp/lens",
"version": "5.2.6-beta.0",
"version": "5.2.6-beta.1",
"main": "static/build/main.js",
"copyright": "© 2021 OpenLens Authors",
"license": "MIT",
@ -74,7 +74,7 @@
]
},
"build": {
"generateUpdatesFilesForAllChannels": true,
"generateUpdatesFilesForAllChannels": false,
"files": [
"static/build/main.js"
],
@ -183,8 +183,8 @@
"@hapi/call": "^8.0.1",
"@hapi/subtext": "^7.0.3",
"@kubernetes/client-node": "^0.15.1",
"@sentry/electron": "^2.5.0",
"@sentry/integrations": "^6.10.0",
"@sentry/electron": "^2.5.4",
"@sentry/integrations": "^6.13.3",
"abort-controller": "^3.0.0",
"array-move": "^3.0.1",
"auto-bind": "^4.0.0",
@ -258,8 +258,7 @@
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^4.0.0-alpha.60",
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
"@sentry/react": "^6.8.0",
"@sentry/types": "^6.8.0",
"@sentry/types": "^6.13.3",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.6",
"@types/byline": "^4.2.32",
@ -326,7 +325,7 @@
"css-loader": "^5.2.6",
"deepdash": "^5.3.5",
"dompurify": "^2.3.1",
"electron": "^13.4.0",
"electron": "^12.2.1",
"electron-builder": "^22.10.5",
"electron-notarize": "^0.3.0",
"esbuild": "^0.12.24",

View File

@ -109,6 +109,10 @@ export class WindowManager extends Singleton {
app.dock?.hide(); // hide icon in dock (mac-os)
})
.webContents
.on("new-window", (event, url) => {
event.preventDefault();
shell.openExternal(url);
})
.on("dom-ready", () => {
appEventBus.emit({ name: "app", action: "dom-ready" });
})
@ -146,10 +150,6 @@ export class WindowManager extends Singleton {
// Always disable Node.js integration for all webviews
webPreferences.nodeIntegration = false;
}).setWindowOpenHandler((details) => {
shell.openExternal(details.url);
return { action: "deny" };
});
}

View File

@ -29,7 +29,7 @@ import * as ReactRouterDom from "react-router-dom";
import * as LensExtensionsCommonApi from "../extensions/common-api";
import * as LensExtensionsRendererApi from "../extensions/renderer-api";
import { monaco } from "react-monaco-editor";
import { render, unmountComponentAtNode } from "react-dom";
import { render } from "react-dom";
import { delay } from "../common/utils";
import { isMac, isDevelopment } from "../common/vars";
import { ClusterStore } from "../common/cluster-store";
@ -52,6 +52,10 @@ import { SentryInit } from "../common/sentry";
import { TerminalStore } from "./components/dock/terminal.store";
import cloudsMidnight from "./monaco-themes/Clouds Midnight.json";
if (process.isMainFrame) {
SentryInit();
}
configurePackages();
/**
@ -66,12 +70,14 @@ async function attachChromeDebugger() {
}
type AppComponent = React.ComponentType & {
init?(): Promise<void>;
init?(rootElem: HTMLElement): Promise<void>;
};
export async function bootstrap(App: AppComponent) {
const rootElem = document.getElementById("app");
UserStore.createInstance();
await attachChromeDebugger();
rootElem.classList.toggle("is-mac", isMac);
@ -90,10 +96,6 @@ export async function bootstrap(App: AppComponent) {
ExtensionLoader.createInstance().init();
ExtensionDiscovery.createInstance().init();
UserStore.createInstance();
SentryInit();
// ClusterStore depends on: UserStore
const cs = ClusterStore.createInstance();
@ -125,16 +127,8 @@ export async function bootstrap(App: AppComponent) {
// init app's dependencies if any
if (App.init) {
await App.init();
await App.init(rootElem);
}
window.addEventListener("message", (ev: MessageEvent) => {
if (ev.data === "teardown") {
UserStore.getInstance(false)?.unregisterIpcListener();
ClusterStore.getInstance(false)?.unregisterIpcListener();
unmountComponentAtNode(rootElem);
window.location.href = "about:blank";
}
});
render(<>
{isMac && <div id="draggable-top" />}
{DefaultProps(App)}

View File

@ -22,7 +22,7 @@
import "./cluster-issues.scss";
import React from "react";
import { disposeOnUnmount, observer } from "mobx-react";
import { observer } from "mobx-react";
import { computed, makeObservable } from "mobx";
import { Icon } from "../icon";
import { SubHeader } from "../layout/sub-header";
@ -34,7 +34,6 @@ import type { ItemObject } from "../../../common/item.store";
import { Spinner } from "../spinner";
import { ThemeStore } from "../../theme.store";
import { kubeSelectedUrlParam, toggleDetails } from "../kube-detail-params";
import { kubeWatchApi } from "../../../common/k8s-api/kube-watch-api";
import { apiManager } from "../../../common/k8s-api/api-manager";
interface Props {
@ -66,10 +65,6 @@ export class ClusterIssues extends React.Component<Props> {
constructor(props: Props) {
super(props);
makeObservable(this);
disposeOnUnmount(this, [
kubeWatchApi.subscribeStores([eventStore, nodesStore])
]);
}
@computed get warnings() {

View File

@ -36,6 +36,8 @@ import { ClusterPieCharts } from "./cluster-pie-charts";
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
import { ClusterStore } from "../../../common/cluster-store";
import { kubeWatchApi } from "../../../common/k8s-api/kube-watch-api";
import { eventStore } from "../+events/event.store";
@observer
export class ClusterOverview extends React.Component {
@ -53,6 +55,9 @@ export class ClusterOverview extends React.Component {
this.metricPoller.start(true);
disposeOnUnmount(this, [
kubeWatchApi.subscribeStores([podsStore, eventStore, nodesStore], {
preload: true,
}),
reaction(
() => clusterOverviewStore.metricNodeRole, // Toggle Master/Worker node switcher
() => this.metricPoller.restart(true)
@ -91,7 +96,7 @@ export class ClusterOverview extends React.Component {
}
render() {
const isLoaded = nodesStore.isLoaded && podsStore.isLoaded;
const isLoaded = nodesStore.isLoaded && eventStore.isLoaded;
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.Cluster);
return (

View File

@ -42,9 +42,6 @@ import whatInput from "what-input";
import { clusterSetFrameIdHandler } from "../../common/cluster-ipc";
import { ClusterPageMenuRegistration, ClusterPageMenuRegistry } from "../../extensions/registries";
import { StatefulSetScaleDialog } from "./+workloads-statefulsets/statefulset-scale-dialog";
import { eventStore } from "./+events/event.store";
import { nodesStore } from "./+nodes/nodes.store";
import { podsStore } from "./+workloads-pods/pods.store";
import { kubeWatchApi } from "../../common/k8s-api/kube-watch-api";
import { ReplicaSetScaleDialog } from "./+workloads-replicasets/replicaset-scale-dialog";
import { CommandContainer } from "./command-palette/command-container";
@ -73,6 +70,7 @@ import { getHostedClusterId } from "../utils";
import { ClusterStore } from "../../common/cluster-store";
import type { ClusterId } from "../../common/cluster-types";
import { watchHistoryState } from "../remote-helpers/history-updater";
import { unmountComponentAtNode } from "react-dom";
@observer
export class App extends React.Component {
@ -83,7 +81,7 @@ export class App extends React.Component {
makeObservable(this);
}
static async init() {
static async init(rootElem: HTMLElement) {
catalogEntityRegistry.init();
const frameId = webFrame.routingId;
@ -112,6 +110,13 @@ export class App extends React.Component {
window.addEventListener("online", () => {
window.location.reload();
});
window.onbeforeunload = () => {
logger.info(`[APP]: Unload dashboard, clusterId=${App.clusterId}, frameId=${frameId}`);
unmountComponentAtNode(rootElem);
};
whatInput.ask(); // Start to monitor user input device
// Setup hosted cluster context
@ -121,7 +126,7 @@ export class App extends React.Component {
componentDidMount() {
disposeOnUnmount(this, [
kubeWatchApi.subscribeStores([podsStore, nodesStore, eventStore, namespaceStore], {
kubeWatchApi.subscribeStores([namespaceStore], {
preload: true,
}),

View File

@ -79,13 +79,7 @@ export async function autoCleanOnRemove(clusterId: ClusterId, iframe: HTMLIFrame
logger.info(`[LENS-VIEW]: remove dashboard, clusterId=${clusterId}`);
lensViews.delete(clusterId);
// Keep frame in DOM to avoid possible bugs when same cluster re-created after being removed.
// In that case for some reasons `webFrame.routingId` returns some previous frameId (usage in app.tsx)
// Issue: https://github.com/lensapp/lens/issues/811
iframe.style.display = "none";
iframe.dataset.meta = `${iframe.name} was removed at ${new Date().toLocaleString()}`;
iframe.removeAttribute("name");
iframe.contentWindow.postMessage("teardown", "*");
iframe.parentNode.removeChild(iframe);
}
export function refreshViews(visibleClusterId?: string) {

View File

@ -21,54 +21,68 @@
import "./error-boundary.scss";
import React from "react";
import React, { ErrorInfo } from "react";
import { observer } from "mobx-react";
import { Button } from "../button";
import { navigation } from "../../navigation";
import { issuesTrackerUrl, slackUrl } from "../../../common/vars";
import * as Sentry from "@sentry/react";
import { observer } from "mobx-react";
interface Props {
}
interface State {
error?: Error;
errorInfo?: ErrorInfo;
}
@observer
export class ErrorBoundary extends React.Component {
render() {
return (
<Sentry.ErrorBoundary
fallback={({ error, componentStack, resetError }) => {
const slackLink = <a href={slackUrl} rel="noreferrer" target="_blank">Slack</a>;
const githubLink = <a href={issuesTrackerUrl} rel="noreferrer" target="_blank">GitHub</a>;
const pageUrl = location.pathname;
export class ErrorBoundary extends React.Component<Props, State> {
public state: State = {};
return (
<div className="flex ErrorBoundary column gaps">
<h5>
App crash at <span className="contrast">{pageUrl}</span>
</h5>
<p>
To help us improve the product please report bugs to {slackLink} community or {githubLink} issues tracker.
</p>
<div className="wrapper">
<code className="block">
<p className="contrast">Component stack:</p>
{componentStack}
</code>
<code className="box grow">
<p className="contrast">Error stack:</p> <br/>
{error.stack}
</code>
</div>
<Button
className="box self-flex-start"
primary label="Back"
onClick={() => {
resetError();
navigation.goBack();
}}
/>
</div>
);
}}>
{this.props.children}
</Sentry.ErrorBoundary>
);
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
this.setState({ error, errorInfo });
}
back = () => {
this.setState({ error: null, errorInfo: null });
navigation.goBack();
};
render() {
const { error, errorInfo } = this.state;
if (error) {
const slackLink = <a href={slackUrl} rel="noreferrer" target="_blank">Slack</a>;
const githubLink = <a href={issuesTrackerUrl} rel="noreferrer" target="_blank">Github</a>;
const pageUrl = location.pathname;
return (
<div className="ErrorBoundary flex column gaps">
<h5>
App crash at <span className="contrast">{pageUrl}</span>
</h5>
<p>
To help us improve the product please report bugs to {slackLink} community or {githubLink} issues tracker.
</p>
<div className="wrapper">
<code className="block">
<p className="contrast">Component stack:</p>
{errorInfo.componentStack}
</code>
<code className="block">
<p className="contrast">Error stack:</p>
{error.stack}
</code>
</div>
<Button
className="box self-flex-start"
primary label="Back"
onClick={this.back}
/>
</div>
);
}
return this.props.children;
}
}

View File

@ -37,10 +37,12 @@ import { ipcRenderer } from "electron";
import { IpcRendererNavigationEvents } from "./navigation/events";
import { catalogEntityRegistry } from "./api/catalog-entity-registry";
import { registerKeyboardShortcuts } from "./keyboard-shortcuts";
import logger from "../common/logger";
import { unmountComponentAtNode } from "react-dom";
@observer
export class LensApp extends React.Component {
static async init() {
static async init(rootElem: HTMLElement) {
catalogEntityRegistry.init();
ExtensionLoader.getInstance().loadOnClusterManagerRenderer();
LensProtocolRouterRenderer.createInstance().init();
@ -51,6 +53,12 @@ export class LensApp extends React.Component {
registerKeyboardShortcuts();
registerIpcListeners();
window.onbeforeunload = () => {
logger.info("[App]: Unload app");
unmountComponentAtNode(rootElem);
};
}
componentDidMount() {

110
yarn.lock
View File

@ -967,16 +967,6 @@
"@sentry/utils" "6.7.1"
tslib "^1.9.3"
"@sentry/browser@6.8.0":
version "6.8.0"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.8.0.tgz#023707cd2302f6818014e9a7e124856b2d064178"
integrity sha512-nxa71csHlG5sMHUxI4e4xxuCWtbCv/QbBfMsYw7ncJSfCKG3yNlCVh8NJ7NS0rZW/MJUT6S6+r93zw0HetNDOA==
dependencies:
"@sentry/core" "6.8.0"
"@sentry/types" "6.8.0"
"@sentry/utils" "6.8.0"
tslib "^1.9.3"
"@sentry/core@6.7.1":
version "6.7.1"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.7.1.tgz#c3aaa6415d06bec65ac446b13b84f073805633e3"
@ -988,21 +978,10 @@
"@sentry/utils" "6.7.1"
tslib "^1.9.3"
"@sentry/core@6.8.0":
version "6.8.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.8.0.tgz#bfac76844deee9126460c18dc6166015992efdc3"
integrity sha512-vJzWt/znEB+JqVwtwfjkRrAYRN+ep+l070Ti8GhJnvwU4IDtVlV3T/jVNrj6rl6UChcczaJQMxVxtG5x0crlAA==
dependencies:
"@sentry/hub" "6.8.0"
"@sentry/minimal" "6.8.0"
"@sentry/types" "6.8.0"
"@sentry/utils" "6.8.0"
tslib "^1.9.3"
"@sentry/electron@^2.5.0":
version "2.5.0"
resolved "https://registry.yarnpkg.com/@sentry/electron/-/electron-2.5.0.tgz#4168ff04ee01cb5a99ce042f3435660a510c634d"
integrity sha512-OiJWi9BKtlj4UeoaCArVXIvfW808fgW1GLmeiC7wD7B64ALHSYSwu8tkqZK+IMVhPmQN04AUyoYXrZohfJ7sOg==
"@sentry/electron@^2.5.4":
version "2.5.4"
resolved "https://registry.yarnpkg.com/@sentry/electron/-/electron-2.5.4.tgz#337b2f7e228e805a3e4eb3611c7b12c6cf87c618"
integrity sha512-tCCK+P581TmdjsDpHBQz7qYcldzGdUk1Fd6FPxPy1JKGzeY4uf/uSLKzR80Lzs5kTpEZFOwiMHSA8yjwFp5qoA==
dependencies:
"@sentry/browser" "6.7.1"
"@sentry/core" "6.7.1"
@ -1021,22 +1000,13 @@
"@sentry/utils" "6.7.1"
tslib "^1.9.3"
"@sentry/hub@6.8.0":
version "6.8.0"
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.8.0.tgz#cb0f8509093919ed3c1ef98ef8cf63dc102a6524"
integrity sha512-hFrI2Ss1fTov7CH64FJpigqRxH7YvSnGeqxT9Jc1BL7nzW/vgCK+Oh2mOZbosTcrzoDv+lE8ViOnSN3w/fo+rg==
"@sentry/integrations@^6.13.3":
version "6.13.3"
resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-6.13.3.tgz#9d80229de6e815c53fa52ca2422a0d13820b8d4e"
integrity sha512-iC8LkbBTxlRo9FNxRqFfEm85FrELltc3E9gFsFSBkCnf7S/3nDCDW+mJX92KpRk97Wqid6/JwlXttKz8lsdF2A==
dependencies:
"@sentry/types" "6.8.0"
"@sentry/utils" "6.8.0"
tslib "^1.9.3"
"@sentry/integrations@^6.10.0":
version "6.10.0"
resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-6.10.0.tgz#f8f9e7efd55ec44d0408bd4493df1c9ceabaaa63"
integrity sha512-NMtB0jjFYFZRxyjYu2dWLThk9YPIwqhi4hYywmWkbv4/ILzi5Rwnh+aqNW6yrj8qG4b9itNMh3YvEzmf0aqauw==
dependencies:
"@sentry/types" "6.10.0"
"@sentry/utils" "6.10.0"
"@sentry/types" "6.13.3"
"@sentry/utils" "6.13.3"
localforage "^1.8.1"
tslib "^1.9.3"
@ -1049,15 +1019,6 @@
"@sentry/types" "6.7.1"
tslib "^1.9.3"
"@sentry/minimal@6.8.0":
version "6.8.0"
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.8.0.tgz#d6c3e4c96f231367aeb2b8a87a83b53d28e7c6db"
integrity sha512-MRxUKXiiYwKjp8mOQMpTpEuIby1Jh3zRTU0cmGZtfsZ38BC1JOle8xlwC4FdtOH+VvjSYnPBMya5lgNHNPUJDQ==
dependencies:
"@sentry/hub" "6.8.0"
"@sentry/types" "6.8.0"
tslib "^1.9.3"
"@sentry/node@6.7.1":
version "6.7.1"
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-6.7.1.tgz#b09e2eca8e187168feba7bd865a23935bf0f5cc0"
@ -1073,18 +1034,6 @@
lru_map "^0.3.3"
tslib "^1.9.3"
"@sentry/react@^6.8.0":
version "6.8.0"
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-6.8.0.tgz#3cf4a2e1ef042ee227836e268e702e9cb3b67e41"
integrity sha512-yXNnDaVw8kIacbwQjA27w8DA74WxmDVw4RlUTJGtq35SDmWsaGN1mwvU+mE1u3zEg927QTCBYig2Zqk8Tdt/fQ==
dependencies:
"@sentry/browser" "6.8.0"
"@sentry/minimal" "6.8.0"
"@sentry/types" "6.8.0"
"@sentry/utils" "6.8.0"
hoist-non-react-statics "^3.3.2"
tslib "^1.9.3"
"@sentry/tracing@6.7.1":
version "6.7.1"
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.7.1.tgz#b11f0c17a6c5dc14ef44733e5436afb686683268"
@ -1096,27 +1045,22 @@
"@sentry/utils" "6.7.1"
tslib "^1.9.3"
"@sentry/types@6.10.0", "@sentry/types@^6.8.0":
version "6.10.0"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.10.0.tgz#6b1f44e5ed4dbc2710bead24d1b32fb08daf04e1"
integrity sha512-M7s0JFgG7/6/yNVYoPUbxzaXDhnzyIQYRRJJKRaTD77YO4MHvi4Ke8alBWqD5fer0cPIfcSkBqa9BLdqRqcMWw==
"@sentry/types@6.13.3", "@sentry/types@^6.13.3":
version "6.13.3"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.13.3.tgz#63ad5b6735b0dfd90b3a256a9f8e77b93f0f66b2"
integrity sha512-Vrz5CdhaTRSvCQjSyIFIaV9PodjAVFkzJkTRxyY7P77RcegMsRSsG1yzlvCtA99zG9+e6MfoJOgbOCwuZids5A==
"@sentry/types@6.7.1":
version "6.7.1"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.7.1.tgz#c8263e1886df5e815570c4668eb40a1cfaa1c88b"
integrity sha512-9AO7HKoip2MBMNQJEd6+AKtjj2+q9Ze4ooWUdEvdOVSt5drg7BGpK221/p9JEOyJAZwEPEXdcMd3VAIMiOb4MA==
"@sentry/types@6.8.0":
version "6.8.0"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.8.0.tgz#97fd531a0ed1e75e65b4a24b26509fb7c15eb7b8"
integrity sha512-PbSxqlh6Fd5thNU5f8EVYBVvX+G7XdPA+ThNb2QvSK8yv3rIf0McHTyF6sIebgJ38OYN7ZFK7vvhC/RgSAfYTA==
"@sentry/utils@6.10.0":
version "6.10.0"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.10.0.tgz#839a099fa0a1f0ca0893c7ce8c55ba0608c1d80f"
integrity sha512-F9OczOcZMFtazYVZ6LfRIe65/eOfQbiAedIKS0li4npuMz0jKYRbxrjd/U7oLiNQkPAp4/BujU4m1ZIwq6a+tg==
"@sentry/utils@6.13.3":
version "6.13.3"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.13.3.tgz#188754d40afe693c3fcae410f9322531588a9926"
integrity sha512-zYFuFH3MaYtBZTeJ4Yajg7pDf0pM3MWs3+9k5my9Fd+eqNcl7dYQYJbT9gyC0HXK1QI4CAMNNlHNl4YXhF91ag==
dependencies:
"@sentry/types" "6.10.0"
"@sentry/types" "6.13.3"
tslib "^1.9.3"
"@sentry/utils@6.7.1":
@ -1127,14 +1071,6 @@
"@sentry/types" "6.7.1"
tslib "^1.9.3"
"@sentry/utils@6.8.0":
version "6.8.0"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.8.0.tgz#0ffafa5b69fe0cdeabad5c4a6cc68a426eaa6b37"
integrity sha512-OYlI2JNrcWKMdvYbWNdQwR4QBVv2V0y5wK0U6f53nArv6RsyO5TzwRu5rMVSIZofUUqjoE5hl27jqnR+vpUrsA==
dependencies:
"@sentry/types" "6.8.0"
tslib "^1.9.3"
"@sideway/address@^4.1.0":
version "4.1.0"
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.0.tgz#0b301ada10ac4e0e3fa525c90615e0b61a72b78d"
@ -5269,10 +5205,10 @@ electron@*:
"@types/node" "^12.0.12"
extract-zip "^1.0.3"
electron@^13.4.0:
version "13.4.0"
resolved "https://registry.yarnpkg.com/electron/-/electron-13.4.0.tgz#f9f9e518d8c6bf23bfa8b69580447eea3ca0f880"
integrity sha512-KJGWS2qa0xZXIMPMDUNkRVO8/JxRd4+M0ejYYOzu2LIQ5ijecPzNuNR9nvDkml9XyyRBzu975FkhJcwD17ietQ==
electron@^12.2.1:
version "12.2.1"
resolved "https://registry.yarnpkg.com/electron/-/electron-12.2.1.tgz#ef138fde11efd01743934c3e0df717cc53ee362b"
integrity sha512-Gp+rO81qoaRDP7PTVtBOvnSgDgGlwUuAEWXxi621uOJMIlYFas9ChXe8pjdL0R0vyUpiHVzp6Vrjx41VZqEpsw==
dependencies:
"@electron/get" "^1.0.1"
"@types/node" "^14.6.2"