60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
import { eq, desc, and } from 'drizzle-orm';
|
|
import { db } from '@/db';
|
|
import { recipes } from '@/db/schema';
|
|
import type { Recipe, SavedRecipe } from './recipe';
|
|
import { ApiError } from './server';
|
|
export function serialize(row: typeof recipes.$inferSelect): SavedRecipe {
|
|
return {
|
|
...row.data,
|
|
steps: row.data.steps.map((step) => ({ ...step, images: step.images ?? [] })),
|
|
id: row.id,
|
|
title: row.title,
|
|
published: row.published,
|
|
createdAt: row.createdAt.toISOString(),
|
|
updatedAt: row.updatedAt.toISOString(),
|
|
};
|
|
}
|
|
export async function listRecipes(isAdmin = false) {
|
|
return (
|
|
await db
|
|
.select()
|
|
.from(recipes)
|
|
.where(isAdmin ? undefined : eq(recipes.published, true))
|
|
.orderBy(desc(recipes.createdAt))
|
|
).map(serialize);
|
|
}
|
|
export async function getRecipe(id: string, isAdmin = false) {
|
|
if (!/^[0-9a-f-]{36}$/i.test(id)) return null;
|
|
const [row] = await db
|
|
.select()
|
|
.from(recipes)
|
|
.where(and(eq(recipes.id, id), isAdmin ? undefined : eq(recipes.published, true)));
|
|
return row ? serialize(row) : null;
|
|
}
|
|
export const titleKey = (title: string) => title.normalize('NFKC').trim().toLocaleLowerCase('de');
|
|
export async function saveRecipe(data: Recipe, id?: string, expected?: string) {
|
|
const values = {
|
|
title: data.title,
|
|
titleKey: titleKey(data.title),
|
|
published: data.published,
|
|
data,
|
|
updatedAt: new Date(),
|
|
};
|
|
if (id) {
|
|
if (!expected) throw new ApiError(428, 'Versionsstand zum Speichern fehlt.');
|
|
const [row] = await db
|
|
.update(recipes)
|
|
.set(values)
|
|
.where(and(eq(recipes.id, id), eq(recipes.updatedAt, new Date(expected))))
|
|
.returning();
|
|
if (!row)
|
|
throw new ApiError(
|
|
409,
|
|
'Das Rezept wurde zwischenzeitlich verändert. Entwurf sichern und Seite neu laden.',
|
|
);
|
|
return serialize(row);
|
|
}
|
|
const [row] = await db.insert(recipes).values(values).returning();
|
|
return serialize(row);
|
|
}
|