mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 01:01:23 +00:00
refactor: centralize isPlainObject, isRecord, isErrno, isLoopbackHost utilities (#12926)
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { isLoopbackHost } from "../gateway/net.js";
|
||||
|
||||
type HostSource = string | null | undefined;
|
||||
|
||||
type CanvasHostUrlParams = {
|
||||
@@ -9,23 +11,6 @@ type CanvasHostUrlParams = {
|
||||
scheme?: "http" | "https";
|
||||
};
|
||||
|
||||
const isLoopbackHost = (value: string) => {
|
||||
const normalized = value.trim().toLowerCase();
|
||||
if (!normalized) {
|
||||
return false;
|
||||
}
|
||||
if (normalized === "localhost") {
|
||||
return true;
|
||||
}
|
||||
if (normalized === "::1") {
|
||||
return true;
|
||||
}
|
||||
if (normalized === "0.0.0.0" || normalized === "::") {
|
||||
return true;
|
||||
}
|
||||
return normalized.startsWith("127.");
|
||||
};
|
||||
|
||||
const normalizeHost = (value: HostSource, rejectLoopback: boolean) => {
|
||||
if (!value) {
|
||||
return "";
|
||||
|
||||
@@ -12,6 +12,20 @@ export function extractErrorCode(err: unknown): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard for NodeJS.ErrnoException (any error with a `code` property).
|
||||
*/
|
||||
export function isErrno(err: unknown): err is NodeJS.ErrnoException {
|
||||
return Boolean(err && typeof err === "object" && "code" in err);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an error has a specific errno code.
|
||||
*/
|
||||
export function hasErrnoCode(err: unknown, code: string): boolean {
|
||||
return isErrno(err) && err.code === code;
|
||||
}
|
||||
|
||||
export function formatErrorMessage(err: unknown): string {
|
||||
if (err instanceof Error) {
|
||||
return err.message || err.name || "Error";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import net from "node:net";
|
||||
import type { PortListener, PortUsage, PortUsageStatus } from "./ports-types.js";
|
||||
import { runCommandWithTimeout } from "../process/exec.js";
|
||||
import { isErrno } from "./errors.js";
|
||||
import { buildPortHints } from "./ports-format.js";
|
||||
import { resolveLsofCommand } from "./ports-lsof.js";
|
||||
|
||||
@@ -11,10 +12,6 @@ type CommandResult = {
|
||||
error?: string;
|
||||
};
|
||||
|
||||
function isErrno(err: unknown): err is NodeJS.ErrnoException {
|
||||
return Boolean(err && typeof err === "object" && "code" in err);
|
||||
}
|
||||
|
||||
async function runCommandSafe(argv: string[], timeoutMs = 5_000): Promise<CommandResult> {
|
||||
try {
|
||||
const res = await runCommandWithTimeout(argv, { timeoutMs });
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { PortListener, PortListenerKind, PortUsage, PortUsageStatus } from
|
||||
import { danger, info, shouldLogVerbose, warn } from "../globals.js";
|
||||
import { logDebug } from "../logger.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
import { isErrno } from "./errors.js";
|
||||
import { formatPortDiagnostics } from "./ports-format.js";
|
||||
import { inspectPortUsage } from "./ports-inspect.js";
|
||||
|
||||
@@ -19,10 +20,6 @@ class PortInUseError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
function isErrno(err: unknown): err is NodeJS.ErrnoException {
|
||||
return Boolean(err && typeof err === "object" && "code" in err);
|
||||
}
|
||||
|
||||
export async function describePortOwner(port: number): Promise<string | undefined> {
|
||||
const diagnostics = await inspectPortUsage(port);
|
||||
if (diagnostics.listeners.length === 0) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ProviderUsageSnapshot, UsageWindow } from "./provider-usage.types.js";
|
||||
import { isRecord } from "../utils.js";
|
||||
import { fetchJson } from "./provider-usage.fetch.shared.js";
|
||||
import { clampPercent, PROVIDER_LABELS } from "./provider-usage.shared.js";
|
||||
|
||||
@@ -148,10 +149,6 @@ const WINDOW_MINUTE_KEYS = [
|
||||
"minutes",
|
||||
] as const;
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
||||
}
|
||||
|
||||
function pickNumber(record: Record<string, unknown>, keys: readonly string[]): number | undefined {
|
||||
for (const key of keys) {
|
||||
const value = record[key];
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { spawn } from "node:child_process";
|
||||
import net from "node:net";
|
||||
import { isErrno } from "./errors.js";
|
||||
import { ensurePortAvailable } from "./ports.js";
|
||||
|
||||
export type SshParsedTarget = {
|
||||
@@ -17,10 +18,6 @@ export type SshTunnel = {
|
||||
stop: () => Promise<void>;
|
||||
};
|
||||
|
||||
function isErrno(err: unknown): err is NodeJS.ErrnoException {
|
||||
return Boolean(err && typeof err === "object" && "code" in err);
|
||||
}
|
||||
|
||||
export function parseSshTarget(raw: string): SshParsedTarget | null {
|
||||
const trimmed = raw.trim().replace(/^ssh\s+/, "");
|
||||
if (!trimmed) {
|
||||
|
||||
Reference in New Issue
Block a user