obsidian-visualiser/server/api/project.post.ts

76 lines
2.5 KiB
TypeScript

import { hasPermissions } from "#shared/auth.util";
import useDatabase from '~/composables/useDatabase';
import { explorerContentTable } from '~/db/schema';
import { project, type ProjectItem } from '~/schemas/project';
import { parsePath } from "#shared/general.utils";
import { eq, getTableColumns } from "drizzle-orm";
export default defineEventHandler(async (e) => {
const { user } = await getUserSession(e);
if(!user || !hasPermissions(user.permissions, ['admin', 'editor']))
{
throw createError({ statusCode: 401, statusText: 'Unauthorized' });
}
const body = await readValidatedBody(e, project.safeParse);
if(!body.success)
{
throw body.error;
}
const items = buildOrder(body.data.items);
const db = useDatabase();
const { content, ...cols } = getTableColumns(explorerContentTable);
const full = db.select(cols).from(explorerContentTable).all();
for(let i = full.length - 1; i >= 0; i--)
{
if(items.find(e => (e.path === '' ? [e.parent, parsePath(e.name === '' ? e.title : e.name)].filter(e => !!e).join('/') : e.path) === full[i].path))
full.splice(i, 1);
}
db.transaction((tx) => {
for(let i = 0; i < items.length; i++)
{
const item = items[i];
tx.insert(explorerContentTable).values({
path: item.path,
owner: user.id,
title: item.title,
type: item.type,
navigable: item.navigable,
private: item.private,
order: item.order,
content: null,
}).onConflictDoUpdate({
set: {
path: [item.parent, parsePath(item.name === '' ? item.title : item.name)].filter(e => !!e).join('/'),
title: item.title,
type: item.type,
navigable: item.navigable,
private: item.private,
order: item.order,
},
target: explorerContentTable.path,
}).run();
}
for(let i = 0; i < full.length; i++)
{
tx.delete(explorerContentTable).where(eq(explorerContentTable.path, full[i].path)).run();
}
});
});
function buildOrder(items: ProjectItem[]): ProjectItem[]
{
items.forEach((e, i) => {
e.order = i;
if(e.children) e.children = buildOrder(e.children);
});
return items.flatMap(e => [e, ...(e.children ?? [])]);
}