Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8889537ff8 |
No files matched your search
@@ -45,7 +45,6 @@ COPY --from=builder /app/apps/nextjs/package.json .
|
|||||||
|
|
||||||
COPY --from=builder /app/apps/tasks/tasks.cjs ./apps/tasks/tasks.cjs
|
COPY --from=builder /app/apps/tasks/tasks.cjs ./apps/tasks/tasks.cjs
|
||||||
COPY --from=builder /app/apps/websocket/wssServer.cjs ./apps/websocket/wssServer.cjs
|
COPY --from=builder /app/apps/websocket/wssServer.cjs ./apps/websocket/wssServer.cjs
|
||||||
COPY --from=builder /app/node_modules/better-sqlite3/build/Release/better_sqlite3.node /app/build/better_sqlite3.node
|
|
||||||
|
|
||||||
COPY --from=builder /app/packages/db/migrations ./db/migrations
|
COPY --from=builder /app/packages/db/migrations ./db/migrations
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,6 @@
|
|||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"drizzle-orm": "^0.45.1",
|
|
||||||
"flag-icons": "^7.5.0",
|
"flag-icons": "^7.5.0",
|
||||||
"glob": "^13.0.0",
|
"glob": "^13.0.0",
|
||||||
"isomorphic-dompurify": "^2.34.0",
|
"isomorphic-dompurify": "^2.34.0",
|
||||||
@@ -88,7 +87,7 @@
|
|||||||
"superjson": "2.2.6",
|
"superjson": "2.2.6",
|
||||||
"swagger-ui-react": "^5.31.0",
|
"swagger-ui-react": "^5.31.0",
|
||||||
"use-deep-compare-effect": "^1.8.1",
|
"use-deep-compare-effect": "^1.8.1",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
import { Card, Center, Stack, Text, Title } from "@mantine/core";
|
import { Card, Center, Stack, Text, Title } from "@mantine/core";
|
||||||
import { and, eq } from "drizzle-orm";
|
|
||||||
|
|
||||||
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 } from "@homarr/db";
|
import { and, db, eq } from "@homarr/db";
|
||||||
import { invites } from "@homarr/db/schema";
|
import { invites } from "@homarr/db/schema";
|
||||||
import { getScopedI18n } from "@homarr/translation/server";
|
import { getScopedI18n } from "@homarr/translation/server";
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
import { inArray } from "drizzle-orm";
|
|
||||||
|
|
||||||
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 } from "@homarr/db";
|
import { db, inArray } from "@homarr/db";
|
||||||
import { groups } from "@homarr/db/schema";
|
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";
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { NextRequest } from "next/server";
|
import type { NextRequest } from "next/server";
|
||||||
import { userAgent } from "next/server";
|
import { userAgent } from "next/server";
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { createOpenApiFetchHandler } from "trpc-to-openapi";
|
import { createOpenApiFetchHandler } from "trpc-to-openapi";
|
||||||
|
|
||||||
import { appRouter, createTRPCContext } from "@homarr/api";
|
import { appRouter, createTRPCContext } from "@homarr/api";
|
||||||
@@ -9,7 +8,7 @@ import { hashPasswordAsync } from "@homarr/auth";
|
|||||||
import { createSessionAsync } from "@homarr/auth/server";
|
import { createSessionAsync } from "@homarr/auth/server";
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
import { ErrorWithMetadata } from "@homarr/core/infrastructure/logs/error";
|
import { ErrorWithMetadata } from "@homarr/core/infrastructure/logs/error";
|
||||||
import { db } from "@homarr/db";
|
import { db, eq } from "@homarr/db";
|
||||||
import { apiKeys } from "@homarr/db/schema";
|
import { apiKeys } from "@homarr/db/schema";
|
||||||
|
|
||||||
const logger = createLogger({ module: "trpcOpenApiRoute" });
|
const logger = createLogger({ module: "trpcOpenApiRoute" });
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import type { NextRequest } from "next/server";
|
import type { NextRequest } from "next/server";
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import DOMPurify from "isomorphic-dompurify";
|
import DOMPurify from "isomorphic-dompurify";
|
||||||
|
|
||||||
import { db } from "@homarr/db";
|
import { db, eq } from "@homarr/db";
|
||||||
import { medias } from "@homarr/db/schema";
|
import { medias } from "@homarr/db/schema";
|
||||||
|
|
||||||
export async function GET(_req: NextRequest, props: { params: Promise<{ id: string }> }) {
|
export async function GET(_req: NextRequest, props: { params: Promise<{ id: string }> }) {
|
||||||
|
|||||||
@@ -39,7 +39,6 @@
|
|||||||
"@homarr/widgets": "workspace:^0.1.0",
|
"@homarr/widgets": "workspace:^0.1.0",
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"drizzle-orm": "^0.45.1",
|
|
||||||
"fastify": "^5.6.2",
|
"fastify": "^5.6.2",
|
||||||
"superjson": "2.2.6",
|
"superjson": "2.2.6",
|
||||||
"undici": "7.16.0"
|
"undici": "7.16.0"
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import type { InferInsertModel } from "drizzle-orm";
|
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { schedule, validate as validateCron } from "node-cron";
|
import { schedule, validate as validateCron } from "node-cron";
|
||||||
|
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
import type { IJobManager } from "@homarr/cron-job-api";
|
import type { IJobManager } from "@homarr/cron-job-api";
|
||||||
import type { jobGroup as cronJobGroup, JobGroupKeys } from "@homarr/cron-jobs";
|
import type { jobGroup as cronJobGroup, JobGroupKeys } from "@homarr/cron-jobs";
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database, InferInsertModel } from "@homarr/db";
|
||||||
|
import { eq } from "@homarr/db";
|
||||||
import { cronJobConfigurations } from "@homarr/db/schema";
|
import { cronJobConfigurations } from "@homarr/db/schema";
|
||||||
|
|
||||||
const logger = createLogger({ module: "jobManager" });
|
const logger = createLogger({ module: "jobManager" });
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { eq, inArray } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { env } from "@homarr/auth/env";
|
import { env } from "@homarr/auth/env";
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
import { db } from "@homarr/db";
|
import { db, eq, inArray } from "@homarr/db";
|
||||||
import { sessions, users } from "@homarr/db/schema";
|
import { sessions, users } from "@homarr/db/schema";
|
||||||
import { supportedAuthProviders } from "@homarr/definitions";
|
import { supportedAuthProviders } from "@homarr/definitions";
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"better-sqlite3": "^12.5.0"
|
"better-sqlite3": "^12.5.0"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.26.0",
|
"packageManager": "pnpm@10.25.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=24.12.0",
|
"node": ">=24.12.0",
|
||||||
"pnpm": ">=10.26.0"
|
"pnpm": ">=10.25.0"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
|
|||||||
+5
-6
@@ -59,16 +59,15 @@
|
|||||||
"vite-tsconfig-paths": "^5.1.4",
|
"vite-tsconfig-paths": "^5.1.4",
|
||||||
"vitest": "^4.0.15"
|
"vitest": "^4.0.15"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.26.0",
|
"packageManager": "pnpm@10.25.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=24.12.0",
|
"node": ">=24.12.0",
|
||||||
"pnpm": ">=10.26.0"
|
"pnpm": ">=10.25.0"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
"@tree-sitter-grammars/tree-sitter-yaml",
|
"@tree-sitter-grammars/tree-sitter-yaml",
|
||||||
"bcrypt",
|
"bcrypt",
|
||||||
"better-sqlite3",
|
|
||||||
"cpu-features",
|
"cpu-features",
|
||||||
"esbuild",
|
"esbuild",
|
||||||
"sharp",
|
"sharp",
|
||||||
@@ -84,18 +83,18 @@
|
|||||||
"brace-expansion@>=1.0.0 <=1.1.11": ">=4.0.1",
|
"brace-expansion@>=1.0.0 <=1.1.11": ">=4.0.1",
|
||||||
"esbuild@<=0.24.2": ">=0.27.1",
|
"esbuild@<=0.24.2": ">=0.27.1",
|
||||||
"form-data@>=4.0.0 <4.0.4": ">=4.0.5",
|
"form-data@>=4.0.0 <4.0.4": ">=4.0.5",
|
||||||
"hono@<4.6.5": ">=4.11.1",
|
"hono@<4.6.5": ">=4.11.0",
|
||||||
"linkifyjs@<4.3.2": ">=4.3.2",
|
"linkifyjs@<4.3.2": ">=4.3.2",
|
||||||
"nanoid@>=4.0.0 <5.0.9": ">=5.1.6",
|
"nanoid@>=4.0.0 <5.0.9": ">=5.1.6",
|
||||||
"prismjs@<1.30.0": ">=1.30.0",
|
"prismjs@<1.30.0": ">=1.30.0",
|
||||||
"proxmox-api>undici": "7.16.0",
|
"proxmox-api>undici": "7.16.0",
|
||||||
"react-is": "^19.2.3",
|
"react-is": "^19.2.3",
|
||||||
"rollup@>=4.0.0 <4.22.4": ">=4.53.4",
|
"rollup@>=4.0.0 <4.22.4": ">=4.53.3",
|
||||||
"sha.js@<=2.4.11": ">=2.4.12",
|
"sha.js@<=2.4.11": ">=2.4.12",
|
||||||
"tar-fs@>=3.0.0 <3.0.9": ">=3.1.1",
|
"tar-fs@>=3.0.0 <3.0.9": ">=3.1.1",
|
||||||
"tar-fs@>=2.0.0 <2.1.3": ">=3.1.1",
|
"tar-fs@>=2.0.0 <2.1.3": ">=3.1.1",
|
||||||
"tmp@<=0.2.3": ">=0.2.5",
|
"tmp@<=0.2.3": ">=0.2.5",
|
||||||
"vite@>=5.0.0 <=5.4.18": ">=7.3.0"
|
"vite@>=5.0.0 <=5.4.18": ">=7.2.7"
|
||||||
},
|
},
|
||||||
"patchedDependencies": {
|
"patchedDependencies": {
|
||||||
"@types/node-unifi": "patches/@types__node-unifi.patch",
|
"@types/node-unifi": "patches/@types__node-unifi.patch",
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
"@homarr/db": "workspace:^0.1.0",
|
"@homarr/db": "workspace:^0.1.0",
|
||||||
"@homarr/server-settings": "workspace:^0.1.0",
|
"@homarr/server-settings": "workspace:^0.1.0",
|
||||||
"@umami/node": "^0.4.0",
|
"@umami/node": "^0.4.0",
|
||||||
"drizzle-orm": "^0.45.1",
|
|
||||||
"superjson": "2.2.6"
|
"superjson": "2.2.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import type { UmamiEventData } from "@umami/node";
|
import type { UmamiEventData } from "@umami/node";
|
||||||
import { Umami } from "@umami/node";
|
import { Umami } from "@umami/node";
|
||||||
import { count } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
import { 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";
|
import { integrations, items, users } from "@homarr/db/schema";
|
||||||
import type { defaultServerSettings } from "@homarr/server-settings";
|
import type { defaultServerSettings } from "@homarr/server-settings";
|
||||||
|
|||||||
@@ -46,14 +46,13 @@
|
|||||||
"@trpc/react-query": "^11.8.0",
|
"@trpc/react-query": "^11.8.0",
|
||||||
"@trpc/server": "^11.8.0",
|
"@trpc/server": "^11.8.0",
|
||||||
"@trpc/tanstack-react-query": "^11.8.0",
|
"@trpc/tanstack-react-query": "^11.8.0",
|
||||||
"drizzle-orm": "^0.45.1",
|
|
||||||
"lodash.clonedeep": "^4.5.0",
|
"lodash.clonedeep": "^4.5.0",
|
||||||
"next": "16.0.10",
|
"next": "16.0.10",
|
||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"react-dom": "19.2.3",
|
"react-dom": "19.2.3",
|
||||||
"superjson": "2.2.6",
|
"superjson": "2.2.6",
|
||||||
"trpc-to-openapi": "^3.1.0",
|
"trpc-to-openapi": "^3.1.0",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { and, eq, inArray } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import type { Session } from "@homarr/auth";
|
import type { Session } from "@homarr/auth";
|
||||||
@@ -8,6 +7,7 @@ import { constructIntegrationPermissions } from "@homarr/auth/shared";
|
|||||||
import { decryptSecret } from "@homarr/common/server";
|
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 { integrations } from "@homarr/db/schema";
|
import { integrations } from "@homarr/db/schema";
|
||||||
import type { IntegrationKind } from "@homarr/definitions";
|
import type { IntegrationKind } from "@homarr/definitions";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { and, eq } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
|
import { and, eq } from "@homarr/db";
|
||||||
import { items } from "@homarr/db/schema";
|
import { items } from "@homarr/db/schema";
|
||||||
import type { WidgetKind } from "@homarr/definitions";
|
import type { WidgetKind } from "@homarr/definitions";
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import { createSaltAsync, hashPasswordAsync } from "@homarr/auth";
|
import { createSaltAsync, hashPasswordAsync } from "@homarr/auth";
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import { generateSecureRandomToken } from "@homarr/common/server";
|
import { generateSecureRandomToken } from "@homarr/common/server";
|
||||||
import { db } from "@homarr/db";
|
import { db, eq } from "@homarr/db";
|
||||||
import { apiKeys } from "@homarr/db/schema";
|
import { apiKeys } from "@homarr/db/schema";
|
||||||
|
|
||||||
import { createTRPCRouter, permissionRequiredProcedure } from "../trpc";
|
import { createTRPCRouter, permissionRequiredProcedure } from "../trpc";
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { asc, eq, inArray, like } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
|
import { asc, eq, inArray, like } from "@homarr/db";
|
||||||
import { apps } from "@homarr/db/schema";
|
import { apps } from "@homarr/db/schema";
|
||||||
import { selectAppSchema } from "@homarr/db/validationSchemas";
|
import { selectAppSchema } from "@homarr/db/validationSchemas";
|
||||||
import { getIconForName } from "@homarr/icons";
|
import { getIconForNameAsync } from "@homarr/icons";
|
||||||
import { appCreateManySchema, appEditSchema, appManageSchema } from "@homarr/validation/app";
|
import { appCreateManySchema, appEditSchema, appManageSchema } from "@homarr/validation/app";
|
||||||
import { byIdSchema, paginatedSchema } from "@homarr/validation/common";
|
import { byIdSchema, paginatedSchema } from "@homarr/validation/common";
|
||||||
|
|
||||||
@@ -141,13 +141,15 @@ export const appRouter = createTRPCRouter({
|
|||||||
.output(z.void())
|
.output(z.void())
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
await ctx.db.insert(apps).values(
|
await ctx.db.insert(apps).values(
|
||||||
input.map((app) => ({
|
await Promise.all(
|
||||||
|
input.map(async (app) => ({
|
||||||
id: createId(),
|
id: createId(),
|
||||||
name: app.name,
|
name: app.name,
|
||||||
description: app.description,
|
description: app.description,
|
||||||
iconUrl: app.iconUrl ?? getIconForName(ctx.db, app.name).sync()?.url ?? defaultIcon,
|
iconUrl: app.iconUrl ?? (await getIconForNameAsync(ctx.db, app.name))?.url ?? defaultIcon,
|
||||||
href: app.href,
|
href: app.href,
|
||||||
})),
|
})),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
update: permissionRequiredProcedure
|
update: permissionRequiredProcedure
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { eq, or } from "drizzle-orm";
|
|
||||||
import SuperJSON from "superjson";
|
import SuperJSON from "superjson";
|
||||||
|
|
||||||
import type { Session } from "@homarr/auth";
|
import type { Session } from "@homarr/auth";
|
||||||
import { db } from "@homarr/db";
|
import { db, eq, or } from "@homarr/db";
|
||||||
import { items } from "@homarr/db/schema";
|
import { items } from "@homarr/db/schema";
|
||||||
|
|
||||||
import type { WidgetComponentProps } from "../../../../widgets/src";
|
import type { WidgetComponentProps } from "../../../../widgets/src";
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import type { InferInsertModel, InferSelectModel, SQL } from "drizzle-orm";
|
|
||||||
import { and, asc, eq, inArray, isNull, like, not, or, sql } from "drizzle-orm";
|
|
||||||
import superjson from "superjson";
|
import superjson from "superjson";
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import { constructBoardPermissions } from "@homarr/auth/shared";
|
import { constructBoardPermissions } from "@homarr/auth/shared";
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import type { DeviceType } from "@homarr/common/server";
|
import type { DeviceType } from "@homarr/common/server";
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database, InferInsertModel, InferSelectModel, SQL } from "@homarr/db";
|
||||||
import { handleTransactionsAsync } from "@homarr/db";
|
import { and, asc, eq, handleTransactionsAsync, inArray, isNull, like, not, or, sql } from "@homarr/db";
|
||||||
import { createDbInsertCollectionWithoutTransaction } from "@homarr/db/collection";
|
import { createDbInsertCollectionWithoutTransaction } from "@homarr/db/collection";
|
||||||
import { getServerSettingByKeyAsync } from "@homarr/db/queries";
|
import { getServerSettingByKeyAsync } from "@homarr/db/queries";
|
||||||
import {
|
import {
|
||||||
@@ -479,47 +477,6 @@ export const boardRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleSync(db) {
|
|
||||||
db.transaction((transaction) => {
|
|
||||||
transaction
|
|
||||||
.insert(boards)
|
|
||||||
.values({
|
|
||||||
...boardProps,
|
|
||||||
id: newBoardId,
|
|
||||||
name: input.name,
|
|
||||||
creatorId: ctx.session.user.id,
|
|
||||||
})
|
|
||||||
.run();
|
|
||||||
|
|
||||||
if (layoutsToInsert.length > 0) {
|
|
||||||
transaction.insert(layouts).values(layoutsToInsert).run();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sectionsToInsert.length > 0) {
|
|
||||||
transaction.insert(sections).values(sectionsToInsert).run();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sectionLayoutsToInsert.length > 0) {
|
|
||||||
transaction.insert(sectionLayouts).values(sectionLayoutsToInsert).run();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sectionCollapseStatesToInsert.length > 0) {
|
|
||||||
transaction.insert(sectionCollapseStates).values(sectionCollapseStatesToInsert).run();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemsToInsert.length > 0) {
|
|
||||||
transaction.insert(items).values(itemsToInsert).run();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemLayoutsToInsert.length > 0) {
|
|
||||||
transaction.insert(itemLayouts).values(itemLayoutsToInsert).run();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemIntegrationsToInsert.length > 0) {
|
|
||||||
transaction.insert(integrationItems).values(itemIntegrationsToInsert).run();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
renameBoard: protectedProcedure.input(boardRenameSchema).mutation(async ({ ctx, input }) => {
|
renameBoard: protectedProcedure.input(boardRenameSchema).mutation(async ({ ctx, input }) => {
|
||||||
@@ -956,216 +913,6 @@ export const boardRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleSync(db) {
|
|
||||||
db.transaction((transaction) => {
|
|
||||||
const addedSections = filterAddedItems(input.sections, dbBoard.sections);
|
|
||||||
|
|
||||||
if (addedSections.length > 0) {
|
|
||||||
transaction
|
|
||||||
.insert(sections)
|
|
||||||
.values(
|
|
||||||
addedSections.map((section) => ({
|
|
||||||
id: section.id,
|
|
||||||
kind: section.kind,
|
|
||||||
yOffset: section.kind !== "dynamic" ? section.yOffset : null,
|
|
||||||
xOffset: section.kind === "dynamic" ? null : 0,
|
|
||||||
options: section.kind === "dynamic" ? superjson.stringify(section.options) : emptySuperJSON,
|
|
||||||
name: "name" in section ? section.name : null,
|
|
||||||
boardId: dbBoard.id,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
|
|
||||||
if (addedSections.some((section) => section.kind === "dynamic")) {
|
|
||||||
transaction
|
|
||||||
.insert(sectionLayouts)
|
|
||||||
.values(
|
|
||||||
addedSections
|
|
||||||
.filter((section) => section.kind === "dynamic")
|
|
||||||
.flatMap((section) =>
|
|
||||||
section.layouts.map(
|
|
||||||
(sectionLayout): InferInsertModel<typeof sectionLayouts> => ({
|
|
||||||
layoutId: sectionLayout.layoutId,
|
|
||||||
sectionId: section.id,
|
|
||||||
parentSectionId: sectionLayout.parentSectionId,
|
|
||||||
height: sectionLayout.height,
|
|
||||||
width: sectionLayout.width,
|
|
||||||
xOffset: sectionLayout.xOffset,
|
|
||||||
yOffset: sectionLayout.yOffset,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const addedItems = filterAddedItems(input.items, dbBoard.items);
|
|
||||||
|
|
||||||
if (addedItems.length > 0) {
|
|
||||||
transaction
|
|
||||||
.insert(items)
|
|
||||||
.values(
|
|
||||||
addedItems.map((item) => ({
|
|
||||||
id: item.id,
|
|
||||||
kind: item.kind,
|
|
||||||
options: superjson.stringify(item.options),
|
|
||||||
advancedOptions: superjson.stringify(item.advancedOptions),
|
|
||||||
boardId: dbBoard.id,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
transaction
|
|
||||||
.insert(itemLayouts)
|
|
||||||
.values(
|
|
||||||
addedItems.flatMap((item) =>
|
|
||||||
item.layouts.map(
|
|
||||||
(layoutSection): InferInsertModel<typeof itemLayouts> => ({
|
|
||||||
layoutId: layoutSection.layoutId,
|
|
||||||
sectionId: layoutSection.sectionId,
|
|
||||||
itemId: item.id,
|
|
||||||
height: layoutSection.height,
|
|
||||||
width: layoutSection.width,
|
|
||||||
xOffset: layoutSection.xOffset,
|
|
||||||
yOffset: layoutSection.yOffset,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
const inputIntegrationRelations = input.items.flatMap(({ integrationIds, id: itemId }) =>
|
|
||||||
integrationIds.map((integrationId) => ({
|
|
||||||
integrationId,
|
|
||||||
itemId,
|
|
||||||
})),
|
|
||||||
);
|
|
||||||
const dbIntegrationRelations = dbBoard.items.flatMap(({ integrationIds, id: itemId }) =>
|
|
||||||
integrationIds.map((integrationId) => ({
|
|
||||||
integrationId,
|
|
||||||
itemId,
|
|
||||||
})),
|
|
||||||
);
|
|
||||||
const addedIntegrationRelations = inputIntegrationRelations.filter(
|
|
||||||
(inputRelation) =>
|
|
||||||
!dbIntegrationRelations.some(
|
|
||||||
(dbRelation) =>
|
|
||||||
dbRelation.itemId === inputRelation.itemId &&
|
|
||||||
dbRelation.integrationId === inputRelation.integrationId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (addedIntegrationRelations.length > 0) {
|
|
||||||
transaction
|
|
||||||
.insert(integrationItems)
|
|
||||||
.values(
|
|
||||||
addedIntegrationRelations.map((relation) => ({
|
|
||||||
itemId: relation.itemId,
|
|
||||||
integrationId: relation.integrationId,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedItems = filterUpdatedItems(input.items, dbBoard.items);
|
|
||||||
|
|
||||||
for (const item of updatedItems) {
|
|
||||||
transaction
|
|
||||||
.update(items)
|
|
||||||
.set({
|
|
||||||
kind: item.kind,
|
|
||||||
options: superjson.stringify(item.options),
|
|
||||||
advancedOptions: superjson.stringify(item.advancedOptions),
|
|
||||||
})
|
|
||||||
.where(eq(items.id, item.id))
|
|
||||||
.run();
|
|
||||||
|
|
||||||
for (const itemSectionLayout of item.layouts) {
|
|
||||||
transaction
|
|
||||||
.update(itemLayouts)
|
|
||||||
.set({
|
|
||||||
height: itemSectionLayout.height,
|
|
||||||
width: itemSectionLayout.width,
|
|
||||||
xOffset: itemSectionLayout.xOffset,
|
|
||||||
yOffset: itemSectionLayout.yOffset,
|
|
||||||
sectionId: itemSectionLayout.sectionId,
|
|
||||||
})
|
|
||||||
.where(and(eq(itemLayouts.itemId, item.id), eq(itemLayouts.layoutId, itemSectionLayout.layoutId)))
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedSections = filterUpdatedItems(input.sections, dbBoard.sections);
|
|
||||||
|
|
||||||
for (const section of updatedSections) {
|
|
||||||
const prev = dbBoard.sections.find((dbSection) => dbSection.id === section.id);
|
|
||||||
transaction
|
|
||||||
.update(sections)
|
|
||||||
.set({
|
|
||||||
yOffset: prev?.kind !== "dynamic" && "yOffset" in section ? section.yOffset : null,
|
|
||||||
xOffset: prev?.kind !== "dynamic" && "yOffset" in section ? 0 : null,
|
|
||||||
options: section.kind === "dynamic" ? superjson.stringify(section.options) : emptySuperJSON,
|
|
||||||
name: prev?.kind === "category" && "name" in section ? section.name : null,
|
|
||||||
})
|
|
||||||
.where(eq(sections.id, section.id))
|
|
||||||
.run();
|
|
||||||
|
|
||||||
if (section.kind !== "dynamic") continue;
|
|
||||||
|
|
||||||
for (const sectionLayout of section.layouts) {
|
|
||||||
transaction
|
|
||||||
.update(sectionLayouts)
|
|
||||||
.set({
|
|
||||||
height: sectionLayout.height,
|
|
||||||
width: sectionLayout.width,
|
|
||||||
xOffset: sectionLayout.xOffset,
|
|
||||||
yOffset: sectionLayout.yOffset,
|
|
||||||
parentSectionId: sectionLayout.parentSectionId,
|
|
||||||
})
|
|
||||||
.where(
|
|
||||||
and(eq(sectionLayouts.sectionId, section.id), eq(sectionLayouts.layoutId, sectionLayout.layoutId)),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const removedIntegrationRelations = dbIntegrationRelations.filter(
|
|
||||||
(dbRelation) =>
|
|
||||||
!inputIntegrationRelations.some(
|
|
||||||
(inputRelation) =>
|
|
||||||
dbRelation.itemId === inputRelation.itemId &&
|
|
||||||
dbRelation.integrationId === inputRelation.integrationId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const relation of removedIntegrationRelations) {
|
|
||||||
transaction
|
|
||||||
.delete(integrationItems)
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(integrationItems.itemId, relation.itemId),
|
|
||||||
eq(integrationItems.integrationId, relation.integrationId),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
const removedItems = filterRemovedItems(input.items, dbBoard.items);
|
|
||||||
|
|
||||||
const itemIds = removedItems.map((item) => item.id);
|
|
||||||
if (itemIds.length > 0) {
|
|
||||||
transaction.delete(items).where(inArray(items.id, itemIds)).run();
|
|
||||||
}
|
|
||||||
|
|
||||||
const removedSections = filterRemovedItems(input.sections, dbBoard.sections);
|
|
||||||
const sectionIds = removedSections.map((section) => section.id);
|
|
||||||
|
|
||||||
if (sectionIds.length > 0) {
|
|
||||||
transaction.delete(sections).where(inArray(sections.id, sectionIds)).run();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
getBoardPermissions: protectedProcedure.input(byIdSchema).query(async ({ input, ctx }) => {
|
getBoardPermissions: protectedProcedure.input(byIdSchema).query(async ({ input, ctx }) => {
|
||||||
@@ -1258,24 +1005,6 @@ export const boardRouter = createTRPCRouter({
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleSync(db) {
|
|
||||||
db.transaction((transaction) => {
|
|
||||||
transaction.delete(boardUserPermissions).where(eq(boardUserPermissions.boardId, input.entityId)).run();
|
|
||||||
if (input.permissions.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
transaction
|
|
||||||
.insert(boardUserPermissions)
|
|
||||||
.values(
|
|
||||||
input.permissions.map((permission) => ({
|
|
||||||
userId: permission.principalId,
|
|
||||||
permission: permission.permission,
|
|
||||||
boardId: input.entityId,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
saveGroupBoardPermissions: protectedProcedure.input(boardSavePermissionsSchema).mutation(async ({ input, ctx }) => {
|
saveGroupBoardPermissions: protectedProcedure.input(boardSavePermissionsSchema).mutation(async ({ input, ctx }) => {
|
||||||
@@ -1299,24 +1028,6 @@ export const boardRouter = createTRPCRouter({
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleSync(db) {
|
|
||||||
db.transaction((transaction) => {
|
|
||||||
transaction.delete(boardGroupPermissions).where(eq(boardGroupPermissions.boardId, input.entityId)).run();
|
|
||||||
if (input.permissions.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
transaction
|
|
||||||
.insert(boardGroupPermissions)
|
|
||||||
.values(
|
|
||||||
input.permissions.map((permission) => ({
|
|
||||||
groupId: permission.principalId,
|
|
||||||
permission: permission.permission,
|
|
||||||
boardId: input.entityId,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
importOldmarrConfig: permissionRequiredProcedure
|
importOldmarrConfig: permissionRequiredProcedure
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import type { SQL } from "drizzle-orm";
|
|
||||||
import { eq, inArray } from "drizzle-orm";
|
|
||||||
|
|
||||||
import type { Session } from "@homarr/auth";
|
import type { Session } from "@homarr/auth";
|
||||||
import { constructBoardPermissions } from "@homarr/auth/shared";
|
import { constructBoardPermissions } from "@homarr/auth/shared";
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database, SQL } from "@homarr/db";
|
||||||
|
import { eq, inArray } from "@homarr/db";
|
||||||
import { boardGroupPermissions, boardUserPermissions, groupMembers } from "@homarr/db/schema";
|
import { boardGroupPermissions, boardUserPermissions, groupMembers } from "@homarr/db/schema";
|
||||||
import type { BoardPermission } from "@homarr/definitions";
|
import type { BoardPermission } from "@homarr/definitions";
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { X509Certificate } from "node:crypto";
|
import { X509Certificate } from "node:crypto";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { and, eq } from "drizzle-orm";
|
|
||||||
import { zfd } from "zod-form-data";
|
import { zfd } from "zod-form-data";
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
@@ -9,6 +8,7 @@ import {
|
|||||||
removeCustomRootCertificateAsync,
|
removeCustomRootCertificateAsync,
|
||||||
} from "@homarr/core/infrastructure/certificates";
|
} from "@homarr/core/infrastructure/certificates";
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
|
import { and, eq } from "@homarr/db";
|
||||||
import { trustedCertificateHostnames } from "@homarr/db/schema";
|
import { trustedCertificateHostnames } from "@homarr/db/schema";
|
||||||
import { certificateValidFileNameSchema, checkCertificateFile } from "@homarr/validation/certificates";
|
import { certificateValidFileNameSchema, checkCertificateFile } from "@homarr/validation/certificates";
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ export const certificateRouter = createTRPCRouter({
|
|||||||
hostname: input.hostname,
|
hostname: input.hostname,
|
||||||
thumbprint: input.thumbprint,
|
thumbprint: input.thumbprint,
|
||||||
});
|
});
|
||||||
const dbResult = await ctx.db
|
await ctx.db
|
||||||
.delete(trustedCertificateHostnames)
|
.delete(trustedCertificateHostnames)
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
@@ -103,7 +103,6 @@ export const certificateRouter = createTRPCRouter({
|
|||||||
logger.info("Removed trusted hostname", {
|
logger.info("Removed trusted hostname", {
|
||||||
hostname: input.hostname,
|
hostname: input.hostname,
|
||||||
thumbprint: input.thumbprint,
|
thumbprint: input.thumbprint,
|
||||||
count: dbResult.changes,
|
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
removeCertificate: permissionRequiredProcedure
|
removeCertificate: permissionRequiredProcedure
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { and, eq, like, not } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database } from "@homarr/db";
|
||||||
import { handleTransactionsAsync } from "@homarr/db";
|
import { and, eq, handleTransactionsAsync, like, not } from "@homarr/db";
|
||||||
import { getMaxGroupPositionAsync } from "@homarr/db/queries";
|
import { getMaxGroupPositionAsync } from "@homarr/db/queries";
|
||||||
import { groupMembers, groupPermissions, groups } from "@homarr/db/schema";
|
import { groupMembers, groupPermissions, groups } from "@homarr/db/schema";
|
||||||
import { everyoneGroup } from "@homarr/definitions";
|
import { everyoneGroup } from "@homarr/definitions";
|
||||||
@@ -261,13 +260,6 @@ export const groupRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleSync: (db) => {
|
|
||||||
db.transaction((trx) => {
|
|
||||||
for (const { id, position } of positions) {
|
|
||||||
trx.update(groups).set({ position }).where(eq(groups.id, id)).run();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
savePermissions: permissionRequiredProcedure
|
savePermissions: permissionRequiredProcedure
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { eq, inArray, or } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { isProviderEnabled } from "@homarr/auth/server";
|
import { isProviderEnabled } from "@homarr/auth/server";
|
||||||
import { db } from "@homarr/db";
|
import { db, eq, inArray, or } from "@homarr/db";
|
||||||
import {
|
import {
|
||||||
apps,
|
apps,
|
||||||
boards,
|
boards,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { and, like } from "drizzle-orm";
|
import { and, like } from "@homarr/db";
|
||||||
|
|
||||||
import { icons } from "@homarr/db/schema";
|
import { icons } from "@homarr/db/schema";
|
||||||
import { iconsFindSchema } from "@homarr/validation/icons";
|
import { iconsFindSchema } from "@homarr/validation/icons";
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import type { SQL } from "drizzle-orm";
|
|
||||||
import { eq, inArray } from "drizzle-orm";
|
|
||||||
|
|
||||||
import type { Session } from "@homarr/auth";
|
import type { Session } from "@homarr/auth";
|
||||||
import { constructIntegrationPermissions } from "@homarr/auth/shared";
|
import { constructIntegrationPermissions } from "@homarr/auth/shared";
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database, SQL } from "@homarr/db";
|
||||||
|
import { eq, inArray } from "@homarr/db";
|
||||||
import { groupMembers, integrationGroupPermissions, integrationUserPermissions } from "@homarr/db/schema";
|
import { groupMembers, integrationGroupPermissions, integrationUserPermissions } from "@homarr/db/schema";
|
||||||
import type { IntegrationPermission } from "@homarr/definitions";
|
import type { IntegrationPermission } from "@homarr/definitions";
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { and, asc, eq, inArray, like, or } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import { createId, objectEntries } from "@homarr/common";
|
import { createId, objectEntries } from "@homarr/common";
|
||||||
import { decryptSecret, encryptSecret } from "@homarr/common/server";
|
import { decryptSecret, encryptSecret } from "@homarr/common/server";
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
import { handleTransactionsAsync } from "@homarr/db";
|
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database } from "@homarr/db";
|
||||||
|
import { and, asc, eq, handleTransactionsAsync, inArray, like, or } from "@homarr/db";
|
||||||
import {
|
import {
|
||||||
apps,
|
apps,
|
||||||
groupMembers,
|
groupMembers,
|
||||||
@@ -542,27 +541,6 @@ export const integrationRouter = createTRPCRouter({
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleSync(db) {
|
|
||||||
db.transaction((transaction) => {
|
|
||||||
transaction
|
|
||||||
.delete(integrationUserPermissions)
|
|
||||||
.where(eq(integrationUserPermissions.integrationId, input.entityId))
|
|
||||||
.run();
|
|
||||||
if (input.permissions.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
transaction
|
|
||||||
.insert(integrationUserPermissions)
|
|
||||||
.values(
|
|
||||||
input.permissions.map((permission) => ({
|
|
||||||
userId: permission.principalId,
|
|
||||||
permission: permission.permission,
|
|
||||||
integrationId: input.entityId,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
saveGroupIntegrationPermissions: protectedProcedure
|
saveGroupIntegrationPermissions: protectedProcedure
|
||||||
@@ -588,27 +566,6 @@ export const integrationRouter = createTRPCRouter({
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleSync(db) {
|
|
||||||
db.transaction((transaction) => {
|
|
||||||
transaction
|
|
||||||
.delete(integrationGroupPermissions)
|
|
||||||
.where(eq(integrationGroupPermissions.integrationId, input.entityId))
|
|
||||||
.run();
|
|
||||||
if (input.permissions.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
transaction
|
|
||||||
.insert(integrationGroupPermissions)
|
|
||||||
.values(
|
|
||||||
input.permissions.map((permission) => ({
|
|
||||||
groupId: permission.principalId,
|
|
||||||
permission: permission.permission,
|
|
||||||
integrationId: input.entityId,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
searchInIntegration: protectedProcedure
|
searchInIntegration: protectedProcedure
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { randomBytes } from "crypto";
|
import { randomBytes } from "crypto";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { asc, eq } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
|
import { asc, eq } from "@homarr/db";
|
||||||
import { invites } from "@homarr/db/schema";
|
import { invites } from "@homarr/db/schema";
|
||||||
import { selectInviteSchema } from "@homarr/db/validationSchemas";
|
import { selectInviteSchema } from "@homarr/db/validationSchemas";
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import type { InferInsertModel } from "drizzle-orm";
|
|
||||||
import { and, desc, eq, like } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
|
import type { InferInsertModel } from "@homarr/db";
|
||||||
|
import { and, desc, eq, like } from "@homarr/db";
|
||||||
import { iconRepositories, icons, medias } from "@homarr/db/schema";
|
import { iconRepositories, icons, medias } from "@homarr/db/schema";
|
||||||
import { createLocalImageUrl, LOCAL_ICON_REPOSITORY_SLUG, mapMediaToIcon } from "@homarr/icons/local";
|
import { createLocalImageUrl, LOCAL_ICON_REPOSITORY_SLUG, mapMediaToIcon } from "@homarr/icons/local";
|
||||||
import { byIdSchema, paginatedSchema } from "@homarr/validation/common";
|
import { byIdSchema, paginatedSchema } from "@homarr/validation/common";
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { isProviderEnabled } from "@homarr/auth/server";
|
import { isProviderEnabled } from "@homarr/auth/server";
|
||||||
import { objectEntries } from "@homarr/common";
|
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 { groups, onboarding } from "@homarr/db/schema";
|
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,9 +1,9 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { asc, eq, like } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
|
import { asc, eq, like } from "@homarr/db";
|
||||||
import { getServerSettingByKeyAsync, updateServerSettingByKeyAsync } from "@homarr/db/queries";
|
import { getServerSettingByKeyAsync, updateServerSettingByKeyAsync } from "@homarr/db/queries";
|
||||||
import { searchEngines, users } from "@homarr/db/schema";
|
import { searchEngines, users } from "@homarr/db/schema";
|
||||||
import { createIntegrationAsync } from "@homarr/integrations";
|
import { createIntegrationAsync } from "@homarr/integrations";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { and, eq } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
|
import { and, eq } from "@homarr/db";
|
||||||
import { sectionCollapseStates, sections } from "@homarr/db/schema";
|
import { sectionCollapseStates, sections } from "@homarr/db/schema";
|
||||||
|
|
||||||
import { createTRPCRouter, protectedProcedure } from "../../trpc";
|
import { createTRPCRouter, protectedProcedure } from "../../trpc";
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import type { InferInsertModel } from "drizzle-orm";
|
|
||||||
import { and, eq, not } from "drizzle-orm";
|
|
||||||
import SuperJSON from "superjson";
|
import SuperJSON from "superjson";
|
||||||
import { describe, expect, it, test, vi } from "vitest";
|
import { describe, expect, it, test, vi } from "vitest";
|
||||||
|
|
||||||
import type { Session } from "@homarr/auth";
|
import type { Session } from "@homarr/auth";
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database, InferInsertModel } from "@homarr/db";
|
||||||
|
import { and, eq, not } from "@homarr/db";
|
||||||
import {
|
import {
|
||||||
boardGroupPermissions,
|
boardGroupPermissions,
|
||||||
boards,
|
boards,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { describe, expect, test, vi } from "vitest";
|
import { describe, expect, test, vi } from "vitest";
|
||||||
|
|
||||||
import * as authShared from "@homarr/auth/shared";
|
import * as authShared from "@homarr/auth/shared";
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
|
import { eq } from "@homarr/db";
|
||||||
import { boards, users } from "@homarr/db/schema";
|
import { boards, users } from "@homarr/db/schema";
|
||||||
import { createDb } from "@homarr/db/test";
|
import { createDb } from "@homarr/db/test";
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { describe, expect, test, vi } from "vitest";
|
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";
|
import * as env from "@homarr/auth/env";
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
|
import { eq } from "@homarr/db";
|
||||||
import { groupMembers, groupPermissions, groups, users } from "@homarr/db/schema";
|
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";
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { describe, expect, test, vi } from "vitest";
|
import { describe, expect, test, vi } from "vitest";
|
||||||
|
|
||||||
import * as authShared from "@homarr/auth/shared";
|
import * as authShared from "@homarr/auth/shared";
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
|
import { eq } from "@homarr/db";
|
||||||
import { integrations, users } from "@homarr/db/schema";
|
import { integrations, users } from "@homarr/db/schema";
|
||||||
import { createDb } from "@homarr/db/test";
|
import { createDb } from "@homarr/db/test";
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { describe, expect, it, test, vi } from "vitest";
|
import { describe, expect, it, test, vi } from "vitest";
|
||||||
|
|
||||||
import type { Session } from "@homarr/auth";
|
import type { Session } from "@homarr/auth";
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database } from "@homarr/db";
|
||||||
|
import { eq } from "@homarr/db";
|
||||||
import { invites, onboarding, users } from "@homarr/db/schema";
|
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";
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { and, eq, like } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import { createSaltAsync, hashPasswordAsync } from "@homarr/auth";
|
import { createSaltAsync, hashPasswordAsync } from "@homarr/auth";
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database } from "@homarr/db";
|
||||||
|
import { and, eq, like } from "@homarr/db";
|
||||||
import { getMaxGroupPositionAsync } from "@homarr/db/queries";
|
import { getMaxGroupPositionAsync } from "@homarr/db/queries";
|
||||||
import { boards, groupMembers, groupPermissions, groups, invites, users } from "@homarr/db/schema";
|
import { boards, groupMembers, groupPermissions, groups, invites, users } from "@homarr/db/schema";
|
||||||
import { selectUserSchema } from "@homarr/db/validationSchemas";
|
import { selectUserSchema } from "@homarr/db/validationSchemas";
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import type { Session } from "@homarr/auth";
|
import type { Session } from "@homarr/auth";
|
||||||
import type { Modify } from "@homarr/common/types";
|
import type { Modify } from "@homarr/common/types";
|
||||||
|
import { eq } from "@homarr/db";
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database } from "@homarr/db";
|
||||||
import { users } from "@homarr/db/schema";
|
import { users } from "@homarr/db/schema";
|
||||||
import { userChangeSearchPreferencesSchema } from "@homarr/validation/user";
|
import { userChangeSearchPreferencesSchema } from "@homarr/validation/user";
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import SuperJSON from "superjson";
|
import SuperJSON from "superjson";
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
|
import { eq } from "@homarr/db";
|
||||||
import { boards, items } from "@homarr/db/schema";
|
import { boards, items } from "@homarr/db/schema";
|
||||||
|
|
||||||
import { createTRPCRouter, protectedProcedure } from "../../trpc";
|
import { createTRPCRouter, protectedProcedure } from "../../trpc";
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type { Adapter } from "@auth/core/adapters";
|
import type { Adapter } from "@auth/core/adapters";
|
||||||
import { DrizzleAdapter } from "@auth/drizzle-adapter";
|
import { DrizzleAdapter } from "@auth/drizzle-adapter";
|
||||||
import { and, eq } from "drizzle-orm";
|
|
||||||
|
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database } from "@homarr/db";
|
||||||
|
import { and, eq } from "@homarr/db";
|
||||||
import { accounts, sessions, users } from "@homarr/db/schema";
|
import { accounts, sessions, users } from "@homarr/db/schema";
|
||||||
import type { SupportedAuthProvider } from "@homarr/definitions";
|
import type { SupportedAuthProvider } from "@homarr/definitions";
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { eq, inArray } from "drizzle-orm";
|
|
||||||
import type { NextAuthConfig } from "next-auth";
|
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 { groupMembers, groupPermissions, users } from "@homarr/db/schema";
|
import { groupMembers, groupPermissions, users } from "@homarr/db/schema";
|
||||||
import { getPermissionsWithChildren } from "@homarr/definitions";
|
import { getPermissionsWithChildren } from "@homarr/definitions";
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { cookies } from "next/headers";
|
import { cookies } from "next/headers";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { and, eq, inArray } from "drizzle-orm";
|
|
||||||
import type { NextAuthConfig } from "next-auth";
|
import type { NextAuthConfig } from "next-auth";
|
||||||
|
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
|
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";
|
import { groupMembers, groups, users } from "@homarr/db/schema";
|
||||||
import { colorSchemeCookieKey, everyoneGroup } from "@homarr/definitions";
|
import { colorSchemeCookieKey, everyoneGroup } from "@homarr/definitions";
|
||||||
|
|||||||
@@ -32,13 +32,12 @@
|
|||||||
"@homarr/validation": "workspace:^0.1.0",
|
"@homarr/validation": "workspace:^0.1.0",
|
||||||
"bcrypt": "^6.0.0",
|
"bcrypt": "^6.0.0",
|
||||||
"cookies": "^0.9.1",
|
"cookies": "^0.9.1",
|
||||||
"drizzle-orm": "^0.45.1",
|
"ldapts": "8.0.23",
|
||||||
"ldapts": "8.0.24",
|
|
||||||
"next": "16.0.10",
|
"next": "16.0.10",
|
||||||
"next-auth": "5.0.0-beta.30",
|
"next-auth": "5.0.0-beta.30",
|
||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"react-dom": "19.2.3",
|
"react-dom": "19.2.3",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { and, eq, inArray, or } from "drizzle-orm";
|
|
||||||
import type { Session } from "next-auth";
|
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 { boards, boardUserPermissions, groupMembers } from "@homarr/db/schema";
|
import { boards, boardUserPermissions, groupMembers } from "@homarr/db/schema";
|
||||||
import type { IntegrationPermission } from "@homarr/definitions";
|
import type { IntegrationPermission } from "@homarr/definitions";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { eq, inArray } from "drizzle-orm";
|
|
||||||
import type { Session } from "next-auth";
|
import type { Session } from "next-auth";
|
||||||
|
|
||||||
import { db } from "@homarr/db";
|
import { db, eq, inArray } from "@homarr/db";
|
||||||
import { groupMembers, integrationGroupPermissions, integrationUserPermissions } from "@homarr/db/schema";
|
import { groupMembers, integrationGroupPermissions, integrationUserPermissions } from "@homarr/db/schema";
|
||||||
|
|
||||||
import { constructIntegrationPermissions } from "./integration-permissions";
|
import { constructIntegrationPermissions } from "./integration-permissions";
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type { InferInsertModel } from "drizzle-orm";
|
|
||||||
import type { Session } from "next-auth";
|
import type { Session } from "next-auth";
|
||||||
import { describe, expect, test, vi } from "vitest";
|
import { describe, expect, test, vi } from "vitest";
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
|
import type { InferInsertModel } from "@homarr/db";
|
||||||
import { boardGroupPermissions, boards, boardUserPermissions, groupMembers, groups, users } from "@homarr/db/schema";
|
import { boardGroupPermissions, boards, boardUserPermissions, groupMembers, groups, users } from "@homarr/db/schema";
|
||||||
import { createDb } from "@homarr/db/test";
|
import { createDb } from "@homarr/db/test";
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import bcrypt from "bcrypt";
|
import bcrypt from "bcrypt";
|
||||||
import { and, eq } from "drizzle-orm";
|
|
||||||
import type { z } from "zod/v4";
|
import type { z } from "zod/v4";
|
||||||
|
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database } from "@homarr/db";
|
||||||
|
import { and, eq } from "@homarr/db";
|
||||||
import { users } from "@homarr/db/schema";
|
import { users } from "@homarr/db/schema";
|
||||||
import type { userSignInSchema } from "@homarr/validation/user";
|
import type { userSignInSchema } from "@homarr/validation/user";
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { CredentialsSignin } from "@auth/core/errors";
|
import { CredentialsSignin } from "@auth/core/errors";
|
||||||
import { and, eq } from "drizzle-orm";
|
|
||||||
import type { InferInsertModel } from "drizzle-orm";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database, InferInsertModel } from "@homarr/db";
|
||||||
|
import { and, eq } from "@homarr/db";
|
||||||
import { users } from "@homarr/db/schema";
|
import { users } from "@homarr/db/schema";
|
||||||
import type { ldapSignInSchema } from "@homarr/validation/user";
|
import type { ldapSignInSchema } from "@homarr/validation/user";
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { CredentialsSignin } from "@auth/core/errors";
|
import { CredentialsSignin } from "@auth/core/errors";
|
||||||
import { and, eq } from "drizzle-orm";
|
|
||||||
import { describe, expect, test, vi } from "vitest";
|
import { describe, expect, test, vi } from "vitest";
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database } from "@homarr/db";
|
||||||
|
import { and, eq } from "@homarr/db";
|
||||||
import { groups, users } from "@homarr/db/schema";
|
import { groups, users } from "@homarr/db/schema";
|
||||||
import { createDb } from "@homarr/db/test";
|
import { createDb } from "@homarr/db/test";
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { ResponseCookie } from "next/dist/compiled/@edge-runtime/cookies";
|
import type { ResponseCookie } from "next/dist/compiled/@edge-runtime/cookies";
|
||||||
import type { ReadonlyRequestCookies } from "next/dist/server/web/spec-extension/adapters/request-cookies";
|
import type { ReadonlyRequestCookies } from "next/dist/server/web/spec-extension/adapters/request-cookies";
|
||||||
import { cookies } from "next/headers";
|
import { cookies } from "next/headers";
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { describe, expect, test, vi } from "vitest";
|
import { describe, expect, test, vi } from "vitest";
|
||||||
|
|
||||||
|
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";
|
import { groupMembers, groups, users } from "@homarr/db/schema";
|
||||||
import { createDb } from "@homarr/db/test";
|
import { createDb } from "@homarr/db/test";
|
||||||
|
|||||||
@@ -28,8 +28,7 @@
|
|||||||
"@homarr/common": "workspace:^0.1.0",
|
"@homarr/common": "workspace:^0.1.0",
|
||||||
"@homarr/db": "workspace:^0.1.0",
|
"@homarr/db": "workspace:^0.1.0",
|
||||||
"@homarr/validation": "workspace:^0.1.0",
|
"@homarr/validation": "workspace:^0.1.0",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3"
|
||||||
"drizzle-orm": "^0.45.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { command } from "@drizzle-team/brocli";
|
import { command } from "@drizzle-team/brocli";
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { db } from "@homarr/db";
|
import { db, eq } from "@homarr/db";
|
||||||
import { users } from "@homarr/db/schema";
|
import { users } from "@homarr/db/schema";
|
||||||
|
|
||||||
export const fixUsernames = command({
|
export const fixUsernames = command({
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { command, string } from "@drizzle-team/brocli";
|
import { command, string } from "@drizzle-team/brocli";
|
||||||
import { and, count, eq } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { createSaltAsync, hashPasswordAsync } from "@homarr/auth";
|
import { createSaltAsync, hashPasswordAsync } from "@homarr/auth";
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import { generateSecureRandomToken } from "@homarr/common/server";
|
import { generateSecureRandomToken } from "@homarr/common/server";
|
||||||
import { db } from "@homarr/db";
|
import { and, count, db, eq } from "@homarr/db";
|
||||||
import { getMaxGroupPositionAsync } from "@homarr/db/queries";
|
import { getMaxGroupPositionAsync } from "@homarr/db/queries";
|
||||||
import { groupMembers, groupPermissions, groups, users } from "@homarr/db/schema";
|
import { groupMembers, groupPermissions, groups, users } from "@homarr/db/schema";
|
||||||
import { usernameSchema } from "@homarr/validation/user";
|
import { usernameSchema } from "@homarr/validation/user";
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { command, string } from "@drizzle-team/brocli";
|
import { command, string } from "@drizzle-team/brocli";
|
||||||
import { and, eq } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { hashPasswordAsync } from "@homarr/auth";
|
import { hashPasswordAsync } from "@homarr/auth";
|
||||||
import { generateSecureRandomToken } from "@homarr/common/server";
|
import { generateSecureRandomToken } from "@homarr/common/server";
|
||||||
import { db } from "@homarr/db";
|
import { and, db, eq } from "@homarr/db";
|
||||||
import { sessions, users } from "@homarr/db/schema";
|
import { sessions, users } from "@homarr/db/schema";
|
||||||
|
|
||||||
export const resetPassword = command({
|
export const resetPassword = command({
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"react-dom": "19.2.3",
|
"react-dom": "19.2.3",
|
||||||
"undici": "7.16.0",
|
"undici": "7.16.0",
|
||||||
"zod": "^4.2.0",
|
"zod": "^4.1.13",
|
||||||
"zod-validation-error": "^5.0.0"
|
"zod-validation-error": "^5.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -37,8 +37,8 @@
|
|||||||
},
|
},
|
||||||
"prettier": "@homarr/prettier-config",
|
"prettier": "@homarr/prettier-config",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@t3-oss/env-nextjs": "^0.13.10",
|
"@libsql/client": "^0.15.15",
|
||||||
"better-sqlite3": "^12.5.0",
|
"@t3-oss/env-nextjs": "^0.13.8",
|
||||||
"dns-caching": "^0.2.9",
|
"dns-caching": "^0.2.9",
|
||||||
"drizzle-orm": "^0.45.1",
|
"drizzle-orm": "^0.45.1",
|
||||||
"ioredis": "5.8.2",
|
"ioredis": "5.8.2",
|
||||||
@@ -46,13 +46,12 @@
|
|||||||
"pg": "^8.16.3",
|
"pg": "^8.16.3",
|
||||||
"superjson": "2.2.6",
|
"superjson": "2.2.6",
|
||||||
"winston": "3.19.0",
|
"winston": "3.19.0",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
"@homarr/prettier-config": "workspace:^0.1.0",
|
"@homarr/prettier-config": "workspace:^0.1.0",
|
||||||
"@homarr/tsconfig": "workspace:^0.1.0",
|
"@homarr/tsconfig": "workspace:^0.1.0",
|
||||||
"@types/better-sqlite3": "7.6.13",
|
|
||||||
"@types/pg": "^8.16.0",
|
"@types/pg": "^8.16.0",
|
||||||
"eslint": "^9.39.2",
|
"eslint": "^9.39.2",
|
||||||
"typescript": "^5.9.3"
|
"typescript": "^5.9.3"
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import Database from "better-sqlite3";
|
import { createClient } from "@libsql/client";
|
||||||
import { drizzle as drizzleSqlite } from "drizzle-orm/better-sqlite3";
|
import { drizzle as drizzleSqlite } from "drizzle-orm/libsql";
|
||||||
|
|
||||||
import { dbEnv } from "../env";
|
import { dbEnv } from "../env";
|
||||||
import type { SharedDrizzleConfig } from "./shared";
|
import type { SharedDrizzleConfig } from "./shared";
|
||||||
|
|
||||||
export const createSqliteDb = <TSchema extends Record<string, unknown>>(config: SharedDrizzleConfig<TSchema>) => {
|
export const createSqliteDb = <TSchema extends Record<string, unknown>>(config: SharedDrizzleConfig<TSchema>) => {
|
||||||
const connection = new Database(dbEnv.URL);
|
const client = createClient({ url: `file:${dbEnv.URL}` });
|
||||||
return drizzleSqlite<TSchema>(connection, config);
|
return drizzleSqlite<TSchema>(client, config);
|
||||||
};
|
};
|
||||||
@@ -2,7 +2,7 @@ import { createBooleanSchema, createEnv } from "../env";
|
|||||||
|
|
||||||
export const dnsEnv = createEnv({
|
export const dnsEnv = createEnv({
|
||||||
server: {
|
server: {
|
||||||
ENABLE_DNS_CACHING: createBooleanSchema(true),
|
ENABLE_DNS_CACHING: createBooleanSchema(false),
|
||||||
},
|
},
|
||||||
experimental__runtimeEnv: process.env,
|
experimental__runtimeEnv: process.env,
|
||||||
});
|
});
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
"@trpc/tanstack-react-query": "^11.8.0",
|
"@trpc/tanstack-react-query": "^11.8.0",
|
||||||
"node-cron": "^4.2.1",
|
"node-cron": "^4.2.1",
|
||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -38,7 +38,6 @@
|
|||||||
"@homarr/server-settings": "workspace:^0.1.0",
|
"@homarr/server-settings": "workspace:^0.1.0",
|
||||||
"@homarr/translation": "workspace:^0.1.0",
|
"@homarr/translation": "workspace:^0.1.0",
|
||||||
"@homarr/validation": "workspace:^0.1.0",
|
"@homarr/validation": "workspace:^0.1.0",
|
||||||
"drizzle-orm": "^0.45.1",
|
|
||||||
"semver-parser": "^4.1.8"
|
"semver-parser": "^4.1.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
import SuperJSON from "superjson";
|
import SuperJSON from "superjson";
|
||||||
|
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
import { ErrorWithMetadata } from "@homarr/core/infrastructure/logs/error";
|
import { ErrorWithMetadata } from "@homarr/core/infrastructure/logs/error";
|
||||||
import { EVERY_MINUTE } from "@homarr/cron-jobs-core/expressions";
|
import { EVERY_MINUTE } from "@homarr/cron-jobs-core/expressions";
|
||||||
import { db } from "@homarr/db";
|
import { db, eq } from "@homarr/db";
|
||||||
import { items } from "@homarr/db/schema";
|
import { items } from "@homarr/db/schema";
|
||||||
import { dockerContainersRequestHandler } from "@homarr/request-handler/docker";
|
import { dockerContainersRequestHandler } from "@homarr/request-handler/docker";
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import type { InferInsertModel } from "drizzle-orm";
|
|
||||||
import { inArray, sql } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { createId, splitToNChunks, Stopwatch } from "@homarr/common";
|
import { createId, splitToNChunks, Stopwatch } from "@homarr/common";
|
||||||
import { env } from "@homarr/common/env";
|
import { env } from "@homarr/common/env";
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
import { EVERY_WEEK } from "@homarr/cron-jobs-core/expressions";
|
import { EVERY_WEEK } from "@homarr/cron-jobs-core/expressions";
|
||||||
import { db, handleTransactionsAsync } from "@homarr/db";
|
import type { InferInsertModel } from "@homarr/db";
|
||||||
|
import { db, handleTransactionsAsync, inArray, sql } from "@homarr/db";
|
||||||
import { iconRepositories, icons } from "@homarr/db/schema";
|
import { iconRepositories, icons } from "@homarr/db/schema";
|
||||||
import { fetchIconsAsync } from "@homarr/icons";
|
import { fetchIconsAsync } from "@homarr/icons";
|
||||||
|
|
||||||
@@ -123,46 +121,6 @@ export const iconsUpdaterJob = createCronJob("iconsUpdater", EVERY_WEEK, {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
countDeleted += deadIcons.length;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleSync() {
|
|
||||||
db.transaction((transaction) => {
|
|
||||||
if (newIconRepositories.length >= 1) {
|
|
||||||
transaction.insert(iconRepositories).values(newIconRepositories).run();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newIcons.length >= 1) {
|
|
||||||
// We only insert 5000 icons at a time to avoid SQLite limitations
|
|
||||||
for (const chunck of splitToNChunks(newIcons, Math.ceil(newIcons.length / 5000))) {
|
|
||||||
transaction.insert(icons).values(chunck).run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (deadIcons.length >= 1) {
|
|
||||||
transaction
|
|
||||||
.delete(icons)
|
|
||||||
.where(
|
|
||||||
inArray(
|
|
||||||
// Combine iconRepositoryId and checksum to allow same icons on different repositories
|
|
||||||
sql`concat(${icons.iconRepositoryId}, '.', ${icons.checksum})`,
|
|
||||||
deadIcons.map((icon) => `${icon.iconRepositoryId}.${icon.checksum}`),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deadIconRepositories.length >= 1) {
|
|
||||||
transaction
|
|
||||||
.delete(iconRepositories)
|
|
||||||
.where(
|
|
||||||
inArray(
|
|
||||||
iconRepositories.id,
|
|
||||||
deadIconRepositories.map((iconRepository) => iconRepository.id),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
countDeleted += deadIcons.length;
|
countDeleted += deadIcons.length;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
import SuperJSON from "superjson";
|
import SuperJSON from "superjson";
|
||||||
|
|
||||||
import { EVERY_5_MINUTES } from "@homarr/cron-jobs-core/expressions";
|
import { EVERY_5_MINUTES } from "@homarr/cron-jobs-core/expressions";
|
||||||
import { db } from "@homarr/db";
|
import { db, eq } from "@homarr/db";
|
||||||
import { items } from "@homarr/db/schema";
|
import { items } from "@homarr/db/schema";
|
||||||
import { minecraftServerStatusRequestHandler } from "@homarr/request-handler/minecraft-server-status";
|
import { minecraftServerStatusRequestHandler } from "@homarr/request-handler/minecraft-server-status";
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
import SuperJSON from "superjson";
|
import SuperJSON from "superjson";
|
||||||
|
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
import { ErrorWithMetadata } from "@homarr/core/infrastructure/logs/error";
|
import { ErrorWithMetadata } from "@homarr/core/infrastructure/logs/error";
|
||||||
import { EVERY_10_MINUTES } from "@homarr/cron-jobs-core/expressions";
|
import { EVERY_10_MINUTES } from "@homarr/cron-jobs-core/expressions";
|
||||||
import { db } from "@homarr/db";
|
import { db, eq } from "@homarr/db";
|
||||||
import { items } from "@homarr/db/schema";
|
import { items } from "@homarr/db/schema";
|
||||||
// This import is done that way to avoid circular dependencies.
|
// This import is done that way to avoid circular dependencies.
|
||||||
import { rssFeedsRequestHandler } from "@homarr/request-handler/rss-feeds";
|
import { rssFeedsRequestHandler } from "@homarr/request-handler/rss-feeds";
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
import SuperJSON from "superjson";
|
import SuperJSON from "superjson";
|
||||||
|
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
import { ErrorWithMetadata } from "@homarr/core/infrastructure/logs/error";
|
import { ErrorWithMetadata } from "@homarr/core/infrastructure/logs/error";
|
||||||
import { EVERY_10_MINUTES } from "@homarr/cron-jobs-core/expressions";
|
import { EVERY_10_MINUTES } from "@homarr/cron-jobs-core/expressions";
|
||||||
import { db } from "@homarr/db";
|
import { db, eq } from "@homarr/db";
|
||||||
import { items } from "@homarr/db/schema";
|
import { items } from "@homarr/db/schema";
|
||||||
import { weatherRequestHandler } from "@homarr/request-handler/weather";
|
import { weatherRequestHandler } from "@homarr/request-handler/weather";
|
||||||
|
|
||||||
|
|||||||
@@ -31,20 +31,8 @@ export const createDbInsertCollectionForTransaction = <TTableKey extends TableKe
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...context,
|
...context,
|
||||||
insertAll: (db: HomarrDatabase) => {
|
|
||||||
db.transaction((transaction) => {
|
|
||||||
for (const [key, values] of objectEntries(context)) {
|
|
||||||
if (values.length >= 1) {
|
|
||||||
transaction
|
|
||||||
.insert(schema[key])
|
|
||||||
.values(values as never)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// We allow any database that supports async passed here but then fallback to mysql to prevent typescript errors
|
// We allow any database that supports async passed here but then fallback to mysql to prevent typescript errors
|
||||||
insertAllAsync: async (db: HomarrDatabaseMysql | HomarrDatabasePostgresql) => {
|
insertAllAsync: async (db: HomarrDatabaseMysql | HomarrDatabasePostgresql | HomarrDatabase) => {
|
||||||
const innerDb = db as HomarrDatabaseMysql;
|
const innerDb = db as HomarrDatabaseMysql;
|
||||||
await innerDb.transaction(async (transaction) => {
|
await innerDb.transaction(async (transaction) => {
|
||||||
for (const [key, values] of objectEntries(context)) {
|
for (const [key, values] of objectEntries(context)) {
|
||||||
@@ -61,7 +49,7 @@ export const createDbInsertCollectionForTransaction = <TTableKey extends TableKe
|
|||||||
export const createDbInsertCollectionWithoutTransaction = <TTableKey extends TableKey>(
|
export const createDbInsertCollectionWithoutTransaction = <TTableKey extends TableKey>(
|
||||||
tablesInInsertOrder: TTableKey[],
|
tablesInInsertOrder: TTableKey[],
|
||||||
) => {
|
) => {
|
||||||
const { insertAll, insertAllAsync, ...collection } = createDbInsertCollectionForTransaction(tablesInInsertOrder);
|
const { insertAllAsync, ...collection } = createDbInsertCollectionForTransaction(tablesInInsertOrder);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...collection,
|
...collection,
|
||||||
@@ -75,7 +63,7 @@ export const createDbInsertCollectionWithoutTransaction = <TTableKey extends Tab
|
|||||||
default:
|
default:
|
||||||
// For better-sqlite3, we need to use the synchronous insertAll method
|
// For better-sqlite3, we need to use the synchronous insertAll method
|
||||||
// default assumes better-sqlite3. It's original implementation.
|
// default assumes better-sqlite3. It's original implementation.
|
||||||
insertAll(db);
|
await insertAllAsync(db);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
|
import type { LibSQLDatabase } from "drizzle-orm/libsql";
|
||||||
import type { MySql2Database } from "drizzle-orm/mysql2";
|
import type { MySql2Database } from "drizzle-orm/mysql2";
|
||||||
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
|
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
|
||||||
|
|
||||||
@@ -6,6 +6,6 @@ import type * as mysqlSchema from "./schema/mysql";
|
|||||||
import type * as pgSchema from "./schema/postgresql";
|
import type * as pgSchema from "./schema/postgresql";
|
||||||
import type * as sqliteSchema from "./schema/sqlite";
|
import type * as sqliteSchema from "./schema/sqlite";
|
||||||
|
|
||||||
export type HomarrDatabase = BetterSQLite3Database<typeof sqliteSchema>;
|
export type HomarrDatabase = LibSQLDatabase<typeof sqliteSchema>;
|
||||||
export type HomarrDatabaseMysql = MySql2Database<typeof mysqlSchema>;
|
export type HomarrDatabaseMysql = MySql2Database<typeof mysqlSchema>;
|
||||||
export type HomarrDatabasePostgresql = NodePgDatabase<typeof pgSchema>;
|
export type HomarrDatabasePostgresql = NodePgDatabase<typeof pgSchema>;
|
||||||
@@ -2,6 +2,7 @@ import { createDb } from "@homarr/core/infrastructure/db";
|
|||||||
|
|
||||||
import { schema } from "./schema";
|
import { schema } from "./schema";
|
||||||
|
|
||||||
|
export * from "drizzle-orm";
|
||||||
export type { HomarrDatabaseMysql, HomarrDatabasePostgresql } from "./driver";
|
export type { HomarrDatabaseMysql, HomarrDatabasePostgresql } from "./driver";
|
||||||
|
|
||||||
export const db = createDb(schema);
|
export const db = createDb(schema);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
import SuperJSON from "superjson";
|
import SuperJSON from "superjson";
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import type { IntegrationKind } from "@homarr/definitions";
|
import type { IntegrationKind } from "@homarr/definitions";
|
||||||
import { getIntegrationKindsByCategory } from "@homarr/definitions";
|
import { getIntegrationKindsByCategory } from "@homarr/definitions";
|
||||||
|
|
||||||
|
import { eq } from "../..";
|
||||||
import type { Database } from "../..";
|
import type { Database } from "../..";
|
||||||
import { items } from "../../schema";
|
import { items } from "../../schema";
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { and, eq } from "drizzle-orm";
|
|
||||||
|
|
||||||
import type { Database } from "../..";
|
import type { Database } from "../..";
|
||||||
|
import { and, eq } from "../..";
|
||||||
import { integrationSecrets } from "../../schema";
|
import { integrationSecrets } from "../../schema";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
import SuperJSON from "superjson";
|
import SuperJSON from "superjson";
|
||||||
|
|
||||||
|
import { eq } from "../..";
|
||||||
import type { Database } from "../..";
|
import type { Database } from "../..";
|
||||||
import { items } from "../../schema";
|
import { items } from "../../schema";
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { createId, objectKeys } from "@homarr/common";
|
import { createId, objectKeys } from "@homarr/common";
|
||||||
import {
|
import {
|
||||||
createDocumentationLink,
|
createDocumentationLink,
|
||||||
@@ -11,6 +9,7 @@ import {
|
|||||||
import { defaultServerSettings, defaultServerSettingsKeys } from "@homarr/server-settings";
|
import { defaultServerSettings, defaultServerSettingsKeys } from "@homarr/server-settings";
|
||||||
|
|
||||||
import type { Database } from "..";
|
import type { Database } from "..";
|
||||||
|
import { eq } from "..";
|
||||||
import {
|
import {
|
||||||
getServerSettingByKeyAsync,
|
getServerSettingByKeyAsync,
|
||||||
insertServerSettingByKeyAsync,
|
insertServerSettingByKeyAsync,
|
||||||
|
|||||||
@@ -51,7 +51,6 @@
|
|||||||
"@paralleldrive/cuid2": "^3.1.0",
|
"@paralleldrive/cuid2": "^3.1.0",
|
||||||
"@testcontainers/mysql": "^11.10.0",
|
"@testcontainers/mysql": "^11.10.0",
|
||||||
"@testcontainers/postgresql": "^11.10.0",
|
"@testcontainers/postgresql": "^11.10.0",
|
||||||
"better-sqlite3": "^12.5.0",
|
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"drizzle-kit": "^0.31.8",
|
"drizzle-kit": "^0.31.8",
|
||||||
"drizzle-orm": "^0.45.1",
|
"drizzle-orm": "^0.45.1",
|
||||||
@@ -64,7 +63,6 @@
|
|||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
"@homarr/prettier-config": "workspace:^0.1.0",
|
"@homarr/prettier-config": "workspace:^0.1.0",
|
||||||
"@homarr/tsconfig": "workspace:^0.1.0",
|
"@homarr/tsconfig": "workspace:^0.1.0",
|
||||||
"@types/better-sqlite3": "7.6.13",
|
|
||||||
"@types/pg": "^8.16.0",
|
"@types/pg": "^8.16.0",
|
||||||
"dotenv-cli": "^11.0.0",
|
"dotenv-cli": "^11.0.0",
|
||||||
"esbuild": "^0.27.1",
|
"esbuild": "^0.27.1",
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { inArray } from "drizzle-orm";
|
|
||||||
|
|
||||||
import type { WidgetKind } from "@homarr/definitions";
|
import type { WidgetKind } from "@homarr/definitions";
|
||||||
|
|
||||||
import type { Database } from "..";
|
import type { Database } from "..";
|
||||||
|
import { inArray } from "..";
|
||||||
import type { inferSupportedIntegrations } from "../../widgets/src";
|
import type { inferSupportedIntegrations } from "../../widgets/src";
|
||||||
import { items } from "../schema";
|
import { items } from "../schema";
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { eq } from "drizzle-orm";
|
|
||||||
import SuperJSON from "superjson";
|
import SuperJSON from "superjson";
|
||||||
|
|
||||||
import type { ServerSettings } from "@homarr/server-settings";
|
import type { ServerSettings } from "@homarr/server-settings";
|
||||||
import { defaultServerSettings, defaultServerSettingsKeys } from "@homarr/server-settings";
|
import { defaultServerSettings, defaultServerSettingsKeys } from "@homarr/server-settings";
|
||||||
|
|
||||||
import type { Database } from "..";
|
import type { Database } from "..";
|
||||||
|
import { eq } from "..";
|
||||||
import { serverSettings } from "../schema";
|
import { serverSettings } from "../schema";
|
||||||
|
|
||||||
export const getServerSettingsAsync = async (db: Database) => {
|
export const getServerSettingsAsync = async (db: Database) => {
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import Database from "better-sqlite3";
|
import { createClient } from "@libsql/client";
|
||||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
import { drizzle } from "drizzle-orm/libsql";
|
||||||
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
|
import { migrate } from "drizzle-orm/libsql/migrator";
|
||||||
|
|
||||||
import { DB_CASING } from "@homarr/core/infrastructure/db/constants";
|
import { DB_CASING } from "@homarr/core/infrastructure/db/constants";
|
||||||
|
|
||||||
import * as sqliteSchema from "../schema/sqlite";
|
import * as sqliteSchema from "../schema/sqlite";
|
||||||
|
|
||||||
export const createDb = (debug?: boolean) => {
|
export const createDb = (debug?: boolean) => {
|
||||||
const sqlite = new Database(":memory:");
|
const sqlite = createClient({ url: ":memory:" });
|
||||||
const db = drizzle(sqlite, { schema: sqliteSchema, logger: debug, casing: DB_CASING });
|
const db = drizzle(sqlite, { schema: sqliteSchema, logger: debug, casing: DB_CASING });
|
||||||
migrate(db, {
|
// TODO: Make async and awaitable
|
||||||
|
void migrate(db, {
|
||||||
migrationsFolder: "./packages/db/migrations/sqlite",
|
migrationsFolder: "./packages/db/migrations/sqlite",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import { isMysql, isPostgresql } from "./collection";
|
|
||||||
import type { HomarrDatabase, HomarrDatabaseMysql } from "./driver";
|
import type { HomarrDatabase, HomarrDatabaseMysql } from "./driver";
|
||||||
import type { MySqlSchema } from "./schema";
|
import type { MySqlSchema } from "./schema";
|
||||||
import * as schema from "./schema";
|
import * as schema from "./schema";
|
||||||
|
|
||||||
interface HandleTransactionInput {
|
interface HandleTransactionInput {
|
||||||
handleAsync: (db: HomarrDatabaseMysql, schema: MySqlSchema) => Promise<void>;
|
handleAsync: (db: HomarrDatabaseMysql, schema: MySqlSchema) => Promise<void>;
|
||||||
handleSync: (db: HomarrDatabase) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,10 +12,5 @@ interface HandleTransactionInput {
|
|||||||
* But it can also generally be used when dealing with different database drivers.
|
* But it can also generally be used when dealing with different database drivers.
|
||||||
*/
|
*/
|
||||||
export const handleDiffrentDbDriverOperationsAsync = async (db: HomarrDatabase, input: HandleTransactionInput) => {
|
export const handleDiffrentDbDriverOperationsAsync = async (db: HomarrDatabase, input: HandleTransactionInput) => {
|
||||||
if (isMysql() || isPostgresql()) {
|
|
||||||
// Schema type is always the correct one based on env variables
|
|
||||||
await input.handleAsync(db as unknown as HomarrDatabaseMysql, schema as unknown as MySqlSchema);
|
await input.handleAsync(db as unknown as HomarrDatabaseMysql, schema as unknown as MySqlSchema);
|
||||||
} else {
|
|
||||||
input.handleSync(db);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@homarr/common": "workspace:^0.1.0",
|
"@homarr/common": "workspace:^0.1.0",
|
||||||
"fast-xml-parser": "^5.3.3",
|
"fast-xml-parser": "^5.3.3",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
"@homarr/validation": "workspace:^0.1.0",
|
"@homarr/validation": "workspace:^0.1.0",
|
||||||
"@mantine/form": "^8.3.10",
|
"@mantine/form": "^8.3.10",
|
||||||
"mantine-form-zod-resolver": "^1.3.0",
|
"mantine-form-zod-resolver": "^1.3.0",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
"@homarr/validation": "workspace:^0.1.0",
|
"@homarr/validation": "workspace:^0.1.0",
|
||||||
"@mantine/core": "^8.3.10",
|
"@mantine/core": "^8.3.10",
|
||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -25,8 +25,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@homarr/common": "workspace:^0.1.0",
|
"@homarr/common": "workspace:^0.1.0",
|
||||||
"@homarr/core": "workspace:^0.1.0",
|
"@homarr/core": "workspace:^0.1.0",
|
||||||
"@homarr/db": "workspace:^0.1.0",
|
"@homarr/db": "workspace:^0.1.0"
|
||||||
"drizzle-orm": "^0.45.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { like } from "drizzle-orm";
|
|
||||||
|
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database } from "@homarr/db";
|
||||||
|
import { like } from "@homarr/db";
|
||||||
import { icons } from "@homarr/db/schema";
|
import { icons } from "@homarr/db/schema";
|
||||||
|
|
||||||
export const getIconForName = (db: Database, name: string) => {
|
export const getIconForNameAsync = async (db: Database, name: string) => {
|
||||||
return db.query.icons.findFirst({
|
return await db.query.icons.findFirst({
|
||||||
where: like(icons.name, `%${name}%`),
|
where: like(icons.name, `%${name}%`),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { createHash } from "crypto";
|
import { createHash } from "crypto";
|
||||||
import type { InferSelectModel } from "drizzle-orm";
|
|
||||||
|
|
||||||
|
import type { InferSelectModel } from "@homarr/db";
|
||||||
import { db } from "@homarr/db";
|
import { db } from "@homarr/db";
|
||||||
import type { medias } from "@homarr/db/schema";
|
import type { medias } from "@homarr/db/schema";
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"tsdav": "^2.1.6",
|
"tsdav": "^2.1.6",
|
||||||
"undici": "7.16.0",
|
"undici": "7.16.0",
|
||||||
"xml2js": "^0.6.2",
|
"xml2js": "^0.6.2",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
"next": "16.0.10",
|
"next": "16.0.10",
|
||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"react-dom": "19.2.3",
|
"react-dom": "19.2.3",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -40,12 +40,11 @@
|
|||||||
"@mantine/core": "^8.3.10",
|
"@mantine/core": "^8.3.10",
|
||||||
"@mantine/hooks": "^8.3.10",
|
"@mantine/hooks": "^8.3.10",
|
||||||
"adm-zip": "0.5.16",
|
"adm-zip": "0.5.16",
|
||||||
"drizzle-orm": "^0.45.1",
|
|
||||||
"next": "16.0.10",
|
"next": "16.0.10",
|
||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"react-dom": "19.2.3",
|
"react-dom": "19.2.3",
|
||||||
"superjson": "2.2.6",
|
"superjson": "2.2.6",
|
||||||
"zod": "^4.2.0",
|
"zod": "^4.1.13",
|
||||||
"zod-form-data": "^3.0.1"
|
"zod-form-data": "^3.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -45,13 +45,6 @@ export const importInitialOldmarrAsync = async (
|
|||||||
await integrationInsertCollection.insertAllAsync(transaction);
|
await integrationInsertCollection.insertAllAsync(transaction);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleSync(db) {
|
|
||||||
db.transaction((transaction) => {
|
|
||||||
boardInsertCollection.insertAll(transaction);
|
|
||||||
userInsertCollection.insertAll(transaction);
|
|
||||||
integrationInsertCollection.insertAll(transaction);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.info("Import successful", { duration: stopwatch.getElapsedInHumanWords() });
|
logger.info("Import successful", { duration: stopwatch.getElapsedInHumanWords() });
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import { inArray } from "drizzle-orm";
|
import { handleTransactionsAsync, inArray } from "@homarr/db";
|
||||||
|
|
||||||
import { handleTransactionsAsync } from "@homarr/db";
|
|
||||||
import type { Database } from "@homarr/db";
|
import type { Database } from "@homarr/db";
|
||||||
import { apps } from "@homarr/db/schema";
|
import { apps } from "@homarr/db/schema";
|
||||||
import type { OldmarrConfig } from "@homarr/old-schema";
|
import type { OldmarrConfig } from "@homarr/old-schema";
|
||||||
@@ -37,8 +35,5 @@ export const importSingleOldmarrConfigAsync = async (
|
|||||||
async handleAsync(db) {
|
async handleAsync(db) {
|
||||||
await boardInsertCollection.insertAllAsync(db);
|
await boardInsertCollection.insertAllAsync(db);
|
||||||
},
|
},
|
||||||
handleSync(db) {
|
|
||||||
boardInsertCollection.insertAll(db);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import type { InferSelectModel } from "drizzle-orm";
|
import type { InferSelectModel } from "@homarr/db";
|
||||||
|
|
||||||
import type { apps } from "@homarr/db/schema";
|
import type { apps } from "@homarr/db/schema";
|
||||||
import type { OldmarrApp } from "@homarr/old-schema";
|
import type { OldmarrApp } from "@homarr/old-schema";
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { InferInsertModel } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
|
import type { InferInsertModel } from "@homarr/db";
|
||||||
import type { boards } from "@homarr/db/schema";
|
import type { boards } from "@homarr/db/schema";
|
||||||
|
|
||||||
import type { prepareMultipleImports } from "../prepare/prepare-multiple";
|
import type { prepareMultipleImports } from "../prepare/prepare-multiple";
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type { InferInsertModel } from "drizzle-orm";
|
|
||||||
import SuperJSON from "superjson";
|
import SuperJSON from "superjson";
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||||
|
import type { InferInsertModel } from "@homarr/db";
|
||||||
import type { itemLayouts, items } from "@homarr/db/schema";
|
import type { itemLayouts, items } from "@homarr/db/schema";
|
||||||
import type { BoardSize, OldmarrApp, OldmarrWidget } from "@homarr/old-schema";
|
import type { BoardSize, OldmarrApp, OldmarrWidget } from "@homarr/old-schema";
|
||||||
import { boardSizes } from "@homarr/old-schema";
|
import { boardSizes } from "@homarr/old-schema";
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { InferInsertModel } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
|
import type { InferInsertModel } from "@homarr/db";
|
||||||
import type { sections } from "@homarr/db/schema";
|
import type { sections } from "@homarr/db/schema";
|
||||||
import type { OldmarrCategorySection, OldmarrEmptySection } from "@homarr/old-schema";
|
import type { OldmarrCategorySection, OldmarrEmptySection } from "@homarr/old-schema";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { InferInsertModel } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { createId } from "@homarr/common";
|
import { createId } from "@homarr/common";
|
||||||
import { decryptSecretWithKey } from "@homarr/common/server";
|
import { decryptSecretWithKey } from "@homarr/common/server";
|
||||||
|
import type { InferInsertModel } from "@homarr/db";
|
||||||
import type { users } from "@homarr/db/schema";
|
import type { users } from "@homarr/db/schema";
|
||||||
|
|
||||||
import type { OldmarrImportUser } from "../user-schema";
|
import type { OldmarrImportUser } from "../user-schema";
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import type { InferSelectModel } from "drizzle-orm";
|
import type { InferSelectModel } from "@homarr/db";
|
||||||
|
|
||||||
import type { apps } from "@homarr/db/schema";
|
import type { apps } from "@homarr/db/schema";
|
||||||
import type { OldmarrConfig } from "@homarr/old-schema";
|
import type { OldmarrConfig } from "@homarr/old-schema";
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"prettier": "@homarr/prettier-config",
|
"prettier": "@homarr/prettier-config",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@homarr/common": "workspace:^0.1.0",
|
"@homarr/common": "workspace:^0.1.0",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -31,11 +31,10 @@
|
|||||||
"@homarr/integrations": "workspace:^0.1.0",
|
"@homarr/integrations": "workspace:^0.1.0",
|
||||||
"@homarr/redis": "workspace:^0.1.0",
|
"@homarr/redis": "workspace:^0.1.0",
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
"drizzle-orm": "^0.45.1",
|
|
||||||
"octokit": "^5.0.5",
|
"octokit": "^5.0.5",
|
||||||
"superjson": "2.2.6",
|
"superjson": "2.2.6",
|
||||||
"undici": "7.16.0",
|
"undici": "7.16.0",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import type { ContainerInfo, ContainerStats } from "dockerode";
|
import type { ContainerInfo, ContainerStats } from "dockerode";
|
||||||
import { like, or } from "drizzle-orm";
|
|
||||||
|
|
||||||
import { db } from "@homarr/db";
|
import { db, like, or } from "@homarr/db";
|
||||||
import { icons } from "@homarr/db/schema";
|
import { icons } from "@homarr/db/schema";
|
||||||
import type { ContainerState } from "@homarr/docker";
|
import type { ContainerState } from "@homarr/docker";
|
||||||
import { dockerLabels, DockerSingleton } from "@homarr/docker";
|
import { dockerLabels, DockerSingleton } from "@homarr/docker";
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@homarr/definitions": "workspace:^0.1.0",
|
"@homarr/definitions": "workspace:^0.1.0",
|
||||||
"@homarr/translation": "workspace:^0.1.0",
|
"@homarr/translation": "workspace:^0.1.0",
|
||||||
"zod": "^4.2.0",
|
"zod": "^4.1.13",
|
||||||
"zod-form-data": "^3.0.1"
|
"zod-form-data": "^3.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -70,7 +70,6 @@
|
|||||||
"@tiptap/starter-kit": "^3.13.0",
|
"@tiptap/starter-kit": "^3.13.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
"drizzle-orm": "^0.45.1",
|
|
||||||
"mantine-form-zod-resolver": "^1.3.0",
|
"mantine-form-zod-resolver": "^1.3.0",
|
||||||
"mantine-react-table": "2.0.0-beta.9",
|
"mantine-react-table": "2.0.0-beta.9",
|
||||||
"next": "16.0.10",
|
"next": "16.0.10",
|
||||||
@@ -79,7 +78,7 @@
|
|||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"recharts": "^2.15.4",
|
"recharts": "^2.15.4",
|
||||||
"video.js": "^8.23.4",
|
"video.js": "^8.23.4",
|
||||||
"zod": "^4.2.0"
|
"zod": "^4.1.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
|
|||||||
Loaded 100 of 104 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user