zod
Version:
TypeScript-first schema declaration and validation library with static type inference
222 lines (221 loc) • 7.61 kB
JavaScript
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");
}
;