import { fail, redirect, type ActionFailure } from '@sveltejs/kit'; import { addOrUncheck, loadUnchecked, toggle } from './groceries'; import { add as addCategory } from './categories'; import { numericId, parseFormString, parseOptionalNumber } from './validation'; import { isUniqueViolation } from '$lib/server/db/errors'; export async function toggleGroceryAction(request: Request) { const data = await request.formData(); try { const id = numericId(data.get('id')); await toggle(id); } catch { return fail(400, { error: 'ID invalide' }); } return { success: true }; } export type RowActionResult = ActionFailure<{ error: string }> | { success: boolean; type?: string }; /** Shared 'run fn with the id form field' action for row-based lists. */ export async function idAction( request: Request, fn: (id: number) => Promise, extra?: { type: string }, ): Promise { const data = await request.formData(); try { await fn(numericId(data.get('id'))); } catch { return fail(400, { error: 'ID invalide' }); } return { success: true, type: extra?.type }; } /** Parses the required 'name' field of an add form, or returns the failure. */ function requireFormName( data: FormData, ): string | ActionFailure<{ error: string }> { const name = parseFormString(data.get('name')); if (!name) { return fail(400, { error: 'Le nom est requis' }); } return name; } export async function addCategoryAction(request: Request) { const data = await request.formData(); const name = requireFormName(data); if (typeof name !== 'string') { return name; } try { await addCategory(name); } catch (error) { if (isUniqueViolation(error)) { return fail(400, { error: 'Cette catégorie existe déjà' }); } throw error; } return { success: true }; } export async function addGroceryAction(request: Request) { const data = await request.formData(); const name = requireFormName(data); if (typeof name !== 'string') { return name; } const categoryId = parseOptionalNumber(data.get('category_id')); await addOrUncheck(name, categoryId); const { items } = await loadUnchecked(); return { success: true, items }; } export async function addGroceryAndEditAction(request: Request) { const data = await request.formData(); const name = requireFormName(data); if (typeof name !== 'string') { return name; } const categoryId = parseOptionalNumber(data.get('category_id')); const { item } = await addOrUncheck(name, categoryId); throw redirect(303, `/grocery/${item.id}`); }