mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix behaviour of auto generated CRD KubeApis and KubeObjectStores (#7384)
* Simplify CRD KubeApi registrations - Switch to auto injectable registrations Signed-off-by: Sebastian Malton <sebastian@malton.name> * Make sure that stores can still be retrieved Signed-off-by: Sebastian Malton <sebastian@malton.name> * Cleanup get extension fake to simplify impl Signed-off-by: Sebastian Malton <sebastian@malton.name> * Simplify logic for extensionInjectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix test in differencing registrator Signed-off-by: Sebastian Malton <sebastian@malton.name> * Cleanup code style Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix some tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix HPA details tests Signed-off-by: Sebastian Malton <sebastian@malton.name> --------- Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
8a80607d85
commit
4b1d740d61
@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { DiContainer } from "@ogre-tools/injectable";
|
import type { DiContainer } from "@ogre-tools/injectable";
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import clusterFrameContextForNamespacedResourcesInjectable from "../../../renderer/cluster-frame-context/for-namespaced-resources.injectable";
|
import clusterFrameContextForNamespacedResourcesInjectable from "../../../renderer/cluster-frame-context/for-namespaced-resources.injectable";
|
||||||
import hostedClusterInjectable from "../../../renderer/cluster-frame-context/hosted-cluster.injectable";
|
import hostedClusterInjectable from "../../../renderer/cluster-frame-context/hosted-cluster.injectable";
|
||||||
import { getDiForUnitTesting } from "../../../renderer/getDiForUnitTesting";
|
import { getDiForUnitTesting } from "../../../renderer/getDiForUnitTesting";
|
||||||
@ -21,6 +22,9 @@ import maybeKubeApiInjectable from "../maybe-kube-api.injectable";
|
|||||||
// eslint-disable-next-line no-restricted-imports
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import { KubeApi as ExternalKubeApi } from "../../../extensions/common-api/k8s-api";
|
import { KubeApi as ExternalKubeApi } from "../../../extensions/common-api/k8s-api";
|
||||||
import { Cluster } from "../../cluster/cluster";
|
import { Cluster } from "../../cluster/cluster";
|
||||||
|
import { runInAction } from "mobx";
|
||||||
|
import { customResourceDefinitionApiInjectionToken } from "../api-manager/crd-api-token";
|
||||||
|
import assert from "assert";
|
||||||
|
|
||||||
class TestApi extends KubeApi<KubeObject> {
|
class TestApi extends KubeApi<KubeObject> {
|
||||||
protected async checkPreferredVersion() {
|
protected async checkPreferredVersion() {
|
||||||
@ -117,4 +121,90 @@ describe("ApiManager", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("given than a CRD has a default KubeApi registered for it", () => {
|
||||||
|
const apiBase = "/apis/aquasecurity.github.io/v1alpha1/vulnerabilityreports";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
runInAction(() => {
|
||||||
|
di.register(getInjectable({
|
||||||
|
id: `default-kube-api-for-custom-resource-definition-${apiBase}`,
|
||||||
|
instantiate: (di) => {
|
||||||
|
const objectConstructor = class extends KubeObject {
|
||||||
|
static readonly kind = "VulnerabilityReport";
|
||||||
|
static readonly namespaced = true;
|
||||||
|
static readonly apiBase = apiBase;
|
||||||
|
};
|
||||||
|
|
||||||
|
return Object.assign(
|
||||||
|
new KubeApi({
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
maybeKubeApi: di.inject(maybeKubeApiInjectable),
|
||||||
|
}, { objectConstructor }),
|
||||||
|
{
|
||||||
|
myField: 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
injectionToken: customResourceDefinitionApiInjectionToken,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("can be retrieved from apiManager", () => {
|
||||||
|
expect(apiManager.getApi(apiBase)).toMatchObject({
|
||||||
|
myField: 1,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("can have a default KubeObjectStore instance retrieved for it", () => {
|
||||||
|
expect(apiManager.getStore(apiBase)).toBeInstanceOf(KubeObjectStore);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given that an extension registers an api with the same apibase", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
void Object.assign(new ExternalKubeApi({
|
||||||
|
objectConstructor: KubeObject,
|
||||||
|
apiBase,
|
||||||
|
kind: "VulnerabilityReport",
|
||||||
|
}), {
|
||||||
|
myField: 2,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("the extension's instance is retrievable instead from apiManager", () => {
|
||||||
|
expect(apiManager.getApi(apiBase)).toMatchObject({
|
||||||
|
myField: 2,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("can have a default KubeObjectStore instance retrieved for it", () => {
|
||||||
|
expect(apiManager.getStore(apiBase)).toBeInstanceOf(KubeObjectStore);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given that an extension registers a store for the same apibase", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const api = apiManager.getApi(apiBase);
|
||||||
|
|
||||||
|
assert(api);
|
||||||
|
|
||||||
|
apiManager.registerStore(Object.assign(
|
||||||
|
new KubeObjectStore({
|
||||||
|
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
}, api),
|
||||||
|
{
|
||||||
|
someField: 2,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("can gets the custom KubeObjectStore instance instead", () => {
|
||||||
|
expect(apiManager.getStore(apiBase)).toMatchObject({
|
||||||
|
someField: 2,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -10,7 +10,8 @@ import { autorun, action, observable } from "mobx";
|
|||||||
import type { KubeApi } from "../kube-api";
|
import type { KubeApi } from "../kube-api";
|
||||||
import type { KubeObject, ObjectReference } from "../kube-object";
|
import type { KubeObject, ObjectReference } from "../kube-object";
|
||||||
import { parseKubeApi, createKubeApiURL } from "../kube-api-parse";
|
import { parseKubeApi, createKubeApiURL } from "../kube-api-parse";
|
||||||
import { iter } from "@k8slens/utilities";
|
import { getOrInsertWith, iter } from "@k8slens/utilities";
|
||||||
|
import type { CreateCustomResourceStore } from "./create-custom-resource-store.injectable";
|
||||||
|
|
||||||
export type RegisterableStore<Store> = Store extends KubeObjectStore<any, any, any>
|
export type RegisterableStore<Store> = Store extends KubeObjectStore<any, any, any>
|
||||||
? Store
|
? Store
|
||||||
@ -26,13 +27,15 @@ export type FindApiCallback = (api: KubeApi<KubeObject>) => boolean;
|
|||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
readonly apis: IComputedValue<KubeApi[]>;
|
readonly apis: IComputedValue<KubeApi[]>;
|
||||||
|
readonly crdApis: IComputedValue<KubeApi[]>;
|
||||||
readonly stores: IComputedValue<KubeObjectStore[]>;
|
readonly stores: IComputedValue<KubeObjectStore[]>;
|
||||||
|
createCustomResourceStore: CreateCustomResourceStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ApiManager {
|
export class ApiManager {
|
||||||
private readonly externalApis = observable.array<KubeApi>();
|
private readonly externalApis = observable.array<KubeApi>();
|
||||||
private readonly externalStores = observable.array<KubeObjectStore>();
|
private readonly externalStores = observable.array<KubeObjectStore>();
|
||||||
|
private readonly defaultCrdStores = observable.map<string, KubeObjectStore>();
|
||||||
private readonly apis = observable.map<string, KubeApi>();
|
private readonly apis = observable.map<string, KubeApi>();
|
||||||
|
|
||||||
constructor(private readonly dependencies: Dependencies) {
|
constructor(private readonly dependencies: Dependencies) {
|
||||||
@ -56,6 +59,12 @@ export class ApiManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const crdApi of this.dependencies.crdApis.get()) {
|
||||||
|
if (!newState.has(crdApi.apiBase)) {
|
||||||
|
newState.set(crdApi.apiBase, crdApi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.apis.replace(newState);
|
this.apis.replace(newState);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -110,6 +119,16 @@ export class ApiManager {
|
|||||||
this.externalStores.push(store);
|
this.externalStores.push(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private apiIsDefaultCrdApi(api: KubeApi): boolean {
|
||||||
|
for (const crdApi of this.dependencies.crdApis.get()) {
|
||||||
|
if (crdApi.apiBase === api.apiBase) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
getStore(api: string | undefined): KubeObjectStore | undefined;
|
getStore(api: string | undefined): KubeObjectStore | undefined;
|
||||||
getStore<Api>(api: RegisterableApi<Api>): KubeObjectStoreFrom<Api> | undefined;
|
getStore<Api>(api: RegisterableApi<Api>): KubeObjectStoreFrom<Api> | undefined;
|
||||||
/**
|
/**
|
||||||
@ -130,9 +149,19 @@ export class ApiManager {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iter.chain(this.dependencies.stores.get().values())
|
const defaultResult = iter.chain(this.dependencies.stores.get().values())
|
||||||
.concat(this.externalStores.values())
|
.concat(this.externalStores.values())
|
||||||
.find(store => store.api.apiBase === api.apiBase);
|
.find(store => store.api.apiBase === api.apiBase);
|
||||||
|
|
||||||
|
if (defaultResult) {
|
||||||
|
return defaultResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.apiIsDefaultCrdApi(api)) {
|
||||||
|
return getOrInsertWith(this.defaultCrdStores, api.apiBase, () => this.dependencies.createCustomResourceStore(api));
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
lookupApiLink(ref: ObjectReference, parentObject?: KubeObject): string {
|
lookupApiLink(ref: ObjectReference, parentObject?: KubeObject): string {
|
||||||
|
|||||||
@ -5,11 +5,9 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import EventEmitter from "events";
|
import EventEmitter from "events";
|
||||||
import type TypedEventEmitter from "typed-emitter";
|
import type TypedEventEmitter from "typed-emitter";
|
||||||
import type { CustomResourceDefinition } from "../endpoints";
|
|
||||||
import type { KubeApi } from "../kube-api";
|
import type { KubeApi } from "../kube-api";
|
||||||
|
|
||||||
export interface LegacyAutoRegistration {
|
export interface LegacyAutoRegistration {
|
||||||
customResourceDefinition: (crd: CustomResourceDefinition) => void;
|
|
||||||
kubeApi: (api: KubeApi<any, any>) => void;
|
kubeApi: (api: KubeApi<any, any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
import type { KubeApi } from "../kube-api";
|
||||||
|
|
||||||
|
export const customResourceDefinitionApiInjectionToken = getInjectionToken<KubeApi>({
|
||||||
|
id: "custom-resource-definition-api-token",
|
||||||
|
});
|
||||||
@ -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 clusterFrameContextForNamespacedResourcesInjectable from "../../../renderer/cluster-frame-context/for-namespaced-resources.injectable";
|
||||||
|
import loggerInjectable from "../../logger.injectable";
|
||||||
|
import type { KubeApi } from "../kube-api";
|
||||||
|
import type { KubeObject } from "../kube-object";
|
||||||
|
import type { KubeObjectStoreDependencies } from "../kube-object.store";
|
||||||
|
import { CustomResourceStore } from "./resource.store";
|
||||||
|
|
||||||
|
export type CreateCustomResourceStore = <K extends KubeObject>(api: KubeApi<K>) => CustomResourceStore<K>;
|
||||||
|
|
||||||
|
const createCustomResourceStoreInjectable = getInjectable({
|
||||||
|
id: "create-custom-resource-store",
|
||||||
|
instantiate: (di): CreateCustomResourceStore => {
|
||||||
|
const deps: KubeObjectStoreDependencies = {
|
||||||
|
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
};
|
||||||
|
|
||||||
|
return (api) => new CustomResourceStore(deps, api);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default createCustomResourceStoreInjectable;
|
||||||
@ -9,6 +9,8 @@ import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-f
|
|||||||
import { kubeObjectStoreInjectionToken } from "./kube-object-store-token";
|
import { kubeObjectStoreInjectionToken } from "./kube-object-store-token";
|
||||||
import { kubeApiInjectionToken } from "../kube-api/kube-api-injection-token";
|
import { kubeApiInjectionToken } from "../kube-api/kube-api-injection-token";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
|
import { customResourceDefinitionApiInjectionToken } from "./crd-api-token";
|
||||||
|
import createCustomResourceStoreInjectable from "./create-custom-resource-store.injectable";
|
||||||
|
|
||||||
const apiManagerInjectable = getInjectable({
|
const apiManagerInjectable = getInjectable({
|
||||||
id: "api-manager",
|
id: "api-manager",
|
||||||
@ -23,6 +25,10 @@ const apiManagerInjectable = getInjectable({
|
|||||||
stores: storesAndApisCanBeCreated
|
stores: storesAndApisCanBeCreated
|
||||||
? computedInjectMany(kubeObjectStoreInjectionToken)
|
? computedInjectMany(kubeObjectStoreInjectionToken)
|
||||||
: computed(() => []),
|
: computed(() => []),
|
||||||
|
crdApis: storesAndApisCanBeCreated
|
||||||
|
? computedInjectMany(customResourceDefinitionApiInjectionToken)
|
||||||
|
: computed(() => []),
|
||||||
|
createCustomResourceStore: di.inject(createCustomResourceStoreInjectable),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -88,7 +88,7 @@ export interface KubeObjectStoreDependencies {
|
|||||||
readonly logger: Logger;
|
readonly logger: Logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class KubeObjectStore<
|
export class KubeObjectStore<
|
||||||
K extends KubeObject = KubeObject,
|
K extends KubeObject = KubeObject,
|
||||||
A extends KubeApi<K, D> = KubeApi<K, KubeJsonApiDataFor<K>>,
|
A extends KubeApi<K, D> = KubeApi<K, KubeJsonApiDataFor<K>>,
|
||||||
D extends KubeJsonApiDataFor<K> = KubeApiDataFrom<K, A>,
|
D extends KubeJsonApiDataFor<K> = KubeApiDataFrom<K, A>,
|
||||||
|
|||||||
25
packages/core/src/common/utils/registrator-helper.ts
Normal file
25
packages/core/src/common/utils/registrator-helper.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { DiContainerForInjection, Injectable } from "@ogre-tools/injectable";
|
||||||
|
|
||||||
|
// Register new injectables and deregister removed injectables by id
|
||||||
|
|
||||||
|
export const injectableDifferencingRegistratorWith = (di: DiContainerForInjection) => (
|
||||||
|
(rawCurrent: Injectable<any, any, any>[], rawPrevious: Injectable<any, any, any>[] = []) => {
|
||||||
|
const current = new Map(rawCurrent.map(inj => [inj.id, inj]));
|
||||||
|
const previous = new Map(rawPrevious.map(inj => [inj.id, inj]));
|
||||||
|
const toAdd = iter.chain(current.entries())
|
||||||
|
.filter(([id]) => !previous.has(id))
|
||||||
|
.collect(entries => new Map(entries));
|
||||||
|
const toRemove = iter.chain(previous.entries())
|
||||||
|
.filter(([id]) => !current.has(id))
|
||||||
|
.collect(entries => new Map(entries));
|
||||||
|
|
||||||
|
di.deregister(...toRemove.values());
|
||||||
|
di.register(...toAdd.values());
|
||||||
|
}
|
||||||
|
);
|
||||||
@ -2,29 +2,18 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import type { Injectable } from "@ogre-tools/injectable";
|
|
||||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||||
import { difference, find, map } from "lodash";
|
|
||||||
import { reaction, runInAction } from "mobx";
|
import { reaction, runInAction } from "mobx";
|
||||||
import { disposer } from "@k8slens/utilities";
|
import { disposer } from "@k8slens/utilities";
|
||||||
import type { LensExtension } from "../../lens-extension";
|
import type { LensExtension } from "../../lens-extension";
|
||||||
import { extensionRegistratorInjectionToken } from "../extension-registrator-injection-token";
|
import { extensionRegistratorInjectionToken } from "../extension-registrator-injection-token";
|
||||||
|
import { injectableDifferencingRegistratorWith } from "../../../common/utils/registrator-helper";
|
||||||
|
|
||||||
export interface Extension {
|
export interface Extension {
|
||||||
register: () => void;
|
register: () => void;
|
||||||
deregister: () => void;
|
deregister: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const idsToInjectables = (ids: string[], injectables: Injectable<any, any, any>[]) => ids.map(id => {
|
|
||||||
const injectable = find(injectables, { id });
|
|
||||||
|
|
||||||
if (!injectable) {
|
|
||||||
throw new Error(`Injectable ${id} not found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return injectable;
|
|
||||||
});
|
|
||||||
|
|
||||||
const extensionInjectable = getInjectable({
|
const extensionInjectable = getInjectable({
|
||||||
id: "extension",
|
id: "extension",
|
||||||
|
|
||||||
@ -35,36 +24,27 @@ const extensionInjectable = getInjectable({
|
|||||||
instantiate: (childDi) => {
|
instantiate: (childDi) => {
|
||||||
const extensionRegistrators = childDi.injectMany(extensionRegistratorInjectionToken);
|
const extensionRegistrators = childDi.injectMany(extensionRegistratorInjectionToken);
|
||||||
const reactionDisposer = disposer();
|
const reactionDisposer = disposer();
|
||||||
|
const injectableDifferencingRegistrator = injectableDifferencingRegistratorWith(childDi);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
register: () => {
|
register: () => {
|
||||||
extensionRegistrators.forEach((getInjectablesOfExtension) => {
|
for (const extensionRegistrator of extensionRegistrators) {
|
||||||
const injectables = getInjectablesOfExtension(instance);
|
const injectables = extensionRegistrator(instance);
|
||||||
|
|
||||||
reactionDisposer.push(
|
if (Array.isArray(injectables)) {
|
||||||
// injectables is either an array or a computed array, in which case
|
runInAction(() => {
|
||||||
// we need to update the registered injectables with a reaction every time they change
|
injectableDifferencingRegistrator(injectables);
|
||||||
reaction(
|
});
|
||||||
() => Array.isArray(injectables) ? injectables : injectables.get(),
|
} else {
|
||||||
(currentInjectables, previousInjectables = []) => {
|
reactionDisposer.push(reaction(
|
||||||
// Register new injectables and deregister removed injectables by id
|
() => injectables.get(),
|
||||||
const currentIds = map(currentInjectables, "id");
|
injectableDifferencingRegistrator,
|
||||||
const previousIds = map(previousInjectables, "id");
|
{
|
||||||
const idsToAdd = difference(currentIds, previousIds);
|
|
||||||
const idsToRemove = previousIds.filter(previousId => !currentIds.includes(previousId));
|
|
||||||
|
|
||||||
if (idsToRemove.length > 0) {
|
|
||||||
childDi.deregister(...idsToInjectables(idsToRemove, previousInjectables));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idsToAdd.length > 0) {
|
|
||||||
childDi.register(...idsToInjectables(idsToAdd, currentInjectables));
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
fireImmediately: true,
|
fireImmediately: true,
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
});
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
deregister: () => {
|
deregister: () => {
|
||||||
|
|||||||
@ -31,8 +31,7 @@ describe("extension special characters in page registrations", () => {
|
|||||||
|
|
||||||
describe("when navigating to route with ID having special characters", () => {
|
describe("when navigating to route with ID having special characters", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const testExtension =
|
const testExtension = builder.extensions.get("some-extension-id").applicationWindows.only;
|
||||||
builder.extensions.get("some-extension-id").applicationWindows.only;
|
|
||||||
|
|
||||||
testExtension.navigate("/some-page-id/");
|
testExtension.navigate("/some-page-id/");
|
||||||
});
|
});
|
||||||
|
|||||||
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* 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 { reaction } from "mobx";
|
||||||
|
import { customResourceDefinitionApiInjectionToken } from "../../../common/k8s-api/api-manager/crd-api-token";
|
||||||
|
import type { CustomResourceDefinition } from "../../../common/k8s-api/endpoints";
|
||||||
|
import { KubeApi } from "../../../common/k8s-api/kube-api";
|
||||||
|
import { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
|
import maybeKubeApiInjectable from "../../../common/k8s-api/maybe-kube-api.injectable";
|
||||||
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
|
import { injectableDifferencingRegistratorWith } from "../../../common/utils/registrator-helper";
|
||||||
|
import customResourceDefinitionStoreInjectable from "../../components/+custom-resources/definition.store.injectable";
|
||||||
|
import { beforeClusterFrameStartsSecondInjectionToken } from "../tokens";
|
||||||
|
|
||||||
|
const setupAutoCrdApiCreationsInjectable = getInjectable({
|
||||||
|
id: "setup-auto-crd-api-creations",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
run: () => {
|
||||||
|
const customResourceDefinitionStore = di.inject(customResourceDefinitionStoreInjectable);
|
||||||
|
const injectableDifferencingRegistrator = injectableDifferencingRegistratorWith(di);
|
||||||
|
|
||||||
|
reaction(
|
||||||
|
() => customResourceDefinitionStore.getItems().map(toCrdApiInjectable),
|
||||||
|
injectableDifferencingRegistrator,
|
||||||
|
{
|
||||||
|
fireImmediately: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
injectionToken: beforeClusterFrameStartsSecondInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default setupAutoCrdApiCreationsInjectable;
|
||||||
|
|
||||||
|
const toCrdApiInjectable = (crd: CustomResourceDefinition) => getInjectable({
|
||||||
|
id: `default-kube-api-for-custom-resource-definition-${crd.getResourceApiBase()}`,
|
||||||
|
instantiate: (di) => {
|
||||||
|
const objectConstructor = class extends KubeObject {
|
||||||
|
static readonly kind = crd.getResourceKind();
|
||||||
|
static readonly namespaced = crd.isNamespaced();
|
||||||
|
static readonly apiBase = crd.getResourceApiBase();
|
||||||
|
};
|
||||||
|
|
||||||
|
return new KubeApi({
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
maybeKubeApi: di.inject(maybeKubeApiInjectable),
|
||||||
|
}, { objectConstructor });
|
||||||
|
},
|
||||||
|
injectionToken: customResourceDefinitionApiInjectionToken,
|
||||||
|
});
|
||||||
@ -5,71 +5,22 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import autoRegistrationEmitterInjectable from "../../../common/k8s-api/api-manager/auto-registration-emitter.injectable";
|
import autoRegistrationEmitterInjectable from "../../../common/k8s-api/api-manager/auto-registration-emitter.injectable";
|
||||||
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
||||||
import { CustomResourceStore } from "../../../common/k8s-api/api-manager/resource.store";
|
import type { KubeApi } from "../../../common/k8s-api/kube-api";
|
||||||
import type { CustomResourceDefinition } from "../../../common/k8s-api/endpoints";
|
|
||||||
import type { KubeApiDependencies } from "../../../common/k8s-api/kube-api";
|
|
||||||
import { KubeApi } from "../../../common/k8s-api/kube-api";
|
|
||||||
import { KubeObject } from "../../../common/k8s-api/kube-object";
|
|
||||||
import { beforeClusterFrameStartsSecondInjectionToken } from "../tokens";
|
import { beforeClusterFrameStartsSecondInjectionToken } from "../tokens";
|
||||||
import type { KubeObjectStoreDependencies } from "../../../common/k8s-api/kube-object.store";
|
|
||||||
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
|
|
||||||
import loggerInjectable from "../../../common/logger.injectable";
|
|
||||||
import maybeKubeApiInjectable from "../../../common/k8s-api/maybe-kube-api.injectable";
|
|
||||||
|
|
||||||
const setupAutoRegistrationInjectable = getInjectable({
|
const setupAutoRegistrationInjectable = getInjectable({
|
||||||
id: "setup-auto-registration",
|
id: "setup-auto-registration",
|
||||||
instantiate: (di) => ({
|
instantiate: (di) => ({
|
||||||
run: () => {
|
run: () => {
|
||||||
const autoRegistrationEmitter = di.inject(autoRegistrationEmitterInjectable);
|
const autoRegistrationEmitter = di.inject(autoRegistrationEmitterInjectable);
|
||||||
const beforeApiManagerInitializationCrds: CustomResourceDefinition[] = [];
|
|
||||||
const beforeApiManagerInitializationApis: KubeApi[] = [];
|
const beforeApiManagerInitializationApis: KubeApi[] = [];
|
||||||
const kubeApiDependencies: KubeApiDependencies = {
|
|
||||||
logger: di.inject(loggerInjectable),
|
|
||||||
maybeKubeApi: di.inject(maybeKubeApiInjectable),
|
|
||||||
};
|
|
||||||
const kubeObjectStoreDependencies: KubeObjectStoreDependencies = {
|
|
||||||
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
|
|
||||||
logger: di.inject(loggerInjectable),
|
|
||||||
};
|
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
|
|
||||||
const autoInitCustomResourceStore = (crd: CustomResourceDefinition) => {
|
|
||||||
const objectConstructor = class extends KubeObject {
|
|
||||||
static readonly kind = crd.getResourceKind();
|
|
||||||
static readonly namespaced = crd.isNamespaced();
|
|
||||||
static readonly apiBase = crd.getResourceApiBase();
|
|
||||||
};
|
|
||||||
|
|
||||||
const api = (() => {
|
|
||||||
const rawApi = apiManager.getApi(objectConstructor.apiBase);
|
|
||||||
|
|
||||||
if (rawApi) {
|
|
||||||
return rawApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
const api = new KubeApi(kubeApiDependencies, { objectConstructor });
|
|
||||||
|
|
||||||
apiManager.registerApi(api);
|
|
||||||
|
|
||||||
return api;
|
|
||||||
})();
|
|
||||||
|
|
||||||
if (!apiManager.getStore(api)) {
|
|
||||||
apiManager.registerStore(new CustomResourceStore(kubeObjectStoreDependencies, api));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const autoInitKubeApi = (api: KubeApi) => {
|
const autoInitKubeApi = (api: KubeApi) => {
|
||||||
apiManager.registerApi(api);
|
apiManager.registerApi(api);
|
||||||
};
|
};
|
||||||
|
|
||||||
autoRegistrationEmitter
|
autoRegistrationEmitter
|
||||||
.on("customResourceDefinition", (crd) => {
|
|
||||||
if (initialized) {
|
|
||||||
autoInitCustomResourceStore(crd);
|
|
||||||
} else {
|
|
||||||
beforeApiManagerInitializationCrds.push(crd);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on("kubeApi", (api) => {
|
.on("kubeApi", (api) => {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
autoInitKubeApi(api);
|
autoInitKubeApi(api);
|
||||||
@ -81,7 +32,6 @@ const setupAutoRegistrationInjectable = getInjectable({
|
|||||||
// NOTE: this MUST happen after the event emitter listeners are registered
|
// NOTE: this MUST happen after the event emitter listeners are registered
|
||||||
const apiManager = di.inject(apiManagerInjectable);
|
const apiManager = di.inject(apiManagerInjectable);
|
||||||
|
|
||||||
beforeApiManagerInitializationCrds.forEach(autoInitCustomResourceStore);
|
|
||||||
beforeApiManagerInitializationApis.forEach(autoInitKubeApi);
|
beforeApiManagerInitializationApis.forEach(autoInitKubeApi);
|
||||||
initialized = true;
|
initialized = true;
|
||||||
},
|
},
|
||||||
|
|||||||
@ -4,8 +4,13 @@
|
|||||||
*/
|
*/
|
||||||
import type { RenderResult } from "@testing-library/react";
|
import type { RenderResult } from "@testing-library/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
|
||||||
|
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
|
import { Cluster } from "../../../common/cluster/cluster";
|
||||||
import { HorizontalPodAutoscaler, HpaMetricType } from "../../../common/k8s-api/endpoints";
|
import { HorizontalPodAutoscaler, HpaMetricType } from "../../../common/k8s-api/endpoints";
|
||||||
|
import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable";
|
||||||
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
|
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
|
||||||
|
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
|
||||||
import type { DiRender } from "../test-utils/renderFor";
|
import type { DiRender } from "../test-utils/renderFor";
|
||||||
import { renderFor } from "../test-utils/renderFor";
|
import { renderFor } from "../test-utils/renderFor";
|
||||||
import { HpaDetails } from "./hpa-details";
|
import { HpaDetails } from "./hpa-details";
|
||||||
@ -41,6 +46,17 @@ describe("<HpaDetails/>", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const di = getDiForUnitTesting();
|
const di = getDiForUnitTesting();
|
||||||
|
|
||||||
|
di.override(directoryForUserDataInjectable, () => "/some-user-store-path");
|
||||||
|
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
|
||||||
|
di.override(storesAndApisCanBeCreatedInjectable, () => true);
|
||||||
|
di.override(hostedClusterInjectable, () => new Cluster({
|
||||||
|
contextName: "some-context-name",
|
||||||
|
id: "some-cluster-id",
|
||||||
|
kubeConfigPath: "/some-path-to-a-kubeconfig",
|
||||||
|
}, {
|
||||||
|
clusterServerUrl: "https://localhost:8080",
|
||||||
|
}));
|
||||||
|
|
||||||
render = renderFor(di);
|
render = renderFor(di);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import autoRegistrationEmitterInjectable from "../../../common/k8s-api/api-manager/auto-registration-emitter.injectable";
|
|
||||||
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token";
|
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token";
|
||||||
import customResourceDefinitionApiInjectable from "../../../common/k8s-api/endpoints/custom-resource-definition.api.injectable";
|
import customResourceDefinitionApiInjectable from "../../../common/k8s-api/endpoints/custom-resource-definition.api.injectable";
|
||||||
import loggerInjectable from "../../../common/logger.injectable";
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
@ -20,7 +19,6 @@ const customResourceDefinitionStoreInjectable = getInjectable({
|
|||||||
const api = di.inject(customResourceDefinitionApiInjectable);
|
const api = di.inject(customResourceDefinitionApiInjectable);
|
||||||
|
|
||||||
return new CustomResourceDefinitionStore({
|
return new CustomResourceDefinitionStore({
|
||||||
autoRegistration: di.inject(autoRegistrationEmitterInjectable),
|
|
||||||
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
|
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
|
||||||
logger: di.inject(loggerInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
}, api);
|
}, api);
|
||||||
|
|||||||
@ -3,37 +3,22 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { computed, reaction, makeObservable } from "mobx";
|
import { computed, makeObservable } from "mobx";
|
||||||
import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store";
|
import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store";
|
||||||
import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store";
|
import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store";
|
||||||
import type { CustomResourceDefinition, CustomResourceDefinitionApi } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
|
import type { CustomResourceDefinition, CustomResourceDefinitionApi } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
|
||||||
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
import type TypedEventEmitter from "typed-emitter";
|
|
||||||
import type { LegacyAutoRegistration } from "../../../common/k8s-api/api-manager/auto-registration-emitter.injectable";
|
|
||||||
import autoBind from "auto-bind";
|
import autoBind from "auto-bind";
|
||||||
|
|
||||||
export interface CustomResourceDefinitionStoreDependencies extends KubeObjectStoreDependencies {
|
|
||||||
readonly autoRegistration: TypedEventEmitter<LegacyAutoRegistration>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CustomResourceDefinitionStore extends KubeObjectStore<CustomResourceDefinition, CustomResourceDefinitionApi> {
|
export class CustomResourceDefinitionStore extends KubeObjectStore<CustomResourceDefinition, CustomResourceDefinitionApi> {
|
||||||
constructor(
|
constructor(
|
||||||
protected readonly dependencies: CustomResourceDefinitionStoreDependencies,
|
dependencies: KubeObjectStoreDependencies,
|
||||||
api: CustomResourceDefinitionApi,
|
api: CustomResourceDefinitionApi,
|
||||||
opts?: KubeObjectStoreOptions,
|
opts?: KubeObjectStoreOptions,
|
||||||
) {
|
) {
|
||||||
super(dependencies, api, opts);
|
super(dependencies, api, opts);
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
autoBind(this);
|
autoBind(this);
|
||||||
|
|
||||||
reaction(
|
|
||||||
() => this.getItems(),
|
|
||||||
crds => {
|
|
||||||
for (const crd of crds) {
|
|
||||||
this.dependencies.autoRegistration.emit("customResourceDefinition", crd);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected sortItems(items: CustomResourceDefinition[]) {
|
protected sortItems(items: CustomResourceDefinition[]) {
|
||||||
|
|||||||
@ -53,7 +53,7 @@ import { applicationWindowInjectionToken } from "../../../main/start-main-applic
|
|||||||
import closeAllWindowsInjectable from "../../../main/start-main-application/lens-window/hide-all-windows/close-all-windows.injectable";
|
import closeAllWindowsInjectable from "../../../main/start-main-application/lens-window/hide-all-windows/close-all-windows.injectable";
|
||||||
import type { LensWindow } from "../../../main/start-main-application/lens-window/application-window/create-lens-window.injectable";
|
import type { LensWindow } from "../../../main/start-main-application/lens-window/application-window/create-lens-window.injectable";
|
||||||
import type { FakeExtensionOptions } from "./get-extension-fake";
|
import type { FakeExtensionOptions } from "./get-extension-fake";
|
||||||
import { getExtensionFakeForMain, getExtensionFakeForRenderer } from "./get-extension-fake";
|
import { getMainExtensionFakeWith, getRendererExtensionFakeWith } from "./get-extension-fake";
|
||||||
import namespaceApiInjectable from "../../../common/k8s-api/endpoints/namespace.api.injectable";
|
import namespaceApiInjectable from "../../../common/k8s-api/endpoints/namespace.api.injectable";
|
||||||
import { Namespace } from "../../../common/k8s-api/endpoints";
|
import { Namespace } from "../../../common/k8s-api/endpoints";
|
||||||
import { getOverrideFsWithFakes } from "../../../test-utils/override-fs-with-fakes";
|
import { getOverrideFsWithFakes } from "../../../test-utils/override-fs-with-fakes";
|
||||||
@ -594,49 +594,28 @@ export const getApplicationBuilder = () => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
enable: (...extensions) => {
|
enable: (...extensions) => {
|
||||||
builder.afterWindowStart(({ windowDi }) => {
|
builder.afterWindowStart(action(({ windowDi }) => {
|
||||||
const rendererExtensionInstances = extensions.map((options) =>
|
extensions
|
||||||
getExtensionFakeForRenderer(
|
.map(getRendererExtensionFakeWith(windowDi))
|
||||||
windowDi,
|
.forEach(enableExtensionFor(windowDi, rendererExtensionsStateInjectable));
|
||||||
options.id,
|
}));
|
||||||
options.name,
|
|
||||||
options.rendererOptions || {},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
rendererExtensionInstances.forEach(
|
builder.afterApplicationStart(action(({ mainDi }) => {
|
||||||
enableExtensionFor(windowDi, rendererExtensionsStateInjectable),
|
extensions
|
||||||
);
|
.map(getMainExtensionFakeWith(mainDi))
|
||||||
});
|
.forEach(enableExtensionFor(mainDi, mainExtensionsStateInjectable));
|
||||||
|
}));
|
||||||
builder.afterApplicationStart(({ mainDi }) => {
|
|
||||||
const mainExtensionInstances = extensions.map((extension) =>
|
|
||||||
getExtensionFakeForMain(mainDi, extension.id, extension.name, extension.mainOptions || {}),
|
|
||||||
);
|
|
||||||
|
|
||||||
runInAction(() => {
|
|
||||||
mainExtensionInstances.forEach(
|
|
||||||
enableExtensionFor(mainDi, mainExtensionsStateInjectable),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
disable: (...extensions) => {
|
disable: (...extensions) => {
|
||||||
builder.afterWindowStart(({ windowDi }) => {
|
builder.afterWindowStart(({ windowDi }) => {
|
||||||
extensions
|
extensions
|
||||||
.map((ext) => ext.id)
|
.forEach(disableExtensionFor(windowDi, rendererExtensionsStateInjectable));
|
||||||
.forEach(
|
|
||||||
disableExtensionFor(windowDi, rendererExtensionsStateInjectable),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.afterApplicationStart(({ mainDi }) => {
|
builder.afterApplicationStart(({ mainDi }) => {
|
||||||
extensions
|
extensions
|
||||||
.map((ext) => ext.id)
|
.forEach(disableExtensionFor(mainDi, mainExtensionsStateInjectable));
|
||||||
.forEach(
|
|
||||||
disableExtensionFor(mainDi, mainExtensionsStateInjectable),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -835,49 +814,29 @@ const selectOptionFor = (builder: ApplicationBuilder, menuId: string) => (labelT
|
|||||||
userEvent.click(option);
|
userEvent.click(option);
|
||||||
};
|
};
|
||||||
|
|
||||||
const enableExtensionFor = (
|
function enableExtensionFor(di: DiContainer, stateInjectable: Injectable<ObservableMap<string, any>, any, any>) {
|
||||||
di: DiContainer,
|
|
||||||
stateInjectable: Injectable<ObservableMap<string, any>, any, any>,
|
|
||||||
) => {
|
|
||||||
const extensionState = di.inject(stateInjectable);
|
const extensionState = di.inject(stateInjectable);
|
||||||
|
|
||||||
const getExtension = (extension: LensExtension) =>
|
return (instance: LensExtension) => {
|
||||||
di.inject(extensionInjectable, extension);
|
const extension = di.inject(extensionInjectable, instance);
|
||||||
|
|
||||||
return (extensionInstance: LensExtension) => {
|
|
||||||
const extension = getExtension(extensionInstance);
|
|
||||||
|
|
||||||
runInAction(() => {
|
|
||||||
extension.register();
|
extension.register();
|
||||||
extensionState.set(extensionInstance.id, extensionInstance);
|
extensionState.set(instance.id, instance);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
const disableExtensionFor =
|
|
||||||
(
|
|
||||||
di: DiContainer,
|
|
||||||
stateInjectable: Injectable<ObservableMap<string, any>, unknown, void>,
|
|
||||||
) =>
|
|
||||||
(id: string) => {
|
|
||||||
const getExtension = (extension: LensExtension) =>
|
|
||||||
di.inject(extensionInjectable, extension);
|
|
||||||
|
|
||||||
|
function disableExtensionFor(di: DiContainer, stateInjectable: Injectable<ObservableMap<string, any>, unknown, void>) {
|
||||||
|
return (extension: FakeExtensionOptions) => {
|
||||||
const extensionsState = di.inject(stateInjectable);
|
const extensionsState = di.inject(stateInjectable);
|
||||||
|
const instance = extensionsState.get(extension.id);
|
||||||
const instance = extensionsState.get(id);
|
|
||||||
|
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
throw new Error(
|
throw new Error(`Tried to disable extension with ID "${extension.id}", but it wasn't enabled`);
|
||||||
`Tried to disable extension with ID "${id}", but it wasn't enabled`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const injectable = getExtension(instance);
|
const injectable = di.inject(extensionInjectable, instance);
|
||||||
|
|
||||||
runInAction(() => {
|
|
||||||
injectable.deregister();
|
injectable.deregister();
|
||||||
|
extensionsState.delete(extension.id);
|
||||||
extensionsState.delete(id);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export interface FakeExtensionOptions {
|
|||||||
mainOptions?: Partial<LensMainExtension>;
|
mainOptions?: Partial<LensMainExtension>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getExtensionFakeForMain = (di: DiContainer, id: string, name: string, options: Partial<LensMainExtension>) => {
|
export const getMainExtensionFakeWith = (di: DiContainer) => ({ id, name, mainOptions = {}}: FakeExtensionOptions) => {
|
||||||
const instance = new TestExtensionMain({
|
const instance = new TestExtensionMain({
|
||||||
id,
|
id,
|
||||||
absolutePath: "irrelevant",
|
absolutePath: "irrelevant",
|
||||||
@ -44,7 +44,7 @@ export const getExtensionFakeForMain = (di: DiContainer, id: string, name: strin
|
|||||||
manifestPath: "irrelevant",
|
manifestPath: "irrelevant",
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.assign(instance, options);
|
Object.assign(instance, mainOptions);
|
||||||
|
|
||||||
(instance as Writable<LensMainExtension>)[lensExtensionDependencies] = {
|
(instance as Writable<LensMainExtension>)[lensExtensionDependencies] = {
|
||||||
fileSystemProvisionerStore: di.inject(fileSystemProvisionerStoreInjectable),
|
fileSystemProvisionerStore: di.inject(fileSystemProvisionerStoreInjectable),
|
||||||
@ -56,7 +56,7 @@ export const getExtensionFakeForMain = (di: DiContainer, id: string, name: strin
|
|||||||
return instance;
|
return instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getExtensionFakeForRenderer = (di: DiContainer, id: string, name: string, options: Partial<LensRendererExtension>) => {
|
export const getRendererExtensionFakeWith = (di: DiContainer) => ({ id, name, rendererOptions = {}}: FakeExtensionOptions) => {
|
||||||
const instance = new TestExtensionRenderer({
|
const instance = new TestExtensionRenderer({
|
||||||
id,
|
id,
|
||||||
absolutePath: "irrelevant",
|
absolutePath: "irrelevant",
|
||||||
@ -73,7 +73,7 @@ export const getExtensionFakeForRenderer = (di: DiContainer, id: string, name: s
|
|||||||
manifestPath: "irrelevant",
|
manifestPath: "irrelevant",
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.assign(instance, options);
|
Object.assign(instance, rendererOptions);
|
||||||
|
|
||||||
(instance as Writable<LensRendererExtension>)[lensExtensionDependencies] = {
|
(instance as Writable<LensRendererExtension>)[lensExtensionDependencies] = {
|
||||||
categoryRegistry: di.inject(catalogCategoryRegistryInjectable),
|
categoryRegistry: di.inject(catalogCategoryRegistryInjectable),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user