mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-01 10:50:21 +00:00
refactor: dedupe gateway infra lowercase helpers
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
requestDevicePairing,
|
||||
} from "../infra/device-pairing.js";
|
||||
import { isTruthyEnvValue } from "../infra/env.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
import { getFreePortBlockWithPermissionFallback } from "../test-utils/ports.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
|
||||
import { GatewayClient } from "./client.js";
|
||||
@@ -101,8 +102,8 @@ export function resolveCliModelSwitchProbeTarget(
|
||||
providerId: string,
|
||||
modelRef: string,
|
||||
): string | undefined {
|
||||
const normalizedProvider = providerId.trim().toLowerCase();
|
||||
const normalizedModelRef = modelRef.trim().toLowerCase();
|
||||
const normalizedProvider = normalizeLowercaseStringOrEmpty(providerId);
|
||||
const normalizedModelRef = normalizeLowercaseStringOrEmpty(modelRef);
|
||||
if (normalizedProvider !== "claude-cli") {
|
||||
return undefined;
|
||||
}
|
||||
@@ -254,7 +255,7 @@ async function connectClientOnce(params: {
|
||||
}
|
||||
|
||||
function isRetryableGatewayConnectError(error: Error): boolean {
|
||||
const message = error.message.toLowerCase();
|
||||
const message = normalizeLowercaseStringOrEmpty(error.message);
|
||||
return (
|
||||
message.includes("gateway closed during connect (1000)") ||
|
||||
message.includes("gateway connect timeout") ||
|
||||
|
||||
@@ -38,7 +38,7 @@ function normalizeTailnetHostForUrl(rawHost: string): string | null {
|
||||
}
|
||||
const parsed = parseCanonicalIpAddress(trimmed);
|
||||
if (parsed && isIpv6Address(parsed)) {
|
||||
return `[${parsed.toString().toLowerCase()}]`;
|
||||
return `[${normalizeLowercaseStringOrEmpty(parsed.toString())}]`;
|
||||
}
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { normalizeModelRef } from "../agents/model-selection.js";
|
||||
import { normalizeProviderId } from "../agents/provider-id.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
|
||||
export type CachedModelPricing = {
|
||||
input: number;
|
||||
@@ -24,7 +25,9 @@ function modelPricingCacheKey(provider: string, model: string): string {
|
||||
if (!providerId || !modelId) {
|
||||
return "";
|
||||
}
|
||||
return modelId.toLowerCase().startsWith(`${providerId.toLowerCase()}/`)
|
||||
return normalizeLowercaseStringOrEmpty(modelId).startsWith(
|
||||
`${normalizeLowercaseStringOrEmpty(providerId)}/`,
|
||||
)
|
||||
? modelId
|
||||
: `${providerId}/${modelId}`;
|
||||
}
|
||||
|
||||
@@ -781,7 +781,7 @@ export function createGatewayHttpServer(opts: {
|
||||
});
|
||||
|
||||
// Don't interfere with WebSocket upgrades; ws handles the 'upgrade' event.
|
||||
if (String(req.headers.upgrade ?? "").toLowerCase() === "websocket") {
|
||||
if (normalizeLowercaseStringOrEmpty(req.headers.upgrade) === "websocket") {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,10 @@ import { classifySessionKeyShape, normalizeAgentId } from "../../routing/session
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { normalizeInputProvenance, type InputProvenance } from "../../sessions/input-provenance.js";
|
||||
import { resolveSendPolicy } from "../../sessions/send-policy.js";
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import {
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString,
|
||||
} from "../../shared/string-coerce.js";
|
||||
import { createRunningTaskRun } from "../../tasks/task-executor.js";
|
||||
import {
|
||||
normalizeDeliveryContext,
|
||||
@@ -502,7 +505,8 @@ export const agentHandlers: GatewayRequestHandlers = {
|
||||
);
|
||||
return;
|
||||
}
|
||||
const resetReason = resetCommandMatch[1]?.toLowerCase() === "new" ? "new" : "reset";
|
||||
const resetReason =
|
||||
normalizeOptionalLowercaseString(resetCommandMatch[1]) === "new" ? "new" : "reset";
|
||||
const resetResult = await runSessionResetFromAgent({
|
||||
key: requestedSessionKey,
|
||||
reason: resetReason,
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
resolveMemoryRemDreamingConfig,
|
||||
} from "../../memory-host-sdk/dreaming.js";
|
||||
import { getActiveMemorySearchManager } from "../../plugins/memory-runtime.js";
|
||||
import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js";
|
||||
import { formatError } from "../server-utils.js";
|
||||
import { asRecord, normalizeTrimmedString } from "./record-shared.js";
|
||||
import type { GatewayRequestHandlers } from "./types.js";
|
||||
@@ -437,7 +438,7 @@ function isManagedDreamingJob(
|
||||
return true;
|
||||
}
|
||||
const name = normalizeTrimmedString(job.name);
|
||||
const payloadKind = normalizeTrimmedString(job.payload?.kind)?.toLowerCase();
|
||||
const payloadKind = normalizeOptionalLowercaseString(job.payload?.kind);
|
||||
const payloadText = normalizeTrimmedString(job.payload?.text);
|
||||
return (
|
||||
name === params.name && payloadKind === "systemevent" && payloadText === params.payloadText
|
||||
|
||||
@@ -33,7 +33,11 @@ import {
|
||||
resolveAgentIdFromSessionKey,
|
||||
toAgentStoreSessionKey,
|
||||
} from "../../routing/session-key.js";
|
||||
import { normalizeOptionalString, readStringValue } from "../../shared/string-coerce.js";
|
||||
import {
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString,
|
||||
readStringValue,
|
||||
} from "../../shared/string-coerce.js";
|
||||
import { GATEWAY_CLIENT_IDS } from "../protocol/client-info.js";
|
||||
import {
|
||||
ErrorCodes,
|
||||
@@ -805,7 +809,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
|
||||
}
|
||||
canonicalParentSessionKey = parent.canonicalKey;
|
||||
}
|
||||
const loweredRequestedKey = requestedKey?.toLowerCase();
|
||||
const loweredRequestedKey = normalizeOptionalLowercaseString(requestedKey);
|
||||
const key = requestedKey
|
||||
? loweredRequestedKey === "global" || loweredRequestedKey === "unknown"
|
||||
? loweredRequestedKey
|
||||
|
||||
@@ -9,6 +9,7 @@ import type { TalkConfigResponse, TalkProviderConfig } from "../../config/types.
|
||||
import type { OpenClawConfig, TtsConfig, TtsProviderConfigMap } from "../../config/types.js";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString,
|
||||
} from "../../shared/string-coerce.js";
|
||||
import { canonicalizeSpeechProviderId, getSpeechProvider } from "../../tts/provider-registry.js";
|
||||
@@ -203,8 +204,8 @@ function inferMimeType(
|
||||
outputFormat: string | undefined,
|
||||
fileExtension: string | undefined,
|
||||
): string | undefined {
|
||||
const normalizedOutput = normalizeOptionalString(outputFormat)?.toLowerCase();
|
||||
const normalizedExtension = normalizeOptionalString(fileExtension)?.toLowerCase();
|
||||
const normalizedOutput = normalizeOptionalLowercaseString(outputFormat);
|
||||
const normalizedExtension = normalizeOptionalLowercaseString(fileExtension);
|
||||
if (
|
||||
normalizedOutput === "mp3" ||
|
||||
normalizedOutput?.startsWith("mp3_") ||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { resolveCanvasHostUrl } from "../../infra/canvas-host-url.js";
|
||||
import { removeRemoteNodeInfo } from "../../infra/skills-remote.js";
|
||||
import { upsertPresence } from "../../infra/system-presence.js";
|
||||
import type { createSubsystemLogger } from "../../logging/subsystem.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js";
|
||||
import { truncateUtf16Safe } from "../../utils.js";
|
||||
import { isWebchatClient } from "../../utils/message-channel.js";
|
||||
import type { AuthRateLimiter } from "../auth-rate-limit.js";
|
||||
@@ -231,7 +232,8 @@ export function attachGatewayWsConnectionHandler(params: AttachGatewayWsConnecti
|
||||
|
||||
const isNoisySwiftPmHelperClose = (userAgent: string | undefined, remote: string | undefined) =>
|
||||
Boolean(
|
||||
userAgent?.toLowerCase().includes("swiftpm-testing-helper") && isLoopbackAddress(remote),
|
||||
normalizeLowercaseStringOrEmpty(userAgent).includes("swiftpm-testing-helper") &&
|
||||
isLoopbackAddress(remote),
|
||||
);
|
||||
|
||||
socket.once("close", (code, reason) => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { verifyDeviceSignature } from "../../../infra/device-identity.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js";
|
||||
import type { AuthRateLimiter } from "../../auth-rate-limit.js";
|
||||
import type { GatewayAuthResult } from "../../auth.js";
|
||||
import { buildDeviceAuthPayload, buildDeviceAuthPayloadV3 } from "../../device-auth.js";
|
||||
@@ -41,7 +42,7 @@ function resolveBrowserOriginRateLimitKey(requestOrigin?: string): string {
|
||||
return BROWSER_ORIGIN_LOOPBACK_RATE_LIMIT_IP;
|
||||
}
|
||||
try {
|
||||
return `${BROWSER_ORIGIN_RATE_LIMIT_KEY_PREFIX}${new URL(trimmedOrigin).origin.toLowerCase()}`;
|
||||
return `${BROWSER_ORIGIN_RATE_LIMIT_KEY_PREFIX}${normalizeLowercaseStringOrEmpty(new URL(trimmedOrigin).origin)}`;
|
||||
} catch {
|
||||
return BROWSER_ORIGIN_LOOPBACK_RATE_LIMIT_IP;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ import {
|
||||
} from "../shared/avatar-policy.js";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString,
|
||||
} from "../shared/string-coerce.js";
|
||||
import { normalizeSessionDeliveryFields } from "../utils/delivery-context.js";
|
||||
@@ -464,10 +465,10 @@ export function findStoreKeysIgnoreCase(
|
||||
store: Record<string, unknown>,
|
||||
targetKey: string,
|
||||
): string[] {
|
||||
const lowered = targetKey.toLowerCase();
|
||||
const lowered = normalizeLowercaseStringOrEmpty(targetKey);
|
||||
const matches: string[] = [];
|
||||
for (const key of Object.keys(store)) {
|
||||
if (key.toLowerCase() === lowered) {
|
||||
if (normalizeLowercaseStringOrEmpty(key) === lowered) {
|
||||
matches.push(key);
|
||||
}
|
||||
}
|
||||
@@ -612,7 +613,7 @@ function normalizeFallbackList(values: readonly string[]): string[] {
|
||||
if (!trimmed) {
|
||||
continue;
|
||||
}
|
||||
const key = trimmed.toLowerCase();
|
||||
const key = normalizeLowercaseStringOrEmpty(trimmed);
|
||||
if (seen.has(key)) {
|
||||
continue;
|
||||
}
|
||||
@@ -701,7 +702,7 @@ export function listAgentsForGateway(cfg: OpenClawConfig): {
|
||||
}
|
||||
|
||||
function canonicalizeSessionKeyForAgent(agentId: string, key: string): string {
|
||||
const lowered = key.toLowerCase();
|
||||
const lowered = normalizeLowercaseStringOrEmpty(key);
|
||||
if (lowered === "global" || lowered === "unknown") {
|
||||
return lowered;
|
||||
}
|
||||
@@ -723,7 +724,7 @@ export function resolveSessionStoreKey(params: {
|
||||
if (!raw) {
|
||||
return raw;
|
||||
}
|
||||
const rawLower = raw.toLowerCase();
|
||||
const rawLower = normalizeLowercaseStringOrEmpty(raw);
|
||||
if (rawLower === "global" || rawLower === "unknown") {
|
||||
return rawLower;
|
||||
}
|
||||
@@ -731,7 +732,7 @@ export function resolveSessionStoreKey(params: {
|
||||
const parsed = parseAgentSessionKey(raw);
|
||||
if (parsed) {
|
||||
const agentId = normalizeAgentId(parsed.agentId);
|
||||
const lowered = raw.toLowerCase();
|
||||
const lowered = normalizeLowercaseStringOrEmpty(raw);
|
||||
const canonical = canonicalizeMainSessionAlias({
|
||||
cfg: params.cfg,
|
||||
agentId,
|
||||
@@ -743,7 +744,7 @@ export function resolveSessionStoreKey(params: {
|
||||
return lowered;
|
||||
}
|
||||
|
||||
const lowered = raw.toLowerCase();
|
||||
const lowered = normalizeLowercaseStringOrEmpty(raw);
|
||||
const rawMainKey = normalizeMainKey(params.cfg.session?.mainKey);
|
||||
if (lowered === "main" || lowered === rawMainKey) {
|
||||
return resolveMainSessionKey(params.cfg);
|
||||
@@ -772,13 +773,13 @@ export function canonicalizeSpawnedByForAgent(
|
||||
if (!raw) {
|
||||
return undefined;
|
||||
}
|
||||
const lower = raw.toLowerCase();
|
||||
const lower = normalizeLowercaseStringOrEmpty(raw);
|
||||
if (lower === "global" || lower === "unknown") {
|
||||
return lower;
|
||||
}
|
||||
let result: string;
|
||||
if (raw.toLowerCase().startsWith("agent:")) {
|
||||
result = raw.toLowerCase();
|
||||
if (lower.startsWith("agent:")) {
|
||||
result = lower;
|
||||
} else {
|
||||
result = `agent:${normalizeAgentId(agentId)}:${lower}`;
|
||||
}
|
||||
@@ -1077,7 +1078,7 @@ export async function resolveGatewayModelSupportsImages(params: {
|
||||
(entry) =>
|
||||
entry.id === params.model && (!params.provider || entry.provider === params.provider),
|
||||
);
|
||||
const normalizedProvider = normalizeOptionalString(params.provider)?.toLowerCase();
|
||||
const normalizedProvider = normalizeOptionalLowercaseString(params.provider);
|
||||
const normalizedCandidates = [
|
||||
normalizeLowercaseStringOrEmpty(params.model),
|
||||
normalizeLowercaseStringOrEmpty(modelEntry?.name),
|
||||
|
||||
@@ -450,7 +450,7 @@ export function normalizeClawHubSha256Hex(value: string): string | null {
|
||||
if (!/^[A-Fa-f0-9]{64}$/.test(trimmed)) {
|
||||
return null;
|
||||
}
|
||||
return trimmed.toLowerCase();
|
||||
return normalizeLowercaseStringOrEmpty(trimmed);
|
||||
}
|
||||
|
||||
export function parseClawHubPluginSpec(raw: string): {
|
||||
|
||||
@@ -220,7 +220,7 @@ export function parseExecApprovalCommandText(
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
const rawDecision = match[2].toLowerCase();
|
||||
const rawDecision = normalizeOptionalLowercaseString(match[2]) ?? "";
|
||||
return {
|
||||
approvalId: match[1],
|
||||
decision:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import path from "node:path";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString,
|
||||
} from "../shared/string-coerce.js";
|
||||
import { isDispatchWrapperExecutable } from "./dispatch-wrapper-resolution.js";
|
||||
@@ -81,7 +82,7 @@ export function isSafeBinUsage(params: {
|
||||
return false;
|
||||
}
|
||||
const resolution = params.resolution;
|
||||
const execName = resolution?.executableName?.toLowerCase();
|
||||
const execName = normalizeOptionalLowercaseString(resolution?.executableName);
|
||||
if (!execName) {
|
||||
return false;
|
||||
}
|
||||
@@ -153,7 +154,7 @@ function pickExecAllowlistContext(params: ExecAllowlistContext): ExecAllowlistCo
|
||||
}
|
||||
|
||||
function normalizeSkillBinName(value: string | undefined): string | null {
|
||||
const trimmed = normalizeOptionalString(value)?.toLowerCase();
|
||||
const trimmed = normalizeOptionalLowercaseString(value);
|
||||
return trimmed && trimmed.length > 0 ? trimmed : null;
|
||||
}
|
||||
|
||||
@@ -164,7 +165,7 @@ function normalizeSkillBinResolvedPath(value: string | undefined): string | null
|
||||
}
|
||||
const resolved = path.resolve(trimmed);
|
||||
if (process.platform === "win32") {
|
||||
return resolved.replace(/\\/g, "/").toLowerCase();
|
||||
return normalizeLowercaseStringOrEmpty(resolved.replace(/\\/g, "/"));
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
@@ -224,7 +225,7 @@ function resolveSkillPreludePath(rawPath: string, cwd?: string): string {
|
||||
|
||||
function isSkillMarkdownPreludePath(filePath: string): boolean {
|
||||
const normalized = filePath.replace(/\\/g, "/");
|
||||
const lowerNormalized = normalized.toLowerCase();
|
||||
const lowerNormalized = normalizeLowercaseStringOrEmpty(normalized);
|
||||
if (!lowerNormalized.endsWith("/skill.md")) {
|
||||
return false;
|
||||
}
|
||||
@@ -246,7 +247,7 @@ function isSkillMarkdownPreludePath(filePath: string): boolean {
|
||||
|
||||
function resolveSkillMarkdownPreludeId(filePath: string): string | null {
|
||||
const normalized = filePath.replace(/\\/g, "/");
|
||||
const lowerNormalized = normalized.toLowerCase();
|
||||
const lowerNormalized = normalizeLowercaseStringOrEmpty(normalized);
|
||||
if (!lowerNormalized.endsWith("/skill.md")) {
|
||||
return null;
|
||||
}
|
||||
@@ -269,7 +270,7 @@ function resolveSkillMarkdownPreludeId(filePath: string): string | null {
|
||||
|
||||
function isSkillPreludeReadSegment(segment: ExecCommandSegment, cwd?: string): boolean {
|
||||
const execution = resolveExecutionTargetResolution(segment.resolution);
|
||||
if (execution?.executableName?.toLowerCase() !== "cat") {
|
||||
if (normalizeLowercaseStringOrEmpty(execution?.executableName) !== "cat") {
|
||||
return false;
|
||||
}
|
||||
// Keep the display-prelude exception narrow: only a plain `cat <...>/SKILL.md`
|
||||
@@ -286,7 +287,7 @@ function isSkillPreludeReadSegment(segment: ExecCommandSegment, cwd?: string): b
|
||||
|
||||
function isSkillPreludeMarkerSegment(segment: ExecCommandSegment): boolean {
|
||||
const execution = resolveExecutionTargetResolution(segment.resolution);
|
||||
if (execution?.executableName?.toLowerCase() !== "printf") {
|
||||
if (normalizeLowercaseStringOrEmpty(execution?.executableName) !== "printf") {
|
||||
return false;
|
||||
}
|
||||
if (segment.argv.length !== 2) {
|
||||
@@ -389,14 +390,18 @@ function resolveShellWrapperScriptArgv(params: {
|
||||
effectiveArgv: string[];
|
||||
cwd?: string;
|
||||
}): string[] {
|
||||
const scriptBase = path.basename(params.shellScriptCandidatePath).toLowerCase();
|
||||
const scriptBase = normalizeLowercaseStringOrEmpty(
|
||||
path.basename(params.shellScriptCandidatePath),
|
||||
);
|
||||
const cwdBase = params.cwd && params.cwd.trim() ? params.cwd.trim() : process.cwd();
|
||||
const resolveArgPath = (a: string): string => (path.isAbsolute(a) ? a : path.resolve(cwdBase, a));
|
||||
let idx = params.effectiveArgv.findIndex(
|
||||
(a) => resolveArgPath(a) === params.shellScriptCandidatePath,
|
||||
);
|
||||
if (idx === -1) {
|
||||
idx = params.effectiveArgv.findIndex((a) => path.basename(a).toLowerCase() === scriptBase);
|
||||
idx = params.effectiveArgv.findIndex(
|
||||
(a) => normalizeLowercaseStringOrEmpty(path.basename(a)) === scriptBase,
|
||||
);
|
||||
}
|
||||
const scriptArgs = idx !== -1 ? params.effectiveArgv.slice(idx + 1) : [];
|
||||
return [params.shellScriptCandidatePath, ...scriptArgs];
|
||||
@@ -883,13 +888,15 @@ function buildScriptArgPatternFromArgv(
|
||||
if (!isWindowsPlatform(platform ?? process.platform)) {
|
||||
return undefined;
|
||||
}
|
||||
const scriptBase = path.basename(scriptPath).toLowerCase();
|
||||
const scriptBase = normalizeLowercaseStringOrEmpty(path.basename(scriptPath));
|
||||
const base = cwd && cwd.trim() ? cwd.trim() : process.cwd();
|
||||
const resolveArgPath = (arg: string): string =>
|
||||
path.isAbsolute(arg) ? arg : path.resolve(base, arg);
|
||||
let scriptIdx = argv.findIndex((arg) => resolveArgPath(arg) === scriptPath);
|
||||
if (scriptIdx === -1) {
|
||||
scriptIdx = argv.findIndex((arg) => path.basename(arg).toLowerCase() === scriptBase);
|
||||
scriptIdx = argv.findIndex(
|
||||
(arg) => normalizeLowercaseStringOrEmpty(path.basename(arg)) === scriptBase,
|
||||
);
|
||||
}
|
||||
const scriptArgs = scriptIdx !== -1 ? argv.slice(scriptIdx + 1) : [];
|
||||
const normalized = scriptArgs.map((a) => a.replace(/\//g, "\\"));
|
||||
|
||||
@@ -103,13 +103,16 @@ function hasSqliteSignal(err: unknown): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
const name = readErrorName(err);
|
||||
if (name.toLowerCase().includes("sqlite")) {
|
||||
const name = normalizeLowercaseStringOrEmpty(readErrorName(err));
|
||||
if (name.includes("sqlite")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const message = "message" in err && typeof err.message === "string" ? err.message : "";
|
||||
if (message.toLowerCase().includes("sqlite")) {
|
||||
const message =
|
||||
"message" in err && typeof err.message === "string"
|
||||
? normalizeLowercaseStringOrEmpty(err.message)
|
||||
: "";
|
||||
if (message.includes("sqlite")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
import { CONFIG_DIR, ensureDir } from "../utils.js";
|
||||
|
||||
export function normalizeWideAreaDomain(raw?: string | null): string | null {
|
||||
@@ -29,9 +30,7 @@ export function getWideAreaZonePath(domain: string): string {
|
||||
}
|
||||
|
||||
function dnsLabel(raw: string, fallback: string): string {
|
||||
const normalized = raw
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
const normalized = normalizeLowercaseStringOrEmpty(raw)
|
||||
.replace(/[^a-z0-9-]+/g, "-")
|
||||
.replace(/^-+/, "")
|
||||
.replace(/-+$/, "");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { execFileSync } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
|
||||
const DEFAULT_SYSTEM_ROOT = "C:\\Windows";
|
||||
const DEFAULT_PROGRAM_FILES = "C:\\Program Files";
|
||||
@@ -102,7 +103,7 @@ function getWindowsRegExeCandidates(env: Record<string, string | undefined>): re
|
||||
if (!root) {
|
||||
continue;
|
||||
}
|
||||
const key = root.toLowerCase();
|
||||
const key = normalizeLowercaseStringOrEmpty(root);
|
||||
if (seen.has(key)) {
|
||||
continue;
|
||||
}
|
||||
@@ -239,7 +240,7 @@ export function getWindowsProgramFilesRoots(
|
||||
if (!value) {
|
||||
continue;
|
||||
}
|
||||
const key = value.toLowerCase();
|
||||
const key = normalizeLowercaseStringOrEmpty(value);
|
||||
if (seen.has(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user