UNPKG

morphbox

Version:

Docker-based AI sandbox for development with Claude integration

198 lines (195 loc) 5.89 kB
import { e as error, j as json } from './index-3BbzJtgI.js'; import { promises } from 'fs'; import path from 'path'; import { W as WORKSPACE_DIR } from './workspace-CcQOwpY7.js'; import 'child_process'; import 'util'; function validatePath(requestPath) { const normalized = path.normalize(path.join(WORKSPACE_DIR, requestPath)); if (!normalized.startsWith(WORKSPACE_DIR)) { throw error(403, "Access denied: Path outside workspace directory"); } return normalized; } const GET = async ({ url }) => { try { const requestPath = url.searchParams.get("path") || "/"; const fullPath = validatePath(requestPath); const stats = await promises.stat(fullPath); if (!stats.isDirectory()) { throw error(400, "Path is not a directory"); } const items = await promises.readdir(fullPath, { withFileTypes: true }); const contents = await Promise.all( items.map(async (item) => { const itemPath = path.join(fullPath, item.name); const itemStats = await promises.stat(itemPath); return { name: item.name, type: item.isDirectory() ? "directory" : "file", path: path.relative(WORKSPACE_DIR, itemPath), size: itemStats.size, modified: itemStats.mtime.toISOString(), created: itemStats.birthtime.toISOString() }; }) ); return json({ path: path.relative(WORKSPACE_DIR, fullPath), contents: contents.sort((a, b) => { if (a.type !== b.type) { return a.type === "directory" ? -1 : 1; } return a.name.localeCompare(b.name); }) }); } catch (err) { if (err instanceof Response) throw err; if (err.code === "ENOENT") { throw error(404, "Directory not found"); } console.error("Error listing directory:", err); throw error(500, "Failed to list directory"); } }; const POST = async ({ request, url }) => { try { const operation = url.searchParams.get("operation"); const body = await request.json(); switch (operation) { case "read": return await handleRead(body); case "write": return await handleWrite(body); case "create": return await handleCreate(body); case "rename": return await handleRename(body); default: throw error(400, "Invalid operation"); } } catch (err) { if (err instanceof Response) throw err; console.error("Error in file operation:", err); throw error(500, "File operation failed"); } }; const DELETE = async ({ request }) => { try { const { path: filePath } = await request.json(); if (!filePath) { throw error(400, "Path is required"); } const fullPath = validatePath(filePath); const stats = await promises.stat(fullPath); if (stats.isDirectory()) { await promises.rmdir(fullPath, { recursive: true }); } else { await promises.unlink(fullPath); } return json({ success: true, message: "File deleted successfully", path: filePath }); } catch (err) { if (err instanceof Response) throw err; if (err.code === "ENOENT") { throw error(404, "File not found"); } console.error("Error deleting file:", err); throw error(500, "Failed to delete file"); } }; async function handleRead(body) { const { path: filePath } = body; if (!filePath) { throw error(400, "Path is required"); } const fullPath = validatePath(filePath); const stats = await promises.stat(fullPath); if (stats.isDirectory()) { throw error(400, "Path is a directory, not a file"); } const content = await promises.readFile(fullPath, "utf-8"); return json({ path: filePath, content, size: stats.size, modified: stats.mtime.toISOString() }); } async function handleWrite(body) { const { path: filePath, content } = body; if (!filePath) { throw error(400, "Path is required"); } if (content === void 0) { throw error(400, "Content is required"); } const fullPath = validatePath(filePath); const dir = path.dirname(fullPath); await promises.mkdir(dir, { recursive: true }); await promises.writeFile(fullPath, content, "utf-8"); const stats = await promises.stat(fullPath); return json({ success: true, path: filePath, size: stats.size, modified: stats.mtime.toISOString() }); } async function handleCreate(body) { const { path: filePath, type = "file", content = "" } = body; if (!filePath) { throw error(400, "Path is required"); } const fullPath = validatePath(filePath); try { await promises.access(fullPath); throw error(409, `${type === "directory" ? "Directory" : "File"} already exists`); } catch (err) { if (err.code !== "ENOENT") { throw err; } } if (type === "directory") { await promises.mkdir(fullPath, { recursive: true }); } else { const dir = path.dirname(fullPath); await promises.mkdir(dir, { recursive: true }); await promises.writeFile(fullPath, content, "utf-8"); } return json({ success: true, path: filePath, type }); } async function handleRename(body) { const { oldPath, newPath } = body; if (!oldPath || !newPath) { throw error(400, "Both oldPath and newPath are required"); } const fullOldPath = validatePath(oldPath); const fullNewPath = validatePath(newPath); await promises.access(fullOldPath); try { await promises.access(fullNewPath); throw error(409, "Destination already exists"); } catch (err) { if (err.code !== "ENOENT") { throw err; } } const destDir = path.dirname(fullNewPath); await promises.mkdir(destDir, { recursive: true }); await promises.rename(fullOldPath, fullNewPath); return json({ success: true, oldPath, newPath }); } export { DELETE, GET, POST }; //# sourceMappingURL=_server.ts-T3xWBEB9.js.map