Introduce clearer boundry between extensions

- Bundled extensions are always enabled, and are always compatible
- Have bundled extensions be loaded asyncronously to support
  typescript dynamic import (which is typed) as opposed to require

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton committed 2023-03-01 12:32:33 -05:00
1 parent 6df01ba468
commit e3c0bc34fd
26 files changed
+231 -278

No files matched your search

@@ -86,7 +86,7 @@ const attemptInstall = ({
}
const extensionFolder = getExtensionDestFolder(name);
const installedExtension = extensionLoader.getExtension(validatedRequest.id);
const installedExtension = extensionLoader.getExtensionById(validatedRequest.id);
if (installedExtension) {
const { version: oldVersion } = installedExtension.manifest;
@@ -73,7 +73,7 @@ const unpackExtensionInjectable = getInjectable({
await fse.move(unpackedRootFolder, extensionFolder, { overwrite: true });
// wait for the loader has actually install it
await when(() => extensionLoader.userExtensions.has(id));
await when(() => extensionLoader.userExtensions.get().has(id));
// Enable installed extensions by default.
extensionLoader.setIsEnabled(id, true);
@@ -0,0 +1,27 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import extensionLoaderInjectable from "../../../extensions/extension-loader/extension-loader.injectable";
import type { LensExtensionId } from "../../../extensions/lens-extension";
export type DisableExtension = (extId: LensExtensionId) => void;
const disableExtensionInjectable = getInjectable({
id: "disable-extension",
instantiate: (di): DisableExtension => {
const extensionLoader = di.inject(extensionLoaderInjectable);
return (extId) => {
const ext = extensionLoader.getExtensionById(extId);
if (ext && !ext.isBundled) {
ext.isEnabled = false;
}
};
},
});
export default disableExtensionInjectable;
@@ -1,18 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import extensionLoaderInjectable from "../../../../extensions/extension-loader/extension-loader.injectable";
import { disableExtension } from "./disable-extension";
const disableExtensionInjectable = getInjectable({
id: "disable-extension",
instantiate: (di) =>
disableExtension({
extensionLoader: di.inject(extensionLoaderInjectable),
}),
});
export default disableExtensionInjectable;
@@ -1,20 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionId } from "../../../../extensions/lens-extension";
import type { ExtensionLoader } from "../../../../extensions/extension-loader";
interface Dependencies {
extensionLoader: ExtensionLoader;
}
export const disableExtension =
({ extensionLoader }: Dependencies) =>
(id: LensExtensionId) => {
const extension = extensionLoader.getExtension(id);
if (extension) {
extension.isEnabled = false;
}
};
@@ -0,0 +1,27 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import extensionLoaderInjectable from "../../../extensions/extension-loader/extension-loader.injectable";
import type { LensExtensionId } from "../../../extensions/lens-extension";
export type EnableExtension = (extId: LensExtensionId) => void;
const enableExtensionInjectable = getInjectable({
id: "enable-extension",
instantiate: (di): EnableExtension => {
const extensionLoader = di.inject(extensionLoaderInjectable);
return (extId) => {
const ext = extensionLoader.getExtensionById(extId);
if (ext && !ext.isBundled) {
ext.isEnabled = true;
}
};
},
});
export default enableExtensionInjectable;
@@ -1,18 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import extensionLoaderInjectable from "../../../../extensions/extension-loader/extension-loader.injectable";
import { enableExtension } from "./enable-extension";
const enableExtensionInjectable = getInjectable({
id: "enable-extension",
instantiate: (di) =>
enableExtension({
extensionLoader: di.inject(extensionLoaderInjectable),
}),
});
export default enableExtensionInjectable;
@@ -1,20 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionId } from "../../../../extensions/lens-extension";
import type { ExtensionLoader } from "../../../../extensions/extension-loader";
interface Dependencies {
extensionLoader: ExtensionLoader;
}
export const enableExtension =
({ extensionLoader }: Dependencies) =>
(id: LensExtensionId) => {
const extension = extensionLoader.getExtension(id);
if (extension) {
extension.isEnabled = true;
}
};
@@ -24,8 +24,8 @@ import { docsUrl } from "../../../common/vars";
import { withInjectables } from "@ogre-tools/injectable-react";
import userExtensionsInjectable from "./user-extensions/user-extensions.injectable";
import enableExtensionInjectable from "./enable-extension/enable-extension.injectable";
import disableExtensionInjectable from "./disable-extension/disable-extension.injectable";
import enableExtensionInjectable from "./enable-extension.injectable";
import disableExtensionInjectable from "./disable-extension.injectable";
import type { ConfirmUninstallExtension } from "./confirm-uninstall-extension.injectable";
import confirmUninstallExtensionInjectable from "./confirm-uninstall-extension.injectable";
import type { InstallExtensionFromInput } from "./install-extension-from-input.injectable";
@@ -13,7 +13,7 @@ import { Icon } from "../icon";
import { List } from "../list/list";
import { MenuActions, MenuItem } from "../menu";
import { Spinner } from "../spinner";
import { cssNames } from "../../utils";
import { cssNames, toJS } from "../../utils";
import { observer } from "mobx-react";
import type { Row } from "react-table";
import type { LensExtensionId } from "../../../extensions/lens-extension";
@@ -45,7 +45,14 @@ function getStatus(extension: InstalledExtension) {
return extension.isEnabled ? "Enabled" : "Disabled";
}
const NonInjectedInstalledExtensions = observer(({ extensionDiscovery, extensionInstallationStateStore, extensions, uninstall, enable, disable }: Dependencies & InstalledExtensionsProps) => {
const NonInjectedInstalledExtensions = observer(({
extensionDiscovery,
extensionInstallationStateStore,
extensions,
uninstall,
enable,
disable,
}: Dependencies & InstalledExtensionsProps) => {
const columns = useMemo(
() => [
{
@@ -138,7 +145,7 @@ const NonInjectedInstalledExtensions = observer(({ extensionDiscovery, extension
</MenuActions>
),
};
}), [extensions, extensionInstallationStateStore.anyUninstalling],
}), [toJS(extensions), extensionInstallationStateStore.anyUninstalling],
);
if (!extensionDiscovery.isLoaded) {
@@ -27,7 +27,7 @@ const uninstallExtensionInjectable = getInjectable({
const showErrorNotification = di.inject(showErrorNotificationInjectable);
return async (extensionId: LensExtensionId): Promise<boolean> => {
const ext = extensionLoader.getExtension(extensionId);
const ext = extensionLoader.getExtensionById(extensionId);
if (!ext) {
logger.debug(`[EXTENSIONS]: cannot uninstall ${extensionId}, was not installed`);
@@ -45,7 +45,7 @@ const uninstallExtensionInjectable = getInjectable({
await extensionDiscovery.uninstallExtension(extensionId);
// wait for the ExtensionLoader to actually uninstall the extension
await when(() => !extensionLoader.userExtensions.has(extensionId));
await when(() => !extensionLoader.userExtensions.get().has(extensionId));
showSuccessNotification(
<p>
@@ -12,7 +12,7 @@ const userExtensionsInjectable = getInjectable({
instantiate: (di) => {
const extensionLoader = di.inject(extensionLoaderInjectable);
return computed(() => [...extensionLoader.userExtensions.values()]);
return computed(() => [...extensionLoader.userExtensions.get().values()]);
},
});
@@ -30,7 +30,7 @@ const createExtensionInstanceInjectable = getInjectable({
};
return (ExtensionClass, extension) => {
const instance = new ExtensionClass(extension) as LensRendererExtension;
const instance = new ExtensionClass(extension as any) as LensRendererExtension;
(instance as Writable<LensRendererExtension>)[lensExtensionDependencies] = deps;