UNPKG

zod-validation-error

Version:

Wrap zod validation errors in user-friendly readable messages

309 lines (292 loc) 9.08 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // lib/v3/index.ts var index_exports = {}; __export(index_exports, { ValidationError: () => ValidationError, createMessageBuilder: () => createMessageBuilder, errorMap: () => errorMap, fromError: () => fromError, fromZodError: () => fromZodError, fromZodIssue: () => fromZodIssue, isValidationError: () => isValidationError, isValidationErrorLike: () => isValidationErrorLike, isZodErrorLike: () => isZodErrorLike, toValidationError: () => toValidationError }); module.exports = __toCommonJS(index_exports); // lib/v3/isZodErrorLike.ts function isZodErrorLike(err) { return err instanceof Error && err.name === "ZodError" && "issues" in err && Array.isArray(err.issues); } // lib/v3/ValidationError.ts var ValidationError = class extends Error { name; details; constructor(message, options) { super(message, options); this.name = "ZodValidationError"; this.details = getIssuesFromErrorOptions(options); } toString() { return this.message; } }; function getIssuesFromErrorOptions(options) { if (options) { const cause = options.cause; if (isZodErrorLike(cause)) { return cause.issues; } } return []; } // lib/v3/isValidationError.ts function isValidationError(err) { return err instanceof ValidationError; } // lib/v3/isValidationErrorLike.ts function isValidationErrorLike(err) { return err instanceof Error && err.name === "ZodValidationError"; } // lib/v3/fromZodIssue.ts var zod2 = __toESM(require("zod/v3")); // lib/v3/MessageBuilder.ts var zod = __toESM(require("zod/v3")); // lib/utils/NonEmptyArray.ts function isNonEmptyArray(value) { return value.length !== 0; } // lib/utils/stringify.ts function stringifySymbol(symbol) { return symbol.description ?? ""; } // lib/utils/joinPath.ts var identifierRegex = /[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/u; function joinPath(path) { if (path.length === 1) { let propertyKey = path[0]; if (typeof propertyKey === "symbol") { propertyKey = stringifySymbol(propertyKey); } return propertyKey.toString() || '""'; } return path.reduce((acc, propertyKey) => { if (typeof propertyKey === "number") { return acc + "[" + propertyKey.toString() + "]"; } if (typeof propertyKey === "symbol") { propertyKey = stringifySymbol(propertyKey); } if (propertyKey.includes('"')) { return acc + '["' + escapeQuotes(propertyKey) + '"]'; } if (!identifierRegex.test(propertyKey)) { return acc + '["' + propertyKey + '"]'; } const separator = acc.length === 0 ? "" : "."; return acc + separator + propertyKey; }, ""); } function escapeQuotes(str) { return str.replace(/"/g, '\\"'); } // lib/v3/config.ts var ISSUE_SEPARATOR = "; "; var MAX_ISSUES_IN_MESSAGE = 99; var PREFIX = "Validation error"; var PREFIX_SEPARATOR = ": "; var UNION_SEPARATOR = ", or "; // lib/v3/MessageBuilder.ts function createMessageBuilder(props = {}) { const { issueSeparator = ISSUE_SEPARATOR, unionSeparator = UNION_SEPARATOR, prefixSeparator = PREFIX_SEPARATOR, prefix = PREFIX, includePath = true, maxIssuesInMessage = MAX_ISSUES_IN_MESSAGE } = props; return (issues) => { const message = issues.slice(0, maxIssuesInMessage).map( (issue) => getMessageFromZodIssue({ issue, issueSeparator, unionSeparator, includePath }) ).join(issueSeparator); return prefixMessage(message, prefix, prefixSeparator); }; } function getMessageFromZodIssue(props) { const { issue, issueSeparator, unionSeparator, includePath } = props; if (issue.code === zod.ZodIssueCode.invalid_union) { return issue.unionErrors.reduce((acc, zodError) => { const newIssues = zodError.issues.map( (issue2) => getMessageFromZodIssue({ issue: issue2, issueSeparator, unionSeparator, includePath }) ).join(issueSeparator); if (!acc.includes(newIssues)) { acc.push(newIssues); } return acc; }, []).join(unionSeparator); } if (issue.code === zod.ZodIssueCode.invalid_arguments) { return [ issue.message, ...issue.argumentsError.issues.map( (issue2) => getMessageFromZodIssue({ issue: issue2, issueSeparator, unionSeparator, includePath }) ) ].join(issueSeparator); } if (issue.code === zod.ZodIssueCode.invalid_return_type) { return [ issue.message, ...issue.returnTypeError.issues.map( (issue2) => getMessageFromZodIssue({ issue: issue2, issueSeparator, unionSeparator, includePath }) ) ].join(issueSeparator); } if (includePath && isNonEmptyArray(issue.path)) { if (issue.path.length === 1) { const identifier = issue.path[0]; if (typeof identifier === "number") { return `${issue.message} at index ${identifier}`; } } return `${issue.message} at "${joinPath(issue.path)}"`; } return issue.message; } function prefixMessage(message, prefix, prefixSeparator) { if (prefix !== null) { if (message.length > 0) { return [prefix, message].join(prefixSeparator); } return prefix; } if (message.length > 0) { return message; } return PREFIX; } // lib/v3/fromZodIssue.ts function fromZodIssue(issue, options = {}) { const messageBuilder = createMessageBuilderFromOptions(options); const message = messageBuilder([issue]); return new ValidationError(message, { cause: new zod2.ZodError([issue]) }); } function createMessageBuilderFromOptions(options) { if ("messageBuilder" in options) { return options.messageBuilder; } return createMessageBuilder(options); } // lib/v3/errorMap.ts var errorMap = (issue, ctx) => { const error = fromZodIssue({ ...issue, // fallback to the default error message // when issue does not have a message message: issue.message ?? ctx.defaultError }); return { message: error.message }; }; // lib/v3/fromZodError.ts function fromZodError(zodError, options = {}) { if (!isZodErrorLike(zodError)) { throw new TypeError( `Invalid zodError param; expected instance of ZodError. Did you mean to use the "${fromError.name}" method instead?` ); } return fromZodErrorWithoutRuntimeCheck(zodError, options); } function fromZodErrorWithoutRuntimeCheck(zodError, options = {}) { const zodIssues = zodError.errors; let message; if (isNonEmptyArray(zodIssues)) { const messageBuilder = createMessageBuilderFromOptions2(options); message = messageBuilder(zodIssues); } else { message = zodError.message; } return new ValidationError(message, { cause: zodError }); } function createMessageBuilderFromOptions2(options) { if ("messageBuilder" in options) { return options.messageBuilder; } return createMessageBuilder(options); } // lib/v3/toValidationError.ts var toValidationError = (options = {}) => (err) => { if (isZodErrorLike(err)) { return fromZodErrorWithoutRuntimeCheck(err, options); } if (err instanceof Error) { return new ValidationError(err.message, { cause: err }); } return new ValidationError("Unknown error"); }; // lib/v3/fromError.ts function fromError(err, options = {}) { return toValidationError(options)(err); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ValidationError, createMessageBuilder, errorMap, fromError, fromZodError, fromZodIssue, isValidationError, isValidationErrorLike, isZodErrorLike, toValidationError }); //# sourceMappingURL=index.js.map