diff --git a/.env.example b/.env.example
index d643c1194..745d45954 100644
--- a/.env.example
+++ b/.env.example
@@ -45,6 +45,12 @@ DB_URL='FULL_PATH_TO_YOUR_SQLITE_DB_FILE'
TURBO_TELEMETRY_DISABLED=1
+# Comma-separated paths to Docker-compatible Unix sockets.
+# Useful for connecting to multiple runtimes (Docker + Podman) simultaneously.
+# When unset and no TCP hosts configured, defaults to /var/run/docker.sock.
+# Example: DOCKER_SOCKET_PATHS=/var/run/docker.sock,/run/user/1000/podman/podman.sock
+# DOCKER_SOCKET_PATHS=
+
# Enable kubernetes tool
# ENABLE_KUBERNETES=true
diff --git a/.github/renovate.json5 b/.github/renovate.json5
index ebfca8af4..269a4d2ff 100644
--- a/.github/renovate.json5
+++ b/.github/renovate.json5
@@ -22,7 +22,7 @@
automerge: true,
},
{
- // disallow automerge for dependencies requiring postinstall scripts
+ // disallow automerge for onlyBuiltDependencies
matchPackageNames: [
"@tree-sitter-grammars/tree-sitter-yaml",
"bcrypt",
@@ -39,7 +39,7 @@
],
// Updates lockfile for prebuilt-debian after if package.json is updated, otherwise only root lockfile is updated
postUpgradeTasks: {
- commands: ["cd deployments/prebuilt-debian && pnpm install --lockfile-only"],
+ commands: ["cd deployments/prebuilt-debian && pnpm install --ignore-workspace --lockfile-only"],
fileFilters: ["deployments/prebuilt-debian/pnpm-lock.yaml"],
executionMode: "update",
},
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 000000000..34451fb2f
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1,6 @@
+# Expo doesn't play nice with pnpm by default.
+# The symbolic links of pnpm break the rules of Expo monorepos.
+# @link https://docs.expo.dev/guides/monorepos/#common-issues
+node-linker=hoisted
+strict-peer-dependencies=false
+engine-strict=true
\ No newline at end of file
diff --git a/CODEOWNERS b/CODEOWNERS
index ed482fd41..b798cfada 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -3,7 +3,11 @@
# Exempt Renovate‑managed files (no owners)
package.json
+**/package.json
package-lock.json
+**/package-lock.json
pnpm-lock.yaml
+**/pnpm-lock.yaml
+pnpm-workspace.yaml
Dockerfile
docker-compose.yml
diff --git a/apps/nextjs/src/app/[locale]/manage/tools/docker/docker-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/docker/docker-table.tsx
index 537c85e7c..de7e781a1 100644
--- a/apps/nextjs/src/app/[locale]/manage/tools/docker/docker-table.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/tools/docker/docker-table.tsx
@@ -58,6 +58,18 @@ const createColumns = (
return ;
},
},
+ {
+ accessorKey: "host",
+ header: t("docker.field.host.label"),
+ size: 140,
+ Cell({ row }) {
+ return (
+
+ {row.original.host}
+
+ );
+ },
+ },
{
accessorKey: "image",
header: t("docker.field.containerImage.label"),
diff --git a/deployments/prebuilt-debian/Dockerfile b/deployments/prebuilt-debian/Dockerfile
index 7ca2aafb1..8ac61693e 100644
--- a/deployments/prebuilt-debian/Dockerfile
+++ b/deployments/prebuilt-debian/Dockerfile
@@ -2,6 +2,5 @@ FROM node:24.15.0-trixie AS base
WORKDIR /app
COPY package.json .
COPY pnpm-lock.yaml .
-COPY pnpm-workspace.yaml .
RUN corepack enable pnpm && pnpm install --frozen-lockfile
CMD ["sleep", "60s"]
\ No newline at end of file
diff --git a/deployments/prebuilt-debian/package.json b/deployments/prebuilt-debian/package.json
index 6d326193c..15876ecc1 100644
--- a/deployments/prebuilt-debian/package.json
+++ b/deployments/prebuilt-debian/package.json
@@ -4,9 +4,14 @@
"dependencies": {
"better-sqlite3": "^12.9.0"
},
- "packageManager": "pnpm@11.0.4",
+ "packageManager": "pnpm@10.33.2",
"engines": {
"node": ">=24.15.0",
- "pnpm": ">=11.0.4"
+ "pnpm": ">=10.33.2"
+ },
+ "pnpm": {
+ "onlyBuiltDependencies": [
+ "better-sqlite3"
+ ]
}
}
diff --git a/deployments/prebuilt-debian/pnpm-workspace.yaml b/deployments/prebuilt-debian/pnpm-workspace.yaml
deleted file mode 100644
index 65783dc34..000000000
--- a/deployments/prebuilt-debian/pnpm-workspace.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-allowBuilds:
- better-sqlite3: true
diff --git a/package.json b/package.json
index d81206e10..5cdd91982 100644
--- a/package.json
+++ b/package.json
@@ -57,12 +57,55 @@
"turbo": "catalog:",
"typescript": "catalog:",
"vite-tsconfig-paths": "catalog:",
- "vitest": "catalog:",
- "yaml": "catalog:"
+ "vitest": "catalog:"
},
- "packageManager": "pnpm@11.0.4",
+ "packageManager": "pnpm@10.33.2",
"engines": {
"node": ">=24.15.0",
- "pnpm": ">=11.0.4"
+ "pnpm": ">=10.33.2"
+ },
+ "pnpm": {
+ "onlyBuiltDependencies": [
+ "@tree-sitter-grammars/tree-sitter-yaml",
+ "bcrypt",
+ "better-sqlite3",
+ "cpu-features",
+ "esbuild",
+ "sharp",
+ "ssh2",
+ "tree-sitter",
+ "tree-sitter-json"
+ ],
+ "overrides": {
+ "@babel/helpers@<7.26.10": ">=7.29.2",
+ "@babel/runtime@<7.26.10": ">=7.29.2",
+ "axios@>=1.0.0 <1.8.2": ">=1.16.0",
+ "brace-expansion@>=2.0.0 <=2.0.1": ">=5.0.5",
+ "brace-expansion@>=1.0.0 <=1.1.11": ">=5.0.5",
+ "esbuild@<=0.24.2": ">=0.28.0",
+ "form-data@>=4.0.0 <4.0.4": ">=4.0.5",
+ "hono@<4.6.5": ">=4.12.16",
+ "linkifyjs@<4.3.2": ">=4.3.2",
+ "nanoid@>=4.0.0 <5.0.9": ">=5.1.11",
+ "prismjs@<1.30.0": ">=1.30.0",
+ "proxmox-api>undici": "7.24.6",
+ "react-is": "^19.2.5",
+ "rollup@>=4.0.0 <4.22.4": ">=4.60.2",
+ "sha.js@<=2.4.11": ">=2.4.12",
+ "tar-fs@>=3.0.0 <3.0.9": ">=3.1.2",
+ "tar-fs@>=2.0.0 <2.1.3": ">=3.1.2",
+ "tmp@<=0.2.3": ">=0.2.5",
+ "vite@>=5.0.0 <=5.4.18": ">=8.0.10"
+ },
+ "patchedDependencies": {
+ "@types/node-unifi": "patches/@types__node-unifi.patch",
+ "trpc-to-openapi": "patches/trpc-to-openapi.patch"
+ },
+ "allowUnusedPatches": true,
+ "ignoredBuiltDependencies": [
+ "@scarf/scarf",
+ "core-js-pure",
+ "protobufjs"
+ ]
}
}
diff --git a/packages/api/src/router/docker/docker-router.ts b/packages/api/src/router/docker/docker-router.ts
index e5a4b4796..4527482f0 100644
--- a/packages/api/src/router/docker/docker-router.ts
+++ b/packages/api/src/router/docker/docker-router.ts
@@ -138,6 +138,7 @@ const getContainerOrThrowAsync = async (id: string) => {
interface DockerContainer {
name: string;
id: string;
+ host: string;
state: ContainerState;
image: string;
ports: Port[] | undefined;
diff --git a/packages/definitions/src/integration.ts b/packages/definitions/src/integration.ts
index 81c58b0af..dfc862fbb 100644
--- a/packages/definitions/src/integration.ts
+++ b/packages/definitions/src/integration.ts
@@ -61,7 +61,7 @@ export const integrationDefs = {
},
qBittorrent: {
name: "qBittorrent",
- secretKinds: [["username", "password"]],
+ secretKinds: [["apiKey"], ["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/qbittorrent.svg",
category: ["downloadClient", "torrent"],
documentationUrl: createDocumentationLink("/docs/integrations/q-bittorent"),
diff --git a/packages/docker/src/env.ts b/packages/docker/src/env.ts
index e858d3e69..003a9bfa6 100644
--- a/packages/docker/src/env.ts
+++ b/packages/docker/src/env.ts
@@ -4,9 +4,11 @@ import { createBooleanSchema, createEnv } from "@homarr/core/infrastructure/env"
export const env = createEnv({
server: {
- // Comma separated list of docker hostnames that can be used to connect to query the docker endpoints (localhost:2375,host.docker.internal:2375, ...)
+ // Comma separated list of docker hostnames that can be used to connect to query the docker endpoints (localhost,host.docker.internal, ...)
DOCKER_HOSTNAMES: z.string().optional(),
DOCKER_PORTS: z.string().optional(),
+ // Comma separated paths to Docker-compatible Unix sockets (e.g., /var/run/docker.sock,/run/user/1000/podman/podman.sock)
+ DOCKER_SOCKET_PATHS: z.string().optional(),
ENABLE_DOCKER: createBooleanSchema(true),
ENABLE_KUBERNETES: createBooleanSchema(false),
},
diff --git a/packages/docker/src/singleton.ts b/packages/docker/src/singleton.ts
index 86ce9661e..f24e8eb9c 100644
--- a/packages/docker/src/singleton.ts
+++ b/packages/docker/src/singleton.ts
@@ -11,31 +11,43 @@ export class DockerSingleton {
private static instances: DockerInstance[] | null = null;
private createInstances() {
+ const socketPaths = env.DOCKER_SOCKET_PATHS;
const hostVariable = env.DOCKER_HOSTNAMES;
const portVariable = env.DOCKER_PORTS;
- if (hostVariable === undefined || portVariable === undefined) {
+
+ // Socket instances from DOCKER_SOCKET_PATHS
+ const socketInstances: DockerInstance[] = socketPaths
+ ? socketPaths.split(",").map((socketPath) => ({
+ host: socketPath,
+ instance: new Docker({ socketPath }),
+ }))
+ : [];
+
+ // TCP instances from existing DOCKER_HOSTNAMES/DOCKER_PORTS
+ let tcpInstances: DockerInstance[] = [];
+ if (hostVariable !== undefined && portVariable !== undefined) {
+ const hostnames = hostVariable.split(",");
+ const ports = portVariable.split(",");
+
+ if (hostnames.length !== ports.length) {
+ throw new Error("The number of hosts and ports must match");
+ }
+
+ tcpInstances = hostnames.map((host, i) => ({
+ host: `${host}:${ports[i]}`,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ instance: new Docker({ host, port: parseInt(ports[i]!, 10) }),
+ }));
+ }
+
+ const instances = [...socketInstances, ...tcpInstances];
+
+ // Default: local socket if nothing else configured
+ if (instances.length === 0) {
return [{ host: "socket", instance: new Docker() }];
}
- const hostnames = hostVariable.split(",");
- const ports = portVariable.split(",");
- if (hostnames.length !== ports.length) {
- throw new Error("The number of hosts and ports must match");
- }
-
- return hostnames.map((host, i) => {
- // Check above ensures that ports[i] is not undefined
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const port = ports[i]!;
-
- return {
- host: `${host}:${port}`,
- instance: new Docker({
- host,
- port: parseInt(port, 10),
- }),
- };
- });
+ return instances;
}
public static findInstance(host: string): DockerInstance | undefined {
diff --git a/packages/docker/src/test/singleton.spec.ts b/packages/docker/src/test/singleton.spec.ts
new file mode 100644
index 000000000..53af453af
--- /dev/null
+++ b/packages/docker/src/test/singleton.spec.ts
@@ -0,0 +1,110 @@
+import { beforeEach, describe, expect, test, vi } from "vitest";
+
+import { DockerSingleton } from "../singleton";
+
+const mockEnv = vi.hoisted(() => ({
+ DOCKER_SOCKET_PATHS: undefined as string | undefined,
+ DOCKER_HOSTNAMES: undefined as string | undefined,
+ DOCKER_PORTS: undefined as string | undefined,
+ ENABLE_DOCKER: true,
+ ENABLE_KUBERNETES: false,
+}));
+
+vi.mock("dockerode", () => {
+ return {
+ default: class MockDocker {
+ constructor(public opts?: Record) {}
+ },
+ };
+});
+
+vi.mock("../env", () => ({
+ env: mockEnv,
+}));
+
+describe("DockerSingleton", () => {
+ beforeEach(() => {
+ // Reset singleton cache between tests
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
+ (DockerSingleton as any).instances = null;
+
+ // Reset env to defaults
+ mockEnv.DOCKER_SOCKET_PATHS = undefined;
+ mockEnv.DOCKER_HOSTNAMES = undefined;
+ mockEnv.DOCKER_PORTS = undefined;
+ });
+
+ test("should return default socket when no env vars set", () => {
+ const instances = DockerSingleton.getInstances();
+
+ expect(instances).toHaveLength(1);
+ expect(instances[0]?.host).toBe("socket");
+ });
+
+ test("should return TCP instances only when DOCKER_HOSTNAMES and DOCKER_PORTS set", () => {
+ mockEnv.DOCKER_HOSTNAMES = "remote-host";
+ mockEnv.DOCKER_PORTS = "2375";
+
+ const instances = DockerSingleton.getInstances();
+
+ expect(instances).toHaveLength(1);
+ expect(instances[0]?.host).toBe("remote-host:2375");
+ });
+
+ test("should return multiple TCP instances", () => {
+ mockEnv.DOCKER_HOSTNAMES = "host1,host2";
+ mockEnv.DOCKER_PORTS = "2375,2376";
+
+ const instances = DockerSingleton.getInstances();
+
+ expect(instances).toHaveLength(2);
+ expect(instances[0]?.host).toBe("host1:2375");
+ expect(instances[1]?.host).toBe("host2:2376");
+ });
+
+ test("should throw when hostname and port counts do not match", () => {
+ mockEnv.DOCKER_HOSTNAMES = "host1,host2";
+ mockEnv.DOCKER_PORTS = "2375";
+
+ expect(() => DockerSingleton.getInstances()).toThrow("The number of hosts and ports must match");
+ });
+
+ test("should return socket instances when DOCKER_SOCKET_PATHS set", () => {
+ mockEnv.DOCKER_SOCKET_PATHS = "/var/run/docker.sock";
+
+ const instances = DockerSingleton.getInstances();
+
+ expect(instances).toHaveLength(1);
+ expect(instances[0]?.host).toBe("/var/run/docker.sock");
+ });
+
+ test("should return multiple socket instances", () => {
+ mockEnv.DOCKER_SOCKET_PATHS = "/var/run/docker.sock,/run/user/1000/podman/podman.sock";
+
+ const instances = DockerSingleton.getInstances();
+
+ expect(instances).toHaveLength(2);
+ expect(instances[0]?.host).toBe("/var/run/docker.sock");
+ expect(instances[1]?.host).toBe("/run/user/1000/podman/podman.sock");
+ });
+
+ test("should combine socket and TCP instances", () => {
+ mockEnv.DOCKER_SOCKET_PATHS = "/var/run/docker.sock,/run/user/1000/podman/podman.sock";
+ mockEnv.DOCKER_HOSTNAMES = "remote-host";
+ mockEnv.DOCKER_PORTS = "2375";
+
+ const instances = DockerSingleton.getInstances();
+
+ expect(instances).toHaveLength(3);
+ expect(instances[0]?.host).toBe("/var/run/docker.sock");
+ expect(instances[1]?.host).toBe("/run/user/1000/podman/podman.sock");
+ expect(instances[2]?.host).toBe("remote-host:2375");
+ });
+
+ test("should cache instances on subsequent calls", () => {
+ const first = DockerSingleton.getInstances();
+ const second = DockerSingleton.getInstances();
+
+ expect(first).toBe(second);
+ });
+});
diff --git a/packages/integrations/src/download-client/qbittorrent/qbittorrent-integration.ts b/packages/integrations/src/download-client/qbittorrent/qbittorrent-integration.ts
index 1076bca5e..a142fb1a3 100644
--- a/packages/integrations/src/download-client/qbittorrent/qbittorrent-integration.ts
+++ b/packages/integrations/src/download-client/qbittorrent/qbittorrent-integration.ts
@@ -90,10 +90,18 @@ export class QBitTorrentIntegration extends Integration implements IDownloadClie
}
private async getClientAsync(dispatcher?: Dispatcher) {
+ const credentials = this.hasSecretValue("apiKey")
+ ? {
+ apiKey: this.getSecretValue("apiKey"),
+ }
+ : {
+ username: this.getSecretValue("username"),
+ password: this.getSecretValue("password"),
+ };
+
return new QBittorrent({
+ ...credentials,
baseUrl: this.url("/").toString(),
- username: this.getSecretValue("username"),
- password: this.getSecretValue("password"),
dispatcher: dispatcher ?? (await createCertificateAgentAsync()),
});
}
diff --git a/packages/request-handler/src/docker.ts b/packages/request-handler/src/docker.ts
index 7b873ec00..6610aba7e 100644
--- a/packages/request-handler/src/docker.ts
+++ b/packages/request-handler/src/docker.ts
@@ -2,6 +2,8 @@ import dayjs from "dayjs";
import type { ContainerInfo, ContainerStats } from "dockerode";
import type Dockerode from "dockerode";
+import { createLogger } from "@homarr/core/infrastructure/logs";
+import { ErrorWithMetadata } from "@homarr/core/infrastructure/logs/error";
import { db, like, or } from "@homarr/db";
import { icons } from "@homarr/db/schema";
import type { ContainerState } from "@homarr/docker";
@@ -9,6 +11,8 @@ import { dockerLabels, DockerSingleton } from "@homarr/docker";
import { createCachedWidgetRequestHandler } from "./lib/cached-widget-request-handler";
+const logger = createLogger({ module: "dockerRequestHandler" });
+
export const dockerContainersRequestHandler = createCachedWidgetRequestHandler({
queryKey: "dockerContainersResult",
widgetKind: "dockerContainers",
@@ -18,19 +22,34 @@ export const dockerContainersRequestHandler = createCachedWidgetRequestHandler({
cacheDuration: dayjs.duration(20, "seconds"),
});
-const dockerInstances = DockerSingleton.getInstances();
-
const extractImage = (container: ContainerInfo) => container.Image.split("/").at(-1)?.split(":").at(0) ?? "";
async function getContainersWithStatsAsync() {
- const containers = await Promise.all(
+ const dockerInstances = DockerSingleton.getInstances();
+ const results = await Promise.allSettled(
dockerInstances.map(async ({ instance, host }) => {
const instanceContainers = await instance.listContainers({ all: true });
return instanceContainers
.filter((container) => !(dockerLabels.hide in container.Labels))
.map((container) => ({ ...container, instance: host }));
}),
- ).then((res) => res.flat());
+ );
+
+ const containers = results.flatMap((result, index) => {
+ if (result.status === "fulfilled") return result.value;
+ logger.warn(
+ new ErrorWithMetadata(
+ "Failed to list containers from Docker host",
+ {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ host: dockerInstances[index]!.host,
+ },
+ { cause: result.reason },
+ ),
+ );
+
+ return [];
+ });
const likeQueries = containers.map((container) => like(icons.name, `%${extractImage(container)}%`));
const dbIcons =
@@ -44,8 +63,6 @@ async function getContainersWithStatsAsync() {
const instance = dockerInstances.find(({ host }) => host === container.instance)?.instance;
if (!instance) return null;
- // Get stats, falling back to an empty stats object if fetch fails
- // calculateCpuUsage and calculateMemoryUsage will return 0 for invalid/missing stats
const stats = await instance
.getContainer(container.Id)
.stats({ stream: false, "one-shot": true })
@@ -63,6 +80,7 @@ async function getContainersWithStatsAsync() {
return {
id: container.Id,
name: container.Names[0]?.split("/")[1] ?? "Unknown",
+ host: container.instance,
state: container.State as ContainerState,
iconUrl:
dbIcons.find((icon) => {
@@ -80,9 +98,10 @@ async function getContainersWithStatsAsync() {
return (await Promise.all(containerStatsPromises)).filter((container) => container !== null);
}
-function calculateCpuUsage(stats: ContainerStats): number {
- // Handle containers with missing or invalid stats (e.g., exited, dead containers)
- if (!stats.cpu_stats.online_cpus || stats.cpu_stats.online_cpus === 0 || !stats.cpu_stats.cpu_usage.total_usage) {
+export function calculateCpuUsage(stats: ContainerStats): number {
+ // Handle containers with missing or invalid stats (e.g., exited, dead containers, Podman responses)
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ if (!stats.cpu_stats?.online_cpus || stats.cpu_stats.online_cpus === 0 || !stats.cpu_stats.cpu_usage?.total_usage) {
return 0;
}
@@ -95,9 +114,10 @@ function calculateCpuUsage(stats: ContainerStats): number {
return (stats.cpu_stats.cpu_usage.total_usage / usage) * numberOfCpus * 100;
}
-function calculateMemoryUsage(stats: ContainerStats): number {
- // Handle containers with missing or invalid stats (e.g., exited, dead containers)
- if (!stats.memory_stats.usage) {
+export function calculateMemoryUsage(stats: ContainerStats): number {
+ // Handle containers with missing or invalid stats (e.g., exited, dead containers, Podman responses)
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ if (!stats.memory_stats?.usage) {
return 0;
}
diff --git a/packages/request-handler/src/test/docker.spec.ts b/packages/request-handler/src/test/docker.spec.ts
new file mode 100644
index 000000000..b4e34f816
--- /dev/null
+++ b/packages/request-handler/src/test/docker.spec.ts
@@ -0,0 +1,121 @@
+import type { ContainerStats } from "dockerode";
+import { describe, expect, test, vi } from "vitest";
+
+import { createDb } from "@homarr/db/test";
+
+import { calculateCpuUsage, calculateMemoryUsage } from "../docker";
+
+vi.mock("@homarr/db", async (importActual) => {
+ // eslint-disable-next-line @typescript-eslint/consistent-type-imports
+ const actual = await importActual();
+ return {
+ ...actual,
+ db: createDb(),
+ };
+});
+
+// Helper to create a partial stats object, cast to ContainerStats.
+// This mirrors what Podman and other Docker-compatible runtimes may return
+// at runtime, even though @types/dockerode declares all fields as required.
+const createStats = (overrides: Record = {}) => overrides as unknown as ContainerStats;
+
+describe("calculateCpuUsage", () => {
+ test("should return 0 when cpu_stats is undefined (Podman)", () => {
+ const stats = createStats({ cpu_stats: undefined });
+ expect(calculateCpuUsage(stats)).toBe(0);
+ });
+
+ test("should return 0 when online_cpus is 0", () => {
+ const stats = createStats({
+ cpu_stats: { online_cpus: 0, cpu_usage: { total_usage: 1000 }, system_cpu_usage: 5000 },
+ });
+ expect(calculateCpuUsage(stats)).toBe(0);
+ });
+
+ test("should return 0 when online_cpus is undefined", () => {
+ const stats = createStats({
+ cpu_stats: { cpu_usage: { total_usage: 1000 }, system_cpu_usage: 5000 },
+ });
+ expect(calculateCpuUsage(stats)).toBe(0);
+ });
+
+ test("should return 0 when cpu_usage is undefined", () => {
+ const stats = createStats({
+ cpu_stats: { online_cpus: 4, system_cpu_usage: 5000 },
+ });
+ expect(calculateCpuUsage(stats)).toBe(0);
+ });
+
+ test("should return 0 when total_usage is 0", () => {
+ const stats = createStats({
+ cpu_stats: { online_cpus: 4, cpu_usage: { total_usage: 0 }, system_cpu_usage: 5000 },
+ });
+ expect(calculateCpuUsage(stats)).toBe(0);
+ });
+
+ test("should return 0 when system_cpu_usage is 0", () => {
+ const stats = createStats({
+ cpu_stats: { online_cpus: 4, cpu_usage: { total_usage: 1000 }, system_cpu_usage: 0 },
+ });
+ expect(calculateCpuUsage(stats)).toBe(0);
+ });
+
+ test("should calculate correct CPU percentage for valid stats", () => {
+ const stats = createStats({
+ cpu_stats: { online_cpus: 4, cpu_usage: { total_usage: 2000 }, system_cpu_usage: 10000 },
+ });
+ // (2000 / 10000) * 4 * 100 = 80
+ expect(calculateCpuUsage(stats)).toBe(80);
+ });
+
+ test("should handle fractional CPU usage", () => {
+ const stats = createStats({
+ cpu_stats: { online_cpus: 2, cpu_usage: { total_usage: 500 }, system_cpu_usage: 100000 },
+ });
+ // (500 / 100000) * 2 * 100 = 1
+ expect(calculateCpuUsage(stats)).toBe(1);
+ });
+});
+
+describe("calculateMemoryUsage", () => {
+ test("should return 0 when memory_stats is undefined (Podman)", () => {
+ const stats = createStats({ memory_stats: undefined });
+ expect(calculateMemoryUsage(stats)).toBe(0);
+ });
+
+ test("should return 0 when memory_stats.usage is 0", () => {
+ const stats = createStats({ memory_stats: { usage: 0 } });
+ expect(calculateMemoryUsage(stats)).toBe(0);
+ });
+
+ test("should return 0 when memory_stats.usage is undefined", () => {
+ const stats = createStats({ memory_stats: {} });
+ expect(calculateMemoryUsage(stats)).toBe(0);
+ });
+
+ test("should subtract cache from usage", () => {
+ const stats = createStats({
+ memory_stats: { usage: 1000, stats: { cache: 200 } },
+ });
+ expect(calculateMemoryUsage(stats)).toBe(800);
+ });
+
+ test("should use total_inactive_file when cache is absent", () => {
+ const stats = createStats({
+ memory_stats: { usage: 1000, stats: { total_inactive_file: 300 } },
+ });
+ expect(calculateMemoryUsage(stats)).toBe(700);
+ });
+
+ test("should use inactive_file as last fallback", () => {
+ const stats = createStats({
+ memory_stats: { usage: 1000, stats: { inactive_file: 150 } },
+ });
+ expect(calculateMemoryUsage(stats)).toBe(850);
+ });
+
+ test("should return raw usage when memory_stats.stats is undefined", () => {
+ const stats = createStats({ memory_stats: { usage: 512 } });
+ expect(calculateMemoryUsage(stats)).toBe(512);
+ });
+});
diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json
index 981839c3b..29e86458e 100644
--- a/packages/translation/src/lang/en.json
+++ b/packages/translation/src/lang/en.json
@@ -3970,6 +3970,9 @@
},
"ports": {
"label": "Ports"
+ },
+ "host": {
+ "label": "Host"
}
},
"action": {
diff --git a/packages/widgets/src/docker/component.tsx b/packages/widgets/src/docker/component.tsx
index 869b76f0b..c135484a8 100644
--- a/packages/widgets/src/docker/component.tsx
+++ b/packages/widgets/src/docker/component.tsx
@@ -79,6 +79,19 @@ const createColumns = (
return ;
},
},
+ {
+ id: "host",
+ accessorKey: "host",
+ size: 100,
+ header: t("field.host.label"),
+ Cell({ row }) {
+ return (
+
+ {row.original.host}
+
+ );
+ },
+ },
{
id: "cpuUsage",
sortingFn: (rowA, rowB) => {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a9e0194fb..83fa4ef59 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -16,8 +16,8 @@ catalogs:
specifier: ^8.0.0
version: 8.0.0
'@ctrl/qbittorrent':
- specifier: ^9.11.2
- version: 9.11.2
+ specifier: ^9.12.1
+ version: 9.12.1
'@ctrl/transmission':
specifier: ^7.4.0
version: 7.4.0
@@ -40,8 +40,8 @@ catalogs:
specifier: 10.0.1
version: 10.0.1
'@extractus/feed-extractor':
- specifier: 7.1.7
- version: 7.1.7
+ specifier: 7.2.1
+ version: 7.2.1
'@gitbeaker/rest':
specifier: ^43.8.0
version: 43.8.0
@@ -130,14 +130,14 @@ catalogs:
specifier: ^3.41.1
version: 3.41.1
'@tanstack/react-query':
- specifier: ^5.100.8
- version: 5.100.8
+ specifier: ^5.100.9
+ version: 5.100.9
'@tanstack/react-query-devtools':
- specifier: ^5.100.8
- version: 5.100.8
+ specifier: ^5.100.9
+ version: 5.100.9
'@tanstack/react-query-next-experimental':
- specifier: ^5.100.8
- version: 5.100.8
+ specifier: ^5.100.9
+ version: 5.100.9
'@testcontainers/mysql':
specifier: ^11.14.0
version: 11.14.0
@@ -211,7 +211,7 @@ catalogs:
specifier: ^11.17.0
version: 11.17.0
'@turbo/gen':
- specifier: ^2.9.7
+ specifier: ^2.9.8
version: 2.9.8
'@types/adm-zip':
specifier: 0.5.8
@@ -364,7 +364,7 @@ catalogs:
specifier: ^10.1.8
version: 10.1.8
eslint-config-turbo:
- specifier: ^2.9.7
+ specifier: ^2.9.8
version: 2.9.8
eslint-plugin-import:
specifier: ^2.32.0
@@ -514,7 +514,7 @@ catalogs:
specifier: 4.20.4
version: 4.20.4
turbo:
- specifier: ^2.9.7
+ specifier: ^2.9.8
version: 2.9.8
typescript:
specifier: ^5.9.3
@@ -550,8 +550,8 @@ catalogs:
specifier: 2.8.4
version: 2.8.4
zod:
- specifier: ^4.4.2
- version: 4.4.2
+ specifier: ^4.4.3
+ version: 4.4.3
zod-form-data:
specifier: ^3.0.1
version: 3.0.1
@@ -563,8 +563,8 @@ overrides:
'@babel/helpers@<7.26.10': '>=7.29.2'
'@babel/runtime@<7.26.10': '>=7.29.2'
axios@>=1.0.0 <1.8.2: '>=1.16.0'
- brace-expansion@>=1.0.0 <=1.1.11: '>=5.0.5'
brace-expansion@>=2.0.0 <=2.0.1: '>=5.0.5'
+ brace-expansion@>=1.0.0 <=1.1.11: '>=5.0.5'
esbuild@<=0.24.2: '>=0.28.0'
form-data@>=4.0.0 <4.0.4: '>=4.0.5'
hono@<4.6.5: '>=4.12.16'
@@ -575,14 +575,18 @@ overrides:
react-is: ^19.2.5
rollup@>=4.0.0 <4.22.4: '>=4.60.2'
sha.js@<=2.4.11: '>=2.4.12'
- tar-fs@>=2.0.0 <2.1.3: '>=3.1.2'
tar-fs@>=3.0.0 <3.0.9: '>=3.1.2'
+ tar-fs@>=2.0.0 <2.1.3: '>=3.1.2'
tmp@<=0.2.3: '>=0.2.5'
vite@>=5.0.0 <=5.4.18: '>=8.0.10'
patchedDependencies:
- '@types/node-unifi': 5e6ae51e2a17a7f9729bfa30b0eb3d0842a5810ac6db47603ab4a6efa1ed84c5
- trpc-to-openapi: 2ca3c16af0fcca0c736697ad4fe553a14f794524fa9ce0d5c3e8ee4aea76090c
+ '@types/node-unifi':
+ hash: 5e6ae51e2a17a7f9729bfa30b0eb3d0842a5810ac6db47603ab4a6efa1ed84c5
+ path: patches/@types__node-unifi.patch
+ trpc-to-openapi:
+ hash: 2ca3c16af0fcca0c736697ad4fe553a14f794524fa9ce0d5c3e8ee4aea76090c
+ path: patches/trpc-to-openapi.patch
importers:
@@ -657,9 +661,6 @@ importers:
vitest:
specifier: 'catalog:'
version: 4.1.5(@types/node@24.12.2)(@vitest/coverage-v8@4.1.5)(@vitest/ui@4.1.5)(jsdom@29.1.1(@noble/hashes@2.0.1))(vite@7.1.12(@types/node@24.12.2)(sass@1.99.0)(sugarss@5.0.0(postcss@8.5.8))(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.4))
- yaml:
- specifier: 'catalog:'
- version: 2.8.4
apps/nextjs:
dependencies:
@@ -785,22 +786,22 @@ importers:
version: 3.41.1(react@19.2.5)
'@tanstack/react-query':
specifier: 'catalog:'
- version: 5.100.8(react@19.2.5)
+ version: 5.100.9(react@19.2.5)
'@tanstack/react-query-devtools':
specifier: 'catalog:'
- version: 5.100.8(@tanstack/react-query@5.100.8(react@19.2.5))(react@19.2.5)
+ version: 5.100.9(@tanstack/react-query@5.100.9(react@19.2.5))(react@19.2.5)
'@tanstack/react-query-next-experimental':
specifier: 'catalog:'
- version: 5.100.8(@tanstack/react-query@5.100.8(react@19.2.5))(next@16.2.4(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(sass@1.99.0))(react@19.2.5)
+ version: 5.100.9(@tanstack/react-query@5.100.9(react@19.2.5))(next@16.2.4(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(sass@1.99.0))(react@19.2.5)
'@trpc/client':
specifier: 'catalog:'
version: 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3)
'@trpc/next':
specifier: 'catalog:'
- version: 11.17.0(@tanstack/react-query@5.100.8(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/react-query@11.17.0(@tanstack/react-query@5.100.8(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(next@16.2.4(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(sass@1.99.0))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@5.9.3)
+ version: 11.17.0(@tanstack/react-query@5.100.9(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/react-query@11.17.0(@tanstack/react-query@5.100.9(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(next@16.2.4(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(sass@1.99.0))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@5.9.3)
'@trpc/react-query':
specifier: 'catalog:'
- version: 11.17.0(@tanstack/react-query@5.100.8(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)
+ version: 11.17.0(@tanstack/react-query@5.100.9(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)
'@trpc/server':
specifier: 'catalog:'
version: 11.17.0(typescript@5.9.3)
@@ -881,7 +882,7 @@ importers:
version: 2.8.4
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -1197,19 +1198,19 @@ importers:
version: 1.4.0
'@tanstack/react-query':
specifier: 'catalog:'
- version: 5.100.8(react@19.2.5)
+ version: 5.100.9(react@19.2.5)
'@trpc/client':
specifier: 'catalog:'
version: 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3)
'@trpc/react-query':
specifier: 'catalog:'
- version: 11.17.0(@tanstack/react-query@5.100.8(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)
+ version: 11.17.0(@tanstack/react-query@5.100.9(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)
'@trpc/server':
specifier: 'catalog:'
version: 11.17.0(typescript@5.9.3)
'@trpc/tanstack-react-query':
specifier: 'catalog:'
- version: 11.17.0(@tanstack/react-query@5.100.8(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)
+ version: 11.17.0(@tanstack/react-query@5.100.9(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)
lodash.clonedeep:
specifier: 'catalog:'
version: 4.5.0
@@ -1227,10 +1228,10 @@ importers:
version: 2.2.6
trpc-to-openapi:
specifier: 'catalog:'
- version: 3.2.0(patch_hash=2ca3c16af0fcca0c736697ad4fe553a14f794524fa9ce0d5c3e8ee4aea76090c)(@trpc/server@11.17.0(typescript@5.9.3))(zod-openapi@5.3.0(zod@4.4.2))(zod@4.4.2)
+ version: 3.2.0(patch_hash=2ca3c16af0fcca0c736697ad4fe553a14f794524fa9ce0d5c3e8ee4aea76090c)(@trpc/server@11.17.0(typescript@5.9.3))(zod-openapi@5.3.0(zod@4.4.3))(zod@4.4.3)
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -1297,7 +1298,7 @@ importers:
version: 19.2.5(react@19.2.5)
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -1423,10 +1424,10 @@ importers:
version: 7.24.6
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
zod-validation-error:
specifier: 'catalog:'
- version: 5.0.0(zod@4.4.2)
+ version: 5.0.0(zod@4.4.3)
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -1448,7 +1449,7 @@ importers:
dependencies:
'@t3-oss/env-nextjs':
specifier: 'catalog:'
- version: 0.13.11(typescript@5.9.3)(zod@4.4.2)
+ version: 0.13.11(arktype@2.1.20)(typescript@5.9.3)(zod@4.4.3)
better-sqlite3:
specifier: 'catalog:'
version: 12.9.0
@@ -1457,7 +1458,7 @@ importers:
version: 0.2.9
drizzle-orm:
specifier: 'catalog:'
- version: 0.45.2(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.9.0)(mysql2@3.22.3(@types/node@24.12.2))(pg@8.20.0)
+ version: 0.45.2(@libsql/client-wasm@0.14.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.9.0)(gel@2.0.0)(mysql2@3.22.3(@types/node@24.12.2))(pg@8.20.0)
ioredis:
specifier: 'catalog:'
version: 5.10.1
@@ -1475,7 +1476,7 @@ importers:
version: 3.19.0
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -1512,7 +1513,7 @@ importers:
version: link:../cron-jobs
'@tanstack/react-query':
specifier: 'catalog:'
- version: 5.100.8(react@19.2.5)
+ version: 5.100.9(react@19.2.5)
'@trpc/client':
specifier: 'catalog:'
version: 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3)
@@ -1521,13 +1522,13 @@ importers:
version: 11.17.0(typescript@5.9.3)
'@trpc/tanstack-react-query':
specifier: 'catalog:'
- version: 11.17.0(@tanstack/react-query@5.100.8(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)
+ version: 11.17.0(@tanstack/react-query@5.100.9(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)
react:
specifier: 'catalog:'
version: 19.2.5
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -1711,10 +1712,10 @@ importers:
version: 0.31.10
drizzle-orm:
specifier: 'catalog:'
- version: 0.45.2(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.9.0)(mysql2@3.22.3(@types/node@24.12.2))(pg@8.20.0)
+ version: 0.45.2(@libsql/client-wasm@0.14.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.9.0)(gel@2.0.0)(mysql2@3.22.3(@types/node@24.12.2))(pg@8.20.0)
drizzle-zod:
specifier: 'catalog:'
- version: 0.8.3(drizzle-orm@0.45.2(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.9.0)(mysql2@3.22.3(@types/node@24.12.2))(pg@8.20.0))(zod@4.4.2)
+ version: 0.8.3(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.9.0)(gel@2.0.0)(mysql2@3.22.3(@types/node@24.12.2))(pg@8.20.0))(zod@4.4.3)
mysql2:
specifier: 'catalog:'
version: 3.22.3(@types/node@24.12.2)
@@ -1769,7 +1770,7 @@ importers:
version: 5.7.2
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -1837,10 +1838,10 @@ importers:
version: 8.3.18(react@19.2.5)
mantine-form-zod-resolver:
specifier: 'catalog:'
- version: 1.3.0(@mantine/form@8.3.18(react@19.2.5))(zod@4.4.2)
+ version: 1.3.0(@mantine/form@8.3.18(react@19.2.5))(zod@4.4.3)
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -1892,7 +1893,7 @@ importers:
version: 19.2.5
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -1979,7 +1980,7 @@ importers:
version: 8.0.0
'@ctrl/qbittorrent':
specifier: 'catalog:'
- version: 9.11.2
+ version: 9.12.1
'@ctrl/transmission':
specifier: 'catalog:'
version: 7.4.0
@@ -2048,7 +2049,7 @@ importers:
version: 0.6.2
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -2161,7 +2162,7 @@ importers:
version: 19.2.5(react@19.2.5)
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -2265,10 +2266,10 @@ importers:
version: 2.2.6
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
zod-form-data:
specifier: 'catalog:'
- version: 3.0.1(zod@4.4.2)
+ version: 3.0.1(zod@4.4.3)
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -2296,7 +2297,7 @@ importers:
version: link:../common
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -2380,7 +2381,7 @@ importers:
dependencies:
'@extractus/feed-extractor':
specifier: 'catalog:'
- version: 7.1.7
+ version: 7.2.1
'@homarr/common':
specifier: workspace:^0.1.0
version: link:../common
@@ -2416,7 +2417,7 @@ importers:
version: 7.24.6
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -2698,10 +2699,10 @@ importers:
version: link:../translation
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
zod-form-data:
specifier: 'catalog:'
- version: 3.0.1(zod@4.4.2)
+ version: 3.0.1(zod@4.4.3)
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -2858,7 +2859,7 @@ importers:
version: 1.11.20
mantine-form-zod-resolver:
specifier: 'catalog:'
- version: 1.3.0(@mantine/form@8.3.18(react@19.2.5))(zod@4.4.2)
+ version: 1.3.0(@mantine/form@8.3.18(react@19.2.5))(zod@4.4.3)
mantine-react-table:
specifier: 'catalog:'
version: 2.0.0-beta.9(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@mantine/dates@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@mantine/hooks@8.3.18(react@19.2.5))(dayjs@1.11.20)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@mantine/hooks@8.3.18(react@19.2.5))(@tabler/icons-react@3.41.1(react@19.2.5))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
@@ -2885,7 +2886,7 @@ importers:
version: 8.23.7
zod:
specifier: 'catalog:'
- version: 4.4.2
+ version: 4.4.3
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0
@@ -2986,6 +2987,12 @@ packages:
'@actions/io@3.0.2':
resolution: {integrity: sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==}
+ '@ark/schema@0.46.0':
+ resolution: {integrity: sha512-c2UQdKgP2eqqDArfBqQIJppxJHvNNXuQPeuSPlDML4rjw+f1cu0qAlzOG4b8ujgm9ctIDWwhpyw6gjG5ledIVQ==}
+
+ '@ark/util@0.46.0':
+ resolution: {integrity: sha512-JPy/NGWn/lvf1WmGCPw2VGpBg5utZraE84I7wli18EDF3p3zc/e9WolT35tINeZO3l7C77SjqRJeAUoT0CvMRg==}
+
'@asamuzakjp/css-color@5.1.11':
resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
@@ -3172,8 +3179,8 @@ packages:
resolution: {integrity: sha512-fEfw3AeQ8XhVsNzogZrnyTNDD/Tpbfl3ybHsspBMvj0UKctabApv1JV3JJUQG/hoX6hiO+DtQS+acN7dMPX01g==}
engines: {node: '>20'}
- '@ctrl/qbittorrent@9.11.2':
- resolution: {integrity: sha512-ZIayGA72R4rzXaCcEYrxBwOMYZ1iT0EABJPwjTkwaO3VYRBBltwHSAxNfMWaz4GVmqLA12/WCfx+IPXBN9Gtxg==}
+ '@ctrl/qbittorrent@9.12.1':
+ resolution: {integrity: sha512-6rSTWPV0UwehqLCyBLh9Avw5FPA1nh8SO+aTxrEXu6okZPjz+3tn7EGZdLhOfy+6poIc7miX/1g1VAOVo3JSTA==}
engines: {node: '>=18'}
'@ctrl/shared-torrent@6.5.1':
@@ -3757,8 +3764,8 @@ packages:
'@noble/hashes':
optional: true
- '@extractus/feed-extractor@7.1.7':
- resolution: {integrity: sha512-eNeddvKK9rBxWSHj5zBo6ODihJqJtq+QzEQdVeadkOK48avmdela+c2JAfMcPEBMFaWcAYV4bUMhI9Tqi8mX2Q==}
+ '@extractus/feed-extractor@7.2.1':
+ resolution: {integrity: sha512-vc84NZST31wLDTesAkmHL8GBxSB2zw2/h9ZKiQMB71az13sC65EeAcDeLJ2z3atsIhtxESnCMaKmQdOrFiFLcg==}
engines: {node: '>= 20'}
'@fastify/ajv-compiler@4.0.5':
@@ -4233,6 +4240,14 @@ packages:
'@kwsites/file-exists@1.1.1':
resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==}
+ '@libsql/client-wasm@0.14.0':
+ resolution: {integrity: sha512-gB/jtz0xuwrqAHApBv9e9JSew2030Fhj2edyZ83InZ4yPj/Q2LTUlEhaspEYT0T0xsAGqPy38uGrmq/OGS+DdQ==}
+ bundledDependencies:
+ - '@libsql/libsql-wasm-experimental'
+
+ '@libsql/core@0.14.0':
+ resolution: {integrity: sha512-nhbuXf7GP3PSZgdCY2Ecj8vz187ptHlZQ0VRc751oB2C1W8jQUXKKklvt7t1LJiUTQBVJuadF628eUk+3cRi4Q==}
+
'@mantine/charts@8.3.18':
resolution: {integrity: sha512-oudif3EUH7Nb9DPm0abAPxpFYDWWjR3k2S5ll0/CcB+pJzlhwaBG19QwpOJaRA6VAvAXDDKOXCO4mi9XCEN78g==}
peerDependencies:
@@ -4320,9 +4335,6 @@ packages:
react: ^18.x || ^19.x
react-dom: ^18.x || ^19.x
- '@ndaidong/bellajs@12.0.1':
- resolution: {integrity: sha512-1iY42uiHz0cxNMbde7O3zVN+ZX1viOOUOBRt6ht6lkRZbSjwOnFV34Zv4URp3hGzEe6L9Byk7BOq/41H0PzAOQ==}
-
'@next/env@16.2.4':
resolution: {integrity: sha512-dKkkOzOSwFYe5RX6y26fZgkSpVAlIOJKQHIiydQcrWH6y/97+RceSOAdjZ14Qa3zLduVUy0TXcn+EiM6t4rPgw==}
@@ -4598,6 +4610,9 @@ packages:
resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==}
engines: {node: '>= 10.0.0'}
+ '@petamoriken/float16@3.9.3':
+ resolution: {integrity: sha512-8awtpHXCx/bNpFt4mt2xdkgtgVvKqty8VbjHI/WWWQuEw+KLzFot3f4+LkQY9YmOtq7A5GdOnqoIC8Pdygjk2g==}
+
'@pinojs/redact@0.4.0':
resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==}
@@ -4650,6 +4665,10 @@ packages:
'@protobufjs/utf8@1.1.0':
resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
+ '@pwshub/bellajs@13.0.2':
+ resolution: {integrity: sha512-OWOaE7Ieufo7VMv957iahOzv/w5oXyyXO28Jh2x6rLU96ZLqC508kAKTgdMJRXgVjda2s+/0C6Kno+k16OmJsQ==}
+ engines: {bun: '>=1.0.0', node: '>=20.0.0'}
+
'@reduxjs/toolkit@2.11.2':
resolution: {integrity: sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==}
peerDependencies:
@@ -5128,27 +5147,27 @@ packages:
resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==}
engines: {node: '>=12'}
- '@tanstack/query-core@5.100.8':
- resolution: {integrity: sha512-ceYwSFOqjPwET5TA6IOYxzxlGc0ekyH/gfOtWkP0PX43rzX9bxW48Iuw8KAduKCToi4rJAQ6nRy2kAe8gszdmg==}
+ '@tanstack/query-core@5.100.9':
+ resolution: {integrity: sha512-SJSFw1S8+kQ0+knv/XGfrbocWoAlT7vDKsSImtLx3ZPQmEcR46hkDjLSvynSy25N8Ms4tIEini1FuBd5k7IscQ==}
- '@tanstack/query-devtools@5.100.8':
- resolution: {integrity: sha512-29D6k564h7eudwNdfRcq6Je2VFUWGxHwADPg1xC2yHxrovYBwZiqzIv/DkPRsK/EMoOIPIvPq+IU0uCxiQXYPA==}
+ '@tanstack/query-devtools@5.100.9':
+ resolution: {integrity: sha512-gqiptrTIhbK2PuCaPRHmWXfJG1NGYVFpAr0HqogEqiSBNB5xDz6fmesQt7w4WgMOqOQPnPHJ3ZDMuhDaXvNO8g==}
- '@tanstack/react-query-devtools@5.100.8':
- resolution: {integrity: sha512-BKpysWo1u3kVMtv92XOv/Gu6eCbE/IxBLJPs0GG/qyySUQvZI2h7mqRwyf8Aa6WfUoX8Yf2AAh0uugQLAr8KtQ==}
+ '@tanstack/react-query-devtools@5.100.9':
+ resolution: {integrity: sha512-mM3slaVGXJmz+pOLgXdANj75ikgQCyudyl3kmFvm6brI1JyVeY/+IeD17uDHIvZrD8hfoO2sdZ54RFsHdYAuhA==}
peerDependencies:
- '@tanstack/react-query': ^5.100.8
+ '@tanstack/react-query': ^5.100.9
react: ^18 || ^19
- '@tanstack/react-query-next-experimental@5.100.8':
- resolution: {integrity: sha512-B1p5yeqWeLrWasZ0s2pG7b7do37XNXIlzHnj8RcEsoJ8DsGWXvAfSjXgnLvG0HdZUTPWjHrVRMIJ0Pgmy+bCtw==}
+ '@tanstack/react-query-next-experimental@5.100.9':
+ resolution: {integrity: sha512-cXkeZW/lEQaVmB3l0eiej5lJUNix4xxWWxOzgIJYC8D4fwgl1Kwf/bb9Av92hm6MKjWyixNCJ1wmjWrhFtuCGA==}
peerDependencies:
- '@tanstack/react-query': ^5.100.8
+ '@tanstack/react-query': ^5.100.9
next: ^13 || ^14 || ^15 || ^16
react: ^18 || ^19
- '@tanstack/react-query@5.100.8':
- resolution: {integrity: sha512-iNNEekixXU5vtAGKKZX2lx3jTooG5yNY+kv0wSgEdEYG0Mj0JM5bcuQtC35ZAP3nDopT6jciUK3xeX65U7AnfA==}
+ '@tanstack/react-query@5.100.9':
+ resolution: {integrity: sha512-Oa44XkaI3kCNN6ME0KByU3xT3SEUNOMfZpHxL6+wFoTm+OeUFYHKdeYVe0aOXlRDm/f15sgLwEt2HDorIdW8+A==}
peerDependencies:
react: ^18 || ^19
@@ -6018,6 +6037,9 @@ packages:
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
engines: {node: '>= 0.4'}
+ arktype@2.1.20:
+ resolution: {integrity: sha512-IZCEEXaJ8g+Ijd59WtSYwtjnqXiwM8sWQ5EjGamcto7+HVN9eK0C4p0zDlCuAwWhpqr6fIBkxPuYDl4/Mcj/+Q==}
+
array-buffer-byte-length@1.0.2:
resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
engines: {node: '>= 0.4'}
@@ -6496,9 +6518,6 @@ packages:
engines: {node: '>=20'}
hasBin: true
- cross-fetch@4.1.0:
- resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==}
-
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
@@ -6909,6 +6928,10 @@ packages:
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
engines: {node: '>=6'}
+ env-paths@3.0.0:
+ resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
environment@1.1.0:
resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==}
engines: {node: '>=18'}
@@ -7339,6 +7362,11 @@ packages:
functions-have-names@1.2.3:
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+ gel@2.0.0:
+ resolution: {integrity: sha512-Oq3Fjay71s00xzDc0BF/mpcLmnA+uRqMEJK8p5K4PaZjUEsxaeo+kR9OHBVAf289/qPd+0OcLOLUN0UhqiUCog==}
+ engines: {node: '>= 18.0.0'}
+ hasBin: true
+
generate-function@2.3.1:
resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==}
@@ -7840,6 +7868,10 @@ packages:
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+ isexe@3.1.5:
+ resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==}
+ engines: {node: '>=18'}
+
isomorphic-dompurify@3.12.0:
resolution: {integrity: sha512-8n+j+6ypTHvriJwFOQ2qusQ6bzGjZVcR3jbe1pBpLcGI1dn4WIl0ctLBngqE5QttquQBAlKXwJeTMw+X7x7qKw==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0}
@@ -7905,6 +7937,9 @@ packages:
react:
optional: true
+ js-base64@3.7.8:
+ resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==}
+
js-file-download@0.4.12:
resolution: {integrity: sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==}
@@ -10138,8 +10173,8 @@ packages:
resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
engines: {node: '>=16'}
- type-fest@5.5.0:
- resolution: {integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==}
+ type-fest@5.6.0:
+ resolution: {integrity: sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==}
engines: {node: '>=20'}
type-is@1.6.18:
@@ -10177,8 +10212,8 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
- ufo@1.6.3:
- resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==}
+ ufo@1.6.4:
+ resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==}
uglify-js@3.19.3:
resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==}
@@ -10535,6 +10570,11 @@ packages:
engines: {node: '>= 8'}
hasBin: true
+ which@4.0.0:
+ resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==}
+ engines: {node: ^16.13.0 || >=18.0.0}
+ hasBin: true
+
why-is-node-running@2.3.0:
resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
engines: {node: '>=8'}
@@ -10702,8 +10742,8 @@ packages:
peerDependencies:
zod: ^3.25.0 || ^4.0.0
- zod@4.4.2:
- resolution: {integrity: sha512-IynmDyxsEsb9RKzO3J9+4SxXnl2FTFSzNBaKKaMV6tsSk0rw9gYw9gs+JFCq/qk2LCZ78KDwyj+Z289TijSkUw==}
+ zod@4.4.3:
+ resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
@@ -10726,6 +10766,14 @@ snapshots:
'@actions/io@3.0.2': {}
+ '@ark/schema@0.46.0':
+ dependencies:
+ '@ark/util': 0.46.0
+ optional: true
+
+ '@ark/util@0.46.0':
+ optional: true
+
'@asamuzakjp/css-color@5.1.11':
dependencies:
'@asamuzakjp/generational-cache': 1.0.1
@@ -10924,8 +10972,8 @@ snapshots:
cookie-es: 3.0.1
node-fetch-native: 1.6.7
ofetch: 1.5.1
- type-fest: 5.5.0
- ufo: 1.6.3
+ type-fest: 5.6.0
+ ufo: 1.6.4
uint8array-extras: 1.5.0
'@ctrl/magnet-link@4.3.0':
@@ -10933,7 +10981,7 @@ snapshots:
rfc4648: 1.5.4
uint8array-extras: 1.5.0
- '@ctrl/qbittorrent@9.11.2':
+ '@ctrl/qbittorrent@9.12.1':
dependencies:
'@ctrl/magnet-link': 4.3.0
'@ctrl/shared-torrent': 6.5.1(ofetch@1.5.1)
@@ -10941,8 +10989,8 @@ snapshots:
cookie: 1.1.1
node-fetch-native: 1.6.7
ofetch: 1.5.1
- type-fest: 5.5.0
- ufo: 1.6.3
+ type-fest: 5.6.0
+ ufo: 1.6.4
uint8array-extras: 1.5.0
'@ctrl/shared-torrent@6.5.1(ofetch@1.5.1)':
@@ -10957,7 +11005,7 @@ snapshots:
'@ctrl/shared-torrent': 6.5.1(ofetch@1.5.1)
ofetch: 1.5.1
type-fest: 4.41.0
- ufo: 1.6.3
+ ufo: 1.6.4
uint8array-extras: 1.5.0
'@dabh/diagnostics@2.0.8':
@@ -11291,14 +11339,11 @@ snapshots:
optionalDependencies:
'@noble/hashes': 2.0.1
- '@extractus/feed-extractor@7.1.7':
+ '@extractus/feed-extractor@7.2.1':
dependencies:
- '@ndaidong/bellajs': 12.0.1
- cross-fetch: 4.1.0
+ '@pwshub/bellajs': 13.0.2
fast-xml-parser: 5.7.2
html-entities: 2.6.0
- transitivePeerDependencies:
- - encoding
'@fastify/ajv-compiler@4.0.5':
dependencies:
@@ -11759,6 +11804,17 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@libsql/client-wasm@0.14.0':
+ dependencies:
+ '@libsql/core': 0.14.0
+ js-base64: 3.7.8
+ optional: true
+
+ '@libsql/core@0.14.0':
+ dependencies:
+ js-base64: 3.7.8
+ optional: true
+
'@mantine/charts@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@mantine/hooks@8.3.18(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(recharts@3.8.1(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react-is@19.2.5)(react@19.2.5)(redux@5.0.1))':
dependencies:
'@mantine/core': 8.3.18(@mantine/hooks@8.3.18(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
@@ -11849,8 +11905,6 @@ snapshots:
react: 19.2.5
react-dom: 19.2.5(react@19.2.5)
- '@ndaidong/bellajs@12.0.1': {}
-
'@next/env@16.2.4': {}
'@next/eslint-plugin-next@16.2.4':
@@ -12110,6 +12164,9 @@ snapshots:
'@parcel/watcher-win32-ia32': 2.4.1
'@parcel/watcher-win32-x64': 2.4.1
+ '@petamoriken/float16@3.9.3':
+ optional: true
+
'@pinojs/redact@0.4.0': {}
'@pkgjs/parseargs@0.11.0':
@@ -12152,6 +12209,8 @@ snapshots:
'@protobufjs/utf8@1.1.0': {}
+ '@pwshub/bellajs@13.0.2': {}
+
'@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.2.14)(react@19.2.5)(redux@5.0.1))(react@19.2.5)':
dependencies:
'@standard-schema/spec': 1.1.0
@@ -12853,17 +12912,19 @@ snapshots:
dependencies:
'@swc/counter': 0.1.3
- '@t3-oss/env-core@0.13.11(typescript@5.9.3)(zod@4.4.2)':
+ '@t3-oss/env-core@0.13.11(arktype@2.1.20)(typescript@5.9.3)(zod@4.4.3)':
optionalDependencies:
+ arktype: 2.1.20
typescript: 5.9.3
- zod: 4.4.2
+ zod: 4.4.3
- '@t3-oss/env-nextjs@0.13.11(typescript@5.9.3)(zod@4.4.2)':
+ '@t3-oss/env-nextjs@0.13.11(arktype@2.1.20)(typescript@5.9.3)(zod@4.4.3)':
dependencies:
- '@t3-oss/env-core': 0.13.11(typescript@5.9.3)(zod@4.4.2)
+ '@t3-oss/env-core': 0.13.11(arktype@2.1.20)(typescript@5.9.3)(zod@4.4.3)
optionalDependencies:
+ arktype: 2.1.20
typescript: 5.9.3
- zod: 4.4.2
+ zod: 4.4.3
'@tabler/icons-react@3.41.1(react@19.2.5)':
dependencies:
@@ -12876,25 +12937,25 @@ snapshots:
dependencies:
remove-accents: 0.5.0
- '@tanstack/query-core@5.100.8': {}
+ '@tanstack/query-core@5.100.9': {}
- '@tanstack/query-devtools@5.100.8': {}
+ '@tanstack/query-devtools@5.100.9': {}
- '@tanstack/react-query-devtools@5.100.8(@tanstack/react-query@5.100.8(react@19.2.5))(react@19.2.5)':
+ '@tanstack/react-query-devtools@5.100.9(@tanstack/react-query@5.100.9(react@19.2.5))(react@19.2.5)':
dependencies:
- '@tanstack/query-devtools': 5.100.8
- '@tanstack/react-query': 5.100.8(react@19.2.5)
+ '@tanstack/query-devtools': 5.100.9
+ '@tanstack/react-query': 5.100.9(react@19.2.5)
react: 19.2.5
- '@tanstack/react-query-next-experimental@5.100.8(@tanstack/react-query@5.100.8(react@19.2.5))(next@16.2.4(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(sass@1.99.0))(react@19.2.5)':
+ '@tanstack/react-query-next-experimental@5.100.9(@tanstack/react-query@5.100.9(react@19.2.5))(next@16.2.4(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(sass@1.99.0))(react@19.2.5)':
dependencies:
- '@tanstack/react-query': 5.100.8(react@19.2.5)
+ '@tanstack/react-query': 5.100.9(react@19.2.5)
next: 16.2.4(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(sass@1.99.0)
react: 19.2.5
- '@tanstack/react-query@5.100.8(react@19.2.5)':
+ '@tanstack/react-query@5.100.9(react@19.2.5)':
dependencies:
- '@tanstack/query-core': 5.100.8
+ '@tanstack/query-core': 5.100.9
react: 19.2.5
'@tanstack/react-table@8.20.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
@@ -13167,7 +13228,7 @@ snapshots:
'@trpc/server': 11.17.0(typescript@5.9.3)
typescript: 5.9.3
- '@trpc/next@11.17.0(@tanstack/react-query@5.100.8(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/react-query@11.17.0(@tanstack/react-query@5.100.8(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(next@16.2.4(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(sass@1.99.0))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@5.9.3)':
+ '@trpc/next@11.17.0(@tanstack/react-query@5.100.9(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/react-query@11.17.0(@tanstack/react-query@5.100.9(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(next@16.2.4(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(sass@1.99.0))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@5.9.3)':
dependencies:
'@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3)
'@trpc/server': 11.17.0(typescript@5.9.3)
@@ -13176,12 +13237,12 @@ snapshots:
react-dom: 19.2.5(react@19.2.5)
typescript: 5.9.3
optionalDependencies:
- '@tanstack/react-query': 5.100.8(react@19.2.5)
- '@trpc/react-query': 11.17.0(@tanstack/react-query@5.100.8(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)
+ '@tanstack/react-query': 5.100.9(react@19.2.5)
+ '@trpc/react-query': 11.17.0(@tanstack/react-query@5.100.9(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)
- '@trpc/react-query@11.17.0(@tanstack/react-query@5.100.8(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)':
+ '@trpc/react-query@11.17.0(@tanstack/react-query@5.100.9(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)':
dependencies:
- '@tanstack/react-query': 5.100.8(react@19.2.5)
+ '@tanstack/react-query': 5.100.9(react@19.2.5)
'@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3)
'@trpc/server': 11.17.0(typescript@5.9.3)
react: 19.2.5
@@ -13191,9 +13252,9 @@ snapshots:
dependencies:
typescript: 5.9.3
- '@trpc/tanstack-react-query@11.17.0(@tanstack/react-query@5.100.8(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)':
+ '@trpc/tanstack-react-query@11.17.0(@tanstack/react-query@5.100.9(react@19.2.5))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.5)(typescript@5.9.3)':
dependencies:
- '@tanstack/react-query': 5.100.8(react@19.2.5)
+ '@tanstack/react-query': 5.100.9(react@19.2.5)
'@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3)
'@trpc/server': 11.17.0(typescript@5.9.3)
react: 19.2.5
@@ -13879,6 +13940,12 @@ snapshots:
aria-query@5.3.2: {}
+ arktype@2.1.20:
+ dependencies:
+ '@ark/schema': 0.46.0
+ '@ark/util': 0.46.0
+ optional: true
+
array-buffer-byte-length@1.0.2:
dependencies:
call-bound: 1.0.4
@@ -14382,12 +14449,6 @@ snapshots:
'@epic-web/invariant': 1.0.0
cross-spawn: 7.0.6
- cross-fetch@4.1.0:
- dependencies:
- node-fetch: 2.7.0
- transitivePeerDependencies:
- - encoding
-
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
@@ -14640,18 +14701,20 @@ snapshots:
esbuild: 0.25.12
tsx: 4.21.0
- drizzle-orm@0.45.2(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.9.0)(mysql2@3.22.3(@types/node@24.12.2))(pg@8.20.0):
+ drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.9.0)(gel@2.0.0)(mysql2@3.22.3(@types/node@24.12.2))(pg@8.20.0):
optionalDependencies:
+ '@libsql/client-wasm': 0.14.0
'@types/better-sqlite3': 7.6.13
'@types/pg': 8.20.0
better-sqlite3: 12.9.0
+ gel: 2.0.0
mysql2: 3.22.3(@types/node@24.12.2)
pg: 8.20.0
- drizzle-zod@0.8.3(drizzle-orm@0.45.2(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.9.0)(mysql2@3.22.3(@types/node@24.12.2))(pg@8.20.0))(zod@4.4.2):
+ drizzle-zod@0.8.3(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.9.0)(gel@2.0.0)(mysql2@3.22.3(@types/node@24.12.2))(pg@8.20.0))(zod@4.4.3):
dependencies:
- drizzle-orm: 0.45.2(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.9.0)(mysql2@3.22.3(@types/node@24.12.2))(pg@8.20.0)
- zod: 4.4.2
+ drizzle-orm: 0.45.2(@libsql/client-wasm@0.14.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.9.0)(gel@2.0.0)(mysql2@3.22.3(@types/node@24.12.2))(pg@8.20.0)
+ zod: 4.4.3
dunder-proto@1.0.1:
dependencies:
@@ -14697,6 +14760,9 @@ snapshots:
env-paths@2.2.1: {}
+ env-paths@3.0.0:
+ optional: true
+
environment@1.1.0: {}
error-causes@3.0.2: {}
@@ -14988,8 +15054,8 @@ snapshots:
'@babel/core': 7.29.0
'@babel/parser': 7.29.2
eslint: 10.3.0
- zod: 4.4.2
- zod-validation-error: 4.0.2(zod@4.4.2)
+ zod: 4.4.3
+ zod-validation-error: 4.0.2(zod@4.4.3)
transitivePeerDependencies:
- supports-color
@@ -15346,6 +15412,18 @@ snapshots:
functions-have-names@1.2.3: {}
+ gel@2.0.0:
+ dependencies:
+ '@petamoriken/float16': 3.9.3
+ debug: 4.4.3
+ env-paths: 3.0.0
+ semver: 7.7.4
+ shell-quote: 1.8.3
+ which: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+ optional: true
+
generate-function@2.3.1:
dependencies:
is-property: 1.0.2
@@ -15464,7 +15542,7 @@ snapshots:
iron-webcrypto: 1.2.1
node-mock-http: 1.0.2
radix3: 1.1.2
- ufo: 1.6.3
+ ufo: 1.6.4
uncrypto: 0.1.3
handlebars@4.7.8:
@@ -15847,6 +15925,9 @@ snapshots:
isexe@2.0.0: {}
+ isexe@3.1.5:
+ optional: true
+
isomorphic-dompurify@3.12.0(@noble/hashes@2.0.1):
dependencies:
dompurify: 3.4.2
@@ -15916,6 +15997,9 @@ snapshots:
'@types/react': 19.2.14
react: 19.2.5
+ js-base64@3.7.8:
+ optional: true
+
js-file-download@0.4.12: {}
js-tokens@10.0.0: {}
@@ -16146,10 +16230,10 @@ snapshots:
dependencies:
semver: 7.7.4
- mantine-form-zod-resolver@1.3.0(@mantine/form@8.3.18(react@19.2.5))(zod@4.4.2):
+ mantine-form-zod-resolver@1.3.0(@mantine/form@8.3.18(react@19.2.5))(zod@4.4.3):
dependencies:
'@mantine/form': 8.3.18(react@19.2.5)
- zod: 4.4.2
+ zod: 4.4.3
mantine-react-table@2.0.0-beta.9(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@mantine/dates@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@mantine/hooks@8.3.18(react@19.2.5))(dayjs@1.11.20)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@mantine/hooks@8.3.18(react@19.2.5))(@tabler/icons-react@3.41.1(react@19.2.5))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.5(react@19.2.5))(react@19.2.5):
dependencies:
@@ -16709,7 +16793,7 @@ snapshots:
dependencies:
destr: 2.0.5
node-fetch-native: 1.6.7
- ufo: 1.6.3
+ ufo: 1.6.4
on-exit-leak-free@2.1.2: {}
@@ -17388,14 +17472,14 @@ snapshots:
dependencies:
find-up-simple: 1.0.1
read-pkg: 10.0.0
- type-fest: 5.5.0
+ type-fest: 5.6.0
read-pkg@10.0.0:
dependencies:
'@types/normalize-package-data': 2.4.4
normalize-package-data: 8.0.0
parse-json: 8.3.0
- type-fest: 5.5.0
+ type-fest: 5.6.0
unicorn-magic: 0.3.0
read-pkg@9.0.1:
@@ -18389,14 +18473,14 @@ snapshots:
trough@2.2.0: {}
- trpc-to-openapi@3.2.0(patch_hash=2ca3c16af0fcca0c736697ad4fe553a14f794524fa9ce0d5c3e8ee4aea76090c)(@trpc/server@11.17.0(typescript@5.9.3))(zod-openapi@5.3.0(zod@4.4.2))(zod@4.4.2):
+ trpc-to-openapi@3.2.0(patch_hash=2ca3c16af0fcca0c736697ad4fe553a14f794524fa9ce0d5c3e8ee4aea76090c)(@trpc/server@11.17.0(typescript@5.9.3))(zod-openapi@5.3.0(zod@4.4.3))(zod@4.4.3):
dependencies:
'@trpc/server': 11.17.0(typescript@5.9.3)
co-body: 6.2.0
h3: 1.15.1
openapi3-ts: 4.4.0
- zod: 4.4.2
- zod-openapi: 5.3.0(zod@4.4.2)
+ zod: 4.4.3
+ zod-openapi: 5.3.0(zod@4.4.3)
optionalDependencies:
'@rollup/rollup-linux-x64-gnu': 4.6.1
@@ -18474,7 +18558,7 @@ snapshots:
type-fest@4.41.0: {}
- type-fest@5.5.0:
+ type-fest@5.6.0:
dependencies:
tagged-tag: 1.0.0
@@ -18533,7 +18617,7 @@ snapshots:
typescript@5.9.3: {}
- ufo@1.6.3: {}
+ ufo@1.6.4: {}
uglify-js@3.19.3:
optional: true
@@ -18912,6 +18996,11 @@ snapshots:
dependencies:
isexe: 2.0.0
+ which@4.0.0:
+ dependencies:
+ isexe: 3.1.5
+ optional: true
+
why-is-node-running@2.3.0:
dependencies:
siginfo: 2.0.0
@@ -19058,23 +19147,23 @@ snapshots:
compress-commons: 6.0.2
readable-stream: 4.5.2
- zod-form-data@3.0.1(zod@4.4.2):
+ zod-form-data@3.0.1(zod@4.4.3):
dependencies:
'@rvf/set-get': 7.0.1
- zod: 4.4.2
+ zod: 4.4.3
- zod-openapi@5.3.0(zod@4.4.2):
+ zod-openapi@5.3.0(zod@4.4.3):
dependencies:
- zod: 4.4.2
+ zod: 4.4.3
- zod-validation-error@4.0.2(zod@4.4.2):
+ zod-validation-error@4.0.2(zod@4.4.3):
dependencies:
- zod: 4.4.2
+ zod: 4.4.3
- zod-validation-error@5.0.0(zod@4.4.2):
+ zod-validation-error@5.0.0(zod@4.4.3):
dependencies:
- zod: 4.4.2
+ zod: 4.4.3
- zod@4.4.2: {}
+ zod@4.4.3: {}
zwitch@2.0.4: {}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 3856311d7..3ad0b0849 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -2,35 +2,19 @@ packages:
- apps/*
- packages/*
- tooling/*
-allowBuilds:
- "@scarf/scarf": false
- "@swc/core": false
- "@tree-sitter-grammars/tree-sitter-yaml": true
- bcrypt: true
- better-sqlite3: true
- core-js-pure: false
- cpu-features: true
- esbuild: true
- protobufjs: false
- sharp: true
- ssh2: true
- tree-sitter: true
- tree-sitter-json: true
- nice-napi: false
-allowUnusedPatches: true
catalog:
"@auth/core": ^0.41.2
"@auth/drizzle-adapter": ^1.11.2
"@ctrl/deluge": ^8.0.0
- "@ctrl/qbittorrent": ^9.11.2
+ "@ctrl/qbittorrent": ^9.12.1
"@ctrl/transmission": ^7.4.0
"@dnd-kit/core": ^6.3.1
"@dnd-kit/modifiers": ^9.0.0
"@dnd-kit/sortable": ^10.0.0
"@dnd-kit/utilities": ^3.2.2
"@drizzle-team/brocli": ^0.12.0
- "@eslint/js": 10.0.1
- "@extractus/feed-extractor": 7.1.7
+ '@eslint/js': 10.0.1
+ "@extractus/feed-extractor": 7.2.1
"@gitbeaker/rest": ^43.8.0
"@homarr/gridstack": ^1.12.0
"@homarr/node-unifi": ^2.6.0
@@ -60,9 +44,9 @@ catalog:
"@semantic-release/release-notes-generator": ^14.1.0
"@t3-oss/env-nextjs": ^0.13.11
"@tabler/icons-react": ^3.41.1
- "@tanstack/react-query": ^5.100.8
- "@tanstack/react-query-devtools": ^5.100.8
- "@tanstack/react-query-next-experimental": ^5.100.8
+ "@tanstack/react-query": ^5.100.9
+ "@tanstack/react-query-devtools": ^5.100.9
+ "@tanstack/react-query-next-experimental": ^5.100.9
"@testcontainers/mysql": ^11.14.0
"@testcontainers/postgresql": ^11.14.0
"@testcontainers/redis": ^11.14.0
@@ -87,7 +71,7 @@ catalog:
"@trpc/react-query": ^11.17.0
"@trpc/server": ^11.17.0
"@trpc/tanstack-react-query": ^11.17.0
- "@turbo/gen": ^2.9.7
+ "@turbo/gen": ^2.9.8
"@types/adm-zip": 0.5.8
"@types/bcrypt": 6.0.0
"@types/better-sqlite3": 7.6.13
@@ -138,7 +122,7 @@ catalog:
esbuild: ^0.28.0
eslint: ^10.3.0
eslint-config-prettier: ^10.1.8
- eslint-config-turbo: ^2.9.7
+ eslint-config-turbo: ^2.9.8
eslint-plugin-import: ^2.32.0
eslint-plugin-jsx-a11y: ^6.10.2
eslint-plugin-react: ^7.37.5
@@ -188,7 +172,7 @@ catalog:
trpc-to-openapi: ^3.2.0
tsdav: ^2.2.0
tsx: 4.20.4
- turbo: ^2.9.7
+ turbo: ^2.9.8
typescript: ^5.9.3
typescript-eslint: ^8.58.2
undici: 7.24.6
@@ -200,36 +184,11 @@ catalog:
ws: ^8.20.0
xml2js: ^0.6.2
yaml: 2.8.4
- zod: ^4.4.2
+ zod: ^4.4.3
zod-form-data: ^3.0.1
zod-validation-error: ^5.0.0
catalogMode: strict
-engineStrict: true
minimumReleaseAge: 4320
minimumReleaseAgeExclude:
- next
- "@next/*"
-nodeLinker: hoisted
-overrides:
- "@babel/helpers@<7.26.10": ">=7.29.2"
- "@babel/runtime@<7.26.10": ">=7.29.2"
- "axios@>=1.0.0 <1.8.2": ">=1.16.0"
- "brace-expansion@>=1.0.0 <=1.1.11": ">=5.0.5"
- "brace-expansion@>=2.0.0 <=2.0.1": ">=5.0.5"
- "esbuild@<=0.24.2": ">=0.28.0"
- "form-data@>=4.0.0 <4.0.4": ">=4.0.5"
- "hono@<4.6.5": ">=4.12.16"
- "linkifyjs@<4.3.2": ">=4.3.2"
- "nanoid@>=4.0.0 <5.0.9": ">=5.1.11"
- "prismjs@<1.30.0": ">=1.30.0"
- "proxmox-api>undici": "7.24.6"
- "react-is": "^19.2.5"
- "rollup@>=4.0.0 <4.22.4": ">=4.60.2"
- "sha.js@<=2.4.11": ">=2.4.12"
- "tar-fs@>=2.0.0 <2.1.3": ">=3.1.2"
- "tar-fs@>=3.0.0 <3.0.9": ">=3.1.2"
- "tmp@<=0.2.3": ">=0.2.5"
- "vite@>=5.0.0 <=5.4.18": ">=8.0.10"
-patchedDependencies:
- "@types/node-unifi": "patches/@types__node-unifi.patch"
- trpc-to-openapi: "patches/trpc-to-openapi.patch"
diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh
index c362eac3a..f4d7c9fa4 100644
--- a/scripts/entrypoint.sh
+++ b/scripts/entrypoint.sh
@@ -18,6 +18,19 @@ if [ "${PUID}" != "0" ] || [ "${PGID}" != "0" ]; then
echo "Changing owner to $PUID:$PGID, done."
fi
+# support _FILE Suffix for environment variables
+for file_var in $(env | cut -d '=' -f 1 | grep "_FILE$"); do
+ target_var=$(echo "$file_var" | cut -d'=' -f1 | sed 's/_FILE//')
+ file_path=$(printenv "$file_var")
+
+ if [ -f "$file_path" ]; then
+ export "$target_var"=$(cat "$file_path" | tr -d '\n\r')
+ echo "Info: Loaded secret for $target_var from $file_path"
+ else
+ echo "Warning: Secret file $file_path not found for $target_var"
+ fi
+done
+
if [ "${PUID}" != "0" ]; then
exec su-exec $PUID:$PGID "$@"
else
diff --git a/scripts/run.sh b/scripts/run.sh
index 4d90499d5..78659a04a 100644
--- a/scripts/run.sh
+++ b/scripts/run.sh
@@ -19,11 +19,6 @@ export AUTH_SECRET=$(openssl rand -base64 32)
# Cron job API key is generated every time the container starts as it is required for communication between nextjs-api and tasks-api
export CRON_JOB_API_KEY=$(openssl rand -base64 32)
-# Support secret file for encryption key (is not empty and file exists)
-if [ -n "$SECRET_ENCRYPTION_KEY_FILE" ] && [ -f "$SECRET_ENCRYPTION_KEY_FILE" ]; then
- export SECRET_ENCRYPTION_KEY=$(cat $SECRET_ENCRYPTION_KEY_FILE)
-fi
-
# Start nginx proxy
# 1. Replace the HOSTNAME in the nginx template file
# 2. Create the nginx configuration file from the template
diff --git a/static-data/contributors.json b/static-data/contributors.json
index 5db83ab61..d6a6b43fa 100644
--- a/static-data/contributors.json
+++ b/static-data/contributors.json
@@ -1 +1 @@
-[{"login":"ajnart","avatar_url":"https://avatars.githubusercontent.com/u/49837342?v=4"},{"login":"manuel-rw","avatar_url":"https://avatars.githubusercontent.com/u/30572287?v=4"},{"login":"Meierschlumpf","avatar_url":"https://avatars.githubusercontent.com/u/63781622?v=4"},{"login":"SeDemal","avatar_url":"https://avatars.githubusercontent.com/u/26098587?v=4"},{"login":"lammersbjorn","avatar_url":"https://avatars.githubusercontent.com/u/71191962?v=4"},{"login":"LarveyOfficial","avatar_url":"https://avatars.githubusercontent.com/u/39219859?v=4"},{"login":"c00ldude1oo","avatar_url":"https://avatars.githubusercontent.com/u/15677803?v=4"},{"login":"InterN0te","avatar_url":"https://avatars.githubusercontent.com/u/10882916?v=4"},{"login":"Aimsucks","avatar_url":"https://avatars.githubusercontent.com/u/1828486?v=4"},{"login":"JannesV","avatar_url":"https://avatars.githubusercontent.com/u/5984244?v=4"},{"login":"MauriceNino","avatar_url":"https://avatars.githubusercontent.com/u/18658092?v=4"},{"login":"hillaliy","avatar_url":"https://avatars.githubusercontent.com/u/950010?v=4"},{"login":"Skeeww","avatar_url":"https://avatars.githubusercontent.com/u/9639992?v=4"},{"login":"RichyHBM","avatar_url":"https://avatars.githubusercontent.com/u/5472275?v=4"},{"login":"Bonfire","avatar_url":"https://avatars.githubusercontent.com/u/5704760?v=4"},{"login":"wieli99","avatar_url":"https://avatars.githubusercontent.com/u/46794825?v=4"},{"login":"ishaanparlikar","avatar_url":"https://avatars.githubusercontent.com/u/43013132?v=4"},{"login":"Zareix","avatar_url":"https://avatars.githubusercontent.com/u/29818713?v=4"},{"login":"tuggan","avatar_url":"https://avatars.githubusercontent.com/u/4325608?v=4"},{"login":"Spillebulle","avatar_url":"https://avatars.githubusercontent.com/u/46653946?v=4"},{"login":"spkesDE","avatar_url":"https://avatars.githubusercontent.com/u/1682314?v=4"},{"login":"j3lte","avatar_url":"https://avatars.githubusercontent.com/u/2557568?v=4"},{"login":"dslatt","avatar_url":"https://avatars.githubusercontent.com/u/5211001?v=4"},{"login":"Malong11-007","avatar_url":"https://avatars.githubusercontent.com/u/40298510?v=4"},{"login":"StefanB7","avatar_url":"https://avatars.githubusercontent.com/u/22056509?v=4"},{"login":"souravghosh01","avatar_url":"https://avatars.githubusercontent.com/u/37548139?v=4"},{"login":"SR3u","avatar_url":"https://avatars.githubusercontent.com/u/2380522?v=4"},{"login":"Rikpat","avatar_url":"https://avatars.githubusercontent.com/u/33869814?v=4"},{"login":"NormanJS","avatar_url":"https://avatars.githubusercontent.com/u/83409549?v=4"},{"login":"No-Maines-Land","avatar_url":"https://avatars.githubusercontent.com/u/20687725?v=4"},{"login":"stark1tty","avatar_url":"https://avatars.githubusercontent.com/u/69326376?v=4"},{"login":"Momcilo42","avatar_url":"https://avatars.githubusercontent.com/u/10118137?v=4"},{"login":"marius-arch","avatar_url":"https://avatars.githubusercontent.com/u/72494359?v=4"},{"login":"Lumilias","avatar_url":"https://avatars.githubusercontent.com/u/10852161?v=4"},{"login":"Havock94","avatar_url":"https://avatars.githubusercontent.com/u/7635248?v=4"},{"login":"Lollyde","avatar_url":"https://avatars.githubusercontent.com/u/11347524?v=4"},{"login":"krishnamuppaneni","avatar_url":"https://avatars.githubusercontent.com/u/4703366?v=4"},{"login":"devtobi","avatar_url":"https://avatars.githubusercontent.com/u/28538704?v=4"},{"login":"TyxTang","avatar_url":"https://avatars.githubusercontent.com/u/90897955?v=4"},{"login":"alotlikebeans","avatar_url":"https://avatars.githubusercontent.com/u/19630511?v=4"},{"login":"WillyJL","avatar_url":"https://avatars.githubusercontent.com/u/49810075?v=4"},{"login":"anonysoul","avatar_url":"https://avatars.githubusercontent.com/u/105715150?v=4"},{"login":"cospeedster","avatar_url":"https://avatars.githubusercontent.com/u/52749645?v=4"},{"login":"diederbert","avatar_url":"https://avatars.githubusercontent.com/u/162878798?v=4"},{"login":"digdilem","avatar_url":"https://avatars.githubusercontent.com/u/4052275?v=4"},{"login":"dinghino","avatar_url":"https://avatars.githubusercontent.com/u/14729459?v=4"},{"login":"gfomichev","avatar_url":"https://avatars.githubusercontent.com/u/1596146?v=4"},{"login":"gnattu","avatar_url":"https://avatars.githubusercontent.com/u/12995396?v=4"},{"login":"tuxpizza","avatar_url":"https://avatars.githubusercontent.com/u/84710786?v=4"},{"login":"xmarkurion","avatar_url":"https://avatars.githubusercontent.com/u/46654687?v=4"},{"login":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?v=4"},{"login":"taos15","avatar_url":"https://avatars.githubusercontent.com/u/122130728?v=4"},{"login":"arghyadipchak","avatar_url":"https://avatars.githubusercontent.com/u/32430374?v=4"},{"login":"AuthorShin","avatar_url":"https://avatars.githubusercontent.com/u/4959043?v=4"},{"login":"benniblot","avatar_url":"https://avatars.githubusercontent.com/u/47495914?v=4"},{"login":"bebsworthy","avatar_url":"https://avatars.githubusercontent.com/u/5266759?v=4"},{"login":"catrielmuller","avatar_url":"https://avatars.githubusercontent.com/u/2272323?v=4"},{"login":"Vysp3r","avatar_url":"https://avatars.githubusercontent.com/u/62019735?v=4"},{"login":"DR-Blogs","avatar_url":"https://avatars.githubusercontent.com/u/96393186?v=4"},{"login":"singular0","avatar_url":"https://avatars.githubusercontent.com/u/1925883?v=4"},{"login":"diogovalentte","avatar_url":"https://avatars.githubusercontent.com/u/49578155?v=4"},{"login":"codezninja","avatar_url":"https://avatars.githubusercontent.com/u/4400773?v=4"},{"login":"fabricionaweb","avatar_url":"https://avatars.githubusercontent.com/u/15933?v=4"},{"login":"nyok1912","avatar_url":"https://avatars.githubusercontent.com/u/32163949?v=4"},{"login":"bo3bdo","avatar_url":"https://avatars.githubusercontent.com/u/5271380?v=4"},{"login":"hskrtich","avatar_url":"https://avatars.githubusercontent.com/u/1214484?v=4"},{"login":"ishults","avatar_url":"https://avatars.githubusercontent.com/u/7275442?v=4"},{"login":"jelliuk","avatar_url":"https://avatars.githubusercontent.com/u/4790959?v=4"},{"login":"Moohan","avatar_url":"https://avatars.githubusercontent.com/u/5982260?v=4"},{"login":"tesar-tech","avatar_url":"https://avatars.githubusercontent.com/u/33880579?v=4"},{"login":"jbruell","avatar_url":"https://avatars.githubusercontent.com/u/31685172?v=4"},{"login":"JasonLeeB06","avatar_url":"https://avatars.githubusercontent.com/u/82266978?v=4"},{"login":"jeffersonraimon","avatar_url":"https://avatars.githubusercontent.com/u/80064475?v=4"},{"login":"jo-chemla","avatar_url":"https://avatars.githubusercontent.com/u/16822841?v=4"},{"login":"joser93","avatar_url":"https://avatars.githubusercontent.com/u/6912089?v=4"},{"login":"justijndepover","avatar_url":"https://avatars.githubusercontent.com/u/9008623?v=4"},{"login":"Aandree5","avatar_url":"https://avatars.githubusercontent.com/u/32734153?v=4"},{"login":"jackwellerreal","avatar_url":"https://avatars.githubusercontent.com/u/97435840?v=4"},{"login":"SergioChan","avatar_url":"https://avatars.githubusercontent.com/u/10103766?v=4"},{"login":"toineenzo","avatar_url":"https://avatars.githubusercontent.com/u/4921397?v=4"},{"login":"oben01","avatar_url":"https://avatars.githubusercontent.com/u/22369027?v=4"},{"login":"rezstje","avatar_url":"https://avatars.githubusercontent.com/u/45420315?v=4"},{"login":"castielwaverly","avatar_url":"https://avatars.githubusercontent.com/u/137005689?v=4"},{"login":"xoxyuxu","avatar_url":"https://avatars.githubusercontent.com/u/3543416?v=4"},{"login":"MaienM","avatar_url":"https://avatars.githubusercontent.com/u/583129?v=4"},{"login":"mvanhorn","avatar_url":"https://avatars.githubusercontent.com/u/455140?v=4"},{"login":"HeapReaper","avatar_url":"https://avatars.githubusercontent.com/u/31496522?v=4"},{"login":"Copilot","avatar_url":"https://avatars.githubusercontent.com/in/1143301?v=4"},{"login":"mairas","avatar_url":"https://avatars.githubusercontent.com/u/407010?v=4"},{"login":"itzTheMeow","avatar_url":"https://avatars.githubusercontent.com/u/50887230?v=4"},{"login":"NicolasNewman","avatar_url":"https://avatars.githubusercontent.com/u/16135852?v=4"},{"login":"NikeLaosClericus","avatar_url":"https://avatars.githubusercontent.com/u/39810627?v=4"},{"login":"noahcroghan","avatar_url":"https://avatars.githubusercontent.com/u/27422774?v=4"},{"login":"ohmzi","avatar_url":"https://avatars.githubusercontent.com/u/6551272?v=4"},{"login":"Rhiz3K","avatar_url":"https://avatars.githubusercontent.com/u/33246262?v=4"},{"login":"saschabuehrle","avatar_url":"https://avatars.githubusercontent.com/u/47737812?v=4"},{"login":"StrandedTurtle","avatar_url":"https://avatars.githubusercontent.com/u/132835255?v=4"},{"login":"CrazyWolf13","avatar_url":"https://avatars.githubusercontent.com/u/96661824?v=4"},{"login":"generalmat82","avatar_url":"https://avatars.githubusercontent.com/u/110256073?v=4"},{"login":"lthomsen","avatar_url":"https://avatars.githubusercontent.com/u/28560325?v=4"},{"login":"pitschi","avatar_url":"https://avatars.githubusercontent.com/u/6841565?v=4"},{"login":"tech62","avatar_url":"https://avatars.githubusercontent.com/u/16237642?v=4"},{"login":"leandroscardua","avatar_url":"https://avatars.githubusercontent.com/u/24698541?v=4"},{"login":"kylegrieder","avatar_url":"https://avatars.githubusercontent.com/u/25424229?v=4"},{"login":"hotrungnhan","avatar_url":"https://avatars.githubusercontent.com/u/40029631?v=4"},{"login":"KelianB","avatar_url":"https://avatars.githubusercontent.com/u/11216155?v=4"},{"login":"Kaotic3","avatar_url":"https://avatars.githubusercontent.com/u/80522225?v=4"},{"login":"frankvHoof93","avatar_url":"https://avatars.githubusercontent.com/u/7346516?v=4"},{"login":"faugusto-oliveira","avatar_url":"https://avatars.githubusercontent.com/u/37384074?v=4"},{"login":"ieugen","avatar_url":"https://avatars.githubusercontent.com/u/1050920?v=4"},{"login":"KartulUdus","avatar_url":"https://avatars.githubusercontent.com/u/23346150?v=4"},{"login":"dgshue","avatar_url":"https://avatars.githubusercontent.com/u/12952156?v=4"},{"login":"DZ945brH","avatar_url":"https://avatars.githubusercontent.com/u/42635243?v=4"},{"login":"Oupsman","avatar_url":"https://avatars.githubusercontent.com/u/11260343?v=4"},{"login":"m0s4ik","avatar_url":"https://avatars.githubusercontent.com/u/26578395?v=4"},{"login":"AartSchinkel","avatar_url":"https://avatars.githubusercontent.com/u/189675191?v=4"}]
\ No newline at end of file
+[{"login":"ajnart","avatar_url":"https://avatars.githubusercontent.com/u/49837342?v=4"},{"login":"manuel-rw","avatar_url":"https://avatars.githubusercontent.com/u/30572287?v=4"},{"login":"Meierschlumpf","avatar_url":"https://avatars.githubusercontent.com/u/63781622?v=4"},{"login":"SeDemal","avatar_url":"https://avatars.githubusercontent.com/u/26098587?v=4"},{"login":"lammersbjorn","avatar_url":"https://avatars.githubusercontent.com/u/71191962?v=4"},{"login":"LarveyOfficial","avatar_url":"https://avatars.githubusercontent.com/u/39219859?v=4"},{"login":"c00ldude1oo","avatar_url":"https://avatars.githubusercontent.com/u/15677803?v=4"},{"login":"InterN0te","avatar_url":"https://avatars.githubusercontent.com/u/10882916?v=4"},{"login":"Aimsucks","avatar_url":"https://avatars.githubusercontent.com/u/1828486?v=4"},{"login":"JannesV","avatar_url":"https://avatars.githubusercontent.com/u/5984244?v=4"},{"login":"MauriceNino","avatar_url":"https://avatars.githubusercontent.com/u/18658092?v=4"},{"login":"hillaliy","avatar_url":"https://avatars.githubusercontent.com/u/950010?v=4"},{"login":"Skeeww","avatar_url":"https://avatars.githubusercontent.com/u/9639992?v=4"},{"login":"RichyHBM","avatar_url":"https://avatars.githubusercontent.com/u/5472275?v=4"},{"login":"Bonfire","avatar_url":"https://avatars.githubusercontent.com/u/5704760?v=4"},{"login":"wieli99","avatar_url":"https://avatars.githubusercontent.com/u/46794825?v=4"},{"login":"ishaanparlikar","avatar_url":"https://avatars.githubusercontent.com/u/43013132?v=4"},{"login":"Zareix","avatar_url":"https://avatars.githubusercontent.com/u/29818713?v=4"},{"login":"tuggan","avatar_url":"https://avatars.githubusercontent.com/u/4325608?v=4"},{"login":"Spillebulle","avatar_url":"https://avatars.githubusercontent.com/u/46653946?v=4"},{"login":"spkesDE","avatar_url":"https://avatars.githubusercontent.com/u/1682314?v=4"},{"login":"j3lte","avatar_url":"https://avatars.githubusercontent.com/u/2557568?v=4"},{"login":"dslatt","avatar_url":"https://avatars.githubusercontent.com/u/5211001?v=4"},{"login":"Malong11-007","avatar_url":"https://avatars.githubusercontent.com/u/40298510?v=4"},{"login":"StefanB7","avatar_url":"https://avatars.githubusercontent.com/u/22056509?v=4"},{"login":"souravghosh01","avatar_url":"https://avatars.githubusercontent.com/u/37548139?v=4"},{"login":"SR3u","avatar_url":"https://avatars.githubusercontent.com/u/2380522?v=4"},{"login":"Rikpat","avatar_url":"https://avatars.githubusercontent.com/u/33869814?v=4"},{"login":"NormanJS","avatar_url":"https://avatars.githubusercontent.com/u/83409549?v=4"},{"login":"No-Maines-Land","avatar_url":"https://avatars.githubusercontent.com/u/20687725?v=4"},{"login":"stark1tty","avatar_url":"https://avatars.githubusercontent.com/u/69326376?v=4"},{"login":"Momcilo42","avatar_url":"https://avatars.githubusercontent.com/u/10118137?v=4"},{"login":"marius-arch","avatar_url":"https://avatars.githubusercontent.com/u/72494359?v=4"},{"login":"Lumilias","avatar_url":"https://avatars.githubusercontent.com/u/10852161?v=4"},{"login":"Havock94","avatar_url":"https://avatars.githubusercontent.com/u/7635248?v=4"},{"login":"Lollyde","avatar_url":"https://avatars.githubusercontent.com/u/11347524?v=4"},{"login":"krishnamuppaneni","avatar_url":"https://avatars.githubusercontent.com/u/4703366?v=4"},{"login":"devtobi","avatar_url":"https://avatars.githubusercontent.com/u/28538704?v=4"},{"login":"TyxTang","avatar_url":"https://avatars.githubusercontent.com/u/90897955?v=4"},{"login":"alotlikebeans","avatar_url":"https://avatars.githubusercontent.com/u/19630511?v=4"},{"login":"WillyJL","avatar_url":"https://avatars.githubusercontent.com/u/49810075?v=4"},{"login":"anonysoul","avatar_url":"https://avatars.githubusercontent.com/u/105715150?v=4"},{"login":"cospeedster","avatar_url":"https://avatars.githubusercontent.com/u/52749645?v=4"},{"login":"diederbert","avatar_url":"https://avatars.githubusercontent.com/u/162878798?v=4"},{"login":"digdilem","avatar_url":"https://avatars.githubusercontent.com/u/4052275?v=4"},{"login":"dinghino","avatar_url":"https://avatars.githubusercontent.com/u/14729459?v=4"},{"login":"gfomichev","avatar_url":"https://avatars.githubusercontent.com/u/1596146?v=4"},{"login":"gnattu","avatar_url":"https://avatars.githubusercontent.com/u/12995396?v=4"},{"login":"tuxpizza","avatar_url":"https://avatars.githubusercontent.com/u/84710786?v=4"},{"login":"xmarkurion","avatar_url":"https://avatars.githubusercontent.com/u/46654687?v=4"},{"login":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?v=4"},{"login":"taos15","avatar_url":"https://avatars.githubusercontent.com/u/122130728?v=4"},{"login":"arghyadipchak","avatar_url":"https://avatars.githubusercontent.com/u/32430374?v=4"},{"login":"AuthorShin","avatar_url":"https://avatars.githubusercontent.com/u/4959043?v=4"},{"login":"benniblot","avatar_url":"https://avatars.githubusercontent.com/u/47495914?v=4"},{"login":"bebsworthy","avatar_url":"https://avatars.githubusercontent.com/u/5266759?v=4"},{"login":"catrielmuller","avatar_url":"https://avatars.githubusercontent.com/u/2272323?v=4"},{"login":"Vysp3r","avatar_url":"https://avatars.githubusercontent.com/u/62019735?v=4"},{"login":"DR-Blogs","avatar_url":"https://avatars.githubusercontent.com/u/96393186?v=4"},{"login":"singular0","avatar_url":"https://avatars.githubusercontent.com/u/1925883?v=4"},{"login":"diogovalentte","avatar_url":"https://avatars.githubusercontent.com/u/49578155?v=4"},{"login":"codezninja","avatar_url":"https://avatars.githubusercontent.com/u/4400773?v=4"},{"login":"fabricionaweb","avatar_url":"https://avatars.githubusercontent.com/u/15933?v=4"},{"login":"nyok1912","avatar_url":"https://avatars.githubusercontent.com/u/32163949?v=4"},{"login":"bo3bdo","avatar_url":"https://avatars.githubusercontent.com/u/5271380?v=4"},{"login":"hskrtich","avatar_url":"https://avatars.githubusercontent.com/u/1214484?v=4"},{"login":"ishults","avatar_url":"https://avatars.githubusercontent.com/u/7275442?v=4"},{"login":"jelliuk","avatar_url":"https://avatars.githubusercontent.com/u/4790959?v=4"},{"login":"Moohan","avatar_url":"https://avatars.githubusercontent.com/u/5982260?v=4"},{"login":"tesar-tech","avatar_url":"https://avatars.githubusercontent.com/u/33880579?v=4"},{"login":"jbruell","avatar_url":"https://avatars.githubusercontent.com/u/31685172?v=4"},{"login":"JasonLeeB06","avatar_url":"https://avatars.githubusercontent.com/u/82266978?v=4"},{"login":"jeffersonraimon","avatar_url":"https://avatars.githubusercontent.com/u/80064475?v=4"},{"login":"jo-chemla","avatar_url":"https://avatars.githubusercontent.com/u/16822841?v=4"},{"login":"joser93","avatar_url":"https://avatars.githubusercontent.com/u/6912089?v=4"},{"login":"justijndepover","avatar_url":"https://avatars.githubusercontent.com/u/9008623?v=4"},{"login":"Aandree5","avatar_url":"https://avatars.githubusercontent.com/u/32734153?v=4"},{"login":"jackwellerreal","avatar_url":"https://avatars.githubusercontent.com/u/97435840?v=4"},{"login":"mvanhorn","avatar_url":"https://avatars.githubusercontent.com/u/455140?v=4"},{"login":"SergioChan","avatar_url":"https://avatars.githubusercontent.com/u/10103766?v=4"},{"login":"toineenzo","avatar_url":"https://avatars.githubusercontent.com/u/4921397?v=4"},{"login":"oben01","avatar_url":"https://avatars.githubusercontent.com/u/22369027?v=4"},{"login":"rezstje","avatar_url":"https://avatars.githubusercontent.com/u/45420315?v=4"},{"login":"castielwaverly","avatar_url":"https://avatars.githubusercontent.com/u/137005689?v=4"},{"login":"xoxyuxu","avatar_url":"https://avatars.githubusercontent.com/u/3543416?v=4"},{"login":"MaienM","avatar_url":"https://avatars.githubusercontent.com/u/583129?v=4"},{"login":"kylegrieder","avatar_url":"https://avatars.githubusercontent.com/u/25424229?v=4"},{"login":"HeapReaper","avatar_url":"https://avatars.githubusercontent.com/u/31496522?v=4"},{"login":"Copilot","avatar_url":"https://avatars.githubusercontent.com/in/1143301?v=4"},{"login":"itzTheMeow","avatar_url":"https://avatars.githubusercontent.com/u/50887230?v=4"},{"login":"NicolasNewman","avatar_url":"https://avatars.githubusercontent.com/u/16135852?v=4"},{"login":"NikeLaosClericus","avatar_url":"https://avatars.githubusercontent.com/u/39810627?v=4"},{"login":"noahcroghan","avatar_url":"https://avatars.githubusercontent.com/u/27422774?v=4"},{"login":"ohmzi","avatar_url":"https://avatars.githubusercontent.com/u/6551272?v=4"},{"login":"Rhiz3K","avatar_url":"https://avatars.githubusercontent.com/u/33246262?v=4"},{"login":"saschabuehrle","avatar_url":"https://avatars.githubusercontent.com/u/47737812?v=4"},{"login":"StrandedTurtle","avatar_url":"https://avatars.githubusercontent.com/u/132835255?v=4"},{"login":"CrazyWolf13","avatar_url":"https://avatars.githubusercontent.com/u/96661824?v=4"},{"login":"generalmat82","avatar_url":"https://avatars.githubusercontent.com/u/110256073?v=4"},{"login":"lthomsen","avatar_url":"https://avatars.githubusercontent.com/u/28560325?v=4"},{"login":"pitschi","avatar_url":"https://avatars.githubusercontent.com/u/6841565?v=4"},{"login":"sharpsalat","avatar_url":"https://avatars.githubusercontent.com/u/15666932?v=4"},{"login":"tech62","avatar_url":"https://avatars.githubusercontent.com/u/16237642?v=4"},{"login":"mairas","avatar_url":"https://avatars.githubusercontent.com/u/407010?v=4"},{"login":"leandroscardua","avatar_url":"https://avatars.githubusercontent.com/u/24698541?v=4"},{"login":"hotrungnhan","avatar_url":"https://avatars.githubusercontent.com/u/40029631?v=4"},{"login":"KelianB","avatar_url":"https://avatars.githubusercontent.com/u/11216155?v=4"},{"login":"Kaotic3","avatar_url":"https://avatars.githubusercontent.com/u/80522225?v=4"},{"login":"febrile42","avatar_url":"https://avatars.githubusercontent.com/u/14597122?v=4"},{"login":"frankvHoof93","avatar_url":"https://avatars.githubusercontent.com/u/7346516?v=4"},{"login":"faugusto-oliveira","avatar_url":"https://avatars.githubusercontent.com/u/37384074?v=4"},{"login":"ieugen","avatar_url":"https://avatars.githubusercontent.com/u/1050920?v=4"},{"login":"KartulUdus","avatar_url":"https://avatars.githubusercontent.com/u/23346150?v=4"},{"login":"dgshue","avatar_url":"https://avatars.githubusercontent.com/u/12952156?v=4"},{"login":"DZ945brH","avatar_url":"https://avatars.githubusercontent.com/u/42635243?v=4"},{"login":"Oupsman","avatar_url":"https://avatars.githubusercontent.com/u/11260343?v=4"},{"login":"m0s4ik","avatar_url":"https://avatars.githubusercontent.com/u/26578395?v=4"},{"login":"AartSchinkel","avatar_url":"https://avatars.githubusercontent.com/u/189675191?v=4"}]
\ No newline at end of file
diff --git a/test/renovate.spec.ts b/test/renovate.spec.ts
index 2b8236ce6..0f40a8061 100644
--- a/test/renovate.spec.ts
+++ b/test/renovate.spec.ts
@@ -2,24 +2,21 @@ import fs from "fs/promises";
import { join } from "path";
import json5 from "json5";
import { describe, test } from "vitest";
-import { parse as parseYaml } from "yaml";
describe("Renovate configuration tests", () => {
- test("automerge should be disabled for built dependencies", async () => {
- const pnpmConfig = await fs.readFile(join(__dirname, "../pnpm-workspace.yaml"), "utf-8").then(parseYaml);
+ test("automerge should be disabled for onlyBuiltDependencies", async () => {
+ const packageJson = await import("../package.json");
const renovateConfig = await fs.readFile(join(__dirname, "../.github/renovate.json5"), "utf-8").then(json5.parse);
- const dependenciesWithBuilt = Object.entries(pnpmConfig.allowBuilds)
- .filter(([_, value]) => value === true)
- .map(([key, _]) => key);
+ const onlyBuiltDependencies = packageJson.pnpm.onlyBuiltDependencies;
const automergeDisabledDeps = renovateConfig.packageRules
.filter((rule: any) => rule.automerge === false)
.flatMap((rule: any) => rule.matchPackageNames || []);
- const missingDeps = dependenciesWithBuilt.filter((dep: string) => !automergeDisabledDeps.includes(dep));
+ const missingDeps = onlyBuiltDependencies.filter((dep: string) => !automergeDisabledDeps.includes(dep));
if (missingDeps.length > 0) {
throw new Error(
- `The following built dependencies are missing automerge disable rules in renovate.json5: ${missingDeps.join(", ")}`,
+ `The following onlyBuiltDependencies are missing automerge disable rules in renovate.json5: ${missingDeps.join(", ")}`,
);
}
});
diff --git a/turbo.json b/turbo.json
index 208d42365..33b661f69 100644
--- a/turbo.json
+++ b/turbo.json
@@ -37,6 +37,7 @@
"DB_DRIVER",
"DOCKER_HOSTNAMES",
"DOCKER_PORTS",
+ "DOCKER_SOCKET_PATHS",
"NODE_ENV",
"PORT",
"LOCAL_CERTIFICATE_PATH",