UNPKG

@omer-x/bs-ui-kit

Version:
48 lines (47 loc) 2.06 kB
import { bundleErrors } from "./zod-v4"; /** * Defines a type-safe React server action for forms, validating form data with Zod and handling errors internally. * * @param definition - The form action definition object. * @param definition.name - The unique name of the action. * @param definition.middleware - An array of middleware functions to execute before the action. (Optional) * @param definition.schema - The Zod schema used to validate form data. * @param definition.action - The function to execute if validation succeeds. * @returns An object containing the server action handler keyed by the action name. */ export function defineFormAction(definition) { async function handler(...allParams) { if (definition.middlewares) { await Promise.all(definition.middlewares.map(middleware => middleware())); } const formData = allParams[allParams.length - 1]; const customArgs = allParams.slice(0, allParams.length - 2); const validation = solveKnownIssues(definition.schema.strip(), Object.fromEntries(formData.entries())); if (!validation.success) { return bundleErrors(validation.error.issues); } return await definition.action(validation.data)(...customArgs); } return { [definition.name]: handler, }; } function solveKnownIssues(schema, input) { const validation = schema.safeParse(input); if (!validation.success) { for (const issue of validation.error.issues) { if (issue.code === "invalid_type") { if (issue.expected === "number" && issue.message.includes("expected number, received string")) { const [location] = issue.path; if (location in input) { return solveKnownIssues(schema, { ...input, [location]: parseFloat(input[location]), }); } } } } } return validation; }