UNPKG

zod-form-data

Version:

Validation helpers for [zod](https://github.com/colinhacks/zod) specifically for parsing `FormData` or `URLSearchParams`. This is particularly useful when using [Remix](https://github.com/remix-run/remix) and combos well with [remix-validated-form](https:

113 lines (112 loc) 3.14 kB
var __defProp = Object.defineProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; // src/helpers.ts var helpers_exports = {}; __export(helpers_exports, { checkbox: () => checkbox, file: () => file, formData: () => formData, json: () => json, numeric: () => numeric, preprocessFormData: () => preprocessFormData, repeatable: () => repeatable, repeatableOfType: () => repeatableOfType, text: () => text }); import { setPath } from "@rvf/set-get"; import * as z from "zod/v4"; import { ZodType } from "zod/v4"; var stripEmpty = z.literal("").transform(() => void 0); var preprocessIfValid = (schema) => (val) => { const result = schema.safeParse(val); if (result.success) return result.data; return val; }; var text = (schema = z.string()) => z.preprocess(preprocessIfValid(stripEmpty), schema); var numeric = (schema = z.number()) => z.preprocess( preprocessIfValid( z.union([ stripEmpty, z.string().transform((val) => Number(val)).refine((val) => !Number.isNaN(val)) ]) ), schema ); var checkbox = ({ trueValue = "on" } = {}) => z.union([ z.literal(trueValue).transform(() => true), z.literal(void 0).transform(() => false) ]); var file = (schema = z.instanceof(File)) => z.preprocess((val) => { return val instanceof File && val.size === 0 ? void 0 : val; }, schema); var repeatable = (schema = z.array(text())) => { return z.preprocess((val) => { if (Array.isArray(val)) return val; if (val === void 0) return []; return [val]; }, schema); }; var repeatableOfType = (schema) => repeatable(z.array(schema)); var entries = z.array(z.tuple([z.string(), z.any()])); var safeParseJson = (jsonString) => { try { return JSON.parse(jsonString); } catch { return jsonString; } }; var json = (schema) => z.preprocess( preprocessIfValid( z.union([stripEmpty, z.string().transform((val) => safeParseJson(val))]) ), schema ); var processFormData = preprocessIfValid( // We're avoiding using `instanceof` here because different environments // won't necessarily have `FormData` or `URLSearchParams` z.any().refine((val) => Symbol.iterator in val, { abort: true }).transform((val) => [...val]).refine( (val) => entries.safeParse(val).success, { abort: true } ).transform((data) => { const map = /* @__PURE__ */ new Map(); for (const [key, value] of data) { if (map.has(key)) { map.get(key).push(value); } else { map.set(key, [value]); } } return [...map.entries()].reduce( (acc, [key, value]) => { return setPath(acc, key, value.length === 1 ? value[0] : value); }, {} ); }) ); var preprocessFormData = processFormData; var formData = (shapeOrSchema) => z.preprocess( processFormData, shapeOrSchema instanceof ZodType ? shapeOrSchema : z.object(shapeOrSchema) ); export { checkbox, file, formData, json, numeric, preprocessFormData, repeatable, repeatableOfType, text, helpers_exports as zfd }; //# sourceMappingURL=index.mjs.map