mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Merge branch 'master' into extension-auto-update
This commit is contained in:
163 files changed
+3307
-1656
No files matched your search
@@ -19,7 +19,6 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import mockFs from "mock-fs";
|
||||
import { watch } from "chokidar";
|
||||
import { ExtensionsStore } from "../extensions-store";
|
||||
import path from "path";
|
||||
@@ -30,6 +29,7 @@ import { AppPaths } from "../../common/app-paths";
|
||||
import type { ExtensionLoader } from "../extension-loader";
|
||||
import extensionLoaderInjectable from "../extension-loader/extension-loader.injectable";
|
||||
import { getDiForUnitTesting } from "../getDiForUnitTesting";
|
||||
import * as fse from "fs-extra";
|
||||
|
||||
jest.setTimeout(60_000);
|
||||
|
||||
@@ -43,6 +43,7 @@ jest.mock("../extension-installer", () => ({
|
||||
installPackage: jest.fn(),
|
||||
},
|
||||
}));
|
||||
jest.mock("fs-extra");
|
||||
jest.mock("electron", () => ({
|
||||
app: {
|
||||
getVersion: () => "99.99.99",
|
||||
@@ -63,6 +64,7 @@ AppPaths.init();
|
||||
|
||||
console = new Console(process.stdout, process.stderr); // fix mockFS
|
||||
const mockedWatch = watch as jest.MockedFunction<typeof watch>;
|
||||
const mockedFse = fse as jest.Mocked<typeof fse>;
|
||||
|
||||
describe("ExtensionDiscovery", () => {
|
||||
let extensionLoader: ExtensionLoader;
|
||||
@@ -77,63 +79,60 @@ describe("ExtensionDiscovery", () => {
|
||||
extensionLoader = di.inject(extensionLoaderInjectable);
|
||||
});
|
||||
|
||||
describe("with mockFs", () => {
|
||||
beforeEach(() => {
|
||||
mockFs({
|
||||
[`${os.homedir()}/.k8slens/extensions/my-extension/package.json`]: JSON.stringify({
|
||||
name: "my-extension",
|
||||
}),
|
||||
});
|
||||
});
|
||||
it("emits add for added extension", async (done) => {
|
||||
let addHandler: (filePath: string) => void;
|
||||
|
||||
afterEach(() => {
|
||||
mockFs.restore();
|
||||
});
|
||||
mockedFse.readJson.mockImplementation((p) => {
|
||||
expect(p).toBe(path.join(os.homedir(), ".k8slens/extensions/my-extension/package.json"));
|
||||
|
||||
it("emits add for added extension", async (done) => {
|
||||
let addHandler: (filePath: string) => void;
|
||||
|
||||
const mockWatchInstance: any = {
|
||||
on: jest.fn((event: string, handler: typeof addHandler) => {
|
||||
if (event === "add") {
|
||||
addHandler = handler;
|
||||
}
|
||||
|
||||
return mockWatchInstance;
|
||||
}),
|
||||
return {
|
||||
name: "my-extension",
|
||||
version: "1.0.0",
|
||||
};
|
||||
|
||||
mockedWatch.mockImplementationOnce(() =>
|
||||
(mockWatchInstance) as any,
|
||||
);
|
||||
|
||||
const extensionDiscovery = ExtensionDiscovery.createInstance(
|
||||
extensionLoader,
|
||||
);
|
||||
|
||||
// Need to force isLoaded to be true so that the file watching is started
|
||||
extensionDiscovery.isLoaded = true;
|
||||
|
||||
await extensionDiscovery.watchExtensions();
|
||||
|
||||
extensionDiscovery.events.on("add", extension => {
|
||||
expect(extension).toEqual({
|
||||
absolutePath: expect.any(String),
|
||||
id: path.normalize("node_modules/my-extension/package.json"),
|
||||
isBundled: false,
|
||||
isEnabled: false,
|
||||
isCompatible: false,
|
||||
manifest: {
|
||||
name: "my-extension",
|
||||
},
|
||||
manifestPath: path.normalize("node_modules/my-extension/package.json"),
|
||||
availableUpdate: null,
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
addHandler(path.join(extensionDiscovery.localFolderPath, "/my-extension/package.json"));
|
||||
});
|
||||
|
||||
mockedFse.pathExists.mockImplementation(() => true);
|
||||
|
||||
const mockWatchInstance: any = {
|
||||
on: jest.fn((event: string, handler: typeof addHandler) => {
|
||||
if (event === "add") {
|
||||
addHandler = handler;
|
||||
}
|
||||
|
||||
return mockWatchInstance;
|
||||
}),
|
||||
};
|
||||
|
||||
mockedWatch.mockImplementationOnce(() =>
|
||||
(mockWatchInstance) as any,
|
||||
);
|
||||
const extensionDiscovery = ExtensionDiscovery.createInstance(
|
||||
extensionLoader,
|
||||
);
|
||||
|
||||
// Need to force isLoaded to be true so that the file watching is started
|
||||
extensionDiscovery.isLoaded = true;
|
||||
|
||||
await extensionDiscovery.watchExtensions();
|
||||
|
||||
extensionDiscovery.events.on("add", extension => {
|
||||
expect(extension).toEqual({
|
||||
absolutePath: expect.any(String),
|
||||
id: path.normalize("node_modules/my-extension/package.json"),
|
||||
isBundled: false,
|
||||
isEnabled: false,
|
||||
isCompatible: false,
|
||||
manifest: {
|
||||
name: "my-extension",
|
||||
version: "1.0.0",
|
||||
},
|
||||
manifestPath: path.normalize("node_modules/my-extension/package.json"),
|
||||
availableUpdate: null,
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
addHandler(path.join(extensionDiscovery.localFolderPath, "/my-extension/package.json"));
|
||||
});
|
||||
|
||||
it("doesn't emit add for added file under extension", async done => {
|
||||
@@ -150,7 +149,7 @@ describe("ExtensionDiscovery", () => {
|
||||
};
|
||||
|
||||
mockedWatch.mockImplementationOnce(() =>
|
||||
(mockWatchInstance) as any,
|
||||
(mockWatchInstance) as any,
|
||||
);
|
||||
const extensionDiscovery = ExtensionDiscovery.createInstance(
|
||||
extensionLoader,
|
||||
@@ -173,3 +172,4 @@ describe("ExtensionDiscovery", () => {
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
|
||||
+25
-7
@@ -18,13 +18,31 @@
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import type { Injectable } from "@ogre-tools/injectable";
|
||||
|
||||
import { BaseRegistry } from "./base-registry";
|
||||
import { getLegacyGlobalDiForExtensionApi } from "./legacy-global-di-for-extension-api";
|
||||
|
||||
export interface WelcomeMenuRegistration {
|
||||
title: string | (() => string);
|
||||
icon: string;
|
||||
click: () => void | Promise<void>;
|
||||
}
|
||||
type TentativeTuple<T> = T extends object ? [T] : [undefined?];
|
||||
|
||||
export class WelcomeMenuRegistry extends BaseRegistry<WelcomeMenuRegistration> {}
|
||||
type FactoryType = <
|
||||
TInjectable extends Injectable<unknown, TInstance, TInstantiationParameter>,
|
||||
TInstantiationParameter,
|
||||
TInstance extends (...args: unknown[]) => any,
|
||||
TFunction extends (...args: unknown[]) => any = Awaited<
|
||||
ReturnType<TInjectable["instantiate"]>
|
||||
>,
|
||||
>(
|
||||
injectableKey: TInjectable,
|
||||
...instantiationParameter: TentativeTuple<TInstantiationParameter>
|
||||
) => (...args: Parameters<TFunction>) => ReturnType<TFunction>;
|
||||
|
||||
export const asLegacyGlobalFunctionForExtensionApi: FactoryType =
|
||||
(injectableKey, ...instantiationParameter) =>
|
||||
(...args) => {
|
||||
const injected = getLegacyGlobalDiForExtensionApi().inject(
|
||||
injectableKey,
|
||||
...instantiationParameter,
|
||||
);
|
||||
|
||||
return injected(...args);
|
||||
};
|
||||
+31
-26
@@ -18,35 +18,40 @@
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import type { Injectable } from "@ogre-tools/injectable";
|
||||
import { getLegacyGlobalDiForExtensionApi } from "./legacy-global-di-for-extension-api";
|
||||
|
||||
// Extensions API -> Commands
|
||||
type TentativeTuple<T> = T extends object ? [T] : [undefined?];
|
||||
|
||||
import { BaseRegistry } from "./base-registry";
|
||||
import type { LensExtension } from "../lens-extension";
|
||||
import type { CatalogEntity } from "../../common/catalog";
|
||||
export const asLegacyGlobalObjectForExtensionApi = <
|
||||
TInjectable extends Injectable<unknown, unknown, TInstantiationParameter>,
|
||||
TInstantiationParameter,
|
||||
>(
|
||||
injectableKey: TInjectable,
|
||||
...instantiationParameter: TentativeTuple<TInstantiationParameter>
|
||||
) =>
|
||||
new Proxy(
|
||||
{},
|
||||
{
|
||||
get(target, propertyName) {
|
||||
if (propertyName === "$$typeof") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export interface CommandContext {
|
||||
entity?: CatalogEntity;
|
||||
}
|
||||
const instance: any = getLegacyGlobalDiForExtensionApi().inject(
|
||||
injectableKey,
|
||||
...instantiationParameter,
|
||||
);
|
||||
|
||||
export interface CommandRegistration {
|
||||
id: string;
|
||||
title: string;
|
||||
scope: "entity" | "global";
|
||||
action: (context: CommandContext) => void;
|
||||
isActive?: (context: CommandContext) => boolean;
|
||||
}
|
||||
const propertyValue = instance[propertyName];
|
||||
|
||||
export class CommandRegistry extends BaseRegistry<CommandRegistration> {
|
||||
add(items: CommandRegistration | CommandRegistration[], extension?: LensExtension) {
|
||||
const itemArray = [items].flat();
|
||||
if (typeof propertyValue === "function") {
|
||||
return function (...args: any[]) {
|
||||
return propertyValue.apply(instance, args);
|
||||
};
|
||||
}
|
||||
|
||||
const newIds = itemArray.map((item) => item.id);
|
||||
const currentIds = this.getItems().map((item) => item.id);
|
||||
|
||||
const filteredIds = newIds.filter((id) => !currentIds.includes(id));
|
||||
const filteredItems = itemArray.filter((item) => filteredIds.includes(item.id));
|
||||
|
||||
return super.add(filteredItems, extension);
|
||||
}
|
||||
}
|
||||
return propertyValue;
|
||||
},
|
||||
},
|
||||
) as ReturnType<TInjectable["instantiate"]>;
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OpenLens Authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import type { Injectable } from "@ogre-tools/injectable";
|
||||
import { getLegacyGlobalDiForExtensionApi } from "./legacy-global-di-for-extension-api";
|
||||
|
||||
type TentativeTuple<T> = T extends object ? [T] : [undefined?];
|
||||
|
||||
export const asLegacyGlobalSingletonForExtensionApi = <
|
||||
TClass extends abstract new (...args: any[]) => any,
|
||||
TInjectable extends Injectable<unknown, unknown, TInstantiationParameter>,
|
||||
TInstantiationParameter,
|
||||
>(
|
||||
Class: TClass,
|
||||
injectableKey: TInjectable,
|
||||
...instantiationParameter: TentativeTuple<TInstantiationParameter>
|
||||
) =>
|
||||
new Proxy(Class, {
|
||||
construct: () => {
|
||||
throw new Error("A legacy singleton class must be created by createInstance()");
|
||||
},
|
||||
|
||||
get: (target: any, propertyName) => {
|
||||
if (propertyName === "getInstance" || propertyName === "createInstance") {
|
||||
return () =>
|
||||
getLegacyGlobalDiForExtensionApi().inject(
|
||||
injectableKey,
|
||||
...instantiationParameter,
|
||||
);
|
||||
}
|
||||
|
||||
if (propertyName === "resetInstance") {
|
||||
return () => getLegacyGlobalDiForExtensionApi().purge(injectableKey);
|
||||
}
|
||||
|
||||
return target[propertyName];
|
||||
},
|
||||
}) as InstanceType<TClass> & {
|
||||
getInstance: () => InstanceType<TClass>;
|
||||
createInstance: () => InstanceType<TClass>;
|
||||
resetInstance: () => void;
|
||||
};
|
||||
+6
-11
@@ -18,17 +18,12 @@
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import type { DependencyInjectionContainer } from "@ogre-tools/injectable";
|
||||
|
||||
import type React from "react";
|
||||
import { BaseRegistry } from "./base-registry";
|
||||
let legacyGlobalDi: DependencyInjectionContainer;
|
||||
|
||||
interface TopBarComponents {
|
||||
Item: React.ComponentType;
|
||||
}
|
||||
export const setLegacyGlobalDiForExtensionApi = (di: DependencyInjectionContainer) => {
|
||||
legacyGlobalDi = di;
|
||||
};
|
||||
|
||||
export interface TopBarRegistration {
|
||||
components: TopBarComponents;
|
||||
}
|
||||
|
||||
export class TopBarRegistry extends BaseRegistry<TopBarRegistration> {
|
||||
}
|
||||
export const getLegacyGlobalDiForExtensionApi = () => legacyGlobalDi;
|
||||
@@ -18,8 +18,7 @@
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import { ExtensionLoader } from "./extension-loader";
|
||||
|
||||
const extensionLoaderInjectable = getInjectable({
|
||||
|
||||
@@ -279,11 +279,7 @@ export class ExtensionLoader {
|
||||
registries.AppPreferenceRegistry.getInstance().add(extension.appPreferences),
|
||||
registries.EntitySettingRegistry.getInstance().add(extension.entitySettings),
|
||||
registries.StatusBarRegistry.getInstance().add(extension.statusBarItems),
|
||||
registries.CommandRegistry.getInstance().add(extension.commands),
|
||||
registries.WelcomeMenuRegistry.getInstance().add(extension.welcomeMenus),
|
||||
registries.WelcomeBannerRegistry.getInstance().add(extension.welcomeBanners),
|
||||
registries.CatalogEntityDetailRegistry.getInstance().add(extension.catalogEntityDetailItems),
|
||||
registries.TopBarRegistry.getInstance().add(extension.topBarItems),
|
||||
];
|
||||
|
||||
this.events.on("remove", (removedExtension: LensRendererExtension) => {
|
||||
@@ -315,7 +311,6 @@ export class ExtensionLoader {
|
||||
registries.KubeObjectDetailRegistry.getInstance().add(extension.kubeObjectDetailItems),
|
||||
registries.KubeObjectStatusRegistry.getInstance().add(extension.kubeObjectStatusTexts),
|
||||
registries.WorkloadsOverviewDetailRegistry.getInstance().add(extension.kubeWorkloadsOverviewItems),
|
||||
registries.CommandRegistry.getInstance().add(extension.commands),
|
||||
];
|
||||
|
||||
this.events.on("remove", (removedExtension: LensRendererExtension) => {
|
||||
|
||||
@@ -41,7 +41,6 @@ export const getDiForUnitTesting = () => {
|
||||
aliases: [injectable, ...(injectable.aliases || [])],
|
||||
};
|
||||
})
|
||||
|
||||
.forEach(injectable => di.register(injectable));
|
||||
|
||||
di.preventSideEffects();
|
||||
|
||||
@@ -25,9 +25,10 @@ import { catalogEntityRegistry } from "../main/catalog";
|
||||
import type { CatalogEntity } from "../common/catalog";
|
||||
import type { IObservableArray } from "mobx";
|
||||
import type { MenuRegistration } from "../main/menu/menu-registration";
|
||||
|
||||
import type { TrayMenuRegistration } from "../main/tray/tray-menu-registration";
|
||||
export class LensMainExtension extends LensExtension {
|
||||
appMenus: MenuRegistration[] = [];
|
||||
trayMenus: TrayMenuRegistration[] = [];
|
||||
|
||||
async navigate(pageId?: string, params?: Record<string, any>, frameId?: number) {
|
||||
return WindowManager.getInstance().navigateExtension(this.id, pageId, params, frameId);
|
||||
|
||||
@@ -26,7 +26,11 @@ import type { CatalogEntity } from "../common/catalog";
|
||||
import type { Disposer } from "../common/utils";
|
||||
import { catalogEntityRegistry, EntityFilter } from "../renderer/api/catalog-entity-registry";
|
||||
import { catalogCategoryRegistry, CategoryFilter } from "../renderer/api/catalog-category-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";
|
||||
import type { WelcomeBannerRegistration } from "../renderer/components/+welcome/welcome-banner-items/welcome-banner-registration";
|
||||
import type { CommandRegistration } from "../renderer/components/command-palette/registered-commands/commands";
|
||||
|
||||
export class LensRendererExtension extends LensExtension {
|
||||
globalPages: registries.PageRegistration[] = [];
|
||||
@@ -39,11 +43,11 @@ export class LensRendererExtension extends LensExtension {
|
||||
kubeObjectDetailItems: registries.KubeObjectDetailRegistration[] = [];
|
||||
kubeObjectMenuItems: registries.KubeObjectMenuRegistration[] = [];
|
||||
kubeWorkloadsOverviewItems: registries.WorkloadsOverviewDetailRegistration[] = [];
|
||||
commands: registries.CommandRegistration[] = [];
|
||||
welcomeMenus: registries.WelcomeMenuRegistration[] = [];
|
||||
welcomeBanners: registries.WelcomeBannerRegistration[] = [];
|
||||
commands: CommandRegistration[] = [];
|
||||
welcomeMenus: WelcomeMenuRegistration[] = [];
|
||||
welcomeBanners: WelcomeBannerRegistration[] = [];
|
||||
catalogEntityDetailItems: registries.CatalogEntityDetailRegistration<CatalogEntity>[] = [];
|
||||
topBarItems: registries.TopBarRegistration[] = [];
|
||||
topBarItems: TopBarRegistration[] = [];
|
||||
|
||||
async navigate<P extends object>(pageId?: string, params?: P) {
|
||||
const { navigate } = await import("../renderer/navigation");
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
// Base class for extensions-api registries
|
||||
import { action, observable, makeObservable } from "mobx";
|
||||
import { Singleton } from "../../common/utils";
|
||||
import { LensExtension } from "../lens-extension";
|
||||
import type { LensExtension } from "../lens-extension";
|
||||
|
||||
export class BaseRegistry<T, I = T> extends Singleton {
|
||||
private items = observable.map<T, I>([], { deep: false });
|
||||
|
||||
@@ -54,7 +54,7 @@ export class EntitySettingRegistry extends BaseRegistry<EntitySettingRegistratio
|
||||
};
|
||||
}
|
||||
|
||||
getItemsForKind(kind: string, apiVersion: string, source?: string) {
|
||||
getItemsForKind = (kind: string, apiVersion: string, source?: string) => {
|
||||
let items = this.getItems().filter((item) => {
|
||||
return item.kind === kind && item.apiVersions.includes(apiVersion);
|
||||
});
|
||||
@@ -66,5 +66,5 @@ export class EntitySettingRegistry extends BaseRegistry<EntitySettingRegistratio
|
||||
}
|
||||
|
||||
return items.sort((a, b) => (b.priority ?? 50) - (a.priority ?? 50));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -28,11 +28,7 @@ export * from "./status-bar-registry";
|
||||
export * from "./kube-object-detail-registry";
|
||||
export * from "./kube-object-menu-registry";
|
||||
export * from "./kube-object-status-registry";
|
||||
export * from "./command-registry";
|
||||
export * from "./entity-setting-registry";
|
||||
export * from "./welcome-menu-registry";
|
||||
export * from "./welcome-banner-registry";
|
||||
export * from "./catalog-entity-detail-registry";
|
||||
export * from "./workloads-overview-detail-registry";
|
||||
export * from "./topbar-registry";
|
||||
export * from "./protocol-handler";
|
||||
@@ -135,10 +135,7 @@ class PageRegistry extends BaseRegistry<PageRegistration, RegisteredPage> {
|
||||
);
|
||||
|
||||
if (notAStringValue && !(parse || stringify)) {
|
||||
throw new Error(
|
||||
`PageRegistry: param's "${paramName}" initialization has failed:
|
||||
paramInit.parse() and paramInit.stringify() are required for non string | string[] "defaultValue"`,
|
||||
);
|
||||
throw new Error(`PageRegistry: param's "${paramName}" initialization has failed: paramInit.parse() and paramInit.stringify() are required for non string | string[] "defaultValue"`);
|
||||
}
|
||||
|
||||
paramInit.defaultValue = value;
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import commandOverlayInjectable from "../../renderer/components/command-palette/command-overlay.injectable";
|
||||
import { asLegacyGlobalObjectForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
|
||||
|
||||
// layouts
|
||||
export * from "../../renderer/components/layout/main-layout";
|
||||
export * from "../../renderer/components/layout/setting-layout";
|
||||
@@ -36,7 +39,7 @@ export * from "../../renderer/components/switch";
|
||||
export * from "../../renderer/components/input/input";
|
||||
|
||||
// command-overlay
|
||||
export { CommandOverlay } from "../../renderer/components/command-palette";
|
||||
export const CommandOverlay = asLegacyGlobalObjectForExtensionApi(commandOverlayInjectable);
|
||||
|
||||
// other components
|
||||
export * from "../../renderer/components/icon";
|
||||
|
||||
+10
-16
@@ -18,22 +18,16 @@
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import extensionsInjectable from "./extensions.injectable";
|
||||
import type { LensRendererExtension } from "./lens-renderer-extension";
|
||||
|
||||
import { BaseRegistry } from "./base-registry";
|
||||
const rendererExtensionsInjectable = getInjectable({
|
||||
lifecycle: lifecycleEnum.singleton,
|
||||
|
||||
/**
|
||||
* WelcomeBannerRegistration is for an extension to register
|
||||
* Provide a Banner component to be renderered in the welcome screen.
|
||||
*/
|
||||
export interface WelcomeBannerRegistration {
|
||||
/**
|
||||
* The banner component to be shown on the welcome screen.
|
||||
*/
|
||||
Banner?: React.ComponentType
|
||||
/**
|
||||
* The banner width in px.
|
||||
*/
|
||||
width?: number
|
||||
}
|
||||
instantiate: (di) =>
|
||||
di.inject(extensionsInjectable) as IComputedValue<LensRendererExtension[]>,
|
||||
});
|
||||
|
||||
export class WelcomeBannerRegistry extends BaseRegistry<WelcomeBannerRegistration> { }
|
||||
export default rendererExtensionsInjectable;
|
||||
Reference in new issue
Block a user