From 3a62cd48484683ae7ae6b7c4335e8e6e46115330 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Wed, 3 May 2023 08:06:13 -0400 Subject: [PATCH] chore: Fix new build errors in @k8slens/core Signed-off-by: Sebastian Malton --- .../core/__mocks__/react-beautiful-dnd.tsx | 14 +++++---- .../src/common/app-paths/app-paths.test.ts | 2 +- .../src/common/catalog-entities/web-link.ts | 3 +- ...request-namespace-list-permissions.test.ts | 6 ++-- .../navigate-to-route-injection-token.ts | 29 +++---------------- .../catalog/navigate-to-catalog.injectable.ts | 7 ++--- packages/core/src/common/fs/fs.injectable.ts | 9 +++--- .../common/k8s-api/api-manager/api-manager.ts | 6 ++-- .../k8s-api/create-json-api.injectable.ts | 4 +-- .../request-create.injectable.ts | 2 +- .../metrics.api/request-metrics.injectable.ts | 4 +-- .../request-patch.injectable.ts | 21 +++++--------- .../request-update.injectable.ts | 21 +++++--------- .../with-error-suppression.test.ts | 4 +-- .../with-orphan-promise.injectable.ts | 4 +-- .../configurable-directories.test.ts | 23 ++++----------- .../extension-loader/extension-loader.ts | 8 ++--- ...ile-system-provisioner-store.injectable.ts | 4 +-- .../features/cluster/workloads/pods.test.tsx | 6 +++- .../list-pod-metrics.injectable.ts | 20 +++++++++++++ .../workloads-pods/store.injectable.ts | 4 +-- .../components/workloads-pods/store.ts | 7 +++-- .../utility-features/json-api/src/json-api.ts | 9 ++---- 23 files changed, 99 insertions(+), 118 deletions(-) create mode 100644 packages/core/src/renderer/components/workloads-pods/list-pod-metrics.injectable.ts diff --git a/packages/core/__mocks__/react-beautiful-dnd.tsx b/packages/core/__mocks__/react-beautiful-dnd.tsx index e3549c2968..120820a82d 100644 --- a/packages/core/__mocks__/react-beautiful-dnd.tsx +++ b/packages/core/__mocks__/react-beautiful-dnd.tsx @@ -7,9 +7,13 @@ import React from "react"; import type { DragDropContextProps, DraggableProps, + DraggableProvided, DraggableProvidedDraggableProps, + DraggableStateSnapshot, DroppableProps, + DroppableProvided, DroppableProvidedProps, + DroppableStateSnapshot, } from "react-beautiful-dnd"; export const DragDropContext = ({ children }: DragDropContextProps) => <>{ children }; @@ -20,14 +24,14 @@ export const Draggable = ({ children }: DraggableProps) => ( { draggableProps: {} as DraggableProvidedDraggableProps, innerRef: () => {}, - }, + } as unknown as DraggableProvided, { isDragging: false, isDropAnimating: false, - }, + } as DraggableStateSnapshot, { draggableId: "some-mock-draggable-id", - mode: "FLUID", + type: "FLUID", source: { droppableId: "some-mock-droppable-id", index: 0, @@ -44,11 +48,11 @@ export const Droppable = ({ children }: DroppableProps) => ( { droppableProps: {} as DroppableProvidedProps, innerRef: () => {}, - }, + } as unknown as DroppableProvided, { isDraggingOver: false, isUsingPlaceholder: false, - }, + } as DroppableStateSnapshot, ) } diff --git a/packages/core/src/common/app-paths/app-paths.test.ts b/packages/core/src/common/app-paths/app-paths.test.ts index 2d8023b129..222cef9908 100644 --- a/packages/core/src/common/app-paths/app-paths.test.ts +++ b/packages/core/src/common/app-paths/app-paths.test.ts @@ -15,7 +15,7 @@ import appPathsInjectable from "./app-paths.injectable"; describe("app-paths", () => { let builder: ApplicationBuilder; - beforeEach(() => { + beforeEach(async () => { builder = getApplicationBuilder(); const defaultAppPathsStub: AppPaths = { diff --git a/packages/core/src/common/catalog-entities/web-link.ts b/packages/core/src/common/catalog-entities/web-link.ts index 505f39c886..52e280f4b3 100644 --- a/packages/core/src/common/catalog-entities/web-link.ts +++ b/packages/core/src/common/catalog-entities/web-link.ts @@ -6,6 +6,7 @@ import { getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "@k8slens/legacy-global-di"; import removeWeblinkInjectable from "../../features/weblinks/common/remove.injectable"; import type { CatalogEntityContextMenuContext, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog"; +import type { CatalogEntitySpec } from "../catalog/catalog-entity"; import { CatalogCategory, CatalogEntity, categoryVersion } from "../catalog/catalog-entity"; import productNameInjectable from "../vars/product-name.injectable"; @@ -15,7 +16,7 @@ export interface WebLinkStatus extends CatalogEntityStatus { phase: WebLinkStatusPhase; } -export interface WebLinkSpec { +export interface WebLinkSpec extends CatalogEntitySpec { url: string; } diff --git a/packages/core/src/common/cluster/request-namespace-list-permissions.test.ts b/packages/core/src/common/cluster/request-namespace-list-permissions.test.ts index 6eb32b49d6..09b3ac881f 100644 --- a/packages/core/src/common/cluster/request-namespace-list-permissions.test.ts +++ b/packages/core/src/common/cluster/request-namespace-list-permissions.test.ts @@ -5,7 +5,7 @@ import type { AsyncFnMock } from "@async-fn/jest"; import asyncFn from "@async-fn/jest"; -import type { AuthorizationV1Api, V1SubjectRulesReviewStatus } from "@kubernetes/client-node"; +import type { AuthorizationV1Api, V1SelfSubjectRulesReview, V1SubjectRulesReviewStatus } from "@kubernetes/client-node"; import type { DiContainer } from "@ogre-tools/injectable"; import type { IncomingMessage } from "http"; import { anyObject } from "jest-mock-extended"; @@ -192,8 +192,8 @@ describe("requestNamespaceListPermissions", () => { body: { status, spec: {}, - }, - value: null as unknown as IncomingMessage, + } as V1SelfSubjectRulesReview, + response: null as unknown as IncomingMessage, }); }); diff --git a/packages/core/src/common/front-end-routing/navigate-to-route-injection-token.ts b/packages/core/src/common/front-end-routing/navigate-to-route-injection-token.ts index 4f37d85531..84c8ce41e0 100644 --- a/packages/core/src/common/front-end-routing/navigate-to-route-injection-token.ts +++ b/packages/core/src/common/front-end-routing/navigate-to-route-injection-token.ts @@ -3,38 +3,17 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectionToken } from "@ogre-tools/injectable"; +import type { RequiredKeysOf } from "type-fest"; import type { Route } from "./front-end-route-injection-token"; -type InferParametersFrom = TRoute extends Route +type InferParametersFrom = TRoute extends Route ? TParameters : never; -type RequiredKeys = Exclude< - { - [K in keyof T]: T extends Record ? K : never; - }[keyof T], - undefined ->; - -type ObjectContainingNoRequired = T extends void - ? never - : ( - RequiredKeys extends [] - ? Record - : never - ); - -type ObjectContainsNoRequired = T extends ObjectContainingNoRequired - ? true - : false; - -// TODO: Missing types for: -// - Navigating to route without parameters, with parameters -// - Navigating to route with required parameters, without parameters -type Parameters = TParameters extends void +type Parameters = TParameters extends void ? { parameters?: undefined } : ( - ObjectContainsNoRequired extends true + RequiredKeysOf extends never ? { parameters?: TParameters } : { parameters: TParameters } ); diff --git a/packages/core/src/common/front-end-routing/routes/catalog/navigate-to-catalog.injectable.ts b/packages/core/src/common/front-end-routing/routes/catalog/navigate-to-catalog.injectable.ts index 24fab385bb..bf067910a8 100644 --- a/packages/core/src/common/front-end-routing/routes/catalog/navigate-to-catalog.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/catalog/navigate-to-catalog.injectable.ts @@ -16,10 +16,9 @@ const navigateToCatalogInjectable = getInjectable({ const navigateToRoute = di.inject(navigateToRouteInjectionToken); const catalogRoute = di.inject(catalogRouteInjectable); - return (parameters) => - navigateToRoute(catalogRoute, { - parameters, - }); + return (parameters) => navigateToRoute(catalogRoute, { + parameters, + }); }, }); diff --git a/packages/core/src/common/fs/fs.injectable.ts b/packages/core/src/common/fs/fs.injectable.ts index f29e806385..e48e4e33c6 100644 --- a/packages/core/src/common/fs/fs.injectable.ts +++ b/packages/core/src/common/fs/fs.injectable.ts @@ -3,8 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { WriteFileOptions } from "fs"; -import type { ReadOptions } from "fs-extra"; +import type { CopyOptions, EnsureOptions, ReadOptions, WriteOptions } from "fs-extra"; import fse from "fs-extra"; export type FileSystemFunctions = ReturnType<(typeof fsInjectable)["instantiate"]>; @@ -45,7 +44,7 @@ const fsInjectable = getInjectable({ readFile, readJson: readJson as (file: string, options?: ReadOptions | BufferEncoding) => Promise, writeFile, - writeJson: writeJson as (file: string, value: unknown, options?: string | WriteFileOptions) => Promise, + writeJson: writeJson as (file: string, value: unknown, options?: string | WriteOptions) => Promise, pathExists, readdir, readFileSync, @@ -56,8 +55,8 @@ const fsInjectable = getInjectable({ lstat, rm, access, - copy: copy as (src: string, dest: string, options?: fse.CopyOptions) => Promise, - ensureDir: ensureDir as (path: string, options?: number | fse.EnsureOptions ) => Promise, + copy: copy as (src: string, dest: string, options?: CopyOptions) => Promise, + ensureDir: ensureDir as (path: string, options?: number | EnsureOptions ) => Promise, ensureDirSync, createReadStream, stat, diff --git a/packages/core/src/common/k8s-api/api-manager/api-manager.ts b/packages/core/src/common/k8s-api/api-manager/api-manager.ts index 1065554ad6..29fa71fbc9 100644 --- a/packages/core/src/common/k8s-api/api-manager/api-manager.ts +++ b/packages/core/src/common/k8s-api/api-manager/api-manager.ts @@ -13,10 +13,12 @@ import { parseKubeApi, createKubeApiURL } from "@k8slens/kube-api"; import { getOrInsertWith, iter } from "@k8slens/utilities"; import type { CreateCustomResourceStore } from "./create-custom-resource-store.injectable"; -export type RegisterableStore = Store extends KubeObjectStore +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type RegisterableStore = Store extends KubeObjectStore ? Store : never; -export type RegisterableApi = Api extends KubeApi +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type RegisterableApi = Api extends KubeApi ? Api : never; export type KubeObjectStoreFrom = Api extends KubeApi diff --git a/packages/core/src/common/k8s-api/create-json-api.injectable.ts b/packages/core/src/common/k8s-api/create-json-api.injectable.ts index 5a70dbf118..cf3a7007a0 100644 --- a/packages/core/src/common/k8s-api/create-json-api.injectable.ts +++ b/packages/core/src/common/k8s-api/create-json-api.injectable.ts @@ -8,10 +8,10 @@ import type { RequestInit } from "@k8slens/node-fetch"; import lensProxyCertificateInjectable from "../certificate/lens-proxy-certificate.injectable"; import fetchInjectable from "../fetch/fetch.injectable"; import { loggerInjectionToken } from "@k8slens/logger"; -import type { JsonApiConfig, JsonApiData, JsonApiDependencies, JsonApiParams } from "@k8slens/json-api"; +import type { JsonApiConfig, JsonApiDependencies, JsonApiParams } from "@k8slens/json-api"; import { JsonApi } from "@k8slens/json-api"; -export type CreateJsonApi = = JsonApiParams>(config: JsonApiConfig, reqInit?: RequestInit) => JsonApi; +export type CreateJsonApi = = JsonApiParams>(config: JsonApiConfig, reqInit?: RequestInit) => JsonApi; const createJsonApiInjectable = getInjectable({ id: "create-json-api", diff --git a/packages/core/src/common/k8s-api/endpoints/helm-releases.api/request-create.injectable.ts b/packages/core/src/common/k8s-api/endpoints/helm-releases.api/request-create.injectable.ts index 253e97bf72..c78416aafd 100644 --- a/packages/core/src/common/k8s-api/endpoints/helm-releases.api/request-create.injectable.ts +++ b/packages/core/src/common/k8s-api/endpoints/helm-releases.api/request-create.injectable.ts @@ -31,7 +31,7 @@ const requestCreateHelmReleaseInjectable = getInjectable({ return apiBase.post(requestCreateEndpoint.compile({}), { data: { chart: `${repo}/${chart}`, - values: yaml.load(values), + values: yaml.load(values) as object, ...data, }, }); diff --git a/packages/core/src/common/k8s-api/endpoints/metrics.api/request-metrics.injectable.ts b/packages/core/src/common/k8s-api/endpoints/metrics.api/request-metrics.injectable.ts index 003c5ca692..861305b2e6 100644 --- a/packages/core/src/common/k8s-api/endpoints/metrics.api/request-metrics.injectable.ts +++ b/packages/core/src/common/k8s-api/endpoints/metrics.api/request-metrics.injectable.ts @@ -46,7 +46,7 @@ const requestMetricsInjectable = getInjectable({ function requestMetrics(query: string, params?: RequestMetricsParams): Promise; function requestMetrics(query: string[], params?: RequestMetricsParams): Promise; function requestMetrics(query: Record>>, params?: RequestMetricsParams): Promise>; - async function requestMetrics(query: string | string[] | Partial>>>, params: RequestMetricsParams = {}): Promise>> { + async function requestMetrics(metricsQuery: string | string[] | Partial>>>, params: RequestMetricsParams = {}): Promise>> { const { range = 3600, step = 60, namespace } = params; let { start, end } = params; @@ -58,7 +58,7 @@ const requestMetricsInjectable = getInjectable({ } return apiBase.post("/metrics", { - data: query, + data: metricsQuery, query: { start, end, step, "kubernetes_namespace": namespace, diff --git a/packages/core/src/common/k8s-api/endpoints/resource-applier.api/request-patch.injectable.ts b/packages/core/src/common/k8s-api/endpoints/resource-applier.api/request-patch.injectable.ts index 8bbb986d4b..9f95ea2a05 100644 --- a/packages/core/src/common/k8s-api/endpoints/resource-applier.api/request-patch.injectable.ts +++ b/packages/core/src/common/k8s-api/endpoints/resource-applier.api/request-patch.injectable.ts @@ -6,9 +6,10 @@ import { getInjectable } from "@ogre-tools/injectable"; import type { Patch } from "rfc6902"; import apiBaseInjectable from "../../api-base.injectable"; import type { AsyncResult, Result } from "@k8slens/utilities"; +import { result } from "@k8slens/utilities"; import type { KubeJsonApiData } from "@k8slens/kube-object"; -export type RequestKubeObjectPatch = (name: string, kind: string, ns: string | undefined, patch: Patch) => AsyncResult; +export type RequestKubeObjectPatch = (name: string, kind: string, ns: string | undefined, patch: Patch) => AsyncResult; const requestKubeObjectPatchInjectable = getInjectable({ id: "request-kube-object-patch", @@ -16,7 +17,7 @@ const requestKubeObjectPatchInjectable = getInjectable({ const apiBase = di.inject(apiBaseInjectable); return async (name, kind, ns, patch) => { - const result = (await apiBase.patch("/stack", { + const patchResult = (await apiBase.patch("/stack", { data: { name, kind, @@ -25,22 +26,14 @@ const requestKubeObjectPatchInjectable = getInjectable({ }, })) as Result; - if (!result.isOk) { - return result; + if (!patchResult.isOk) { + return result.wrapError("Failed to patch kube object", patchResult); } try { - const response = JSON.parse(result.value) as KubeJsonApiData; - - return { - isOk: true, - response, - }; + return result.ok(JSON.parse(patchResult.value) as KubeJsonApiData); } catch (error) { - return { - isOk: false, - error: String(error), - }; + return result.error(new Error("Failed to parse response from patching kube object", { cause: error })); } }; }, diff --git a/packages/core/src/common/k8s-api/endpoints/resource-applier.api/request-update.injectable.ts b/packages/core/src/common/k8s-api/endpoints/resource-applier.api/request-update.injectable.ts index 1b75d31255..74780494b8 100644 --- a/packages/core/src/common/k8s-api/endpoints/resource-applier.api/request-update.injectable.ts +++ b/packages/core/src/common/k8s-api/endpoints/resource-applier.api/request-update.injectable.ts @@ -5,9 +5,10 @@ import { getInjectable } from "@ogre-tools/injectable"; import apiBaseInjectable from "../../api-base.injectable"; import type { AsyncResult, Result } from "@k8slens/utilities"; +import { result } from "@k8slens/utilities"; import type { KubeJsonApiData } from "@k8slens/kube-object"; -export type RequestKubeObjectCreation = (resourceDescriptor: string) => AsyncResult; +export type RequestKubeObjectCreation = (resourceDescriptor: string) => AsyncResult; const requestKubeObjectCreationInjectable = getInjectable({ id: "request-kube-object-creation", @@ -15,24 +16,16 @@ const requestKubeObjectCreationInjectable = getInjectable({ const apiBase = di.inject(apiBaseInjectable); return async (data) => { - const result = await apiBase.post("/stack", { data }) as Result; + const postResult = await apiBase.post("/stack", { data }) as Result; - if (!result.isOk) { - return result; + if (!postResult.isOk) { + return result.wrapError("Failed to create kube object", postResult); } try { - const response = JSON.parse(result.value) as KubeJsonApiData; - - return { - isOk: true, - response, - }; + return result.ok(JSON.parse(postResult.value) as KubeJsonApiData); } catch (error) { - return { - isOk: false, - error: String(error), - }; + return result.error(new Error("Failed to parse result from kube object creation", { cause: error })); } }; }, diff --git a/packages/core/src/common/utils/with-error-suppression/with-error-suppression.test.ts b/packages/core/src/common/utils/with-error-suppression/with-error-suppression.test.ts index bcee8edbaa..59d6be41a7 100644 --- a/packages/core/src/common/utils/with-error-suppression/with-error-suppression.test.ts +++ b/packages/core/src/common/utils/with-error-suppression/with-error-suppression.test.ts @@ -57,7 +57,7 @@ describe("with-error-suppression", () => { }); describe("given decorated async function", () => { - let decorated: (a: string, b: string) => Promise | Promise; + let decorated: (a: string, b: string) => Promise; let toBeDecorated: AsyncFnMock<(a: string, b: string) => Promise>; beforeEach(() => { @@ -67,7 +67,7 @@ describe("with-error-suppression", () => { }); describe("when called", () => { - let returnValuePromise: Promise | Promise; + let returnValuePromise: Promise; beforeEach(() => { returnValuePromise = decorated("some-parameter", "some-other-parameter"); diff --git a/packages/core/src/common/utils/with-orphan-promise/with-orphan-promise.injectable.ts b/packages/core/src/common/utils/with-orphan-promise/with-orphan-promise.injectable.ts index ee3bd50390..4014358599 100644 --- a/packages/core/src/common/utils/with-orphan-promise/with-orphan-promise.injectable.ts +++ b/packages/core/src/common/utils/with-orphan-promise/with-orphan-promise.injectable.ts @@ -13,8 +13,8 @@ const withOrphanPromiseInjectable = getInjectable({ instantiate: (di) => { const withErrorLoggingFor = di.inject(withErrorLoggingInjectable); - return Promise>(toBeDecorated: T) => - (...args: Parameters): void => { + return (toBeDecorated: (...args: Args) => unknown) => + (...args: Args): void => { const decorated = pipeline( toBeDecorated, withErrorLoggingFor(() => "Orphan promise rejection encountered"), diff --git a/packages/core/src/extensions/__tests__/configurable-directories.test.ts b/packages/core/src/extensions/__tests__/configurable-directories.test.ts index 29dcc3c897..d8baf7f237 100644 --- a/packages/core/src/extensions/__tests__/configurable-directories.test.ts +++ b/packages/core/src/extensions/__tests__/configurable-directories.test.ts @@ -5,7 +5,6 @@ import { runInAction } from "mobx"; import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; -import type { FakeExtensionOptions } from "../../renderer/components/test-utils/get-extension-fake"; import getHashInjectable from "../../extensions/extension-loader/file-system-provisioner-store/get-hash.injectable"; import fsInjectable from "../../common/fs/fs.injectable"; @@ -30,11 +29,8 @@ describe("configurable directories for extension files", () => { }); describe("when extension with a specific store name is enabled", () => { - let testExtensionOptions: FakeExtensionOptions; - - beforeEach(() => { - - testExtensionOptions = { + beforeEach(async () => { + await builder.extensions.enable({ id: "some-extension", name: "some-extension-name", @@ -48,9 +44,7 @@ describe("configurable directories for extension files", () => { }, }, }, - }; - - await builder.extensions.enable(testExtensionOptions); + }); }); it("creates extension directory for specific store name", async () => { @@ -65,11 +59,8 @@ describe("configurable directories for extension files", () => { }); describe("when extension with no specific store name is enabled", () => { - let testExtensionOptions: FakeExtensionOptions; - - beforeEach(() => { - - testExtensionOptions = { + beforeEach(async () => { + await builder.extensions.enable({ id: "some-extension", name: "some-extension-name", @@ -83,9 +74,7 @@ describe("configurable directories for extension files", () => { }, }, }, - }; - - await builder.extensions.enable(testExtensionOptions); + }); }); it("creates extension directory for package name", async () => { diff --git a/packages/core/src/extensions/extension-loader/extension-loader.ts b/packages/core/src/extensions/extension-loader/extension-loader.ts index bfa019631b..160ee4ec21 100644 --- a/packages/core/src/extensions/extension-loader/extension-loader.ts +++ b/packages/core/src/extensions/extension-loader/extension-loader.ts @@ -182,8 +182,8 @@ export class ExtensionLoader { ipcMainHandle(extensionLoaderFromMainChannel, () => [...this.toJSON()]); - ipcMainOn(extensionLoaderFromRendererChannel, (event, extensions: [LensExtensionId, InstalledExtension][]) => { - this.syncExtensions(extensions); + ipcMainOn(extensionLoaderFromRendererChannel, (event, extensions) => { + this.syncExtensions(extensions as [LensExtensionId, InstalledExtension][]); }); } @@ -205,8 +205,8 @@ export class ExtensionLoader { }; void requestExtensionLoaderInitialState().then(extensionListHandler); - ipcRendererOn(extensionLoaderFromMainChannel, (event, extensions: [LensExtensionId, InstalledExtension][]) => { - extensionListHandler(extensions); + ipcRendererOn(extensionLoaderFromMainChannel, (event, extensions) => { + extensionListHandler(extensions as [LensExtensionId, InstalledExtension][]); }); } diff --git a/packages/core/src/extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.injectable.ts b/packages/core/src/extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.injectable.ts index 2f08efa17e..57fb1cfb2c 100644 --- a/packages/core/src/extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.injectable.ts +++ b/packages/core/src/extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import { registeredExtensionsInjectable } from "./registered-extensions.injectable"; import createPersistentStorageInjectable from "../../../features/persistent-storage/common/create.injectable"; -import { action } from "mobx"; +import { runInAction } from "mobx"; import { object } from "@k8slens/utilities"; import storeMigrationVersionInjectable from "../../../common/vars/store-migration-version.injectable"; @@ -21,7 +21,7 @@ const fileSystemProvisionerStoreInjectable = getInjectable({ configName: "lens-filesystem-provisioner-store", accessPropertiesByDotNotation: false, // To make dots safe in cluster context names projectVersion: storeMigrationVersion, - fromStore: action(({ extensions = {}}) => { + fromStore: ({ extensions = {}}) => runInAction(() => { registeredExtensions.replace(object.entries(extensions)); }), toJSON: () => ({ diff --git a/packages/core/src/features/cluster/workloads/pods.test.tsx b/packages/core/src/features/cluster/workloads/pods.test.tsx index 0658af0837..95497f9afc 100644 --- a/packages/core/src/features/cluster/workloads/pods.test.tsx +++ b/packages/core/src/features/cluster/workloads/pods.test.tsx @@ -11,6 +11,7 @@ import type { PodStatus } from "@k8slens/kube-object"; import { Pod } from "@k8slens/kube-object"; import type { RequestMetrics } from "../../../common/k8s-api/endpoints/metrics.api/request-metrics.injectable"; import requestMetricsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-metrics.injectable"; +import requestPodMetricsByNamespaceInjectable from "../../../renderer/components/workloads-pods/list-pod-metrics.injectable"; describe("workloads / pods", () => { let rendered: RenderResult; @@ -19,7 +20,10 @@ describe("workloads / pods", () => { beforeEach(async () => { builder = await getApplicationBuilder().setEnvironmentToClusterFrame(); builder.namespaces.add("default"); - await builder.beforeWindowStart(() => { + await builder.beforeWindowStart(({ windowDi }) => { + windowDi.override(requestPodMetricsByNamespaceInjectable, () => () => Promise.resolve([])); + }); + await builder.afterWindowStart(() => { builder.allowKubeResource({ apiName: "pods", group: "", diff --git a/packages/core/src/renderer/components/workloads-pods/list-pod-metrics.injectable.ts b/packages/core/src/renderer/components/workloads-pods/list-pod-metrics.injectable.ts new file mode 100644 index 0000000000..0ace433416 --- /dev/null +++ b/packages/core/src/renderer/components/workloads-pods/list-pod-metrics.injectable.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { PodMetrics } from "@k8slens/kube-object"; +import { getInjectable } from "@ogre-tools/injectable"; +import podMetricsApiInjectable from "../../../common/k8s-api/endpoints/pod-metrics.api.injectable"; + +export type RequestPodMetricsByNamespace = (namespace: string | undefined) => Promise; + +const requestPodMetricsByNamespaceInjectable = getInjectable({ + id: "request-pod-metrics-by-namespace", + instantiate: (di): RequestPodMetricsByNamespace => { + const podMetricsApi = di.inject(podMetricsApiInjectable); + + return (namespace) => podMetricsApi.list({ namespace }); + }, +}); + +export default requestPodMetricsByNamespaceInjectable; diff --git a/packages/core/src/renderer/components/workloads-pods/store.injectable.ts b/packages/core/src/renderer/components/workloads-pods/store.injectable.ts index ca944ce50f..4242c96590 100644 --- a/packages/core/src/renderer/components/workloads-pods/store.injectable.ts +++ b/packages/core/src/renderer/components/workloads-pods/store.injectable.ts @@ -7,9 +7,9 @@ import podApiInjectable from "../../../common/k8s-api/endpoints/pod.api.injectab import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { getKubeStoreInjectable } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import { PodStore } from "./store"; -import podMetricsApiInjectable from "../../../common/k8s-api/endpoints/pod-metrics.api.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import { loggerInjectionToken } from "@k8slens/logger"; +import requestPodMetricsByNamespaceInjectable from "./list-pod-metrics.injectable"; const podStoreInjectable = getKubeStoreInjectable({ id: "pod-store", @@ -19,7 +19,7 @@ const podStoreInjectable = getKubeStoreInjectable({ const api = di.inject(podApiInjectable); return new PodStore({ - podMetricsApi: di.inject(podMetricsApiInjectable), + requestPodMetricsByNamespace: di.inject(requestPodMetricsByNamespaceInjectable), context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), logger: di.inject(loggerInjectionToken), }, api); diff --git a/packages/core/src/renderer/components/workloads-pods/store.ts b/packages/core/src/renderer/components/workloads-pods/store.ts index 1c8ab8f57d..9c57a1bc8d 100644 --- a/packages/core/src/renderer/components/workloads-pods/store.ts +++ b/packages/core/src/renderer/components/workloads-pods/store.ts @@ -9,10 +9,11 @@ import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../ import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; import { cpuUnitsToNumber, unitsToBytes } from "@k8slens/utilities"; import type { Pod, PodMetrics, KubeObject, NamespaceScopedMetadata } from "@k8slens/kube-object"; -import type { PodApi, PodMetricsApi } from "@k8slens/kube-api"; +import type { PodApi } from "@k8slens/kube-api"; +import type { RequestPodMetricsByNamespace } from "./list-pod-metrics.injectable"; export interface PodStoreDependencies extends KubeObjectStoreDependencies { - readonly podMetricsApi: PodMetricsApi; + requestPodMetricsByNamespace: RequestPodMetricsByNamespace; } export class PodStore extends KubeObjectStore { @@ -28,7 +29,7 @@ export class PodStore extends KubeObjectStore { async loadKubeMetrics(namespace?: string) { try { - const metrics = await this.dependencies.podMetricsApi.list({ namespace }); + const metrics = await this.dependencies.requestPodMetricsByNamespace(namespace); this.kubeMetrics.replace(metrics ?? []); } catch (error) { diff --git a/packages/utility-features/json-api/src/json-api.ts b/packages/utility-features/json-api/src/json-api.ts index 06d69d0833..fa70ca0f7c 100644 --- a/packages/utility-features/json-api/src/json-api.ts +++ b/packages/utility-features/json-api/src/json-api.ts @@ -7,7 +7,6 @@ import { Agent as HttpAgent } from "http"; import { Agent as HttpsAgent } from "https"; import { merge } from "lodash"; import { stringify } from "querystring"; -import type { Patch } from "rfc6902"; import type { PartialDeep, ValueOf } from "type-fest"; import { EventEmitter } from "@k8slens/event-emitter"; import type { Logger } from "@k8slens/logger"; @@ -16,8 +15,6 @@ import type { RequestInit, Response } from "@k8slens/node-fetch"; import type { Defaulted } from "@k8slens/utilities"; import { isArray, isObject, isString, json } from "@k8slens/utilities"; -export type JsonApiData = Record; - export interface JsonApiError { code?: number; message?: string; @@ -106,7 +103,7 @@ export class JsonApiErrorParsed { } } -export class JsonApi = JsonApiParams> { +export class JsonApi { static readonly reqInitDefault = { headers: { "content-type": "application/json", @@ -188,7 +185,7 @@ export class JsonApi = Js patch( path: string, - params?: ParamsAndQuery, Query> & { data?: Patch | PartialDeep }, + params?: ParamsAndQuery, reqInit: RequestInit = {}, ) { return this.request(path, params, { ...reqInit, method: "patch" }); @@ -204,7 +201,7 @@ export class JsonApi = Js protected async request( path: string, - params: (ParamsAndQuery, Query> & { data?: unknown }) | undefined, + params: ParamsAndQuery | undefined, init: Defaulted, ) { let reqUrl = `${this.config.serverAddress}${this.config.apiBase}${path}`;