diff --git a/src/plugins/bundled-plugin-scan.ts b/src/plugins/bundled-plugin-scan.ts index 40d00f1f3c3..43538284be4 100644 --- a/src/plugins/bundled-plugin-scan.ts +++ b/src/plugins/bundled-plugin-scan.ts @@ -1,5 +1,7 @@ import fs from "node:fs"; import path from "node:path"; +import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; const PUBLIC_SURFACE_SOURCE_EXTENSIONS = [".ts", ".mts", ".js", ".mjs", ".cts", ".cjs"] as const; const RUNTIME_SIDECAR_ARTIFACTS = new Set([ @@ -10,17 +12,11 @@ const RUNTIME_SIDECAR_ARTIFACTS = new Set([ ]); export function trimBundledPluginString(value: unknown): string | undefined { - return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined; + return normalizeOptionalString(value); } export function normalizeBundledPluginStringList(value: unknown): string[] { - if (!Array.isArray(value)) { - return []; - } - return value.flatMap((entry) => { - const normalized = trimBundledPluginString(entry); - return normalized ? [normalized] : []; - }); + return normalizeTrimmedStringList(value); } export function rewriteBundledPluginEntryToBuiltPath( @@ -79,9 +75,9 @@ export function collectBundledPluginPublicSurfaceArtifacts(params: { setupEntry?: string; }): readonly string[] | undefined { const excluded = new Set( - [params.sourceEntry, params.setupEntry] - .filter((entry): entry is string => typeof entry === "string" && entry.trim().length > 0) - .map((entry) => path.basename(entry)), + normalizeTrimmedStringList([params.sourceEntry, params.setupEntry]).map((entry) => + path.basename(entry), + ), ); const artifacts = fs .readdirSync(params.pluginDir, { withFileTypes: true }) diff --git a/src/plugins/cache-controls.ts b/src/plugins/cache-controls.ts index 8b613516d80..6ece26892e0 100644 --- a/src/plugins/cache-controls.ts +++ b/src/plugins/cache-controls.ts @@ -1,18 +1,20 @@ +import { normalizeOptionalString } from "../shared/string-coerce.js"; + export const DEFAULT_PLUGIN_DISCOVERY_CACHE_MS = 1000; export const DEFAULT_PLUGIN_MANIFEST_CACHE_MS = 1000; export function shouldUsePluginSnapshotCache(env: NodeJS.ProcessEnv): boolean { - if (env.OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE?.trim()) { + if (normalizeOptionalString(env.OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE)) { return false; } - if (env.OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE?.trim()) { + if (normalizeOptionalString(env.OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE)) { return false; } - const discoveryCacheMs = env.OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS?.trim(); + const discoveryCacheMs = normalizeOptionalString(env.OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS); if (discoveryCacheMs === "0") { return false; } - const manifestCacheMs = env.OPENCLAW_PLUGIN_MANIFEST_CACHE_MS?.trim(); + const manifestCacheMs = normalizeOptionalString(env.OPENCLAW_PLUGIN_MANIFEST_CACHE_MS); if (manifestCacheMs === "0") { return false; } @@ -20,7 +22,7 @@ export function shouldUsePluginSnapshotCache(env: NodeJS.ProcessEnv): boolean { } export function resolvePluginCacheMs(rawValue: string | undefined, defaultMs: number): number { - const raw = rawValue?.trim(); + const raw = normalizeOptionalString(rawValue); if (raw === "" || raw === "0") { return 0; } diff --git a/src/plugins/http-path.ts b/src/plugins/http-path.ts index 069b5ff8d92..d4afb692fed 100644 --- a/src/plugins/http-path.ts +++ b/src/plugins/http-path.ts @@ -1,10 +1,12 @@ +import { normalizeOptionalString } from "../shared/string-coerce.js"; + export function normalizePluginHttpPath( path?: string | null, fallback?: string | null, ): string | null { - const trimmed = path?.trim(); + const trimmed = normalizeOptionalString(path); if (!trimmed) { - const fallbackTrimmed = fallback?.trim(); + const fallbackTrimmed = normalizeOptionalString(fallback); if (!fallbackTrimmed) { return null; } diff --git a/src/plugins/provider-auth-choice-helpers.ts b/src/plugins/provider-auth-choice-helpers.ts index c47fe9bb84d..c450f401f21 100644 --- a/src/plugins/provider-auth-choice-helpers.ts +++ b/src/plugins/provider-auth-choice-helpers.ts @@ -1,12 +1,13 @@ import { normalizeProviderId } from "../agents/model-selection.js"; import type { OpenClawConfig } from "../config/config.js"; +import { normalizeOptionalString } from "../shared/string-coerce.js"; import type { ProviderAuthMethod, ProviderPlugin } from "./types.js"; export function resolveProviderMatch( providers: ProviderPlugin[], rawProvider?: string, ): ProviderPlugin | null { - const raw = rawProvider?.trim(); + const raw = normalizeOptionalString(rawProvider); if (!raw) { return null; } @@ -25,7 +26,7 @@ export function pickAuthMethod( provider: ProviderPlugin, rawMethod?: string, ): ProviderAuthMethod | null { - const raw = rawMethod?.trim(); + const raw = normalizeOptionalString(rawMethod); if (!raw) { return null; } diff --git a/src/plugins/provider-registry-shared.ts b/src/plugins/provider-registry-shared.ts index e840ae9e658..ac8cbc9cd52 100644 --- a/src/plugins/provider-registry-shared.ts +++ b/src/plugins/provider-registry-shared.ts @@ -1,5 +1,7 @@ +import { normalizeOptionalString } from "../shared/string-coerce.js"; + export function normalizeCapabilityProviderId(providerId: string | undefined): string | undefined { - const trimmed = providerId?.trim().toLowerCase(); + const trimmed = normalizeOptionalString(providerId)?.toLowerCase(); return trimmed ? trimmed : undefined; } diff --git a/src/plugins/provider-validation.ts b/src/plugins/provider-validation.ts index 32db406f8df..6f3c8c42560 100644 --- a/src/plugins/provider-validation.ts +++ b/src/plugins/provider-validation.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalString } from "../shared/string-coerce.js"; +import { normalizeTrimmedStringList } from "../shared/string-normalization.js"; import type { PluginDiagnostic, ProviderAuthMethod, ProviderPlugin } from "./types.js"; type ProviderWizardSetup = NonNullable["setup"]>; @@ -20,14 +22,11 @@ function pushProviderDiagnostic(params: { } function normalizeText(value: string | undefined): string | undefined { - const trimmed = value?.trim(); - return trimmed ? trimmed : undefined; + return normalizeOptionalString(value); } function normalizeTextList(values: string[] | undefined): string[] | undefined { - const normalized = Array.from( - new Set((values ?? []).map((value) => value.trim()).filter(Boolean)), - ); + const normalized = Array.from(new Set(normalizeTrimmedStringList(values))); return normalized.length > 0 ? normalized : undefined; }