chore(deps): update dependency eslint to v9 (#452)

* chore(deps): update dependency eslint to v9

* chore: migrate eslint to v9

* fix: dependency issues

* fix: unit tests not working

* chore: disable lint check for Image component that does not work in ci

* fix: lint issue

---------

Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
This commit is contained in:
homarr-renovate[bot]
2024-06-08 20:49:57 +02:00
committed by GitHub
parent d7ecdf5567
commit 1bae7352dc
117 changed files with 686 additions and 604 deletions

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -16,7 +16,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -27,14 +27,9 @@
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"@umami/node": "^0.3.0",

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -14,7 +14,7 @@
"type": "module",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -40,15 +40,9 @@
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/dockerode": "^3.3.29",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"prettier": "^3.3.1",
"typescript": "^5.4.5"
},
"eslintConfig": {
"root": true,
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -72,7 +72,7 @@ function sanitizeContainers(
): DockerContainer[] {
return containers.map((container) => {
return {
name: container.Names[0]?.split("/")[1] || "Unknown",
name: container.Names[0]?.split("/")[1] ?? "Unknown",
id: container.Id,
instance: container.instance,
state: container.State as DockerContainerState,

View File

@@ -28,7 +28,7 @@ export class DockerSingleton {
host: `${host}:${ports[i]}`,
instance: new Docker({
host,
port: parseInt(ports[i] || "", 10),
port: parseInt(ports[i] ?? "", 10),
}),
});
return instances;
@@ -41,6 +41,7 @@ export class DockerSingleton {
}
public static getInstance(): DockerInstance[] {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!DockerSingleton.instances) {
DockerSingleton.instances = new DockerSingleton().createInstances();
}

View File

@@ -42,7 +42,7 @@ export const groupRouter = createTRPCRouter({
...group,
members: group.members.map((member) => member.user),
})),
totalCount: groupCount[0]!.count,
totalCount: groupCount[0]?.count ?? 0,
};
}),
getById: protectedProcedure.input(validation.group.byId).query(async ({ input, ctx }) => {

View File

@@ -15,7 +15,7 @@ export const iconsRouter = createTRPCRouter({
name: true,
url: true,
},
where: input.searchText?.length ?? 0 > 0 ? like(icons.name, `%${input.searchText}%`) : undefined,
where: (input.searchText?.length ?? 0) > 0 ? like(icons.name, `%${input.searchText}%`) : undefined,
limit: 5,
},
},

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { describe, expect, test, vi } from "vitest";
import type { Session } from "@homarr/auth";

View File

@@ -169,7 +169,7 @@ describe("byId should return group by id including members and permissions", ()
expect(result.id).toBe(groupId);
expect(result.members.length).toBe(1);
const userKeys = Object.keys(result?.members[0] ?? {});
const userKeys = Object.keys(result.members[0] ?? {});
expect(userKeys.length).toBe(4);
expect(["id", "name", "email", "image"].some((key) => userKeys.includes(key)));
expect(result.permissions.length).toBe(1);

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { describe, expect, it, vi } from "vitest";
import type { Session } from "@homarr/auth";

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { describe, expect, test, vi } from "vitest";
import type { Session } from "@homarr/auth";

View File

@@ -44,13 +44,6 @@ export const userRouter = createTRPCRouter({
});
}
if (!dbInvite || dbInvite.expirationDate < new Date()) {
throw new TRPCError({
code: "FORBIDDEN",
message: "Invalid invite",
});
}
await checkUsernameAlreadyTakenAndThrowAsync(ctx.db, input.username);
await createUserAsync(ctx.db, input);

View File

@@ -18,7 +18,7 @@ export const weatherRouter = createTRPCRouter({
maxTemp: weather.daily.temperature_2m_max[index],
minTemp: weather.daily.temperature_2m_min[index],
};
}) ?? [{ time: 0, weatherCode: 404 }],
}),
};
}),
});

