refactor: dedupe shared helper readers

This commit is contained in:
Peter Steinberger
2026-04-07 06:24:41 +01:00
parent 4504efb7ec
commit cd313c7f67
7 changed files with 31 additions and 21 deletions

View File

@@ -1,4 +1,5 @@
import { z } from "zod";
import { normalizeOptionalString } from "../shared/string-coerce.js";
import { normalizeMessageChannel } from "../utils/message-channel.js";
export type ClaudeChannelMode = "off" | "on" | "auto";
@@ -125,7 +126,7 @@ export const ClaudePermissionRequestSchema = z.object({
});
export function toText(value: unknown): string | undefined {
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
return normalizeOptionalString(value);
}
export function resolveMessageId(entry: Record<string, unknown>): string | undefined {

View File

@@ -1,3 +1,5 @@
import { normalizeOptionalString } from "./string-coerce.js";
export function resolveEmojiAndHomepage(params: {
metadata?: { emoji?: string; homepage?: string } | null;
frontmatter?: {
@@ -13,6 +15,6 @@ export function resolveEmojiAndHomepage(params: {
params.frontmatter?.homepage ??
params.frontmatter?.website ??
params.frontmatter?.url;
const homepage = homepageRaw?.trim() ? homepageRaw.trim() : undefined;
const homepage = normalizeOptionalString(homepageRaw);
return { ...(emoji ? { emoji } : {}), ...(homepage ? { homepage } : {}) };
}

View File

@@ -1,3 +1,5 @@
import { normalizeOptionalString } from "./string-coerce.js";
export type GatewayBindUrlResult =
| {
url: string;
@@ -18,7 +20,7 @@ export function resolveGatewayBindUrl(params: {
}): GatewayBindUrlResult {
const bind = params.bind ?? "loopback";
if (bind === "custom") {
const host = params.customBindHost?.trim();
const host = normalizeOptionalString(params.customBindHost);
if (host) {
return { url: `${params.scheme}://${host}:${params.port}`, source: "gateway.bind=custom" };
}

View File

@@ -1,4 +1,5 @@
import ipaddr from "ipaddr.js";
import { normalizeOptionalString } from "../string-coerce.js";
export type ParsedIpAddress = ipaddr.IPv4 | ipaddr.IPv6;
type Ipv4Range = ReturnType<ipaddr.IPv4["range"]>;
@@ -134,7 +135,7 @@ function normalizeIpv4MappedAddress(address: ParsedIpAddress): ParsedIpAddress {
}
function normalizeIpParseInput(raw: string | undefined): string | undefined {
const trimmed = raw?.trim();
const trimmed = normalizeOptionalString(raw);
if (!trimmed) {
return undefined;
}
@@ -179,7 +180,7 @@ export function normalizeIpAddress(raw: string | undefined): string | undefined
}
export function isCanonicalDottedDecimalIPv4(raw: string | undefined): boolean {
const trimmed = raw?.trim();
const trimmed = normalizeOptionalString(raw);
if (!trimmed) {
return false;
}
@@ -191,7 +192,7 @@ export function isCanonicalDottedDecimalIPv4(raw: string | undefined): boolean {
}
export function isLegacyIpv4Literal(raw: string | undefined): boolean {
const trimmed = raw?.trim();
const trimmed = normalizeOptionalString(raw);
if (!trimmed) {
return false;
}

View File

@@ -1,3 +1,5 @@
import { normalizeOptionalString } from "./string-coerce.js";
export type NodeMatchCandidate = {
nodeId: string;
displayName?: string;
@@ -30,19 +32,20 @@ function listKnownNodes(nodes: NodeMatchCandidate[]): string {
function formatNodeCandidateLabel(node: NodeMatchCandidate): string {
const label = node.displayName || node.remoteIp || node.nodeId;
const details = [`node=${node.nodeId}`];
if (typeof node.clientId === "string" && node.clientId.trim()) {
details.push(`client=${node.clientId.trim()}`);
const clientId = normalizeOptionalString(node.clientId);
if (clientId) {
details.push(`client=${clientId}`);
}
return `${label} [${details.join(", ")}]`;
}
function isCurrentOpenClawClient(clientId: string | undefined): boolean {
const normalized = clientId?.trim().toLowerCase() ?? "";
const normalized = normalizeOptionalString(clientId)?.toLowerCase() ?? "";
return normalized.startsWith("openclaw-");
}
function isLegacyClawdbotClient(clientId: string | undefined): boolean {
const normalized = clientId?.trim().toLowerCase() ?? "";
const normalized = normalizeOptionalString(clientId)?.toLowerCase() ?? "";
return normalized.startsWith("clawdbot-") || normalized.startsWith("moldbot-");
}
@@ -95,7 +98,7 @@ function scoreNodeCandidate(node: NodeMatchCandidate, matchScore: number): numbe
}
function resolveScoredMatches(nodes: NodeMatchCandidate[], query: string): ScoredNodeMatch[] {
const trimmed = query.trim();
const trimmed = normalizeOptionalString(query);
if (!trimmed) {
return [];
}

View File

@@ -15,5 +15,5 @@ export function normalizeOptionalString(value: unknown): string | undefined {
}
export function hasNonEmptyString(value: unknown): value is string {
return typeof value === "string" && value.trim().length > 0;
return normalizeOptionalString(value) !== undefined;
}

View File

@@ -1,3 +1,5 @@
import { normalizeOptionalString } from "./string-coerce.js";
export function normalizeStringEntries(list?: ReadonlyArray<unknown>) {
return (list ?? []).map((entry) => String(entry).trim()).filter(Boolean);
}
@@ -10,9 +12,10 @@ export function normalizeTrimmedStringList(value: unknown): string[] {
if (!Array.isArray(value)) {
return [];
}
return value.flatMap((entry) =>
typeof entry === "string" && entry.trim() ? [entry.trim()] : [],
);
return value.flatMap((entry) => {
const normalized = normalizeOptionalString(entry);
return normalized ? [normalized] : [];
});
}
export function normalizeOptionalTrimmedStringList(value: unknown): string[] | undefined {
@@ -31,10 +34,8 @@ export function normalizeSingleOrTrimmedStringList(value: unknown): string[] {
if (Array.isArray(value)) {
return normalizeTrimmedStringList(value);
}
if (typeof value === "string" && value.trim()) {
return [value.trim()];
}
return [];
const normalized = normalizeOptionalString(value);
return normalized ? [normalized] : [];
}
export function normalizeCsvOrLooseStringList(value: unknown): string[] {
@@ -51,7 +52,7 @@ export function normalizeCsvOrLooseStringList(value: unknown): string[] {
}
export function normalizeHyphenSlug(raw?: string | null) {
const trimmed = raw?.trim().toLowerCase() ?? "";
const trimmed = normalizeOptionalString(raw)?.toLowerCase() ?? "";
if (!trimmed) {
return "";
}
@@ -61,7 +62,7 @@ export function normalizeHyphenSlug(raw?: string | null) {
}
export function normalizeAtHashSlug(raw?: string | null) {
const trimmed = raw?.trim().toLowerCase() ?? "";
const trimmed = normalizeOptionalString(raw)?.toLowerCase() ?? "";
if (!trimmed) {
return "";
}