UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

71 lines (70 loc) 3.58 kB
import "./fs-safe-defaults-DGE52WTl.js"; import path from "node:path"; import { canUseRootFileOpen, canonicalPathFromExistingAncestor, matchRootFileOpenFailure, matchRootFileOpenFailure as matchRootFileOpenFailure$1, openRootFile, openRootFile as openRootFile$1, openRootFileSync, readFileDescriptorBounded, readFileDescriptorBoundedSync } from "@openclaw/fs-safe/advanced"; import { FsSafeError } from "@openclaw/fs-safe/errors"; //#region src/infra/boundary-file-read.ts /** * Opens a root-scoped file after canonicalizing symlink parents. fs-safe * rejects every symlink path component by default; the workspace contract * follows contained parent symlinks (directory aliases) while final-symlink * targets and out-of-root escapes stay rejected by openRootFile itself. */ async function openRootFileFollowingParents(params) { let absolutePath = path.resolve(params.absolutePath); try { const canonicalParent = await canonicalPathFromExistingAncestor(path.dirname(absolutePath)); absolutePath = path.join(canonicalParent, path.basename(absolutePath)); } catch {} return await openRootFile({ ...params, absolutePath }); } const MISSING_PATH_ERROR_CODES = /* @__PURE__ */ new Set(["ENOENT", "ENOTDIR"]); function readFailureErrorCode(error) { const code = error && typeof error === "object" ? error.code : void 0; return typeof code === "string" && code ? code : void 0; } function isRootFileMissingFailure(failure) { return failure.reason === "path" && MISSING_PATH_ERROR_CODES.has(readFailureErrorCode(failure.error) ?? ""); } /** * Describes a root-scoped open failure without collapsing every cause into a * containment violation. Only `validation` means the path failed the boundary or * alias check; a missing artifact or an unreadable descriptor is an ordinary * operational state, and reporting those as escapes sends operators hunting a * security incident that never happened. */ function describeRootFileOpenFailure(params) { const unreadable = (code) => `${params.subject} could not be read${code ? ` (${code})` : ""}: ${params.filePath}`; return matchRootFileOpenFailure(params.failure, { path: (failure) => { const code = readFailureErrorCode(failure.error); return isRootFileMissingFailure(failure) ? `${params.subject} not found: ${params.filePath}` : unreadable(code); }, validation: () => `${params.subject} escapes ${params.boundaryLabel} or fails alias checks: ${params.filePath}`, fallback: (failure) => unreadable(readFailureErrorCode(failure.error)) }); } function preserveOpenClawOverflowError(error, maxBytes) { if (error instanceof FsSafeError && error.code === "too-large") throw new RangeError(`File exceeds ${maxBytes} bytes`, { cause: error }); throw error; } /** Read a pinned descriptor without changing OpenClaw's user-facing overflow error. */ async function readFileDescriptorBounded$1(fd, maxBytes) { try { return await readFileDescriptorBounded(fd, maxBytes); } catch (error) { return preserveOpenClawOverflowError(error, maxBytes); } } /** Synchronous variant for callers that own a pinned descriptor. */ function readFileDescriptorBoundedSync$1(fd, maxBytes) { try { return readFileDescriptorBoundedSync(fd, maxBytes); } catch (error) { return preserveOpenClawOverflowError(error, maxBytes); } } //#endregion export { openRootFile$1 as a, readFileDescriptorBounded$1 as c, matchRootFileOpenFailure$1 as i, readFileDescriptorBoundedSync$1 as l, describeRootFileOpenFailure as n, openRootFileFollowingParents as o, isRootFileMissingFailure as r, openRootFileSync as s, canUseRootFileOpen as t };