/** Target media-node version served from /install/media-node-linux-* */ export const MEDIA_NODE_TARGET_VERSION = process.env.MEDIA_NODE_VERSION?.trim() || "1.3.3"; /** Minimum node version that handles UPGRADE over WebSocket */ const REMOTE_UPGRADE_MIN_VERSION = "1.3.3"; function parseVersion(version: string): [number, number, number] { const parts = version.trim().split("."); return [ Number.parseInt(parts[0] ?? "0", 10) || 0, Number.parseInt(parts[1] ?? "0", 10) || 0, Number.parseInt(parts[2] ?? "0", 10) || 0, ]; } export function versionGte(version: string | null | undefined, min: string): boolean { if (!version?.trim()) return false; const [a0, a1, a2] = parseVersion(version); const [b0, b1, b2] = parseVersion(min); if (a0 !== b0) return a0 > b0; if (a1 !== b1) return a1 > b1; return a2 >= b2; } export function nodeSupportsRemoteUpgrade(version: string | null | undefined): boolean { return versionGte(version, REMOTE_UPGRADE_MIN_VERSION); } export function mediaNodeBinaryForArch(architecture: string | null | undefined): string { const arch = (architecture ?? "amd64").toLowerCase(); if (arch === "arm64" || arch === "aarch64") { return "media-node-linux-arm64"; } return "media-node-linux-amd64"; } export function inferNodeAppdata(paths: string[]): { appdata: string; platform: "synology" | "unraid"; } { const isSynology = paths.some((p) => p.startsWith("/volume1")); return { appdata: isSynology ? "/volume1/docker/media-node" : "/mnt/user/appdata/media-node", platform: isSynology ? "synology" : "unraid", }; } export function buildUpgradeCommand( masterUrl: string, paths: string[] ): { command: string; appdata: string; platform: "synology" | "unraid" } { const { appdata, platform } = inferNodeAppdata(paths); const command = `curl -fsSL ${masterUrl}/install/upgrade-node.sh | bash -s -- --appdata=${appdata}`; return { command, appdata, platform }; }