UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

113 lines (112 loc) 6.06 kB
import "./fs-safe-defaults-DGE52WTl.js"; import path from "node:path"; import fs from "node:fs/promises"; import { appendRegularFile, appendRegularFileSync, assertAbsolutePathInput, assertNoSymlinkParents, assertNoSymlinkParentsSync, canonicalPathFromExistingAncestor as canonicalPathFromExistingAncestor$1, ensureDirectoryWithinRoot, findExistingAncestor, findExistingAncestor as findExistingAncestor$1, movePathToTrash, pathExists, pathExistsSync, readFileHandleBounded, readLocalFileFromRoots, readRegularFile, readRegularFileSync, resolveAbsolutePathForRead, resolveAbsolutePathForWrite, resolveLocalPathFromRootsSync, resolveRegularFileAppendFlags, sameFileIdentity, sanitizeUntrustedFileName, statRegularFile, statRegularFileSync, tempFile, withTempFile, withTimeout } from "@openclaw/fs-safe/advanced"; import { FsSafeError, FsSafeError as FsSafeError$1 } from "@openclaw/fs-safe/errors"; import { isPathInside } from "@openclaw/fs-safe/path"; import { writeExternalFileWithinRoot } from "@openclaw/fs-safe/output"; import { openLocalFileSafely, readLocalFileSafely, resolveOpenedFileRealPathForHandle, root } from "@openclaw/fs-safe/root"; import { readSecretFile } from "@openclaw/fs-safe/secret"; import { readSecureFile } from "@openclaw/fs-safe/secure-file"; import { walkDirectory, walkDirectorySync } from "@openclaw/fs-safe/walk"; //#region src/infra/owned-temp-file.ts async function inspectDirectory(dir) { const stat = await fs.lstat(dir, { bigint: true }); if (!stat.isDirectory() || stat.isSymbolicLink() || process.platform === "win32" && (stat.dev === 0n || stat.ino === 0n)) throw new FsSafeError("path-mismatch", "temporary output directory identity is unavailable"); return { dev: stat.dev, ino: stat.ino, realPath: await fs.realpath(dir) }; } async function guardDirectory(dir) { const expected = await inspectDirectory(dir); return async () => { const current = await inspectDirectory(dir); if (current.dev !== expected.dev || current.ino !== expected.ino || current.realPath !== expected.realPath) throw new FsSafeError("path-mismatch", "temporary output directory changed during write"); }; } async function writeOwnedTempFile(tempPath, write) { const parent = path.dirname(tempPath); const assertParent = await guardDirectory(parent); const targetRoot = await root(parent); return await withTempFile({ rootDir: targetRoot.rootReal, prefix: "openclaw-output", fileName: path.basename(tempPath) }, async (filePath) => { const assertWorkspace = await guardDirectory(path.dirname(filePath)); const result = await write(filePath); await assertWorkspace(); await assertParent(); await targetRoot.move(path.relative(targetRoot.rootReal, filePath), path.basename(tempPath)); return result; }); } //#endregion //#region src/infra/fs-safe.ts async function root$1(rootDir, defaults) { return await root(rootDir, defaults); } async function ensureAbsoluteDirectory(dirPath, options) { const absolutePath = path.resolve(dirPath); const scopeLabel = options?.scopeLabel ?? "directory"; const existingAncestor = await findExistingAncestor(absolutePath); if (!existingAncestor) return { ok: false, error: /* @__PURE__ */ new Error(`Invalid path: must stay within ${scopeLabel}`) }; if (existingAncestor === absolutePath) { try { const stat = await fs.lstat(absolutePath); if (!stat.isSymbolicLink() && stat.isDirectory()) return { ok: true, path: absolutePath }; } catch {} return { ok: false, error: /* @__PURE__ */ new Error(`Invalid path: must stay within ${scopeLabel}`) }; } const result = await ensureDirectoryWithinRoot({ rootDir: existingAncestor, requestedPath: path.relative(existingAncestor, absolutePath), scopeLabel, mode: options?.mode }); if (result.ok) return result; return { ok: false, error: new Error(result.error) }; } async function writeExternalFileWithinRoot$1(options) { const requestedPath = path.resolve(options.rootDir, options.path); const result = await writeExternalFileWithinRoot({ rootDir: options.rootDir, path: options.path, write: (tempPath) => writeOwnedTempFile(tempPath, options.write), staging: "sibling", fallbackFileName: options.fallbackFileName ?? options.tempPrefix }); return { path: path.join(path.dirname(requestedPath), path.basename(result.path)) }; } /** @deprecated Use root(rootDir).read(relativePath, options). */ async function readFileWithinRoot(params) { return await (await root(params.rootDir)).read(params.relativePath, { hardlinks: params.rejectHardlinks === false ? "allow" : "reject", maxBytes: params.maxBytes, nonBlockingRead: params.nonBlockingRead, symlinks: params.allowSymlinkTargetWithinRoot === true ? "follow-within-root" : "reject" }); } /** @deprecated Use root(rootDir).write(relativePath, data, options). */ async function writeFileWithinRoot(params) { await (await root(params.rootDir)).write(params.relativePath, params.data, { encoding: params.encoding, mkdir: params.mkdir }); } //#endregion export { writeExternalFileWithinRoot$1 as A, resolveRegularFileAppendFlags as C, walkDirectory as D, statRegularFileSync as E, readSecretFile as F, sameFileIdentity as I, sanitizeUntrustedFileName as L, assertNoSymlinkParents as M, assertNoSymlinkParentsSync as N, walkDirectorySync as O, readFileHandleBounded as P, tempFile as R, resolveOpenedFileRealPathForHandle as S, statRegularFile as T, readRegularFileSync as _, canonicalPathFromExistingAncestor$1 as a, resolveAbsolutePathForWrite as b, isPathInside as c, pathExists as d, pathExistsSync as f, readRegularFile as g, readLocalFileSafely as h, assertAbsolutePathInput as i, writeFileWithinRoot as j, withTimeout as k, movePathToTrash as l, readLocalFileFromRoots as m, appendRegularFile as n, ensureAbsoluteDirectory as o, readFileWithinRoot as p, appendRegularFileSync as r, findExistingAncestor$1 as s, FsSafeError$1 as t, openLocalFileSafely as u, readSecureFile as v, root$1 as w, resolveLocalPathFromRootsSync as x, resolveAbsolutePathForRead as y, writeOwnedTempFile as z };