mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Improve Table typing and remove annotations on callbacks
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
1 parent
22c9d03edb
commit
defb0ea0dd
55 files changed
+498
-490
No files matched your search
@@ -22,8 +22,9 @@
|
||||
import { ingressStore } from "../../components/+network-ingresses/ingress.store";
|
||||
import { apiManager } from "../api-manager";
|
||||
import { KubeApi } from "../kube-api";
|
||||
import { KubeObject } from "../kube-object";
|
||||
|
||||
class TestApi extends KubeApi {
|
||||
class TestApi extends KubeApi<KubeObject> {
|
||||
|
||||
protected async checkPreferredVersion() {
|
||||
return;
|
||||
@@ -36,6 +37,7 @@ describe("ApiManager", () => {
|
||||
const apiBase = "apis/v1/foo";
|
||||
const fallbackApiBase = "/apis/extensions/v1beta1/foo";
|
||||
const kubeApi = new TestApi({
|
||||
objectConstructor: KubeObject,
|
||||
apiBase,
|
||||
fallbackApiBases: [fallbackApiBase],
|
||||
checkPreferredVersion: true,
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
import { KubeApi } from "../kube-api";
|
||||
import { KubeObject } from "../kube-object";
|
||||
|
||||
describe("KubeApi", () => {
|
||||
it("uses url from apiBase if apiBase contains the resource", async () => {
|
||||
@@ -29,7 +30,7 @@ describe("KubeApi", () => {
|
||||
body: JSON.stringify({
|
||||
resources: [{
|
||||
name: "ingresses"
|
||||
}] as any []
|
||||
}] as any[]
|
||||
})
|
||||
};
|
||||
} else if (request.url === "/api-kube/apis/extensions/v1beta1") {
|
||||
@@ -38,13 +39,13 @@ describe("KubeApi", () => {
|
||||
body: JSON.stringify({
|
||||
resources: [{
|
||||
name: "ingresses"
|
||||
}] as any []
|
||||
}] as any[]
|
||||
})
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
body: JSON.stringify({
|
||||
resources: [] as any []
|
||||
resources: [] as any[]
|
||||
})
|
||||
};
|
||||
}
|
||||
@@ -53,6 +54,7 @@ describe("KubeApi", () => {
|
||||
const apiBase = "/apis/networking.k8s.io/v1/ingresses";
|
||||
const fallbackApiBase = "/apis/extensions/v1beta1/ingresses";
|
||||
const kubeApi = new KubeApi({
|
||||
objectConstructor: KubeObject,
|
||||
apiBase,
|
||||
fallbackApiBases: [fallbackApiBase],
|
||||
checkPreferredVersion: true,
|
||||
@@ -68,7 +70,7 @@ describe("KubeApi", () => {
|
||||
if (request.url === "/api-kube/apis/networking.k8s.io/v1") {
|
||||
return {
|
||||
body: JSON.stringify({
|
||||
resources: [] as any []
|
||||
resources: [] as any[]
|
||||
})
|
||||
};
|
||||
} else if (request.url === "/api-kube/apis/extensions/v1beta1") {
|
||||
@@ -76,13 +78,13 @@ describe("KubeApi", () => {
|
||||
body: JSON.stringify({
|
||||
resources: [{
|
||||
name: "ingresses"
|
||||
}] as any []
|
||||
}] as any[]
|
||||
})
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
body: JSON.stringify({
|
||||
resources: [] as any []
|
||||
resources: [] as any[]
|
||||
})
|
||||
};
|
||||
}
|
||||
@@ -91,6 +93,7 @@ describe("KubeApi", () => {
|
||||
const apiBase = "apis/networking.k8s.io/v1/ingresses";
|
||||
const fallbackApiBase = "/apis/extensions/v1beta1/ingresses";
|
||||
const kubeApi = new KubeApi({
|
||||
objectConstructor: KubeObject,
|
||||
apiBase,
|
||||
fallbackApiBases: [fallbackApiBase],
|
||||
checkPreferredVersion: true,
|
||||
|
||||
@@ -24,17 +24,18 @@ import type { KubeObjectStore } from "../kube-object.store";
|
||||
import { action, observable, makeObservable } from "mobx";
|
||||
import { autoBind } from "../utils";
|
||||
import { KubeApi, parseKubeApi } from "./kube-api";
|
||||
import type { KubeObject } from "./kube-object";
|
||||
|
||||
export class ApiManager {
|
||||
private apis = observable.map<string, KubeApi>();
|
||||
private stores = observable.map<string, KubeObjectStore>();
|
||||
private apis = observable.map<string, KubeApi<KubeObject>>();
|
||||
private stores = observable.map<string, KubeObjectStore<KubeObject>>();
|
||||
|
||||
constructor() {
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
getApi(pathOrCallback: string | ((api: KubeApi) => boolean)) {
|
||||
getApi(pathOrCallback: string | ((api: KubeApi<KubeObject>) => boolean)) {
|
||||
if (typeof pathOrCallback === "string") {
|
||||
return this.apis.get(pathOrCallback) || this.apis.get(parseKubeApi(pathOrCallback).apiBase);
|
||||
}
|
||||
@@ -46,10 +47,10 @@ export class ApiManager {
|
||||
return Array.from(this.apis.values()).find((api) => api.kind === kind && api.apiVersionWithGroup === apiVersion);
|
||||
}
|
||||
|
||||
registerApi(apiBase: string, api: KubeApi) {
|
||||
registerApi(apiBase: string, api: KubeApi<KubeObject>) {
|
||||
if (!this.apis.has(apiBase)) {
|
||||
this.stores.forEach((store) => {
|
||||
if(store.api === api) {
|
||||
if (store.api === api) {
|
||||
this.stores.set(apiBase, store);
|
||||
}
|
||||
});
|
||||
@@ -58,13 +59,13 @@ export class ApiManager {
|
||||
}
|
||||
}
|
||||
|
||||
protected resolveApi(api: string | KubeApi): KubeApi {
|
||||
if (typeof api === "string") return this.getApi(api);
|
||||
protected resolveApi<K extends KubeObject>(api: string | KubeApi<K>): KubeApi<K> {
|
||||
if (typeof api === "string") return this.getApi(api) as KubeApi<K>;
|
||||
|
||||
return api;
|
||||
}
|
||||
|
||||
unregisterApi(api: string | KubeApi) {
|
||||
unregisterApi(api: string | KubeApi<KubeObject>) {
|
||||
if (typeof api === "string") this.apis.delete(api);
|
||||
else {
|
||||
const apis = Array.from(this.apis.entries());
|
||||
@@ -75,13 +76,13 @@ export class ApiManager {
|
||||
}
|
||||
|
||||
@action
|
||||
registerStore(store: KubeObjectStore, apis: KubeApi[] = [store.api]) {
|
||||
registerStore(store: KubeObjectStore<KubeObject>, apis: KubeApi<KubeObject>[] = [store.api]) {
|
||||
apis.forEach(api => {
|
||||
this.stores.set(api.apiBase, store);
|
||||
});
|
||||
}
|
||||
|
||||
getStore<S extends KubeObjectStore>(api: string | KubeApi): S {
|
||||
getStore<S extends KubeObjectStore<KubeObject>>(api: string | KubeApi<KubeObject>): S {
|
||||
return this.stores.get(this.resolveApi(api)?.apiBase) as S;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ export const resourceApplierApi = {
|
||||
"kubectl.kubernetes.io/last-applied-configuration"
|
||||
],
|
||||
|
||||
async update<D extends KubeObject>(resource: object | string): Promise<D> {
|
||||
async update<K extends KubeObject>(resource: object | string): Promise<K | null> {
|
||||
if (typeof resource === "string") {
|
||||
resource = jsYaml.safeLoad(resource);
|
||||
}
|
||||
@@ -48,7 +48,7 @@ export const resourceApplierApi = {
|
||||
}
|
||||
});
|
||||
|
||||
return items.length === 1 ? items[0] : items;
|
||||
return items[0] as K ?? null;
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -49,7 +49,7 @@ export interface IKubeApiOptions<T extends KubeObject> {
|
||||
*/
|
||||
fallbackApiBases?: string[];
|
||||
|
||||
objectConstructor?: IKubeObjectConstructor<T>;
|
||||
objectConstructor: IKubeObjectConstructor<T>;
|
||||
request?: KubeJsonApi;
|
||||
isNamespaced?: boolean;
|
||||
kind?: string;
|
||||
@@ -115,7 +115,7 @@ export function forCluster<T extends KubeObject>(cluster: IKubeApiCluster, kubeC
|
||||
});
|
||||
}
|
||||
|
||||
export function ensureObjectSelfLink(api: KubeApi, object: KubeJsonApiData) {
|
||||
export function ensureObjectSelfLink(api: KubeApi<KubeObject>, object: KubeJsonApiData) {
|
||||
if (!object.metadata.selfLink) {
|
||||
object.metadata.selfLink = createKubeApiURL({
|
||||
apiPrefix: api.apiPrefix,
|
||||
@@ -127,7 +127,7 @@ export function ensureObjectSelfLink(api: KubeApi, object: KubeJsonApiData) {
|
||||
}
|
||||
}
|
||||
|
||||
export type KubeApiWatchCallback = (data: IKubeWatchEvent, error: any) => void;
|
||||
export type KubeApiWatchCallback = (data: IKubeWatchEvent<KubeJsonApiData>, error: any) => void;
|
||||
|
||||
export type KubeApiWatchOptions = {
|
||||
namespace: string;
|
||||
@@ -135,7 +135,7 @@ export type KubeApiWatchOptions = {
|
||||
abortController?: AbortController
|
||||
};
|
||||
|
||||
export class KubeApi<T extends KubeObject = any> {
|
||||
export class KubeApi<T extends KubeObject> {
|
||||
readonly kind: string;
|
||||
readonly apiBase: string;
|
||||
readonly apiPrefix: string;
|
||||
@@ -152,7 +152,7 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
|
||||
constructor(protected options: IKubeApiOptions<T>) {
|
||||
const {
|
||||
objectConstructor = KubeObject as IKubeObjectConstructor,
|
||||
objectConstructor,
|
||||
request = apiKube,
|
||||
kind = options.objectConstructor?.kind,
|
||||
isNamespaced = options.objectConstructor?.namespaced
|
||||
@@ -456,14 +456,14 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
|
||||
clearTimeout(timedRetry);
|
||||
timedRetry = setTimeout(() => { // we did not get any kubernetes errors so let's retry
|
||||
this.watch({...opts, namespace, callback});
|
||||
this.watch({ ...opts, namespace, callback });
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
byline(nodeStream).on("data", (line) => {
|
||||
try {
|
||||
const event: IKubeWatchEvent = JSON.parse(line);
|
||||
const event: IKubeWatchEvent<KubeJsonApiData> = JSON.parse(line);
|
||||
|
||||
if (event.type === "ERROR" && event.object.kind === "Status") {
|
||||
errorReceived = true;
|
||||
@@ -474,7 +474,7 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
this.modifyWatchEvent(event);
|
||||
callback(event, null);
|
||||
} catch (ignore) {
|
||||
// ignore parse errors
|
||||
// ignore parse errors
|
||||
}
|
||||
});
|
||||
})
|
||||
@@ -487,7 +487,7 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
return abort;
|
||||
}
|
||||
|
||||
protected modifyWatchEvent(event: IKubeWatchEvent) {
|
||||
protected modifyWatchEvent(event: IKubeWatchEvent<KubeJsonApiData>) {
|
||||
|
||||
switch (event.type) {
|
||||
case "ADDED":
|
||||
|
||||
@@ -30,7 +30,7 @@ import type { JsonApiParams } from "./json-api";
|
||||
import { resourceApplierApi } from "./endpoints/resource-applier.api";
|
||||
import { hasOptionalProperty, hasTypedProperty, isObject, isString, bindPredicate, isTypedArray, isRecord } from "../../common/utils/type-narrowing";
|
||||
|
||||
export type IKubeObjectConstructor<T extends KubeObject = any> = (new (data: KubeJsonApiData | any) => T) & {
|
||||
export type IKubeObjectConstructor<K extends KubeObject = KubeObject> = (new (data: KubeJsonApiData | any) => K) & {
|
||||
kind?: string;
|
||||
namespaced?: boolean;
|
||||
apiBase?: string;
|
||||
@@ -266,8 +266,8 @@ export class KubeObject<Metadata extends IKubeObjectMetadata = IKubeObjectMetada
|
||||
}
|
||||
|
||||
// use unified resource-applier api for updating all k8s objects
|
||||
async update<T extends KubeObject>(data: Partial<T>): Promise<T> {
|
||||
return resourceApplierApi.update<T>({
|
||||
async update<K extends KubeObject>(data: Partial<K>): Promise<K> {
|
||||
return resourceApplierApi.update<K>({
|
||||
...this.toPlainObject(),
|
||||
...data,
|
||||
});
|
||||
|
||||
@@ -31,8 +31,9 @@ import { autoBind, Disposer, noop } from "../utils";
|
||||
import type { KubeApi } from "./kube-api";
|
||||
import type { KubeJsonApiData } from "./kube-json-api";
|
||||
import { isDebugging, isProduction } from "../../common/vars";
|
||||
import type { KubeObject } from "./kube-object";
|
||||
|
||||
export interface IKubeWatchEvent<T = KubeJsonApiData> {
|
||||
export interface IKubeWatchEvent<T extends KubeJsonApiData> {
|
||||
type: "ADDED" | "MODIFIED" | "DELETED" | "ERROR";
|
||||
object?: T;
|
||||
}
|
||||
@@ -58,11 +59,11 @@ export class KubeWatchApi {
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
isAllowedApi(api: KubeApi): boolean {
|
||||
isAllowedApi(api: KubeApi<KubeObject>): boolean {
|
||||
return Boolean(this.context?.cluster.isAllowedResource(api.kind));
|
||||
}
|
||||
|
||||
preloadStores(stores: KubeObjectStore[], opts: { namespaces?: string[], loadOnce?: boolean } = {}) {
|
||||
preloadStores(stores: KubeObjectStore<KubeObject>[], opts: { namespaces?: string[], loadOnce?: boolean } = {}) {
|
||||
const limitRequests = plimit(1); // load stores one by one to allow quick skipping when fast clicking btw pages
|
||||
const preloading: Promise<any>[] = [];
|
||||
|
||||
@@ -80,7 +81,7 @@ export class KubeWatchApi {
|
||||
};
|
||||
}
|
||||
|
||||
subscribeStores(stores: KubeObjectStore[], opts: IKubeWatchSubscribeStoreOptions = {}): Disposer {
|
||||
subscribeStores(stores: KubeObjectStore<KubeObject>[], opts: IKubeWatchSubscribeStoreOptions = {}): Disposer {
|
||||
const { preload = true, waitUntilLoaded = true, loadOnce = false, } = opts;
|
||||
const subscribingNamespaces = opts.namespaces ?? this.context?.allNamespaces ?? [];
|
||||
const unsubscribeList: Function[] = [];
|
||||
|
||||
Reference in new issue
Block a user