View File

@@ -122,7 +122,7 @@ export const protectedProcedure = t.procedure.use(enforceUserIsAuthed);
export const permissionRequiredProcedure = {
requiresPermission: (permission: GroupPermissionKey) => {
return protectedProcedure.use(({ ctx, input, next }) => {
if (!ctx.session?.user.permissions.includes(permission)) {
if (!ctx.session.user.permissions.includes(permission)) {
throw new TRPCError({
code: "FORBIDDEN",
message: "Permission denied",

View File

@@ -44,10 +44,8 @@ export const createSignInCallback =
async ({ user }) => {
if (!isCredentialsRequest) return true;
if (!user) return true;
// https://github.com/nextauthjs/next-auth/issues/6106
if (!adapter?.createSession) {
if (!adapter.createSession) {
return false;
}
@@ -56,6 +54,7 @@ export const createSignInCallback =
await adapter.createSession({
sessionToken,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
userId: user.id!,
expires: sessionExpiry,
});

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -16,7 +16,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -40,15 +40,9 @@
"@homarr/definitions": "workspace:^0.1.0",
"@types/bcrypt": "5.0.2",
"@types/cookies": "0.9.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"prettier": "^3.3.1",
"typescript": "^5.4.5"
},
"eslintConfig": {
"root": true,
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -23,14 +23,14 @@ export const constructBoardPermissions = (board: BoardPermissionsProps, session:
const creatorId = "creator" in board ? board.creator?.id : board.creatorId;
return {
hasFullAccess: session?.user?.id === creatorId || session?.user.permissions.includes("board-full-access"),
hasFullAccess: session?.user.id === creatorId || session?.user.permissions.includes("board-full-access"),
hasChangeAccess:
session?.user?.id === creatorId ||
session?.user.id === creatorId ||
board.userPermissions.some(({ permission }) => permission === "board-change") ||
board.groupPermissions.some(({ permission }) => permission === "board-change") ||
session?.user.permissions.includes("board-modify-all"),
hasViewAccess:
session?.user?.id === creatorId ||
session?.user.id === creatorId ||
board.userPermissions.length >= 1 ||
board.groupPermissions.length >= 1 ||
board.isPublic ||

View File

@@ -1,8 +1,9 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { ResponseCookie } from "next/dist/compiled/@edge-runtime/cookies";
import type { ReadonlyRequestCookies } from "next/dist/server/web/spec-extension/adapters/request-cookies";
import { cookies } from "next/headers";
import type { Adapter, AdapterUser } from "@auth/core/adapters";
import type { Account, User } from "next-auth";
import type { Account } from "next-auth";
import type { JWT } from "next-auth/jwt";
import { describe, expect, it, test, vi } from "vitest";
@@ -141,21 +142,11 @@ describe("createSignInCallback", () => {
expect(result).toBe(true);
});
it("should return true if no user", async () => {
const isCredentialsRequest = true;
const signInCallback = createSignInCallback(createAdapter(), isCredentialsRequest);
const result = await signInCallback({
user: undefined as unknown as User,
account: {} as Account,
});
expect(result).toBe(true);
});
it("should return false if no adapter.createSession", async () => {
const isCredentialsRequest = true;
const signInCallback = createSignInCallback(
// https://github.com/nextauthjs/next-auth/issues/6106
undefined as unknown as Adapter,
{ createSession: undefined } as unknown as Adapter,
isCredentialsRequest,
);
const result = await signInCallback({

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -17,7 +17,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -25,13 +25,8 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import * as dotenv from "dotenv";
import type { Config } from "drizzle-kit";

View File

@@ -6,6 +6,7 @@ dotenv.config({ path: "../../.env" });
export default {
dialect: "sqlite",
schema: "./schema",
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
dbCredentials: { url: process.env.DB_URL! },
out: "./migrations/sqlite",
} satisfies Config;

View File

@@ -13,6 +13,7 @@ import * as sqliteSchema from "./schema/sqlite";
type HomarrDatabase = BetterSQLite3Database<typeof sqliteSchema>;
const init = () => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!connection) {
switch (process.env.DB_DRIVER) {
case "mysql2":
@@ -48,6 +49,7 @@ const initMySQL2 = () => {
} else {
connection = mysql.createConnection({
host: process.env.DB_HOST,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
database: process.env.DB_NAME!,
port: Number(process.env.DB_PORT),
user: process.env.DB_USER,

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { drizzle } from "drizzle-orm/mysql2";
import { migrate } from "drizzle-orm/mysql2/migrator";
import mysql from "mysql2";

View File

@@ -17,7 +17,7 @@
"build:sqlite": "esbuild migrations/sqlite/migrate.ts --bundle --platform=node --outfile=migrations/sqlite/migrate.cjs",
"build:mysql": "esbuild migrations/mysql/migrate.ts --bundle --platform=node --outfile=migrations/mysql/migrate.cjs",
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"migration:sqlite:generate": "drizzle-kit generate --config ./configs/sqlite.config.ts",
"migration:sqlite:run": "drizzle-kit migrate --config ./configs/sqlite.config.ts",
@@ -44,15 +44,9 @@
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/better-sqlite3": "7.6.10",
"dotenv-cli": "^7.4.2",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"prettier": "^3.3.1",
"typescript": "^5.4.5"
},
"eslintConfig": {
"root": true,
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { Column, InferSelectModel } from "drizzle-orm";
import type { ForeignKey as MysqlForeignKey, MySqlTableWithColumns } from "drizzle-orm/mysql-core";
import type { ForeignKey as SqliteForeignKey, SQLiteTableWithColumns } from "drizzle-orm/sqlite-core";

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -16,7 +16,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -24,14 +24,9 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"@homarr/common": "workspace:^0.1.0"

View File

@@ -115,16 +115,16 @@ export const integrationDefs = {
}
>;
export const getIconUrl = (integration: IntegrationKind) => integrationDefs[integration]?.iconUrl ?? null;
export const getIconUrl = (integration: IntegrationKind) => integrationDefs[integration].iconUrl;
export const getIntegrationName = (integration: IntegrationKind) => integrationDefs[integration].name;
export const getDefaultSecretKinds = (integration: IntegrationKind): IntegrationSecretKind[] =>
integrationDefs[integration]?.secretKinds[0];
integrationDefs[integration].secretKinds[0];
export const getAllSecretKindOptions = (
integration: IntegrationKind,
): [IntegrationSecretKind[], ...IntegrationSecretKind[][]] => integrationDefs[integration]?.secretKinds;
): [IntegrationSecretKind[], ...IntegrationSecretKind[][]] => integrationDefs[integration].secretKinds;
export const integrationKinds = objectKeys(integrationDefs);

View File

@@ -34,6 +34,7 @@ export const getPermissionsWithParents = (permissions: GroupPermissionKey[]): Gr
const getPermissionsInner = (permissionSet: Set<GroupPermissionKey>, permissions: GroupPermissionKey[]) => {
permissions.forEach((permission) => {
const children = groupPermissionParents[permission as keyof typeof groupPermissionParents];
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (children) {
getPermissionsInner(permissionSet, children);
}

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -2,6 +2,7 @@
"name": "@homarr/form",
"private": true,
"version": "0.1.0",
"type": "module",
"exports": {
".": "./index.ts"
},
@@ -15,7 +16,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -23,14 +24,9 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"@mantine/form": "^7.10.1",

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -16,7 +16,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -27,13 +27,8 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -32,6 +32,7 @@ export class GitHubIconRepository extends IconRepository {
const fileNameWithExtension = this.getFileNameWithoutExtensionFromPath(treeItem.path);
return {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
imageUrl: new URL(this.repositoryBlobUrlTemplate!.replace("{0}", treeItem.path)),
fileNameWithExtension: fileNameWithExtension,
local: false,

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -17,7 +17,7 @@
"type": "module",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -25,17 +25,12 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"dependencies": {
"@homarr/definitions": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -2,6 +2,7 @@
"name": "@homarr/log",
"private": true,
"version": "0.1.0",
"type": "module",
"exports": {
".": {
"types": "./src/index.d.ts",
@@ -19,7 +20,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -32,13 +33,8 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -1,7 +1,6 @@
void (async () => {
const { logger } = await import("./index.mjs");
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
const nextLogger = require("next/dist/build/output/log");
const getWinstonMethodForConsole = (consoleMethod) => {
@@ -37,9 +36,7 @@ void (async () => {
}
};
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
Object.keys(nextLogger.prefixes).forEach((method) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
nextLogger[method] = getWinstonMethodForNext(method);
});
})();

View File

@@ -0,0 +1,5 @@
import baseConfig from "@homarr/eslint-config/base";
import reactConfig from "@homarr/eslint-config/react";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig, ...reactConfig];

View File

@@ -2,6 +2,7 @@
"name": "@homarr/modals",
"private": true,
"version": "0.1.0",
"type": "module",
"exports": {
".": "./index.ts"
},
@@ -15,7 +16,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -27,13 +28,8 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -41,7 +41,7 @@ export const ConfirmModal = createModal<Omit<ConfirmModalProps, "title">>(({ act
const handleCancel = useCallback(
async (event: React.MouseEvent<HTMLButtonElement>) => {
typeof cancelProps?.onClick === "function" && cancelProps?.onClick(event);
typeof cancelProps?.onClick === "function" && cancelProps.onClick(event);
typeof onCancel === "function" && (await onCancel());
closeOnCancel && actions.closeModal();
},
@@ -51,7 +51,7 @@ export const ConfirmModal = createModal<Omit<ConfirmModalProps, "title">>(({ act
const handleConfirm = useCallback(
async (event: React.MouseEvent<HTMLButtonElement>) => {
setLoading(true);
typeof confirmProps?.onClick === "function" && confirmProps?.onClick(event);
typeof confirmProps?.onClick === "function" && confirmProps.onClick(event);
typeof onConfirm === "function" && (await onConfirm());
closeOnConfirm && actions.closeModal();
setLoading(false);
@@ -65,11 +65,11 @@ export const ConfirmModal = createModal<Omit<ConfirmModalProps, "title">>(({ act
<Group justify="flex-end" {...groupProps}>
<Button variant="default" {...cancelProps} onClick={handleCancel}>
{cancelProps?.children || translateIfNecessary(t, cancelLabel)}
{cancelProps?.children ?? translateIfNecessary(t, cancelLabel)}
</Button>
<Button {...confirmProps} onClick={handleConfirm} color="red.9" loading={loading}>
{confirmProps?.children || translateIfNecessary(t, confirmLabel)}
{confirmProps?.children ?? translateIfNecessary(t, confirmLabel)}
</Button>
</Group>
</>

View File

@@ -138,6 +138,8 @@ export const useModalAction = <TModal extends ModalDefinition>(modal: TModal) =>
return {
openModal: (innerProps: inferInnerProps<TModal>, options: OpenModalOptions | void) => {
// void actually is undefined
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
context.openModalInner({ modal, innerProps, options: options ?? {} });
},
};

View File

@@ -62,7 +62,7 @@ export const modalReducer = (state: ModalsState, action: OpenAction | CloseActio
const remainingModals = state.modals.filter((modal) => modal.id !== action.modalId);
return {
current: remainingModals[remainingModals.length - 1] || state.current,
current: remainingModals[remainingModals.length - 1] ?? state.current,
modals: remainingModals,
};
}

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -2,6 +2,7 @@
"name": "@homarr/notifications",
"private": true,
"version": "0.1.0",
"type": "module",
"exports": {
".": "./index.ts",
"./styles.css": "./src/styles.css"
@@ -16,7 +17,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -24,17 +25,12 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"dependencies": {
"@mantine/notifications": "^7.10.1",
"@homarr/ui": "workspace:^0.1.0"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -16,7 +16,7 @@
"type": "module",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -28,13 +28,8 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -16,7 +16,7 @@
"type": "module",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -30,13 +30,8 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -16,7 +16,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -24,13 +24,8 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -0,0 +1,5 @@
import baseConfig from "@homarr/eslint-config/base";
import reactConfig from "@homarr/eslint-config/react";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig, ...reactConfig];

View File

@@ -2,6 +2,7 @@
"name": "@homarr/spotlight",
"private": true,
"version": "0.1.0",
"type": "module",
"exports": {
".": "./index.ts",
"./styles.css": "./src/styles.css"
@@ -16,7 +17,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -24,14 +25,9 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"@mantine/spotlight": "^7.10.1",

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -2,6 +2,7 @@
"name": "@homarr/translation",
"private": true,
"version": "0.1.0",
"type": "module",
"exports": {
".": "./index.ts",
"./client": "./src/client.ts",
@@ -18,7 +19,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -26,14 +27,9 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"next-international": "^1.2.4"

View File

@@ -0,0 +1,5 @@
import baseConfig from "@homarr/eslint-config/base";
import reactConfig from "@homarr/eslint-config/react";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig, ...reactConfig];

View File

@@ -2,6 +2,7 @@
"name": "@homarr/ui",
"private": true,
"version": "0.1.0",
"type": "module",
"exports": {
".": "./index.ts",
"./styles.css": "./src/styles.css"
@@ -16,7 +17,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -25,17 +26,12 @@
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/css-modules": "^1.0.5",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"dependencies": {
"@homarr/log": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config"
}

View File

@@ -72,6 +72,7 @@ export const TextMultiSelect = ({ label, value = [], onChange, onBlur, onFocus,
onKeyDown={(event) => {
if (event.key === "Backspace" && search.length === 0) {
event.preventDefault();
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
handleValueRemove(value.at(-1)!);
}
}}

View File

@@ -0,0 +1,4 @@
import baseConfig from "@homarr/eslint-config/base";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig];

View File

@@ -17,7 +17,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -25,14 +25,9 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"zod": "^3.23.8",

View File

@@ -3,7 +3,9 @@ import { z } from "zod";
type CouldBeReadonlyArray<T> = T[] | readonly T[];
export const zodEnumFromArray = <T extends string>(array: CouldBeReadonlyArray<T>) =>
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
z.enum([array[0]!, ...array.slice(1)]);
export const zodUnionFromArray = <T extends z.ZodTypeAny>(array: CouldBeReadonlyArray<T>) =>
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
z.union([array[0]!, array[1]!, ...array.slice(2)]);

View File

@@ -13,7 +13,7 @@ export const zodErrorMap = <
const error = handleZodError(issue, ctx);
if ("message" in error && error.message)
return {
message: error.message ?? ctx.defaultError,
message: error.message,
};
return {
message: t(error.key ? `common.zod.${error.key}` : "common.zod.errors.default", error.params ?? {}),

View File

@@ -0,0 +1,5 @@
import baseConfig from "@homarr/eslint-config/base";
import reactConfig from "@homarr/eslint-config/react";
/** @type {import('typescript-eslint').Config} */
export default [...baseConfig, ...reactConfig];

View File

@@ -2,6 +2,7 @@
"name": "@homarr/widgets",
"private": true,
"version": "0.1.0",
"type": "module",
"exports": {
".": "./index.ts",
"./errors": "./src/errors/component.tsx"
@@ -16,7 +17,7 @@
"license": "MIT",
"scripts": {
"clean": "rm -rf .turbo node_modules",
"lint": "eslint .",
"lint": "eslint",
"format": "prettier --check . --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
@@ -26,14 +27,9 @@
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/prismjs": "^1.26.4",
"@types/video.js": "^7.3.58",
"eslint": "^8.57.0",
"eslint": "^9.4.0",
"typescript": "^5.4.5"
},
"eslintConfig": {
"extends": [
"@homarr/eslint-config/base"
]
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"@homarr/api": "workspace:^0.1.0",

View File

@@ -20,7 +20,7 @@ export const WidgetMultiSelectInput = ({ property, kind, options }: CommonWidget
? option
: {
value: option.value,
label: translateIfNecessary(t, option.label)!,
label: translateIfNecessary(t, option.label) ?? option.value,
},
)}
description={options.withDescription ? t("description") : undefined}

View File

@@ -36,7 +36,7 @@ export const WidgetSelectInput = ({ property, kind, options }: CommonWidgetInput
? option
: {
value: option.value,
label: translateIfNecessary(t, option.label)!,
label: translateIfNecessary(t, option.label) ?? option.value,
},
)}
description={options.withDescription ? tWidget("description") : undefined}

View File

@@ -27,7 +27,7 @@ export default function AppWidget({ options, serverData, isEditMode, width, heig
{
initialData:
// We need to check if the id's match because otherwise the same initialData for a changed id will be used
serverData?.app?.id === options.appId ? serverData?.app : undefined,
serverData?.app?.id === options.appId ? serverData.app : undefined,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
@@ -54,12 +54,12 @@ export default function AppWidget({ options, serverData, isEditMode, width, heig
? [
{
id: `app-${options.appId}`,
title: app?.name,
description: app?.description ?? "",
icon: app?.iconUrl,
title: app.name,
description: app.description ?? "",
icon: app.iconUrl,
group: "app",
type: "link",
href: app?.href,
href: app.href,
openInNewTab: options.openInNewTab,
},
]

View File

@@ -62,6 +62,7 @@ export const WidgetEditModal = createModal<ModalProps<WidgetKind>>(({ actions, i
{Object.entries(definition.options).map(([key, value]: [string, OptionsBuilderResult[string]]) => {
const Input = getInputForType(value.type);
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!Input || value.shouldHide?.(form.values.options as never)) {
return null;
}

View File

@@ -303,7 +303,9 @@ export function Notebook({ options, isEditMode, boardId, itemId }: WidgetCompone
<RichTextEditor.BulletList title={tControls("bulletList")} />
<RichTextEditor.OrderedList title={tControls("orderedList")} />
<TaskListToggle />
{(editor?.isActive("taskList") || editor?.isActive("bulletList") || editor?.isActive("orderedList")) && (
{(Boolean(editor?.isActive("taskList")) ||
Boolean(editor?.isActive("bulletList")) ||
Boolean(editor?.isActive("orderedList"))) && (
<>
<ListIndentIncrease />
<ListIndentDecrease />
@@ -680,7 +682,7 @@ function ListIndentIncrease() {
}, [editor, itemType]);
editor?.on("selectionUpdate", ({ editor }) => {
setItemType(editor?.isActive("taskItem") ? "taskItem" : "listItem");
setItemType(editor.isActive("taskItem") ? "taskItem" : "listItem");
});
return (
@@ -704,7 +706,7 @@ function ListIndentDecrease() {
}, [editor, itemType]);
editor?.on("selectionUpdate", ({ editor }) => {
setItemType(editor?.isActive("taskItem") ? "taskItem" : "listItem");
setItemType(editor.isActive("taskItem") ? "taskItem" : "listItem");
});
return (

View File

@@ -98,6 +98,7 @@ export const WidgetIntegrationSelect = ({
if (event.key !== "Backspace") return;
event.preventDefault();
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
handleValueRemove(multiSelectValues[multiSelectValues.length - 1]!);
}}
/>