chore(release): automatic release v1.0.0

This commit is contained in:
homarr-releases[bot]
2024-12-19 16:51:02 +00:00
committed by GitHub
134 changed files with 9690 additions and 2446 deletions

View File

@@ -40,6 +40,7 @@ jobs:
SKIP_RELEASE: ${{ github.event_name == 'workflow_dispatch' || github.ref_name == 'dev' }} SKIP_RELEASE: ${{ github.event_name == 'workflow_dispatch' || github.ref_name == 'dev' }}
outputs: outputs:
version: ${{ steps.read-semver.outputs.version || steps.version-fallback.outputs.version }} version: ${{ steps.read-semver.outputs.version || steps.version-fallback.outputs.version }}
git_ref: ${{ steps.read-git-ref.outputs.ref || github.ref }}
steps: steps:
- run: echo "Skipping release for workflow_dispatch event" - run: echo "Skipping release for workflow_dispatch event"
@@ -87,9 +88,16 @@ jobs:
run: | run: |
git fetch --tags git fetch --tags
echo "version=$(git describe --tags --abbrev=0)" >> "$GITHUB_OUTPUT" echo "version=$(git describe --tags --abbrev=0)" >> "$GITHUB_OUTPUT"
- name: Read git ref
if: env.SKIP_RELEASE == 'false'
id: read-git-ref
run: |
echo "ref=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
- name: Update dev branch - name: Update dev branch
if: env.SKIP_RELEASE == 'false' if: env.SKIP_RELEASE == 'false'
continue-on-error: true # Prevent pipeline from failing when merge fails continue-on-error: true # Prevent pipeline from failing when merge fails
env:
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
run: | run: |
git fetch origin dev git fetch origin dev
git checkout dev git checkout dev
@@ -107,6 +115,8 @@ jobs:
PUSH_IMAGE: ${{ github.event_name != 'workflow_dispatch' || github.events.inputs.push-image == true }} PUSH_IMAGE: ${{ github.event_name != 'workflow_dispatch' || github.events.inputs.push-image == true }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with:
ref: ${{ needs.release.outputs.git_ref }}
- name: Discord notification - name: Discord notification
if: ${{ github.events.inputs.send-notifications != false }} if: ${{ github.events.inputs.send-notifications != false }}
env: env:

View File

@@ -1,5 +1,6 @@
// Importing env files here to validate on build // Importing env files here to validate on build
import "@homarr/auth/env.mjs"; import "@homarr/auth/env.mjs";
import "@homarr/db/env.mjs";
import MillionLint from "@million/lint"; import MillionLint from "@million/lint";
import createNextIntlPlugin from "next-intl/plugin"; import createNextIntlPlugin from "next-intl/plugin";

View File

@@ -65,7 +65,7 @@
"glob": "^11.0.0", "glob": "^11.0.0",
"jotai": "^2.10.4", "jotai": "^2.10.4",
"mantine-react-table": "2.0.0-beta.7", "mantine-react-table": "2.0.0-beta.7",
"next": "^14.2.20", "next": "^14.2.21",
"postcss-preset-mantine": "^1.17.0", "postcss-preset-mantine": "^1.17.0",
"prismjs": "^1.29.0", "prismjs": "^1.29.0",
"react": "^19.0.0", "react": "^19.0.0",
@@ -84,7 +84,7 @@
"@types/chroma-js": "2.4.5", "@types/chroma-js": "2.4.5",
"@types/node": "^22.10.2", "@types/node": "^22.10.2",
"@types/prismjs": "^1.26.5", "@types/prismjs": "^1.26.5",
"@types/react": "^19.0.1", "@types/react": "^19.0.2",
"@types/react-dom": "^19.0.2", "@types/react-dom": "^19.0.2",
"@types/swagger-ui-react": "^4.18.3", "@types/swagger-ui-react": "^4.18.3",
"concurrently": "^9.1.0", "concurrently": "^9.1.0",

View File

@@ -4,7 +4,7 @@ import { Card, Center, Stack, Text, Title } from "@mantine/core";
import { auth } from "@homarr/auth/next"; import { auth } from "@homarr/auth/next";
import { isProviderEnabled } from "@homarr/auth/server"; import { isProviderEnabled } from "@homarr/auth/server";
import { and, db, eq } from "@homarr/db"; import { and, db, eq } from "@homarr/db";
import { invites } from "@homarr/db/schema/sqlite"; import { invites } from "@homarr/db/schema";
import { getScopedI18n } from "@homarr/translation/server"; import { getScopedI18n } from "@homarr/translation/server";
import { HomarrLogoWithTitle } from "~/components/layout/logo/homarr-logo"; import { HomarrLogoWithTitle } from "~/components/layout/logo/homarr-logo";

View File

@@ -2,7 +2,7 @@ import { IconHomeOff } from "@tabler/icons-react";
import { auth } from "@homarr/auth/next"; import { auth } from "@homarr/auth/next";
import { db } from "@homarr/db"; import { db } from "@homarr/db";
import { boards } from "@homarr/db/schema/sqlite"; import { boards } from "@homarr/db/schema";
import { getI18n } from "@homarr/translation/server"; import { getI18n } from "@homarr/translation/server";
import type { BoardNotFoundProps } from "~/components/board/not-found"; import type { BoardNotFoundProps } from "~/components/board/not-found";

View File

@@ -24,10 +24,19 @@ export const ImportDropZone = ({ loading, updateFile }: ImportDropZoneProps) =>
}} }}
acceptColor="blue.6" acceptColor="blue.6"
rejectColor="red.6" rejectColor="red.6"
accept={[MIME_TYPES.zip]} accept={[MIME_TYPES.zip, "application/x-zip-compressed"]}
loading={loading} loading={loading}
multiple={false} multiple={false}
maxSize={1024 * 1024 * 1024 * 64} // 64 MB maxSize={1024 * 1024 * 1024 * 64} // 64 MB
onReject={(rejections) => {
console.error(
"Rejected files",
rejections.map(
(rejection) =>
`File: ${rejection.file.name} size=${rejection.file.size} fileType=${rejection.file.type}\n - ${rejection.errors.map((error) => error.message).join("\n - ")}`,
),
);
}}
> >
<Group justify="center" gap="xl" mih={220} style={{ pointerEvents: "none" }}> <Group justify="center" gap="xl" mih={220} style={{ pointerEvents: "none" }}>
<Dropzone.Accept> <Dropzone.Accept>

View File

@@ -3,7 +3,7 @@ import { notFound } from "next/navigation";
import { auth } from "@homarr/auth/next"; import { auth } from "@homarr/auth/next";
import { isProviderEnabled } from "@homarr/auth/server"; import { isProviderEnabled } from "@homarr/auth/server";
import { db, inArray } from "@homarr/db"; import { db, inArray } from "@homarr/db";
import { groups } from "@homarr/db/schema/sqlite"; import { groups } from "@homarr/db/schema";
import { everyoneGroup } from "@homarr/definitions"; import { everyoneGroup } from "@homarr/definitions";
import { getScopedI18n } from "@homarr/translation/server"; import { getScopedI18n } from "@homarr/translation/server";

View File

