chore(deps): batch dependency updates, pnpm v11 migration, and fix integration cache (#5939)

This commit is contained in:
Thomas authored and GitHub committed 2026-06-12 13:52:43 +02:00
1 parent 905f795b56
commit d16571d4c4
35 files changed
+2104 -2052

No files matched your search

+1 -1
View File
@@ -22,7 +22,7 @@
automerge: true,
},
{
// disallow automerge for onlyBuiltDependencies
// disallow automerge for allowBuilds dependencies (native builds need manual verification)
matchPackageNames: [
"@tree-sitter-grammars/tree-sitter-yaml",
"bcrypt",
+1 -1
View File
@@ -52,7 +52,7 @@ jobs:
xargs -r -a /tmp/changed-files pnpm exec oxfmt --write
- name: Commit fixes
uses: stefanzweifel/git-auto-commit-action@v5
uses: stefanzweifel/git-auto-commit-action@v7
with:
commit_message: "style: auto-fix lint and format"
+3 -3
View File
@@ -38,9 +38,9 @@ jobs:
env:
CI: "true"
- name: Setup Pages
uses: actions/configure-pages@v5
uses: actions/configure-pages@v6
- name: Upload pages artifact
uses: actions/upload-pages-artifact@v4
uses: actions/upload-pages-artifact@v5
with:
path: "apps/docs/build"
@@ -53,4 +53,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v5
@@ -31,7 +31,7 @@ jobs:
run: pnpm api-dump-contributors
- name: Commit updated contributors
uses: EndBug/add-and-commit@v9
uses: EndBug/add-and-commit@v10
with:
add: "apps/docs/static"
default_author: github_actor
+1 -1
View File
@@ -58,7 +58,7 @@ jobs:
echo "OpenAPI spec updated ($(jq '.paths | length' /tmp/openapi.json) paths)"
- name: Commit updated spec
uses: EndBug/add-and-commit@v9
uses: EndBug/add-and-commit@v10
with:
add: "apps/docs/static/api/"
default_author: github_actor
-1
View File
@@ -1,3 +1,2 @@
[tools]
node = "24.16.0"
pnpm = "10.34.1"
+2 -6
View File
@@ -1,6 +1,2 @@
# 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
# pnpm v11: non-auth settings moved to pnpm-workspace.yaml
# Keep this file for any future registry/auth configuration
+2 -4
View File
@@ -289,13 +289,11 @@ const config: Config = {
};
},
"@signalwire/docusaurus-plugin-llms-txt",
async function tailwindCssPlugin(context, options) {
async function tailwindCssPlugin() {
return {
name: "docusaurus-tailwindcss",
configurePostCss(postcssOptions) {
// Appends TailwindCSS and AutoPrefixer.
postcssOptions.plugins.push(require("tailwindcss"));
postcssOptions.plugins.push(require("autoprefixer"));
postcssOptions.plugins.push(require("@tailwindcss/postcss"));
return postcssOptions;
},
};
+4 -4
View File
@@ -32,25 +32,25 @@
"@scalar/api-reference-react": "catalog:",
"@signalwire/docusaurus-plugin-llms-txt": "^1.2.2",
"@tabler/icons-react": "catalog:",
"autoprefixer": "^10.5.0",
"@tailwindcss/postcss": "^4.3.0",
"clsx": "catalog:",
"dayjs": "catalog:",
"docusaurus-plugin-image-zoom": "^3.0.1",
"leader-line-new": "^1.1.9",
"postcss": "^8.4.32",
"postcss": "^8.5.10",
"posthog-docusaurus": "^2.0.5",
"prism-react-renderer": "^2.4.1",
"random-word-slugs": "^0.1.7",
"react": "catalog:",
"react-dom": "catalog:",
"swiper": "^12.2.0",
"tailwindcss": "^3.4.19"
"tailwindcss": "^4.3.0"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^3.10.1",
"@docusaurus/tsconfig": "^3.10.1",
"@docusaurus/types": "^3.10.1",
"@fec/remark-a11y-emoji": "^3.1.0",
"@fec/remark-a11y-emoji": "^4.0.2",
"@tsconfig/docusaurus": "^2.0.9",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
+10 -4
View File
@@ -1,9 +1,15 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "tailwindcss/theme" layer(theme);
@import "tailwindcss/utilities" layer(utilities);
@import url(https://api.fontshare.com/v2/css?f[]=work-sans@2,1&display=swap);
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
@theme {
--spacing-128: 32rem;
--breakpoint-3xl: 1697px;
}
:root {
--ifm-color-primary: #fa5252;
--ifm-color-primary-dark: #f93232;
@@ -87,7 +93,7 @@
}
.menu__list {
transition: all 0.s ease-in-out !important;
transition: all 0.5s ease-in-out !important;
}
.announcementBar_node_modules-\@docusaurus-theme-classic-lib-theme-AnnouncementBar-styles-module {
-19
View File
@@ -1,19 +0,0 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {
spacing: {
128: "32rem",
},
screens: {
"3xl": "1697px",
},
},
},
darkMode: ["class", '[data-theme="dark"]'],
plugins: [],
corePlugins: {
preflight: false,
},
};
+1
View File
@@ -1,6 +1,7 @@
{
"extends": "@docusaurus/tsconfig",
"compilerOptions": {
"ignoreDeprecations": "6.0",
"baseUrl": ".",
"target": "es5",
"lib": [
@@ -19,6 +19,7 @@ export const DeleteIntegrationActionButton = ({ count, integration }: DeleteInte
const t = useScopedI18n("integration.page.delete");
const router = useRouter();
const { openConfirmModal } = useConfirmModal();
const utils = clientApi.useUtils();
const { mutateAsync, isPending } = clientApi.integration.delete.useMutation();
return (
@@ -43,6 +44,7 @@ export const DeleteIntegrationActionButton = ({ count, integration }: DeleteInte
router.replace("/manage/integrations");
}
void revalidatePathActionAsync("/manage/integrations");
void utils.integration.invalidate();
},
onError: () => {
showErrorNotification({
@@ -54,6 +54,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
const hasUrlSecret = initialSecretsKinds.includes("url");
const utils = clientApi.useUtils();
const router = useRouter();
const form = useZodForm(formSchema, {
initialValues: {
@@ -102,6 +103,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
title: t("integration.page.edit.notification.success.title"),
message: t("integration.page.edit.notification.success.message"),
});
void utils.integration.invalidate();
void revalidatePathActionAsync("/manage/integrations").then(() => router.push("/manage/integrations"));
},
onError: () => {
@@ -97,13 +97,19 @@ export const NewIntegrationForm = ({
},
});
const utils = clientApi.useUtils();
const { mutateAsync: createIntegrationAsync, isPending: isCreatePending } = clientApi.integration.create.useMutation({
async onSuccess() {
await revalidatePathActionAsync("/manage/integrations");
await utils.integration.invalidate();
},
});
const { mutateAsync: createOnboardingIntegrationAsync, isPending: isOnboardingCreatePending } =
clientApi.onboard.createIntegration.useMutation();
clientApi.onboard.createIntegration.useMutation({
async onSuccess() {
await utils.integration.invalidate();
},
});
const isPending = isCreatePending || isOnboardingCreatePending;
const [error, setError] = useState<null | AnyMappedTestConnectionError>(null);
@@ -2,7 +2,7 @@
import type { SegmentedControlItem } from "@mantine/core";
import { Button, Fieldset, Grid, Group, SegmentedControl, Stack, Textarea, TextInput } from "@mantine/core";
import { WidgetIntegrationSelect } from "node_modules/@homarr/widgets/src/widget-integration-select";
import { WidgetIntegrationSelect } from "@homarr/widgets/widget-integration-select";
import type { z } from "zod/v4";
import { clientApi } from "@homarr/api/client";
@@ -2,7 +2,7 @@ import { Badge, Card } from "@mantine/core";
import { useElementSize } from "@mantine/hooks";
import { QueryErrorResetBoundary } from "@tanstack/react-query";
import combineClasses from "clsx";
import { NoIntegrationSelectedError } from "node_modules/@homarr/widgets/src/errors";
import { NoIntegrationSelectedError } from "@homarr/widgets/errors/classes";
import { ErrorBoundary } from "react-error-boundary";
import { useRequiredBoard } from "@homarr/boards/context";
-1
View File
@@ -1,7 +1,6 @@
{
"extends": "@homarr/tsconfig/base.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": ["./src/*"],
"@homarr/node-unifi": ["../../node_modules/@types/node-unifi"]
+1 -2
View File
@@ -1,9 +1,8 @@
{
"extends": "@homarr/tsconfig/base.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": ["src/*"],
"~/*": ["./src/*"],
"@homarr/node-unifi": ["../../node_modules/@types/node-unifi"]
},
"tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json"
+1 -2
View File
@@ -1,9 +1,8 @@
{
"extends": "@homarr/tsconfig/base.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": ["src/*"],
"~/*": ["./src/*"],
"@homarr/node-unifi": ["../../node_modules/@types/node-unifi"]
},
"tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json"
+1
View File
@@ -2,5 +2,6 @@ FROM node:24.16.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"]
+2 -7
View File
@@ -6,12 +6,7 @@
},
"engines": {
"node": ">=24.16.0",
"pnpm": ">=10.34.1"
"pnpm": ">=11.0.0"
},
"packageManager": "pnpm@10.34.1",
"pnpm": {
"onlyBuiltDependencies": [
"better-sqlite3"
]
}
"packageManager": "pnpm@11.5.3"
}
@@ -0,0 +1,2 @@
allowBuilds:
better-sqlite3: true
+3 -47
View File
@@ -56,59 +56,15 @@
"testcontainers": "catalog:",
"turbo": "catalog:",
"typescript": "catalog:",
"vite": "catalog:",
"vite-tsconfig-paths": "catalog:",
"vitest": "catalog:"
},
"engines": {
"node": ">=24.16.0",
"pnpm": ">=10.34.1"
},
"packageManager": "pnpm@10.34.1",
"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.7",
"@babel/runtime@<7.26.10": ">=7.29.7",
"axios@>=1.0.0 <1.8.2": ">=1.17.0",
"brace-expansion@>=2.0.0 <=2.0.1": ">=5.0.6",
"brace-expansion@>=1.0.0 <=1.1.11": ">=5.0.6",
"esbuild@<=0.24.2": ">=0.28.0",
"form-data@>=4.0.0 <4.0.4": ">=4.0.5",
"hono@<4.6.5": ">=4.12.23",
"linkifyjs@<4.3.2": ">=4.3.3",
"nanoid@>=4.0.0 <5.0.9": ">=5.1.11",
"prismjs@<1.30.0": ">=1.30.0",
"proxmox-api>undici": "7.27.1",
"react-is": "^19.2.7",
"rollup@>=4.0.0 <4.22.4": ">=4.61.1",
"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.7",
"vite@>=5.0.0 <=5.4.18": ">=8.0.16"
},
"patchedDependencies": {
"@types/node-unifi": "patches/@types__node-unifi.patch",
"trpc-to-openapi": "patches/trpc-to-openapi.patch"
},
"allowUnusedPatches": true,
"ignoredBuiltDependencies": [
"@scarf/scarf",
"@swc/core",
"core-js-pure",
"protobufjs"
]
"pnpm": ">=11.0.0"
},
"packageManager": "pnpm@11.5.3",
"dependencies": {
"jsonpath-plus": "catalog:"
}
@@ -91,8 +91,8 @@ export type HomarrDocumentationPath =
| "/docs/tags/redis"
| "/docs/tags/responsive"
| "/docs/tags/roles"
| "/docs/tags/search"
| "/docs/tags/search-engines"
| "/docs/tags/search"
| "/docs/tags/secrets"
| "/docs/tags/security"
| "/docs/tags/self-signed"
@@ -126,8 +126,8 @@ export type HomarrDocumentationPath =
| "/docs/category/community"
| "/docs/category/developer-guides"
| "/docs/category/getting-started"
| "/docs/category/installation"
| "/docs/category/installation-1"
| "/docs/category/installation"
| "/docs/category/integrations"
| "/docs/category/management"
| "/docs/category/widgets"
@@ -156,6 +156,7 @@ export type HomarrDocumentationPath =
| "/docs/integrations/adguard-home"
| "/docs/integrations/anchor"
| "/docs/integrations/aria2"
| "/docs/integrations/audiobookshelf"
| "/docs/integrations/codeberg"
| "/docs/integrations/coolify"
| "/docs/integrations/dash-dot"
@@ -175,6 +176,7 @@ export type HomarrDocumentationPath =
| "/docs/integrations/kubernetes"
| "/docs/integrations/lidarr"
| "/docs/integrations/linux-server-io"
| "/docs/integrations/navidrome"
| "/docs/integrations/nextcloud"
| "/docs/integrations/npm"
| "/docs/integrations/ntfy"
@@ -182,6 +184,7 @@ export type HomarrDocumentationPath =
| "/docs/integrations/open-media-vault"
| "/docs/integrations/opnsense"
| "/docs/integrations/overseerr"
| "/docs/integrations/paperless-ngx"
| "/docs/integrations/peanut"
| "/docs/integrations/pi-hole"
| "/docs/integrations/plex"
@@ -198,12 +201,14 @@ export type HomarrDocumentationPath =
| "/docs/integrations/sonarr"
| "/docs/integrations/speedtest-tracker"
| "/docs/integrations/tdarr"
| "/docs/integrations/technitium-dns"
| "/docs/integrations/tracearr"
| "/docs/integrations/transmission"
| "/docs/integrations/truenas"
| "/docs/integrations/umami"
| "/docs/integrations/unifi-controller"
| "/docs/integrations/unraid"
| "/docs/integrations/uptime-kuma"
| "/docs/management/api"
| "/docs/management/apps"
| "/docs/management/boards"
@@ -216,6 +221,7 @@ export type HomarrDocumentationPath =
| "/docs/management/users"
| "/docs/widgets/anchor-note"
| "/docs/widgets/app"
| "/docs/widgets/audio-stats"
| "/docs/widgets/bookmarks"
| "/docs/widgets/calendar"
| "/docs/widgets/clock"
@@ -240,6 +246,7 @@ export type HomarrDocumentationPath =
| "/docs/widgets/network-controller-summary"
| "/docs/widgets/notebook"
| "/docs/widgets/notifications"
| "/docs/widgets/paperless-ngx"
| "/docs/widgets/releases"
| "/docs/widgets/rss-feed"
| "/docs/widgets/smart-home-entity-state"
@@ -251,6 +258,7 @@ export type HomarrDocumentationPath =
| "/docs/widgets/tracearr"
| "/docs/widgets/umami"
| "/docs/widgets/ups"
| "/docs/widgets/uptime-kuma"
| "/docs/widgets/video"
| "/docs/widgets/weather"
| ""
@@ -55,7 +55,8 @@ export class ProxmoxIntegration extends Integration implements IClusterHealthMon
host: this.url("/").host,
tokenID: `${this.getSecretValue("username")}@${this.getSecretValue("realm")}!${this.getSecretValue("tokenId")}`,
tokenSecret: this.getSecretValue("apiKey"),
fetch: fetchAsync,
// proxmox-api bundles its own undici types which are incompatible with the project's undici version
fetch: fetchAsync as any,
});
}
}
@@ -1,5 +1,4 @@
import proxmoxApi from "proxmox-api";
import type { fetch as undiciFetch } from "undici";
import { Response } from "undici";
import { describe, expect, test } from "vitest";
@@ -9,48 +8,32 @@ import { ProxmoxApiErrorHandler } from "../proxmox-error-handler";
describe("ProxmoxApiErrorHandler handleError should handle the provided error accordingly", () => {
test.each([400, 401, 500])("should handle %s error", async (statusCode) => {
// Arrange
// eslint-disable-next-line no-restricted-syntax
const mockedFetch: typeof undiciFetch = async () => {
return Promise.resolve(createFakeResponse(statusCode));
};
const mockedFetch = async () => Promise.resolve(createFakeResponse(statusCode));
// Act
const result = await runWithAsync(mockedFetch);
// Assert
expect(result).toBeInstanceOf(IntegrationResponseError);
const error = result as unknown as IntegrationResponseError;
expect(error.cause.statusCode).toBe(statusCode);
});
test("should handle other non successful status codes", async () => {
// Arrange
// eslint-disable-next-line no-restricted-syntax
const mockedFetch: typeof undiciFetch = async () => {
return Promise.resolve(createFakeResponse(404));
};
const mockedFetch = async () => Promise.resolve(createFakeResponse(404));
// Act
const result = await runWithAsync(mockedFetch);
// Assert
expect(result).toBeInstanceOf(IntegrationResponseError);
const error = result as unknown as IntegrationResponseError;
expect(error.cause.statusCode).toBe(404);
});
test("should handle request error", async () => {
// Arrange
const mockedFetch: typeof undiciFetch = () => {
const mockedFetch = () => {
const errorWithCode = new Error("Inner error") as Error & { code: string };
errorWithCode.code = "ECONNREFUSED";
throw new TypeError("Outer error", { cause: errorWithCode });
};
// Act
const result = await runWithAsync(mockedFetch);
// Assert
// In the end in should have the structure IntegrationRequestError -> RequestError -> TypeError -> Error (with code)
expect(result).toBeInstanceOf(IntegrationRequestError);
const error = result as unknown as IntegrationRequestError;
expect(error.cause.cause).toBeInstanceOf(TypeError);
@@ -65,13 +48,11 @@ describe("ProxmoxApiErrorHandler handleError should handle the provided error ac
const createFakeResponse = (statusCode: number) => {
return new Response(JSON.stringify({ data: {} }), {
status: statusCode,
// It expects a content-type and valid json response
// https://github.com/UrielCh/proxmox-api/blob/master/api/src/ProxmoxEngine.ts#L258
headers: { "content-type": "application/json;charset=UTF-8" },
});
};
const runWithAsync = async (mockedFetch: typeof undiciFetch) => {
const runWithAsync = async (mockedFetch: (...args: any[]) => any) => {
const integration = { id: "test", name: "test", url: "http://proxmox.example.com" };
const client = createProxmoxClient(mockedFetch);
const handler = new ProxmoxApiErrorHandler();
@@ -79,11 +60,11 @@ const runWithAsync = async (mockedFetch: typeof undiciFetch) => {
return await client.nodes.$get().catch((error) => handler.handleError(error, integration));
};
const createProxmoxClient = (fetch: typeof undiciFetch) => {
const createProxmoxClient = (fetch: (...args: any[]) => any) => {
return proxmoxApi({
host: "proxmox.example.com",
tokenID: "username@realm!tokenId",
tokenSecret: crypto.randomUUID(),
fetch,
fetch: fetch as any,
});
};
@@ -0,0 +1,2 @@
declare const classes: Record<string, string>;
export default classes;
@@ -0,0 +1,2 @@
declare const classes: Record<string, string>;
export default classes;
+2
View File
@@ -17,6 +17,8 @@
"./custom-api/component": "./src/custom-api/component.tsx",
"./custom-api/extract-display-data": "./src/custom-api/extract-display-data.ts",
"./errors": "./src/errors/component.tsx",
"./errors/classes": "./src/errors/index.ts",
"./widget-integration-select": "./src/widget-integration-select.tsx",
"./modals": "./src/modals/index.ts",
"./prefetch": "./src/prefetch.ts"
},
+1944 -1876
View File
File diff suppressed because it is too large. Load diff
+74 -28
View File
@@ -21,7 +21,7 @@ catalog:
"@immich/sdk": ^2.7.5
"@jellyfin/sdk": ^0.13.0
"@kubernetes/client-node": ^1.4.0
"@modelcontextprotocol/sdk": 1.26.0
"@modelcontextprotocol/sdk": 1.29.0
"@mantine/charts": ^9.3.0
"@mantine/colors-generator": ^9.3.0
"@mantine/core": ^9.3.0
@@ -52,22 +52,22 @@ catalog:
"@testcontainers/mysql": ^12.0.1
"@testcontainers/postgresql": ^12.0.1
"@testcontainers/redis": ^12.0.1
"@tiptap/extension-color": 3.25.0
"@tiptap/extension-highlight": 3.25.0
"@tiptap/extension-image": 3.25.0
"@tiptap/extension-link": ^3.25.0
"@tiptap/extension-placeholder": ^3.25.0
"@tiptap/extension-table": 3.25.0
"@tiptap/extension-table-cell": 3.25.0
"@tiptap/extension-table-header": 3.25.0
"@tiptap/extension-table-row": 3.25.0
"@tiptap/extension-task-item": 3.25.0
"@tiptap/extension-task-list": 3.25.0
"@tiptap/extension-text-align": 3.25.0
"@tiptap/extension-text-style": 3.25.0
"@tiptap/extension-underline": 3.25.0
"@tiptap/react": ^3.25.0
"@tiptap/starter-kit": ^3.25.0
"@tiptap/extension-color": 3.26.0
"@tiptap/extension-highlight": 3.26.0
"@tiptap/extension-image": 3.26.0
"@tiptap/extension-link": ^3.26.0
"@tiptap/extension-placeholder": ^3.26.0
"@tiptap/extension-table": 3.26.0
"@tiptap/extension-table-cell": 3.26.0
"@tiptap/extension-table-header": 3.26.0
"@tiptap/extension-table-row": 3.26.0
"@tiptap/extension-task-item": 3.26.0
"@tiptap/extension-task-list": 3.26.0
"@tiptap/extension-text-align": 3.26.0
"@tiptap/extension-text-style": 3.26.0
"@tiptap/extension-underline": 3.26.0
"@tiptap/react": ^3.26.0
"@tiptap/starter-kit": ^3.26.0
"@trpc/client": ^11.17.0
"@trpc/next": ^11.17.0
"@trpc/react-query": ^11.17.0
@@ -86,14 +86,14 @@ catalog:
"@types/node-unifi": ^2.5.1
"@types/pg": ^8.20.0
"@types/prismjs": ^1.26.6
"@types/react": 19.2.16
"@types/react": 19.2.17
"@types/react-dom": 19.2.3
"@scalar/api-reference-react": ^0.9.42
"@types/video.js": ^7.3.58
"@types/ws": ^8.18.1
"@types/xml2js": ^0.4.14
"@umami/node": ^0.4.0
"@vitejs/plugin-react": ^5.2.0
"@vitejs/plugin-react": ^6.0.2
"@vitest/coverage-v8": ^4.1.8
"@vitest/ui": ^4.1.8
"@xterm/addon-canvas": ^0.7.0
@@ -101,13 +101,13 @@ catalog:
"@xterm/xterm": ^6.0.0
adm-zip: 0.5.17
jszip: ^3.10.1
sql.js: ^1.12.0
sql.js: ^1.14.1
babel-plugin-react-compiler: ^1.0.0
bcrypt: ^6.0.0
better-sqlite3: ^12.10.0
chroma-js: ^3.2.0
clsx: ^2.1.1
concurrently: ^9.2.1
concurrently: ^10.0.3
conventional-changelog-conventionalcommits: ^9.3.1
cookie: 1.1.1
cookies: ^0.9.1
@@ -129,7 +129,7 @@ catalog:
flag-icons: ^7.5.0
glob: ^13.0.6
ical.js: ^2.2.1
ioredis: 5.11.0
ioredis: 5.11.1
isomorphic-dompurify: ^3.16.0
jotai: ^2.20.0
jsdom: ^29.1.1
@@ -138,19 +138,19 @@ catalog:
ldapts: 8.1.8
lodash.clonedeep: ^4.5.0
lucide-react: ^1.17.0
"mantine-contextmenu": ^7.17.1
"mantine-contextmenu": ^9.2.1
mantine-datatable: ^9.2.2
mantine-react-table: npm:mantine-react-table-open@9.0.3
mcp-handler: ^1.1.0
maria2: ^0.4.1
mysql2: 3.22.4
mysql2: 3.22.5
next: 16.2.7
next-auth: 5.0.0-beta.31
next-intl: 4.13.0
node-loader: ^2.1.0
octokit: ^5.0.5
oxfmt: ^0.53.0
oxlint: ^1.67.0
oxfmt: ^0.54.0
oxlint: ^1.68.0
pg: ^8.21.0
postcss-preset-mantine: ^1.18.0
prismjs: ^1.30.0
@@ -175,8 +175,9 @@ catalog:
tsdav: ^2.2.2
tsx: 4.20.4
turbo: ^2.9.16
typescript: ^5.9.3
undici: 8.4.0
typescript: ^6.0.3
vite: ^8.0.16
undici: 7.27.1
use-deep-compare-effect: ^1.8.1
video.js: ^8.23.7
vite-tsconfig-paths: ^6.1.1
@@ -189,9 +190,54 @@ catalog:
zod-form-data: ^3.0.2
zod-validation-error: ^5.0.0
catalogMode: strict
nodeLinker: hoisted
strictPeerDependencies: false
engineStrict: true
verifyDepsBeforeRun: warn
minimumReleaseAge: 4320
minimumReleaseAgeExclude:
- next
- "@next/*"
# Renovate security update: turbo@2.9.14
- turbo@2.9.14
overrides:
"@babel/helpers@<7.26.10": ">=7.29.7"
"@babel/runtime@<7.26.10": ">=7.29.7"
"axios@>=1.0.0 <1.8.2": ">=1.17.0"
"brace-expansion@>=2.0.0 <=2.0.1": ">=5.0.6"
"brace-expansion@>=1.0.0 <=1.1.11": ">=5.0.6"
"esbuild@<=0.24.2": ">=0.28.0"
"form-data@>=4.0.0 <4.0.4": ">=4.0.5"
"hono@<4.6.5": ">=4.12.23"
"linkifyjs@<4.3.2": ">=4.3.3"
"nanoid@>=4.0.0 <5.0.9": ">=5.1.11"
"prismjs@<1.30.0": ">=1.30.0"
"proxmox-api>undici": "7.27.1"
"react-is": "^19.2.7"
"rollup@>=4.0.0 <4.22.4": ">=4.61.1"
"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.7"
"vite@>=5.0.0 <=5.4.18": ">=8.0.16"
patchedDependencies:
"@types/node-unifi": "patches/@types__node-unifi.patch"
"trpc-to-openapi": "patches/trpc-to-openapi.patch"
allowUnusedPatches: true
allowBuilds:
"@tree-sitter-grammars/tree-sitter-yaml": true
bcrypt: true
better-sqlite3: true
cpu-features: true
esbuild: true
sharp: true
ssh2: true
tree-sitter: true
tree-sitter-json: true
"@scarf/scarf": false
"@swc/core": false
core-js: false
core-js-pure: false
msw: false
protobufjs: false
vue-demi: false
+11 -5
View File
@@ -1,22 +1,28 @@
import fs from "fs/promises";
import { join } from "path";
import json5 from "json5";
import { parse } from "yaml";
import { describe, test } from "vitest";
describe("Renovate configuration tests", () => {
test("automerge should be disabled for onlyBuiltDependencies", async () => {
const packageJson = await import("../package.json");
test("automerge should be disabled for allowBuilds dependencies", async () => {
const workspaceYaml = await fs.readFile(join(__dirname, "../pnpm-workspace.yaml"), "utf-8").then(parse);
const renovateConfig = await fs.readFile(join(__dirname, "../.github/renovate.json5"), "utf-8").then(json5.parse);
const onlyBuiltDependencies = packageJson.pnpm.onlyBuiltDependencies;
if (!workspaceYaml.allowBuilds || typeof workspaceYaml.allowBuilds !== "object") {
throw new Error("pnpm-workspace.yaml must define allowBuilds as an object");
}
const allowedBuilds = Object.entries(workspaceYaml.allowBuilds)
.filter(([, allowed]) => allowed === true)
.map(([name]) => name);
const automergeDisabledDeps = renovateConfig.packageRules
.filter((rule: any) => rule.automerge === false)
.flatMap((rule: any) => rule.matchPackageNames || []);
const missingDeps = onlyBuiltDependencies.filter((dep: string) => !automergeDisabledDeps.includes(dep));
const missingDeps = allowedBuilds.filter((dep: string) => !automergeDisabledDeps.includes(dep));
if (missingDeps.length > 0) {
throw new Error(
`The following onlyBuiltDependencies are missing automerge disable rules in renovate.json5: ${missingDeps.join(", ")}`,
`The following allowBuilds dependencies are missing automerge disable rules in renovate.json5: ${missingDeps.join(", ")}`,
);
}
});
+2 -3
View File
@@ -19,10 +19,9 @@
"noUncheckedIndexedAccess": true,
"strictNullChecks": true,
"experimentalDecorators": true,
"baseUrl": ".",
"types": ["node"],
"paths": {
"@homarr/node-unifi": ["${configDir}/../../node_modules/@types/node-unifi"],
"*": ["node_modules/*"]
"@homarr/node-unifi": ["${configDir}/../../node_modules/@types/node-unifi"]
}
},
"exclude": ["node_modules", "build", "dist", ".next"]
-5
View File
@@ -9,11 +9,6 @@ export default defineConfig({
environment: "jsdom",
include: ["**/*.spec.ts"],
clearMocks: true,
poolOptions: {
threads: {
singleThread: false,
},
},
coverage: {
provider: "v8",
reporter: ["html", "json-summary", "json"],