"use server"; import { revalidatePath } from "next/cache"; import { db, Database } from "bridge-common"; import { FieldDescription, Entity } from "../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; }, {}, ); const record = await db .insertInto(table) .values(newRecord) .returning(["id"]) .executeTakeFirstOrThrow(); revalidatePath(`/${entity}`); return { ...currentState, values: { ...newRecord, id: record.id }, 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; }; export const selectAllAction = async (table: keyof Database) => { return db.selectFrom(table).selectAll().execute(); }; type SelectOneArgs = { table: keyof Database; id: string; }; export const selectOneAction = async ({ table, id }: SelectOneArgs) => { return db .selectFrom(table) .selectAll() .where("id", "=", id) .executeTakeFirst(); };