57 lines
1.6 KiB
TypeScript

import * as Sentry from "@sentry/nextjs";
import { NextResponse } from "next/server";
import { requireClient, unauthorizedJson, UnauthorizedError } from "@/lib/nextcloud-session";
import { normalizePath } from "@/lib/paths";
export const runtime = "nodejs";
export const dynamic = "force-dynamic";
function json<T>(data: T, init?: { status?: number } & ResponseInit) {
return NextResponse.json(data, init);
}
export async function POST(req: Request) {
try {
const body = (await req.json().catch(() => ({}))) as {
from?: string;
to?: string;
};
if (!body?.from || !body?.to) {
return json({ error: "from and to are required" }, { status: 400 });
}
const from = normalizePath(body.from);
const to = normalizePath(body.to);
let client;
try {
client = await requireClient(req);
} catch (err) {
if (err instanceof UnauthorizedError) return unauthorizedJson();
throw err;
}
const result = await Sentry.startSpan(
{ op: "function", name: "api.files.copy" },
async (span) => {
span.setAttribute("path_from", from);
span.setAttribute("path_to", to);
const res = await client.copyFile(from, to);
return res;
},
);
return json(result);
} catch (error: unknown) {
Sentry.captureException(error);
const message = error instanceof Error ? error.message : String(error);
const status = /409|conflict/i.test(message)
? 409
: /423|locked/i.test(message)
? 423
: 500;
return json({ error: "Failed to copy file", message }, { status });
}
}