UNPKG

zod

Version:

TypeScript-first schema declaration and validation library with static type inference

222 lines (221 loc) 7.61 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.$ZodRealError = exports.$ZodError = void 0; exports.flattenError = flattenError; exports.formatError = formatError; exports.treeifyError = treeifyError; exports.toDotPath = toDotPath; exports.prettifyError = prettifyError; const core_js_1 = require("./core.cjs"); const util = __importStar(require("./util.cjs")); const initializer = (inst, def) => { inst.name = "$ZodError"; Object.defineProperty(inst, "_zod", { value: inst._zod, enumerable: false, }); Object.defineProperty(inst, "issues", { value: def, enumerable: false, }); inst.message = JSON.stringify(def, util.jsonStringifyReplacer, 2); Object.defineProperty(inst, "toString", { value: () => inst.message, enumerable: false, }); }; exports.$ZodError = (0, core_js_1.$constructor)("$ZodError", initializer); exports.$ZodRealError = (0, core_js_1.$constructor)("$ZodError", initializer, { Parent: Error }); function flattenError(error, mapper = (issue) => issue.message) { const fieldErrors = {}; const formErrors = []; for (const sub of error.issues) { if (sub.path.length > 0) { fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || []; fieldErrors[sub.path[0]].push(mapper(sub)); } else { formErrors.push(mapper(sub)); } } return { formErrors, fieldErrors }; } function formatError(error, _mapper) { const mapper = _mapper || function (issue) { return issue.message; }; const fieldErrors = { _errors: [] }; const processError = (error) => { for (const issue of error.issues) { if (issue.code === "invalid_union" && issue.errors.length) { issue.errors.map((issues) => processError({ issues })); } else if (issue.code === "invalid_key") { processError({ issues: issue.issues }); } else if (issue.code === "invalid_element") { processError({ issues: issue.issues }); } else if (issue.path.length === 0) { fieldErrors._errors.push(mapper(issue)); } else { let curr = fieldErrors; let i = 0; while (i < issue.path.length) { const el = issue.path[i]; const terminal = i === issue.path.length - 1; if (!terminal) { curr[el] = curr[el] || { _errors: [] }; } else { curr[el] = curr[el] || { _errors: [] }; curr[el]._errors.push(mapper(issue)); } curr = curr[el]; i++; } } } }; processError(error); return fieldErrors; } function treeifyError(error, _mapper) { const mapper = _mapper || function (issue) { return issue.message; }; const result = { errors: [] }; const processError = (error, path = []) => { var _a, _b; for (const issue of error.issues) { if (issue.code === "invalid_union" && issue.errors.length) { // regular union error issue.errors.map((issues) => processError({ issues }, issue.path)); } else if (issue.code === "invalid_key") { processError({ issues: issue.issues }, issue.path); } else if (issue.code === "invalid_element") { processError({ issues: issue.issues }, issue.path); } else { const fullpath = [...path, ...issue.path]; if (fullpath.length === 0) { result.errors.push(mapper(issue)); continue; } let curr = result; let i = 0; while (i < fullpath.length) { const el = fullpath[i]; const terminal = i === fullpath.length - 1; if (typeof el === "string") { curr.properties ?? (curr.properties = {}); (_a = curr.properties)[el] ?? (_a[el] = { errors: [] }); curr = curr.properties[el]; } else { curr.items ?? (curr.items = []); (_b = curr.items)[el] ?? (_b[el] = { errors: [] }); curr = curr.items[el]; } if (terminal) { curr.errors.push(mapper(issue)); } i++; } } } }; processError(error); return result; } /** Format a ZodError as a human-readable string in the following form. * * From * * ```ts * ZodError { * issues: [ * { * expected: 'string', * code: 'invalid_type', * path: [ 'username' ], * message: 'Invalid input: expected string' * }, * { * expected: 'number', * code: 'invalid_type', * path: [ 'favoriteNumbers', 1 ], * message: 'Invalid input: expected number' * } * ]; * } * ``` * * to * * ``` * username * ✖ Expected number, received string at "username * favoriteNumbers[0] * ✖ Invalid input: expected number * ``` */ function toDotPath(_path) { const segs = []; const path = _path.map((seg) => (typeof seg === "object" ? seg.key : seg)); for (const seg of path) { if (typeof seg === "number") segs.push(`[${seg}]`); else if (typeof seg === "symbol") segs.push(`[${JSON.stringify(String(seg))}]`); else if (/[^\w$]/.test(seg)) segs.push(`[${JSON.stringify(seg)}]`); else { if (segs.length) segs.push("."); segs.push(seg); } } return segs.join(""); } function prettifyError(error) { const lines = []; // sort by path length const issues = [...error.issues].sort((a, b) => (a.path ?? []).length - (b.path ?? []).length); // Process each issue for (const issue of issues) { lines.push(`✖ ${issue.message}`); if (issue.path?.length) lines.push(` → at ${toDotPath(issue.path)}`); } // Convert Map to formatted string return lines.join("\n"); }