Compare commits

..
Author SHA1 Message Date
Meier Lukas 0513a8e6f5 feat(integrations): add suggestions to manage home page 2025-06-12 22:36:37 +02:00
54 changed files with 1395 additions and 1206 deletions

No files matched your search

-1
View File
@@ -31,7 +31,6 @@ body:
label: Version
description: What version of Homarr are you running?
options:
- 1.24.0
- 1.23.0
- 1.22.0
- 1.21.0
-65
View File
@@ -1,68 +1,3 @@
## [1.25.0](https://github.com/homarr-labs/homarr/compare/v1.24.0...v1.25.0) (2025-06-20)
### Features
* **integrations:** add support for self-signed-cert-in-chain request error ([#3399](https://github.com/homarr-labs/homarr/issues/3399)) ([e6cb35b](https://github.com/homarr-labs/homarr/commit/e6cb35b7c2dc45349a9cf0819aa21228aea03e26))
### Bug Fixes
* **deps:** update dependency node-cron to ^4.1.1 ([#3427](https://github.com/homarr-labs/homarr/issues/3427)) ([f6a99ff](https://github.com/homarr-labs/homarr/commit/f6a99ffedd690c01e18f445ade6343f1ca476b27))
* **deps:** update dependency swagger-ui-react to ^5.24.2 ([#3405](https://github.com/homarr-labs/homarr/issues/3405)) ([bdca920](https://github.com/homarr-labs/homarr/commit/bdca92036a3dde7f655735c305e55c5c15b63440))
* **deps:** update dependency swagger-ui-react to ^5.25.2 ([#3420](https://github.com/homarr-labs/homarr/issues/3420)) ([02cd7a5](https://github.com/homarr-labs/homarr/commit/02cd7a50dad9e954cfd569b0f1efcc4fe4fd5da4))
* **deps:** update dependency tsdav to ^2.1.5 ([#3414](https://github.com/homarr-labs/homarr/issues/3414)) ([6bcfe78](https://github.com/homarr-labs/homarr/commit/6bcfe789561c518e7ce6c78a9be95412a50f04dd))
* **deps:** update dependency typescript-eslint to ^8.34.1 ([#3409](https://github.com/homarr-labs/homarr/issues/3409)) ([637bfb8](https://github.com/homarr-labs/homarr/commit/637bfb8b47b7dc6c70163bd481c47bca9bd93d55))
* **deps:** update dependency zod to ^3.25.65 ([#3410](https://github.com/homarr-labs/homarr/issues/3410)) ([a8c9c07](https://github.com/homarr-labs/homarr/commit/a8c9c075f08bca4b86307e98156cae7167ef6ab1))
* **deps:** update dependency zod to ^3.25.67 ([#3413](https://github.com/homarr-labs/homarr/issues/3413)) ([56ca8b7](https://github.com/homarr-labs/homarr/commit/56ca8b7b0b1c0187457c085af1c7f4504d72ed9a))
* **deps:** update dependency zod-validation-error to ^3.5.1 ([#3406](https://github.com/homarr-labs/homarr/issues/3406)) ([adbef25](https://github.com/homarr-labs/homarr/commit/adbef252c61c29fbbc8c7b0e325a0e9d69bb3191))
* **deps:** update dependency zod-validation-error to ^3.5.2 ([#3417](https://github.com/homarr-labs/homarr/issues/3417)) ([430f671](https://github.com/homarr-labs/homarr/commit/430f6714345b5b90859fd3302f76fd3d14956148))
* **deps:** update mantine monorepo to ^8.1.1 ([#3404](https://github.com/homarr-labs/homarr/issues/3404)) ([f97a261](https://github.com/homarr-labs/homarr/commit/f97a2619734dcf3b326c69587fa2f4e170cb9c88))
* **deps:** update nextjs monorepo to v15.3.4 ([#3421](https://github.com/homarr-labs/homarr/issues/3421)) ([3759a98](https://github.com/homarr-labs/homarr/commit/3759a9831c6fe54b0b0eb0e101c8eb912b752b41))
* **deps:** update tanstack-query monorepo to ^5.80.10 ([#3422](https://github.com/homarr-labs/homarr/issues/3422)) ([7c58e8a](https://github.com/homarr-labs/homarr/commit/7c58e8ac9bdb2868637648b43b7965189421b295))
* **deps:** update tiptap monorepo to v2.14.1 ([#3423](https://github.com/homarr-labs/homarr/issues/3423)) ([9e4b463](https://github.com/homarr-labs/homarr/commit/9e4b4635bc582e4d92821844d58fdb3d057f7fec))
* **deps:** update tiptap monorepo to v2.22.0 ([#3425](https://github.com/homarr-labs/homarr/issues/3425)) ([ec4dde6](https://github.com/homarr-labs/homarr/commit/ec4dde64fdd4302b091a0255ec1bcdc6b2caca89))
* **deps:** update trpc monorepo to ^11.4.2 ([#3419](https://github.com/homarr-labs/homarr/issues/3419)) ([8e428e2](https://github.com/homarr-labs/homarr/commit/8e428e20a764c54c15fc44b57f85fa684cfbc00e))
* **downloads:** not updating automatically ([#3412](https://github.com/homarr-labs/homarr/issues/3412)) ([b5ef7e5](https://github.com/homarr-labs/homarr/commit/b5ef7e5194a828abfddcac5eb492910de5f1f7d8))
* **widget-integration-select:** fixed error about `<p>` being descendant of `<p>` ([#3418](https://github.com/homarr-labs/homarr/issues/3418)) ([73fff02](https://github.com/homarr-labs/homarr/commit/73fff02ad0a3a710aa39cda7dccf9206569c2879))
## [1.24.0](https://github.com/homarr-labs/homarr/compare/v1.23.0...v1.24.0) (2025-06-13)
### Features
* reduce cron job intervals ([#3235](https://github.com/homarr-labs/homarr/issues/3235)) ([f67702e](https://github.com/homarr-labs/homarr/commit/f67702e1d32954b4f6db28c02b1a25e56122d779))
### Bug Fixes
* csp prevents external videos ([#3372](https://github.com/homarr-labs/homarr/issues/3372)) ([c59cded](https://github.com/homarr-labs/homarr/commit/c59cdeda47a504069c09634dafe36a9bc80c922f))
* **deps:** update dependency @t3-oss/env-nextjs to ^0.13.7 ([#3357](https://github.com/homarr-labs/homarr/issues/3357)) ([22f0cd8](https://github.com/homarr-labs/homarr/commit/22f0cd885e6b3f0cd15daa60840554a545eb2532))
* **deps:** update dependency @t3-oss/env-nextjs to ^0.13.8 ([#3364](https://github.com/homarr-labs/homarr/issues/3364)) ([ab3ee3b](https://github.com/homarr-labs/homarr/commit/ab3ee3bac186913cbc76c1381c90b3c90a447185))
* **deps:** update dependency fast-xml-parser to ^5.2.5 ([#3353](https://github.com/homarr-labs/homarr/issues/3353)) ([9e86de6](https://github.com/homarr-labs/homarr/commit/9e86de6e1781ef2c088f83af1ba341baecb496da))
* **deps:** update dependency glob to ^11.0.3 ([#3391](https://github.com/homarr-labs/homarr/issues/3391)) ([f16efac](https://github.com/homarr-labs/homarr/commit/f16efac05a17b77303f4c41b8910d491d237add2))
* **deps:** update dependency sass to ^1.89.2 ([#3362](https://github.com/homarr-labs/homarr/issues/3362)) ([b1a559d](https://github.com/homarr-labs/homarr/commit/b1a559d80161f59114ba3098005c3334662987eb))
* **deps:** update dependency swagger-ui-react to ^5.24.1 ([#3368](https://github.com/homarr-labs/homarr/issues/3368)) ([fa52b55](https://github.com/homarr-labs/homarr/commit/fa52b5582880075cd76826641547ccbf42b56f7a))
* **deps:** update dependency tsx to v4.20.0 ([#3375](https://github.com/homarr-labs/homarr/issues/3375)) ([3d07306](https://github.com/homarr-labs/homarr/commit/3d07306e7d3bf90db7f7c02d68550a137c5554bc))
* **deps:** update dependency tsx to v4.20.1 ([#3380](https://github.com/homarr-labs/homarr/issues/3380)) ([e7652ea](https://github.com/homarr-labs/homarr/commit/e7652ea4eb1ddaf8373c02abfcdb5440bf55c236))
* **deps:** update dependency tsx to v4.20.2 ([#3387](https://github.com/homarr-labs/homarr/issues/3387)) ([79519ec](https://github.com/homarr-labs/homarr/commit/79519ec0ebf4ff101fa1cd395f974e023d1af3c3))
* **deps:** update dependency tsx to v4.20.3 ([#3393](https://github.com/homarr-labs/homarr/issues/3393)) ([c9097a9](https://github.com/homarr-labs/homarr/commit/c9097a95e2072ed619e93301f8d4644aaadce2dd))
* **deps:** update dependency typescript-eslint to ^8.34.0 ([#3359](https://github.com/homarr-labs/homarr/issues/3359)) ([f6da091](https://github.com/homarr-labs/homarr/commit/f6da0915773dd60b40475f258d90e5f3dbdb6729))
* **deps:** update dependency zod to ^3.25.56 ([#3340](https://github.com/homarr-labs/homarr/issues/3340)) ([aafd883](https://github.com/homarr-labs/homarr/commit/aafd883c3250ddf3438877d82b4b63a6a15eadda))
* **deps:** update dependency zod to ^3.25.57 ([#3367](https://github.com/homarr-labs/homarr/issues/3367)) ([e7a9797](https://github.com/homarr-labs/homarr/commit/e7a9797484e9e2cd595d31e6db4cdf63e25e3b82))
* **deps:** update dependency zod to ^3.25.58 ([#3373](https://github.com/homarr-labs/homarr/issues/3373)) ([f37fc0e](https://github.com/homarr-labs/homarr/commit/f37fc0edfee45386b3469bac11c91e4f17c83673))
* **deps:** update dependency zod to ^3.25.60 ([#3378](https://github.com/homarr-labs/homarr/issues/3378)) ([7388c90](https://github.com/homarr-labs/homarr/commit/7388c907a57c7999a48118d96a3f34d2c3656f79))
* **deps:** update dependency zod to ^3.25.61 ([#3379](https://github.com/homarr-labs/homarr/issues/3379)) ([863f935](https://github.com/homarr-labs/homarr/commit/863f935ef4c27f87a632a5e0b376fe088f4e8a04))
* **deps:** update dependency zod to ^3.25.62 ([#3382](https://github.com/homarr-labs/homarr/issues/3382)) ([0b200dc](https://github.com/homarr-labs/homarr/commit/0b200dc9e2239060ddf2670f8508f68e624e821e))
* **deps:** update dependency zod to ^3.25.63 ([#3386](https://github.com/homarr-labs/homarr/issues/3386)) ([153c2ef](https://github.com/homarr-labs/homarr/commit/153c2ef8a0098cbe2d998c98a25a0c5880f0da5d))
* **deps:** update dependency zod to ^3.25.64 ([#3392](https://github.com/homarr-labs/homarr/issues/3392)) ([5dc0ee8](https://github.com/homarr-labs/homarr/commit/5dc0ee8842dbd4bde468c5762cf5dc0d73958242))
* **deps:** update dependency zod-validation-error to ^3.5.0 ([#3388](https://github.com/homarr-labs/homarr/issues/3388)) ([747d034](https://github.com/homarr-labs/homarr/commit/747d034114bd2a3b381aa7318c59015b21811353))
* **deps:** update mantine monorepo to ^8.1.0 ([#3360](https://github.com/homarr-labs/homarr/issues/3360)) ([d862ae0](https://github.com/homarr-labs/homarr/commit/d862ae03e319d173468cd7797bd74be022cbc966))
* **deps:** update tanstack-query monorepo to ^5.80.7 ([#3385](https://github.com/homarr-labs/homarr/issues/3385)) ([c5cc8f1](https://github.com/homarr-labs/homarr/commit/c5cc8f1d375d5a582b169da706a5b433a0181c20))
* **deps:** update testcontainers-node monorepo to ^11.0.1 ([#3343](https://github.com/homarr-labs/homarr/issues/3343)) ([6ec66b1](https://github.com/homarr-labs/homarr/commit/6ec66b1fe2d5779b2267532d75d6933b3460ffd5))
* **deps:** update testcontainers-node monorepo to ^11.0.2 ([#3352](https://github.com/homarr-labs/homarr/issues/3352)) ([98c4cd1](https://github.com/homarr-labs/homarr/commit/98c4cd1e39286164c09f7d8e961488e26fa2c562))
* **deps:** update testcontainers-node monorepo to ^11.0.3 ([#3369](https://github.com/homarr-labs/homarr/issues/3369)) ([ad444e8](https://github.com/homarr-labs/homarr/commit/ad444e8fa7a186710deafd98f2aa48717de1ec80))
* **deps:** update trpc monorepo to ^11.4.0 ([#3389](https://github.com/homarr-labs/homarr/issues/3389)) ([3bf4f9e](https://github.com/homarr-labs/homarr/commit/3bf4f9e0588440d74dfaf7016acc66c1ed40843a))
* **deps:** update trpc monorepo to ^11.4.1 ([#3395](https://github.com/homarr-labs/homarr/issues/3395)) ([6d9992d](https://github.com/homarr-labs/homarr/commit/6d9992d7114f97c24e02c40dcaf11fad90608a1c))
* module not found sshcrypto.node during development ([#3349](https://github.com/homarr-labs/homarr/issues/3349)) ([1b3770a](https://github.com/homarr-labs/homarr/commit/1b3770aafbe4e903e6235dc681edac556a36e4e0))
* **pi-hole:** cached session not invalidated when changing password ([#3351](https://github.com/homarr-labs/homarr/issues/3351)) ([a9e68e1](https://github.com/homarr-labs/homarr/commit/a9e68e13d53c8e06d150ecba085680cd248d4f64))
## [1.23.0](https://github.com/homarr-labs/homarr/compare/v1.22.0...v1.23.0) (2025-06-06)
### Features
+19 -19
View File
@@ -48,21 +48,21 @@
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@homarr/widgets": "workspace:^0.1.0",
"@mantine/colors-generator": "^8.1.1",
"@mantine/core": "^8.1.1",
"@mantine/dropzone": "^8.1.1",
"@mantine/hooks": "^8.1.1",
"@mantine/modals": "^8.1.1",
"@mantine/tiptap": "^8.1.1",
"@mantine/colors-generator": "^8.1.0",
"@mantine/core": "^8.1.0",
"@mantine/dropzone": "^8.1.0",
"@mantine/hooks": "^8.1.0",
"@mantine/modals": "^8.1.0",
"@mantine/tiptap": "^8.1.0",
"@million/lint": "1.0.14",
"@tabler/icons-react": "^3.34.0",
"@tanstack/react-query": "^5.80.10",
"@tanstack/react-query-devtools": "^5.80.10",
"@tanstack/react-query-next-experimental": "^5.80.10",
"@trpc/client": "^11.4.2",
"@trpc/next": "^11.4.2",
"@trpc/react-query": "^11.4.2",
"@trpc/server": "^11.4.2",
"@tanstack/react-query": "^5.80.6",
"@tanstack/react-query-devtools": "^5.80.6",
"@tanstack/react-query-next-experimental": "^5.80.6",
"@trpc/client": "^11.3.1",
"@trpc/next": "^11.3.1",
"@trpc/react-query": "^11.3.1",
"@trpc/server": "^11.3.1",
"@xterm/addon-canvas": "^0.7.0",
"@xterm/addon-fit": "0.10.0",
"@xterm/xterm": "^5.5.0",
@@ -71,10 +71,10 @@
"dayjs": "^1.11.13",
"dotenv": "^16.5.0",
"flag-icons": "^7.5.0",
"glob": "^11.0.3",
"glob": "^11.0.2",
"jotai": "^2.12.5",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.3.4",
"next": "15.3.3",
"postcss-preset-mantine": "^1.17.0",
"prismjs": "^1.30.0",
"react": "19.1.0",
@@ -83,22 +83,22 @@
"react-simple-code-editor": "^0.14.1",
"sass": "^1.89.2",
"superjson": "2.2.2",
"swagger-ui-react": "^5.25.2",
"swagger-ui-react": "^5.24.1",
"use-deep-compare-effect": "^1.8.1",
"zod": "^3.25.67"
"zod": "^3.25.62"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/chroma-js": "3.1.1",
"@types/node": "^22.15.32",
"@types/node": "^22.15.31",
"@types/prismjs": "^1.26.5",
"@types/react": "19.1.8",
"@types/react-dom": "19.1.6",
"@types/swagger-ui-react": "^5.18.0",
"concurrently": "^9.1.2",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"node-loader": "^2.1.0",
"prettier": "^3.5.3",
"typescript": "^5.8.3"
@@ -30,8 +30,6 @@ export const CertificateErrorDetails = ({ error, url }: CertificateErrorDetailsP
const { mutateAsync: trustHostnameAsync } = clientApi.certificates.trustHostnameMismatch.useMutation();
const { mutateAsync: addCertificateAsync } = clientApi.certificates.addCertificate.useMutation();
const rootCertificate = getHeighestCertificate(error.data.certificate);
const handleTrustHostname = () => {
const { hostname } = new URL(url);
openConfirmModal({
@@ -74,7 +72,7 @@ export const CertificateErrorDetails = ({ error, url }: CertificateErrorDetailsP
const formData = new FormData();
formData.append(
"file",
new File([rootCertificate.pem], `${hostname}-${createId()}.crt`, {
new File([error.data.certificate.pem], `${hostname}-${createId()}.crt`, {
type: "application/x-x509-ca-cert",
}),
);
@@ -112,11 +110,11 @@ export const CertificateErrorDetails = ({ error, url }: CertificateErrorDetailsP
<>
{description}
<CertificateDetailsCard certificate={rootCertificate} />
<CertificateDetailsCard certificate={error.data.certificate} />
{error.data.reason === "hostnameMismatch" && <HostnameMismatchAlert />}
{!rootCertificate.isSelfSigned && error.data.reason === "untrusted" && <CertificateExtractAlert />}
{!error.data.certificate.isSelfSigned && error.data.reason === "untrusted" && <CertificateExtractAlert />}
{showRetryButton && (
<Button
@@ -129,7 +127,7 @@ export const CertificateErrorDetails = ({ error, url }: CertificateErrorDetailsP
</Button>
)}
{(error.data.reason === "untrusted" && rootCertificate.isSelfSigned) ||
{(error.data.reason === "untrusted" && error.data.certificate.isSelfSigned) ||
error.data.reason === "hostnameMismatch" ? (
<Button
variant="default"
@@ -139,7 +137,7 @@ export const CertificateErrorDetails = ({ error, url }: CertificateErrorDetailsP
{tError("certificate.action.trust.label")}
</Button>
) : null}
{error.data.reason === "untrusted" && !rootCertificate.isSelfSigned ? (
{error.data.reason === "untrusted" && !error.data.certificate.isSelfSigned ? (
<Button
variant="default"
fullWidth
@@ -327,8 +325,3 @@ const PemContentModal = createModal<{ content: string }>(({ actions, innerProps
},
size: "lg",
});
const getHeighestCertificate = (certificate: MappedCertificate): MappedCertificate => {
if (certificate.issuerCertificate) return getHeighestCertificate(certificate.issuerCertificate);
return certificate;
};
+37 -1
View File
@@ -1,13 +1,16 @@
import Link from "next/link";
import { Card, Group, SimpleGrid, Space, Stack, Text } from "@mantine/core";
import { Card, Group, SimpleGrid, Space, Stack, Text, Title } from "@mantine/core";
import { IconArrowRight } from "@tabler/icons-react";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { isProviderEnabled } from "@homarr/auth/server";
import { getIntegrationName } from "@homarr/definitions";
import { getScopedI18n } from "@homarr/translation/server";
import { IntegrationAvatar } from "@homarr/ui";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
import { catchTrpcNotFound } from "~/errors/trpc-catch-error";
import { createMetaTitle } from "~/metadata";
import { HeroBanner } from "./_components/hero-banner";
@@ -30,6 +33,8 @@ export async function generateMetadata() {
export default async function ManagementPage() {
const statistics = await api.home.getStats();
const session = await auth();
const isAdmin = session?.user.permissions.includes("admin") ?? false;
const suggestions = isAdmin ? await api.integration.suggestedIntegrations().catch(catchTrpcNotFound) : [];
const t = await getScopedI18n("management.page.home");
const links: LinkProps[] = [
@@ -102,6 +107,37 @@ export default async function ManagementPage() {
),
)}
</SimpleGrid>
{suggestions.length >= 1 && (
<>
<Space h="md" />
<Stack gap="sm">
<Stack gap={0}>
<Title order={3}>Suggested integrations</Title>
<Text c="dimmed">Based on your Docker containers</Text>
</Stack>
<SimpleGrid cols={{ xs: 1, sm: 2, md: 3 }}>
{suggestions.slice(0, 6).map((suggestion) => (
<Card key={suggestion.kind} component={Link} href="#" radius="lg">
<Group justify="space-between">
<Group>
<IntegrationAvatar kind={suggestion.kind} size="sm" />
<Stack gap={0}>
<Text size="md" fw={500}>
{getIntegrationName(suggestion.kind)}
</Text>
<Text c="dimmed" size="sm">
Show active media streams
</Text>
</Stack>
</Group>
<IconArrowRight />
</Group>
</Card>
))}
</SimpleGrid>
</Stack>
</>
)}
</>
);
}
+3 -3
View File
@@ -44,12 +44,12 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/node": "^22.15.32",
"@types/node": "^22.15.31",
"dotenv-cli": "^8.0.0",
"esbuild": "^0.25.5",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"prettier": "^3.5.3",
"tsx": "4.20.3",
"tsx": "4.20.1",
"typescript": "^5.8.3"
}
}
+2 -2
View File
@@ -26,7 +26,7 @@
"@homarr/redis": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"dotenv": "^16.5.0",
"tsx": "4.20.3",
"tsx": "4.20.1",
"ws": "^8.18.2"
},
"devDependencies": {
@@ -35,7 +35,7 @@
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/ws": "^8.18.1",
"esbuild": "^0.25.5",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"prettier": "^3.5.3",
"typescript": "^5.8.3"
}
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "homarr",
"version": "1.25.0",
"version": "1.23.0",
"private": true,
"scripts": {
"build": "cross-env CI=true turbo build",
@@ -40,8 +40,8 @@
"@semantic-release/release-notes-generator": "^14.0.3",
"@turbo/gen": "^2.5.4",
"@vitejs/plugin-react": "^4.5.2",
"@vitest/coverage-v8": "^3.2.4",
"@vitest/ui": "^3.2.4",
"@vitest/coverage-v8": "^3.2.3",
"@vitest/ui": "^3.2.3",
"conventional-changelog-conventionalcommits": "^9.0.0",
"cross-env": "^7.0.3",
"jsdom": "^26.1.0",
@@ -51,7 +51,7 @@
"turbo": "^2.5.4",
"typescript": "^5.8.3",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.2.4"
"vitest": "^3.2.3"
},
"packageManager": "pnpm@10.12.1",
"engines": {
+1 -1
View File
@@ -32,7 +32,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+8 -8
View File
@@ -41,24 +41,24 @@
"@homarr/server-settings": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@kubernetes/client-node": "^1.3.0",
"@tanstack/react-query": "^5.80.10",
"@trpc/client": "^11.4.2",
"@trpc/react-query": "^11.4.2",
"@trpc/server": "^11.4.2",
"@trpc/tanstack-react-query": "^11.4.2",
"@tanstack/react-query": "^5.80.6",
"@trpc/client": "^11.3.1",
"@trpc/react-query": "^11.3.1",
"@trpc/server": "^11.3.1",
"@trpc/tanstack-react-query": "^11.3.1",
"lodash.clonedeep": "^4.5.0",
"next": "15.3.4",
"next": "15.3.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"superjson": "2.2.2",
"trpc-to-openapi": "^2.3.1",
"zod": "^3.25.67"
"zod": "^3.25.62"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"prettier": "^3.5.3",
"typescript": "^5.8.3"
}
@@ -14,15 +14,19 @@ import {
integrationUserPermissions,
searchEngines,
} from "@homarr/db/schema";
import type { IntegrationSecretKind } from "@homarr/definitions";
import type { IntegrationKind, IntegrationSecretKind } from "@homarr/definitions";
import {
getIconUrl,
getIntegrationKindsByCategory,
getIntegrationName,
getPermissionsWithParents,
integrationDefs,
integrationKinds,
integrationSecretKindObject,
} from "@homarr/definitions";
import type { ContainerInfo, Port } from "@homarr/docker";
import { DockerSingleton } from "@homarr/docker";
import { env } from "@homarr/docker/env";
import { createIntegrationAsync } from "@homarr/integrations";
import { logger } from "@homarr/log";
import { byIdSchema } from "@homarr/validation/common";
@@ -527,8 +531,169 @@ export const integrationRouter = createTRPCRouter({
const integrationInstance = await createIntegrationAsync(ctx.integration);
return await integrationInstance.searchAsync(encodeURI(input.query));
}),
suggestedIntegrations: permissionRequiredProcedure.requiresPermission("admin").query(async ({ ctx }) => {
if (!env.ENABLE_DOCKER)
throw new TRPCError({
code: "NOT_FOUND",
message: "Docker is not enabled",
});
const dockerInstances = DockerSingleton.getInstances();
if (dockerInstances.length === 0) {
throw new TRPCError({
code: "NOT_FOUND",
message: "No Docker instances found",
});
}
// TODO: remove those that were already added
const containers = await Promise.all(
dockerInstances.map(({ instance, host, isSocket }) =>
instance.listContainers().then((containers) =>
containers.map((containerInfo) => ({
info: containerInfo,
host,
isSocket,
})),
),
),
).then((results) => results.flat());
// Default docker hostname consist out of first 12 characters of the container id
const homarrContainer = containers.find((container) => container.info.Id.slice(0, 12) === process.env.HOSTNAME);
const suggestions = containers
.map((container) => getSuggestionFromContainer(container, homarrContainer))
.filter((suggestion) => suggestion !== null);
const groupedSuggestions = suggestions.reduce(
(acc, suggestion) => {
acc[suggestion.kind] ??= [];
// is defined above
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
acc[suggestion.kind]!.push(suggestion);
return acc;
},
{} as Partial<Record<IntegrationKind, IntegrationSuggestion[]>>,
);
return Object.entries(groupedSuggestions)
.map(([kind, suggestions]) => ({
kind: kind as IntegrationKind,
suggestions,
}))
.sort((itemA, itemB) => {
if (itemA.suggestions.length !== itemB.suggestions.length)
return itemB.suggestions.length - itemA.suggestions.length;
const createdAtA = Math.max(...itemA.suggestions.map((suggestion) => suggestion.createdAt?.getTime() ?? 0));
const createdAtB = Math.max(...itemB.suggestions.map((suggestion) => suggestion.createdAt?.getTime() ?? 0));
return createdAtB - createdAtA;
});
}),
});
interface IntegrationSuggestion {
containerId: string;
name: string;
internalUrl: string | null;
externalUrl: string | null;
kind: IntegrationKind;
createdAt?: Date;
}
interface ContainerInfoWithHost {
info: ContainerInfo;
host: string;
isSocket: boolean | undefined;
}
const getSuggestionFromContainer = (
container: ContainerInfoWithHost,
homarrContainer: ContainerInfoWithHost | undefined,
): IntegrationSuggestion | null => {
const integrationKind = getSuggestionKind(container.info);
if (!integrationKind) return null;
return {
containerId: container.info.Id,
name: getIntegrationName(integrationKind),
kind: integrationKind,
internalUrl: getInternalUrl(container, homarrContainer),
externalUrl: getExternalUrl(container),
createdAt: container.info.Created ? new Date(container.info.Created * 1000) : undefined,
};
};
const getSuggestionKind = (container: ContainerInfo): IntegrationKind | null => {
const [image, _tag] = container.Image.split(":");
if (!image) return null;
return (
objectEntries(integrationDefs).find(
([, integration]) =>
"containerImages" in integration &&
integration.containerImages.some((containerImage) => containerImage.toLowerCase() === image.toLowerCase()),
)?.[0] ?? null
);
};
const calculatePortScore = (port: Port): number => {
let score = 0;
if (port.PublicPort) score += 10; // Public ports are more likely to be used
if (port.PrivatePort % 1000 === 80) score += 5; // Default http ports are most likely suffixed with 80 like 8080 or 80
if (port.PrivatePort % 1000 === 443) score += 10; // Default https ports are most likely suffixed with 443 like 8443 or 443
return score;
};
const getPort = (container: ContainerInfoWithHost): Port | null => {
const ports = container.info.Ports.filter((port) => port.Type === "tcp");
return (
ports
.map((port) => ({ port, score: calculatePortScore(port) }))
.sort((portA, portB) => portB.score - portA.score)
.at(0)?.port ?? null
);
};
const getInternalUrl = (
container: ContainerInfoWithHost,
homarrContainer: ContainerInfoWithHost | undefined,
): string | null => {
const port = getPort(container);
if (!port) return null;
const protocol = port.PrivatePort % 1000 === 443 ? "https" : "http";
if (homarrContainer) {
const matchingNetwork = Object.entries(homarrContainer.info.NetworkSettings.Networks).find(
([_key, homarrNetwork]) =>
Object.entries(container.info.NetworkSettings.Networks).some(
([_name, network]) => homarrNetwork.NetworkID === network.NetworkID,
),
)?.[1];
if (matchingNetwork) return `${protocol}://${matchingNetwork.IPAddress}:${port.PrivatePort}`;
}
// TODO: Let user specify the internal ip-address for integrations --> use as default before falling back to host.docker.internal
if (container.host === homarrContainer?.host && container.isSocket === homarrContainer.isSocket) {
return `${protocol}://host.docker.internal:${port.PublicPort}`;
}
// TODO: Change this
return `${protocol}://localhost:${port.PublicPort}`;
};
const getExternalUrl = (container: ContainerInfoWithHost): string | null => {
const port = getPort(container);
if (!port) return null;
const protocol = port.PrivatePort % 1000 === 443 ? "https" : "http";
// TODO: Use some labels like "traefik.host" to determine the external url
// For now we just use localhost as external url
return `${protocol}://localhost:${port.PublicPort}`;
};
interface UpdateSecretInput {
integrationId: string;
value: string;
@@ -36,7 +36,6 @@ const mapError = (error: Error): MappedError => {
export interface MappedCertificate {
isSelfSigned: boolean;
issuer: string;
issuerCertificate?: MappedCertificate;
subject: string;
serialNumber: string;
validFrom: Date;
@@ -48,7 +47,6 @@ export interface MappedCertificate {
const mapCertificate = (certificate: X509Certificate, code: RequestErrorCode): MappedCertificate => ({
isSelfSigned: certificate.ca || code === "DEPTH_ZERO_SELF_SIGNED_CERT",
issuer: certificate.issuer,
issuerCertificate: certificate.issuerCertificate ? mapCertificate(certificate.issuerCertificate, code) : undefined,
subject: certificate.subject,
serialNumber: certificate.serialNumber,
validFrom: certificate.validFromDate,
+3 -3
View File
@@ -35,11 +35,11 @@
"bcrypt": "^6.0.0",
"cookies": "^0.9.1",
"ldapts": "8.0.1",
"next": "15.3.4",
"next": "15.3.3",
"next-auth": "5.0.0-beta.28",
"react": "19.1.0",
"react-dom": "19.1.0",
"zod": "^3.25.67"
"zod": "^3.25.62"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
@@ -47,7 +47,7 @@
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/bcrypt": "5.0.2",
"@types/cookies": "0.9.1",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"prettier": "^3.5.3",
"typescript": "^5.8.3"
}
+1 -1
View File
@@ -32,7 +32,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+1 -1
View File
@@ -30,7 +30,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+1 -1
View File
@@ -35,7 +35,7 @@
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"esbuild": "^0.25.5",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+4 -4
View File
@@ -30,18 +30,18 @@
"@homarr/env": "workspace:^0.1.0",
"@homarr/log": "workspace:^0.1.0",
"dayjs": "^1.11.13",
"next": "15.3.4",
"next": "15.3.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"undici": "7.10.0",
"zod": "^3.25.67",
"zod-validation-error": "^3.5.2"
"zod": "^3.25.62",
"zod-validation-error": "^3.4.1"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
@@ -36,12 +36,7 @@ export const requestErrorMap = {
expired: ["CERT_HAS_EXPIRED"],
hostnameMismatch: ["ERR_TLS_CERT_ALTNAME_INVALID", "CERT_COMMON_NAME_INVALID"],
notYetValid: ["CERT_NOT_YET_VALID"],
untrusted: [
"DEPTH_ZERO_SELF_SIGNED_CERT",
"UNABLE_TO_VERIFY_LEAF_SIGNATURE",
"UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
"SELF_SIGNED_CERT_IN_CHAIN",
],
untrusted: ["DEPTH_ZERO_SELF_SIGNED_CERT", "UNABLE_TO_VERIFY_LEAF_SIGNATURE", "UNABLE_TO_GET_ISSUER_CERT_LOCALLY"],
},
connection: {
hostUnreachable: "EHOSTUNREACH",
+1 -1
View File
@@ -33,7 +33,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+1 -1
View File
@@ -29,7 +29,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+2 -2
View File
@@ -25,14 +25,14 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@homarr/common": "workspace:^0.1.0",
"node-cron": "^4.1.1"
"node-cron": "^4.1.0"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/node-cron": "^3.0.11",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+1 -1
View File
@@ -44,7 +44,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+3 -3
View File
@@ -44,7 +44,7 @@
"@homarr/env": "workspace:^0.1.0",
"@homarr/log": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
"@mantine/core": "^8.1.1",
"@mantine/core": "^8.1.0",
"@paralleldrive/cuid2": "^2.2.2",
"@testcontainers/mysql": "^11.0.3",
"better-sqlite3": "^11.10.0",
@@ -61,9 +61,9 @@
"@types/better-sqlite3": "7.6.13",
"dotenv-cli": "^8.0.0",
"esbuild": "^0.25.5",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"prettier": "^3.5.3",
"tsx": "4.20.3",
"tsx": "4.20.1",
"typescript": "^5.8.3"
}
}
+3 -3
View File
@@ -25,14 +25,14 @@
"dependencies": {
"@homarr/common": "workspace:^0.1.0",
"fast-xml-parser": "^5.2.5",
"zod": "^3.25.67"
"zod": "^3.25.62"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"tsx": "4.20.3",
"eslint": "^9.28.0",
"tsx": "4.20.1",
"typescript": "^5.8.3"
}
}
+94
View File
@@ -16,6 +16,7 @@ interface integrationDefinition {
iconUrl: string;
secretKinds: AtLeastOneOf<IntegrationSecretKind[]>; // at least one secret kind set is required
category: AtLeastOneOf<IntegrationCategory>;
containerImages?: string[]; // Optional, used for container images to suggest in the UI
}
export const integrationDefs = {
@@ -24,30 +25,45 @@ export const integrationDefs = {
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/sabnzbd.svg",
category: ["downloadClient", "usenet"],
containerImages: ["linuxserver/sabnzbd", "lscr.io/linuxserver/sabnzbd", "ghcr.io/linuxserver/sabnzbd"],
},
nzbGet: {
name: "NZBGet",
secretKinds: [["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/nzbget.svg",
category: ["downloadClient", "usenet"],
containerImages: [
"nzbgetcom/nzbget",
"ghcr.io/nzbgetcom/nzbget",
"linuxserver/nzbget",
"lscr.io/linuxserver/nzbget",
"ghcr.io/linuxserver/nzbget",
],
},
deluge: {
name: "Deluge",
secretKinds: [["password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/deluge.svg",
category: ["downloadClient", "torrent"],
containerImages: ["linuxserver/deluge", "lscr.io/linuxserver/deluge", "ghcr.io/linuxserver/deluge"],
},
transmission: {
name: "Transmission",
secretKinds: [["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/transmission.svg",
category: ["downloadClient", "torrent"],
containerImages: [
"linuxserver/transmission",
"lscr.io/linuxserver/transmission",
"ghcr.io/linuxserver/transmission",
],
},
qBittorrent: {
name: "qBittorrent",
secretKinds: [["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/qbittorrent.svg",
category: ["downloadClient", "torrent"],
containerImages: ["linuxserver/qbittorrent", "lscr.io/linuxserver/qbittorrent", "ghcr.io/linuxserver/qbittorrent"],
},
aria2: {
name: "Aria2",
@@ -60,78 +76,144 @@ export const integrationDefs = {
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/sonarr.svg",
category: ["calendar"],
containerImages: [
"hotio/sonarr",
"ghcr.io/hotio/sonarr",
"linuxserver/sonarr",
"lscr.io/linuxserver/sonarr",
"ghcr.io/linuxserver/sonarr",
],
},
radarr: {
name: "Radarr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/radarr.svg",
category: ["calendar"],
containerImages: [
"hotio/radarr",
"ghcr.io/hotio/radarr",
"linuxserver/radarr",
"lscr.io/linuxserver/radarr",
"ghcr.io/linuxserver/radarr",
],
},
lidarr: {
name: "Lidarr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/lidarr.svg",
category: ["calendar"],
containerImages: [
"hotio/lidarr",
"ghcr.io/hotio/lidarr",
"linuxserver/lidarr",
"lscr.io/linuxserver/lidarr",
"ghcr.io/linuxserver/lidarr",
],
},
readarr: {
name: "Readarr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/readarr.svg",
category: ["calendar"],
containerImages: [
"hotio/readarr",
"ghcr.io/hotio/readarr",
"linuxserver/readarr",
"lscr.io/linuxserver/readarr",
"ghcr.io/linuxserver/readarr",
],
},
prowlarr: {
name: "Prowlarr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/prowlarr.svg",
category: ["indexerManager"],
containerImages: [
"hotio/prowlarr",
"ghcr.io/hotio/prowlarr",
"linuxserver/prowlarr",
"lscr.io/linuxserver/prowlarr",
"ghcr.io/linuxserver/prowlarr",
],
},
jellyfin: {
name: "Jellyfin",
secretKinds: [["username", "password"], ["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/jellyfin.svg",
category: ["mediaService"],
containerImages: [
"jellyfin/jellyfin",
"ghcr.io/jellyfin/jellyfin",
"linuxserver/jellyfin",
"lscr.io/linuxserver/jellyfin",
"ghcr.io/linuxserver/jellyfin",
],
},
emby: {
name: "Emby",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/emby.svg",
category: ["mediaService"],
containerImages: [
"emby/embyserver",
"emby/embyserver_arm64v8",
"emby/embyserver_arm32v7",
"linuxserver/emby",
"lscr.io/linuxserver/emby",
"ghcr.io/linuxserver/emby",
],
},
plex: {
name: "Plex",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/plex.svg",
category: ["mediaService"],
containerImages: ["plexinc/pms-docker", "linuxserver/plex", "lscr.io/linuxserver/plex", "ghcr.io/linuxserver/plex"],
},
jellyseerr: {
name: "Jellyseerr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/jellyseerr.svg",
category: ["mediaSearch", "mediaRequest", "search"],
containerImages: ["fallenbagel/jellyseerr", "ghcr.io/fallenbagel/jellyseerr"],
},
overseerr: {
name: "Overseerr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/overseerr.svg",
category: ["mediaSearch", "mediaRequest", "search"],
containerImages: [
"sct/overseerr",
"linuxserver/overseerr",
"lscr.io/linuxserver/overseerr",
"ghcr.io/linuxserver/overseerr",
],
},
piHole: {
name: "Pi-hole",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/pi-hole.svg",
category: ["dnsHole"],
containerImages: ["pihole/pihole"],
},
adGuardHome: {
name: "AdGuard Home",
secretKinds: [["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/adguard-home.svg",
category: ["dnsHole"],
containerImages: ["adguard/adguardhome"],
},
homeAssistant: {
name: "Home Assistant",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/home-assistant.svg",
category: ["smartHomeServer"],
containerImages: [
"homeassistant/home-assistant",
"linuxserver/home-assistant",
"lscr.io/linuxserver/home-assistant",
"ghcr.io/linuxserver/home-assistant",
],
},
openmediavault: {
name: "OpenMediaVault",
@@ -144,12 +226,14 @@ export const integrationDefs = {
secretKinds: [[]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/dashdot.png",
category: ["healthMonitoring"],
containerImages: ["mauricenino/dashdot", "ghcr.io/mauricenino/dashdot"],
},
tdarr: {
name: "Tdarr",
secretKinds: [[], ["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/tdarr.png",
category: ["mediaTranscoding"],
containerImages: ["haveagitgat/tdarr", "ghcr.io/haveagitgat/tdarr"],
},
proxmox: {
name: "Proxmox",
@@ -168,6 +252,16 @@ export const integrationDefs = {
secretKinds: [["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/unifi.png",
category: ["networkController"],
containerImages: [
"jacobalberty/unifi",
"ghcr.io/jacobalberty/unifi",
"linuxserver/unifi-controller",
"lscr.io/linuxserver/unifi-controller",
"ghcr.io/linuxserver/unifi-controller",
"linuxserver/unifi-network-application",
"lscr.io/linuxserver/unifi-network-application",
"ghcr.io/linuxserver/unifi-network-application",
],
},
} as const satisfies Record<string, integrationDefinition>;
+2 -2
View File
@@ -32,8 +32,8 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/dockerode": "^3.3.41",
"eslint": "^9.29.0",
"@types/dockerode": "^3.3.40",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+2 -1
View File
@@ -5,6 +5,7 @@ import { env } from "./env";
export interface DockerInstance {
host: string;
instance: Docker;
isSocket?: boolean;
}
export class DockerSingleton {
@@ -14,7 +15,7 @@ export class DockerSingleton {
const hostVariable = env.DOCKER_HOSTNAMES;
const portVariable = env.DOCKER_PORTS;
if (hostVariable === undefined || portVariable === undefined) {
return [{ host: "socket", instance: new Docker() }];
return [{ host: "socket", instance: new Docker(), isSocket: true }];
}
const hostnames = hostVariable.split(",");
const ports = portVariable.split(",");
+2 -2
View File
@@ -24,13 +24,13 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@t3-oss/env-nextjs": "^0.13.8",
"zod": "^3.25.67"
"zod": "^3.25.62"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+3 -3
View File
@@ -26,14 +26,14 @@
"@homarr/common": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/form": "^8.1.1",
"zod": "^3.25.67"
"@mantine/form": "^8.1.0",
"zod": "^3.25.62"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+3 -3
View File
@@ -29,15 +29,15 @@
"@homarr/notifications": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.1.1",
"@mantine/core": "^8.1.0",
"react": "19.1.0",
"zod": "^3.25.67"
"zod": "^3.25.62"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+1 -1
View File
@@ -31,7 +31,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+3 -3
View File
@@ -41,10 +41,10 @@
"maria2": "^0.4.0",
"node-ical": "^0.20.1",
"proxmox-api": "1.1.1",
"tsdav": "^2.1.5",
"tsdav": "^2.1.4",
"undici": "7.10.0",
"xml2js": "^0.6.2",
"zod": "^3.25.67"
"zod": "^3.25.62"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
@@ -52,7 +52,7 @@
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/node-unifi": "^2.5.1",
"@types/xml2js": "^0.4.14",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+2 -2
View File
@@ -27,13 +27,13 @@
"ioredis": "5.6.1",
"superjson": "2.2.2",
"winston": "3.17.0",
"zod": "^3.25.67"
"zod": "^3.25.62"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+4 -4
View File
@@ -33,19 +33,19 @@
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.1.1",
"@mantine/core": "^8.1.0",
"@tabler/icons-react": "^3.34.0",
"dayjs": "^1.11.13",
"next": "15.3.4",
"next": "15.3.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"zod": "^3.25.67"
"zod": "^3.25.62"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+3 -3
View File
@@ -24,15 +24,15 @@
"dependencies": {
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@mantine/core": "^8.1.1",
"@mantine/hooks": "^8.1.1",
"@mantine/core": "^8.1.0",
"@mantine/hooks": "^8.1.0",
"react": "19.1.0"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+2 -2
View File
@@ -24,14 +24,14 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@homarr/ui": "workspace:^0.1.0",
"@mantine/notifications": "^8.1.1",
"@mantine/notifications": "^8.1.0",
"@tabler/icons-react": "^3.34.0"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+5 -5
View File
@@ -37,14 +37,14 @@
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.1.1",
"@mantine/hooks": "^8.1.1",
"@mantine/core": "^8.1.0",
"@mantine/hooks": "^8.1.0",
"adm-zip": "0.5.16",
"next": "15.3.4",
"next": "15.3.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"superjson": "2.2.2",
"zod": "^3.25.67",
"zod": "^3.25.62",
"zod-form-data": "^2.0.7"
},
"devDependencies": {
@@ -52,7 +52,7 @@
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/adm-zip": "0.5.7",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+2 -2
View File
@@ -23,13 +23,13 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@homarr/common": "workspace:^0.1.0",
"zod": "^3.25.67"
"zod": "^3.25.62"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+1 -1
View File
@@ -30,7 +30,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+1 -1
View File
@@ -33,7 +33,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+1 -1
View File
@@ -37,7 +37,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+1 -1
View File
@@ -29,7 +29,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+3 -3
View File
@@ -26,8 +26,8 @@
"@homarr/api": "workspace:^0.1.0",
"@homarr/db": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
"@mantine/dates": "^8.1.1",
"next": "15.3.4",
"@mantine/dates": "^8.1.0",
"next": "15.3.3",
"react": "19.1.0",
"react-dom": "19.1.0"
},
@@ -35,7 +35,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+5 -5
View File
@@ -33,12 +33,12 @@
"@homarr/settings": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@mantine/core": "^8.1.1",
"@mantine/hooks": "^8.1.1",
"@mantine/spotlight": "^8.1.1",
"@mantine/core": "^8.1.0",
"@mantine/hooks": "^8.1.0",
"@mantine/spotlight": "^8.1.0",
"@tabler/icons-react": "^3.34.0",
"jotai": "^2.12.5",
"next": "15.3.4",
"next": "15.3.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"use-deep-compare-effect": "^1.8.1"
@@ -47,7 +47,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+2 -2
View File
@@ -32,7 +32,7 @@
"dayjs": "^1.11.13",
"deepmerge": "4.3.1",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.3.4",
"next": "15.3.3",
"next-intl": "4.1.0",
"react": "19.1.0",
"react-dom": "19.1.0"
@@ -41,7 +41,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+5 -5
View File
@@ -29,12 +29,12 @@
"@homarr/log": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.1.1",
"@mantine/dates": "^8.1.1",
"@mantine/hooks": "^8.1.1",
"@mantine/core": "^8.1.0",
"@mantine/dates": "^8.1.0",
"@mantine/hooks": "^8.1.0",
"@tabler/icons-react": "^3.34.0",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.3.4",
"next": "15.3.3",
"react": "19.1.0",
"react-dom": "19.1.0"
},
@@ -43,7 +43,7 @@
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/css-modules": "^1.0.5",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+2 -2
View File
@@ -24,14 +24,14 @@
"dependencies": {
"@homarr/definitions": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"zod": "^3.25.67",
"zod": "^3.25.62",
"zod-form-data": "^2.0.7"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+21 -21
View File
@@ -48,42 +48,42 @@
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/charts": "^8.1.1",
"@mantine/core": "^8.1.1",
"@mantine/hooks": "^8.1.1",
"@mantine/charts": "^8.1.0",
"@mantine/core": "^8.1.0",
"@mantine/hooks": "^8.1.0",
"@tabler/icons-react": "^3.34.0",
"@tiptap/extension-color": "2.22.0",
"@tiptap/extension-highlight": "2.22.0",
"@tiptap/extension-image": "2.22.0",
"@tiptap/extension-link": "^2.22.0",
"@tiptap/extension-table": "2.22.0",
"@tiptap/extension-table-cell": "2.22.0",
"@tiptap/extension-table-header": "2.22.0",
"@tiptap/extension-table-row": "2.22.0",
"@tiptap/extension-task-item": "2.22.0",
"@tiptap/extension-task-list": "2.22.0",
"@tiptap/extension-text-align": "2.22.0",
"@tiptap/extension-text-style": "2.22.0",
"@tiptap/extension-underline": "2.22.0",
"@tiptap/react": "^2.22.0",
"@tiptap/starter-kit": "^2.22.0",
"@tiptap/extension-color": "2.14.0",
"@tiptap/extension-highlight": "2.14.0",
"@tiptap/extension-image": "2.14.0",
"@tiptap/extension-link": "^2.14.0",
"@tiptap/extension-table": "2.14.0",
"@tiptap/extension-table-cell": "2.14.0",
"@tiptap/extension-table-header": "2.14.0",
"@tiptap/extension-table-row": "2.14.0",
"@tiptap/extension-task-item": "2.14.0",
"@tiptap/extension-task-list": "2.14.0",
"@tiptap/extension-text-align": "2.14.0",
"@tiptap/extension-text-style": "2.14.0",
"@tiptap/extension-underline": "2.14.0",
"@tiptap/react": "^2.14.0",
"@tiptap/starter-kit": "^2.14.0",
"clsx": "^2.1.1",
"dayjs": "^1.11.13",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.3.4",
"next": "15.3.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-markdown": "^10.1.0",
"recharts": "^2.15.3",
"video.js": "^8.23.3",
"zod": "^3.25.67"
"zod": "^3.25.62"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/video.js": "^7.3.58",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}
+12 -15
View File
@@ -131,22 +131,19 @@ export default function DownloadClientsWidget({
},
{
onData: (data) => {
utils.widget.downloads.getJobsAndStatuses.setData(
{ integrationIds, limitPerIntegration: options.limitPerIntegration },
(prevData) => {
return prevData?.map((item) => {
if (item.integration.id !== data.integration.id) return item;
utils.widget.downloads.getJobsAndStatuses.setData({ integrationIds }, (prevData) => {
return prevData?.map((item) => {
if (item.integration.id !== data.integration.id) return item;
return {
data: data.data,
integration: {
...data.integration,
updatedAt: new Date(),
},
};
});
},
);
return {
data: data.data,
integration: {
...data.integration,
updatedAt: new Date(),
},
};
});
});
},
},
);
@@ -105,7 +105,7 @@ export const WidgetIntegrationSelect = ({
<PillsInput
inputWrapperOrder={["label", "input", "description", "error"]}
description={
<Text size="xs" span>
<Text size="xs">
{t.rich("widget.common.integration.description", {
here: () => (
<Anchor size="xs" component={Link} target="_blank" href="/manage/integrations">
+940 -964
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -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":"tancak","avatar_url":"https://avatars.githubusercontent.com/u/11760749?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":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?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":"VinnyVynce","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":"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/5266759Line truncated
[{"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":"tancak","avatar_url":"https://avatars.githubusercontent.com/u/11760749?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":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?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":"VinnyVynce","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":"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/5266759Line truncated
+1 -1
View File
@@ -1 +1 @@
[{"username":"carlchina","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/6697/medium/d22bbe7797bbeb30dbdc73a5648d329a_default.png"},{"username":"zielmann","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/7795/medium/ad22b8b8d5eb33e4154d53a454c862fd_default.png"},{"username":"Thalyn","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12494028/medium/5faf5acc945a874ed116c4567edaa09f_default.png"},{"username":"magnushj","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12503488/medium/68f32e33ea7b891960055c9f831f7344_default.png"},{"username":"almontegil","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12580457/medium/f4136cacbdfdb4c28ae7f85dc5f840db_default.png"},{"username":"Skick","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12619811/medium/0331f1de413a645b4516bc4e037f31bb.jpg"},{"username":"andibing","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12664938/medium/b8be63e4dcb2e791ced1ffc9e3a049a5.jpg"},{"username":"gronare","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12680911/medium/c6eb14d1504156f34a158e507f73aa3d_default.png"},{"username":"SmartPhoneLover","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12701640/medium/ec95486662ec875cda080e778c3ff702.jpg"},{"username":"marcelotk_15","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12773227/medium/ecf6bea16ab0c873c131df2154ee9718_default.png"},{"username":"S3OD177","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13051544/medium/11dd990837f61f7e8f7d36b041a7fddb_default.png"},{"username":"marcg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13153301/medium/ebcf60fbf27deb148ec40a659566c6ff_default.png"},{"username":"BeersTeddy","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13185230/medium/2f1f4e1effe74a23422b195cbefb2a95_default.png"},{"username":"jamesmcmahon0","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13245578/medium/586aa873b4abddbd9abc6f3de99ab70e.jpeg"},{"username":"b1nar10","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13286752/medium/249b02e3368752cb175446082015737c_default.png"},{"username":"vannCN","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13330448/medium/9b8a9ee3611e51e951e22d5fd4eb7d8d.jpg"},{"username":"binswm","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13343482/medium/45dde0e6097b9b72705d2eba9dbbc276_default.png"},{"username":"SkewRam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13496556/medium/188f5c2deb7938eda51eb786cc4539ca.jpeg"},{"username":"raphcatarino","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13547726/medium/b003511e67df13a4b4b5689488fa8099.jpg"},{"username":"shillos5","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13600557/medium/b17650b2b84f829d54fa548c44c1ab27.jpeg"},{"username":"wolong98","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13641407/medium/f4634edc58c7857a357e5293543c15cf.jpg"},{"username":"spair0039","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14012333/medium/72430e96027c09c19141cac38eae4617.png"},{"username":"MajorMarcin","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14072183/medium/0a197e64bb92b6ea94cecbb607512c45.jpg"},{"username":"KosmoMoustache","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14103535/medium/51c438cdd9f86e8811c75f4869de479c.png"},{"username":"Soochaehwa","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14118689/medium/496a1ce63111547bf455a1e0a7ac75f1_default.png"},{"username":"garryfield","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14187035/medium/520c964706676045f6eeec1b08edc880.jpg"},{"username":"droidenko","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14444264/medium/4aa3a8e824f72bc9e5ec0d8de307095e.jpeg"},{"username":"maathis","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14489950/medium/6eeddf13a757ee35f78f1763f94d95e1.jpeg"},{"username":"bukvam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14546502/medium/a819dc40a13c57395a17dc46e847d3ce.jpg"},{"username":"gm.cinalli","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14670666/medium/2d466a0fdbda40764526be86c97c0ab4.jpeg"},{"username":"antoine2tt","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14722148/medium/f88d926900862dd59007ea4b3419cb9d.png"},{"username":"cretzen","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14799754/medium/3ba5c1805ec20c000d5810c07985afe9.jpg"},{"username":"ktKongTong","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14817246/medium/97cfc3c028dbdaf85ebd1102da71e58c.jpeg"},{"username":"marinkaberg","avatarUrl":"https://crowLine truncated
[{"username":"carlchina","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/6697/medium/d22bbe7797bbeb30dbdc73a5648d329a_default.png"},{"username":"zielmann","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/7795/medium/ad22b8b8d5eb33e4154d53a454c862fd_default.png"},{"username":"Thalyn","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12494028/medium/5faf5acc945a874ed116c4567edaa09f_default.png"},{"username":"magnushj","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12503488/medium/68f32e33ea7b891960055c9f831f7344_default.png"},{"username":"almontegil","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12580457/medium/f4136cacbdfdb4c28ae7f85dc5f840db_default.png"},{"username":"Skick","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12619811/medium/0331f1de413a645b4516bc4e037f31bb.jpg"},{"username":"andibing","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12664938/medium/b8be63e4dcb2e791ced1ffc9e3a049a5.jpg"},{"username":"gronare","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12680911/medium/c6eb14d1504156f34a158e507f73aa3d_default.png"},{"username":"SmartPhoneLover","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12701640/medium/ec95486662ec875cda080e778c3ff702.jpg"},{"username":"marcelotk_15","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12773227/medium/ecf6bea16ab0c873c131df2154ee9718_default.png"},{"username":"S3OD177","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13051544/medium/11dd990837f61f7e8f7d36b041a7fddb_default.png"},{"username":"marcg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13153301/medium/ebcf60fbf27deb148ec40a659566c6ff_default.png"},{"username":"BeersTeddy","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13185230/medium/2f1f4e1effe74a23422b195cbefb2a95_default.png"},{"username":"jamesmcmahon0","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13245578/medium/586aa873b4abddbd9abc6f3de99ab70e.jpeg"},{"username":"b1nar10","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13286752/medium/249b02e3368752cb175446082015737c_default.png"},{"username":"vannCN","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13330448/medium/9b8a9ee3611e51e951e22d5fd4eb7d8d.jpg"},{"username":"binswm","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13343482/medium/45dde0e6097b9b72705d2eba9dbbc276_default.png"},{"username":"SkewRam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13496556/medium/188f5c2deb7938eda51eb786cc4539ca.jpeg"},{"username":"raphcatarino","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13547726/medium/b003511e67df13a4b4b5689488fa8099.jpg"},{"username":"shillos5","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13600557/medium/b17650b2b84f829d54fa548c44c1ab27.jpeg"},{"username":"wolong98","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13641407/medium/f4634edc58c7857a357e5293543c15cf.jpg"},{"username":"spair0039","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14012333/medium/72430e96027c09c19141cac38eae4617.png"},{"username":"MajorMarcin","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14072183/medium/0a197e64bb92b6ea94cecbb607512c45.jpg"},{"username":"KosmoMoustache","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14103535/medium/51c438cdd9f86e8811c75f4869de479c.png"},{"username":"Soochaehwa","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14118689/medium/496a1ce63111547bf455a1e0a7ac75f1_default.png"},{"username":"garryfield","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14187035/medium/520c964706676045f6eeec1b08edc880.jpg"},{"username":"droidenko","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14444264/medium/4aa3a8e824f72bc9e5ec0d8de307095e.jpeg"},{"username":"maathis","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14489950/medium/6eeddf13a757ee35f78f1763f94d95e1.jpeg"},{"username":"bukvam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14546502/medium/a819dc40a13c57395a17dc46e847d3ce.jpg"},{"username":"gm.cinalli","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14670666/medium/2d466a0fdbda40764526be86c97c0ab4.jpeg"},{"username":"antoine2tt","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14722148/medium/f88d926900862dd59007ea4b3419cb9d.png"},{"username":"cretzen","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14799754/medium/3ba5c1805ec20c000d5810c07985afe9.jpg"},{"username":"ktKongTong","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14817246/medium/97cfc3c028dbdaf85ebd1102da71e58c.jpeg"},{"username":"Prototypem95","avatarUrl":"https://croLine truncated
+3 -3
View File
@@ -17,19 +17,19 @@
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"@next/eslint-plugin-next": "15.3.4",
"@next/eslint-plugin-next": "15.3.3",
"eslint-config-prettier": "^10.1.5",
"eslint-config-turbo": "^2.5.4",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"typescript-eslint": "^8.34.1"
"typescript-eslint": "^8.34.0"
},
"devDependencies": {
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.29.0",
"eslint": "^9.28.0",
"typescript": "^5.8.3"
}
}