From 7dabc89ab644ace8973f561fb37329983d9a6e7c Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Mon, 27 Apr 2026 22:07:52 +0200 Subject: [PATCH] fix: lint errors and warnings Co-authored-by: Copilot --- .../app/[locale]/widgets/[kind]/_content.tsx | 2 +- .../components/board/items/item-content.tsx | 2 +- .../memory-resource-parser.spec.ts | 20 +++++------ packages/auth/callbacks.ts | 2 +- .../auth/providers/credentials/ldap-client.ts | 3 -- packages/db/collection.ts | 2 +- .../coolify/test/coolify-integration.spec.ts | 6 ++-- packages/integrations/test/sabnzbd.spec.ts | 6 ++-- packages/request-handler/src/docker.ts | 2 ++ packages/server-settings/src/index.ts | 4 +++ .../widget-sortable-item-list-input.tsx | 36 +++++++++---------- .../widgets/src/coolify/instance-card.tsx | 6 ++-- packages/widgets/src/index.tsx | 1 + .../widgets/src/modals/widget-edit-modal.tsx | 1 + .../src/system-resources/component.tsx | 6 ++-- 15 files changed, 51 insertions(+), 48 deletions(-) diff --git a/apps/nextjs/src/app/[locale]/widgets/[kind]/_content.tsx b/apps/nextjs/src/app/[locale]/widgets/[kind]/_content.tsx index cd8b67ea2..816f6b722 100644 --- a/apps/nextjs/src/app/[locale]/widgets/[kind]/_content.tsx +++ b/apps/nextjs/src/app/[locale]/widgets/[kind]/_content.tsx @@ -109,7 +109,7 @@ export const WidgetPreviewPageContent = ({ kind, integrationData }: WidgetPrevie )} > { /> { const parser = new MemoryResourceParser(); @@ -20,11 +20,11 @@ describe("MemoryResourceParser", () => { }); it("should parse binary units (Ki, Mi, Gi, Ti, Pi) into GiB", () => { - expect(parser.parse(`1024${KI}`)).toBeCloseTo(1 / 1024); // 1 MiB = 1/1024 GiB - expect(parser.parse(`1${MI}`)).toBeCloseTo(1 / 1024); // 1 MiB = 1/1024 GiB - expect(parser.parse(`1${GI}`)).toBe(1); // 1 GiB - expect(parser.parse(`1${TI}`)).toBe(BYTES_IN_KIB); // 1 TiB = 1024 GiB - expect(parser.parse(`1${PI}`)).toBe(BYTES_IN_MIB); // 1 PiB = 1024^2 GiB + expect(parser.parse(`1024${KI_UNIT}`)).toBeCloseTo(1 / 1024); // 1 MiB = 1/1024 GiB + expect(parser.parse(`1${MI_UNIT}`)).toBeCloseTo(1 / 1024); // 1 MiB = 1/1024 GiB + expect(parser.parse(`1${GI_UNIT}`)).toBe(1); // 1 GiB + expect(parser.parse(`1${TI_UNIT}`)).toBe(BYTES_IN_KIB); // 1 TiB = 1024 GiB + expect(parser.parse(`1${PI_UNIT}`)).toBe(BYTES_IN_MIB); // 1 PiB = 1024^2 GiB }); it("should parse decimal units (K, M, G, T, P) into GiB", () => { diff --git a/packages/auth/callbacks.ts b/packages/auth/callbacks.ts index 8f1168ad8..546c49410 100644 --- a/packages/auth/callbacks.ts +++ b/packages/auth/callbacks.ts @@ -38,7 +38,7 @@ export const createSessionAsync = async ( permissions: await getCurrentUserPermissionsAsync(db, user.id), colorScheme: "dark", }, - } as Session; + }; }; export const createSessionCallback = (db: Database): NextAuthCallbackOf<"session"> => { diff --git a/packages/auth/providers/credentials/ldap-client.ts b/packages/auth/providers/credentials/ldap-client.ts index 4dc48e2a8..bbf171f0d 100644 --- a/packages/auth/providers/credentials/ldap-client.ts +++ b/packages/auth/providers/credentials/ldap-client.ts @@ -49,9 +49,6 @@ export class LdapClient { .map(([key, value]) => [key, LdapClient.convertEntryPropertyToString(value)] as const) .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {} as Record), dn: LdapClient.getEntryDn(entry), - } as { - [key: string]: string; - dn: string; }; }); } diff --git a/packages/db/collection.ts b/packages/db/collection.ts index 00e5aba18..80bc79699 100644 --- a/packages/db/collection.ts +++ b/packages/db/collection.ts @@ -50,7 +50,7 @@ export const createDbInsertCollectionForTransaction = = 1) { // Below is actually the mysqlSchema when the driver is mysql - await transaction.insert(schema[key] as never).values(values as never); + await transaction.insert(schema[key] as never).values(values); } } }); diff --git a/packages/integrations/src/coolify/test/coolify-integration.spec.ts b/packages/integrations/src/coolify/test/coolify-integration.spec.ts index c551fd3dc..44264a7fd 100644 --- a/packages/integrations/src/coolify/test/coolify-integration.spec.ts +++ b/packages/integrations/src/coolify/test/coolify-integration.spec.ts @@ -36,7 +36,7 @@ const setupMockFetch = (responses: Record) => { new Response(body, { status: 200, headers: { "content-type": "application/json" }, - }) as unknown as Awaited>, + }), ); } @@ -44,7 +44,7 @@ const setupMockFetch = (responses: Record) => { new Response(JSON.stringify({ error: "Not Found" }), { status: 404, headers: { "content-type": "application/json" }, - }) as unknown as Awaited>, + }), ); }); }; @@ -82,7 +82,7 @@ describe("CoolifyIntegration", () => { new Response("Unauthorized", { status: 401, headers: { "content-type": "text/plain" }, - }) as unknown as Awaited>, + }), ); const integration = createCoolifyIntegration(); diff --git a/packages/integrations/test/sabnzbd.spec.ts b/packages/integrations/test/sabnzbd.spec.ts index 8603f04a0..58cc7fe5c 100644 --- a/packages/integrations/test/sabnzbd.spec.ts +++ b/packages/integrations/test/sabnzbd.spec.ts @@ -1,13 +1,12 @@ import { join } from "path"; -import { GenericContainer, getContainerRuntimeClient, ImageName, Wait } from "testcontainers"; import type { StartedTestContainer } from "testcontainers"; +import { GenericContainer, getContainerRuntimeClient, ImageName, Wait } from "testcontainers"; import { beforeAll, describe, expect, test, vi } from "vitest"; import { createDb } from "@homarr/db/test"; import { SabnzbdIntegration } from "../src"; import { TestConnectionError } from "../src/base/test-connection/test-connection-error"; -import type { DownloadClientItem } from "../src/interfaces/downloads/download-client-items"; vi.mock("@homarr/db", async (importActual) => { // eslint-disable-next-line @typescript-eslint/consistent-type-imports @@ -189,8 +188,7 @@ describe("Sabnzbd integration", () => { const item = await sabNzbdAddItemAsync(startedContainer, DEFAULT_API_KEY, sabnzbdIntegration); // Act - fromDisk already doesn't work for sabnzbd, so only test deletion itself. - const actAsync = async () => - await sabnzbdIntegration.deleteItemAsync({ ...item, progress: 0 } as DownloadClientItem, false); + const actAsync = async () => await sabnzbdIntegration.deleteItemAsync({ ...item, progress: 0 }, false); const getAsync = async () => await sabnzbdIntegration.getClientJobsAndStatusAsync({ limit: 99 }); // Assert diff --git a/packages/request-handler/src/docker.ts b/packages/request-handler/src/docker.ts index 7b873ec00..d46615f9c 100644 --- a/packages/request-handler/src/docker.ts +++ b/packages/request-handler/src/docker.ts @@ -73,6 +73,8 @@ async function getContainersWithStatsAsync() { cpuUsage, memoryUsage, image: container.Image, + // In some cases the type of Ports can also be undefined + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion ports: container.Ports as Dockerode.Port[] | undefined, }; }); diff --git a/packages/server-settings/src/index.ts b/packages/server-settings/src/index.ts index 5c4470f6a..914b536fc 100644 --- a/packages/server-settings/src/index.ts +++ b/packages/server-settings/src/index.ts @@ -36,9 +36,13 @@ export const defaultServerSettings = { enableGravatar: true, }, appearance: { + // We want to force the type to be bigger than just "light" to allow other values + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion defaultColorScheme: "light" as ColorScheme, }, culture: { + // We want to force the type to be bigger than just "light" to allow other values + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion defaultLocale: "en" as SupportedLanguage, }, search: { diff --git a/packages/widgets/src/_inputs/widget-sortable-item-list-input.tsx b/packages/widgets/src/_inputs/widget-sortable-item-list-input.tsx index d765c1d73..9d503f9ad 100644 --- a/packages/widgets/src/_inputs/widget-sortable-item-list-input.tsx +++ b/packages/widgets/src/_inputs/widget-sortable-item-list-input.tsx @@ -198,25 +198,23 @@ const Item = ({ shadow="xs" padding="sm" radius="md" - style={ - { - transition: [transition].filter(Boolean).join(", "), - "--translate-x": transform ? `${Math.round(transform.x)}px` : undefined, - "--translate-y": transform ? `${Math.round(transform.y)}px` : undefined, - "--scale-x": transform?.scaleX ? `${transform.scaleX}` : undefined, - "--scale-y": transform?.scaleY ? `${transform.scaleY}` : undefined, - "--index": index, - transform: - "translate3d(var(--translate-x, 0), var(--translate-y, 0), 0) scaleX(var(--scale-x, 1)) scaleY(var(--scale-y, 1))", - transformOrigin: "0 0", - ...(isDragging - ? { - opacity: "var(--dragging-opacity, 0.5)", - zIndex: 0, - } - : {}), - } as React.CSSProperties - } + style={{ + transition: [transition].filter(Boolean).join(", "), + "--translate-x": transform ? `${Math.round(transform.x)}px` : undefined, + "--translate-y": transform ? `${Math.round(transform.y)}px` : undefined, + "--scale-x": transform?.scaleX ? `${transform.scaleX}` : undefined, + "--scale-y": transform?.scaleY ? `${transform.scaleY}` : undefined, + "--index": index, + transform: + "translate3d(var(--translate-x, 0), var(--translate-y, 0), 0) scaleX(var(--scale-x, 1)) scaleY(var(--scale-y, 1))", + transformOrigin: "0 0", + ...(isDragging + ? { + opacity: "var(--dragging-opacity, 0.5)", + zIndex: 0, + } + : {}), + }} ref={setNodeRef} > s.is_reachable !== false).length; + const onlineServers = instance.instanceInfo.servers.filter(({ is_reachable }) => is_reachable !== false).length; const runningApps = instance.instanceInfo.applications.filter( - (a) => parseStatus(a.status ?? "") === "running", + ({ status }) => parseStatus(status ?? "") === "running", ).length; const runningServices = instance.instanceInfo.services.filter( - (s) => parseStatus(s.status ?? "") === "running", + ({ status }) => parseStatus(status ?? "") === "running", ).length; return ( diff --git a/packages/widgets/src/index.tsx b/packages/widgets/src/index.tsx index a59f93f42..0038791c8 100644 --- a/packages/widgets/src/index.tsx +++ b/packages/widgets/src/index.tsx @@ -135,6 +135,7 @@ export const reduceWidgetOptionsWithDefaultValues = ( currentValue: Record = {}, ) => { const definition = widgetImports[kind].definition; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const options = definition.createOptions(settings) as Record; return objectEntries(options).reduce( (prev, [key, value]) => ({ diff --git a/packages/widgets/src/modals/widget-edit-modal.tsx b/packages/widgets/src/modals/widget-edit-modal.tsx index d05ac95c1..948414d6a 100644 --- a/packages/widgets/src/modals/widget-edit-modal.tsx +++ b/packages/widgets/src/modals/widget-edit-modal.tsx @@ -45,6 +45,7 @@ export const WidgetEditModal = createModal>(({ actions, i customError: zodErrorMap(t), }); const { definition } = widgetImports[innerProps.kind]; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const options = definition.createOptions(innerProps.settings) as Record; const form = useForm({ diff --git a/packages/widgets/src/system-resources/component.tsx b/packages/widgets/src/system-resources/component.tsx index d1d54ff85..efa1de835 100644 --- a/packages/widgets/src/system-resources/component.tsx +++ b/packages/widgets/src/system-resources/component.tsx @@ -32,7 +32,8 @@ export default function SystemResources({ integrationIds, options }: WidgetCompo memory: item.healthInfo.memUsedInBytes, gpu: item.healthInfo.gpu.length > 0 - ? item.healthInfo.gpu.reduce((acc, g) => acc + g.processorUtilization, 0) / item.healthInfo.gpu.length + ? item.healthInfo.gpu.reduce((acc, { processorUtilization }) => acc + processorUtilization, 0) / + item.healthInfo.gpu.length : 0, network: item.healthInfo.network, })), @@ -50,7 +51,8 @@ export default function SystemResources({ integrationIds, options }: WidgetCompo memory: data.healthInfo.memUsedInBytes, gpu: data.healthInfo.gpu.length > 0 - ? data.healthInfo.gpu.reduce((acc, g) => acc + g.processorUtilization, 0) / data.healthInfo.gpu.length + ? data.healthInfo.gpu.reduce((acc, { processorUtilization }) => acc + processorUtilization, 0) / + data.healthInfo.gpu.length : 0, network: data.healthInfo.network, };