UNPKG

remix-conform-rpc

Version:

Supercharge your remix/react-router actions and loaders with typesafe param and query parsing using conform and zod

66 lines 2.03 kB
export function serializeToFormData(data) { if (data instanceof FormData) { return data; } const formData = new FormData(); if (isObject(data)) { serializeData(data, [], formData); } return formData; } function serializeData(data, path, formData) { if (isArray(data)) { serializeArray(data, path, formData); return; } if (isObject(data)) { const entries = Object.entries(data); for (const [key, value] of entries) { const newPath = [...path, { type: "object", key, delimiter: shouldHaveDelimiter(value) }]; serializeData(value, newPath, formData); } return; } if (shouldAddData(data)) { formData.append(constructPath(path), serializePrimitive(data)); } } function serializeArray(entries, path, formData) { entries.forEach((value, index) => { const newPath = [...path, { type: "array", index, delimiter: shouldHaveDelimiter(value) }]; serializeData(value, newPath, formData); }); } function isArray(value) { return Array.isArray(value); } function isObject(value) { return !isArray(value) && typeof value === "object" && value !== null; } function shouldAddData(data) { return typeof data !== "function" && !!data; } /** * Check if an object should have a delimiter (dot) in the path */ function shouldHaveDelimiter(childEntry) { return isObject(childEntry) && Object.keys(childEntry).length >= 1; } function constructPath(elements) { return elements.map((element) => { if (element.type === "array") { return `[${element.index}]${element.delimiter ? "." : ""}`; } return `${element.key}${element.delimiter ? "." : ""}`; }).join(""); } function serializePrimitive(value) { if (value instanceof Date) { return value.toISOString(); } if (typeof value === "boolean") { return value ? "on" : ""; } return String(value); } //# sourceMappingURL=serialize-to-form-data.js.map