1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Ensure that all mentioned items in extension API are exported

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-02-28 08:34:45 -05:00
parent 1077a949ec
commit 33de7cf7e9
118 changed files with 1761 additions and 894 deletions

View File

@ -1,12 +1,12 @@
name: Check Documentation
on:
pull_request:
types: [opened, labeled, unlabeled, synchronize]
branches:
- "**"
jobs:
build:
name: Check Docs
runs-on: ubuntu-latest
if: ${{ contains(github.event.pull_request.labels.*.name, 'area/documentation') }}
strategy:
matrix:
node-version: [14.x]

View File

@ -41,6 +41,7 @@
"lint:fix": "yarn run lint --fix",
"mkdocs-serve-local": "docker build -t mkdocs-serve-local:latest mkdocs/ && docker run --rm -it -p 8000:8000 -v ${PWD}:/docs mkdocs-serve-local:latest",
"verify-docs": "docker build -t mkdocs-serve-local:latest mkdocs/ && docker run --rm -v ${PWD}:/docs mkdocs-serve-local:latest build --strict",
"preverify-docs": "yarn run typedocs-extensions-api",
"typedocs-extensions-api": "yarn run typedoc src/extensions/extension-api.ts",
"version-checkout": "cat package.json | jq '.version' -r | xargs printf \"release/v%s\" | xargs git checkout -b",
"version-commit": "cat package.json | jq '.version' -r | xargs printf \"release v%s\" | git commit --no-edit -s -F -",

View File