@@ -8,7 +8,7 @@ import { hashPasswordAsync } from "@homarr/auth";
import type { Session } from "@homarr/auth"; import type { Session } from "@homarr/auth";
import { createSessionAsync } from "@homarr/auth/server"; import { createSessionAsync } from "@homarr/auth/server";
import { db, eq } from "@homarr/db"; import { db, eq } from "@homarr/db";
import { apiKeys } from "@homarr/db/schema/sqlite"; import { apiKeys } from "@homarr/db/schema";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";
const handlerAsync = async (req: NextRequest) => { const handlerAsync = async (req: NextRequest) => {

View File

@@ -3,7 +3,7 @@ import { NextResponse } from "next/server";
import type { NextRequest } from "next/server"; import type { NextRequest } from "next/server";
import { db, eq } from "@homarr/db"; import { db, eq } from "@homarr/db";
import { medias } from "@homarr/db/schema/sqlite"; import { medias } from "@homarr/db/schema";
export async function GET(_req: NextRequest, { params }: { params: { id: string } }) { export async function GET(_req: NextRequest, { params }: { params: { id: string } }) {
const image = await db.query.medias.findFirst({ const image = await db.query.medias.findFirst({

View File

@@ -1,10 +1,6 @@
import { createEnv } from "@t3-oss/env-nextjs"; import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod"; import { z } from "zod";
const isUsingDbUrl = Boolean(process.env.DB_URL);
const isUsingDbHost = Boolean(process.env.DB_HOST);
const isUsingDbCredentials = process.env.DB_DRIVER === "mysql2";
export const env = createEnv({ export const env = createEnv({
shared: { shared: {
VERCEL_URL: z VERCEL_URL: z
@@ -19,21 +15,6 @@ export const env = createEnv({
* built with invalid env vars. * built with invalid env vars.
*/ */
server: { server: {
DB_DRIVER: z.enum(["better-sqlite3", "mysql2"]).default("better-sqlite3"),
// If the DB_HOST is set, the DB_URL is optional
DB_URL: isUsingDbHost ? z.string().optional() : z.string(),
DB_HOST: isUsingDbUrl ? z.string().optional() : z.string(),
DB_PORT: isUsingDbUrl
? z.string().regex(/\d+/).transform(Number).optional()
: z
.string()
.regex(/\d+/)
.transform(Number)
.refine((number) => number >= 1)
.default("3306"),
DB_USER: isUsingDbCredentials ? z.string() : z.string().optional(),
DB_PASSWORD: isUsingDbCredentials ? z.string() : z.string().optional(),
DB_NAME: isUsingDbUrl ? z.string().optional() : z.string(),
// Comma separated list of docker hostnames that can be used to connect to query the docker endpoints (localhost:2375,host.docker.internal:2375, ...) // Comma separated list of docker hostnames that can be used to connect to query the docker endpoints (localhost:2375,host.docker.internal:2375, ...)
DOCKER_HOSTNAMES: z.string().optional(), DOCKER_HOSTNAMES: z.string().optional(),
DOCKER_PORTS: z.number().optional(), DOCKER_PORTS: z.number().optional(),
@@ -51,13 +32,6 @@ export const env = createEnv({
runtimeEnv: { runtimeEnv: {
VERCEL_URL: process.env.VERCEL_URL, VERCEL_URL: process.env.VERCEL_URL,
PORT: process.env.PORT, PORT: process.env.PORT,
DB_URL: process.env.DB_URL,
DB_HOST: process.env.DB_HOST,
DB_USER: process.env.DB_USER,
DB_PASSWORD: process.env.DB_PASSWORD,
DB_NAME: process.env.DB_NAME,
DB_PORT: process.env.DB_PORT,
DB_DRIVER: process.env.DB_DRIVER,
NODE_ENV: process.env.NODE_ENV, NODE_ENV: process.env.NODE_ENV,
DOCKER_HOSTNAMES: process.env.DOCKER_HOSTNAMES, DOCKER_HOSTNAMES: process.env.DOCKER_HOSTNAMES,
DOCKER_PORTS: process.env.DOCKER_PORTS, DOCKER_PORTS: process.env.DOCKER_PORTS,

View File

@@ -38,7 +38,7 @@
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"dotenv": "^16.4.7", "dotenv": "^16.4.7",
"superjson": "2.2.2", "superjson": "2.2.2",
"undici": "7.1.1" "undici": "7.2.0"
}, },
"devDependencies": { "devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -3,7 +3,7 @@ import { Umami } from "@umami/node";
import { count, db } from "@homarr/db"; import { count, db } from "@homarr/db";
import { getServerSettingByKeyAsync } from "@homarr/db/queries"; import { getServerSettingByKeyAsync } from "@homarr/db/queries";
import { integrations, items, users } from "@homarr/db/schema/sqlite"; import { integrations, items, users } from "@homarr/db/schema";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";
import type { defaultServerSettings } from "@homarr/server-settings"; import type { defaultServerSettings } from "@homarr/server-settings";

View File

@@ -40,7 +40,7 @@
"@trpc/react-query": "next", "@trpc/react-query": "next",
"@trpc/server": "next", "@trpc/server": "next",
"dockerode": "^4.0.2", "dockerode": "^4.0.2",
"next": "^14.2.20", "next": "^14.2.21",
"react": "^19.0.0", "react": "^19.0.0",
"superjson": "2.2.2", "superjson": "2.2.2",
"trpc-to-openapi": "^2.1.0" "trpc-to-openapi": "^2.1.0"

View File

@@ -7,7 +7,7 @@ import { decryptSecret } from "@homarr/common/server";
import type { AtLeastOneOf } from "@homarr/common/types"; import type { AtLeastOneOf } from "@homarr/common/types";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { and, eq, inArray } from "@homarr/db"; import { and, eq, inArray } from "@homarr/db";
import { integrations } from "@homarr/db/schema/sqlite"; import { integrations } from "@homarr/db/schema";
import type { IntegrationKind } from "@homarr/definitions"; import type { IntegrationKind } from "@homarr/definitions";
import { z } from "@homarr/validation"; import { z } from "@homarr/validation";

View File

@@ -1,7 +1,7 @@
import { TRPCError } from "@trpc/server"; import { TRPCError } from "@trpc/server";
import { and, eq } from "@homarr/db"; import { and, eq } from "@homarr/db";
import { items } from "@homarr/db/schema/sqlite"; import { items } from "@homarr/db/schema";
import type { WidgetKind } from "@homarr/definitions"; import type { WidgetKind } from "@homarr/definitions";
import { z } from "@homarr/validation"; import { z } from "@homarr/validation";

View File

@@ -1,7 +1,7 @@
import { createSaltAsync, hashPasswordAsync } from "@homarr/auth"; import { createSaltAsync, hashPasswordAsync } from "@homarr/auth";
import { generateSecureRandomToken } from "@homarr/common/server"; import { generateSecureRandomToken } from "@homarr/common/server";
import { createId, db } from "@homarr/db"; import { createId, db } from "@homarr/db";
import { apiKeys } from "@homarr/db/schema/sqlite"; import { apiKeys } from "@homarr/db/schema";
import { createTRPCRouter, permissionRequiredProcedure } from "../trpc"; import { createTRPCRouter, permissionRequiredProcedure } from "../trpc";

View File

@@ -1,7 +1,7 @@
import { TRPCError } from "@trpc/server"; import { TRPCError } from "@trpc/server";
import { asc, createId, eq, inArray, like } from "@homarr/db"; import { asc, createId, eq, inArray, like } from "@homarr/db";
import { apps } from "@homarr/db/schema/sqlite"; import { apps } from "@homarr/db/schema";
import { selectAppSchema } from "@homarr/db/validationSchemas"; import { selectAppSchema } from "@homarr/db/validationSchemas";
import { validation, z } from "@homarr/validation"; import { validation, z } from "@homarr/validation";

View File

@@ -2,7 +2,7 @@ import SuperJSON from "superjson";
import type { Session } from "@homarr/auth"; import type { Session } from "@homarr/auth";
import { db, eq, or } from "@homarr/db"; import { db, eq, or } from "@homarr/db";
import { items } from "@homarr/db/schema/sqlite"; import { items } from "@homarr/db/schema";
import type { WidgetComponentProps } from "../../../../widgets/src"; import type { WidgetComponentProps } from "../../../../widgets/src";

View File

@@ -15,7 +15,7 @@ import {
items, items,
sections, sections,
users, users,
} from "@homarr/db/schema/sqlite"; } from "@homarr/db/schema";
import type { WidgetKind } from "@homarr/definitions"; import type { WidgetKind } from "@homarr/definitions";
import { getPermissionsWithParents, widgetKinds } from "@homarr/definitions"; import { getPermissionsWithParents, widgetKinds } from "@homarr/definitions";
import { importOldmarrAsync } from "@homarr/old-import"; import { importOldmarrAsync } from "@homarr/old-import";

View File

@@ -4,7 +4,7 @@ import type { Session } from "@homarr/auth";
import { constructBoardPermissions } from "@homarr/auth/shared"; import { constructBoardPermissions } from "@homarr/auth/shared";
import type { Database, SQL } from "@homarr/db"; import type { Database, SQL } from "@homarr/db";
import { eq, inArray } from "@homarr/db"; import { eq, inArray } from "@homarr/db";
import { boardGroupPermissions, boardUserPermissions, groupMembers } from "@homarr/db/schema/sqlite"; import { boardGroupPermissions, boardUserPermissions, groupMembers } from "@homarr/db/schema";
import type { BoardPermission } from "@homarr/definitions"; import type { BoardPermission } from "@homarr/definitions";
/** /**

View File

@@ -3,7 +3,7 @@ import type Docker from "dockerode";
import type { Container } from "dockerode"; import type { Container } from "dockerode";
import { db, like, or } from "@homarr/db"; import { db, like, or } from "@homarr/db";
import { icons } from "@homarr/db/schema/sqlite"; import { icons } from "@homarr/db/schema";
import type { DockerContainerState } from "@homarr/definitions"; import type { DockerContainerState } from "@homarr/definitions";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";
import { createCacheChannel } from "@homarr/redis"; import { createCacheChannel } from "@homarr/redis";

View File

@@ -2,7 +2,7 @@ import { TRPCError } from "@trpc/server";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { and, createId, eq, like, not, sql } from "@homarr/db"; import { and, createId, eq, like, not, sql } from "@homarr/db";
import { groupMembers, groupPermissions, groups } from "@homarr/db/schema/sqlite"; import { groupMembers, groupPermissions, groups } from "@homarr/db/schema";
import { everyoneGroup } from "@homarr/definitions"; import { everyoneGroup } from "@homarr/definitions";
import { validation, z } from "@homarr/validation"; import { validation, z } from "@homarr/validation";

View File

@@ -3,7 +3,7 @@ import type { AnySQLiteTable } from "drizzle-orm/sqlite-core";
import { isProviderEnabled } from "@homarr/auth/server"; import { isProviderEnabled } from "@homarr/auth/server";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { count } from "@homarr/db"; import { count } from "@homarr/db";
import { apps, boards, groups, integrations, invites, users } from "@homarr/db/schema/sqlite"; import { apps, boards, groups, integrations, invites, users } from "@homarr/db/schema";
import { createTRPCRouter, publicProcedure } from "../trpc"; import { createTRPCRouter, publicProcedure } from "../trpc";

View File

@@ -1,5 +1,5 @@
import { count, like } from "@homarr/db"; import { count, like } from "@homarr/db";
import { icons } from "@homarr/db/schema/sqlite"; import { icons } from "@homarr/db/schema";
import { validation } from "@homarr/validation"; import { validation } from "@homarr/validation";
import { createTRPCRouter, publicProcedure } from "../trpc"; import { createTRPCRouter, publicProcedure } from "../trpc";

View File

@@ -4,7 +4,7 @@ import type { Session } from "@homarr/auth";
import { constructIntegrationPermissions } from "@homarr/auth/shared"; import { constructIntegrationPermissions } from "@homarr/auth/shared";
import type { Database, SQL } from "@homarr/db"; import type { Database, SQL } from "@homarr/db";
import { eq, inArray } from "@homarr/db"; import { eq, inArray } from "@homarr/db";
import { groupMembers, integrationGroupPermissions, integrationUserPermissions } from "@homarr/db/schema/sqlite"; import { groupMembers, integrationGroupPermissions, integrationUserPermissions } from "@homarr/db/schema";
import type { IntegrationPermission } from "@homarr/definitions"; import type { IntegrationPermission } from "@homarr/definitions";
/** /**

View File

@@ -11,7 +11,7 @@ import {
integrations, integrations,
integrationSecrets, integrationSecrets,
integrationUserPermissions, integrationUserPermissions,
} from "@homarr/db/schema/sqlite"; } from "@homarr/db/schema";
import type { IntegrationSecretKind } from "@homarr/definitions"; import type { IntegrationSecretKind } from "@homarr/definitions";
import { import {
getIntegrationKindsByCategory, getIntegrationKindsByCategory,

View File

@@ -1,5 +1,5 @@
import { decryptSecret } from "@homarr/common/server"; import { decryptSecret } from "@homarr/common/server";
import type { Integration } from "@homarr/db/schema/sqlite"; import type { Integration } from "@homarr/db/schema";
import type { IntegrationKind, IntegrationSecretKind } from "@homarr/definitions"; import type { IntegrationKind, IntegrationSecretKind } from "@homarr/definitions";
import { getAllSecretKindOptions } from "@homarr/definitions"; import { getAllSecretKindOptions } from "@homarr/definitions";
import { integrationCreator, IntegrationTestConnectionError } from "@homarr/integrations"; import { integrationCreator, IntegrationTestConnectionError } from "@homarr/integrations";

View File

@@ -2,7 +2,7 @@ import { randomBytes } from "crypto";
import { TRPCError } from "@trpc/server"; import { TRPCError } from "@trpc/server";
import { asc, createId, eq } from "@homarr/db"; import { asc, createId, eq } from "@homarr/db";
import { invites } from "@homarr/db/schema/sqlite"; import { invites } from "@homarr/db/schema";
import { selectInviteSchema } from "@homarr/db/validationSchemas"; import { selectInviteSchema } from "@homarr/db/validationSchemas";
import { z } from "@homarr/validation"; import { z } from "@homarr/validation";

View File

@@ -1,7 +1,7 @@
import { TRPCError } from "@trpc/server"; import { TRPCError } from "@trpc/server";
import { and, createId, desc, eq, like } from "@homarr/db"; import { and, createId, desc, eq, like } from "@homarr/db";
import { medias } from "@homarr/db/schema/sqlite"; import { medias } from "@homarr/db/schema";
import { validation, z } from "@homarr/validation"; import { validation, z } from "@homarr/validation";
import { createTRPCRouter, permissionRequiredProcedure, protectedProcedure } from "../../trpc"; import { createTRPCRouter, permissionRequiredProcedure, protectedProcedure } from "../../trpc";

View File

@@ -3,7 +3,7 @@ import { objectEntries } from "@homarr/common";
import type { MaybePromise } from "@homarr/common/types"; import type { MaybePromise } from "@homarr/common/types";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { eq } from "@homarr/db"; import { eq } from "@homarr/db";
import { groups, onboarding } from "@homarr/db/schema/sqlite"; import { groups, onboarding } from "@homarr/db/schema";
import type { OnboardingStep } from "@homarr/definitions"; import type { OnboardingStep } from "@homarr/definitions";
import { credentialsAdminGroup } from "@homarr/definitions"; import { credentialsAdminGroup } from "@homarr/definitions";

View File

@@ -1,4 +1,4 @@
import { onboarding } from "@homarr/db/schema/sqlite"; import { onboarding } from "@homarr/db/schema";
import { onboardingSteps } from "@homarr/definitions"; import { onboardingSteps } from "@homarr/definitions";
import { z, zodEnumFromArray } from "@homarr/validation"; import { z, zodEnumFromArray } from "@homarr/validation";

View File

@@ -1,7 +1,7 @@
import { TRPCError } from "@trpc/server"; import { TRPCError } from "@trpc/server";
import { createId, eq, like, sql } from "@homarr/db"; import { createId, eq, like, sql } from "@homarr/db";
import { searchEngines } from "@homarr/db/schema/sqlite"; import { searchEngines } from "@homarr/db/schema";
import { validation } from "@homarr/validation"; import { validation } from "@homarr/validation";
import { createTRPCRouter, permissionRequiredProcedure, protectedProcedure } from "../../trpc"; import { createTRPCRouter, permissionRequiredProcedure, protectedProcedure } from "../../trpc";

View File

@@ -3,7 +3,7 @@ import { describe, expect, test, vi } from "vitest";
import type { Session } from "@homarr/auth"; import type { Session } from "@homarr/auth";
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import { apps } from "@homarr/db/schema/sqlite"; import { apps } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import type { GroupPermissionKey } from "@homarr/definitions"; import type { GroupPermissionKey } from "@homarr/definitions";

View File

@@ -17,7 +17,7 @@ import {
sections, sections,
serverSettings, serverSettings,
users, users,
} from "@homarr/db/schema/sqlite"; } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import type { BoardPermission, GroupPermissionKey } from "@homarr/definitions"; import type { BoardPermission, GroupPermissionKey } from "@homarr/definitions";

View File

@@ -2,7 +2,7 @@ import { describe, expect, test, vi } from "vitest";
import * as authShared from "@homarr/auth/shared"; import * as authShared from "@homarr/auth/shared";
import { createId, eq } from "@homarr/db"; import { createId, eq } from "@homarr/db";
import { boards, users } from "@homarr/db/schema/sqlite"; import { boards, users } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import { throwIfActionForbiddenAsync } from "../../board/board-access"; import { throwIfActionForbiddenAsync } from "../../board/board-access";

View File

@@ -3,7 +3,7 @@ import { describe, expect, test, vi } from "vitest";
import type { Session } from "@homarr/auth"; import type { Session } from "@homarr/auth";
import * as env from "@homarr/auth/env.mjs"; import * as env from "@homarr/auth/env.mjs";
import { createId, eq } from "@homarr/db"; import { createId, eq } from "@homarr/db";
import { groupMembers, groupPermissions, groups, users } from "@homarr/db/schema/sqlite"; import { groupMembers, groupPermissions, groups, users } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import type { GroupPermissionKey } from "@homarr/definitions"; import type { GroupPermissionKey } from "@homarr/definitions";

View File

@@ -2,7 +2,7 @@ import { describe, expect, test, vi } from "vitest";
import * as authShared from "@homarr/auth/shared"; import * as authShared from "@homarr/auth/shared";
import { createId, eq } from "@homarr/db"; import { createId, eq } from "@homarr/db";
import { integrations, users } from "@homarr/db/schema/sqlite"; import { integrations, users } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import { throwIfActionForbiddenAsync } from "../../integration/integration-access"; import { throwIfActionForbiddenAsync } from "../../integration/integration-access";

View File

@@ -4,7 +4,7 @@ import { describe, expect, test, vi } from "vitest";
import type { Session } from "@homarr/auth"; import type { Session } from "@homarr/auth";
import { encryptSecret } from "@homarr/common/server"; import { encryptSecret } from "@homarr/common/server";
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import { integrations, integrationSecrets } from "@homarr/db/schema/sqlite"; import { integrations, integrationSecrets } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import type { GroupPermissionKey } from "@homarr/definitions"; import type { GroupPermissionKey } from "@homarr/definitions";

View File

@@ -3,7 +3,7 @@ import { describe, expect, test, vi } from "vitest";
import type { Session } from "@homarr/auth"; import type { Session } from "@homarr/auth";
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import { invites, users } from "@homarr/db/schema/sqlite"; import { invites, users } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import { inviteRouter } from "../invite"; import { inviteRouter } from "../invite";

View File

@@ -3,7 +3,7 @@ import { describe, expect, test, vi } from "vitest";
import type { Session } from "@homarr/auth"; import type { Session } from "@homarr/auth";
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import { serverSettings } from "@homarr/db/schema/sqlite"; import { serverSettings } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import { defaultServerSettings, defaultServerSettingsKeys } from "@homarr/server-settings"; import { defaultServerSettings, defaultServerSettingsKeys } from "@homarr/server-settings";

View File

@@ -2,8 +2,8 @@ import { describe, expect, it, test, vi } from "vitest";
import type { Session } from "@homarr/auth"; import type { Session } from "@homarr/auth";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { createId, eq, schema } from "@homarr/db"; import { createId, eq } from "@homarr/db";
import { onboarding, users } from "@homarr/db/schema/sqlite"; import { invites, onboarding, users } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import type { GroupPermissionKey, OnboardingStep } from "@homarr/definitions"; import type { GroupPermissionKey, OnboardingStep } from "@homarr/definitions";
@@ -121,7 +121,7 @@ describe("register should create a user with valid invitation", () => {
await db.insert(users).values({ await db.insert(users).values({
id: userId, id: userId,
}); });
await db.insert(schema.invites).values({ await db.insert(invites).values({
id: inviteId, id: inviteId,
token: inviteToken, token: inviteToken,
creatorId: userId, creatorId: userId,
@@ -176,7 +176,7 @@ describe("register should create a user with valid invitation", () => {
await db.insert(users).values({ await db.insert(users).values({
id: userId, id: userId,
}); });
await db.insert(schema.invites).values({ await db.insert(invites).values({
id: inviteId, id: inviteId,
token: inviteToken, token: inviteToken,
creatorId: userId, creatorId: userId,
@@ -211,7 +211,7 @@ describe("editProfile shoud update user", () => {
const emailVerified = new Date(2024, 0, 5); const emailVerified = new Date(2024, 0, 5);
await db.insert(schema.users).values({ await db.insert(users).values({
id: defaultOwnerId, id: defaultOwnerId,
name: "TEST 1", name: "TEST 1",
email: "abc@gmail.com", email: "abc@gmail.com",
@@ -226,7 +226,7 @@ describe("editProfile shoud update user", () => {
}); });
// assert // assert
const user = await db.select().from(schema.users).where(eq(schema.users.id, defaultOwnerId)); const user = await db.select().from(users).where(eq(users.id, defaultOwnerId));
expect(user).toHaveLength(1); expect(user).toHaveLength(1);
expect(user[0]).containSubset({ expect(user[0]).containSubset({
@@ -245,7 +245,7 @@ describe("editProfile shoud update user", () => {
session: defaultSession, session: defaultSession,
}); });
await db.insert(schema.users).values({ await db.insert(users).values({
id: defaultOwnerId, id: defaultOwnerId,
name: "TEST 1", name: "TEST 1",
email: "abc@gmail.com", email: "abc@gmail.com",
@@ -260,7 +260,7 @@ describe("editProfile shoud update user", () => {
}); });
// assert // assert
const user = await db.select().from(schema.users).where(eq(schema.users.id, defaultOwnerId)); const user = await db.select().from(users).where(eq(users.id, defaultOwnerId));
expect(user).toHaveLength(1); expect(user).toHaveLength(1);
expect(user[0]).containSubset({ expect(user[0]).containSubset({
@@ -295,11 +295,11 @@ describe("delete should delete user", () => {
}, },
]; ];
await db.insert(schema.users).values(initialUsers); await db.insert(users).values(initialUsers);
await caller.delete({ userId: defaultOwnerId }); await caller.delete({ userId: defaultOwnerId });
const usersInDb = await db.select().from(schema.users); const usersInDb = await db.select().from(users);
expect(usersInDb).toHaveLength(2); expect(usersInDb).toHaveLength(2);
expect(usersInDb[0]).containSubset(initialUsers[0]); expect(usersInDb[0]).containSubset(initialUsers[0]);
expect(usersInDb[1]).containSubset(initialUsers[2]); expect(usersInDb[1]).containSubset(initialUsers[2]);

View File

@@ -2,8 +2,8 @@ import { TRPCError } from "@trpc/server";
import { createSaltAsync, hashPasswordAsync } from "@homarr/auth"; import { createSaltAsync, hashPasswordAsync } from "@homarr/auth";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { and, createId, eq, like, schema } from "@homarr/db"; import { and, createId, eq, like } from "@homarr/db";
import { groupMembers, groupPermissions, groups, invites, users } from "@homarr/db/schema/sqlite"; import { groupMembers, groupPermissions, groups, invites, users } from "@homarr/db/schema";
import { selectUserSchema } from "@homarr/db/validationSchemas"; import { selectUserSchema } from "@homarr/db/validationSchemas";
import { credentialsAdminGroup } from "@homarr/definitions"; import { credentialsAdminGroup } from "@homarr/definitions";
import type { SupportedAuthProvider } from "@homarr/definitions"; import type { SupportedAuthProvider } from "@homarr/definitions";
@@ -509,7 +509,7 @@ const createUserAsync = async (db: Database, input: Omit<z.infer<typeof validati
const username = input.username.toLowerCase(); const username = input.username.toLowerCase();
const userId = createId(); const userId = createId();
await db.insert(schema.users).values({ await db.insert(users).values({
id: userId, id: userId,
name: username, name: username,
email: input.email, email: input.email,

View File

@@ -1,7 +1,7 @@
import { observable } from "@trpc/server/observable"; import { observable } from "@trpc/server/observable";
import type { Modify } from "@homarr/common/types"; import type { Modify } from "@homarr/common/types";
import type { Integration } from "@homarr/db/schema/sqlite"; import type { Integration } from "@homarr/db/schema";
import type { IntegrationKindByCategory } from "@homarr/definitions"; import type { IntegrationKindByCategory } from "@homarr/definitions";
import { getIntegrationKindsByCategory } from "@homarr/definitions"; import { getIntegrationKindsByCategory } from "@homarr/definitions";
import { integrationCreator } from "@homarr/integrations"; import { integrationCreator } from "@homarr/integrations";

View File

@@ -1,7 +1,7 @@
import { observable } from "@trpc/server/observable"; import { observable } from "@trpc/server/observable";
import type { Modify } from "@homarr/common/types"; import type { Modify } from "@homarr/common/types";
import type { Integration } from "@homarr/db/schema/sqlite"; import type { Integration } from "@homarr/db/schema";
import type { IntegrationKindByCategory } from "@homarr/definitions"; import type { IntegrationKindByCategory } from "@homarr/definitions";
import { getIntegrationKindsByCategory } from "@homarr/definitions"; import { getIntegrationKindsByCategory } from "@homarr/definitions";
import type { DownloadClientJobsAndStatus } from "@homarr/integrations"; import type { DownloadClientJobsAndStatus } from "@homarr/integrations";

View File

@@ -2,7 +2,7 @@ import { TRPCError } from "@trpc/server";
import SuperJSON from "superjson"; import SuperJSON from "superjson";
import { eq } from "@homarr/db"; import { eq } from "@homarr/db";
import { items } from "@homarr/db/schema/sqlite"; import { items } from "@homarr/db/schema";
import { z } from "@homarr/validation"; import { z } from "@homarr/validation";
import { createTRPCRouter, protectedProcedure } from "../../trpc"; import { createTRPCRouter, protectedProcedure } from "../../trpc";

View File

@@ -3,7 +3,7 @@ import { DrizzleAdapter } from "@auth/drizzle-adapter";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { and, eq } from "@homarr/db"; import { and, eq } from "@homarr/db";
import { accounts, sessions, users } from "@homarr/db/schema/sqlite"; import { accounts, sessions, users } from "@homarr/db/schema";
import type { SupportedAuthProvider } from "@homarr/definitions"; import type { SupportedAuthProvider } from "@homarr/definitions";
export const createAdapter = (db: Database, provider: SupportedAuthProvider | "unknown"): Adapter => { export const createAdapter = (db: Database, provider: SupportedAuthProvider | "unknown"): Adapter => {

View File

@@ -4,7 +4,7 @@ import type { NextAuthConfig } from "next-auth";
import type { Session } from "@homarr/auth"; import type { Session } from "@homarr/auth";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { eq, inArray } from "@homarr/db"; import { eq, inArray } from "@homarr/db";
import { groupMembers, groupPermissions, users } from "@homarr/db/schema/sqlite"; import { groupMembers, groupPermissions, users } from "@homarr/db/schema";
import { getPermissionsWithChildren } from "@homarr/definitions"; import { getPermissionsWithChildren } from "@homarr/definitions";
export const getCurrentUserPermissionsAsync = async (db: Database, userId: string) => { export const getCurrentUserPermissionsAsync = async (db: Database, userId: string) => {

View File

@@ -4,7 +4,7 @@ import type { NextAuthConfig } from "next-auth";
import { and, eq, inArray } from "@homarr/db"; import { and, eq, inArray } from "@homarr/db";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { groupMembers, groups, users } from "@homarr/db/schema/sqlite"; import { groupMembers, groups, users } from "@homarr/db/schema";
import { colorSchemeCookieKey, everyoneGroup } from "@homarr/definitions"; import { colorSchemeCookieKey, everyoneGroup } from "@homarr/definitions";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";

View File

@@ -34,7 +34,7 @@
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"cookies": "^0.9.1", "cookies": "^0.9.1",
"ldapts": "7.3.0", "ldapts": "7.3.0",
"next": "^14.2.20", "next": "^14.2.21",
"next-auth": "5.0.0-beta.25", "next-auth": "5.0.0-beta.25",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0" "react-dom": "^19.0.0"

View File

@@ -2,7 +2,7 @@ import type { Session } from "next-auth";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { and, eq, inArray, or } from "@homarr/db"; import { and, eq, inArray, or } from "@homarr/db";
import { boards, boardUserPermissions, groupMembers } from "@homarr/db/schema/sqlite"; import { boards, boardUserPermissions, groupMembers } from "@homarr/db/schema";
import type { IntegrationPermission } from "@homarr/definitions"; import type { IntegrationPermission } from "@homarr/definitions";
import { constructIntegrationPermissions } from "./integration-permissions"; import { constructIntegrationPermissions } from "./integration-permissions";

View File

@@ -1,7 +1,7 @@
import type { Session } from "next-auth"; import type { Session } from "next-auth";
import { db, eq, inArray } from "@homarr/db"; import { db, eq, inArray } from "@homarr/db";
import { groupMembers, integrationGroupPermissions, integrationUserPermissions } from "@homarr/db/schema/sqlite"; import { groupMembers, integrationGroupPermissions, integrationUserPermissions } from "@homarr/db/schema";
import { constructIntegrationPermissions } from "./integration-permissions"; import { constructIntegrationPermissions } from "./integration-permissions";

View File

@@ -3,14 +3,7 @@ import { describe, expect, test, vi } from "vitest";
import type { InferInsertModel } from "@homarr/db"; import type { InferInsertModel } from "@homarr/db";
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import { import { boardGroupPermissions, boards, boardUserPermissions, groupMembers, groups, users } from "@homarr/db/schema";
boardGroupPermissions,
boards,
boardUserPermissions,
groupMembers,
groups,
users,
} from "@homarr/db/schema/sqlite";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import * as integrationPermissions from "../integration-permissions"; import * as integrationPermissions from "../integration-permissions";

View File

@@ -2,7 +2,7 @@ import bcrypt from "bcrypt";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { and, eq } from "@homarr/db"; import { and, eq } from "@homarr/db";
import { users } from "@homarr/db/schema/sqlite"; import { users } from "@homarr/db/schema";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";
import type { validation, z } from "@homarr/validation"; import type { validation, z } from "@homarr/validation";

View File

@@ -2,7 +2,7 @@ import { CredentialsSignin } from "@auth/core/errors";
import type { Database, InferInsertModel } from "@homarr/db"; import type { Database, InferInsertModel } from "@homarr/db";
import { and, createId, eq } from "@homarr/db"; import { and, createId, eq } from "@homarr/db";
import { users } from "@homarr/db/schema/sqlite"; import { users } from "@homarr/db/schema";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";
import type { validation } from "@homarr/validation"; import type { validation } from "@homarr/validation";
import { z } from "@homarr/validation"; import { z } from "@homarr/validation";

View File

@@ -1,7 +1,7 @@
import { describe, expect, test } from "vitest"; import { describe, expect, test } from "vitest";
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import { users } from "@homarr/db/schema/sqlite"; import { users } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import { createSaltAsync, hashPasswordAsync } from "../../security"; import { createSaltAsync, hashPasswordAsync } from "../../security";

View File

@@ -3,7 +3,7 @@ import { describe, expect, test, vi } from "vitest";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { and, createId, eq } from "@homarr/db"; import { and, createId, eq } from "@homarr/db";
import { groups, users } from "@homarr/db/schema/sqlite"; import { groups, users } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import { authorizeWithLdapCredentialsAsync } from "../credentials/authorization/ldap-authorization"; import { authorizeWithLdapCredentialsAsync } from "../credentials/authorization/ldap-authorization";

View File

@@ -1,6 +1,6 @@
import { describe, expect, test } from "vitest"; import { describe, expect, test } from "vitest";
import { users } from "@homarr/db/schema/sqlite"; import { users } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import { createAdapter } from "../adapter"; import { createAdapter } from "../adapter";

View File

@@ -3,7 +3,7 @@ import type { AdapterUser } from "@auth/core/adapters";
import type { JWT } from "next-auth/jwt"; import type { JWT } from "next-auth/jwt";
import { describe, expect, test, vi } from "vitest"; import { describe, expect, test, vi } from "vitest";
import { groupMembers, groupPermissions, groups, users } from "@homarr/db/schema/sqlite"; import { groupMembers, groupPermissions, groups, users } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import * as definitions from "@homarr/definitions"; import * as definitions from "@homarr/definitions";

View File

@@ -5,7 +5,7 @@ import { describe, expect, test, vi } from "vitest";
import { eq } from "@homarr/db"; import { eq } from "@homarr/db";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { groupMembers, groups, users } from "@homarr/db/schema/sqlite"; import { groupMembers, groups, users } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test"; import { createDb } from "@homarr/db/test";
import { colorSchemeCookieKey, everyoneGroup } from "@homarr/definitions"; import { colorSchemeCookieKey, everyoneGroup } from "@homarr/definitions";

View File

@@ -3,7 +3,7 @@ import { command, string } from "@drizzle-team/brocli";
import { hashPasswordAsync } from "@homarr/auth"; import { hashPasswordAsync } from "@homarr/auth";
import { generateSecureRandomToken } from "@homarr/common/server"; import { generateSecureRandomToken } from "@homarr/common/server";
import { and, db, eq } from "@homarr/db"; import { and, db, eq } from "@homarr/db";
import { sessions, users } from "@homarr/db/schema/sqlite"; import { sessions, users } from "@homarr/db/schema";
export const resetPassword = command({ export const resetPassword = command({
name: "reset-password", name: "reset-password",

View File

@@ -27,9 +27,9 @@
"dependencies": { "dependencies": {
"@homarr/log": "workspace:^0.1.0", "@homarr/log": "workspace:^0.1.0",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"next": "^14.2.20", "next": "^14.2.21",
"react": "^19.0.0", "react": "^19.0.0",
"tldts": "^6.1.68" "tldts": "^6.1.69"
}, },
"devDependencies": { "devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -3,7 +3,7 @@ import { EVERY_WEEK } from "@homarr/cron-jobs-core/expressions";
import type { InferInsertModel } from "@homarr/db"; import type { InferInsertModel } from "@homarr/db";
import { db, inArray } from "@homarr/db"; import { db, inArray } from "@homarr/db";
import { createId } from "@homarr/db/client"; import { createId } from "@homarr/db/client";
import { iconRepositories, icons } from "@homarr/db/schema/sqlite"; import { iconRepositories, icons } from "@homarr/db/schema";
import { fetchIconsAsync } from "@homarr/icons"; import { fetchIconsAsync } from "@homarr/icons";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";

View File

@@ -5,7 +5,7 @@ import SuperJSON from "superjson";
import type { Modify } from "@homarr/common/types"; import type { Modify } from "@homarr/common/types";
import { EVERY_5_MINUTES } from "@homarr/cron-jobs-core/expressions"; import { EVERY_5_MINUTES } from "@homarr/cron-jobs-core/expressions";
import { db, eq } from "@homarr/db"; import { db, eq } from "@homarr/db";
import { items } from "@homarr/db/schema/sqlite"; import { items } from "@homarr/db/schema";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";
import { createItemChannel } from "@homarr/redis"; import { createItemChannel } from "@homarr/redis";
import { z } from "@homarr/validation"; import { z } from "@homarr/validation";

View File

@@ -1,7 +1,7 @@
import { env } from "@homarr/auth/env.mjs"; import { env } from "@homarr/auth/env.mjs";
import { NEVER } from "@homarr/cron-jobs-core/expressions"; import { NEVER } from "@homarr/cron-jobs-core/expressions";
import { db, eq, inArray } from "@homarr/db"; import { db, eq, inArray } from "@homarr/db";
import { sessions, users } from "@homarr/db/schema/sqlite"; import { sessions, users } from "@homarr/db/schema";
import { supportedAuthProviders } from "@homarr/definitions"; import { supportedAuthProviders } from "@homarr/definitions";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";

View File

@@ -1,19 +1,19 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import * as dotenv from "dotenv";
import type { Config } from "drizzle-kit"; import type { Config } from "drizzle-kit";
dotenv.config({ path: "../../.env" }); import { env } from "../env.mjs";
export default { export default {
dialect: "mysql", dialect: "mysql",
schema: "./schema", schema: "./schema",
casing: "snake_case", casing: "snake_case",
dbCredentials: { dbCredentials: env.DB_URL
host: process.env.DB_HOST!, ? { url: env.DB_URL }
user: process.env.DB_USER!, : {
password: process.env.DB_PASSWORD!, host: env.DB_HOST,
database: process.env.DB_NAME!, user: env.DB_USER,
port: parseInt(process.env.DB_PORT!), password: env.DB_PASSWORD,
}, database: env.DB_NAME,
port: env.DB_PORT,
},
out: "./migrations/mysql", out: "./migrations/mysql",
} satisfies Config; } satisfies Config;

View File

@@ -1,13 +1,11 @@
import * as dotenv from "dotenv";
import type { Config } from "drizzle-kit"; import type { Config } from "drizzle-kit";
dotenv.config({ path: "../../.env" }); import { env } from "../env.mjs";
export default { export default {
dialect: "sqlite", dialect: "sqlite",
schema: "./schema", schema: "./schema",
casing: "snake_case", casing: "snake_case",
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion dbCredentials: { url: env.DB_URL },
dbCredentials: { url: process.env.DB_URL! },
out: "./migrations/sqlite", out: "./migrations/sqlite",
} satisfies Config; } satisfies Config;

View File

@@ -7,6 +7,7 @@ import mysql from "mysql2";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";
import { env } from "./env.mjs";
import * as mysqlSchema from "./schema/mysql"; import * as mysqlSchema from "./schema/mysql";
import * as sqliteSchema from "./schema/sqlite"; import * as sqliteSchema from "./schema/sqlite";
@@ -15,7 +16,7 @@ type HomarrDatabase = BetterSQLite3Database<typeof sqliteSchema>;
const init = () => { const init = () => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!connection) { if (!connection) {
switch (process.env.DB_DRIVER) { switch (env.DB_DRIVER) {
case "mysql2": case "mysql2":
initMySQL2(); initMySQL2();
break; break;
@@ -36,7 +37,7 @@ class WinstonDrizzleLogger implements Logger {
} }
const initBetterSqlite = () => { const initBetterSqlite = () => {
connection = new Database(process.env.DB_URL); connection = new Database(env.DB_URL);
database = drizzleSqlite(connection, { database = drizzleSqlite(connection, {
schema: sqliteSchema, schema: sqliteSchema,
logger: new WinstonDrizzleLogger(), logger: new WinstonDrizzleLogger(),
@@ -45,16 +46,15 @@ const initBetterSqlite = () => {
}; };
const initMySQL2 = () => { const initMySQL2 = () => {
if (!process.env.DB_HOST) { if (!env.DB_HOST) {
connection = mysql.createConnection({ uri: process.env.DB_URL }); connection = mysql.createConnection({ uri: env.DB_URL });
} else { } else {
connection = mysql.createConnection({ connection = mysql.createConnection({
host: process.env.DB_HOST, host: env.DB_HOST,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion database: env.DB_NAME,
database: process.env.DB_NAME!, port: env.DB_PORT,
port: Number(process.env.DB_PORT), user: env.DB_USER,
user: process.env.DB_USER, password: env.DB_PASSWORD,
password: process.env.DB_PASSWORD,
}); });
} }

60
packages/db/env.mjs Normal file
View File

@@ -0,0 +1,60 @@
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";
const drivers = {
betterSqlite3: "better-sqlite3",
mysql2: "mysql2",
};
const isDriver = (driver) => process.env.DB_DRIVER === driver;
const isUsingDbHost = Boolean(process.env.DB_HOST);
const onlyAllowUrl = isDriver(drivers.betterSqlite3);
const urlRequired = onlyAllowUrl || !isUsingDbHost;
const hostRequired = isUsingDbHost && !onlyAllowUrl;
export const env = createEnv({
/**
* Specify your server-side environment variables schema here. This way you can ensure the app isn't
* built with invalid env vars.
*/
server: {
DB_DRIVER: z
.union([z.literal(drivers.betterSqlite3), z.literal(drivers.mysql2)], {
message: `Invalid database driver, supported are ${Object.keys(drivers).join(", ")}`,
})
.default(drivers.betterSqlite3),
...(urlRequired
? {
DB_URL: z.string(),
}
: {}),
...(hostRequired
? {
DB_HOST: z.string(),
DB_PORT: z
.string()
.regex(/\d+/)
.transform(Number)
.refine((number) => number >= 1)
.default("3306"),
DB_USER: z.string(),
DB_PASSWORD: z.string(),
DB_NAME: z.string(),
}
: {}),
},
/**
* Destructure all variables from `process.env` to make sure they aren't tree-shaken away.
*/
runtimeEnv: {
DB_DRIVER: process.env.DB_DRIVER,
DB_URL: process.env.DB_URL,
DB_HOST: process.env.DB_HOST,
DB_USER: process.env.DB_USER,
DB_PASSWORD: process.env.DB_PASSWORD,
DB_NAME: process.env.DB_NAME,
DB_PORT: process.env.DB_PORT,
},
skipValidation:
Boolean(process.env.CI) || Boolean(process.env.SKIP_ENV_VALIDATION) || process.env.npm_lifecycle_event === "lint",
});

View File

@@ -1,10 +1,6 @@
import Database from "better-sqlite3"; import Database from "better-sqlite3";
import { database } from "./driver"; import { database } from "./driver";
import * as sqliteSchema from "./schema/sqlite";
// Export only the types from the sqlite schema as we're using that.
export const schema = sqliteSchema;
export * from "drizzle-orm"; export * from "drizzle-orm";

View File

@@ -1,9 +1,9 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { drizzle } from "drizzle-orm/mysql2"; import { drizzle } from "drizzle-orm/mysql2";
import { migrate } from "drizzle-orm/mysql2/migrator"; import { migrate } from "drizzle-orm/mysql2/migrator";
import mysql from "mysql2"; import mysql from "mysql2";
import type { Database } from "../.."; import type { Database } from "../..";
import { env } from "../../env.mjs";
import * as mysqlSchema from "../../schema/mysql"; import * as mysqlSchema from "../../schema/mysql";
import { seedDataAsync } from "../seed"; import { seedDataAsync } from "../seed";
@@ -11,15 +11,15 @@ const migrationsFolder = process.argv[2] ?? ".";
const migrateAsync = async () => { const migrateAsync = async () => {
const mysql2 = mysql.createConnection( const mysql2 = mysql.createConnection(
process.env.DB_HOST env.DB_URL
? { ? { uri: env.DB_URL }
host: process.env.DB_HOST, : {
database: process.env.DB_NAME!, host: env.DB_HOST,
port: Number(process.env.DB_PORT), database: env.DB_NAME,
user: process.env.DB_USER, port: env.DB_PORT,
password: process.env.DB_PASSWORD, user: env.DB_USER,
} password: env.DB_PASSWORD,
: { uri: process.env.DB_URL }, },
); );
const db = drizzle(mysql2, { const db = drizzle(mysql2, {

View File

@@ -6,8 +6,8 @@ import { defaultServerSettings, defaultServerSettingsKeys } from "@homarr/server
import { createId, eq } from ".."; import { createId, eq } from "..";
import type { Database } from ".."; import type { Database } from "..";
import { onboarding, serverSettings } from "../schema";
import { groups } from "../schema/mysql"; import { groups } from "../schema/mysql";
import { onboarding, serverSettings } from "../schema/sqlite";
export const seedDataAsync = async (db: Database) => { export const seedDataAsync = async (db: Database) => {
await seedEveryoneGroupAsync(db); await seedEveryoneGroupAsync(db);

View File

@@ -2,15 +2,16 @@ import Database from "better-sqlite3";
import { drizzle } from "drizzle-orm/better-sqlite3"; import { drizzle } from "drizzle-orm/better-sqlite3";
import { migrate } from "drizzle-orm/better-sqlite3/migrator"; import { migrate } from "drizzle-orm/better-sqlite3/migrator";
import { schema } from "../.."; import { env } from "../../env.mjs";
import * as sqliteSchema from "../../schema/sqlite";
import { seedDataAsync } from "../seed"; import { seedDataAsync } from "../seed";
const migrationsFolder = process.argv[2] ?? "."; const migrationsFolder = process.argv[2] ?? ".";
const migrateAsync = async () => { const migrateAsync = async () => {
const sqlite = new Database(process.env.DB_URL?.replace("file:", "")); const sqlite = new Database(env.DB_URL.replace("file:", ""));
const db = drizzle(sqlite, { schema, casing: "snake_case" }); const db = drizzle(sqlite, { schema: sqliteSchema, casing: "snake_case" });
migrate(db, { migrationsFolder }); migrate(db, { migrationsFolder });

View File

@@ -7,10 +7,11 @@
"exports": { "exports": {
".": "./index.ts", ".": "./index.ts",
"./client": "./client.ts", "./client": "./client.ts",
"./schema/sqlite": "./schema/sqlite.ts", "./schema": "./schema/index.ts",
"./test": "./test/index.ts", "./test": "./test/index.ts",
"./queries": "./queries/index.ts", "./queries": "./queries/index.ts",
"./validationSchemas": "./validationSchemas.ts" "./validationSchemas": "./validationSchemas.ts",
"./env.mjs": "./env.mjs"
}, },
"main": "./index.ts", "main": "./index.ts",
"types": "./index.ts", "types": "./index.ts",
@@ -21,16 +22,16 @@
"clean": "rm -rf .turbo node_modules", "clean": "rm -rf .turbo node_modules",
"format": "prettier --check . --ignore-path ../../.gitignore", "format": "prettier --check . --ignore-path ../../.gitignore",
"lint": "eslint", "lint": "eslint",
"migration:mysql:drop": "drizzle-kit drop --config ./configs/mysql.config.ts", "migration:mysql:drop": "pnpm with-env drizzle-kit drop --config ./configs/mysql.config.ts",
"migration:mysql:generate": "drizzle-kit generate --config ./configs/mysql.config.ts", "migration:mysql:generate": "pnpm with-env drizzle-kit generate --config ./configs/mysql.config.ts",
"migration:mysql:run": "drizzle-kit migrate --config ./configs/mysql.config.ts && pnpm run seed", "migration:mysql:run": "pnpm with-env drizzle-kit migrate --config ./configs/mysql.config.ts && pnpm run seed",
"migration:sqlite:drop": "drizzle-kit drop --config ./configs/sqlite.config.ts", "migration:sqlite:drop": "pnpm with-env drizzle-kit drop --config ./configs/sqlite.config.ts",
"migration:sqlite:generate": "drizzle-kit generate --config ./configs/sqlite.config.ts", "migration:sqlite:generate": "pnpm with-env drizzle-kit generate --config ./configs/sqlite.config.ts",
"migration:sqlite:run": "drizzle-kit migrate --config ./configs/sqlite.config.ts && pnpm run seed", "migration:sqlite:run": "pnpm with-env drizzle-kit migrate --config ./configs/sqlite.config.ts && pnpm run seed",
"push:mysql": "drizzle-kit push --config ./configs/mysql.config.ts", "push:mysql": "pnpm with-env drizzle-kit push --config ./configs/mysql.config.ts",
"push:sqlite": "drizzle-kit push --config ./configs/sqlite.config.ts", "push:sqlite": "pnpm with-env drizzle-kit push --config ./configs/sqlite.config.ts",
"seed": "pnpm with-env tsx ./migrations/run-seed.ts", "seed": "pnpm with-env tsx ./migrations/run-seed.ts",
"studio": "drizzle-kit studio --config ./configs/sqlite.config.ts", "studio": "pnpm with-env drizzle-kit studio --config ./configs/sqlite.config.ts",
"typecheck": "tsc --noEmit", "typecheck": "tsc --noEmit",
"with-env": "dotenv -e ../../.env --" "with-env": "dotenv -e ../../.env --"
}, },
@@ -42,6 +43,7 @@
"@homarr/log": "workspace:^0.1.0", "@homarr/log": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0", "@homarr/server-settings": "workspace:^0.1.0",
"@paralleldrive/cuid2": "^2.2.2", "@paralleldrive/cuid2": "^2.2.2",
"@t3-oss/env-nextjs": "^0.11.1",
"@testcontainers/mysql": "^10.16.0", "@testcontainers/mysql": "^10.16.0",
"better-sqlite3": "^11.7.0", "better-sqlite3": "^11.7.0",
"dotenv": "^16.4.7", "dotenv": "^16.4.7",

View File

@@ -3,7 +3,7 @@ import type { WidgetKind } from "@homarr/definitions";
import type { Database } from ".."; import type { Database } from "..";
import { inArray } from ".."; import { inArray } from "..";
import type { inferSupportedIntegrations } from "../../widgets/src"; import type { inferSupportedIntegrations } from "../../widgets/src";
import { items } from "../schema/sqlite"; import { items } from "../schema";
export const getItemsWithIntegrationsAsync = async <TKind extends WidgetKind>( export const getItemsWithIntegrationsAsync = async <TKind extends WidgetKind>(
db: Database, db: Database,

View File

@@ -5,7 +5,7 @@ import { defaultServerSettings, defaultServerSettingsKeys } from "@homarr/server
import type { Database } from ".."; import type { Database } from "..";
import { eq } from ".."; import { eq } from "..";
import { serverSettings } from "../schema/sqlite"; import { serverSettings } from "../schema";
export const getServerSettingsAsync = async (db: Database) => { export const getServerSettingsAsync = async (db: Database) => {
const settings = await db.query.serverSettings.findMany(); const settings = await db.query.serverSettings.findMany();

View File

@@ -0,0 +1,45 @@
import type { InferSelectModel } from "drizzle-orm";
import * as mysqlSchema from "./mysql";
import * as sqliteSchema from "./sqlite";
type Schema = typeof sqliteSchema;
const schema = process.env.DB_DRIVER === "mysql2" ? (mysqlSchema as unknown as Schema) : sqliteSchema;
// Sadly we can't use export * from here as we have multiple possible exports
export const {
accounts,
apiKeys,
apps,
boardGroupPermissions,
boardUserPermissions,
boards,
groupMembers,
groupPermissions,
groups,
iconRepositories,
icons,
integrationGroupPermissions,
integrationItems,
integrationSecrets,
integrationUserPermissions,
integrations,
invites,
items,
medias,
onboarding,
searchEngines,
sections,
serverSettings,
sessions,
users,
verificationTokens,
} = schema;
export type User = InferSelectModel<typeof schema.users>;
export type Account = InferSelectModel<typeof schema.accounts>;
export type Session = InferSelectModel<typeof schema.sessions>;
export type VerificationToken = InferSelectModel<typeof schema.verificationTokens>;
export type Integration = InferSelectModel<typeof schema.integrations>;
export type IntegrationSecret = InferSelectModel<typeof schema.integrationSecrets>;

View File

@@ -1,6 +1,5 @@
import type { AdapterAccount } from "@auth/core/adapters"; import type { AdapterAccount } from "@auth/core/adapters";
import type { DayOfWeek } from "@mantine/dates"; import type { DayOfWeek } from "@mantine/dates";
import type { InferSelectModel } from "drizzle-orm";
import { relations, sql } from "drizzle-orm"; import { relations, sql } from "drizzle-orm";
import type { AnySQLiteColumn } from "drizzle-orm/sqlite-core"; import type { AnySQLiteColumn } from "drizzle-orm/sqlite-core";
import { blob, index, int, primaryKey, sqliteTable, text } from "drizzle-orm/sqlite-core"; import { blob, index, int, primaryKey, sqliteTable, text } from "drizzle-orm/sqlite-core";
@@ -567,10 +566,3 @@ export const searchEngineRelations = relations(searchEngines, ({ one }) => ({
references: [integrations.id], references: [integrations.id],
}), }),
})); }));
export type User = InferSelectModel<typeof users>;
export type Account = InferSelectModel<typeof accounts>;
export type Session = InferSelectModel<typeof sessions>;
export type VerificationToken = InferSelectModel<typeof verificationTokens>;
export type Integration = InferSelectModel<typeof integrations>;
export type IntegrationSecret = InferSelectModel<typeof integrationSecrets>;

View File

@@ -2,11 +2,11 @@ import Database from "better-sqlite3";
import { drizzle } from "drizzle-orm/better-sqlite3"; import { drizzle } from "drizzle-orm/better-sqlite3";
import { migrate } from "drizzle-orm/better-sqlite3/migrator"; import { migrate } from "drizzle-orm/better-sqlite3/migrator";
import { schema } from ".."; import * as sqliteSchema from "../schema/sqlite";
export const createDb = (debug?: boolean) => { export const createDb = (debug?: boolean) => {
const sqlite = new Database(":memory:"); const sqlite = new Database(":memory:");
const db = drizzle(sqlite, { schema, logger: debug, casing: "snake_case" }); const db = drizzle(sqlite, { schema: sqliteSchema, logger: debug, casing: "snake_case" });
migrate(db, { migrate(db, {
migrationsFolder: "./packages/db/migrations/sqlite", migrationsFolder: "./packages/db/migrations/sqlite",
}); });

View File

@@ -1,6 +1,6 @@
import { createSelectSchema } from "drizzle-zod"; import { createSelectSchema } from "drizzle-zod";
import { apps, boards, groups, invites, searchEngines, serverSettings, users } from "./schema/sqlite"; import { apps, boards, groups, invites, searchEngines, serverSettings, users } from "./schema";
export const selectAppSchema = createSelectSchema(apps); export const selectAppSchema = createSelectSchema(apps);
export const selectBoardSchema = createSelectSchema(boards); export const selectBoardSchema = createSelectSchema(boards);

View File

@@ -1,6 +1,6 @@
import { decryptSecret } from "@homarr/common/server"; import { decryptSecret } from "@homarr/common/server";
import type { Modify } from "@homarr/common/types"; import type { Modify } from "@homarr/common/types";
import type { Integration as DbIntegration } from "@homarr/db/schema/sqlite"; import type { Integration as DbIntegration } from "@homarr/db/schema";
import type { IntegrationKind, IntegrationSecretKind } from "@homarr/definitions"; import type { IntegrationKind, IntegrationSecretKind } from "@homarr/definitions";
import { AdGuardHomeIntegration } from "../adguard-home/adguard-home-integration"; import { AdGuardHomeIntegration } from "../adguard-home/adguard-home-integration";

View File

@@ -1,4 +1,4 @@
import type { Integration } from "@homarr/db/schema/sqlite"; import type { Integration } from "@homarr/db/schema";
import { z } from "@homarr/validation"; import { z } from "@homarr/validation";
const usenetQueueState = ["downloading", "queued", "paused"] as const; const usenetQueueState = ["downloading", "queued", "paused"] as const;

View File

@@ -1,4 +1,4 @@
import type { Integration } from "@homarr/db/schema/sqlite"; import type { Integration } from "@homarr/db/schema";
export interface DownloadClientStatus { export interface DownloadClientStatus {
/** If client is considered paused */ /** If client is considered paused */

View File

@@ -35,7 +35,7 @@
"@mantine/core": "^7.15.1", "@mantine/core": "^7.15.1",
"@tabler/icons-react": "^3.26.0", "@tabler/icons-react": "^3.26.0",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"next": "^14.2.20", "next": "^14.2.21",
"react": "^19.0.0" "react": "^19.0.0"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -40,11 +40,11 @@
"@mantine/core": "^7.15.1", "@mantine/core": "^7.15.1",
"@mantine/hooks": "^7.15.1", "@mantine/hooks": "^7.15.1",
"adm-zip": "0.5.16", "adm-zip": "0.5.16",
"next": "^14.2.20", "next": "^14.2.21",
"react": "^19.0.0", "react": "^19.0.0",
"superjson": "2.2.2", "superjson": "2.2.2",
"zod": "^3.24.1", "zod": "^3.24.1",
"zod-form-data": "^2.0.2" "zod-form-data": "^2.0.4"
}, },
"devDependencies": { "devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -1,6 +1,6 @@
import { createId, inArray } from "@homarr/db"; import { createId, inArray } from "@homarr/db";
import type { Database, InferInsertModel, InferSelectModel } from "@homarr/db"; import type { Database, InferInsertModel, InferSelectModel } from "@homarr/db";
import { apps as appsTable } from "@homarr/db/schema/sqlite"; import { apps as appsTable } from "@homarr/db/schema";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";
import type { OldmarrApp } from "@homarr/old-schema"; import type { OldmarrApp } from "@homarr/old-schema";

View File

@@ -1,6 +1,6 @@
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import { boards } from "@homarr/db/schema/sqlite"; import { boards } from "@homarr/db/schema";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";
import type { OldmarrConfig } from "@homarr/old-schema"; import type { OldmarrConfig } from "@homarr/old-schema";

View File

@@ -2,7 +2,7 @@ import SuperJSON from "superjson";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import { items } from "@homarr/db/schema/sqlite"; import { items } from "@homarr/db/schema";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";
import type { OldmarrApp, OldmarrWidget } from "@homarr/old-schema"; import type { OldmarrApp, OldmarrWidget } from "@homarr/old-schema";

View File

@@ -1,6 +1,6 @@
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { sections } from "@homarr/db/schema/sqlite"; import { sections } from "@homarr/db/schema";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";
import type { OldmarrConfig } from "@homarr/old-schema"; import type { OldmarrConfig } from "@homarr/old-schema";

View File

@@ -1,6 +1,6 @@
import { objectEntries } from "@homarr/common"; import { objectEntries } from "@homarr/common";
import type { Database, InferInsertModel } from "@homarr/db"; import type { Database, InferInsertModel } from "@homarr/db";
import { schema } from "@homarr/db"; import * as schema from "@homarr/db/schema";
type TableKey = { type TableKey = {
[K in keyof typeof schema]: (typeof schema)[K] extends { _: { brand: "Table" } } ? K : never; [K in keyof typeof schema]: (typeof schema)[K] extends { _: { brand: "Table" } } ? K : never;

View File

@@ -1,6 +1,6 @@
import { inArray } from "@homarr/db"; import { inArray } from "@homarr/db";
import type { Database } from "@homarr/db"; import type { Database } from "@homarr/db";
import { apps } from "@homarr/db/schema/sqlite"; import { apps } from "@homarr/db/schema";
import type { OldmarrConfig } from "@homarr/old-schema"; import type { OldmarrConfig } from "@homarr/old-schema";
import { doAppsMatch } from "../prepare/prepare-apps"; import { doAppsMatch } from "../prepare/prepare-apps";

View File

@@ -1,5 +1,5 @@
import type { InferSelectModel } from "@homarr/db"; import type { InferSelectModel } from "@homarr/db";
import type { apps } from "@homarr/db/schema/sqlite"; import type { apps } from "@homarr/db/schema";
import type { OldmarrApp } from "@homarr/old-schema"; import type { OldmarrApp } from "@homarr/old-schema";
import type { OldmarrBookmarkDefinition } from "../widgets/definitions/bookmark"; import type { OldmarrBookmarkDefinition } from "../widgets/definitions/bookmark";

View File

@@ -1,6 +1,6 @@
import type { InferInsertModel } from "@homarr/db"; import type { InferInsertModel } from "@homarr/db";
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import type { boards } from "@homarr/db/schema/sqlite"; import type { boards } from "@homarr/db/schema";
import type { prepareMultipleImports } from "../prepare/prepare-multiple"; import type { prepareMultipleImports } from "../prepare/prepare-multiple";
import { mapColor } from "./map-colors"; import { mapColor } from "./map-colors";

View File

@@ -2,7 +2,7 @@ import SuperJSON from "superjson";
import type { InferInsertModel } from "@homarr/db"; import type { InferInsertModel } from "@homarr/db";
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import type { items } from "@homarr/db/schema/sqlite"; import type { items } from "@homarr/db/schema";
import { logger } from "@homarr/log"; import { logger } from "@homarr/log";
import type { BoardSize, OldmarrApp, OldmarrWidget } from "@homarr/old-schema"; import type { BoardSize, OldmarrApp, OldmarrWidget } from "@homarr/old-schema";

View File

@@ -1,6 +1,6 @@
import type { InferInsertModel } from "@homarr/db"; import type { InferInsertModel } from "@homarr/db";
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import type { sections } from "@homarr/db/schema/sqlite"; import type { sections } from "@homarr/db/schema";
import type { OldmarrCategorySection, OldmarrEmptySection } from "@homarr/old-schema"; import type { OldmarrCategorySection, OldmarrEmptySection } from "@homarr/old-schema";
export const mapCategorySection = ( export const mapCategorySection = (

View File

@@ -1,7 +1,7 @@
import { decryptSecretWithKey } from "@homarr/common/server"; import { decryptSecretWithKey } from "@homarr/common/server";
import type { InferInsertModel } from "@homarr/db"; import type { InferInsertModel } from "@homarr/db";
import { createId } from "@homarr/db"; import { createId } from "@homarr/db";
import type { users } from "@homarr/db/schema/sqlite"; import type { users } from "@homarr/db/schema";
import type { OldmarrImportUser } from "../user-schema"; import type { OldmarrImportUser } from "../user-schema";

View File

@@ -1,5 +1,5 @@
import type { InferSelectModel } from "@homarr/db"; import type { InferSelectModel } from "@homarr/db";
import type { apps } from "@homarr/db/schema/sqlite"; import type { apps } from "@homarr/db/schema";
import type { OldmarrConfig } from "@homarr/old-schema"; import type { OldmarrConfig } from "@homarr/old-schema";
import type { ValidAnalyseConfig } from "../analyse/types"; import type { ValidAnalyseConfig } from "../analyse/types";

View File

@@ -1,7 +1,7 @@
import type { Duration } from "dayjs/plugin/duration"; import type { Duration } from "dayjs/plugin/duration";
import type { Modify } from "@homarr/common/types"; import type { Modify } from "@homarr/common/types";
import type { Integration, IntegrationSecret } from "@homarr/db/schema/sqlite"; import type { Integration, IntegrationSecret } from "@homarr/db/schema";
import type { IntegrationKind } from "@homarr/definitions"; import type { IntegrationKind } from "@homarr/definitions";
import { createIntegrationOptionsChannel } from "@homarr/redis"; import { createIntegrationOptionsChannel } from "@homarr/redis";

View File

@@ -37,7 +37,7 @@
"@mantine/spotlight": "^7.15.1", "@mantine/spotlight": "^7.15.1",
"@tabler/icons-react": "^3.26.0", "@tabler/icons-react": "^3.26.0",
"jotai": "^2.10.4", "jotai": "^2.10.4",
"next": "^14.2.20", "next": "^14.2.21",
"react": "^19.0.0", "react": "^19.0.0",
"use-deep-compare-effect": "^1.8.1" "use-deep-compare-effect": "^1.8.1"
}, },

View File

@@ -32,7 +32,7 @@
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"deepmerge": "4.3.1", "deepmerge": "4.3.1",
"mantine-react-table": "2.0.0-beta.7", "mantine-react-table": "2.0.0-beta.7",
"next": "^14.2.20", "next": "^14.2.21",
"next-intl": "3.26.2", "next-intl": "3.26.2",
"react": "^19.0.0" "react": "^19.0.0"
}, },

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More