UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

96 lines (95 loc) 3.8 kB
import "./fs-safe-defaults-DGE52WTl.js"; import { r as isMissingPathError } from "./errno-CkbDOfLk.js"; import path from "node:path"; import { FsSafeError } from "@openclaw/fs-safe/errors"; import { root } from "@openclaw/fs-safe/root"; //#region src/infra/fs-safe-remove.ts async function listDirectoryEntries(root, relativePath) { return await root.list(relativePath, { withFileTypes: true }); } function compareDirectoryEntryNames(left, right) { if (left.name === right.name) return 0; return left.name < right.name ? -1 : 1; } function isNotFoundError(error) { return isMissingPathError(error) || isMissingPathError(findPathAliasFilesystemCause(error)); } function findPathAliasFilesystemCause(error) { if (error?.code !== "path-alias") return; const cause = error.cause; const causeCode = cause?.code; return typeof causeCode === "string" && /^E[A-Z0-9_]+$/u.test(causeCode) ? cause : void 0; } function relativeParentPath(relativePath) { const parentPath = path.dirname(relativePath); return parentPath === "." ? "" : parentPath; } function joinRootRelativePath(parentRelativePath, childName) { return parentRelativePath.length === 0 ? childName : path.join(parentRelativePath, childName); } async function findDirectoryEntry(root, relativePath) { const targetName = path.basename(relativePath); if (targetName.length === 0 || targetName === ".") return; return (await listDirectoryEntries(root, relativeParentPath(relativePath))).find((entry) => entry.name === targetName); } async function removeRootRelativePath(root, relativePath, suppressNotFound) { try { await root.remove(relativePath); } catch (error) { if (isNotFoundError(error)) { if (suppressNotFound) return; throw new FsSafeError("not-found", "file not found", { cause: error instanceof Error ? error : void 0 }); } const filesystemCause = findPathAliasFilesystemCause(error); if (filesystemCause) throw filesystemCause; throw error; } } function assertNotSymbolicLink(relativePath, entry) { if (!entry.isSymbolicLink) return; throw new FsSafeError("symlink", `symlink not allowed: ${relativePath}`); } async function removeDirectoryEntry(root, relativePath, suppressNotFound) { const entry = await findDirectoryEntry(root, relativePath).catch((error) => { if (suppressNotFound && isNotFoundError(error)) return; throw error; }); if (!entry) { await removeRootRelativePath(root, relativePath, suppressNotFound); return; } assertNotSymbolicLink(relativePath, entry); if (entry.isDirectory) { const children = (await listDirectoryEntries(root, relativePath).catch((error) => { if (suppressNotFound && isNotFoundError(error)) return; throw error; }))?.toSorted(compareDirectoryEntryNames); if (!children) { await removeRootRelativePath(root, relativePath, suppressNotFound); return; } for (const child of children) await removeDirectoryEntry(root, joinRootRelativePath(relativePath, child.name), suppressNotFound); } await removeRootRelativePath(root, relativePath, suppressNotFound); } async function removePathWithinRoot(params) { const root$1 = await root(params.rootDir); const suppressNotFound = params.force !== false; const recursive = params.recursive === true; const entry = await findDirectoryEntry(root$1, params.relativePath).catch((error) => { if (suppressNotFound && isNotFoundError(error)) return; throw error; }); if (!entry) { await removeRootRelativePath(root$1, params.relativePath, suppressNotFound); return; } if (!recursive || !entry.isDirectory) { assertNotSymbolicLink(params.relativePath, entry); await removeRootRelativePath(root$1, params.relativePath, suppressNotFound); return; } await removeDirectoryEntry(root$1, params.relativePath, suppressNotFound); } //#endregion export { removePathWithinRoot as t };