refactor: dedupe infra lowercase helpers

This commit is contained in:
Peter Steinberger
2026-04-07 15:36:33 +01:00
parent ddde144cb6
commit 761e12008d
8 changed files with 31 additions and 28 deletions

View File

@@ -9,6 +9,7 @@ import {
} from "../infra/device-pairing.js";
import { formatTimeAgo } from "../infra/format-time/format-relative.ts";
import { defaultRuntime } from "../runtime.js";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
import { getTerminalTableWidth, renderTable } from "../terminal/table.js";
import { theme } from "../terminal/theme.js";
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
@@ -100,7 +101,7 @@ function normalizeErrorMessage(error: unknown): string {
}
function shouldUseLocalPairingFallback(opts: DevicesRpcOpts, error: unknown): boolean {
const message = normalizeErrorMessage(error).toLowerCase();
const message = normalizeLowercaseStringOrEmpty(normalizeErrorMessage(error));
if (!message.includes("pairing required")) {
return false;
}

View File

@@ -6,6 +6,7 @@ import { formatErrorMessage } from "../infra/errors.js";
import { readConfiguredLogTail } from "../logging/log-tail.js";
import { parseLogLine } from "../logging/parse-log-line.js";
import { formatTimestamp, isValidTimeZone } from "../logging/timestamps.js";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
import { formatDocsLink } from "../terminal/links.js";
import { clearActiveProgressLine } from "../terminal/progress-line.js";
import { createSafeStreamWriter } from "../terminal/stream-writer.js";
@@ -94,7 +95,7 @@ function normalizeErrorMessage(error: unknown): string {
}
function shouldUseLocalLogsFallback(opts: LogsCliOptions, error: unknown): boolean {
const message = normalizeErrorMessage(error).toLowerCase();
const message = normalizeLowercaseStringOrEmpty(normalizeErrorMessage(error));
if (!message.includes("pairing required")) {
return false;
}

View File

@@ -8,10 +8,10 @@ function parseEnvFlags(raw?: string): string[] {
return [];
}
const trimmed = raw.trim();
if (!trimmed) {
const lowered = normalizeLowercaseStringOrEmpty(trimmed);
if (!lowered) {
return [];
}
const lowered = trimmed.toLowerCase();
if (["0", "false", "off", "none"].includes(lowered)) {
return [];
}

View File

@@ -49,7 +49,10 @@ import {
toAgentStoreSessionKey,
} from "../routing/session-key.js";
import { defaultRuntime, type RuntimeEnv } from "../runtime.js";
import { normalizeOptionalString } from "../shared/string-coerce.js";
import {
normalizeLowercaseStringOrEmpty,
normalizeOptionalString,
} from "../shared/string-coerce.js";
import { escapeRegExp } from "../utils.js";
import { formatErrorMessage, hasErrnoCode } from "./errors.js";
import { isWithinActiveHours } from "./heartbeat-active-hours.js";
@@ -257,7 +260,7 @@ function resolveHeartbeatSession(
};
}
const normalized = trimmed.toLowerCase();
const normalized = normalizeLowercaseStringOrEmpty(trimmed);
if (normalized === "main" || normalized === "global") {
return {
sessionKey: mainSessionKey,

View File

@@ -1,3 +1,5 @@
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
type RuntimeStatusFormatInput = {
status?: string;
pid?: number;
@@ -17,7 +19,11 @@ export function formatRuntimeStatusWithDetails({
fullDetails.push(`pid ${pid}`);
}
const normalizedState = state?.trim();
if (normalizedState && normalizedState.toLowerCase() !== runtimeStatus.toLowerCase()) {
if (
normalizedState &&
normalizeLowercaseStringOrEmpty(normalizedState) !==
normalizeLowercaseStringOrEmpty(runtimeStatus)
) {
fullDetails.push(`state ${normalizedState}`);
}
for (const detail of details) {

View File

@@ -3,6 +3,7 @@
// events ephemeral. Events are session-scoped and require an explicit key.
import { resolveGlobalMap } from "../shared/global-singleton.js";
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
import {
mergeDeliveryContext,
normalizeDeliveryContext,
@@ -45,14 +46,7 @@ function requireSessionKey(key?: string | null): string {
}
function normalizeContextKey(key?: string | null): string | null {
if (!key) {
return null;
}
const trimmed = key.trim();
if (!trimmed) {
return null;
}
return trimmed.toLowerCase();
return normalizeOptionalLowercaseString(key) ?? null;
}
function getSessionQueue(sessionKey: string): SessionQueue | undefined {

View File

@@ -1,5 +1,9 @@
import { spawnSync } from "node:child_process";
import os from "node:os";
import {
normalizeLowercaseStringOrEmpty,
normalizeOptionalLowercaseString,
} from "../shared/string-coerce.js";
import { resolveRuntimeServiceVersion } from "../version.js";
import { pickBestEffortPrimaryLanIPv4 } from "./network-discovery-display.js";
@@ -34,14 +38,7 @@ const TTL_MS = 5 * 60 * 1000; // 5 minutes
const MAX_ENTRIES = 200;
function normalizePresenceKey(key: string | undefined): string | undefined {
if (!key) {
return undefined;
}
const trimmed = key.trim();
if (!trimmed) {
return undefined;
}
return trimmed.toLowerCase();
return normalizeOptionalLowercaseString(key);
}
function resolvePrimaryIPv4(): string | undefined {
@@ -107,7 +104,7 @@ function initSelfPresence() {
text,
ts: Date.now(),
};
const key = host.toLowerCase();
const key = normalizeLowercaseStringOrEmpty(host);
entries.set(key, selfEntry);
}
@@ -122,7 +119,7 @@ function ensureSelfPresence() {
function touchSelfPresence() {
const host = os.hostname();
const key = host.toLowerCase();
const key = normalizeLowercaseStringOrEmpty(host);
const existing = entries.get(key);
if (existing) {
entries.set(key, { ...existing, ts: Date.now() });
@@ -200,7 +197,7 @@ export function updateSystemPresence(payload: SystemPresencePayload): SystemPres
normalizePresenceKey(parsed.host) ||
parsed.ip ||
parsed.text.slice(0, 64) ||
os.hostname().toLowerCase();
normalizeLowercaseStringOrEmpty(os.hostname());
const hadExisting = entries.has(key);
const existing = entries.get(key) ?? ({} as SystemPresence);
const merged: SystemPresence = {
@@ -247,7 +244,7 @@ export function updateSystemPresence(payload: SystemPresencePayload): SystemPres
export function upsertPresence(key: string, presence: Partial<SystemPresence>) {
ensureSelfPresence();
const normalizedKey = normalizePresenceKey(key) ?? os.hostname().toLowerCase();
const normalizedKey = normalizePresenceKey(key) ?? normalizeLowercaseStringOrEmpty(os.hostname());
const existing = entries.get(normalizedKey) ?? ({} as SystemPresence);
const roles = mergeStringList(existing.roles, presence.roles);
const scopes = mergeStringList(existing.scopes, presence.scopes);

View File

@@ -1,3 +1,4 @@
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
import { theme } from "./theme.js";
export function styleHealthChannelLine(line: string, rich: boolean): string {
@@ -12,7 +13,7 @@ export function styleHealthChannelLine(line: string, rich: boolean): string {
const label = line.slice(0, colon + 1);
const detail = line.slice(colon + 1).trimStart();
const normalized = detail.toLowerCase();
const normalized = normalizeLowercaseStringOrEmpty(detail);
const applyPrefix = (prefix: string, color: (value: string) => string) =>
`${label} ${color(detail.slice(0, prefix.length))}${detail.slice(prefix.length)}`;