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

chore: Fix new build errors in @k8slens/core

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2023-05-03 08:06:13 -04:00
parent 64f3a47230
commit 3a62cd4848
23 changed files with 99 additions and 118 deletions

View File

@ -7,9 +7,13 @@ import React from "react";
import type { import type {
DragDropContextProps, DragDropContextProps,
DraggableProps, DraggableProps,
DraggableProvided,
DraggableProvidedDraggableProps, DraggableProvidedDraggableProps,
DraggableStateSnapshot,
DroppableProps, DroppableProps,
DroppableProvided,
DroppableProvidedProps, DroppableProvidedProps,
DroppableStateSnapshot,
} from "react-beautiful-dnd"; } from "react-beautiful-dnd";
export const DragDropContext = ({ children }: DragDropContextProps) => <>{ children }</>; export const DragDropContext = ({ children }: DragDropContextProps) => <>{ children }</>;
@ -20,14 +24,14 @@ export const Draggable = ({ children }: DraggableProps) => (
{ {
draggableProps: {} as DraggableProvidedDraggableProps, draggableProps: {} as DraggableProvidedDraggableProps,
innerRef: () => {}, innerRef: () => {},
}, } as unknown as DraggableProvided,
{ {
isDragging: false, isDragging: false,
isDropAnimating: false, isDropAnimating: false,
}, } as DraggableStateSnapshot,
{ {
draggableId: "some-mock-draggable-id", draggableId: "some-mock-draggable-id",
mode: "FLUID", type: "FLUID",
source: { source: {
droppableId: "some-mock-droppable-id", droppableId: "some-mock-droppable-id",
index: 0, index: 0,
@ -44,11 +48,11 @@ export const Droppable = ({ children }: DroppableProps) => (
{ {
droppableProps: {} as DroppableProvidedProps, droppableProps: {} as DroppableProvidedProps,
innerRef: () => {}, innerRef: () => {},
}, } as unknown as DroppableProvided,
{ {
isDraggingOver: false, isDraggingOver: false,
isUsingPlaceholder: false, isUsingPlaceholder: false,
}, } as DroppableStateSnapshot,
) )
} }
</> </>

View File

@ -15,7 +15,7 @@ import appPathsInjectable from "./app-paths.injectable";
describe("app-paths", () => { describe("app-paths", () => {
let builder: ApplicationBuilder; let builder: ApplicationBuilder;
beforeEach(() => { beforeEach(async () => {
builder = getApplicationBuilder(); builder = getApplicationBuilder();
const defaultAppPathsStub: AppPaths = { const defaultAppPathsStub: AppPaths = {

View File

@ -6,6 +6,7 @@
import { getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "@k8slens/legacy-global-di"; import { getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "@k8slens/legacy-global-di";
import removeWeblinkInjectable from "../../features/weblinks/common/remove.injectable"; import removeWeblinkInjectable from "../../features/weblinks/common/remove.injectable";
import type { CatalogEntityContextMenuContext, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog"; import type { CatalogEntityContextMenuContext, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog";
import type { CatalogEntitySpec } from "../catalog/catalog-entity";
import { CatalogCategory, CatalogEntity, categoryVersion } from "../catalog/catalog-entity"; import { CatalogCategory, CatalogEntity, categoryVersion } from "../catalog/catalog-entity";
import productNameInjectable from "../vars/product-name.injectable"; import productNameInjectable from "../vars/product-name.injectable";
@ -15,7 +16,7 @@ export interface WebLinkStatus extends CatalogEntityStatus {
phase: WebLinkStatusPhase; phase: WebLinkStatusPhase;
} }
export interface WebLinkSpec { export interface WebLinkSpec extends CatalogEntitySpec {
url: string; url: string;
} }

View File

@ -5,7 +5,7 @@
import type { AsyncFnMock } from "@async-fn/jest"; import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn 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 { DiContainer } from "@ogre-tools/injectable";
import type { IncomingMessage } from "http"; import type { IncomingMessage } from "http";
import { anyObject } from "jest-mock-extended"; import { anyObject } from "jest-mock-extended";
@ -192,8 +192,8 @@ describe("requestNamespaceListPermissions", () => {
body: { body: {
status, status,
spec: {}, spec: {},
}, } as V1SelfSubjectRulesReview,
value: null as unknown as IncomingMessage, response: null as unknown as IncomingMessage,
}); });
}); });

View File

@ -3,38 +3,17 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectionToken } from "@ogre-tools/injectable"; import { getInjectionToken } from "@ogre-tools/injectable";
import type { RequiredKeysOf } from "type-fest";
import type { Route } from "./front-end-route-injection-token"; import type { Route } from "./front-end-route-injection-token";
type InferParametersFrom<TRoute> = TRoute extends Route<infer TParameters> type InferParametersFrom<TRoute> = TRoute extends Route<infer TParameters extends object>
? TParameters ? TParameters
: never; : never;
type RequiredKeys<T> = Exclude< type Parameters<TParameters extends object> = TParameters extends void
{
[K in keyof T]: T extends Record<K, T[K]> ? K : never;
}[keyof T],
undefined
>;
type ObjectContainingNoRequired<T> = T extends void
? never
: (
RequiredKeys<T> extends []
? Record<string, never>
: never
);
type ObjectContainsNoRequired<T> = T extends ObjectContainingNoRequired<T>
? true
: false;
// TODO: Missing types for:
// - Navigating to route without parameters, with parameters
// - Navigating to route with required parameters, without parameters
type Parameters<TParameters> = TParameters extends void
? { parameters?: undefined } ? { parameters?: undefined }
: ( : (
ObjectContainsNoRequired<TParameters> extends true RequiredKeysOf<TParameters> extends never
? { parameters?: TParameters } ? { parameters?: TParameters }
: { parameters: TParameters } : { parameters: TParameters }
); );

View File

@ -16,10 +16,9 @@ const navigateToCatalogInjectable = getInjectable({
const navigateToRoute = di.inject(navigateToRouteInjectionToken); const navigateToRoute = di.inject(navigateToRouteInjectionToken);
const catalogRoute = di.inject(catalogRouteInjectable); const catalogRoute = di.inject(catalogRouteInjectable);
return (parameters) => return (parameters) => navigateToRoute(catalogRoute, {
navigateToRoute(catalogRoute, { parameters,
parameters, });
});
}, },
}); });

View File

@ -3,8 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import type { WriteFileOptions } from "fs"; import type { CopyOptions, EnsureOptions, ReadOptions, WriteOptions } from "fs-extra";
import type { ReadOptions } from "fs-extra";
import fse from "fs-extra"; import fse from "fs-extra";
export type FileSystemFunctions = ReturnType<(typeof fsInjectable)["instantiate"]>; export type FileSystemFunctions = ReturnType<(typeof fsInjectable)["instantiate"]>;
@ -45,7 +44,7 @@ const fsInjectable = getInjectable({
readFile, readFile,
readJson: readJson as (file: string, options?: ReadOptions | BufferEncoding) => Promise<unknown>, readJson: readJson as (file: string, options?: ReadOptions | BufferEncoding) => Promise<unknown>,
writeFile, writeFile,
writeJson: writeJson as (file: string, value: unknown, options?: string | WriteFileOptions) => Promise<void>, writeJson: writeJson as (file: string, value: unknown, options?: string | WriteOptions) => Promise<void>,
pathExists, pathExists,
readdir, readdir,
readFileSync, readFileSync,
@ -56,8 +55,8 @@ const fsInjectable = getInjectable({
lstat, lstat,
rm, rm,
access, access,
copy: copy as (src: string, dest: string, options?: fse.CopyOptions) => Promise<void>, copy: copy as (src: string, dest: string, options?: CopyOptions) => Promise<void>,
ensureDir: ensureDir as (path: string, options?: number | fse.EnsureOptions ) => Promise<void>, ensureDir: ensureDir as (path: string, options?: number | EnsureOptions ) => Promise<void>,
ensureDirSync, ensureDirSync,
createReadStream, createReadStream,
stat, stat,

View File

@ -13,10 +13,12 @@ import { parseKubeApi, createKubeApiURL } from "@k8slens/kube-api";
import { getOrInsertWith, iter } from "@k8slens/utilities"; import { getOrInsertWith, iter } from "@k8slens/utilities";
import type { CreateCustomResourceStore } from "./create-custom-resource-store.injectable"; import type { CreateCustomResourceStore } from "./create-custom-resource-store.injectable";
export type RegisterableStore<Store> = Store extends KubeObjectStore // eslint-disable-next-line @typescript-eslint/no-explicit-any
export type RegisterableStore<Store> = Store extends KubeObjectStore<any, any, any>
? Store ? Store
: never; : never;
export type RegisterableApi<Api> = Api extends KubeApi // eslint-disable-next-line @typescript-eslint/no-explicit-any
export type RegisterableApi<Api> = Api extends KubeApi<any, any>
? Api ? Api
: never; : never;
export type KubeObjectStoreFrom<Api> = Api extends KubeApi<infer KubeObj, infer ApiData> export type KubeObjectStoreFrom<Api> = Api extends KubeApi<infer KubeObj, infer ApiData>

View File

@ -8,10 +8,10 @@ import type { RequestInit } from "@k8slens/node-fetch";
import lensProxyCertificateInjectable from "../certificate/lens-proxy-certificate.injectable"; import lensProxyCertificateInjectable from "../certificate/lens-proxy-certificate.injectable";
import fetchInjectable from "../fetch/fetch.injectable"; import fetchInjectable from "../fetch/fetch.injectable";
import { loggerInjectionToken } from "@k8slens/logger"; 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"; import { JsonApi } from "@k8slens/json-api";
export type CreateJsonApi = <Data = JsonApiData, Params extends JsonApiParams<Data> = JsonApiParams<Data>>(config: JsonApiConfig, reqInit?: RequestInit) => JsonApi<Data, Params>; export type CreateJsonApi = <Data = unknown, Params extends JsonApiParams<Data> = JsonApiParams<Data>>(config: JsonApiConfig, reqInit?: RequestInit) => JsonApi<Data, Params>;
const createJsonApiInjectable = getInjectable({ const createJsonApiInjectable = getInjectable({
id: "create-json-api", id: "create-json-api",

View File

@ -31,7 +31,7 @@ const requestCreateHelmReleaseInjectable = getInjectable({
return apiBase.post(requestCreateEndpoint.compile({}), { return apiBase.post(requestCreateEndpoint.compile({}), {
data: { data: {
chart: `${repo}/${chart}`, chart: `${repo}/${chart}`,
values: yaml.load(values), values: yaml.load(values) as object,
...data, ...data,
}, },
}); });

View File

@ -46,7 +46,7 @@ const requestMetricsInjectable = getInjectable({
function requestMetrics(query: string, params?: RequestMetricsParams): Promise<MetricData>; function requestMetrics(query: string, params?: RequestMetricsParams): Promise<MetricData>;
function requestMetrics(query: string[], params?: RequestMetricsParams): Promise<MetricData[]>; function requestMetrics(query: string[], params?: RequestMetricsParams): Promise<MetricData[]>;
function requestMetrics<Keys extends string>(query: Record<Keys, Partial<Record<string, string>>>, params?: RequestMetricsParams): Promise<Record<Keys, MetricData>>; function requestMetrics<Keys extends string>(query: Record<Keys, Partial<Record<string, string>>>, params?: RequestMetricsParams): Promise<Record<Keys, MetricData>>;
async function requestMetrics(query: string | string[] | Partial<Record<string, Partial<Record<string, string>>>>, params: RequestMetricsParams = {}): Promise<MetricData | MetricData[] | Partial<Record<string, MetricData>>> { async function requestMetrics(metricsQuery: string | string[] | Partial<Record<string, Partial<Record<string, string>>>>, params: RequestMetricsParams = {}): Promise<MetricData | MetricData[] | Partial<Record<string, MetricData>>> {
const { range = 3600, step = 60, namespace } = params; const { range = 3600, step = 60, namespace } = params;
let { start, end } = params; let { start, end } = params;
@ -58,7 +58,7 @@ const requestMetricsInjectable = getInjectable({
} }
return apiBase.post("/metrics", { return apiBase.post("/metrics", {
data: query, data: metricsQuery,
query: { query: {
start, end, step, start, end, step,
"kubernetes_namespace": namespace, "kubernetes_namespace": namespace,

View File

@ -6,9 +6,10 @@ import { getInjectable } from "@ogre-tools/injectable";
import type { Patch } from "rfc6902"; import type { Patch } from "rfc6902";
import apiBaseInjectable from "../../api-base.injectable"; import apiBaseInjectable from "../../api-base.injectable";
import type { AsyncResult, Result } from "@k8slens/utilities"; import type { AsyncResult, Result } from "@k8slens/utilities";
import { result } from "@k8slens/utilities";
import type { KubeJsonApiData } from "@k8slens/kube-object"; import type { KubeJsonApiData } from "@k8slens/kube-object";
export type RequestKubeObjectPatch = (name: string, kind: string, ns: string | undefined, patch: Patch) => AsyncResult<KubeJsonApiData, string>; export type RequestKubeObjectPatch = (name: string, kind: string, ns: string | undefined, patch: Patch) => AsyncResult<KubeJsonApiData, Error>;
const requestKubeObjectPatchInjectable = getInjectable({ const requestKubeObjectPatchInjectable = getInjectable({
id: "request-kube-object-patch", id: "request-kube-object-patch",
@ -16,7 +17,7 @@ const requestKubeObjectPatchInjectable = getInjectable({
const apiBase = di.inject(apiBaseInjectable); const apiBase = di.inject(apiBaseInjectable);
return async (name, kind, ns, patch) => { return async (name, kind, ns, patch) => {
const result = (await apiBase.patch("/stack", { const patchResult = (await apiBase.patch("/stack", {
data: { data: {
name, name,
kind, kind,
@ -25,22 +26,14 @@ const requestKubeObjectPatchInjectable = getInjectable({
}, },
})) as Result<string, string>; })) as Result<string, string>;
if (!result.isOk) { if (!patchResult.isOk) {
return result; return result.wrapError("Failed to patch kube object", patchResult);
} }
try { try {
const response = JSON.parse(result.value) as KubeJsonApiData; return result.ok(JSON.parse(patchResult.value) as KubeJsonApiData);
return {
isOk: true,
response,
};
} catch (error) { } catch (error) {
return { return result.error(new Error("Failed to parse response from patching kube object", { cause: error }));
isOk: false,
error: String(error),
};
} }
}; };
}, },

View File

@ -5,9 +5,10 @@
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import apiBaseInjectable from "../../api-base.injectable"; import apiBaseInjectable from "../../api-base.injectable";
import type { AsyncResult, Result } from "@k8slens/utilities"; import type { AsyncResult, Result } from "@k8slens/utilities";
import { result } from "@k8slens/utilities";
import type { KubeJsonApiData } from "@k8slens/kube-object"; import type { KubeJsonApiData } from "@k8slens/kube-object";
export type RequestKubeObjectCreation = (resourceDescriptor: string) => AsyncResult<KubeJsonApiData, string>; export type RequestKubeObjectCreation = (resourceDescriptor: string) => AsyncResult<KubeJsonApiData, Error>;
const requestKubeObjectCreationInjectable = getInjectable({ const requestKubeObjectCreationInjectable = getInjectable({
id: "request-kube-object-creation", id: "request-kube-object-creation",
@ -15,24 +16,16 @@ const requestKubeObjectCreationInjectable = getInjectable({
const apiBase = di.inject(apiBaseInjectable); const apiBase = di.inject(apiBaseInjectable);
return async (data) => { return async (data) => {
const result = await apiBase.post("/stack", { data }) as Result<string, string>; const postResult = await apiBase.post("/stack", { data }) as Result<string, string>;
if (!result.isOk) { if (!postResult.isOk) {
return result; return result.wrapError("Failed to create kube object", postResult);
} }
try { try {
const response = JSON.parse(result.value) as KubeJsonApiData; return result.ok(JSON.parse(postResult.value) as KubeJsonApiData);
return {
isOk: true,
response,
};
} catch (error) { } catch (error) {
return { return result.error(new Error("Failed to parse result from kube object creation", { cause: error }));
isOk: false,
error: String(error),
};
} }
}; };
}, },

View File

@ -57,7 +57,7 @@ describe("with-error-suppression", () => {
}); });
describe("given decorated async function", () => { describe("given decorated async function", () => {
let decorated: (a: string, b: string) => Promise<number> | Promise<void>; let decorated: (a: string, b: string) => Promise<number | undefined>;
let toBeDecorated: AsyncFnMock<(a: string, b: string) => Promise<number>>; let toBeDecorated: AsyncFnMock<(a: string, b: string) => Promise<number>>;
beforeEach(() => { beforeEach(() => {
@ -67,7 +67,7 @@ describe("with-error-suppression", () => {
}); });
describe("when called", () => { describe("when called", () => {
let returnValuePromise: Promise<number> | Promise<void>; let returnValuePromise: Promise<number | undefined>;
beforeEach(() => { beforeEach(() => {
returnValuePromise = decorated("some-parameter", "some-other-parameter"); returnValuePromise = decorated("some-parameter", "some-other-parameter");

View File

@ -13,8 +13,8 @@ const withOrphanPromiseInjectable = getInjectable({
instantiate: (di) => { instantiate: (di) => {
const withErrorLoggingFor = di.inject(withErrorLoggingInjectable); const withErrorLoggingFor = di.inject(withErrorLoggingInjectable);
return <T extends (...args: unknown[]) => Promise<unknown>>(toBeDecorated: T) => return <Args extends unknown[]>(toBeDecorated: (...args: Args) => unknown) =>
(...args: Parameters<T>): void => { (...args: Args): void => {
const decorated = pipeline( const decorated = pipeline(
toBeDecorated, toBeDecorated,
withErrorLoggingFor(() => "Orphan promise rejection encountered"), withErrorLoggingFor(() => "Orphan promise rejection encountered"),

View File

@ -5,7 +5,6 @@
import { runInAction } from "mobx"; import { runInAction } from "mobx";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } 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 getHashInjectable from "../../extensions/extension-loader/file-system-provisioner-store/get-hash.injectable";
import fsInjectable from "../../common/fs/fs.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", () => { describe("when extension with a specific store name is enabled", () => {
let testExtensionOptions: FakeExtensionOptions; beforeEach(async () => {
await builder.extensions.enable({
beforeEach(() => {
testExtensionOptions = {
id: "some-extension", id: "some-extension",
name: "some-extension-name", 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 () => { 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", () => { describe("when extension with no specific store name is enabled", () => {
let testExtensionOptions: FakeExtensionOptions; beforeEach(async () => {
await builder.extensions.enable({
beforeEach(() => {
testExtensionOptions = {
id: "some-extension", id: "some-extension",
name: "some-extension-name", 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 () => { it("creates extension directory for package name", async () => {

View File

@ -182,8 +182,8 @@ export class ExtensionLoader {
ipcMainHandle(extensionLoaderFromMainChannel, () => [...this.toJSON()]); ipcMainHandle(extensionLoaderFromMainChannel, () => [...this.toJSON()]);
ipcMainOn(extensionLoaderFromRendererChannel, (event, extensions: [LensExtensionId, InstalledExtension][]) => { ipcMainOn(extensionLoaderFromRendererChannel, (event, extensions) => {
this.syncExtensions(extensions); this.syncExtensions(extensions as [LensExtensionId, InstalledExtension][]);
}); });
} }
@ -205,8 +205,8 @@ export class ExtensionLoader {
}; };
void requestExtensionLoaderInitialState().then(extensionListHandler); void requestExtensionLoaderInitialState().then(extensionListHandler);
ipcRendererOn(extensionLoaderFromMainChannel, (event, extensions: [LensExtensionId, InstalledExtension][]) => { ipcRendererOn(extensionLoaderFromMainChannel, (event, extensions) => {
extensionListHandler(extensions); extensionListHandler(extensions as [LensExtensionId, InstalledExtension][]);
}); });
} }

View File

@ -5,7 +5,7 @@
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { registeredExtensionsInjectable } from "./registered-extensions.injectable"; import { registeredExtensionsInjectable } from "./registered-extensions.injectable";
import createPersistentStorageInjectable from "../../../features/persistent-storage/common/create.injectable"; import createPersistentStorageInjectable from "../../../features/persistent-storage/common/create.injectable";
import { action } from "mobx"; import { runInAction } from "mobx";
import { object } from "@k8slens/utilities"; import { object } from "@k8slens/utilities";
import storeMigrationVersionInjectable from "../../../common/vars/store-migration-version.injectable"; import storeMigrationVersionInjectable from "../../../common/vars/store-migration-version.injectable";
@ -21,7 +21,7 @@ const fileSystemProvisionerStoreInjectable = getInjectable({
configName: "lens-filesystem-provisioner-store", configName: "lens-filesystem-provisioner-store",
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
projectVersion: storeMigrationVersion, projectVersion: storeMigrationVersion,
fromStore: action(({ extensions = {}}) => { fromStore: ({ extensions = {}}) => runInAction(() => {
registeredExtensions.replace(object.entries(extensions)); registeredExtensions.replace(object.entries(extensions));
}), }),
toJSON: () => ({ toJSON: () => ({

View File

@ -11,6 +11,7 @@ import type { PodStatus } from "@k8slens/kube-object";
import { Pod } from "@k8slens/kube-object"; import { Pod } from "@k8slens/kube-object";
import type { RequestMetrics } from "../../../common/k8s-api/endpoints/metrics.api/request-metrics.injectable"; 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 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", () => { describe("workloads / pods", () => {
let rendered: RenderResult; let rendered: RenderResult;
@ -19,7 +20,10 @@ describe("workloads / pods", () => {
beforeEach(async () => { beforeEach(async () => {
builder = await getApplicationBuilder().setEnvironmentToClusterFrame(); builder = await getApplicationBuilder().setEnvironmentToClusterFrame();
builder.namespaces.add("default"); builder.namespaces.add("default");
await builder.beforeWindowStart(() => { await builder.beforeWindowStart(({ windowDi }) => {
windowDi.override(requestPodMetricsByNamespaceInjectable, () => () => Promise.resolve([]));
});
await builder.afterWindowStart(() => {
builder.allowKubeResource({ builder.allowKubeResource({
apiName: "pods", apiName: "pods",
group: "", group: "",

View File

@ -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<PodMetrics[] | null>;
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;

View File

@ -7,9 +7,9 @@ import podApiInjectable from "../../../common/k8s-api/endpoints/pod.api.injectab
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { getKubeStoreInjectable } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import { getKubeStoreInjectable } from "../../../common/k8s-api/api-manager/kube-object-store-token";
import { PodStore } from "./store"; 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 clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import { loggerInjectionToken } from "@k8slens/logger"; import { loggerInjectionToken } from "@k8slens/logger";
import requestPodMetricsByNamespaceInjectable from "./list-pod-metrics.injectable";
const podStoreInjectable = getKubeStoreInjectable({ const podStoreInjectable = getKubeStoreInjectable({
id: "pod-store", id: "pod-store",
@ -19,7 +19,7 @@ const podStoreInjectable = getKubeStoreInjectable({
const api = di.inject(podApiInjectable); const api = di.inject(podApiInjectable);
return new PodStore({ return new PodStore({
podMetricsApi: di.inject(podMetricsApiInjectable), requestPodMetricsByNamespace: di.inject(requestPodMetricsByNamespaceInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectionToken), logger: di.inject(loggerInjectionToken),
}, api); }, api);

View File

@ -9,10 +9,11 @@ import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../
import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store";
import { cpuUnitsToNumber, unitsToBytes } from "@k8slens/utilities"; import { cpuUnitsToNumber, unitsToBytes } from "@k8slens/utilities";
import type { Pod, PodMetrics, KubeObject, NamespaceScopedMetadata } from "@k8slens/kube-object"; 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 { export interface PodStoreDependencies extends KubeObjectStoreDependencies {
readonly podMetricsApi: PodMetricsApi; requestPodMetricsByNamespace: RequestPodMetricsByNamespace;
} }
export class PodStore extends KubeObjectStore<Pod, PodApi> { export class PodStore extends KubeObjectStore<Pod, PodApi> {
@ -28,7 +29,7 @@ export class PodStore extends KubeObjectStore<Pod, PodApi> {
async loadKubeMetrics(namespace?: string) { async loadKubeMetrics(namespace?: string) {
try { try {
const metrics = await this.dependencies.podMetricsApi.list({ namespace }); const metrics = await this.dependencies.requestPodMetricsByNamespace(namespace);
this.kubeMetrics.replace(metrics ?? []); this.kubeMetrics.replace(metrics ?? []);
} catch (error) { } catch (error) {

View File

@ -7,7 +7,6 @@ import { Agent as HttpAgent } from "http";
import { Agent as HttpsAgent } from "https"; import { Agent as HttpsAgent } from "https";
import { merge } from "lodash"; import { merge } from "lodash";
import { stringify } from "querystring"; import { stringify } from "querystring";
import type { Patch } from "rfc6902";
import type { PartialDeep, ValueOf } from "type-fest"; import type { PartialDeep, ValueOf } from "type-fest";
import { EventEmitter } from "@k8slens/event-emitter"; import { EventEmitter } from "@k8slens/event-emitter";
import type { Logger } from "@k8slens/logger"; 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 type { Defaulted } from "@k8slens/utilities";
import { isArray, isObject, isString, json } from "@k8slens/utilities"; import { isArray, isObject, isString, json } from "@k8slens/utilities";
export type JsonApiData = Record<string, never>;
export interface JsonApiError { export interface JsonApiError {
code?: number; code?: number;
message?: string; message?: string;
@ -106,7 +103,7 @@ export class JsonApiErrorParsed {
} }
} }
export class JsonApi<Data = JsonApiData, Params extends JsonApiParams<Data> = JsonApiParams<Data>> { export class JsonApi<Data = unknown, Params extends { data?: unknown } = { data?: unknown }> {
static readonly reqInitDefault = { static readonly reqInitDefault = {
headers: { headers: {
"content-type": "application/json", "content-type": "application/json",
@ -188,7 +185,7 @@ export class JsonApi<Data = JsonApiData, Params extends JsonApiParams<Data> = Js
patch<OutData = Data, Query = QueryParams>( patch<OutData = Data, Query = QueryParams>(
path: string, path: string,
params?: ParamsAndQuery<Omit<Params, "data">, Query> & { data?: Patch | PartialDeep<Data> }, params?: ParamsAndQuery<Params, Query>,
reqInit: RequestInit = {}, reqInit: RequestInit = {},
) { ) {
return this.request<OutData, Query>(path, params, { ...reqInit, method: "patch" }); return this.request<OutData, Query>(path, params, { ...reqInit, method: "patch" });
@ -204,7 +201,7 @@ export class JsonApi<Data = JsonApiData, Params extends JsonApiParams<Data> = Js
protected async request<OutData, Query = QueryParams>( protected async request<OutData, Query = QueryParams>(
path: string, path: string,
params: (ParamsAndQuery<Omit<Params, "data">, Query> & { data?: unknown }) | undefined, params: ParamsAndQuery<Params, Query> | undefined,
init: Defaulted<RequestInit, "method">, init: Defaulted<RequestInit, "method">,
) { ) {
let reqUrl = `${this.config.serverAddress}${this.config.apiBase}${path}`; let reqUrl = `${this.config.serverAddress}${this.config.apiBase}${path}`;