1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/packages/core/src/extensions/lens-extension.ts
Sebastian Malton 2c3c88be04
Fix bundled extensions not being loaded (#7359)
* Fix bundled extensions not being loaded

- Also show that this fixes it by added an example bundled
  extension to 'open-lens'

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

* Fix build

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

* Add explanatory comment for inline require

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

---------

Signed-off-by: Sebastian Malton <sebastian@malton.name>
2023-03-15 18:16:09 +02:00

144 lines
3.7 KiB
TypeScript

/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
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";
export const lensExtensionDependencies = Symbol("lens-extension-dependencies");
export const Disposers = Symbol("disposers");
export class LensExtension<
/**
* @ignore
*/
Dependencies extends LensExtensionDependencies = LensExtensionDependencies,
> implements LegacyLensExtension {
readonly id: LensExtensionId;
readonly manifest: LensExtensionManifest;
readonly manifestPath: string;
readonly isBundled: boolean;
get sanitizedExtensionId() {
return sanitizeExtensionName(this.name);
}
protocolHandlers: ProtocolHandlerRegistration[] = [];
@observable private _isEnabled = false;
@computed get isEnabled() {
return this._isEnabled;
}
/**
* @ignore
*/
[Disposers] = disposer();
constructor({ id, manifest, manifestPath, isBundled }: InstalledExtension) {
makeObservable(this);
// id is the name of the manifest
this.id = id;
this.manifest = manifest;
this.manifestPath = manifestPath;
this.isBundled = !!isBundled;
}
get name() {
return this.manifest.name;
}
get version() {
return this.manifest.version;
}
get description() {
return this.manifest.description;
}
// Name of extension for persisting data
get storeName() {
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.
*
* Note: there is no security done on this folder, only obfuscation of the
* folder name.
*/
async getExtensionFileFolder(): Promise<string> {
// storeName is read from the manifest and has a fallback to the manifest name, which equals id
return this[lensExtensionDependencies].fileSystemProvisionerStore.requestDirectory(this.storeName);
}
@action
async enable() {
if (this._isEnabled) {
return;
}
this._isEnabled = true;
this[lensExtensionDependencies].logger.info(`[EXTENSION]: enabled ${this.name}@${this.version}`);
}
@action
async disable() {
if (!this._isEnabled) {
return;
}
this._isEnabled = false;
try {
await this.onDeactivate();
this[Disposers]();
this[lensExtensionDependencies].logger.info(`[EXTENSION]: disabled ${this.name}@${this.version}`);
} catch (error) {
this[lensExtensionDependencies].logger.error(`[EXTENSION]: disabling ${this.name}@${this.version} threw an error: ${error}`);
}
}
async activate(): Promise<void> {
return this.onActivate();
}
protected onActivate(): Promise<void> | void {
return;
}
protected onDeactivate(): Promise<void> | void {
return;
}
}
export function sanitizeExtensionName(name: string) {
return name.replace("@", "").replace("/", "--");
}
export function getSanitizedPath(...parts: string[]) {
return parts
.filter(Boolean)
.join("/")
.replace(/\/+/g, "/")
.replace(/\/$/, "");
} // normalize multi-slashes (e.g. coming from page.id)
export function extensionDisplayName(name: string, version: string) {
return `${name}@${version}`;
}