From 1b74d73de06aea47fece27d08bb2f62eff872849 Mon Sep 17 00:00:00 2001 From: ajnart Date: Sun, 16 Aug 2026 15:50:35 +0200 Subject: [PATCH] revert(version): undo version refactor and tests, keep single-file change Keep the User-Agent change as a single edit to packages/core/src/infrastructure/http/request.ts. Remove the @homarr/version package, the consumer migrations, and the unit tests. --- packages/analytics/package.json | 1 - .../analytics/src/send-server-analytics.ts | 4 +- packages/api/package.json | 1 - packages/api/src/router/info.ts | 5 +- packages/core/package.json | 1 - .../src/infrastructure/http/request.spec.ts | 77 ------------------- .../core/src/infrastructure/http/request.ts | 23 +++--- packages/request-handler/package.json | 1 - .../request-handler/src/update-checker.ts | 7 +- packages/version/index.ts | 3 - packages/version/package.json | 20 ----- packages/version/tsconfig.json | 8 -- pnpm-lock.yaml | 22 ------ 13 files changed, 19 insertions(+), 154 deletions(-) delete mode 100644 packages/core/src/infrastructure/http/request.spec.ts delete mode 100644 packages/version/index.ts delete mode 100644 packages/version/package.json delete mode 100644 packages/version/tsconfig.json diff --git a/packages/analytics/package.json b/packages/analytics/package.json index c97ef407a..2c99a29b4 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -26,7 +26,6 @@ "@homarr/core": "workspace:^0.1.0", "@homarr/db": "workspace:^0.1.0", "@homarr/docker": "workspace:^0.1.0", - "@homarr/version": "workspace:^0.1.0", "posthog-node": "catalog:" }, "devDependencies": { diff --git a/packages/analytics/src/send-server-analytics.ts b/packages/analytics/src/send-server-analytics.ts index 497ad0e40..b851f86ec 100644 --- a/packages/analytics/src/send-server-analytics.ts +++ b/packages/analytics/src/send-server-analytics.ts @@ -28,8 +28,8 @@ import { users, } from "@homarr/db/schema"; import { env as dockerEnv } from "@homarr/docker/env"; -import { VERSION } from "@homarr/version"; +import packageJson from "../../../package.json"; import { getPostHogClient } from "./client"; const logger = createLogger({ module: "analytics" }); @@ -121,7 +121,7 @@ export const sendServerAnalyticsAsync = async (): Promise => { const enabledAuthProviders = (["credentials", "oidc", "ldap"] as const).filter(isProviderEnabled); const properties: Record = { - homarrVersion: VERSION, + homarrVersion: packageJson.version, databaseType: isMysql() ? "mysql" : isPostgresql() ? "postgresql" : "sqlite", dockerEnabled: Boolean(dockerEnv.ENABLE_DOCKER), kubernetesEnabled: Boolean(dockerEnv.ENABLE_KUBERNETES), diff --git a/packages/api/package.json b/packages/api/package.json index 60f38eab8..92f68ea36 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -46,7 +46,6 @@ "@homarr/server-settings": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0", - "@homarr/version": "workspace:^0.1.0", "@kubernetes/client-node": "catalog:", "@tanstack/react-query": "catalog:", "@trpc/client": "catalog:", diff --git a/packages/api/src/router/info.ts b/packages/api/src/router/info.ts index a9b1fbe61..156f6387a 100644 --- a/packages/api/src/router/info.ts +++ b/packages/api/src/router/info.ts @@ -1,7 +1,6 @@ import z from "zod/v4"; -import { VERSION } from "@homarr/version"; - +import packageJson from "../../../../package.json"; import { createTRPCRouter, isDemoMode, isDemoReadOnly, publicProcedure, protectedProcedure } from "../trpc"; export const infoRouter = createTRPCRouter({ @@ -17,7 +16,7 @@ export const infoRouter = createTRPCRouter({ }) .query(() => { return { - version: VERSION, + version: packageJson.version, }; }), isDemoMode: publicProcedure.query(() => isDemoMode), diff --git a/packages/core/package.json b/packages/core/package.json index e96a94c90..9c46dd637 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -36,7 +36,6 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@homarr/version": "workspace:^0.1.0", "@t3-oss/env-nextjs": "catalog:", "better-sqlite3": "catalog:", "dns-caching": "catalog:", diff --git a/packages/core/src/infrastructure/http/request.spec.ts b/packages/core/src/infrastructure/http/request.spec.ts deleted file mode 100644 index 643791781..000000000 --- a/packages/core/src/infrastructure/http/request.spec.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { describe, expect, it, vi, beforeEach } from "vitest"; - -const { fetchMock } = vi.hoisted(() => ({ fetchMock: vi.fn() })); - -vi.mock("undici", async (importOriginal) => { - const actual = await (importOriginal as () => Promise>)(); - return { ...actual, fetch: fetchMock }; -}); - -import { Headers } from "undici"; -import { fetchWithTrustedCertificatesAsync, getDefaultUserAgent } from "./request"; - -const dummyDispatcher = {} as never; - -const lastFetchHeaders = (): Headers => { - const [, init] = fetchMock.mock.calls.at(-1) ?? []; - return init?.headers as unknown as Headers; -}; - -describe("fetchWithTrustedCertificatesAsync default User-Agent", () => { - beforeEach(() => { - fetchMock.mockReset(); - }); - - const defaultUserAgent = getDefaultUserAgent(); - - it("sets the default User-Agent when no header is provided", async () => { - await fetchWithTrustedCertificatesAsync("https://example.com", { dispatcher: dummyDispatcher }); - expect(lastFetchHeaders().get("User-Agent")).toBe(defaultUserAgent); - }); - - it("keeps caller-provided record headers", async () => { - await fetchWithTrustedCertificatesAsync("https://example.com", { - dispatcher: dummyDispatcher, - headers: { Authorization: "token" }, - }); - const headers = lastFetchHeaders(); - expect(headers.get("authorization")).toBe("token"); - expect(headers.get("User-Agent")).toBe(defaultUserAgent); - }); - - it("normalizes a Headers instance without losing entries", async () => { - await fetchWithTrustedCertificatesAsync("https://example.com", { - dispatcher: dummyDispatcher, - headers: new Headers({ "x-custom": "present" }), - }); - const headers = lastFetchHeaders(); - expect(headers.get("x-custom")).toBe("present"); - expect(headers.get("User-Agent")).toBe(defaultUserAgent); - }); - - it("normalizes a tuple-array of headers", async () => { - await fetchWithTrustedCertificatesAsync("https://example.com", { - dispatcher: dummyDispatcher, - headers: [["x-tuple", "value"]], - }); - const headers = lastFetchHeaders(); - expect(headers.get("x-tuple")).toBe("value"); - expect(headers.get("User-Agent")).toBe(defaultUserAgent); - }); - - it("does not override a caller-provided User-Agent regardless of casing", async () => { - await fetchWithTrustedCertificatesAsync("https://example.com", { - dispatcher: dummyDispatcher, - headers: { "user-agent": "custom-agent" }, - }); - expect(lastFetchHeaders().get("User-Agent")).toBe("custom-agent"); - }); - - it("sets the default User-Agent on the timeout path too", async () => { - await fetchWithTrustedCertificatesAsync("https://example.com", { - dispatcher: dummyDispatcher, - timeout: 1000, - }); - expect(lastFetchHeaders().get("User-Agent")).toBe(defaultUserAgent); - }); -}); diff --git a/packages/core/src/infrastructure/http/request.ts b/packages/core/src/infrastructure/http/request.ts index 97ba40859..20af8232f 100644 --- a/packages/core/src/infrastructure/http/request.ts +++ b/packages/core/src/infrastructure/http/request.ts @@ -3,27 +3,20 @@ import { Agent as HttpsAgent } from "node:https"; import { checkServerIdentity } from "node:tls"; import axios from "axios"; import type { Agent as UndiciAgent, RequestInfo, RequestInit, Response } from "undici"; -import { Headers, fetch } from "undici"; +import { fetch } from "undici"; import { getAllTrustedCertificatesAsync, getTrustedCertificateHostnamesAsync, } from "@homarr/core/infrastructure/certificates"; import { UndiciHttpAgent } from "@homarr/core/infrastructure/http"; -import { VERSION } from "@homarr/version"; import type { TrustedCertificateHostname } from "../certificates/hostnames"; import { withTimeoutAsync } from "./timeout"; -export const getDefaultUserAgent = () => `Homarr/${VERSION} (+https://homarr.dev)`; +import packageJson from "../../../../../package.json"; -const createFetchHeaders = (initial: RequestInit["headers"]): Headers => { - const headers = new Headers(initial); - if (!headers.has("User-Agent")) { - headers.set("User-Agent", getDefaultUserAgent()); - } - return headers; -}; +export const getDefaultUserAgent = () => `Homarr/${packageJson.version} (+https://homarr.dev)`; export const createCustomCheckServerIdentity = ( trustedHostnames: TrustedCertificateHostname[], @@ -90,7 +83,10 @@ export const fetchWithTrustedCertificatesAsync = async ( async (signal) => fetch(url, { ...fetchOptions, - headers: createFetchHeaders(fetchOptions.headers), + headers: { + "User-Agent": getDefaultUserAgent(), + ...fetchOptions.headers, + }, signal, dispatcher: agent, }), @@ -101,7 +97,10 @@ export const fetchWithTrustedCertificatesAsync = async ( const { bodyTimeout: _bodyTimeout, dispatcher: _dispatcher, ...fetchOptions } = options ?? {}; return fetch(url, { ...fetchOptions, - headers: createFetchHeaders(fetchOptions.headers), + headers: { + "User-Agent": getDefaultUserAgent(), + ...fetchOptions.headers, + }, dispatcher: agent, }); }; diff --git a/packages/request-handler/package.json b/packages/request-handler/package.json index 9d6e03601..29609d87d 100644 --- a/packages/request-handler/package.json +++ b/packages/request-handler/package.json @@ -29,7 +29,6 @@ "@homarr/docker": "workspace:^0.1.0", "@homarr/integrations": "workspace:^0.1.0", "@homarr/redis": "workspace:^0.1.0", - "@homarr/version": "workspace:^0.1.0", "dayjs": "catalog:", "octokit": "catalog:", "superjson": "catalog:", diff --git a/packages/request-handler/src/update-checker.ts b/packages/request-handler/src/update-checker.ts index 7945fc72e..9bc2085cd 100644 --- a/packages/request-handler/src/update-checker.ts +++ b/packages/request-handler/src/update-checker.ts @@ -6,7 +6,8 @@ import { fetchWithTrustedCertificatesAsync } from "@homarr/core/infrastructure/h import { createLogger } from "@homarr/core/infrastructure/logs"; import { ErrorWithMetadata } from "@homarr/core/infrastructure/logs/error"; import { createGetSetChannel, createLockChannel } from "@homarr/redis"; -import { VERSION } from "@homarr/version"; + +import packageJson from "../../../package.json"; const logger = createLogger({ module: "updateCheckerRequestHandler" }); @@ -21,7 +22,7 @@ type UpdateCheckCacheEntry = { checkedAt: number | null; }; -const updateCheckCacheVersion = `v2:${VERSION}`; +const updateCheckCacheVersion = `v2:${packageJson.version}`; const freshUpdateCheckChannel = createGetSetChannel( `update-checker:fresh:${updateCheckCacheVersion}`, ); @@ -68,7 +69,7 @@ const getCachedAvailableUpdatesAsync = async (): Promise try { const attemptedAt = Date.now(); - const availableUpdates = await getAvailableUpdatesAsync(VERSION); + const availableUpdates = await getAvailableUpdatesAsync(packageJson.version); const result: UpdateCheckCacheEntry = { availableUpdates, attemptedAt, diff --git a/packages/version/index.ts b/packages/version/index.ts deleted file mode 100644 index 31b768021..000000000 --- a/packages/version/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import packageJson from "../../package.json"; - -export const VERSION = packageJson.version; diff --git a/packages/version/package.json b/packages/version/package.json deleted file mode 100644 index 25b10702a..000000000 --- a/packages/version/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@homarr/version", - "version": "0.1.0", - "private": true, - "license": "Apache-2.0", - "type": "module", - "exports": { - ".": "./index.ts" - }, - "scripts": { - "clean": "rm -rf .turbo node_modules", - "format": "oxfmt .", - "lint": "oxlint", - "typecheck": "tsc --noEmit" - }, - "devDependencies": { - "@homarr/tsconfig": "workspace:^0.1.0", - "typescript": "catalog:" - } -} diff --git a/packages/version/tsconfig.json b/packages/version/tsconfig.json deleted file mode 100644 index cbe8483d9..000000000 --- a/packages/version/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "@homarr/tsconfig/base.json", - "compilerOptions": { - "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" - }, - "include": ["*.ts", "src"], - "exclude": ["node_modules"] -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8d00a775c..d620d34f4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1241,9 +1241,6 @@ importers: '@homarr/docker': specifier: workspace:^0.1.0 version: link:../docker - '@homarr/version': - specifier: workspace:^0.1.0 - version: link:../version posthog-node: specifier: 'catalog:' version: 5.41.0(rxjs@7.8.2) @@ -1314,9 +1311,6 @@ importers: '@homarr/validation': specifier: workspace:^0.1.0 version: link:../validation - '@homarr/version': - specifier: workspace:^0.1.0 - version: link:../version '@kubernetes/client-node': specifier: 'catalog:' version: 1.4.0(supports-color@10.2.2) @@ -1526,9 +1520,6 @@ importers: packages/core: dependencies: - '@homarr/version': - specifier: workspace:^0.1.0 - version: link:../version '@t3-oss/env-nextjs': specifier: 'catalog:' version: 0.13.11(arktype@2.1.20)(typescript@7.0.2)(zod@4.4.3) @@ -2265,9 +2256,6 @@ importers: '@homarr/redis': specifier: workspace:^0.1.0 version: link:../redis - '@homarr/version': - specifier: workspace:^0.1.0 - version: link:../version dayjs: specifier: 'catalog:' version: 1.11.21 @@ -2525,15 +2513,6 @@ importers: specifier: 'catalog:' version: 7.0.2 - packages/version: - devDependencies: - '@homarr/tsconfig': - specifier: workspace:^0.1.0 - version: link:../../tooling/typescript - typescript: - specifier: 'catalog:' - version: 7.0.2 - packages/widgets: dependencies: '@dnd-kit/core': @@ -9428,7 +9407,6 @@ packages: crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} - deprecated: Active development of CryptoJS has been discontinued. This library is no longer maintained. crypto-random-string@4.0.0: resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==}