@ -7,7 +7,7 @@ import { navigate } from "../../renderer/navigation";
import { CatalogCategory, CatalogEntity, CatalogEntityMetadata, CatalogEntitySpec, CatalogEntityStatus } from "../catalog";
import { catalogCategoryRegistry } from "../catalog/catalog-category-registry";
interface GeneralEntitySpec extends CatalogEntitySpec {
export interface GeneralEntitySpec extends CatalogEntitySpec {
path: string;
icon?: {
material?: string;

View File

@ -130,10 +130,14 @@ export class KubernetesCluster<
catalogCategoryRegistry
.getCategoryForEntity<KubernetesClusterCategory>(this)
?.emit("contextMenuOpen", this, context);
.emit("contextMenuOpen", this, context);
}
}
/**
* The category for {@link KubernetesCluster}'s. Not constructable, use
* {@link kubernetesClusterCategory} to register event handlers.
*/
class KubernetesClusterCategory extends CatalogCategory {
public readonly apiVersion = "catalog.k8slens.dev/v1alpha1";
public readonly kind = "CatalogCategory";
@ -155,6 +159,7 @@ class KubernetesClusterCategory extends CatalogCategory {
};
}
export type { KubernetesClusterCategory };
export const kubernetesClusterCategory = new KubernetesClusterCategory();
catalogCategoryRegistry.add(kubernetesClusterCategory);

View File

@ -4,16 +4,29 @@
*/
import { action, computed, observable, makeObservable } from "mobx";
import { type Disposer, strictSet, iter, getOrInsertMap } from "../utils";
import { CatalogCategory, CatalogEntity, CatalogEntityData, CatalogEntityKindData } from "./catalog-entity";
import { once } from "lodash";
import { iter, getOrInsertMap, strictSet } from "../utils";
import type { Disposer } from "../utils";
import { CatalogCategory, CatalogEntityData, CatalogEntityKindData } from "./catalog-entity";
export type CategoryFilter = (category: CatalogCategory) => any;
/**
* The registry of declared categories in the renderer
*/
export class CatalogCategoryRegistry {
/**
* @internal
*/
protected categories = observable.set<CatalogCategory>();
/**
* @internal
*/
protected groupKinds = new Map<string, Map<string, CatalogCategory>>();
/**
* @internal
*/
protected filters = observable.set<CategoryFilter>([], {
deep: false,
});
@ -22,6 +35,12 @@ export class CatalogCategoryRegistry {
makeObservable(this);
}
/**
* Attempt to add a new category to the registry.
* @param category The category instance to add
* @returns A function to deregister the instance
* @throws If there already exists a previous category that declared as specific group and kind
*/
@action add(category: CatalogCategory): Disposer {
const byGroup = getOrInsertMap(this.groupKinds, category.spec.group);
@ -34,10 +53,16 @@ export class CatalogCategoryRegistry {
};
}
/**
* Get a list of all the categories that are currently registered
*/
@computed get items() {
return Array.from(this.categories);
}
/**
* Get a list of all the categories that match all the registered filters
*/
@computed get filteredItems() {
return Array.from(
iter.reduce(
@ -48,12 +73,22 @@ export class CatalogCategoryRegistry {
);
}
/**
* Attempt to get a category but the api group and kind it declared
* @param group The group string of the desired category
* @param kind The name that a category declares
*/
getForGroupKind<T extends CatalogCategory>(group: string, kind: string): T | undefined {
return this.groupKinds.get(group)?.get(kind) as T;
}
getEntityForData(data: CatalogEntityData & CatalogEntityKindData) {
/**
* Create a new entity instance from `data` or return `null` if cannot find category
* @param data The data to create the instance from
* @param data.apiVersion Used to find the category by group and version
* @param data.kind Used to find the category for a specific kind
*/
getEntityForData(data: CatalogEntityData & CatalogEntityKindData): CatalogEntity | null {
const category = this.getCategoryForEntity(data);
if (!category) {
@ -72,14 +107,24 @@ export class CatalogCategoryRegistry {
return new specVersion.entityClass(data);
}
getCategoryForEntity<T extends CatalogCategory>(data: CatalogEntityData & CatalogEntityKindData): T | undefined {
/**
* Try and find a category by its version declarations
* @param data The `apiVersion` and `kind` that was declared by a category
* @returns The category instance if found
*/
getCategoryForEntity<T extends CatalogCategory>(data: CatalogEntityKindData): T | undefined {
const splitApiVersion = data.apiVersion.split("/");
const group = splitApiVersion[0];
return this.getForGroupKind(group, data.kind);
}
getByName(name: string) {
/**
* Try and find a category by the name is was registered with
* @param name The name of the category
* @returns The category instance if found
*/
getByName(name: string): CatalogCategory | undefined {
return this.items.find(category => category.metadata?.name == name);
}

View File

@ -10,9 +10,9 @@ import { once } from "lodash";
import { iter, Disposer } from "../utils";
import type { CategoryColumnRegistration } from "../../renderer/components/+catalog/custom-category-columns";
type ExtractEntityMetadataType<Entity> = Entity extends CatalogEntity<infer Metadata> ? Metadata : never;
type ExtractEntityStatusType<Entity> = Entity extends CatalogEntity<any, infer Status> ? Status : never;
type ExtractEntitySpecType<Entity> = Entity extends CatalogEntity<any, any, infer Spec> ? Spec : never;
export type ExtractEntityMetadataType<Entity> = Entity extends CatalogEntity<infer Metadata> ? Metadata : never;
export type ExtractEntityStatusType<Entity> = Entity extends CatalogEntity<any, infer Status> ? Status : never;
export type ExtractEntitySpecType<Entity> = Entity extends CatalogEntity<any, any, infer Spec> ? Spec : never;
export type CatalogEntityConstructor<Entity extends CatalogEntity> = (
(new (data: CatalogEntityData<
@ -88,26 +88,35 @@ export interface CatalogCategorySpec {
*/
export type AddMenuFilter = (menu: CatalogEntityAddMenu) => any;
/**
* The events that can be emitted onto a catalog category
*/
export interface CatalogCategoryEvents {
/**
* This event will be emitted when the category is loaded in the catalog
* An event which is emitted when the category becomes active on the catalog
* view.
*/
load: () => void;
/**
* This event will be emitted when the catalog add menu is opened and is the
* way to added entries to that menu.
* An event which is emitted when the menu for adding new catalog entities
* is opened.
* @param context The event context
*/
catalogAddMenu: (context: CatalogEntityAddMenuContext) => void;
/**
* This event will be emitted when the context menu for an entity is declared
* by this category is opened.
* An event which is emitted when the context menu on a entity versioned by
* this category is opened.
* @param entity The entity that was opened
* @param context The event context
*/
contextMenuOpen: (entity: CatalogEntity, context: CatalogEntityContextMenuContext) => void;
}
/**
* A declartion of supported versions a specific kind of CatalogEntity
*/
export abstract class CatalogCategory extends (EventEmitter as new () => TypedEmitter<CatalogCategoryEvents>) {
/**
* The version of category that you are wanting to declare.
@ -210,6 +219,9 @@ export interface CatalogEntityMetadata {
[key: string]: string | object;
}
/**
* The minimal information that all entities must use to describe their current status
*/
export interface CatalogEntityStatus {
phase: string;
reason?: string;
@ -222,59 +234,104 @@ export interface CatalogEntityStatus {
active?: boolean;
}
/**
* The event context for when an entity is activated
*/
export interface CatalogEntityActionContext {
navigate: (url: string) => void;
setCommandPaletteContext: (context?: CatalogEntity) => void;
/**
* A function to navigate around the application
* @param pathname The path to navigate to
*/
navigate: (pathname: string) => void;
/**
* A function to change the active entity for the command palette
*/
setCommandPaletteContext: (entity?: CatalogEntity) => void;
}
/**
* The descriptor for entities' context menus and detail panels' topbars
*/
export interface CatalogEntityContextMenu {
/**
* Menu title
* When in a context menu, the text displayed
*/
title: string;
/**
* Menu icon
* When in a toolbar the icon's material or svg data
*
* If not present then this item will not be displayed in the toolbar
*/
icon?: string;
/**
* OnClick handler
* The function that will be called when the menu item is clicked
*/
onClick: () => void | Promise<void>;
/**
* Confirm click with a message
* If present then a confirmation dialog will be displayed to the user with
* the given message before the `onClick` handler is called.
*/
confirm?: {
message: string;
};
}
/**
* The context type for the add menu event in the catalog view
*/
export interface CatalogEntityAddMenu extends CatalogEntityContextMenu {
/**
* The icon's material or svg data for the menu item.
*/
icon: string;
/**
* If this menu item should be the default action. If multiple items are
* declared as the default one then none are executed.
*/
defaultAction?: boolean;
}
export interface CatalogEntitySettingsMenu {
group?: string;
title: string;
components: {
View: React.ComponentType<any>;
};
}
/**
* The context type for entity context menus and drawer detail topbar menus
*/
export interface CatalogEntityContextMenuContext {
/**
* Navigate to the specified pathname
* A function to navigate around the application
* @param pathname The path to navigate to
*/
navigate: (pathname: string) => void;
/**
* The output array of items
*/
menuItems: CatalogEntityContextMenu[];
}
/**
* @deprecated Not used
*/
export interface CatalogEntitySettingsContext {
/**
* The output array of items
*/
menuItems: CatalogEntityContextMenu[];
}
export interface CatalogEntityAddMenuContext {
/**
* A function to navigate around the application
* @param pathname The path to navigate to
*/
navigate: (url: string) => void;
/**
* The output array of items
*/
menuItems: CatalogEntityAddMenu[];
}
@ -336,14 +393,14 @@ export abstract class CatalogEntity<
}
/**
* Get the UID of this entity
* A convenience function for getting the entity ID
*/
public getId(): string {
return this.metadata.uid;
}
/**
* Get the name of this entity
* A convenience function for getting the entity name
*/
public getName(): string {
return this.metadata.name;
@ -364,7 +421,18 @@ export abstract class CatalogEntity<
return this.status.enabled ?? true;
}
/**
* The function that will be called when the entity is activated
*/
public abstract onRun?(context: CatalogEntityActionContext): void | Promise<void>;
public abstract onContextMenuOpen(context: CatalogEntityContextMenuContext): void | Promise<void>;
public abstract onSettingsOpen(context: CatalogEntitySettingsContext): void | Promise<void>;
/**
* The function that is called when the context menu is opened for a specific entity
*/
public abstract onContextMenuOpen?(context: CatalogEntityContextMenuContext): void | Promise<void>;
/**
* @deprecated This is not used. Use the `RenderExtension.entitySettings` field instead
*/
public abstract onSettingsOpen?(context: CatalogEntitySettingsContext): void | Promise<void>;
}

View File

@ -3,32 +3,75 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
// Custom event emitter
/**
* The options for when adding a new listener
*/
export interface AddListenerOptions {
/**
* Should the listener only ever receive one event.
*
* @default false
*/
once?: boolean;
interface Options {
once?: boolean; // call once and remove
prepend?: boolean; // put listener to the beginning
/**
* If `true` then the listener will be put to the front of the event queue
*
* @default false
*/
prepend?: boolean;
}
type Callback<D extends [...any[]]> = (...data: D) => void | boolean;
/**
* A function for handling events. If the function returns `false` then no
* further listeners will be called for that event.
*/
export type EventListener<D extends any[]> = (...data: D) => void | boolean;
export class EventEmitter<D extends [...any[]]> {
protected listeners: [Callback<D>, Options][] = [];
/**
* An event emitter for a single event. Generic over the arguments for the
* event handler.
*/
export class EventEmitter<D extends any[]> {
protected listeners = new Map<EventListener<D>, Required<Omit<AddListenerOptions, "prepend">>>();
addListener(callback: Callback<D>, options: Options = {}) {
const fn = options.prepend ? "unshift" : "push";
/**
* Add a new listener for this event emitter
* @param callback The function to call when an event is emitted.
* @param options Options for controlling how the listener is handled.
*/
addListener(callback: EventListener<D>, options?: AddListenerOptions) {
const { prepend, once = false } = options ?? {};
this.listeners[fn]([callback, options]);
if (prepend) {
this.listeners = new Map([
[callback, { once }],
...this.listeners.entries(),
]);
} else {
this.listeners.set(callback, { once });
}
}
removeListener(callback: Callback<D>) {
this.listeners = this.listeners.filter(([cb]) => cb !== callback);
/**
* Removes `callback` from being called for future events.
* @param callback The listener instance to remove
*/
removeListener(callback: EventListener<D>) {
this.listeners.delete(callback);
}
/**
* Removes all current listeners.
*/
removeAllListeners() {
this.listeners.length = 0;
this.listeners.clear();
}
/**
* Emits a new event.
* @param data The event data
*/
emit = (...data: D) => {
for (const [callback, { once }] of this.listeners) {
if (once) {

View File

@ -7,6 +7,9 @@ import orderBy from "lodash/orderBy";
import { autoBind } from "./utils";
import { action, computed, observable, when, makeObservable } from "mobx";
/**
* An object whose ID and name can be gotten via methods.
*/
export interface ItemObject {
getId(): string;
getName(): string;

View File

@ -29,7 +29,7 @@ describe("Crds", () => {
storage: false,
},
],
},
} as CustomResourceDefinitionSpec,
});
expect(() => crd.getVersion()).toThrowError("Failed to find a version for CustomResourceDefinition foo");
@ -57,7 +57,7 @@ describe("Crds", () => {
storage: false,
},
],
},
} as CustomResourceDefinitionSpec,
});
expect(crd.getVersion()).toBe("123");
@ -85,7 +85,7 @@ describe("Crds", () => {
storage: false,
},
],
},
} as CustomResourceDefinitionSpec,
});
expect(crd.getVersion()).toBe("123");
@ -114,7 +114,7 @@ describe("Crds", () => {
storage: false,
},
],
},
} as CustomResourceDefinitionSpec,
});
expect(crd.getVersion()).toBe("123");

View File

@ -11,82 +11,137 @@ import type { KubeApi } from "./kube-api";
import type { KubeObject } from "./kube-object";
import { IKubeObjectRef, parseKubeApi, createKubeApiURL } from "./kube-api-parse";
/**
* The manager of registered kube apis and KubeObject stores
*/
export class ApiManager {
private apis = observable.map<string, KubeApi<KubeObject>>();
private stores = observable.map<string, KubeObjectStore<KubeObject>>();
private stores = observable.map<KubeApi<KubeObject>, KubeObjectStore<KubeObject>>();
/**
* @internal
*/
constructor() {
makeObservable(this);
autoBind(this);
}
getApi(pathOrCallback: string | ((api: KubeApi<KubeObject>) => boolean)) {
/**
* Get the KubeApi instance which either has registered under the given
* path or by the apiBase of the given path or the first api which the
* callback returns `true` for.
* @param pathOrCallback Either the api path or a matching function
*/
getApi(pathOrCallback: string | ((api: KubeApi<KubeObject>) => boolean)): KubeApi<KubeObject> | undefined {
if (typeof pathOrCallback === "string") {
return this.apis.get(pathOrCallback) || this.apis.get(parseKubeApi(pathOrCallback).apiBase);
}
return iter.find(this.apis.values(), pathOrCallback ?? (() => true));
return iter.find(this.apis.values(), pathOrCallback);
}
getApiByKind(kind: string, apiVersion: string) {
return iter.find(this.apis.values(), api => api.kind === kind && api.apiVersionWithGroup === apiVersion);
/**
* Get the `KubeApi` instance which is for the kube resource `kind` under the
* apiVersion and group `apiVersion`
*
* Example:
* ```ts
* this.getApiByKind("Pod", "api/v1");
* ```
* @param kind The kube resource kind
* @param apiVersion The kube apiVersion and group
*/
getApiByKind(kind: string, apiVersion: string): KubeApi<KubeObject> | undefined {
return this.getApi(api => api.kind === kind && api.apiVersionWithGroup === apiVersion);
}
registerApi(apiBase: string, api: KubeApi<KubeObject>) {
if (!api.apiBase) return;
if (!this.apis.has(apiBase)) {
this.stores.forEach((store) => {
if (store.api === api) {
this.stores.set(apiBase, store);
/**
* Attempt to register `api` under `apiBase`. If `apiBase` already has been
* registered then this function does nothing.
* @param apiBase The kube resource api base to register the api against
* @param api The `KubeApi` instance to register
*/
registerApi(apiBase: string, api: KubeApi<KubeObject>): void {
if (!api.apiBase || this.apis.has(apiBase)) {
return;
}
});
this.apis.set(apiBase, api);
}
}
protected resolveApi<K extends KubeObject>(api?: string | KubeApi<K>): KubeApi<K> | undefined {
if (!api) {
/**
* Unifies apiBases and instances into instances
* @param apiOrBase Either the `apiBase` string or the `KubeApi` instance
*/
protected resolveApi<K extends KubeObject>(apiOrBase: string | KubeApi<K>): KubeApi<K> | undefined {
if (!apiOrBase) {
return undefined;
}
if (typeof api === "string") {
return this.getApi(api) as KubeApi<K>;
if (typeof apiOrBase === "string") {
return this.getApi(apiOrBase) as KubeApi<K>;
}
return api;
return apiOrBase;
}
unregisterApi(api: string | KubeApi<KubeObject>) {
if (typeof api === "string") this.apis.delete(api);
else {
const apis = Array.from(this.apis.entries());
const entry = apis.find(entry => entry[1] === api);
if (entry) this.unregisterApi(entry[0]);
/**
* Removes
* @param apiOrBase Either an apiBase string or the instance to deregister
*/
unregisterApi(apiOrBase: string | KubeApi<KubeObject>) {
if (typeof apiOrBase === "string") {
this.apis.delete(apiOrBase);
} else {
for (const [apiBase, api] of this.apis) {
if (api === apiOrBase) {
this.apis.delete(apiBase);
}
}
}
}
/**
* Register a store under its api's apiBase
* @param store The store instance to register
*/
registerStore(store: KubeObjectStore<KubeObject>): void;
/**
* @deprecated Use {@link ApiManager.registerStore} instead as a store should
* only be registered under its own api
*/
registerStore(store: KubeObjectStore<KubeObject>, apis: KubeApi<KubeObject>[]): void;
@action
registerStore(store: KubeObjectStore<KubeObject>, apis: KubeApi<KubeObject>[] = [store.api]) {
apis.filter(Boolean).forEach(api => {
if (api.apiBase) this.stores.set(api.apiBase, store);
});
registerStore(store: KubeObjectStore<KubeObject>, apis?: KubeApi<KubeObject>[]): void {
if (apis) {
for (const api of apis) {
this.stores.set(api, store);
}
} else {
this.stores.set(store.api, store);
}
}
getStore<S extends KubeObjectStore<KubeObject>>(api: string | KubeApi<KubeObject>): S | undefined {
return this.stores.get(this.resolveApi(api)?.apiBase) as S;
/**
* Get the registered store under the provided key
* @param apiOrBase Either the apiBase or a KubeApi instance
*/
getStore<S extends KubeObjectStore<KubeObject>>(apiOrBase: string | KubeApi<KubeObject>): S | undefined {
return this.stores.get(this.resolveApi(apiOrBase)) as S;
}
/**
* Attempt to get the api string for a given kube resource
* @param ref An object describing the kube resource
* @param parentObject Used to get the namespace or the resource if `ref` does not provided it
* @returns The kube API resource string
*/
lookupApiLink(ref: IKubeObjectRef, parentObject?: KubeObject): string {
const {
kind, apiVersion, name,
namespace = parentObject?.getNs(),
} = ref;
if (!kind) return "";
// search in registered apis by 'kind' & 'apiVersion'
const api = this.getApi(api => api.kind === kind && api.apiVersionWithGroup == apiVersion);
@ -119,4 +174,7 @@ export class ApiManager {
}
}
/**
* The single instance per frame.
*/
export const apiManager = new ApiManager();

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import { KubeObject } from "../kube-object";
export type ClusterRoleBindingSubjectKind = "Group" | "ServiceAccount" | "User";
@ -39,16 +39,20 @@ export class ClusterRoleBinding extends KubeObject {
}
/**
* Only available within kubernetes cluster pages
* The api type for {@link ClusterRoleBinding}'s
*/
let clusterRoleBindingApi: KubeApi<ClusterRoleBinding>;
if (isClusterPageContext()) {
clusterRoleBindingApi = new KubeApi({
export class ClusterRoleBindingApi extends KubeApi<ClusterRoleBinding> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: ClusterRoleBinding,
});
}
}
export {
clusterRoleBindingApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const clusterRoleBindingApi = isClusterPageContext()
? new ClusterRoleBindingApi()
: undefined;

View File

@ -4,7 +4,7 @@
*/
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import { KubeObject } from "../kube-object";
export interface ClusterRole {
@ -27,16 +27,20 @@ export class ClusterRole extends KubeObject {
}
/**
* Only available within kubernetes cluster pages
* The api type for {@link ClusterRole}'s
*/
let clusterRoleApi: KubeApi<ClusterRole>;
if (isClusterPageContext()) { // initialize automatically only when within a cluster iframe/context
clusterRoleApi = new KubeApi({
export class ClusterRoleApi extends KubeApi<ClusterRole> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: ClusterRole,
});
}
}
export {
clusterRoleApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const clusterRoleApi = isClusterPageContext()
? new ClusterRoleApi()
: undefined;

View File

@ -110,14 +110,8 @@ export class Cluster extends KubeObject {
/**
* Only available within kubernetes cluster pages
*/
let clusterApi: ClusterApi;
if (isClusterPageContext()) { // initialize automatically only when within a cluster iframe/context
clusterApi = new ClusterApi({
export const clusterApi = isClusterPageContext()
? new ClusterApi({
objectConstructor: Cluster,
});
}
export {
clusterApi,
};
})
: undefined;

View File

@ -5,7 +5,7 @@
import { KubeObject } from "../kube-object";
import type { KubeJsonApiData } from "../kube-json-api";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import { autoBind } from "../../utils";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
@ -32,17 +32,18 @@ export class ConfigMap extends KubeObject {
}
}
/**
* Only available within kubernetes cluster pages
*/
let configMapApi: KubeApi<ConfigMap>;
if (isClusterPageContext()) {
configMapApi = new KubeApi({
export class ConfigMapApi extends KubeApi<ConfigMap> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: ConfigMap,
});
}
}
export {
configMapApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const configMapApi = isClusterPageContext()
? new ConfigMapApi()
: undefined;

View File

@ -3,13 +3,12 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { KubeCreationError, KubeObject } from "../kube-object";
import { KubeApi } from "../kube-api";
import { KubeObject, KubeObjectMetadata } from "../kube-object";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import { crdResourcesURL } from "../../routes";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
import type { KubeJsonApiData } from "../kube-json-api";
interface AdditionalPrinterColumnsCommon {
export interface AdditionalPrinterColumnsCommon {
name: string;
type: "integer" | "number" | "string" | "boolean" | "date";
priority: number;
@ -20,7 +19,7 @@ export type AdditionalPrinterColumnsV1 = AdditionalPrinterColumnsCommon & {
jsonPath: string;
};
type AdditionalPrinterColumnsV1Beta = AdditionalPrinterColumnsCommon & {
export type AdditionalPrinterColumnsV1Beta = AdditionalPrinterColumnsCommon & {
JSONPath: string;
};
@ -79,25 +78,35 @@ export interface CustomResourceDefinition {
};
storedVersions: string[];
};
/**
* @deprecated for apiextensions.k8s.io/v1 but used previously
*/
additionalPrinterColumns?: AdditionalPrinterColumnsV1Beta[];
}
export interface CRDApiData extends KubeJsonApiData {
spec: object; // TODO: make better
export interface CustomResourceDefinitionStatus {
conditions: {
lastTransitionTime: string;
message: string;
reason: string;
status: string;
type?: string;
}[];
acceptedNames: {
plural: string;
singular: string;
kind: string;
shortNames: string[];
listKind: string;
};
storedVersions: string[];
}
export class CustomResourceDefinition extends KubeObject {
export class CustomResourceDefinition extends KubeObject<KubeObjectMetadata, CustomResourceDefinitionStatus, CustomResourceDefinitionSpec> {
static kind = "CustomResourceDefinition";
static namespaced = false;
static apiBase = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions";
constructor(data: CRDApiData) {
super(data);
if (!data.spec || typeof data.spec !== "object") {
throw new KubeCreationError("Cannot create a CustomResourceDefinition from an object without spec", data);
}
}
getResourceUrl() {
return crdResourcesURL({
params: {
@ -211,17 +220,21 @@ export class CustomResourceDefinition extends KubeObject {
}
/**
* Only available within kubernetes cluster pages
* The api type for {@link CustomResourceDefinition}'s
*/
let crdApi: KubeApi<CustomResourceDefinition>;
if (isClusterPageContext()) {
crdApi = new KubeApi<CustomResourceDefinition>({
export class CustomResourceDefinitionApi extends KubeApi<CustomResourceDefinition> {
constructor(params?: Pick<BaseKubeApiOptions, "request">) {
super({
...(params ?? {}),
objectConstructor: CustomResourceDefinition,
checkPreferredVersion: true,
});
}
}
export {
crdApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const crdApi = isClusterPageContext()
? new CustomResourceDefinitionApi()
: undefined;

View File

@ -128,14 +128,8 @@ export class CronJob extends KubeObject {
/**
* Only available within kubernetes cluster pages
*/
let cronJobApi: CronJobApi;
if (isClusterPageContext()) {
cronJobApi = new CronJobApi({
export const cronJobApi = isClusterPageContext()
? new CronJobApi({
objectConstructor: CronJob,
});
}
export {
cronJobApi,
};
})
: undefined;

View File

@ -103,14 +103,8 @@ export function getMetricsForDaemonSets(daemonsets: DaemonSet[], namespace: stri
/**
* Only available within kubernetes cluster pages
*/
let daemonSetApi: DaemonSetApi;
if (isClusterPageContext()) {
daemonSetApi = new DaemonSetApi({
export const daemonSetApi = isClusterPageContext()
? new DaemonSetApi({
objectConstructor: DaemonSet,
});
}
export {
daemonSetApi,
};
})
: undefined;

View File

@ -77,7 +77,7 @@ export function getMetricsForDeployments(deployments: Deployment[], namespace: s
});
}
interface IContainerProbe {
export interface IContainerProbe {
httpGet?: {
path?: string;
port: number;
@ -224,14 +224,11 @@ export class Deployment extends WorkloadKubeObject {
}
}
let deploymentApi: DeploymentApi;
if (isClusterPageContext()) {
deploymentApi = new DeploymentApi({
/**
* Only available within kubernetes cluster pages
*/
export const deploymentApi = isClusterPageContext()
? new DeploymentApi({
objectConstructor: Deployment,
});
}
export {
deploymentApi,
};
})
: undefined;

View File

@ -5,7 +5,7 @@
import { autoBind } from "../../utils";
import { KubeObject } from "../kube-object";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import type { KubeJsonApiData } from "../kube-json-api";
import { get } from "lodash";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
@ -28,7 +28,7 @@ export interface IEndpointSubset {
ports: IEndpointPort[];
}
interface ITargetRef {
export interface ITargetRef {
kind: string;
namespace: string;
name: string;
@ -131,17 +131,23 @@ export class Endpoint extends KubeObject {
return "<none>";
}
}
}
let endpointApi: KubeApi<Endpoint>;
if (isClusterPageContext()) {
endpointApi = new KubeApi<Endpoint>({
/**
* The api type for {@link Endpoint}'s
*/
export class EndpointApi extends KubeApi<Endpoint> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: Endpoint,
});
}
}
export {
endpointApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const endpointApi = isClusterPageContext()
? new EndpointApi()
: undefined;

View File

@ -6,7 +6,7 @@
import moment from "moment";
import { KubeObject } from "../kube-object";
import { formatDuration } from "../../utils/formatDuration";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
export interface KubeEvent {
@ -62,14 +62,22 @@ export class KubeEvent extends KubeObject {
}
}
let eventApi: KubeApi<KubeEvent>;
/**
* The api type for {@link KubeEvent}'s
*/
if (isClusterPageContext()) {
eventApi = new KubeApi<KubeEvent>({
export class KubeEventApi extends KubeApi<KubeEvent> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: KubeEvent,
});
}
}
export {
eventApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const eventApi = isClusterPageContext()
? new KubeEventApi()
: undefined;

View File

@ -4,7 +4,7 @@
*/
import { KubeObject } from "../kube-object";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
export enum HpaMetricType {
@ -148,14 +148,21 @@ export class HorizontalPodAutoscaler extends KubeObject {
}
}
let hpaApi: KubeApi<HorizontalPodAutoscaler>;
if (isClusterPageContext()) {
hpaApi = new KubeApi<HorizontalPodAutoscaler>({
/**
* The api type for {@link HorizontalPodAutoscaler}'s
*/
export class HorizontalPodAutoscalerApi extends KubeApi<HorizontalPodAutoscaler> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: HorizontalPodAutoscaler,
});
}
}
export {
hpaApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const hpaApi = isClusterPageContext()
? new HorizontalPodAutoscalerApi()
: undefined;

View File

@ -40,14 +40,18 @@ export interface ILoadBalancerIngress {
ip?: string;
}
// extensions/v1beta1
interface IExtensionsBackend {
/**
* For use when Ingresses are under `extensions/v1beta1`
*/
export interface IExtensionsBackend {
serviceName: string;
servicePort: number | string;
}
// networking.k8s.io/v1
interface INetworkingBackend {
/**
* For use when Ingresses are under `networking.k8s.io/v1`
*/
export interface INetworkingBackend {
service: IIngressService;
}
@ -194,17 +198,14 @@ export class Ingress extends KubeObject {
}
}
let ingressApi: IngressApi;
if (isClusterPageContext()) {
ingressApi = new IngressApi({
/**
* Only available within kubernetes cluster pages
*/
export const ingressApi = isClusterPageContext()
? new IngressApi({
objectConstructor: Ingress,
// Add fallback for Kubernetes <1.19
checkPreferredVersion: true,
fallbackApiBases: ["/apis/extensions/v1beta1/ingresses"],
});
}
export {
ingressApi,
};
})
: undefined;

View File

@ -123,14 +123,11 @@ export function getMetricsForJobs(jobs: Job[], namespace: string, selector = "")
});
}
let jobApi: JobApi;
if (isClusterPageContext()) {
jobApi = new JobApi({
/**
* Only available within kubernetes cluster pages
*/
export const jobApi = isClusterPageContext()
? new JobApi({
objectConstructor: Job,
});
}
export {
jobApi,
};
})
: undefined;

View File

@ -4,7 +4,7 @@
*/
import { KubeObject } from "../kube-object";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import { autoBind } from "../../utils";
import type { KubeJsonApiData } from "../kube-json-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
@ -65,14 +65,21 @@ export class LimitRange extends KubeObject {
}
}
let limitRangeApi: KubeApi<LimitRange>;
if (isClusterPageContext()) {
limitRangeApi = new KubeApi<LimitRange>({
/**
* The api type for {@link LimitRange}'s
*/
export class LimitRangeApi extends KubeApi<LimitRange> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: LimitRange,
});
}
}
export {
limitRangeApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const limitRangeApi = isClusterPageContext()
? new LimitRangeApi()
: undefined;

View File

@ -56,14 +56,11 @@ export function getMetricsForNamespace(namespace: string, selector = ""): Promis
});
}
let namespacesApi: NamespaceApi;
if (isClusterPageContext()) {
namespacesApi = new NamespaceApi({
/**
* Only available within kubernetes cluster pages
*/
export const namespacesApi = isClusterPageContext()
? new NamespaceApi({
objectConstructor: Namespace,
});
}
export {
namespacesApi,
};
})
: undefined;

View File

@ -5,7 +5,7 @@
import { KubeObject, LabelSelector } from "../kube-object";
import { autoBind } from "../../utils";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import type { KubeJsonApiData } from "../kube-json-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
@ -129,14 +129,22 @@ export class NetworkPolicy extends KubeObject {
}
}
let networkPolicyApi: KubeApi<NetworkPolicy>;
/**
* The api type for {@link NetworkPolicy}'s
*/
if (isClusterPageContext()) {
networkPolicyApi = new KubeApi<NetworkPolicy>({
export class NetworkPolicyApi extends KubeApi<NetworkPolicy> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: NetworkPolicy,
});
}
}
export {
networkPolicyApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const networkPolicyApi = isClusterPageContext()
? new NetworkPolicyApi()
: undefined;

View File

@ -249,14 +249,11 @@ export class Node extends KubeObject {
}
}
let nodesApi: NodesApi;
if (isClusterPageContext()) {
nodesApi = new NodesApi({
/**
* Only available within kubernetes cluster pages
*/
export const nodesApi = isClusterPageContext()
? new NodesApi({
objectConstructor: Node,
});
}
export {
nodesApi,
};
})
: undefined;

View File

@ -94,14 +94,11 @@ export class PersistentVolumeClaim extends KubeObject {
}
}
let pvcApi: PersistentVolumeClaimsApi;
if (isClusterPageContext()) {
pvcApi = new PersistentVolumeClaimsApi({
/**
* Only available within kubernetes cluster pages
*/
export const pvcApi = isClusterPageContext()
? new PersistentVolumeClaimsApi({
objectConstructor: PersistentVolumeClaim,
});
}
export {
pvcApi,
};
})
: undefined;

View File

@ -5,7 +5,7 @@
import { KubeObject } from "../kube-object";
import { autoBind, unitsToBytes } from "../../utils";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import type { KubeJsonApiData } from "../kube-json-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
@ -86,14 +86,22 @@ export class PersistentVolume extends KubeObject {
}
}
let persistentVolumeApi: KubeApi<PersistentVolume>;
/**
* The api type for {@link PersistentVolume}'s
*/
if (isClusterPageContext()) {
persistentVolumeApi = new KubeApi({
export class PersistentVolumeApi extends KubeApi<PersistentVolume> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: PersistentVolume,
});
}
}
export {
persistentVolumeApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const persistentVolumeApi = isClusterPageContext()
? new PersistentVolumeApi()
: undefined;

View File

@ -25,14 +25,11 @@ export class PodMetrics extends KubeObject {
static apiBase = "/apis/metrics.k8s.io/v1beta1/pods";
}
let podMetricsApi: KubeApi<PodMetrics>;
if (isClusterPageContext()) {
podMetricsApi = new KubeApi<PodMetrics>({
/**
* Only available within kubernetes cluster pages
*/
export const podMetricsApi = isClusterPageContext()
? new KubeApi<PodMetrics>({
objectConstructor: PodMetrics,
});
}
export {
podMetricsApi,
};
})
: undefined;

View File

@ -5,7 +5,7 @@
import { autoBind } from "../../utils";
import { KubeObject, LabelSelector } from "../kube-object";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import type { KubeJsonApiData } from "../kube-json-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
@ -54,17 +54,23 @@ export class PodDisruptionBudget extends KubeObject {
getDesiredHealthy() {
return this.status.desiredHealthy;
}
}
let pdbApi: KubeApi<PodDisruptionBudget>;
if (isClusterPageContext()) {
pdbApi = new KubeApi({
/**
* The api type for {@link PodDisruptionBudget}'s
*/
export class PodDisruptionBudgetApi extends KubeApi<PodDisruptionBudget> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: PodDisruptionBudget,
});
}
}
export {
pdbApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const pdbApi = isClusterPageContext()
? new PodDisruptionBudgetApi()
: undefined;

View File

@ -73,7 +73,7 @@ export enum PodStatus {
EVICTED = "Evicted",
}
export interface IPodContainer extends Partial<Record<PodContainerProbe, IContainerProbe>> {
export interface IPodContainer extends Partial<Record<PodContainerProbe, ContainerProbe>> {
name: string;
image: string;
command?: string[];
@ -129,7 +129,7 @@ export interface IPodContainer extends Partial<Record<PodContainerProbe, IContai
export type PodContainerProbe = "livenessProbe" | "readinessProbe" | "startupProbe";
interface IContainerProbe {
export interface ContainerProbe {
httpGet?: {
path?: string;
@ -501,14 +501,11 @@ export class Pod extends WorkloadKubeObject {
}
}
let podsApi: PodsApi;
if (isClusterPageContext()) {
podsApi = new PodsApi({
/**
* Only available within kubernetes cluster pages
*/
export const podsApi = isClusterPageContext()
? new PodsApi({
objectConstructor: Pod,
});
}
export {
podsApi,
};
})
: undefined;

View File

@ -102,14 +102,11 @@ export class PodSecurityPolicy extends KubeObject {
}
}
let pspApi: KubeApi<PodSecurityPolicy>;
if (isClusterPageContext()) {
pspApi = new KubeApi({
/**
* Only available within kubernetes cluster pages
*/
export const pspApi = isClusterPageContext()
? new KubeApi<PodSecurityPolicy>({
objectConstructor: PodSecurityPolicy,
});
}
export {
pspApi,
};
})
: undefined;

View File

@ -111,14 +111,11 @@ export class ReplicaSet extends WorkloadKubeObject {
}
}
let replicaSetApi: ReplicaSetApi;
if (isClusterPageContext()) {
replicaSetApi = new ReplicaSetApi({
/**
* Only available within kubernetes cluster pages
*/
export const replicaSetApi = isClusterPageContext()
? new ReplicaSetApi({
objectConstructor: ReplicaSet,
});
}
export {
replicaSetApi,
};
})
: undefined;

View File

@ -4,7 +4,7 @@
*/
import { KubeObject } from "../kube-object";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
export interface IResourceQuotaValues {
@ -65,14 +65,23 @@ export class ResourceQuota extends KubeObject {
}
}
let resourceQuotaApi: KubeApi<ResourceQuota>;
/**
* The api type for {@link ResourceQuota}'s
*/
if (isClusterPageContext()) {
resourceQuotaApi = new KubeApi<ResourceQuota>({
export class ResourceQuotaApi extends KubeApi<ResourceQuota> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: ResourceQuota,
});
}
}
/**
* Only available within kubernetes cluster pages
*/
export const resourceQuotaApi = isClusterPageContext()
? new ResourceQuotaApi()
: undefined;
export {
resourceQuotaApi,
};

View File

@ -5,7 +5,7 @@
import { autoBind } from "../../utils";
import { KubeObject } from "../kube-object";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import type { KubeJsonApiData } from "../kube-json-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
@ -46,14 +46,22 @@ export class RoleBinding extends KubeObject {
}
}
let roleBindingApi: KubeApi<RoleBinding>;
/**
* The api type for {@link RoleBinding}'s
*/
if (isClusterPageContext()) {
roleBindingApi = new KubeApi({
export class RoleBindingApi extends KubeApi<RoleBinding> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: RoleBinding,
});
}
}
export {
roleBindingApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const roleBindingApi = isClusterPageContext()
? new RoleBindingApi()
: undefined;

View File

@ -4,7 +4,7 @@
*/
import { KubeObject } from "../kube-object";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
export interface Role {
@ -26,14 +26,23 @@ export class Role extends KubeObject {
}
}
let roleApi: KubeApi<Role>;
/**
* The api type for {@link Role}'s
*/
if (isClusterPageContext()) {
roleApi = new KubeApi<Role>({
export class RoleApi extends KubeApi<Role> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: Role,
});
}
}
/**
* Only available within kubernetes cluster pages
*/
export const roleApi = isClusterPageContext()
? new RoleApi()
: undefined;
export{
roleApi,
};

View File

@ -6,7 +6,7 @@
import { KubeObject } from "../kube-object";
import type { KubeJsonApiData } from "../kube-json-api";
import { autoBind } from "../../utils";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
export enum SecretType {
@ -54,14 +54,21 @@ export class Secret extends KubeObject {
}
}
let secretsApi: KubeApi<Secret>;
if (isClusterPageContext()) {
secretsApi = new KubeApi({
/**
* The api type for {@link Secret}'s
*/
export class SecretApi extends KubeApi<Secret> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: Secret,
});
}
}
export {
secretsApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const secretsApi = isClusterPageContext()
? new SecretApi()
: undefined;

View File

@ -71,15 +71,12 @@ export class SelfSubjectRulesReview extends KubeObject {
}
}
let selfSubjectRulesReviewApi: SelfSubjectRulesReviewApi;
if (isClusterPageContext()) {
selfSubjectRulesReviewApi = new SelfSubjectRulesReviewApi({
/**
* Only available within kubernetes cluster pages
*/
export const selfSubjectRulesReviewApi = isClusterPageContext()
? new SelfSubjectRulesReviewApi({
objectConstructor: SelfSubjectRulesReview,
});
}
export {
selfSubjectRulesReviewApi,
};
})
: undefined;

View File

@ -5,7 +5,7 @@
import { autoBind } from "../../utils";
import { KubeObject } from "../kube-object";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import type { KubeJsonApiData } from "../kube-json-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
@ -37,14 +37,22 @@ export class ServiceAccount extends KubeObject {
}
}
let serviceAccountsApi: KubeApi<ServiceAccount>;
/**
* The api type for {@link ServiceAccount}'s
*/
if (isClusterPageContext()) {
serviceAccountsApi = new KubeApi<ServiceAccount>({
export class ServiceAccountApi extends KubeApi<ServiceAccount> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: ServiceAccount,
});
}
}
export {
serviceAccountsApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const serviceAccountsApi = isClusterPageContext()
? new ServiceAccountApi()
: undefined;

View File

@ -5,7 +5,7 @@
import { autoBind } from "../../../renderer/utils";
import { KubeObject } from "../kube-object";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import type { KubeJsonApiData } from "../kube-json-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
@ -132,14 +132,21 @@ export class Service extends KubeObject {
}
}
let serviceApi: KubeApi<Service>;
if (isClusterPageContext()) {
serviceApi = new KubeApi<Service>({
/**
* The api type for {@link Service}'s
*/
export class ServiceApi extends KubeApi<Service> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: Service,
});
}
}
export {
serviceApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const serviceApi = isClusterPageContext()
? new ServiceApi()
: undefined;

View File

@ -136,14 +136,11 @@ export class StatefulSet extends WorkloadKubeObject {
}
}
let statefulSetApi: StatefulSetApi;
if (isClusterPageContext()) {
statefulSetApi = new StatefulSetApi({
/**
* Only available within kubernetes cluster pages
*/
export const statefulSetApi = isClusterPageContext()
? new StatefulSetApi({
objectConstructor: StatefulSet,
});
}
export {
statefulSetApi,
};
})
: undefined;

View File

@ -5,7 +5,7 @@
import { autoBind } from "../../utils";
import { KubeObject } from "../kube-object";
import { KubeApi } from "../kube-api";
import { BaseKubeApiOptions, KubeApi } from "../kube-api";
import type { KubeJsonApiData } from "../kube-json-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
@ -47,14 +47,22 @@ export class StorageClass extends KubeObject {
}
}
let storageClassApi: KubeApi<StorageClass>;
/**
* The api type for {@link StorageClass}'s
*/
if (isClusterPageContext()) {
storageClassApi = new KubeApi({
export class StorageClassApi extends KubeApi<StorageClass> {
constructor(params?: BaseKubeApiOptions) {
super({
...(params ?? {}),
objectConstructor: StorageClass,
});
}
}
export {
storageClassApi,
};
/**
* Only available within kubernetes cluster pages
*/
export const storageClassApi = isClusterPageContext()
? new StorageClassApi()
: undefined;

View File

@ -9,8 +9,7 @@ import { apiKubePrefix, apiPrefix, isDebugging, isDevelopment } from "../../comm
import { isClusterPageContext } from "../utils/cluster-id-url-parsing";
import { appEventBus } from "../app-event-bus/event-bus";
let apiBase: JsonApi;
let apiKube: KubeJsonApi;
export let apiBase: JsonApi;
if (typeof window === "undefined") {
appEventBus.addListener((event) => {
@ -42,8 +41,11 @@ if (typeof window === "undefined") {
});
}
if (isClusterPageContext()) {
apiKube = new KubeJsonApi({
/**
* Only available within kubernetes cluster pages
*/
export const apiKube = isClusterPageContext()
? new KubeJsonApi({
serverAddress: `http://127.0.0.1:${window.location.port}`,
apiBase: apiKubePrefix,
debug: isDevelopment,
@ -51,10 +53,5 @@ if (isClusterPageContext()) {
headers: {
"Host": window.location.host,
},
});
}
export {
apiBase,
apiKube,
};
})
: undefined;

View File

@ -44,6 +44,9 @@ export interface JsonApiConfig {
const httpAgent = new HttpAgent({ keepAlive: true });
const httpsAgent = new HttpsAgent({ keepAlive: true });
/**
* The base type used for communicating with a JSON returning API server
*/
export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
static reqInitDefault: RequestInit = {
headers: {
@ -199,6 +202,9 @@ export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
}
}
/**
* The pseudo-error type that is throw when there are errors from a request
*/
export class JsonApiErrorParsed {
isUsedForNotification = false;

View File

@ -12,7 +12,7 @@ import { inspect } from "util";
export interface IKubeObjectRef {
kind: string;
apiVersion: string;
apiVersion?: string;
name: string;
namespace?: string;
}

View File

@ -23,16 +23,10 @@ import { Agent, AgentOptions } from "https";
import type { Patch } from "rfc6902";
/**
* The options used for creating a `KubeApi`
* The base constructor options for {@link KubeApi} for use with child classes
* of it.
*/
export interface IKubeApiOptions<T extends KubeObject> {
/**
* base api-path for listing all resources, e.g. "/api/v1/pods"
*
* If not specified then will be the one on the `objectConstructor`
*/
apiBase?: string;
export interface BaseKubeApiOptions {
/**
* If the API uses a different API endpoint (e.g. apiBase) depending on the cluster version,
* fallback API bases can be listed individually.
@ -47,17 +41,29 @@ export interface IKubeApiOptions<T extends KubeObject> {
*/
checkPreferredVersion?: boolean;
/**
* The constructor for the kube objects returned from the API
*/
objectConstructor: KubeObjectConstructor<T>;
/**
* The api instance to use for making requests
*
* @default apiKube
*/
request?: KubeJsonApi;
}
/**
* The options used for creating a `KubeApi`
*/
export interface IKubeApiOptions<T extends KubeObject> extends BaseKubeApiOptions {
/**
* The constructor for the kube objects returned from the API
*/
objectConstructor: KubeObjectConstructor<T>;
/**
* base api-path for listing all resources, e.g. "/api/v1/pods"
*
* @deprecated It should be specified on the `objectConstructor`
*/
apiBase?: string;
/**
* @deprecated should be specified by `objectConstructor`
@ -290,7 +296,7 @@ export class KubeApi<T extends KubeObject> {
this.objectConstructor = objectConstructor;
this.parseResponse = this.parseResponse.bind(this);
apiManager.registerApi(apiBase, this);
apiManager.registerApi(this.apiBase, this);
}
get apiVersionWithGroup() {

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { JsonApi, JsonApiData, JsonApiError } from "./json-api";
import { JsonApi, JsonApiError } from "./json-api";
import type { Response } from "node-fetch";
import { LensProxy } from "../../main/lens-proxy";
import { apiKubePrefix, isDebugging } from "../vars";
@ -38,10 +38,12 @@ export interface KubeJsonApiMetadata {
[key: string]: any;
}
export interface KubeJsonApiData extends JsonApiData {
export interface KubeJsonApiData<Metadata extends KubeJsonApiMetadata = KubeJsonApiMetadata, Status = {}, Spec = {}> {
kind: string;
apiVersion: string;
metadata: KubeJsonApiMetadata;
metadata: Metadata;
status?: Status;
spec?: Spec;
}
export interface KubeJsonApiError extends JsonApiError {

View File

@ -57,7 +57,10 @@ export interface KubeObjectStoreSubscribeParams {
}
export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T> {
static defaultContext = observable.box<ClusterContext>(); // TODO: support multiple cluster contexts
/**
* @internal
*/
static defaultContext: ClusterContext; // TODO: support multiple cluster contexts
public api: KubeApi<T>;
public readonly limit?: number;
@ -81,8 +84,11 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
this.bindWatchEventsUpdater();
}
/**
* @internal
*/
get context(): ClusterContext {
return KubeObjectStore.defaultContext.get();
return KubeObjectStore.defaultContext;
}
// TODO: Circular dependency: KubeObjectStore -> ClusterFrameContext -> NamespaceStore -> KubeObjectStore
@ -369,11 +375,10 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
return Promise.all(this.selectedItems.map(this.remove));
}
async removeItems(items: T[]) {
await Promise.all(items.map(this.remove));
}
// collect items from watch-api events to avoid UI blowing up with huge streams of data
/**
* collect items from watch-api events to avoid UI blowing up with huge streams of data
* @internal
*/
protected eventsBuffer = observable.array<IKubeWatchEvent<KubeJsonApiData>>([], { deep: false });
protected bindWatchEventsUpdater(delay = 1000) {

View File

@ -14,6 +14,7 @@ import type { JsonApiParams } from "./json-api";
import * as resourceApplierApi from "./endpoints/resource-applier.api";
import { hasOptionalProperty, hasTypedProperty, isObject, isString, bindPredicate, isTypedArray, isRecord } from "../../common/utils/type-narrowing";
import type { Patch } from "rfc6902";
import Joi from "joi";
export type KubeObjectConstructor<K extends KubeObject> = (new (data: KubeJsonApiData | any) => K) & {
kind?: string;
@ -25,9 +26,9 @@ export interface KubeObjectMetadata {
uid: string;
name: string;
namespace?: string;
creationTimestamp: string;
creationTimestamp?: string;
resourceVersion: string;
selfLink: string;
selfLink?: string;
deletionTimestamp?: string;
finalizers?: string[];
continue?: string; // provided when used "?limit=" query param to fetch objects list
@ -116,6 +117,36 @@ export interface LabelSelector {
matchExpressions?: LabelMatchExpression[];
}
const kubeObjectValidator = Joi
.object({
metadata: Joi
.object()
.unknown(true)
.required(),
spec: Joi.
object()
.unknown(true)
.optional(),
status: Joi.
object()
.unknown(true)
.optional(),
managedFields: Joi.
object()
.unknown(true)
.optional(),
apiVersion: Joi
.string()
.required(),
kind: Joi
.string()
.required(),
})
.unknown(true);
/**
* The Lens representation of a kube resource
*/
export class KubeObject<Metadata extends KubeObjectMetadata = KubeObjectMetadata, Status = any, Spec = any> implements ItemObject {
static readonly kind?: string;
static readonly namespaced?: boolean;
@ -126,7 +157,7 @@ export class KubeObject<Metadata extends KubeObjectMetadata = KubeObjectMetadata
metadata: Metadata;
status?: Status;
spec?: Spec;
managedFields?: any;
managedFields?: object;
static create(data: KubeJsonApiData) {
return new KubeObject(data);
@ -227,13 +258,11 @@ export class KubeObject<Metadata extends KubeObjectMetadata = KubeObjectMetadata
...KubeObject.nonEditablePathPrefixes,
]);
constructor(data: KubeJsonApiData) {
if (typeof data !== "object") {
throw new TypeError(`Cannot create a KubeObject from ${typeof data}`);
}
constructor(data: KubeJsonApiData<Metadata, Status, Spec>) {
const { error } = kubeObjectValidator.validate(data);
if (!data.metadata || typeof data.metadata !== "object") {
throw new KubeCreationError(`Cannot create a KubeObject from an object without metadata`, data);
if (error) {
throw error;
}
Object.assign(this, data);

View File

@ -14,13 +14,18 @@ export interface IToleration {
tolerationSeconds?: number;
}
interface IMatchExpression {
export interface Affinity<T> {
requiredDuringSchedulingIgnoredDuringExecution?: T[];
preferredDuringSchedulingIgnoredDuringExecution?: T[];
}
export interface IMatchExpression {
key: string;
operator: string;
values: string[];
}
interface INodeAffinity {
export interface INodeAffinity {
nodeSelectorTerms?: {
matchExpressions: IMatchExpression[];
}[];
@ -30,7 +35,7 @@ interface INodeAffinity {
};
}
interface IPodAffinity {
export interface IPodAffinity {
labelSelector: {
matchExpressions: IMatchExpression[];
};
@ -38,18 +43,9 @@ interface IPodAffinity {
}
export interface IAffinity {
nodeAffinity?: {
requiredDuringSchedulingIgnoredDuringExecution?: INodeAffinity[];
preferredDuringSchedulingIgnoredDuringExecution?: INodeAffinity[];
};
podAffinity?: {
requiredDuringSchedulingIgnoredDuringExecution?: IPodAffinity[];
preferredDuringSchedulingIgnoredDuringExecution?: IPodAffinity[];
};
podAntiAffinity?: {
requiredDuringSchedulingIgnoredDuringExecution?: IPodAffinity[];
preferredDuringSchedulingIgnoredDuringExecution?: IPodAffinity[];
};
nodeAffinity?: Affinity<INodeAffinity>;
podAffinity?: Affinity<IPodAffinity>;
podAntiAffinity?: Affinity<IPodAffinity>;
}
export class WorkloadKubeObject extends KubeObject {

View File

@ -10,6 +10,8 @@ export function noop<T extends any[]>(...args: T): void {
return void args;
}
export type Defaulted<Params, DefaultParams extends keyof Params> = Required<Pick<Params, DefaultParams>> & Omit<Params, DefaultParams>;
export * from "./abort-controller";
export * from "./app-version";
export * from "./autobind";

View File

@ -1,45 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Injectable, TentativeTuple } from "@ogre-tools/injectable";
import { getLegacyGlobalDiForExtensionApi } from "./legacy-global-di-for-extension-api";
type MapInjectables<T> = {
[Key in keyof T]: T[Key] extends () => infer Res ? Res : never;
};
export const asLegacyGlobalObjectForExtensionApiWithModifications = <
TInjectable extends Injectable<unknown, unknown, TInstantiationParameter>,
TInstantiationParameter,
OtherFields extends Record<string, () => any>,
>(
injectableKey: TInjectable,
otherFields: OtherFields,
...instantiationParameter: TentativeTuple<TInstantiationParameter>
) =>
new Proxy(
{},
{
get(target, propertyName) {
if (propertyName === "$$typeof") {
return undefined;
}
const instance: any = getLegacyGlobalDiForExtensionApi().inject(
injectableKey,
...instantiationParameter,
);
const propertyValue = instance[propertyName] ?? otherFields[propertyName as any]();
if (typeof propertyValue === "function") {
return function (...args: any[]) {
return propertyValue.apply(instance, args);
};
}
return propertyValue;
},
},
) as ReturnType<TInjectable["instantiate"]> & MapInjectables<OtherFields>;

View File

@ -9,16 +9,22 @@ export {
GeneralEntity,
WebLink,
} from "../../common/catalog-entities";
export type {
KubernetesClusterPrometheusMetrics,
KubernetesClusterSpec,
KubernetesClusterCategory,
KubernetesClusterMetadata,
WebLinkSpec,
WebLinkStatus,
WebLinkStatusPhase,
KubernetesClusterStatusPhase,
KubernetesClusterStatus,
GeneralEntitySpec,
} from "../../common/catalog-entities";
export type {
CategoryFilter,
} from "../../common/catalog/catalog-category-registry";
export * from "../../common/catalog/catalog-entity";
export { CatalogRunEvent } from "../../common/catalog/catalog-run-event";

View File

@ -5,3 +5,4 @@
export { appEventBus } from "../../common/app-event-bus/event-bus";
export type { AppEvent } from "../../common/app-event-bus/event-bus";
export type { EventEmitter, AddListenerOptions, EventListener } from "../../common/event-emitter";

View File

@ -2,13 +2,23 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export type { StatusBarRegistration } from "../../renderer/components/status-bar/status-bar-registration";
export type { KubeObjectMenuRegistration, KubeObjectMenuComponents } from "../../renderer/components/kube-object-menu/dependencies/kube-object-menu-items/kube-object-menu-registration";
export type { StatusBarRegistration, StatusBarComponents, StatusBarItemProps } from "../../renderer/components/status-bar/status-bar-registration";
export type { KubeObjectMenuRegistration, KubeObjectMenuComponents, KubeObjectMenuItemProps } from "../../renderer/components/kube-object-menu/dependencies/kube-object-menu-items/kube-object-menu-registration";
export type { AppPreferenceRegistration, AppPreferenceComponents } from "../../renderer/components/+preferences/app-preferences/app-preference-registration";
export type { KubeObjectDetailRegistration, KubeObjectDetailComponents } from "../registries/kube-object-detail-registry";
export type { KubeObjectStatusRegistration } from "../registries/kube-object-status-registry";
export type { PageRegistration, RegisteredPage, PageParams, PageComponentProps, PageComponents, PageTarget } from "../registries/page-registry";
export type { ClusterPageMenuRegistration, ClusterPageMenuComponents } from "../registries/page-menu-registry";
export type { ProtocolHandlerRegistration, RouteParams as ProtocolRouteParams, RouteHandler as ProtocolRouteHandler } from "../registries/protocol-handler";
export type { MenuRegistration } from "../../main/menu/menu-registration";
export type { MenuTopId } from "../../main/menu/menu";
export type { CatalogEntityDetailRegistration, CatalogEntityDetailsProps, CatalogEntityDetailComponents } from "../registries/catalog-entity-detail-registry";
export type { CustomCategoryViewProps, CustomCategoryViewComponents, CustomCategoryViewRegistration } from "../../renderer/components/+catalog/custom-views";
export type { ShellEnvModifier, ShellEnvContext } from "../../main/shell-session/shell-env-modifier/shell-env-modifier-registration";
export type { ProtocolHandlerRegistration, RouteParams as ProtocolRouteParams, RouteHandler as ProtocolRouteHandler } from "../registries/protocol-handler";
export type { CommandRegistration, CommandContext } from "../../renderer/components/command-palette/registered-commands/commands";
export type { EntitySettingRegistration, EntitySettingViewProps, EntitySettingComponents } from "../registries/entity-setting-registry";
export type { WorkloadsOverviewDetailRegistration, WorkloadsOverviewDetailComponents } from "../registries/workloads-overview-detail-registry";
export type { TopBarRegistration, TopBarComponents } from "../../renderer/components/layout/top-bar/top-bar-registration";
export type { WelcomeBannerRegistration } from "../../renderer/components/+welcome/welcome-banner-items/welcome-banner-registration";
export type { WelcomeMenuRegistration } from "../../renderer/components/+welcome/welcome-menu-items/welcome-menu-registration";
export type { TrayMenuRegistration } from "../../main/tray/tray-menu-registration";

View File

@ -4,3 +4,4 @@
*/
export { ExtensionStore } from "../extension-store";
export type { BaseStoreParams } from "../../common/base-store";

View File

@ -6,5 +6,15 @@
export type IpcMainInvokeEvent = Electron.IpcMainInvokeEvent;
export type IpcRendererEvent = Electron.IpcRendererEvent;
export type IpcMainEvent = Electron.IpcMainEvent;
export type { LensExtension, LensExtensionManifest, LensExtensionId } from "../lens-extension";
export type { InstalledExtension } from "../extension-discovery/extension-discovery";
export type { Disposer } from "../../common/utils";
export {
ItemStore,
} from "../../common/item.store";
export type {
ItemObject,
} from "../../common/item.store";
export * from "./registrations";

View File

@ -0,0 +1,199 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
/**
* This file is for the common exports to both `Renderer.K8sApi` and `Main.K8sApi`
*
* It would be nicer if we exported this from `Common.K8sApi` but there doesn't seem
* to be a good way to deprecate an export so that will have to wait.
*/
export {
ResourceStack,
} from "../common/k8s/resource-stack";
export {
KubeObjectStore,
} from "../common/k8s-api/kube-object.store";
export {
forCluster,
forRemoteCluster,
KubeApi,
} from "../common/k8s-api/kube-api";
export type {
BaseKubeApiOptions,
DeleteResourceDescriptor,
KubeApiListOptions,
KubeApiPatchType,
KubeApiWatchCallback,
KubeApiWatchOptions,
PartialKubeObject,
PropagationPolicy,
ResourceDescriptor,
} from "../common/k8s-api/kube-api";
export type {
IKubeWatchEvent,
} from "../common/k8s-api/kube-watch-event";
export {
KubeObject,
KubeStatus,
} from "../common/k8s-api/kube-object";
export type {
KubeStatusData,
} from "../common/k8s-api/kube-object";
export {
ClusterRole,
ClusterRoleApi,
ClusterRoleBinding,
ClusterRoleBindingApi,
ConfigMap,
ConfigMapApi,
CronJob,
CronJobApi,
CustomResourceDefinition,
CustomResourceDefinitionApi,
DaemonSet,
DaemonSetApi,
Deployment,
DeploymentApi,
Endpoint,
EndpointApi,
HorizontalPodAutoscaler,
HorizontalPodAutoscalerApi,
Ingress,
IngressApi,
Job,
JobApi,
KubeEvent,
KubeEventApi,
LimitRange,
LimitRangeApi,
Namespace,
NamespaceApi,
NetworkPolicy,
NetworkPolicyApi,
Node,
NodesApi,
PersistentVolume,
PersistentVolumeApi,
PersistentVolumeClaim,
PersistentVolumeClaimsApi,
Pod,
PodDisruptionBudget,
PodDisruptionBudgetApi,
PodsApi,
ReplicaSet,
ReplicaSetApi,
ResourceQuota,
ResourceQuotaApi,
Role,
RoleApi,
RoleBinding,
RoleBindingApi,
Secret,
SecretApi,
SecretType,
Service,
ServiceAccount,
ServiceAccountApi,
ServiceApi,
StatefulSet,
StatefulSetApi,
StorageClass,
StorageClassApi,
} from "../common/k8s-api/endpoints";
export {
KubeObjectStatusLevel,
} from "./registries/kube-object-status-registry";
export type {
IKubeApiCluster,
IKubeApiOptions,
IKubeApiQueryParams,
ILocalKubeApiConfig,
IRemoteKubeApiConfig,
} from "../common/k8s-api/kube-api";
export type {
KubeObjectConstructor,
KubeObjectMetadata,
LabelMatchExpression,
LabelSelector,
} from "../common/k8s-api/kube-object";
export type {
AdditionalPrinterColumnsCommon,
AdditionalPrinterColumnsV1,
AdditionalPrinterColumnsV1Beta,
ClusterRoleBindingSubject,
ClusterRoleBindingSubjectKind,
ContainerProbe,
ContainerState,
ContainerStateRunning,
ContainerStateTerminated,
ContainerStateWaiting,
CRDVersion,
CustomResourceDefinitionSpec,
CustomResourceDefinitionStatus,
EndpointAddress,
EndpointSubset,
HpaMetricType,
IContainerProbe,
IEndpointAddress,
IEndpointPort,
IEndpointSubset,
IExtensionsBackend,
IHpaMetric,
IHpaMetricData,
IIngressBackend,
IIngressService,
ILoadBalancerIngress,
INetworkingBackend,
IPodContainer,
IPodContainerStatus,
IPodLogsQuery,
IPolicyEgress,
IPolicyIngress,
IPolicyIpBlock,
IResourceQuotaValues,
ISecretRef,
ITargetRef,
LimitRangeItem,
NetworkPolicyPeer,
NetworkPolicyPort,
NetworkPolicySpec,
NodeCondition,
NodeTaint,
PodMetrics,
PodStatus,
PolicyType,
RoleBindingSubject,
RoleBindingSubjectKind,
SecretData,
ServicePort,
} from "../common/k8s-api/endpoints";
export type {
Affinity,
IAffinity,
IMatchExpression,
INodeAffinity,
IPodAffinity,
IToleration,
} from "../common/k8s-api/workload-kube-object";
export type {
KubeObjectStatus,
} from "./registries/kube-object-status-registry";
export type {
JsonApi,
JsonApiConfig,
JsonApiData,
JsonApiError,
JsonApiErrorParsed,
JsonApiLog,
JsonApiParams,
} from "../common/k8s-api/json-api";
export type {
KubeJsonApi,
KubeJsonApiData,
KubeJsonApiDataList,
KubeJsonApiListMetadata,
KubeJsonApiMetadata,
} from "../common/k8s-api/kube-json-api";

View File

@ -14,18 +14,45 @@ import {
setLensExtensionDependencies,
} from "./lens-extension-set-dependencies";
export type LensExtensionId = string; // path to manifest (package.json)
/**
* A named type for when functions should expect an extension's ID
*/
export type LensExtensionId = string;
export type LensExtensionConstructor = new (...args: ConstructorParameters<typeof LensExtension>) => LensExtension;
/**
* The required fields that an extension's `package.json` must include
*/
export interface LensExtensionManifest extends PackageJson {
/**
* The name of the extension
*/
name: string;
/**
* The SemVer version string
*/
version: string;
main?: string; // path to %ext/dist/main.js
renderer?: string; // path to %ext/dist/renderer.js
/**
* The path to compiled JS file for the main side of the extension.
*/
main?: string;
/**
* The path to compiled JS file for the renderer side of the extension.
*/
renderer?: string;
}
/**
* @internal
*/
export const Disposers = Symbol();
/**
* The base class for all extensions.
*/
export class LensExtension {
readonly id: LensExtensionId;
readonly manifest: LensExtensionManifest;
@ -40,6 +67,9 @@ export class LensExtension {
return this._isEnabled;
}
/**
* @internal
*/
[Disposers] = disposer();
constructor({ id, manifest, manifestPath, isBundled }: InstalledExtension) {
@ -64,6 +94,9 @@ export class LensExtension {
private dependencies: LensExtensionDependencies;
/**
* @internal
*/
[setLensExtensionDependencies] = (dependencies: LensExtensionDependencies) => {
this.dependencies = dependencies;
};

View File

@ -3,6 +3,8 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export * from "../common-k8s-api";
/**
* @deprecated This function never works
* @returns false
@ -10,45 +12,3 @@
export function isAllowedResource(...args: any[]) {
return Boolean(void args);
}
export { ResourceStack } from "../../common/k8s/resource-stack";
export { apiManager } from "../../common/k8s-api/api-manager";
export { KubeApi, forCluster, forRemoteCluster } from "../../common/k8s-api/kube-api";
export { KubeObject, KubeStatus } from "../../common/k8s-api/kube-object";
export { KubeObjectStore } from "../../common/k8s-api/kube-object.store";
export { Pod, podsApi, PodsApi } from "../../common/k8s-api/endpoints/pods.api";
export { Node, nodesApi, NodesApi } from "../../common/k8s-api/endpoints/nodes.api";
export { Deployment, deploymentApi, DeploymentApi } from "../../common/k8s-api/endpoints/deployment.api";
export { DaemonSet, daemonSetApi } from "../../common/k8s-api/endpoints/daemon-set.api";
export { StatefulSet, statefulSetApi } from "../../common/k8s-api/endpoints/stateful-set.api";
export { Job, jobApi } from "../../common/k8s-api/endpoints/job.api";
export { CronJob, cronJobApi } from "../../common/k8s-api/endpoints/cron-job.api";
export { ConfigMap, configMapApi } from "../../common/k8s-api/endpoints/configmap.api";
export { Secret, secretsApi } from "../../common/k8s-api/endpoints/secret.api";
export { ReplicaSet, replicaSetApi } from "../../common/k8s-api/endpoints/replica-set.api";
export { ResourceQuota, resourceQuotaApi } from "../../common/k8s-api/endpoints/resource-quota.api";
export { LimitRange, limitRangeApi } from "../../common/k8s-api/endpoints/limit-range.api";
export { HorizontalPodAutoscaler, hpaApi } from "../../common/k8s-api/endpoints/hpa.api";
export { PodDisruptionBudget, pdbApi } from "../../common/k8s-api/endpoints/poddisruptionbudget.api";
export { Service, serviceApi } from "../../common/k8s-api/endpoints/service.api";
export { Endpoint, endpointApi } from "../../common/k8s-api/endpoints/endpoint.api";
export { Ingress, ingressApi, IngressApi } from "../../common/k8s-api/endpoints/ingress.api";
export { NetworkPolicy, networkPolicyApi } from "../../common/k8s-api/endpoints/network-policy.api";
export { PersistentVolume, persistentVolumeApi } from "../../common/k8s-api/endpoints/persistent-volume.api";
export { PersistentVolumeClaim, pvcApi, PersistentVolumeClaimsApi } from "../../common/k8s-api/endpoints/persistent-volume-claims.api";
export { StorageClass, storageClassApi } from "../../common/k8s-api/endpoints/storage-class.api";
export { Namespace, namespacesApi } from "../../common/k8s-api/endpoints/namespaces.api";
export { KubeEvent, eventApi } from "../../common/k8s-api/endpoints/events.api";
export { ServiceAccount, serviceAccountsApi } from "../../common/k8s-api/endpoints/service-accounts.api";
export { Role, roleApi } from "../../common/k8s-api/endpoints/role.api";
export { RoleBinding, roleBindingApi } from "../../common/k8s-api/endpoints/role-binding.api";
export { ClusterRole, clusterRoleApi } from "../../common/k8s-api/endpoints/cluster-role.api";
export { ClusterRoleBinding, clusterRoleBindingApi } from "../../common/k8s-api/endpoints/cluster-role-binding.api";
export { CustomResourceDefinition, crdApi } from "../../common/k8s-api/endpoints/crd.api";
// types
export type { ILocalKubeApiConfig, IRemoteKubeApiConfig, IKubeApiCluster } from "../../common/k8s-api/kube-api";
export type { IPodContainer, IPodContainerStatus } from "../../common/k8s-api/endpoints/pods.api";
export type { ISecretRef } from "../../common/k8s-api/endpoints/secret.api";
export type { KubeObjectMetadata, KubeStatusData } from "../../common/k8s-api/kube-object";
export type { KubeObjectStoreLoadAllParams, KubeObjectStoreLoadingParams, KubeObjectStoreSubscribeParams } from "../../common/k8s-api/kube-object.store";

View File

@ -2,7 +2,7 @@
"name": "@k8slens/extensions",
"productName": "OpenLens extensions",
"description": "OpenLens - Open Source Kubernetes IDE: extensions",
"version": "0.0.0",
"version": "5.3.0",
"copyright": "© 2021 OpenLens Authors",
"license": "MIT",
"main": "dist/src/extensions/extension-api.js",

View File

@ -3,9 +3,21 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { KubeObject, KubeObjectStatus } from "../renderer-api/k8s-api";
import type { KubeObject } from "../renderer-api/k8s-api";
import { BaseRegistry } from "./base-registry";
export enum KubeObjectStatusLevel {
INFO = 1,
WARNING = 2,
CRITICAL = 3,
}
export interface KubeObjectStatus {
level: KubeObjectStatusLevel;
text: string;
timestamp?: string;
}
export interface KubeObjectStatusRegistration {
kind: string;
apiVersions: string[];

View File

@ -8,7 +8,7 @@ import type React from "react";
import { BaseRegistry } from "./base-registry";
export interface WorkloadsOverviewDetailComponents {
Details: React.ComponentType<{}>;
Details: React.ComponentType;
}
export interface WorkloadsOverviewDetailRegistration {

View File

@ -8,9 +8,19 @@ import type { CatalogCategory, CatalogEntity } from "../../common/catalog";
import { catalogEntityRegistry as registry } from "../../renderer/api/catalog-entity-registry";
import type { CatalogEntityOnBeforeRun } from "../../renderer/api/catalog-entity-registry";
import type { Disposer } from "../../common/utils";
export type {
EntityFilter,
CatalogEntityOnBeforeRun,
} from "../../renderer/api/catalog-entity-registry";
export type { CatalogCategoryRegistry } from "../../common/catalog/catalog-category-registry";
export { catalogCategoryRegistry as catalogCategories } from "../../common/catalog/catalog-category-registry";
export class CatalogEntityRegistry {
/**
* The registry for entities synced to renderer
*/
class CatalogEntityRegistry {
/**
* Currently active/visible entity
*/
@ -18,18 +28,36 @@ export class CatalogEntityRegistry {
return registry.activeEntity;
}
/**
* The mapping of all entities from ID to instance
*/
get entities(): Map<string, CatalogEntity> {
return registry.entities;
}
getById(id: string) {
/**
* Attempt to get a catalog entity by its ID.
* @param id The ID of the desired entity
*/
getById(id: string): CatalogEntity | undefined {
return this.entities.get(id);
}
/**
* Get all the entities of a specific version and kind
* @param apiVersion The version string of an entity
* @param kind The kind of the entity
* @returns A list of entities matching that `apiVersion` and `kind`
*/
getItemsForApiKind<T extends CatalogEntity>(apiVersion: string, kind: string): T[] {
return registry.getItemsForApiKind<T>(apiVersion, kind);
}
/**
* Get all the entities for the kinds declared by a specific category
* @param category The category that declares different apiVersions for a specific kind
* @returns A list of entities matching the deckared `apiVersion`'s and `kind`
*/
getItemsForCategory<T extends CatalogEntity>(category: CatalogCategory): T[] {
return registry.getItemsForCategory(category);
}
@ -47,4 +75,6 @@ export class CatalogEntityRegistry {
}
}
export type { CatalogEntityRegistry };
export const catalogEntities = new CatalogEntityRegistry();

View File

@ -5,16 +5,26 @@
import { asLegacyGlobalFunctionForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api";
import createTerminalTabInjectable from "../../renderer/components/dock/terminal/create-terminal-tab.injectable";
import terminalStoreInjectable from "../../renderer/components/dock/terminal/store.injectable";
import type { TerminalStore as TerminalStoreType, TerminalTab } from "../../renderer/components/dock/terminal/store";
import { asLegacyGlobalObjectForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
import logTabStoreInjectable from "../../renderer/components/dock/logs/tab-store.injectable";
import commandOverlayInjectable from "../../renderer/components/command-palette/command-overlay.injectable";
import { asLegacyGlobalObjectForExtensionApiWithModifications } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api-with-modifications";
import createPodLogsTabInjectable from "../../renderer/components/dock/logs/create-pod-logs-tab.injectable";
import createWorkloadLogsTabInjectable from "../../renderer/components/dock/logs/create-workload-logs-tab.injectable";
import sendCommandInjectable from "../../renderer/components/dock/terminal/send-command.injectable";
import type { CommandOverlay as CommandPalletState } from "../../renderer/components/command-palette/command-overlay.injectable";
import createPodLogsTabInjectable, { PodLogsTabData } from "../../renderer/components/dock/logs/create-pod-logs-tab.injectable";
import createWorkloadLogsTabInjectable, { WorkloadLogsTabData } from "../../renderer/components/dock/logs/create-workload-logs-tab.injectable";
import sendCommandInjectable, { SendCommandOptions } from "../../renderer/components/dock/terminal/send-command.injectable";
import { podsStore } from "../../renderer/components/+workloads-pods/pods.store";
import renameTabInjectable from "../../renderer/components/dock/dock/rename-tab.injectable";
import type { DockTabStorageState } from "../../renderer/components/dock/dock-tab-store/dock-tab.store";
import type { LogTabData, LogTabOwnerRef, LogTabStore } from "../../renderer/components/dock/logs/tab-store";
import type { CommandActionContext, CommandActionNavigateOptions } from "../../renderer/components/command-palette/registered-commands/commands";
import type { TerminalApi, TerminalApiQuery, TerminalChannels, TerminalEvents, TerminalMessage } from "../../renderer/api/terminal-api";
import type { Terminal } from "../../renderer/components/dock/terminal/terminal";
import type { WebSocketApiState } from "../../renderer/api/websocket-api";
import type { HeaderCustomizer, ItemsFilters, ItemsFilter, SearchFilter, SearchFilters, HeaderPlaceholders, ItemListLayout, ItemListLayoutProps } from "../../renderer/components/item-object-list";
import type { ItemListLayoutHeader, ItemListLayoutHeaderProps } from "../../renderer/components/item-object-list/header";
import type { Filter, FilterType } from "../../renderer/components/item-object-list/page-filters.store";
// layouts
export * from "../../renderer/components/layout/main-layout";
@ -29,15 +39,37 @@ export * from "../../renderer/components/checkbox";
export * from "../../renderer/components/radio";
export * from "../../renderer/components/select";
export * from "../../renderer/components/slider";
export * from "../../renderer/components/switch";
export * from "../../renderer/components/input/input";
export { FormSwitch, Switcher } from "../../renderer/components/switch";
export type { SwitcherProps, SwitcherStyles } from "../../renderer/components/switch";
export {
Input,
InputValidators,
SearchInput,
} from "../../renderer/components/input";
export type {
IconData,
IconDataFnArg,
InputElement,
InputElementProps,
InputProps,
InputState,
InputValidator,
SearchInputProps,
SearchInputUrlProps,
} from "../../renderer/components/input";
// command-overlay
export const CommandOverlay = asLegacyGlobalObjectForExtensionApi(commandOverlayInjectable);
export type {
CommandPalletState,
CommandActionContext,
CommandActionNavigateOptions,
};
export const CommandOverlay = asLegacyGlobalObjectForExtensionApi(commandOverlayInjectable) as CommandPalletState;
export type {
CategoryColumnRegistration,
AdditionalCategoryColumnRegistration,
TitleCellProps,
} from "../../renderer/components/+catalog/custom-category-columns";
// other components
@ -59,14 +91,32 @@ export * from "../../renderer/components/+workloads-pods/pod-details-list";
export * from "../../renderer/components/+namespaces/namespace-select";
export * from "../../renderer/components/+namespaces/namespace-select-filter";
export * from "../../renderer/components/layout/sub-title";
export * from "../../renderer/components/input/search-input";
export * from "../../renderer/components/chart/bar-chart";
export * from "../../renderer/components/chart/pie-chart";
export * from "../../renderer/components/chart";
// kube helpers
export * from "../../renderer/components/kube-detail-params";
export * from "../../renderer/components/kube-object-details";
export * from "../../renderer/components/kube-object-list-layout";
export type { AddRemoveButtonsProps } from "../../renderer/components/add-remove-buttons";
export {
cssNames,
type IClassName,
type IClassNameMap,
} from "../../renderer/utils";
export type {
HeaderCustomizer,
ItemsFilters,
ItemsFilter,
FilterType,
Filter,
SearchFilter,
SearchFilters,
HeaderPlaceholders,
ItemListLayout,
ItemListLayoutProps,
ItemListLayoutHeader,
ItemListLayoutHeaderProps,
};
export * from "../../renderer/components/kube-object-menu";
export * from "../../renderer/components/kube-object-meta";
export * from "../../renderer/components/+events/kube-event-details";
@ -74,31 +124,59 @@ export * from "../../renderer/components/+events/kube-event-details";
// specific exports
export * from "../../renderer/components/status-brick";
export type {
SendCommandOptions,
PodLogsTabData,
WorkloadLogsTabData,
DockTabStorageState,
};
export type {
TabKind,
TabId,
DockTabCreateOption,
BaseDockTabCreateOptions,
} from "../../renderer/components/dock/dock/store";
export const createTerminalTab = asLegacyGlobalFunctionForExtensionApi(createTerminalTabInjectable);
export const terminalStore = asLegacyGlobalObjectForExtensionApiWithModifications(terminalStoreInjectable, {
sendCommand: () => asLegacyGlobalFunctionForExtensionApi(sendCommandInjectable),
export type {
TerminalStoreType,
TerminalApi,
Terminal,
TerminalTab,
TerminalApiQuery,
WebSocketApiState,
TerminalEvents,
TerminalMessage,
TerminalChannels,
};
export const terminalStore = Object.assign(asLegacyGlobalObjectForExtensionApi(terminalStoreInjectable), {
sendCommand: asLegacyGlobalFunctionForExtensionApi(sendCommandInjectable),
});
export const logTabStore = asLegacyGlobalObjectForExtensionApiWithModifications(logTabStoreInjectable, {
createPodTab: () => asLegacyGlobalFunctionForExtensionApi(createPodLogsTabInjectable),
createWorkloadTab: () => asLegacyGlobalFunctionForExtensionApi(createWorkloadLogsTabInjectable),
renameTab: () => (tabId: string): void => {
export const TerminalStore = {
getInstance() {
return terminalStore;
},
createInstance() {
return terminalStore;
},
resetInstance() {
console.warn("TerminalStore.resetInstance() does nothing");
},
};
export type { LogTabStore, LogTabData, LogTabOwnerRef };
export const logTabStore = Object.assign(asLegacyGlobalObjectForExtensionApi(logTabStoreInjectable), {
createPodTab: asLegacyGlobalFunctionForExtensionApi(createPodLogsTabInjectable),
createWorkloadTab: asLegacyGlobalFunctionForExtensionApi(createWorkloadLogsTabInjectable),
renameTab: (tabId: string): void => {
const renameTab = asLegacyGlobalFunctionForExtensionApi(renameTabInjectable);
const tabData = logTabStore.getData(tabId);
const pod = podsStore.getById(tabData.selectedPodId);
renameTab(tabId, `Pod ${pod.getName()}`);
},
tabs: () => undefined,
tabs: undefined,
});
export class TerminalStore {
static getInstance() {
return terminalStore;
}
static createInstance() {
return terminalStore;
}
static resetInstance() {
console.warn("TerminalStore.resetInstance() does nothing");
}
}

View File

@ -12,80 +12,88 @@ export function isAllowedResource(resource: KubeResource | KubeResource[]) {
const resources = castArray(resource);
return resources.every(x => _isAllowedResource(x));
return resources.every(_isAllowedResource);
}
export { ResourceStack } from "../../common/k8s/resource-stack";
export { apiManager } from "../../common/k8s-api/api-manager";
export { KubeObjectStore } from "../../common/k8s-api/kube-object.store";
export { KubeApi, forCluster, forRemoteCluster } from "../../common/k8s-api/kube-api";
export { KubeObject, KubeStatus } from "../../common/k8s-api/kube-object";
export { Pod, podsApi, PodsApi } from "../../common/k8s-api/endpoints";
export { Node, nodesApi, NodesApi } from "../../common/k8s-api/endpoints";
export { Deployment, deploymentApi, DeploymentApi } from "../../common/k8s-api/endpoints";
export { DaemonSet, daemonSetApi } from "../../common/k8s-api/endpoints";
export { StatefulSet, statefulSetApi } from "../../common/k8s-api/endpoints";
export { Job, jobApi } from "../../common/k8s-api/endpoints";
export { CronJob, cronJobApi } from "../../common/k8s-api/endpoints";
export { ConfigMap, configMapApi } from "../../common/k8s-api/endpoints";
export { Secret, secretsApi } from "../../common/k8s-api/endpoints";
export { ReplicaSet, replicaSetApi } from "../../common/k8s-api/endpoints";
export { ResourceQuota, resourceQuotaApi } from "../../common/k8s-api/endpoints";
export { LimitRange, limitRangeApi } from "../../common/k8s-api/endpoints";
export { HorizontalPodAutoscaler, hpaApi } from "../../common/k8s-api/endpoints";
export { PodDisruptionBudget, pdbApi } from "../../common/k8s-api/endpoints";
export { Service, serviceApi } from "../../common/k8s-api/endpoints";
export { Endpoint, endpointApi } from "../../common/k8s-api/endpoints";
export { Ingress, ingressApi, IngressApi } from "../../common/k8s-api/endpoints";
export { NetworkPolicy, networkPolicyApi } from "../../common/k8s-api/endpoints";
export { PersistentVolume, persistentVolumeApi } from "../../common/k8s-api/endpoints";
export { PersistentVolumeClaim, pvcApi, PersistentVolumeClaimsApi } from "../../common/k8s-api/endpoints";
export { StorageClass, storageClassApi } from "../../common/k8s-api/endpoints";
export { Namespace, namespacesApi } from "../../common/k8s-api/endpoints";
export { KubeEvent, eventApi } from "../../common/k8s-api/endpoints";
export { ServiceAccount, serviceAccountsApi } from "../../common/k8s-api/endpoints";
export { Role, roleApi } from "../../common/k8s-api/endpoints";
export { RoleBinding, roleBindingApi } from "../../common/k8s-api/endpoints";
export { ClusterRole, clusterRoleApi } from "../../common/k8s-api/endpoints";
export { ClusterRoleBinding, clusterRoleBindingApi } from "../../common/k8s-api/endpoints";
export { CustomResourceDefinition, crdApi } from "../../common/k8s-api/endpoints";
export { KubeObjectStatusLevel } from "./kube-object-status";
export { KubeJsonApi } from "../../common/k8s-api/kube-json-api";
export * from "../common-k8s-api";
// types
export type { ILocalKubeApiConfig, IRemoteKubeApiConfig, IKubeApiCluster } from "../../common/k8s-api/kube-api";
export type { IPodContainer, IPodContainerStatus } from "../../common/k8s-api/endpoints";
export type { ISecretRef } from "../../common/k8s-api/endpoints";
export type { KubeObjectStatus } from "./kube-object-status";
export type { KubeObjectMetadata, KubeStatusData } from "../../common/k8s-api/kube-object";
export type { KubeObjectStoreLoadAllParams, KubeObjectStoreLoadingParams, KubeObjectStoreSubscribeParams } from "../../common/k8s-api/kube-object.store";
export type {
KubeResource,
} from "../../common/rbac";
export type {
IKubeObjectRef,
} from "../../common/k8s-api/kube-api-parse";
export {
apiManager,
} from "../../common/k8s-api/api-manager";
export type {
ApiManager,
} from "../../common/k8s-api/api-manager";
export {
clusterRoleApi,
clusterRoleBindingApi,
configMapApi,
crdApi,
cronJobApi,
daemonSetApi,
deploymentApi,
endpointApi,
eventApi,
hpaApi,
ingressApi,
jobApi,
limitRangeApi,
namespacesApi,
networkPolicyApi,
nodesApi,
pdbApi,
persistentVolumeApi,
podsApi,
pvcApi,
replicaSetApi,
resourceQuotaApi,
roleApi,
roleBindingApi,
secretsApi,
serviceAccountsApi,
serviceApi,
statefulSetApi,
storageClassApi,
} from "../../common/k8s-api/endpoints";
// stores
export type { EventStore } from "../../renderer/components/+events/event.store";
export type { PodsStore } from "../../renderer/components/+workloads-pods/pods.store";
export type { NodesStore } from "../../renderer/components/+nodes/nodes.store";
export type { DeploymentStore } from "../../renderer/components/+workloads-deployments/deployments.store";
export type { DaemonSetStore } from "../../renderer/components/+workloads-daemonsets/daemonsets.store";
export type { StatefulSetStore } from "../../renderer/components/+workloads-statefulsets/statefulset.store";
export type { JobStore } from "../../renderer/components/+workloads-jobs/job.store";
export type { CronJobStore } from "../../renderer/components/+workloads-cronjobs/cronjob.store";
export type { ClusterRoleBindingsStore } from "../../renderer/components/+user-management/+cluster-role-bindings/store";
export type { ClusterRolesStore } from "../../renderer/components/+user-management/+cluster-roles/store";
export type { ConfigMapsStore } from "../../renderer/components/+config-maps/config-maps.store";
export type { SecretsStore } from "../../renderer/components/+config-secrets/secrets.store";
export type { CRDResourceStore } from "../../renderer/components/+custom-resources/crd-resource.store";
export type { CRDStore } from "../../renderer/components/+custom-resources/crd.store";
export type { CronJobStore } from "../../renderer/components/+workloads-cronjobs/cronjob.store";
export type { DaemonSetStore } from "../../renderer/components/+workloads-daemonsets/daemonsets.store";
export type { DeploymentStore } from "../../renderer/components/+workloads-deployments/deployments.store";
export type { EndpointStore } from "../../renderer/components/+network-endpoints/endpoints.store";
export type { EventStore } from "../../renderer/components/+events/event.store";
export type { HPAStore } from "../../renderer/components/+config-autoscalers/hpa.store";
export type { IngressStore } from "../../renderer/components/+network-ingresses/ingress.store";
export type { JobStore } from "../../renderer/components/+workloads-jobs/job.store";
export type { LimitRangesStore } from "../../renderer/components/+config-limit-ranges/limit-ranges.store";
export type { NamespaceStore } from "../../renderer/components/+namespaces/namespace-store/namespace.store";
export type { NetworkPolicyStore } from "../../renderer/components/+network-policies/network-policy.store";
export type { NodesStore } from "../../renderer/components/+nodes/nodes.store";
export type { PersistentVolumesStore } from "../../renderer/components/+storage-volumes/volumes.store";
export type { PodDisruptionBudgetsStore } from "../../renderer/components/+config-pod-disruption-budgets/pod-disruption-budgets.store";
export type { PodsStore } from "../../renderer/components/+workloads-pods/pods.store";
export type { ReplicaSetStore } from "../../renderer/components/+workloads-replicasets/replicasets.store";
export type { ResourceQuotasStore } from "../../renderer/components/+config-resource-quotas/resource-quotas.store";
export type { LimitRangesStore } from "../../renderer/components/+config-limit-ranges/limit-ranges.store";
export type { HPAStore } from "../../renderer/components/+config-autoscalers/hpa.store";
export type { PodDisruptionBudgetsStore } from "../../renderer/components/+config-pod-disruption-budgets/pod-disruption-budgets.store";
export type { ServiceStore } from "../../renderer/components/+network-services/services.store";
export type { EndpointStore } from "../../renderer/components/+network-endpoints/endpoints.store";
export type { IngressStore } from "../../renderer/components/+network-ingresses/ingress.store";
export type { NetworkPolicyStore } from "../../renderer/components/+network-policies/network-policy.store";
export type { PersistentVolumesStore } from "../../renderer/components/+storage-volumes/volumes.store";
export type { VolumeClaimStore } from "../../renderer/components/+storage-volume-claims/volume-claim.store";
export type { StorageClassStore } from "../../renderer/components/+storage-classes/storage-class.store";
export type { NamespaceStore } from "../../renderer/components/+namespaces/namespace-store/namespace.store";
export type { ServiceAccountsStore } from "../../renderer/components/+user-management/+service-accounts/store";
export type { RolesStore } from "../../renderer/components/+user-management/+roles/store";
export type { RoleBindingsStore } from "../../renderer/components/+user-management/+role-bindings/store";
export type { CRDStore } from "../../renderer/components/+custom-resources/crd.store";
export type { CRDResourceStore } from "../../renderer/components/+custom-resources/crd-resource.store";
export type { RolesStore } from "../../renderer/components/+user-management/+roles/store";
export type { SecretsStore } from "../../renderer/components/+config-secrets/secrets.store";
export type { ServiceAccountsStore } from "../../renderer/components/+user-management/+service-accounts/store";
export type { ServiceStore } from "../../renderer/components/+network-services/services.store";
export type { StatefulSetStore } from "../../renderer/components/+workloads-statefulsets/statefulset.store";
export type { StorageClassStore } from "../../renderer/components/+storage-classes/storage-class.store";
export type { VolumeClaimStore } from "../../renderer/components/+storage-volume-claims/volume-claim.store";
export type {
KubeObjectStoreLoadAllParams,
KubeObjectStoreLoadingParams,
KubeObjectStoreSubscribeParams,
} from "../../common/k8s-api/kube-object.store";

View File

@ -1,16 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export interface KubeObjectStatus {
level: KubeObjectStatusLevel;
text: string;
timestamp?: string;
}
export enum KubeObjectStatusLevel {
INFO = 1,
WARNING = 2,
CRITICAL = 3,
}

View File

@ -5,6 +5,9 @@
import { ThemeStore } from "../../renderer/theme.store";
export type { Theme } from "../../renderer/theme.store";
export type { MonacoTheme, MonacoCustomTheme } from "../../renderer/components/monaco-editor";
export function getActiveTheme() {
return ThemeStore.getInstance().activeTheme;
}

View File

@ -15,6 +15,11 @@ import { preferencesURL, extensionsURL, addClusterURL, catalogURL, welcomeURL }
import { checkForUpdates, isAutoUpdateEnabled } from "../app-updater";
import type { MenuRegistration } from "./menu-registration";
/**
* The IDs of the menus that Lens uses.
*
* Note: `"mac"` is only valid on macOS
*/
export type MenuTopId = "mac" | "file" | "edit" | "view" | "help";
interface MenuItemsOpts extends MenuItemConstructorOptions {

View File

@ -60,6 +60,9 @@ export interface TerminalEvents extends WebSocketEvents {
}
export class TerminalApi extends WebSocketApi<TerminalEvents> {
/**
* @internal
*/
protected size: { width: number; height: number };
@observable public isReady = false;
@ -144,6 +147,9 @@ export class TerminalApi extends WebSocketApi<TerminalEvents> {
}
}
/**
* @internal
*/
protected _onMessage({ data, ...evt }: MessageEvent<ArrayBuffer>): void {
try {
const message: TerminalMessage = deserialize(new Uint8Array(data));
@ -169,6 +175,9 @@ export class TerminalApi extends WebSocketApi<TerminalEvents> {
}
}
/**
* @internal
*/
protected _onOpen(evt: Event) {
// Client should send terminal size in special channel 4,
// But this size will be changed by terminal.fit()
@ -176,11 +185,17 @@ export class TerminalApi extends WebSocketApi<TerminalEvents> {
super._onOpen(evt);
}
/**
* @internal
*/
protected _onClose(evt: CloseEvent) {
super._onClose(evt);
this.isReady = false;
}
/**
* @internal
*/
protected emitStatus(data: string, options: { color?: TerminalColor; showTime?: boolean } = {}) {
const { color, showTime } = options;
const time = showTime ? `${(new Date()).toLocaleString()} ` : "";
@ -192,6 +207,9 @@ export class TerminalApi extends WebSocketApi<TerminalEvents> {
this.emit("data", `${time}${data}\r\n`);
}
/**
* @internal
*/
protected emitError(error: string) {
this.emitStatus(error, {
color: TerminalColor.RED,

View File

@ -8,6 +8,7 @@ import EventEmitter from "events";
import type TypedEventEmitter from "typed-emitter";
import type { Arguments } from "typed-emitter";
import { isDevelopment } from "../../common/vars";
import type { Defaulted } from "../utils";
interface WebsocketApiParams {
/**
@ -62,28 +63,29 @@ export interface WebSocketEvents {
close: () => void;
}
type Defaulted<Params, DefaultParams extends keyof Params> = Required<Pick<Params, DefaultParams>> & Omit<Params, DefaultParams>;
export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter as { new<T>(): TypedEventEmitter<T> })<Events> {
protected socket?: WebSocket | null;
protected pendingCommands: (string | ArrayBufferLike | Blob | ArrayBufferView)[] = [];
protected reconnectTimer?: any;
protected pingTimer?: any;
protected params: Defaulted<WebsocketApiParams, keyof typeof WebSocketApi["defaultParams"]>;
@observable readyState = WebSocketApiState.PENDING;
private static defaultParams = {
const defaultWebsocketApiParams = {
logging: isDevelopment,
reconnectDelay: 10,
flushOnOpen: true,
pingMessage: "PING",
};
export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter as { new<T>(): TypedEventEmitter<T> })<Events> {
protected socket?: WebSocket | null;
protected pendingCommands: (string | ArrayBufferLike | Blob | ArrayBufferView)[] = [];
protected reconnectTimer?: any;
protected pingTimer?: any;
private params: Defaulted<WebsocketApiParams, keyof typeof defaultWebsocketApiParams>;
@observable readyState = WebSocketApiState.PENDING;
constructor(params: WebsocketApiParams) {
super();
makeObservable(this);
this.params = Object.assign({}, WebSocketApi.defaultParams, params);
this.params = {
...defaultWebsocketApiParams,
...params,
};
const { pingInterval } = this.params;
if (pingInterval) {

View File

@ -10,7 +10,7 @@ import { Icon } from "../icon";
import { observer } from "mobx-react";
import { observable, makeObservable, action } from "mobx";
import { boundMethod } from "../../../common/utils";
import type { CatalogCategory, CatalogEntityAddMenuContext, CatalogEntityAddMenu } from "../../api/catalog-entity";
import type { CatalogCategory, CatalogEntityAddMenu } from "../../api/catalog-entity";
import { EventEmitter } from "events";
import { navigate } from "../../navigation";
import { catalogCategoryRegistry } from "../../api/catalog-category-registry";
@ -60,12 +60,11 @@ export class CatalogAddButton extends React.Component<CatalogAddButtonProps> {
updateCategoryItems = action((category: CatalogCategory) => {
if (category instanceof EventEmitter) {
const menuItems: CatalogEntityAddMenu[] = [];
const context: CatalogEntityAddMenuContext = {
category.emit("catalogAddMenu", {
navigate: (url: string) => navigate(url),
menuItems,
};
category.emit("catalogAddMenu", context);
});
this.menuItems.set(category.getId(), menuItems);
}
});
@ -86,10 +85,13 @@ export class CatalogAddButton extends React.Component<CatalogAddButtonProps> {
@boundMethod
onButtonClick() {
const defaultAction = this.items.find(item => item.defaultAction)?.onClick;
const clickAction = defaultAction || (this.items.length === 1 ? this.items[0].onClick : null);
const defaultActions = this.items.filter(item => item.defaultAction);
clickAction?.();
if (defaultActions.length === 1) {
defaultActions[0].onClick();
} else if (defaultActions.length === 0 && this.items.length === 1) {
this.items[0].onClick();
}
}
get items() {

View File

@ -11,7 +11,14 @@ import type { TableCellProps } from "../table";
* These are the supported props for the title cell
*/
export interface TitleCellProps {
/**
* An optional className entry
*/
className?: string;
/**
* The actual title for the column
*/
title: string;
}

View File

@ -45,6 +45,16 @@ interface Dependencies {
extensionInstallationStateStore: ExtensionInstallationStateStore;
}
interface Dependencies {
userExtensions: IComputedValue<InstalledExtension[]>;
enableExtension: (id: LensExtensionId) => void;
disableExtension: (id: LensExtensionId) => void;
confirmUninstallExtension: (extension: InstalledExtension) => Promise<void>;
installFromInput: (input: string) => Promise<void>;
installFromSelectFileDialog: () => Promise<void>;
installOnDrop: (files: File[]) => Promise<void>;
}
@observer
class NonInjectedExtensions extends React.Component<Dependencies> {
@observable installPath = "";

View File

@ -88,13 +88,9 @@ class NonInjectedNamespaceSelect extends React.Component<NamespaceSelectProps &
}
}
export const NamespaceSelect = withInjectables<Dependencies, NamespaceSelectProps>(
NonInjectedNamespaceSelect,
{
export const NamespaceSelect = withInjectables<Dependencies, NamespaceSelectProps>(NonInjectedNamespaceSelect, {
getProps: (di, props) => ({
namespaceStore: di.inject(namespaceStoreInjectable),
...props,
}),
},
);
});

View File

@ -15,6 +15,9 @@ interface Dependencies {
export class NamespaceStore extends KubeObjectStore<Namespace> {
api = namespacesApi;
/**
* @internal
*/
constructor(private dependencies: Dependencies) {
super();
makeObservable(this);

View File

@ -12,7 +12,12 @@ jest.mock("../../kube-object-meta");
describe("NetworkPolicyDetails", () => {
it("should render w/o errors", () => {
const policy = new NetworkPolicy({ metadata: {} as any, spec: {}} as any);
const policy = new NetworkPolicy({
metadata: {} as any,
kind: "NetworkPolicy",
apiVersion:"networking.k8s.io/v1",
spec: {},
});
const { container } = render(<NetworkPolicyDetails object={policy} />);
expect(container).toBeInstanceOf(HTMLElement);
@ -31,7 +36,12 @@ describe("NetworkPolicyDetails", () => {
}],
podSelector: {},
};
const policy = new NetworkPolicy({ metadata: {} as any, spec } as any);
const policy = new NetworkPolicy({
metadata: {} as any,
kind: "NetworkPolicy",
apiVersion: "networking.k8s.io/v1",
spec,
});
const { container } = render(<NetworkPolicyDetails object={policy} />);
expect(await findByTestId(container, "egress-0")).toBeInstanceOf(HTMLElement);
@ -47,7 +57,12 @@ describe("NetworkPolicyDetails", () => {
}],
podSelector: {},
};
const policy = new NetworkPolicy({ metadata: {} as any, spec } as any);
const policy = new NetworkPolicy({
metadata: {} as any,
kind: "NetworkPolicy",
apiVersion: "networking.k8s.io/v1",
spec,
});
const { container } = render(<NetworkPolicyDetails object={policy} />);
expect(container).toBeInstanceOf(HTMLElement);

View File

@ -21,6 +21,9 @@ interface State {
}
export class ServiceAccountsSecret extends React.Component<ServiceAccountsSecretProps, State> {
/**
* @internal
*/
public state: State = {
showToken: false,
};

View File

@ -9,7 +9,7 @@ import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store";
import { autoBind, cpuUnitsToNumber, unitsToBytes } from "../../utils";
import { Pod, PodMetrics, podMetricsApi, podsApi } from "../../../common/k8s-api/endpoints";
import { apiManager } from "../../../common/k8s-api/api-manager";
import type { WorkloadKubeObject } from "../../../common/k8s-api/workload-kube-object";
import type { KubeObject } from "../../../common/k8s-api/kube-object";
export class PodsStore extends KubeObjectStore<Pod> {
api = podsApi;
@ -31,7 +31,7 @@ export class PodsStore extends KubeObjectStore<Pod> {
}
}
getPodsByOwner(workload: WorkloadKubeObject): Pod[] {
getPodsByOwner(workload: KubeObject): Pod[] {
if (!workload) return [];
return this.items.filter(pod => {

View File

@ -16,8 +16,16 @@ import { ThemeStore } from "../../theme.store";
import { NoMetrics } from "../resource-metrics/no-metrics";
export interface BarChartProps extends ChartProps {
/**
* The name of the chart
*/
name?: string;
timeLabelStep?: number; // Minute labels appearance step
/**
* The step between the minute labels
* @default 10
*/
timeLabelStep?: number;
}
const defaultProps: Partial<BarChartProps> = {

View File

@ -15,7 +15,9 @@ export interface CommandContext {
export interface CommandActionNavigateOptions {
/**
* If `true` then the navigate will only navigate on the root frame and not
* within a cluster
* within a cluster's frame.
*
* If `false` then the navigation will only occur in the current frame
* @default false
*/
forceRootFrame?: boolean;

View File

@ -15,7 +15,7 @@ import type { CommandContext, CommandRegistration } from "./commands";
import { getInjectable } from "@ogre-tools/injectable";
import commandOverlayInjectable from "../command-overlay.injectable";
import createTerminalTabInjectable from "../../dock/terminal/create-terminal-tab.injectable";
import type { DockTabCreate } from "../../dock/dock/store";
import type { BaseDockTabCreateOptions } from "../../dock/dock/store";
export function isKubernetesClusterActive(context: CommandContext): boolean {
return context.entity?.kind === "KubernetesCluster";
@ -24,7 +24,7 @@ export function isKubernetesClusterActive(context: CommandContext): boolean {
interface Dependencies {
openCommandDialog: (component: React.ReactElement) => void;
getEntitySettingItems: (kind: string, apiVersion: string, source?: string) => RegisteredEntitySetting[];
createTerminalTab: () => DockTabCreate;
createTerminalTab: () => BaseDockTabCreateOptions;
}
function getInternalCommands({ openCommandDialog, getEntitySettingItems, createTerminalTab }: Dependencies): CommandRegistration[] {

View File

@ -27,13 +27,12 @@ export interface DialogProps {
animated?: boolean;
"data-testid"?: string;
}
interface DialogState {
export interface DialogState {
isOpen: boolean;
}
@observer
export class Dialog extends React.PureComponent<DialogProps, DialogState> {
export class Dialog extends React.Component<DialogProps, DialogState> {
private contentElem: HTMLElement;
ref = React.createRef<HTMLDivElement>();
@ -48,6 +47,9 @@ export class Dialog extends React.PureComponent<DialogProps, DialogState> {
pinned: false,
};
/**
* @internal
*/
public state: DialogState = {
isOpen: this.props.isOpen,
};

View File

@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import dockStoreInjectable from "../dock/store.injectable";
import { DockTabCreateSpecific, TabKind } from "../dock/store";
import { DockTabCreateOption, TabKind } from "../dock/store";
const createResourceTabInjectable = getInjectable({
id: "create-resource-tab",
@ -12,7 +12,7 @@ const createResourceTabInjectable = getInjectable({
instantiate: (di) => {
const dockStore = di.inject(dockStoreInjectable);
return (tabParams: DockTabCreateSpecific = {}) =>
return (tabParams: DockTabCreateOption = {}) =>
dockStore.createTab({
title: "Create resource",
...tabParams,

View File

@ -4,7 +4,7 @@
*/
import { action, observable, reaction } from "mobx";
import { autoBind, StorageHelper, toJS } from "../../../utils";
import { autoBind, noop, StorageHelper, toJS } from "../../../utils";
import type { TabId } from "../dock/store";
export interface DockTabStoreOptions {
@ -19,36 +19,40 @@ interface DockTabStoreDependencies {
}
export class DockTabStore<T> {
/**
* @internal
*/
protected storage?: StorageHelper<DockTabStorageState<T>>;
private data = observable.map<TabId, T>();
constructor(protected dependencies: DockTabStoreDependencies, protected options: DockTabStoreOptions) {
/**
* @internal
*/
protected dependencies: DockTabStoreDependencies;
constructor(dependencies: DockTabStoreDependencies, { autoInit = true, storageKey }: DockTabStoreOptions) {
autoBind(this);
this.options = {
autoInit: true,
...this.options,
};
this.dependencies = dependencies;
if (this.options.autoInit) {
this.init();
}
}
protected init() {
const { storageKey } = this.options;
// auto-save to local-storage
if (storageKey) {
this.init = storageKey
? (() => {
this.storage = this.dependencies.createStorage<T>(storageKey, {});
this.storage.whenReady.then(() => {
this.data.replace(this.storage.value);
reaction(() => this.toJSON(), data => this.storage.set(data));
});
})
: noop;
if (autoInit) {
this.init();
}
}
protected init: () => void;
protected finalizeDataForSave(data: T): T {
return data;
}

View File

@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import dockStoreInjectable from "./store.injectable";
import type { DockTab, DockTabCreate } from "./store";
import type { DockTab, BaseDockTabCreateOptions } from "./store";
const createDockTabInjectable = getInjectable({
id: "create-dock-tab",
@ -12,7 +12,7 @@ const createDockTabInjectable = getInjectable({
instantiate: (di) => {
const dockStore = di.inject(dockStoreInjectable);
return (rawTabDesc: DockTabCreate, addNumber?: boolean): DockTab =>
return (rawTabDesc: BaseDockTabCreateOptions, addNumber?: boolean): DockTab =>
dockStore.createTab(rawTabDesc, addNumber);
},
});

View File

@ -24,12 +24,12 @@ export enum TabKind {
*
* All fields are required.
*/
export type DockTab = Required<DockTabCreate>;
export type DockTab = Required<BaseDockTabCreateOptions>;
/**
* These are the arguments for creating a new Tab on the dock
*/
export interface DockTabCreate {
export interface BaseDockTabCreateOptions {
/**
* The ID of the tab for reference purposes.
*/
@ -63,7 +63,7 @@ export interface DockTabCreate {
* That way users should get a type error if they try and specify a `kind`
* themselves.
*/
export type DockTabCreateSpecific = Omit<DockTabCreate, "kind">;
export type DockTabCreateOption = Omit<BaseDockTabCreateOptions, "kind">;
export interface DockStorageState {
height: number;
@ -288,7 +288,7 @@ export class DockStore implements DockStorageState {
}
}
createTab = action((rawTabDesc: DockTabCreate, addNumber = true): DockTab => {
createTab = action((rawTabDesc: BaseDockTabCreateOptions, addNumber = true): DockTab => {
const {
id = uuid.v4(),
kind,

View File

@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import editResourceTabStoreInjectable from "./store.injectable";
import dockStoreInjectable from "../dock/store.injectable";
import type { KubeObject } from "../../../../common/k8s-api/kube-object";
import { DockStore, DockTabCreateSpecific, TabId, TabKind } from "../dock/store";
import { DockStore, DockTabCreateOption, TabId, TabKind } from "../dock/store";
import type { EditResourceTabStore } from "./store";
import { runInAction } from "mobx";
@ -15,7 +15,7 @@ interface Dependencies {
editResourceStore: EditResourceTabStore;
}
const createEditResourceTab = ({ dockStore, editResourceStore }: Dependencies) => (object: KubeObject, tabParams: DockTabCreateSpecific = {}): TabId => {
const createEditResourceTab = ({ dockStore, editResourceStore }: Dependencies) => (object: KubeObject, tabParams: DockTabCreateOption = {}): TabId => {
// use existing tab if already opened
const tabId = editResourceStore.getTabIdByResource(object);

View File

@ -17,12 +17,12 @@ import { Notifications } from "../notifications";
import { withInjectables } from "@ogre-tools/injectable-react";
import dockStoreInjectable from "./dock/store.injectable";
export interface InfoPanelProps extends OptionalProps {
export interface InfoPanelProps extends InfoPanelOptionalProps {
tabId: TabId;
submit?: () => Promise<ReactNode | string | void>;
}
export interface OptionalProps {
export interface InfoPanelOptionalProps {
className?: string;
error?: string;
controls?: ReactNode;
@ -42,7 +42,7 @@ interface Dependencies {
@observer
class NonInjectedInfoPanel extends Component<InfoPanelProps & Dependencies> {
static defaultProps: OptionalProps = {
static defaultProps: InfoPanelOptionalProps = {
submitLabel: "Submit",
submittingMessage: "Submitting..",
showButtons: true,

View File

@ -7,19 +7,19 @@ import installChartTabStoreInjectable from "./store.injectable";
import type { HelmChart } from "../../../../common/k8s-api/endpoints/helm-charts.api";
import {
DockTab,
DockTabCreate,
DockTabCreateSpecific,
BaseDockTabCreateOptions,
DockTabCreateOption,
TabKind,
} from "../dock/store";
import type { InstallChartTabStore } from "./store";
import createDockTabInjectable from "../dock/create-dock-tab.injectable";
interface Dependencies {
createDockTab: (rawTab: DockTabCreate, addNumber: boolean) => DockTab;
createDockTab: (rawTab: BaseDockTabCreateOptions, addNumber: boolean) => DockTab;
installChartStore: InstallChartTabStore;
}
const createInstallChartTab = ({ createDockTab, installChartStore }: Dependencies) => (chart: HelmChart, tabParams: DockTabCreateSpecific = {}) => {
const createInstallChartTab = ({ createDockTab, installChartStore }: Dependencies) => (chart: HelmChart, tabParams: DockTabCreateOption = {}) => {
const { name, repo, version } = chart;
const tab = createDockTab(

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { DockTabCreate, DockTab, TabKind, TabId } from "../dock/store";
import { BaseDockTabCreateOptions, DockTab, TabKind, TabId } from "../dock/store";
import type { LogTabData } from "./tab-store";
import * as uuid from "uuid";
import { runInAction } from "mobx";
@ -13,7 +13,7 @@ import setLogTabDataInjectable from "./set-log-tab-data.injectable";
export type CreateLogsTabData = Pick<LogTabData, "owner" | "selectedPodId" | "selectedContainer" | "namespace"> & Omit<Partial<LogTabData>, "owner" | "selectedPodId" | "selectedContainer" | "namespace">;
interface Dependencies {
createDockTab: (rawTabDesc: DockTabCreate, addNumber?: boolean) => DockTab;
createDockTab: (rawTabDesc: BaseDockTabCreateOptions, addNumber?: boolean) => DockTab;
setLogTabData: (tabId: string, data: LogTabData) => void;
}

View File

@ -4,12 +4,12 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import { podsStore } from "../../+workloads-pods/pods.store";
import type { WorkloadKubeObject } from "../../../../common/k8s-api/workload-kube-object";
import type { DaemonSet, Deployment, Job, Pod, ReplicaSet, StatefulSet } from "../../../../common/k8s-api/endpoints";
import type { TabId } from "../dock/store";
import createLogsTabInjectable, { CreateLogsTabData } from "./create-logs-tab.injectable";
export interface WorkloadLogsTabData {
workload: WorkloadKubeObject;
workload: DaemonSet | Deployment | Job | Pod | ReplicaSet | StatefulSet;
}
interface Dependencies {

View File

@ -61,7 +61,10 @@ interface Dependencies {
}
export class LogTabStore extends DockTabStore<LogTabData> {
constructor(protected dependencies: Dependencies) {
/**
* @internal
*/
constructor(dependencies: Dependencies) {
super(dependencies, {
storageKey: "pod_logs",
});

View File

@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import dockStoreInjectable from "../dock/store.injectable";
import { DockTabCreateSpecific, TabKind } from "../dock/store";
import { DockTabCreateOption, TabKind } from "../dock/store";
const createTerminalTabInjectable = getInjectable({
id: "create-terminal-tab",
@ -12,7 +12,7 @@ const createTerminalTabInjectable = getInjectable({
instantiate: (di) => {
const dockStore = di.inject(dockStoreInjectable);
return (tabParams: DockTabCreateSpecific = {}) =>
return (tabParams: DockTabCreateOption = {}) =>
dockStore.createTab({
title: `Terminal`,
...tabParams,

View File

@ -9,7 +9,7 @@ import { TerminalApi } from "../../../api/terminal-api";
import type { DockTab, TabId } from "../dock/store";
import { WebSocketApiState } from "../../../api/websocket-api";
export interface ITerminalTab extends DockTab {
export interface TerminalTab extends DockTab {
node?: string; // activate node shell mode
}
@ -21,11 +21,14 @@ export class TerminalStore {
protected terminals = new Map<TabId, Terminal>();
protected connections = observable.map<TabId, TerminalApi>();
/**
* @internal
*/
constructor(private dependencies: Dependencies) {
}
@action
connect(tab: ITerminalTab) {
connect(tab: TerminalTab) {
if (this.isConnected(tab.id)) {
return;
}

View File

@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import upgradeChartTabStoreInjectable from "./store.injectable";
import dockStoreInjectable from "../dock/store.injectable";
import type { HelmRelease } from "../../../../common/k8s-api/endpoints/helm-releases.api";
import { DockStore, DockTabCreateSpecific, TabId, TabKind } from "../dock/store";
import { DockStore, DockTabCreateOption, TabId, TabKind } from "../dock/store";
import type { UpgradeChartTabStore } from "./store";
import { runInAction } from "mobx";
@ -15,7 +15,7 @@ interface Dependencies {
dockStore: DockStore;
}
const createUpgradeChartTab = ({ upgradeChartStore, dockStore }: Dependencies) => (release: HelmRelease, tabParams: DockTabCreateSpecific = {}): TabId => {
const createUpgradeChartTab = ({ upgradeChartStore, dockStore }: Dependencies) => (release: HelmRelease, tabParams: DockTabCreateOption = {}): TabId => {
const tabId = upgradeChartStore.getTabIdByRelease(release.getName());
if (tabId) {

View File

@ -12,11 +12,11 @@ export interface DrawerParamTogglerProps {
label: string | number;
}
interface State {
export interface DrawerParamTogglerState {
open?: boolean;
}
export class DrawerParamToggler extends React.Component<DrawerParamTogglerProps, State> {
public state: State = {};
export class DrawerParamToggler extends React.Component<DrawerParamTogglerProps, DrawerParamTogglerState> {
public state: DrawerParamTogglerState = {};
toggle = () => {
this.setState({ open: !this.state.open });

View File

@ -12,9 +12,7 @@ import { cssNames, noop, StorageHelper } from "../../utils";
import { Icon } from "../icon";
import { Animate, AnimateName } from "../animate";
import { ResizeDirection, ResizeGrowthDirection, ResizeSide, ResizingAnchor } from "../resizing-anchor";
import drawerStorageInjectable, {
defaultDrawerWidth,
} from "./drawer-storage/drawer-storage.injectable";
import drawerStorageInjectable, { defaultDrawerWidth } from "./drawer-storage/drawer-storage.injectable";
import { withInjectables } from "@ogre-tools/injectable-react";
import historyInjectable from "../../navigation/history.injectable";
import type { History } from "history";
@ -47,7 +45,7 @@ const defaultProps: Partial<DrawerProps> = {
onClose: noop,
};
interface State {
export interface DrawerState {
isCopied: boolean;
width: number;
}
@ -64,7 +62,7 @@ interface Dependencies {
drawerStorage: StorageHelper<{ width: number }>;
}
class NonInjectedDrawer extends React.Component<DrawerProps & Dependencies, State> {
class NonInjectedDrawer extends React.Component<DrawerProps & Dependencies, DrawerState> {
static defaultProps = defaultProps as object;
private mouseDownTarget: HTMLElement;

View File

@ -21,6 +21,9 @@ interface State {
@observer
export class ErrorBoundary extends React.Component<ErrorBoundaryProps, State> {
/**
* @internal
*/
public state: State = {};
componentDidCatch(error: Error, errorInfo: ErrorInfo) {

Some files were not shown because too many files have changed in this diff Show More