From 3effffb4911b876d318525cf1e2f1761975f9863 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 15 Feb 2026 04:04:33 +0000 Subject: [PATCH] refactor(commands): dedupe gateway self presence picker --- src/commands/gateway-presence.ts | 27 ++++++++++++++++++++++++++ src/commands/gateway-status/helpers.ts | 23 ++-------------------- src/commands/status-all/gateway.ts | 22 +-------------------- src/commands/status.gateway-probe.ts | 23 +--------------------- 4 files changed, 31 insertions(+), 64 deletions(-) create mode 100644 src/commands/gateway-presence.ts diff --git a/src/commands/gateway-presence.ts b/src/commands/gateway-presence.ts new file mode 100644 index 00000000000..7623b698951 --- /dev/null +++ b/src/commands/gateway-presence.ts @@ -0,0 +1,27 @@ +export type GatewaySelfPresence = { + host?: string; + ip?: string; + version?: string; + platform?: string; +}; + +export function pickGatewaySelfPresence(presence: unknown): GatewaySelfPresence | null { + if (!Array.isArray(presence)) { + return null; + } + const entries = presence as Array>; + const self = + entries.find((e) => e.mode === "gateway" && e.reason === "self") ?? + // Back-compat: older presence payloads only included a `text` line. + entries.find((e) => typeof e.text === "string" && String(e.text).startsWith("Gateway:")) ?? + null; + if (!self) { + return null; + } + return { + host: typeof self.host === "string" ? self.host : undefined, + ip: typeof self.ip === "string" ? self.ip : undefined, + version: typeof self.version === "string" ? self.version : undefined, + platform: typeof self.platform === "string" ? self.platform : undefined, + }; +} diff --git a/src/commands/gateway-status/helpers.ts b/src/commands/gateway-status/helpers.ts index daf9ab7364b..566f894d090 100644 --- a/src/commands/gateway-status/helpers.ts +++ b/src/commands/gateway-status/helpers.ts @@ -3,6 +3,7 @@ import type { GatewayProbeResult } from "../../gateway/probe.js"; import { resolveGatewayPort } from "../../config/config.js"; import { pickPrimaryTailnetIPv4 } from "../../infra/tailnet.js"; import { colorize, theme } from "../../terminal/theme.js"; +import { pickGatewaySelfPresence } from "../gateway-presence.js"; type TargetKind = "explicit" | "configRemote" | "localLoopback" | "sshTunnel"; @@ -178,27 +179,7 @@ export function resolveAuthForTarget( }; } -export function pickGatewaySelfPresence( - presence: unknown, -): { host?: string; ip?: string; version?: string; platform?: string } | null { - if (!Array.isArray(presence)) { - return null; - } - const entries = presence as Array>; - const self = - entries.find((e) => e.mode === "gateway" && e.reason === "self") ?? - entries.find((e) => typeof e.text === "string" && String(e.text).startsWith("Gateway:")) ?? - null; - if (!self) { - return null; - } - return { - host: typeof self.host === "string" ? self.host : undefined, - ip: typeof self.ip === "string" ? self.ip : undefined, - version: typeof self.version === "string" ? self.version : undefined, - platform: typeof self.platform === "string" ? self.platform : undefined, - }; -} +export { pickGatewaySelfPresence }; export function extractConfigSummary(snapshotUnknown: unknown): GatewayConfigSummary { const snap = snapshotUnknown as Partial | null; diff --git a/src/commands/status-all/gateway.ts b/src/commands/status-all/gateway.ts index 6d764376a47..de0fcd0ea66 100644 --- a/src/commands/status-all/gateway.ts +++ b/src/commands/status-all/gateway.ts @@ -180,24 +180,4 @@ export function summarizeLogTail(rawLines: string[], opts?: { maxLines?: number return kept; } -export function pickGatewaySelfPresence(presence: unknown): { - host?: string; - ip?: string; - version?: string; - platform?: string; -} | null { - if (!Array.isArray(presence)) { - return null; - } - const entries = presence as Array>; - const self = entries.find((e) => e.mode === "gateway" && e.reason === "self") ?? null; - if (!self) { - return null; - } - return { - host: typeof self.host === "string" ? self.host : undefined, - ip: typeof self.ip === "string" ? self.ip : undefined, - version: typeof self.version === "string" ? self.version : undefined, - platform: typeof self.platform === "string" ? self.platform : undefined, - }; -} +export { pickGatewaySelfPresence } from "../gateway-presence.js"; diff --git a/src/commands/status.gateway-probe.ts b/src/commands/status.gateway-probe.ts index c0c00465ea1..cec628281cf 100644 --- a/src/commands/status.gateway-probe.ts +++ b/src/commands/status.gateway-probe.ts @@ -1,4 +1,5 @@ import type { loadConfig } from "../config/config.js"; +export { pickGatewaySelfPresence } from "./gateway-presence.js"; export function resolveGatewayProbeAuth(cfg: ReturnType): { token?: string; @@ -25,25 +26,3 @@ export function resolveGatewayProbeAuth(cfg: ReturnType): { : undefined); return { token, password }; } - -export function pickGatewaySelfPresence(presence: unknown): { - host?: string; - ip?: string; - version?: string; - platform?: string; -} | null { - if (!Array.isArray(presence)) { - return null; - } - const entries = presence as Array>; - const self = entries.find((e) => e.mode === "gateway" && e.reason === "self") ?? null; - if (!self) { - return null; - } - return { - host: typeof self.host === "string" ? self.host : undefined, - ip: typeof self.ip === "string" ? self.ip : undefined, - version: typeof self.version === "string" ? self.version : undefined, - platform: typeof self.platform === "string" ? self.platform : undefined, - }; -}