refactor: dedupe browser trimmed readers

This commit is contained in:
Peter Steinberger
2026-04-07 23:04:38 +01:00
parent 5fa3b8d7a0
commit 1868f301ed
6 changed files with 31 additions and 22 deletions

View File

@@ -1,3 +1,5 @@
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
type BridgeAuth = {
token?: string;
password?: string;
@@ -11,8 +13,8 @@ export function setBridgeAuthForPort(port: number, auth: BridgeAuth): void {
if (!Number.isFinite(port) || port <= 0) {
return;
}
const token = typeof auth.token === "string" ? auth.token.trim() : "";
const password = typeof auth.password === "string" ? auth.password.trim() : "";
const token = normalizeOptionalString(auth.token) ?? "";
const password = normalizeOptionalString(auth.password) ?? "";
authByPort.set(port, {
token: token || undefined,
password: password || undefined,

View File

@@ -1,3 +1,4 @@
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
import { formatCliCommand } from "../cli/command-format.js";
import { loadConfig } from "../config/config.js";
@@ -141,8 +142,9 @@ function resolveBrowserFetchOperatorHint(url: string): string {
}
function normalizeErrorMessage(err: unknown): string {
if (err instanceof Error && err.message.trim().length > 0) {
return err.message.trim();
const message = err instanceof Error ? normalizeOptionalString(err.message) : undefined;
if (message) {
return message;
}
return String(err);
}

View File

@@ -1,4 +1,7 @@
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
import {
normalizeLowercaseStringOrEmpty,
normalizeOptionalString,
} from "openclaw/plugin-sdk/text-runtime";
import type { OpenClawConfig } from "../config/config.js";
import { loadConfig } from "../config/config.js";
import { resolveGatewayAuth } from "../gateway/auth.js";
@@ -18,8 +21,8 @@ export function resolveBrowserControlAuth(
env,
tailscaleMode: cfg?.gateway?.tailscale?.mode,
});
const token = typeof auth.token === "string" ? auth.token.trim() : "";
const password = typeof auth.password === "string" ? auth.password.trim() : "";
const token = normalizeOptionalString(auth.token) ?? "";
const password = normalizeOptionalString(auth.password) ?? "";
return {
token: token || undefined,
password: password || undefined,

View File

@@ -1,3 +1,4 @@
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
import { toBrowserErrorResponse } from "../errors.js";
import type { PwAiModule } from "../pw-ai-module.js";
import { getPwAiModule as getPwAiModuleBase } from "../pw-ai-module.js";
@@ -24,12 +25,12 @@ export function readBody(req: BrowserRequest): Record<string, unknown> {
}
export function resolveTargetIdFromBody(body: Record<string, unknown>): string | undefined {
const targetId = typeof body.targetId === "string" ? body.targetId.trim() : "";
const targetId = normalizeOptionalString(body.targetId) ?? "";
return targetId || undefined;
}
export function resolveTargetIdFromQuery(query: Record<string, unknown>): string | undefined {
const targetId = typeof query.targetId === "string" ? query.targetId.trim() : "";
const targetId = normalizeOptionalString(query.targetId) ?? "";
return targetId || undefined;
}

View File

@@ -38,11 +38,8 @@ export function jsonError(res: BrowserResponse, status: number, message: string)
}
export function toStringOrEmpty(value: unknown) {
if (typeof value === "string") {
return value.trim();
}
if (typeof value === "number" || typeof value === "boolean") {
return String(value).trim();
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
return normalizeOptionalString(String(value)) ?? "";
}
return "";
}
@@ -51,8 +48,9 @@ export function toNumber(value: unknown) {
if (typeof value === "number" && Number.isFinite(value)) {
return value;
}
if (typeof value === "string" && value.trim()) {
const parsed = Number(value);
const normalized = typeof value === "string" ? normalizeOptionalString(value) : undefined;
if (normalized) {
const parsed = Number(normalized);
return Number.isFinite(parsed) ? parsed : undefined;
}
return undefined;

View File

@@ -1,5 +1,8 @@
import crypto from "node:crypto";
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
import {
normalizeLowercaseStringOrEmpty,
normalizeOptionalString,
} from "openclaw/plugin-sdk/text-runtime";
import {
ErrorCodes,
applyBrowserProxyPaths,
@@ -49,7 +52,7 @@ function normalizeNodeKey(value: string) {
}
function resolveBrowserNode(nodes: NodeSession[], query: string): NodeSession | null {
const q = query.trim();
const q = normalizeOptionalString(query) ?? "";
if (!q) {
return null;
}
@@ -94,12 +97,12 @@ function resolveBrowserNodeTarget(params: {
}
const browserNodes = params.nodes.filter((node) => isBrowserNode(node));
if (browserNodes.length === 0) {
if (policy?.node?.trim()) {
if (normalizeOptionalString(policy?.node)) {
throw new Error("No connected browser-capable nodes.");
}
return null;
}
const requested = policy?.node?.trim() || "";
const requested = normalizeOptionalString(policy?.node) ?? "";
if (requested) {
const resolved = resolveBrowserNode(browserNodes, requested);
if (!resolved) {
@@ -130,8 +133,8 @@ export async function handleBrowserGatewayRequest({
context,
}: Parameters<GatewayRequestHandlers["browser.request"]>[0]) {
const typed = params as BrowserRequestParams;
const methodRaw = typeof typed.method === "string" ? typed.method.trim().toUpperCase() : "";
const path = typeof typed.path === "string" ? typed.path.trim() : "";
const methodRaw = (normalizeOptionalString(typed.method) ?? "").toUpperCase();
const path = normalizeOptionalString(typed.path) ?? "";
const query = typed.query && typeof typed.query === "object" ? typed.query : undefined;
const body = typed.body;
const timeoutMs =