Add lens:// protocol handling with a routing mechanism (#1949)

- Add lens:// protocol handling with a routing mechanism

- document the methods in an extension guide

- remove handlers when an extension is deactivated or removed

- make sure that the found extension when routing a request is currently enabled (as a backup)

- added documentation about the above behaviour to the guide

- tweaked the naming convention so that it is clearer that the router uses extension names as not IDs (which currently are folder paths)

- Convert the extension API to use an array for registering handlers

- switch design to execute both main and renderer handlers simultaneously, without any overlap checking

- change open to be a dev dep

- improve docs, export types for extensions, skip integration tests

- switch to event emitting renderer being ready

- Add logging and fix renderer:loaded send to main

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton authored and GitHub committed 2021-02-25 09:32:40 -05:00
1 parent 38c3734d5c
commit 1470103fd4
33 files changed
+1010 -40

No files matched your search

+58 -11
View File
@@ -4,7 +4,7 @@ import "../common/system-ca";
import "../common/prometheus-providers";
import * as Mobx from "mobx";
import * as LensExtensions from "../extensions/core-api";
import { app, autoUpdater, dialog, powerMonitor } from "electron";
import { app, autoUpdater, ipcMain, dialog, powerMonitor } from "electron";
import { appName } from "../common/vars";
import path from "path";
import { LensProxy } from "./lens-proxy";
@@ -25,6 +25,7 @@ import { InstalledExtension, extensionDiscovery } from "../extensions/extension-
import type { LensExtensionId } from "../extensions/lens-extension";
import { installDeveloperTools } from "./developer-tools";
import { filesystemProvisionerStore } from "./extension-filesystem";
import { LensProtocolRouterMain } from "./protocol-handler";
import { getAppVersion, getAppVersionFromProxyServer } from "../common/utils";
import { bindBroadcastHandlers } from "../common/ipc";
import { startUpdateChecking } from "./app-updater";
@@ -37,30 +38,54 @@ let windowManager: WindowManager;
app.setName(appName);
logger.info("📟 Setting as Lens as protocol client for lens://");
if (app.setAsDefaultProtocolClient("lens")) {
logger.info("📟 succeeded ✅");
} else {
logger.info("📟 failed ❗");
}
if (!process.env.CICD) {
app.setPath("userData", workingDir);
}
if (process.env.LENS_DISABLE_GPU) {
app.disableHardwareAcceleration();
}
mangleProxyEnv();
if (app.commandLine.getSwitchValue("proxy-server") !== "") {
process.env.HTTPS_PROXY = app.commandLine.getSwitchValue("proxy-server");
}
const instanceLock = app.requestSingleInstanceLock();
if (!instanceLock) {
if (!app.requestSingleInstanceLock()) {
app.exit();
} else {
const lprm = LensProtocolRouterMain.getInstance<LensProtocolRouterMain>();
for (const arg of process.argv) {
if (arg.toLowerCase().startsWith("lens://")) {
lprm.route(arg)
.catch(error => logger.error(`${LensProtocolRouterMain.LoggingPrefix}: an error occured`, { error, rawUrl: arg }));
}
}
}
app.on("second-instance", () => {
app.on("second-instance", (event, argv) => {
const lprm = LensProtocolRouterMain.getInstance<LensProtocolRouterMain>();
for (const arg of argv) {
if (arg.toLowerCase().startsWith("lens://")) {
lprm.route(arg)
.catch(error => logger.error(`${LensProtocolRouterMain.LoggingPrefix}: an error occured`, { error, rawUrl: arg }));
}
}
windowManager?.ensureMainWindow();
});
if (process.env.LENS_DISABLE_GPU) {
app.disableHardwareAcceleration();
}
app.on("ready", async () => {
logger.info(`🚀 Starting Lens from "${workingDir}"`);
logger.info("🐚 Syncing shell environment");
@@ -128,7 +153,19 @@ app.on("ready", async () => {
logger.info("🖥️ Starting WindowManager");
windowManager = WindowManager.getInstance<WindowManager>(proxyPort);
windowManager.whenLoaded.then(() => startUpdateChecking());
ipcMain.on("renderer:loaded", () => {
startUpdateChecking();
LensProtocolRouterMain
.getInstance<LensProtocolRouterMain>()
.rendererLoaded = true;
});
extensionLoader.whenLoaded.then(() => {
LensProtocolRouterMain
.getInstance<LensProtocolRouterMain>()
.extensionsLoaded = true;
});
logger.info("🧩 Initializing extensions");
@@ -174,8 +211,8 @@ let blockQuit = true;
autoUpdater.on("before-quit-for-update", () => blockQuit = false);
// Quit app on Cmd+Q (MacOS)
app.on("will-quit", (event) => {
// Quit app on Cmd+Q (MacOS)
logger.info("APP:QUIT");
appEventBus.emit({name: "app", action: "close"});
@@ -188,6 +225,16 @@ app.on("will-quit", (event) => {
}
});
app.on("open-url", (event, rawUrl) => {
// lens:// protocol handler
event.preventDefault();
LensProtocolRouterMain
.getInstance<LensProtocolRouterMain>()
.route(rawUrl)
.catch(error => logger.error(`${LensProtocolRouterMain.LoggingPrefix}: an error occured`, { error, rawUrl }));
});
// Extensions-api runtime exports
export const LensExtensionsApi = {
...LensExtensions,