chore(release): automatic release v1.0.0
This commit is contained in:
10
.github/workflows/deployment-docker-image.yml
vendored
10
.github/workflows/deployment-docker-image.yml
vendored
@@ -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:
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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) => {
|
||||||
|
|||||||
@@ -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({
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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 => {
|
||||||
|
|||||||
@@ -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) => {
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
60
packages/db/env.mjs
Normal 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",
|
||||||
|
});
|
||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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, {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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 });
|
||||||
|
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
45
packages/db/schema/index.ts
Normal file
45
packages/db/schema/index.ts
Normal 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>;
|
||||||
@@ -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>;
|
|
||||||
|
|||||||
@@ -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",
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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 = (
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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
Reference in New Issue
Block a user