mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
chore: Simplify extension dependency injection
- Has better typing
- Removes use of unnusual unique symbol
- Fix welcome banner tests
- Update associated snapshots
- Start converting custom column tests to use ApplicationBuilder
- Remove old and unnused RecursiveTreeView
- Introduce new TreeView for use in CatalogMenu to fix tests
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
1 parent
5db8fc1342
commit
82bf67cc9e
70 files changed
+7110
-2945
No files matched your search
@@ -3,17 +3,23 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { LensExtension } from "../lens-extension";
|
||||
import { Console } from "console";
|
||||
import { stdout, stderr } from "process";
|
||||
|
||||
console = new Console(stdout, stderr);
|
||||
|
||||
let ext: LensExtension;
|
||||
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||
import { LensMainExtension } from "../lens-main-extension";
|
||||
|
||||
describe("lens extension", () => {
|
||||
let ext: LensMainExtension;
|
||||
|
||||
beforeEach(async () => {
|
||||
ext = new LensExtension({
|
||||
const builder = getApplicationBuilder();
|
||||
|
||||
/**
|
||||
* This is required because it sets up `AppPaths` which are required by LensMainExtension.
|
||||
*
|
||||
* That type isn't used internally so it needs to use "legacy global DI" to get its dependencies.
|
||||
*/
|
||||
await builder.render();
|
||||
|
||||
ext = new LensMainExtension({
|
||||
manifest: {
|
||||
name: "foo-bar",
|
||||
version: "0.1.1",
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { LensExtensionConstructor, BundledInstalledExtension, ExternalInstalledExtension, BundledLensExtensionConstructor } from "@k8slens/legacy-extensions";
|
||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||
import type { LensExtension } from "../lens-extension";
|
||||
|
||||
export interface CreateExtensionInstance {
|
||||
(ExtensionClass: LensExtensionConstructor, extension: ExternalInstalledExtension): LensExtension;
|
||||
(ExtensionClass: BundledLensExtensionConstructor, extension: BundledInstalledExtension): LensExtension;
|
||||
}
|
||||
|
||||
export const createExtensionInstanceInjectionToken = getInjectionToken<CreateExtensionInstance>({
|
||||
id: "create-extension-instance-token",
|
||||
});
|
||||
@@ -2,14 +2,13 @@
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { LensExtensionId } from "@k8slens/legacy-extensions";
|
||||
import type { LegacyLensExtension, LensExtensionId } from "@k8slens/legacy-extensions";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { observable } from "mobx";
|
||||
import type { LensExtension } from "../lens-extension";
|
||||
|
||||
const extensionInstancesInjectable = getInjectable({
|
||||
id: "extension-instances",
|
||||
instantiate: () => observable.map<LensExtensionId, LensExtension>(),
|
||||
instantiate: () => observable.map<LensExtensionId, LegacyLensExtension>(),
|
||||
});
|
||||
|
||||
export default extensionInstancesInjectable;
|
||||
@@ -4,9 +4,7 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { ExtensionLoader } from "./extension-loader";
|
||||
import { createExtensionInstanceInjectionToken } from "./create-extension-instance.token";
|
||||
import extensionInstancesInjectable from "./extension-instances.injectable";
|
||||
import type { LensExtension } from "../lens-extension";
|
||||
import extensionInjectable from "./extension/extension.injectable";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import joinPathsInjectable from "../../common/path/join-paths.injectable";
|
||||
@@ -20,9 +18,8 @@ const extensionLoaderInjectable = getInjectable({
|
||||
|
||||
instantiate: (di) => new ExtensionLoader({
|
||||
updateExtensionsState: di.inject(updateExtensionsStateInjectable),
|
||||
createExtensionInstance: di.inject(createExtensionInstanceInjectionToken),
|
||||
extensionInstances: di.inject(extensionInstancesInjectable),
|
||||
getExtension: (instance: LensExtension) => di.inject(extensionInjectable, instance),
|
||||
getExtension: (instance) => di.inject(extensionInjectable, instance),
|
||||
bundledExtensions: di.injectMany(bundledExtensionInjectionToken),
|
||||
extensionEntryPointName: di.inject(extensionEntryPointNameInjectionToken),
|
||||
logger: di.inject(loggerInjectable),
|
||||
|
||||
@@ -9,13 +9,12 @@ import type { ObservableMap } from "mobx";
|
||||
import { runInAction, action, computed, toJS, observable, reaction, when } from "mobx";
|
||||
import { broadcastMessage, ipcMainOn, ipcRendererOn, ipcMainHandle } from "../../common/ipc";
|
||||
import { isDefined, iter } from "@k8slens/utilities";
|
||||
import type { ExternalInstalledExtension, InstalledExtension, LensExtensionConstructor, LensExtensionId, BundledExtension } from "@k8slens/legacy-extensions";
|
||||
import type { ExternalInstalledExtension, InstalledExtension, LensExtensionConstructor, LensExtensionId, BundledExtension, BundledInstalledExtension, LegacyLensExtension } from "@k8slens/legacy-extensions";
|
||||
import type { LensExtension } from "../lens-extension";
|
||||
import { extensionLoaderFromMainChannel, extensionLoaderFromRendererChannel } from "../../common/ipc/extension-handling";
|
||||
import { requestExtensionLoaderInitialState } from "../../renderer/ipc";
|
||||
import assert from "assert";
|
||||
import { EventEmitter } from "../../common/event-emitter";
|
||||
import type { CreateExtensionInstance } from "./create-extension-instance.token";
|
||||
import type { Extension } from "./extension/extension.injectable";
|
||||
import type { Logger } from "../../common/logger";
|
||||
import type { JoinPaths } from "../../common/path/join-paths.injectable";
|
||||
@@ -25,13 +24,12 @@ import type { UpdateExtensionsState } from "../../features/extensions/enabled/co
|
||||
const logModule = "[EXTENSIONS-LOADER]";
|
||||
|
||||
interface Dependencies {
|
||||
readonly extensionInstances: ObservableMap<LensExtensionId, LensExtension>;
|
||||
readonly extensionInstances: ObservableMap<LensExtensionId, LegacyLensExtension>;
|
||||
readonly bundledExtensions: BundledExtension[];
|
||||
readonly logger: Logger;
|
||||
readonly extensionEntryPointName: "main" | "renderer";
|
||||
updateExtensionsState: UpdateExtensionsState;
|
||||
createExtensionInstance: CreateExtensionInstance;
|
||||
getExtension: (instance: LensExtension) => Extension;
|
||||
getExtension: (instance: LegacyLensExtension) => Extension;
|
||||
joinPaths: JoinPaths;
|
||||
getDirnameOfPath: GetDirnameOfPath;
|
||||
}
|
||||
@@ -85,7 +83,7 @@ export class ExtensionLoader {
|
||||
* - `null` if no class definition is provided for the current process
|
||||
* - `undefined` if the name is not known about
|
||||
*/
|
||||
getInstanceByName(name: string): LensExtension | null | undefined {
|
||||
getInstanceByName(name: string): LegacyLensExtension | null | undefined {
|
||||
if (this.nonInstancesByName.has(name)) {
|
||||
return null;
|
||||
}
|
||||
@@ -236,7 +234,7 @@ export class ExtensionLoader {
|
||||
return null;
|
||||
}
|
||||
|
||||
const installedExtension: InstalledExtension = {
|
||||
const installedExtension: BundledInstalledExtension = {
|
||||
absolutePath: "irrelevant",
|
||||
id: extension.manifest.name,
|
||||
isBundled: true,
|
||||
@@ -245,10 +243,7 @@ export class ExtensionLoader {
|
||||
manifest: extension.manifest,
|
||||
manifestPath: "irrelevant",
|
||||
};
|
||||
const instance = this.dependencies.createExtensionInstance(
|
||||
LensExtensionClass,
|
||||
installedExtension,
|
||||
);
|
||||
const instance = new LensExtensionClass(installedExtension);
|
||||
|
||||
this.dependencies.extensionInstances.set(extension.manifest.name, instance);
|
||||
|
||||
@@ -307,35 +302,32 @@ export class ExtensionLoader {
|
||||
|
||||
return [...installedExtensions.entries()]
|
||||
.filter((entry): entry is [string, ExternalInstalledExtension] => !entry[1].isBundled)
|
||||
.map(([extId, extension]) => {
|
||||
const alreadyInit = this.dependencies.extensionInstances.has(extId) || this.nonInstancesByName.has(extension.manifest.name);
|
||||
.map(([extId, installedExtension]) => {
|
||||
const alreadyInit = this.dependencies.extensionInstances.has(extId) || this.nonInstancesByName.has(installedExtension.manifest.name);
|
||||
|
||||
if (extension.isCompatible && extension.isEnabled && !alreadyInit) {
|
||||
if (installedExtension.isCompatible && installedExtension.isEnabled && !alreadyInit) {
|
||||
try {
|
||||
const LensExtensionClass = this.requireExtension(extension);
|
||||
const LensExtensionClass = this.requireExtension(installedExtension);
|
||||
|
||||
if (!LensExtensionClass) {
|
||||
this.nonInstancesByName.add(extension.manifest.name);
|
||||
this.nonInstancesByName.add(installedExtension.manifest.name);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const instance = this.dependencies.createExtensionInstance(
|
||||
LensExtensionClass,
|
||||
extension,
|
||||
);
|
||||
const instance = new LensExtensionClass(installedExtension);
|
||||
|
||||
this.dependencies.extensionInstances.set(extId, instance);
|
||||
|
||||
return {
|
||||
instance,
|
||||
installedExtension: extension,
|
||||
installedExtension,
|
||||
activated: instance.activate(),
|
||||
} as ExtensionBeingActivated;
|
||||
} catch (err) {
|
||||
this.dependencies.logger.error(`${logModule}: error loading extension`, { ext: extension, err });
|
||||
this.dependencies.logger.error(`${logModule}: error loading extension`, { ext: installedExtension, err });
|
||||
}
|
||||
} else if (!extension.isEnabled && alreadyInit) {
|
||||
} else if (!installedExtension.isEnabled && alreadyInit) {
|
||||
this.removeInstance(extId);
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -2,13 +2,14 @@
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { LegacyLensExtension } from "@k8slens/legacy-extensions";
|
||||
import type { Injectable } from "@ogre-tools/injectable";
|
||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import type { LensExtension } from "../lens-extension";
|
||||
|
||||
export type ExtensionRegistrator = (extension: LensExtension) =>
|
||||
Injectable<any, any, any>[] | IComputedValue<Injectable<any, any, any>[]>;
|
||||
export type Injectables = Injectable<any, any, any>[];
|
||||
export type Registration = Injectables | IComputedValue<Injectables>;
|
||||
export type ExtensionRegistrator = (extension: LegacyLensExtension) => Registration;
|
||||
|
||||
export const extensionRegistratorInjectionToken = getInjectionToken<ExtensionRegistrator>({
|
||||
id: "extension-registrator-token",
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import { reaction, runInAction } from "mobx";
|
||||
import { disposer } from "@k8slens/utilities";
|
||||
import type { LensExtension } from "../../lens-extension";
|
||||
import { extensionRegistratorInjectionToken } from "../extension-registrator-injection-token";
|
||||
import { injectableDifferencingRegistratorWith } from "../../../common/utils/registrator-helper";
|
||||
import type { LegacyLensExtension } from "@k8slens/legacy-extensions";
|
||||
|
||||
export interface Extension {
|
||||
register: () => void;
|
||||
@@ -17,7 +17,7 @@ export interface Extension {
|
||||
const extensionInjectable = getInjectable({
|
||||
id: "extension",
|
||||
|
||||
instantiate: (parentDi, instance: LensExtension): Extension => {
|
||||
instantiate: (parentDi, instance): Extension => {
|
||||
const extensionInjectable = getInjectable({
|
||||
id: `extension-${instance.sanitizedExtensionId}`,
|
||||
|
||||
@@ -66,7 +66,7 @@ const extensionInjectable = getInjectable({
|
||||
},
|
||||
|
||||
lifecycle: lifecycleEnum.keyedSingleton({
|
||||
getInstanceKey: (di, instance: LensExtension) => instance,
|
||||
getInstanceKey: (di, instance: LegacyLensExtension) => instance,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -2,16 +2,23 @@
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { iter } from "@k8slens/utilities";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import isExtensionEnabledInjectable from "../features/extensions/enabled/common/is-enabled.injectable";
|
||||
import extensionInstancesInjectable from "./extension-loader/extension-instances.injectable";
|
||||
|
||||
const extensionsInjectable = getInjectable({
|
||||
id: "extensions",
|
||||
instantiate: (di) => {
|
||||
const extensionInstances = di.inject(extensionInstancesInjectable);
|
||||
const isExtensionEnabled = di.inject(isExtensionEnabledInjectable);
|
||||
|
||||
return computed(() => [...extensionInstances.values()].filter(extension => extension.isEnabled));
|
||||
return computed(() => (
|
||||
iter.chain(extensionInstances.values())
|
||||
.filter(extension => extension.isBundled || isExtensionEnabled(extension.id))
|
||||
.toArray()
|
||||
));
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -4,16 +4,31 @@
|
||||
*/
|
||||
import { ipcMain } from "electron";
|
||||
import { IpcPrefix, IpcRegistrar } from "./ipc-registrar";
|
||||
import { Disposers, lensExtensionDependencies } from "../lens-extension";
|
||||
import { Disposers } from "../lens-extension";
|
||||
import type { LensMainExtension } from "../lens-main-extension";
|
||||
import type { Disposer } from "@k8slens/utilities";
|
||||
import { once } from "lodash";
|
||||
import { ipcMainHandle } from "../../common/ipc";
|
||||
import type { Logger } from "../common-api";
|
||||
import { getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
readonly logger: Logger;
|
||||
}
|
||||
|
||||
export abstract class IpcMain extends IpcRegistrar {
|
||||
private readonly dependencies: Dependencies;
|
||||
|
||||
constructor(extension: LensMainExtension) {
|
||||
super(extension);
|
||||
|
||||
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi("main");
|
||||
|
||||
this.dependencies = {
|
||||
logger: di.inject(loggerInjectable),
|
||||
};
|
||||
|
||||
// Call the static method on the bottom child class.
|
||||
extension[Disposers].push(() => (this.constructor as typeof IpcMain).resetInstance());
|
||||
}
|
||||
@@ -27,12 +42,12 @@ export abstract class IpcMain extends IpcRegistrar {
|
||||
listen(channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => any): Disposer {
|
||||
const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`;
|
||||
const cleanup = once(() => {
|
||||
this.extension[lensExtensionDependencies].logger.debug(`[IPC-RENDERER]: removing extension listener`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
|
||||
this.dependencies.logger.debug(`[IPC-RENDERER]: removing extension listener`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
|
||||
|
||||
return ipcMain.removeListener(prefixedChannel, listener);
|
||||
});
|
||||
|
||||
this.extension[lensExtensionDependencies].logger.debug(`[IPC-RENDERER]: adding extension listener`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
|
||||
this.dependencies.logger.debug(`[IPC-RENDERER]: adding extension listener`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
|
||||
ipcMain.addListener(prefixedChannel, listener);
|
||||
this.extension[Disposers].push(cleanup);
|
||||
|
||||
@@ -47,10 +62,10 @@ export abstract class IpcMain extends IpcRegistrar {
|
||||
handle(channel: string, handler: (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any): void {
|
||||
const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`;
|
||||
|
||||
this.extension[lensExtensionDependencies].logger.debug(`[IPC-RENDERER]: adding extension handler`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
|
||||
this.dependencies.logger.debug(`[IPC-RENDERER]: adding extension handler`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
|
||||
ipcMainHandle(prefixedChannel, handler);
|
||||
this.extension[Disposers].push(() => {
|
||||
this.extension[lensExtensionDependencies].logger.debug(`[IPC-RENDERER]: removing extension handler`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
|
||||
this.dependencies.logger.debug(`[IPC-RENDERER]: removing extension handler`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
|
||||
|
||||
return ipcMain.removeHandler(prefixedChannel);
|
||||
});
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { IComputedValue } from "mobx";
|
||||
import type { CatalogCategoryRegistry } from "../common/catalog";
|
||||
import type { NavigateToRoute } from "../common/front-end-routing/navigate-to-route-injection-token";
|
||||
import type { Route } from "../common/front-end-routing/front-end-route-injection-token";
|
||||
import type { CatalogEntityRegistry as MainCatalogEntityRegistry } from "../main/catalog";
|
||||
import type { CatalogEntityRegistry as RendererCatalogEntityRegistry } from "../renderer/api/catalog/entity/registry";
|
||||
import type { GetExtensionPageParameters } from "../renderer/routes/get-extension-page-parameters.injectable";
|
||||
import type { NavigateForExtension } from "../main/start-main-application/lens-window/navigate-for-extension.injectable";
|
||||
import type { Logger } from "../common/logger";
|
||||
import type { EnsureHashedDirectoryForExtension } from "./extension-loader/file-system-provisioner-store/ensure-hashed-directory-for-extension.injectable";
|
||||
|
||||
export interface LensExtensionDependencies {
|
||||
readonly logger: Logger;
|
||||
ensureHashedDirectoryForExtension: EnsureHashedDirectoryForExtension;
|
||||
}
|
||||
|
||||
export interface LensMainExtensionDependencies extends LensExtensionDependencies {
|
||||
readonly entityRegistry: MainCatalogEntityRegistry;
|
||||
readonly navigate: NavigateForExtension;
|
||||
}
|
||||
|
||||
export interface LensRendererExtensionDependencies extends LensExtensionDependencies {
|
||||
navigateToRoute: NavigateToRoute;
|
||||
getExtensionPageParameters: GetExtensionPageParameters;
|
||||
readonly routes: IComputedValue<Route<unknown>[]>;
|
||||
readonly entityRegistry: RendererCatalogEntityRegistry;
|
||||
readonly categoryRegistry: CatalogCategoryRegistry;
|
||||
}
|
||||
@@ -5,19 +5,19 @@
|
||||
|
||||
import { action, computed, makeObservable, observable } from "mobx";
|
||||
import { disposer } from "@k8slens/utilities";
|
||||
import type { LensExtensionDependencies } from "./lens-extension-set-dependencies";
|
||||
import type { ProtocolHandlerRegistration } from "../common/protocol-handler/registration";
|
||||
import type { InstalledExtension, LegacyLensExtension, LensExtensionId, LensExtensionManifest } from "@k8slens/legacy-extensions";
|
||||
import type { InstalledExtension, LensExtensionId, LensExtensionManifest } from "@k8slens/legacy-extensions";
|
||||
import type { Logger } from "./common-api";
|
||||
import type { EnsureHashedDirectoryForExtension } from "./extension-loader/file-system-provisioner-store/ensure-hashed-directory-for-extension.injectable";
|
||||
|
||||
export const lensExtensionDependencies = Symbol("lens-extension-dependencies");
|
||||
export const Disposers = Symbol("disposers");
|
||||
|
||||
export class LensExtension<
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Dependencies extends LensExtensionDependencies = LensExtensionDependencies,
|
||||
> implements LegacyLensExtension {
|
||||
export interface LensExtensionDependencies {
|
||||
readonly logger: Logger;
|
||||
ensureHashedDirectoryForExtension: EnsureHashedDirectoryForExtension;
|
||||
}
|
||||
|
||||
export class LensExtension {
|
||||
readonly id: LensExtensionId;
|
||||
readonly manifest: LensExtensionManifest;
|
||||
readonly manifestPath: string;
|
||||
@@ -27,6 +27,11 @@ export class LensExtension<
|
||||
return sanitizeExtensionName(this.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
protected readonly dependencies: LensExtensionDependencies;
|
||||
|
||||
protocolHandlers: ProtocolHandlerRegistration[] = [];
|
||||
|
||||
@observable private _isEnabled = false;
|
||||
@@ -40,12 +45,12 @@ export class LensExtension<
|
||||
*/
|
||||
[Disposers] = disposer();
|
||||
|
||||
constructor({ id, manifest, manifestPath, isBundled }: InstalledExtension) {
|
||||
// id is the name of the manifest
|
||||
constructor(deps: LensExtensionDependencies, { id, manifest, manifestPath, isBundled }: InstalledExtension) {
|
||||
this.dependencies = deps;
|
||||
this.id = id;
|
||||
this.manifest = manifest as LensExtensionManifest;
|
||||
this.manifestPath = manifestPath;
|
||||
this.isBundled = !!isBundled;
|
||||
this.isBundled = isBundled;
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
@@ -66,11 +71,6 @@ export class LensExtension<
|
||||
return this.manifest.storeName || this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
readonly [lensExtensionDependencies]!: Dependencies;
|
||||
|
||||
/**
|
||||
* getExtensionFileFolder returns the path to an already created folder. This
|
||||
* folder is for the sole use of this extension.
|
||||
@@ -80,7 +80,7 @@ export class LensExtension<
|
||||
*/
|
||||
async getExtensionFileFolder(): Promise<string> {
|
||||
// storeName is read from the manifest and has a fallback to the manifest name, which equals id
|
||||
return this[lensExtensionDependencies].ensureHashedDirectoryForExtension(this.storeName);
|
||||
return this.dependencies.ensureHashedDirectoryForExtension(this.storeName);
|
||||
}
|
||||
|
||||
@action
|
||||
@@ -90,7 +90,7 @@ export class LensExtension<
|
||||
}
|
||||
|
||||
this._isEnabled = true;
|
||||
this[lensExtensionDependencies].logger.info(`[EXTENSION]: enabled ${this.name}@${this.version}`);
|
||||
this.dependencies.logger.info(`[EXTENSION]: enabled ${this.name}@${this.version}`);
|
||||
}
|
||||
|
||||
@action
|
||||
@@ -104,9 +104,9 @@ export class LensExtension<
|
||||
try {
|
||||
await this.onDeactivate();
|
||||
this[Disposers]();
|
||||
this[lensExtensionDependencies].logger.info(`[EXTENSION]: disabled ${this.name}@${this.version}`);
|
||||
this.dependencies.logger.info(`[EXTENSION]: disabled ${this.name}@${this.version}`);
|
||||
} catch (error) {
|
||||
this[lensExtensionDependencies].logger.error(`[EXTENSION]: disabling ${this.name}@${this.version} threw an error: ${error}`);
|
||||
this.dependencies.logger.error(`[EXTENSION]: disabling ${this.name}@${this.version} threw an error: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,19 +3,49 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { LensExtension, lensExtensionDependencies } from "./lens-extension";
|
||||
import type { LensExtensionDependencies } from "./lens-extension";
|
||||
import { LensExtension } from "./lens-extension";
|
||||
import type { CatalogEntity } from "../common/catalog";
|
||||
import type { IComputedValue, IObservableArray } from "mobx";
|
||||
import { isObservableArray } from "mobx";
|
||||
import type { MenuRegistration } from "../features/application-menu/main/menu-registration";
|
||||
import type { TrayMenuRegistration } from "../main/tray/tray-menu-registration";
|
||||
import type { ShellEnvModifier } from "../main/shell-session/shell-env-modifier/shell-env-modifier-registration";
|
||||
import type { LensMainExtensionDependencies } from "./lens-extension-set-dependencies";
|
||||
import { getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "./as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||
import type { InstalledExtension } from "./common-api";
|
||||
import type { CatalogEntityRegistry } from "../main/catalog";
|
||||
import type { NavigateForExtension } from "../main/start-main-application/lens-window/navigate-for-extension.injectable";
|
||||
import catalogEntityRegistryInjectable from "../main/catalog/entity-registry.injectable";
|
||||
import loggerInjectable from "../common/logger.injectable";
|
||||
import navigateForExtensionInjectable from "../main/start-main-application/lens-window/navigate-for-extension.injectable";
|
||||
import ensureHashedDirectoryForExtensionInjectable from "./extension-loader/file-system-provisioner-store/ensure-hashed-directory-for-extension.injectable";
|
||||
|
||||
export class LensMainExtension extends LensExtension<LensMainExtensionDependencies> {
|
||||
interface LensMainExtensionDependencies extends LensExtensionDependencies {
|
||||
readonly entityRegistry: CatalogEntityRegistry;
|
||||
readonly navigate: NavigateForExtension;
|
||||
}
|
||||
|
||||
export class LensMainExtension extends LensExtension {
|
||||
appMenus: MenuRegistration[] | IComputedValue<MenuRegistration[]> = [];
|
||||
trayMenus: TrayMenuRegistration[] | IComputedValue<TrayMenuRegistration[]> = [];
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
declare readonly dependencies: LensMainExtensionDependencies;
|
||||
|
||||
constructor(extension: InstalledExtension) {
|
||||
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi("main");
|
||||
const deps: LensMainExtensionDependencies = {
|
||||
ensureHashedDirectoryForExtension: di.inject(ensureHashedDirectoryForExtensionInjectable),
|
||||
navigate: di.inject(navigateForExtensionInjectable),
|
||||
entityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
};
|
||||
|
||||
super(deps, extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* implement this to modify the shell environment that Lens terminals are opened with. The ShellEnvModifier type has the signature
|
||||
*
|
||||
@@ -32,18 +62,18 @@ export class LensMainExtension extends LensExtension<LensMainExtensionDependenci
|
||||
terminalShellEnvModifier?: ShellEnvModifier;
|
||||
|
||||
async navigate(pageId?: string, params?: Record<string, any>, frameId?: number) {
|
||||
await this[lensExtensionDependencies].navigate(this.id, pageId, params, frameId);
|
||||
await this.dependencies.navigate(this.id, pageId, params, frameId);
|
||||
}
|
||||
|
||||
addCatalogSource(id: string, source: IObservableArray<CatalogEntity> | IComputedValue<CatalogEntity[]>) {
|
||||
if (isObservableArray(source)) {
|
||||
this[lensExtensionDependencies].entityRegistry.addObservableSource(`${this.name}:${id}`, source);
|
||||
this.dependencies.entityRegistry.addObservableSource(`${this.name}:${id}`, source);
|
||||
} else {
|
||||
this[lensExtensionDependencies].entityRegistry.addComputedSource(`${this.name}:${id}`, source);
|
||||
this.dependencies.entityRegistry.addComputedSource(`${this.name}:${id}`, source);
|
||||
}
|
||||
}
|
||||
|
||||
removeCatalogSource(id: string) {
|
||||
this[lensExtensionDependencies].entityRegistry.removeSource(`${this.name}:${id}`);
|
||||
this.dependencies.entityRegistry.removeSource(`${this.name}:${id}`);
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,11 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { Disposers, LensExtension, lensExtensionDependencies } from "./lens-extension";
|
||||
import type { CatalogEntity, CategoryFilter } from "../common/catalog";
|
||||
import { Disposers, LensExtension } from "./lens-extension";
|
||||
import type { Disposer } from "@k8slens/utilities";
|
||||
import type { EntityFilter } from "../renderer/api/catalog/entity/registry";
|
||||
import type { LensExtensionDependencies } from "./lens-extension";
|
||||
import type { CatalogEntity, CategoryFilter, CatalogCategoryRegistry } from "../common/catalog";
|
||||
import type { EntityFilter, CatalogEntityRegistry } from "../renderer/api/catalog/entity/registry";
|
||||
import type { TopBarRegistration } from "../renderer/components/layout/top-bar/top-bar-registration";
|
||||
import type { KubernetesCluster } from "../common/catalog-entities";
|
||||
import type { WelcomeMenuRegistration } from "../renderer/components/+welcome/welcome-menu-items/welcome-menu-registration";
|
||||
@@ -22,7 +23,6 @@ import type { KubeObjectStatusRegistration } from "../renderer/components/kube-o
|
||||
import { fromPairs, map, matches, toPairs } from "lodash/fp";
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import { getExtensionRoutePath } from "../renderer/routes/for-extension";
|
||||
import type { LensRendererExtensionDependencies } from "./lens-extension-set-dependencies";
|
||||
import type { KubeObjectHandlerRegistration } from "../renderer/kube-object/handler";
|
||||
import type { AppPreferenceTabRegistration } from "../features/preferences/renderer/compliance-for-legacy-extension-api/app-preference-tab-registration";
|
||||
import type { KubeObjectDetailRegistration } from "../renderer/components/kube-object-details/kube-object-detail-registration";
|
||||
@@ -31,8 +31,29 @@ import type { EntitySettingRegistration } from "../renderer/components/+entity-s
|
||||
import type { CatalogEntityDetailRegistration } from "../renderer/components/+catalog/entity-details/token";
|
||||
import type { PageRegistration } from "../renderer/routes/page-registration";
|
||||
import type { ClusterPageMenuRegistration } from "../renderer/components/layout/cluster-page-menu";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import type { NavigateToRoute } from "../common/front-end-routing/navigate-to-route-injection-token";
|
||||
import type { Route } from "../common/front-end-routing/front-end-route-injection-token";
|
||||
import type { GetExtensionPageParameters } from "../renderer/routes/get-extension-page-parameters.injectable";
|
||||
import type { InstalledExtension } from "./common-api";
|
||||
import { getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "./as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||
import catalogCategoryRegistryInjectable from "../common/catalog/category-registry.injectable";
|
||||
import catalogEntityRegistryInjectable from "../renderer/api/catalog/entity/registry.injectable";
|
||||
import loggerInjectable from "../common/logger.injectable";
|
||||
import getExtensionPageParametersInjectable from "../renderer/routes/get-extension-page-parameters.injectable";
|
||||
import navigateToRouteInjectable from "../renderer/routes/navigate-to-route.injectable";
|
||||
import routesInjectable from "../renderer/routes/routes.injectable";
|
||||
import ensureHashedDirectoryForExtensionInjectable from "./extension-loader/file-system-provisioner-store/ensure-hashed-directory-for-extension.injectable";
|
||||
|
||||
export class LensRendererExtension extends LensExtension<LensRendererExtensionDependencies> {
|
||||
interface LensRendererExtensionDependencies extends LensExtensionDependencies {
|
||||
navigateToRoute: NavigateToRoute;
|
||||
getExtensionPageParameters: GetExtensionPageParameters;
|
||||
readonly routes: IComputedValue<Route<unknown>[]>;
|
||||
readonly entityRegistry: CatalogEntityRegistry;
|
||||
readonly categoryRegistry: CatalogCategoryRegistry;
|
||||
}
|
||||
|
||||
export class LensRendererExtension extends LensExtension {
|
||||
globalPages: PageRegistration[] = [];
|
||||
clusterPages: PageRegistration[] = [];
|
||||
clusterPageMenus: ClusterPageMenuRegistration[] = [];
|
||||
@@ -54,8 +75,28 @@ export class LensRendererExtension extends LensExtension<LensRendererExtensionDe
|
||||
customCategoryViews: CustomCategoryViewRegistration[] = [];
|
||||
kubeObjectHandlers: KubeObjectHandlerRegistration[] = [];
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
declare protected readonly dependencies: LensRendererExtensionDependencies;
|
||||
|
||||
constructor(extension: InstalledExtension) {
|
||||
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi("renderer");
|
||||
const deps: LensRendererExtensionDependencies = {
|
||||
getExtensionPageParameters: di.inject(getExtensionPageParametersInjectable),
|
||||
navigateToRoute: di.inject(navigateToRouteInjectable),
|
||||
ensureHashedDirectoryForExtension: di.inject(ensureHashedDirectoryForExtensionInjectable),
|
||||
categoryRegistry: di.inject(catalogCategoryRegistryInjectable),
|
||||
entityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||
routes: di.inject(routesInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
};
|
||||
|
||||
super(deps, extension);
|
||||
}
|
||||
|
||||
async navigate(pageId?: string, params: object = {}) {
|
||||
const routes = this[lensExtensionDependencies].routes.get();
|
||||
const routes = this.dependencies.routes.get();
|
||||
const targetRegistration = [...this.globalPages, ...this.clusterPages]
|
||||
.find(registration => registration.id === (pageId || undefined));
|
||||
|
||||
@@ -70,7 +111,7 @@ export class LensRendererExtension extends LensExtension<LensRendererExtensionDe
|
||||
return;
|
||||
}
|
||||
|
||||
const normalizedParams = this[lensExtensionDependencies].getExtensionPageParameters({
|
||||
const normalizedParams = this.dependencies.getExtensionPageParameters({
|
||||
extension: this,
|
||||
registration: targetRegistration,
|
||||
});
|
||||
@@ -84,7 +125,7 @@ export class LensRendererExtension extends LensExtension<LensRendererExtensionDe
|
||||
fromPairs,
|
||||
);
|
||||
|
||||
this[lensExtensionDependencies].navigateToRoute(targetRoute, {
|
||||
this.dependencies.navigateToRoute(targetRoute, {
|
||||
query,
|
||||
});
|
||||
}
|
||||
@@ -107,7 +148,7 @@ export class LensRendererExtension extends LensExtension<LensRendererExtensionDe
|
||||
* @returns A function to clean up the filter
|
||||
*/
|
||||
addCatalogFilter(fn: EntityFilter): Disposer {
|
||||
const dispose = this[lensExtensionDependencies].entityRegistry.addCatalogFilter(fn);
|
||||
const dispose = this.dependencies.entityRegistry.addCatalogFilter(fn);
|
||||
|
||||
this[Disposers].push(dispose);
|
||||
|
||||
@@ -120,7 +161,7 @@ export class LensRendererExtension extends LensExtension<LensRendererExtensionDe
|
||||
* @returns A function to clean up the filter
|
||||
*/
|
||||
addCatalogCategoryFilter(fn: CategoryFilter): Disposer {
|
||||
const dispose = this[lensExtensionDependencies].categoryRegistry.addCatalogCategoryFilter(fn);
|
||||
const dispose = this.dependencies.categoryRegistry.addCatalogCategoryFilter(fn);
|
||||
|
||||
this[Disposers].push(dispose);
|
||||
|
||||
|
||||
Reference in new issue
Block a user