remix-hook-form
Version:
Utility wrapper around react-hook-form for use with react-router v7+
140 lines (138 loc) • 4.41 kB
JavaScript
// src/utilities/index.ts
var tryParseJSON = (value) => {
if (value instanceof File || value instanceof Blob) {
return value;
}
try {
const json = JSON.parse(value);
return json;
} catch (e) {
return value;
}
};
var generateFormData = (formData, preserveStringified = false) => {
var _a;
const outputObject = {};
const keyCounts = {};
for (const key of formData.keys()) {
keyCounts[key] = ((_a = keyCounts[key]) != null ? _a : 0) + 1;
}
for (const [key, value] of formData.entries()) {
const keyCount = keyCounts[key];
const data = preserveStringified ? value : tryParseJSON(value);
const keyParts = key.split(".");
let currentObject = outputObject;
for (let i = 0; i < keyParts.length - 1; i++) {
const keyPart = keyParts[i];
if (!currentObject[keyPart]) {
currentObject[keyPart] = /^\d+$/.test(keyParts[i + 1]) ? [] : {};
}
currentObject = currentObject[keyPart];
}
const lastKeyPart = keyParts[keyParts.length - 1];
const lastKeyPartIsArray = /\[\d*\]$|\[\]$/.test(lastKeyPart);
if (lastKeyPartIsArray) {
const key2 = lastKeyPart.replace(/\[\d*\]$|\[\]$/, "");
if (!currentObject[key2]) {
currentObject[key2] = [];
}
currentObject[key2].push(data);
} else {
if (/^\d+$/.test(lastKeyPart)) {
currentObject.push(data);
} else {
if (keyCount > 1) {
if (!currentObject[key]) {
currentObject[key] = [];
}
currentObject[key].push(data);
} else {
currentObject[lastKeyPart] = data;
}
}
}
}
return outputObject;
};
var getFormDataFromSearchParams = (request, preserveStringified = false) => {
const searchParams = new URL(request.url).searchParams;
return generateFormData(searchParams, preserveStringified);
};
var isGet = (request) => request.method === "GET" || request.method === "get";
var getValidatedFormData = async (request, resolver, preserveStringified = false) => {
const { receivedValues } = await getFormData(
request,
preserveStringified
);
const data = await validateFormData(receivedValues, resolver);
return { ...data, receivedValues };
};
var getFormData = async (request, preserveStringified = false) => {
const receivedValues = "url" in request && isGet(request) ? getFormDataFromSearchParams(request, preserveStringified) : await parseFormData(request, preserveStringified);
return { receivedValues };
};
var validateFormData = async (data, resolver) => {
const dataToValidate = data instanceof FormData ? Object.fromEntries(data) : data;
const { errors, values } = await resolver(dataToValidate, {}, {
shouldUseNativeValidation: false,
fields: {}
});
if (Object.keys(errors).length > 0) {
return { errors, data: void 0 };
}
return { errors: void 0, data: values };
};
var createFormData = (data, stringifyAll = true) => {
const formData = new FormData();
if (!data) {
return formData;
}
for (const [key, value] of Object.entries(data)) {
if (value === void 0) {
continue;
}
if (typeof FileList !== "undefined" && value instanceof FileList) {
for (let i = 0; i < value.length; i++) {
formData.append(key, value[i]);
}
continue;
}
if (Array.isArray(value) && value.length > 0 && value.every((item) => item instanceof File || item instanceof Blob)) {
for (let i = 0; i < value.length; i++) {
formData.append(key, value[i]);
}
continue;
}
if (value instanceof File || value instanceof Blob) {
formData.append(key, value);
continue;
}
if (stringifyAll) {
formData.append(key, JSON.stringify(value));
continue;
}
if (typeof value === "string") {
formData.append(key, value);
continue;
}
if (value instanceof Date) {
formData.append(key, value.toISOString());
continue;
}
formData.append(key, JSON.stringify(value));
}
return formData;
};
var parseFormData = async (request, preserveStringified = false) => {
const formData = request instanceof Request ? await request.formData() : request;
return generateFormData(formData, preserveStringified);
};
export {
generateFormData,
getFormDataFromSearchParams,
getValidatedFormData,
getFormData,
validateFormData,
createFormData,
parseFormData
};