Upgrade to electron@^19 (#5369)

* Upgrade to use electron 19.0.4

- Update documentation

- Updated disturl in .yarnrc to fix build issue

- Remove use of abort-controller package

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Remove support for webview tags

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton authored and GitHub committed 2022-08-12 05:17:06 -07:00
1 parent edacf3bec6
commit 6d37019089
18 files changed
+84 -134

No files matched your search

@@ -6,7 +6,6 @@
import { forRemoteCluster, KubeApi } from "../kube-api";
import { KubeJsonApi } from "../kube-json-api";
import { KubeObject } from "../kube-object";
import AbortController from "abort-controller";
import { delay } from "../../utils/delay";
import { PassThrough } from "stream";
import { ApiManager } from "../api-manager";
+4 -2
View File
@@ -19,7 +19,6 @@ import { KubeJsonApi } from "./kube-json-api";
import type { Disposer } from "../utils";
import { isDefined, noop, WrappedAbortController } from "../utils";
import type { RequestInit } from "node-fetch";
import type AbortController from "abort-controller";
import type { AgentOptions } from "https";
import { Agent } from "https";
import type { Patch } from "rfc6902";
@@ -29,6 +28,9 @@ import logger from "../logger";
import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import autoRegistrationEmitterInjectable from "./api-manager/auto-registration-emitter.injectable";
// TODO: upgrade node-fetch once we are starting to use ES modules
type LegacyAbortSignal = NonNullable<RequestInit["signal"]>;
/**
* The options used for creating a `KubeApi`
*/
@@ -717,7 +719,7 @@ export class KubeApi<
const requestParams = timeout ? { query: { timeoutSeconds: timeout }} : {};
const watchUrl = this.getWatchUrl(namespace);
const responsePromise = this.request.getResponse(watchUrl, requestParams, {
signal: abortController.signal,
signal: abortController.signal as LegacyAbortSignal,
timeout: 600_000,
});
+5 -2
View File
@@ -15,13 +15,15 @@ import { ItemStore } from "../item.store";
import type { KubeApiQueryParams, KubeApi, KubeApiWatchCallback } from "./kube-api";
import { parseKubeApi } from "./kube-api-parse";
import type { RequestInit } from "node-fetch";
import AbortController from "abort-controller";
import type { Patch } from "rfc6902";
import logger from "../logger";
import assert from "assert";
import type { PartialDeep } from "type-fest";
import { entries } from "../utils/objects";
// TODO: upgrade node-fetch once we are starting to use ES modules
type LegacyAbortSignal = NonNullable<RequestInit["signal"]>;
export type OnLoadFailure = (error: unknown) => void;
export interface KubeObjectStoreLoadingParams {
@@ -477,7 +479,8 @@ export abstract class KubeObjectStore<
callback,
});
const { signal } = abortController;
// TODO: upgrade node-fetch once we are starting to use ES modules
const signal = abortController.signal as LegacyAbortSignal;
const callback: KubeApiWatchCallback<D> = (data, error) => {
if (!this.isLoaded || error?.type === "aborted") return;
+5 -2
View File
@@ -2,10 +2,13 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import AbortController from "abort-controller";
/**
* This is like an `AbortController` but will also abort if the parent aborts,
* but won't make the parent abort if this aborts (single direction)
*/
export class WrappedAbortController extends AbortController {
constructor(parent?: AbortController) {
constructor(parent?: AbortController | undefined) {
super();
parent?.signal.addEventListener("abort", () => {
-2
View File
@@ -3,8 +3,6 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { AbortController } from "abort-controller";
/**
* Return a promise that will be resolved after at least `timeout` ms have
* passed. If `failFast` is provided then the promise is also resolved if it has
-2
View File
@@ -3,8 +3,6 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { AbortSignal } from "abort-controller";
/**
* Creates a new promise that will be rejected when the signal rejects.
*
@@ -11,9 +11,8 @@ import { watch } from "chokidar";
import type { Stats } from "fs";
import fs from "fs";
import path from "path";
import type stream from "stream";
import type { Disposer } from "../../../common/utils";
import { bytesToUnits, getOrInsertWith, iter, noop } from "../../../common/utils";
import { disposer, bytesToUnits, getOrInsertWith, iter, noop } from "../../../common/utils";
import logger from "../../logger";
import type { KubeConfig } from "@kubernetes/client-node";
import { loadConfigFromString, splitConfig } from "../../../common/kube-helpers";
@@ -265,47 +264,35 @@ const diffChangedConfigFor = (dependencies: ComputeDiffDependencies) => ({ fileP
return noop;
}
// TODO: replace with an AbortController with fs.readFile when we upgrade to Node 16 (after it comes out)
const fileReader = fs.createReadStream(filePath, {
mode: fs.constants.O_RDONLY,
const controller = new AbortController();
const fileContentsP = fs.promises.readFile(filePath, {
signal: controller.signal,
});
const readStream: stream.Readable = fileReader;
const decoder = new TextDecoder("utf-8", { fatal: true });
let fileString = "";
let closed = false;
const cleanup = disposer(
() => controller.abort(),
);
const cleanup = () => {
closed = true;
fileReader.close(); // This may not close the stream.
// Artificially marking end-of-stream, as if the underlying resource had
// indicated end-of-file by itself, allows the stream to close.
// This does not cancel pending read operations, and if there is such an
// operation, the process may still not be able to exit successfully
// until it finishes.
fileReader.push(null);
fileReader.read(0);
readStream.removeAllListeners();
};
fileContentsP
.then((fileData) => {
const decoder = new TextDecoder("utf-8", { fatal: true });
readStream
.on("data", (chunk: Buffer) => {
try {
fileString += decoder.decode(chunk, { stream: true });
const fileString = decoder.decode(fileData);
computeDiff(dependencies)(fileString, source, filePath);
} catch (error) {
logger.warn(`${logPrefix} skipping ${filePath}: ${error}`);
source.clear();
cleanup();
}
})
.on("close", () => cleanup())
.on("error", error => {
cleanup();
logger.warn(`${logPrefix} failed to read file: ${error}`, { filePath });
})
.on("end", () => {
if (!closed) {
computeDiff(dependencies)(fileString, source, filePath);
.catch(error => {
if (controller.signal.aborted) {
return;
}
logger.warn(`${logPrefix} failed to read file: ${error}`, { filePath });
cleanup();
});
return cleanup;
@@ -77,9 +77,7 @@ const createElectronWindowInjectable = getInjectable({
webPreferences: {
nodeIntegration: true,
nodeIntegrationInSubFrames: true,
webviewTag: true,
contextIsolation: false,
nativeWindowOpen: false,
},
});
@@ -89,20 +87,16 @@ const createElectronWindowInjectable = getInjectable({
.on("focus", () => {
configuration.onFocus?.();
})
.on("blur", () => {
configuration.onBlur?.();
})
.on("closed", () => {
configuration.onClose();
applicationWindowState.unmanage();
})
.webContents.on("dom-ready", () => {
configuration.onDomReady?.();
})
.on("did-fail-load", (_event, code, desc) => {
logger.error(
`[CREATE-ELECTRON-WINDOW]: Failed to load window "${configuration.id}"`,
@@ -112,52 +106,11 @@ const createElectronWindowInjectable = getInjectable({
},
);
})
.on("did-finish-load", () => {
logger.info(
`[CREATE-ELECTRON-WINDOW]: Window "${configuration.id}" loaded`,
);
})
.on("will-attach-webview", (event, webPreferences, params) => {
logger.debug(
`[CREATE-ELECTRON-WINDOW]: Attaching webview to window "${configuration.id}"`,
);
// Following is security recommendations because we allow webview tag (webviewTag: true)
// suggested by https://www.electronjs.org/docs/tutorial/security#11-verify-webview-options-before-creation
// and https://www.electronjs.org/docs/tutorial/security#10-do-not-use-allowpopups
if (webPreferences.preload) {
logger.warn(
"[CREATE-ELECTRON-WINDOW]: Strip away preload scripts of webview",
);
delete webPreferences.preload;
}
// @ts-expect-error some electron version uses webPreferences.preloadURL/webPreferences.preload
if (webPreferences.preloadURL) {
logger.warn(
"[CREATE-ELECTRON-WINDOW]: Strip away preload scripts of webview",
);
delete webPreferences.preload;
}
if (params.allowpopups) {
logger.warn(
"[CREATE-ELECTRON-WINDOW]: We do not allow allowpopups props, stop webview from renderer",
);
// event.preventDefault() will destroy the guest page.
event.preventDefault();
return;
}
// Always disable Node.js integration for all webviews
webPreferences.nodeIntegration = false;
webPreferences.nativeWindowOpen = false;
})
.setWindowOpenHandler((details) => {
openLinkInBrowser(details.url).catch((error) => {
logger.error("[CREATE-ELECTRON-WINDOW]: failed to open browser", {
@@ -5,11 +5,14 @@
import { comparer, reaction } from "mobx";
import type { Disposer } from "../../common/utils";
import { disposer, getOrInsert, noop, WrappedAbortController } from "../../common/utils";
import AbortController from "abort-controller";
import { once } from "lodash";
import type { ClusterFrameContext } from "../cluster-frame-context/cluster-frame-context";
import logger from "../../common/logger";
import type { KubeObjectStoreLoadAllParams, KubeObjectStoreSubscribeParams } from "../../common/k8s-api/kube-object.store";
import type { RequestInit } from "node-fetch";
// TODO: upgrade node-fetch once we are starting to use ES modules
type LegacyAbortSignal = NonNullable<RequestInit["signal"]>;
// Kubernetes watch-api client
// API: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams
@@ -103,7 +106,7 @@ export class KubeWatchApi {
const loadThenSubscribe = async (namespaces: string[] | undefined) => {
try {
await store.loadAll({ namespaces, reqInit: { signal: childController.signal }, onLoadFailure });
await store.loadAll({ namespaces, reqInit: { signal: childController.signal as LegacyAbortSignal }, onLoadFailure });
unsubscribe.push(store.subscribe({ onLoadFailure, abortController: childController }));
} catch (error) {
if (!(error instanceof DOMException)) {