124_webcalibre2/src/app/dashboard/sync-actions.ts

62 lines
2 KiB
TypeScript
Raw Normal View History

'use server';
import { auth } from "@/auth";
import { prisma } from "@/lib/prisma";
import { revalidatePath } from "next/cache";
import { getFreshAccessToken } from "@/lib/auth-utils";
export async function syncOneDrive() {
const session = await auth();
if (!session?.user?.id) throw new Error("Unauthorized");
try {
const accessToken = await getFreshAccessToken(session.user.id);
const response = await fetch("https://graph.microsoft.com/v1.0/me/drive/root:/WebCalibre:/children", {
headers: { Authorization: `Bearer ${accessToken}` },
});
if (!response.ok) return { success: true, count: 0 };
const data = await response.json();
let syncedCount = 0;
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
for (const item of data.value) {
const isFolder = !!item.folder;
// Only skip if it's a folder AND it's a UUID (storage container)
// If a user named a file with a UUID, we still want it.
if (isFolder && uuidRegex.test(item.name)) {
continue;
}
const extension = isFolder ? 'FOLDER' : (item.name.split('.').pop()?.toUpperCase() || 'UNKNOWN');
await prisma.fileNode.upsert({
where: { oneDriveId: item.id }, // Primary match
update: {
name: item.name,
size: BigInt(item.size || 0),
isFolder: isFolder,
path: item.parentReference?.path + '/' + item.name,
updatedAt: new Date(),
},
create: {
id: crypto.randomUUID(),
oneDriveId: item.id,
name: item.name,
size: BigInt(item.size || 0),
isFolder: isFolder,
path: item.parentReference?.path + '/' + item.name,
ownerId: session.user.id,
metadata: { type: extension, mimeType: item.file?.mimeType || null },
}
});
syncedCount++;
}
revalidatePath('/dashboard');
return { success: true, count: syncedCount };
} catch (error: any) {
throw new Error(error.message);
}
}