fix: lint errors and warnings
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
15 files changed
+51
-48
No files matched your search
@@ -109,7 +109,7 @@ export const WidgetPreviewPageContent = ({ kind, integrationData }: WidgetPrevie
|
||||
)}
|
||||
>
|
||||
<Comp
|
||||
options={state.options as never}
|
||||
options={state.options}
|
||||
integrationIds={state.integrationIds}
|
||||
width={dimensions.width}
|
||||
height={dimensions.height}
|
||||
|
||||
@@ -122,7 +122,7 @@ const InnerContent = ({ item, ...dimensions }: InnerContentProps) => {
|
||||
/>
|
||||
<BoardItemMenu offset={4} item={newItem} />
|
||||
<Comp
|
||||
options={options as never}
|
||||
options={options}
|
||||
integrationIds={item.integrationIds}
|
||||
isEditMode={isEditMode}
|
||||
boardId={board.id}
|
||||
|
||||
+10
-10
@@ -5,11 +5,11 @@ import { MemoryResourceParser } from "../../../kubernetes/resource-parser/memory
|
||||
const BYTES_IN_GIB = 1024 ** 3; // 1 GiB in bytes
|
||||
const BYTES_IN_MIB = 1024 ** 2; // 1 MiB in bytes
|
||||
const BYTES_IN_KIB = 1024; // 1 KiB in bytes
|
||||
const KI = "Ki";
|
||||
const MI = "Mi";
|
||||
const GI = "Gi";
|
||||
const TI = "Ti";
|
||||
const PI = "Pi";
|
||||
const KI_UNIT = "Ki";
|
||||
const MI_UNIT = "Mi";
|
||||
const GI_UNIT = "Gi";
|
||||
const TI_UNIT = "Ti";
|
||||
const PI_UNIT = "Pi";
|
||||
|
||||
describe("MemoryResourceParser", () => {
|
||||
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", () => {
|
||||
|
||||
@@ -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"> => {
|
||||
|
||||
@@ -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<string, string>),
|
||||
dn: LdapClient.getEntryDn(entry),
|
||||
} as {
|
||||
[key: string]: string;
|
||||
dn: string;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ export const createDbInsertCollectionForTransaction = <TTableKey extends TableKe
|
||||
for (const [key, values] of objectEntries(context)) {
|
||||
if (values.length >= 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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -36,7 +36,7 @@ const setupMockFetch = (responses: Record<string, MockResponseData>) => {
|
||||
new Response(body, {
|
||||
status: 200,
|
||||
headers: { "content-type": "application/json" },
|
||||
}) as unknown as Awaited<ReturnType<typeof fetchWithTrustedCertificatesAsync>>,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ const setupMockFetch = (responses: Record<string, MockResponseData>) => {
|
||||
new Response(JSON.stringify({ error: "Not Found" }), {
|
||||
status: 404,
|
||||
headers: { "content-type": "application/json" },
|
||||
}) as unknown as Awaited<ReturnType<typeof fetchWithTrustedCertificatesAsync>>,
|
||||
}),
|
||||
);
|
||||
});
|
||||
};
|
||||
@@ -82,7 +82,7 @@ describe("CoolifyIntegration", () => {
|
||||
new Response("Unauthorized", {
|
||||
status: 401,
|
||||
headers: { "content-type": "text/plain" },
|
||||
}) as unknown as Awaited<ReturnType<typeof fetchWithTrustedCertificatesAsync>>,
|
||||
}),
|
||||
);
|
||||
|
||||
const integration = createCoolifyIntegration();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -198,25 +198,23 @@ const Item = <TItem, TOptionValue extends UniqueIdentifier>({
|
||||
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}
|
||||
>
|
||||
<options.itemComponent
|
||||
|
||||
@@ -41,12 +41,12 @@ export function InstanceCard({ instance, options, isTiny, widgetKey }: InstanceC
|
||||
const baseUrl = instance.integrationUrl.replace(/\/+$/, "");
|
||||
const relativeTime = useTimeAgo(instance.updatedAt);
|
||||
|
||||
const onlineServers = instance.instanceInfo.servers.filter((s) => 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 (
|
||||
|
||||
@@ -135,6 +135,7 @@ export const reduceWidgetOptionsWithDefaultValues = (
|
||||
currentValue: Record<string, unknown> = {},
|
||||
) => {
|
||||
const definition = widgetImports[kind].definition;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
const options = definition.createOptions(settings) as Record<string, WidgetOptionDefinition>;
|
||||
return objectEntries(options).reduce(
|
||||
(prev, [key, value]) => ({
|
||||
|
||||
@@ -45,6 +45,7 @@ export const WidgetEditModal = createModal<ModalProps<WidgetKind>>(({ 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<string, OptionsBuilderResult[string]>;
|
||||
|
||||
const form = useForm({
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user