refactor: dedupe shared normalizer readers

This commit is contained in:
Peter Steinberger
2026-04-07 08:25:45 +01:00
parent 2197ce62bd
commit 02c08b3929
7 changed files with 32 additions and 37 deletions

View File

@@ -1,5 +1,6 @@
import type { Command } from "commander";
import { defaultRuntime } from "../../runtime.js";
import { normalizeOptionalString } from "../../shared/string-coerce.js";
import { getNodesTheme, runNodesCommand } from "./cli-utils.js";
import { callGatewayCli, nodesCallOpts, resolveNodeId } from "./rpc.js";
import type { NodesRpcOpts } from "./types.js";
@@ -15,7 +16,7 @@ function normalizeEnvironment(value: unknown): "sandbox" | "production" | null {
if (typeof value !== "string") {
return null;
}
const normalized = value.trim().toLowerCase();
const normalized = normalizeOptionalString(value)?.toLowerCase();
if (normalized === "sandbox" || normalized === "production") {
return normalized;
}
@@ -68,12 +69,10 @@ export function registerNodesPushCommand(nodes: Command) {
const ok = parsed.ok === true;
const status = typeof parsed.status === "number" ? parsed.status : 0;
const reason =
typeof parsed.reason === "string" && parsed.reason.trim().length > 0
? parsed.reason.trim()
: undefined;
typeof parsed.reason === "string" ? normalizeOptionalString(parsed.reason) : undefined;
const env =
typeof parsed.environment === "string" && parsed.environment.trim().length > 0
? parsed.environment.trim()
typeof parsed.environment === "string"
? (normalizeOptionalString(parsed.environment) ?? "unknown")
: "unknown";
const { ok: okLabel, error: errorLabel } = getNodesTheme();
const label = ok ? okLabel : errorLabel;

View File

@@ -5,6 +5,7 @@ import path from "node:path";
import { promisify } from "node:util";
import type { OpenClawConfig } from "../config/config.js";
import { hasConfiguredSecretInput } from "../config/types.secrets.js";
import { normalizeOptionalString } from "../shared/string-coerce.js";
import { note } from "../terminal/note.js";
import { shortenHomePath } from "../utils.js";
@@ -79,10 +80,10 @@ export async function noteMacLaunchctlGatewayEnvOverrides(
const passwordEntries = [
["OPENCLAW_GATEWAY_PASSWORD", await getenv("OPENCLAW_GATEWAY_PASSWORD")],
] as const;
const tokenEntry = tokenEntries.find(([, value]) => value?.trim());
const passwordEntry = passwordEntries.find(([, value]) => value?.trim());
const envToken = tokenEntry?.[1]?.trim() ?? "";
const envPassword = passwordEntry?.[1]?.trim() ?? "";
const tokenEntry = tokenEntries.find(([, value]) => normalizeOptionalString(value));
const passwordEntry = passwordEntries.find(([, value]) => normalizeOptionalString(value));
const envToken = normalizeOptionalString(tokenEntry?.[1]) ?? "";
const envPassword = normalizeOptionalString(passwordEntry?.[1]) ?? "";
const envTokenKey = tokenEntry?.[0];
const envPasswordKey = passwordEntry?.[0];
if (!envToken && !envPassword) {
@@ -106,7 +107,7 @@ export async function noteMacLaunchctlGatewayEnvOverrides(
}
function isTruthyEnvValue(value: string | undefined): boolean {
return typeof value === "string" && value.trim().length > 0;
return Boolean(normalizeOptionalString(value));
}
function isTmpCompileCachePath(cachePath: string): boolean {

View File

@@ -1,11 +1,8 @@
import { mapAllowFromEntries } from "openclaw/plugin-sdk/channel-config-helpers";
import { normalizeOptionalString } from "../shared/string-coerce.js";
export function normalizeNonEmptyString(value: unknown): string | null {
if (typeof value !== "string") {
return null;
}
const trimmed = value.trim();
return trimmed ? trimmed : null;
return typeof value === "string" ? (normalizeOptionalString(value) ?? null) : null;
}
export function normalizeStringArray(value: unknown): string[] {

View File

@@ -1,4 +1,5 @@
import crypto from "node:crypto";
import { normalizeOptionalString } from "../shared/string-coerce.js";
export function sha256HexPrefix(value: string, len = 12): string {
const safeLen = Number.isFinite(len) ? Math.max(1, Math.floor(len)) : 12;
@@ -6,7 +7,7 @@ export function sha256HexPrefix(value: string, len = 12): string {
}
export function redactIdentifier(value: string | undefined, opts?: { len?: number }): string {
const trimmed = value?.trim();
const trimmed = normalizeOptionalString(value);
if (!trimmed) {
return "-";
}

View File

@@ -7,6 +7,7 @@ import type {
PluginHookReplyDispatchEvent,
PluginHookReplyDispatchResult,
} from "../plugins/types.js";
import { normalizeOptionalString } from "../shared/string-coerce.js";
export { getAcpSessionManager };
export { AcpRuntimeError, isAcpRuntimeError } from "../acp/runtime/errors.js";
@@ -42,17 +43,12 @@ function loadDispatchAcpRuntime() {
}
function hasExplicitCommandCandidate(ctx: PluginHookReplyDispatchEvent["ctx"]): boolean {
const commandBody = ctx.CommandBody;
if (typeof commandBody === "string" && commandBody.trim().length > 0) {
const commandBody = normalizeOptionalString(ctx.CommandBody);
if (commandBody) {
return true;
}
const bodyForCommands = ctx.BodyForCommands;
if (typeof bodyForCommands !== "string") {
return false;
}
const normalized = bodyForCommands.trim();
const normalized = normalizeOptionalString(ctx.BodyForCommands);
if (!normalized) {
return false;
}

View File

@@ -1,5 +1,6 @@
import { readFileSync, statSync } from "node:fs";
import path from "node:path";
import { normalizeOptionalString } from "../shared/string-coerce.js";
export type WindowsSpawnResolution =
| "direct"
@@ -129,7 +130,7 @@ function resolveBinEntry(
binField: string | Record<string, string> | undefined,
): string | null {
if (typeof binField === "string") {
const trimmed = binField.trim();
const trimmed = normalizeOptionalString(binField);
return trimmed || null;
}
if (!binField || typeof binField !== "object") {
@@ -138,14 +139,17 @@ function resolveBinEntry(
if (packageName) {
const preferred = binField[packageName];
if (typeof preferred === "string" && preferred.trim()) {
return preferred.trim();
const normalizedPreferred =
typeof preferred === "string" ? normalizeOptionalString(preferred) : undefined;
if (normalizedPreferred) {
return normalizedPreferred;
}
}
for (const value of Object.values(binField)) {
if (typeof value === "string" && value.trim()) {
return value.trim();
const normalizedValue = typeof value === "string" ? normalizeOptionalString(value) : undefined;
if (normalizedValue) {
return normalizedValue;
}
}
return null;