remix-validated-form
Version:
Form component and utils for easy form validation in remix
44 lines (43 loc) • 1.67 kB
JavaScript
import * as R from "remeda";
import { FORM_ID_FIELD } from "../internal/constants";
import { objectFromPathEntries } from "../internal/flatten";
const preprocessFormData = (data) => {
// A slightly janky way of determining if the data is a FormData object
// since node doesn't really have FormData
if ("entries" in data && typeof data.entries === "function")
return objectFromPathEntries([...data.entries()]);
return objectFromPathEntries(Object.entries(data));
};
const omitInternalFields = (data) => R.omit(data, [FORM_ID_FIELD]);
/**
* Used to create a validator for a form.
* It provides built-in handling for unflattening nested objects and
* extracting the values from FormData.
*/
export function createValidator(validator) {
return {
validate: async (value) => {
const data = preprocessFormData(value);
const result = await validator.validate(omitInternalFields(data));
if (result.error) {
return {
data: undefined,
error: {
fieldErrors: result.error,
subaction: data.subaction,
formId: data[FORM_ID_FIELD],
},
submittedData: data,
formId: data[FORM_ID_FIELD],
};
}
return {
data: result.data,
error: undefined,
submittedData: data,
formId: data[FORM_ID_FIELD],
};
},
validateField: (data, field) => validator.validateField(preprocessFormData(data), field),
};
}