UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

72 lines (71 loc) 2.55 kB
import { m as FsSafeError } from "./path-BlG8lhgR.js"; import { k as resolveAbsolutePathForRead } from "./fs-safe-aqmM_n6V.js"; import "./security-runtime-CQm7DD1u.js"; import path from "node:path"; import fs from "node:fs/promises"; //#region extensions/file-transfer/src/node-host/path-errors.ts const SYMLINK_REJECTED_MESSAGE = "path traverses a symlink; refusing because followSymlinks=false (set plugins.entries.file-transfer.config.nodes.<node>.followSymlinks=true to allow, or update allowReadPaths to the canonical path)"; function classifyFsSafeReadError(err) { if (!(err instanceof FsSafeError)) return; if (err.code === "not-found") return "NOT_FOUND"; if (err.code === "symlink") return "SYMLINK_REDIRECT"; if (err.code === "invalid-path") return "INVALID_PATH"; } function readAbsolutePath(input) { if (typeof input !== "string" || input.length === 0) return { ok: false, code: "INVALID_PATH", message: "path required" }; if (input.includes("\0")) return { ok: false, code: "INVALID_PATH", message: "path contains NUL byte" }; if (!path.isAbsolute(input)) return { ok: false, code: "INVALID_PATH", message: "path must be absolute" }; return input; } function canonicalPathFromFsSafeError(err) { if (!(err instanceof FsSafeError) || !err.cause || typeof err.cause !== "object") return; return "canonicalPath" in err.cause && typeof err.cause.canonicalPath === "string" ? err.cause.canonicalPath : void 0; } async function resolveCanonicalReadPath(input) { try { return (await resolveAbsolutePathForRead(input.requestedPath, { symlinks: input.followSymlinks ? "follow" : "reject" })).canonicalPath; } catch (err) { const code = input.classifyError(err); const canonicalPath = canonicalPathFromFsSafeError(err); return { ok: false, code, message: code === "NOT_FOUND" ? input.notFoundMessage : code === "SYMLINK_REDIRECT" ? SYMLINK_REJECTED_MESSAGE : `realpath failed: ${String(err)}`, ...canonicalPath ? { canonicalPath } : {} }; } } async function statRequiredDirectory(canonicalPath, classifyError) { let stats; try { stats = await fs.stat(canonicalPath); } catch (err) { return { ok: false, code: classifyError(err), message: `stat failed: ${String(err)}`, canonicalPath }; } if (!stats.isDirectory()) return { ok: false, code: "IS_FILE", message: "path is not a directory", canonicalPath }; return { ok: true }; } //#endregion export { statRequiredDirectory as i, readAbsolutePath as n, resolveCanonicalReadPath as r, classifyFsSafeReadError as t };