"use server"; import { revalidatePath } from "next/cache"; import { db, Database } from "@/app/_lib/database"; import { FieldDescription, Entity } from "@/app/_lib/service"; import crypto from "crypto"; const generateToken = () => { const length = 20; const randomBytes = crypto.randomBytes(length); const randomString = randomBytes.toString("hex").slice(0, length); return randomString; }; type CreateActionArgs = { entity: Entity; table: keyof Database; fields: FieldDescription[]; currentState: any; formData: FormData; }; export const createAction = async ({ entity, table, fields, currentState, formData, }: CreateActionArgs) => { const newRecord = fields.reduce( (acc: Record, field: FieldDescription) => { if (field.autogenerated === "token") { acc[field.name] = generateToken(); return acc; } acc[field.name] = formData.get(field.name)?.toString() ?? null; return acc; }, {}, ); await db.insertInto(table).values(newRecord).execute(); revalidatePath(`/${entity}`); return { ...currentState, values: newRecord, success: true, }; }; type UpdateActionArgs = { entity: Entity; table: keyof Database; fields: FieldDescription[]; currentState: any; formData: FormData; }; export const updateAction = async ({ entity, table, fields, currentState, formData, }: UpdateActionArgs) => { const id = currentState.values.id; const updatedRecord = fields.reduce( (acc: Record, field: FieldDescription) => { acc[field.name] = formData.get(field.name)?.toString() ?? null; return acc; }, {}, ); await db .updateTable(table) .set(updatedRecord) .where("id", "=", id) .executeTakeFirst(); revalidatePath(`/${entity}/${id}`); return { ...currentState, values: updatedRecord, success: true, }; }; type DeleteActionArgs = { entity: Entity; table: keyof Database; id: string; }; export const deleteAction = async ({ entity, table, id }: DeleteActionArgs) => { await db.deleteFrom(table).where("id", "=", id).execute(); revalidatePath(`/${entity}`); return true; };