UNPKG

@schema-hub/zod-error-formatter

Version:

Simple and easy-to-understand zod error messages

77 lines 2.87 kB
import { util } from 'zod/v4/core'; import { formatOneOfList, isParsedType } from '../list.js'; import { findValueByPath } from '../path.js'; function flattenAllIssues(errors) { return errors.flatMap((issues) => { return issues.flatMap((issue) => { if (issue.code === 'invalid_union') { return flattenAllIssues(issue.errors); } return issue; }); }); } function isSamePath(pathA, pathB) { if (pathA.length !== pathB.length) { return false; } return pathA.every((element, index) => { return element === pathB[index]; }); } function isSupportedIssueWithSamePath(issue, expectedPath) { return ['invalid_type', 'invalid_value'].includes(issue.code) && isSamePath(issue.path, expectedPath); } function filterSupportedIssuesWithSamePath(issues, expectedPath) { return issues.filter((issue) => { return isSupportedIssueWithSamePath(issue, expectedPath); }); } function isPrimitive(value) { return ['string', 'number', 'symbol', 'bigint', 'boolean', 'undefined'].includes(typeof value) || value === null; } function determineExpectedValue(issue) { if (issue.code === 'invalid_type') { return { type: issue.expected }; } if (isPrimitive(issue.values[0])) { return issue.values[0]; } return JSON.stringify(issue.values); } function hasValue(values, expectedValue) { return values.some((value) => { if (isParsedType(value) && isParsedType(expectedValue)) { return value.type === expectedValue.type; } return value === expectedValue; }); } function removeDuplicateListValues(values) { const uniqueValues = []; for (const value of values) { if (!hasValue(uniqueValues, value)) { uniqueValues.push(value); } } return uniqueValues; } // eslint-disable-next-line max-statements -- no idea how to refactor right now export function formatInvalidUnionIssueMessage(issue, input) { const result = findValueByPath(input, issue.path); if (result.found) { const memberIssues = flattenAllIssues(issue.errors); const supportedIssues = filterSupportedIssuesWithSamePath(memberIssues, []); if (memberIssues.length === supportedIssues.length) { const [firstIssue] = supportedIssues; if (firstIssue !== undefined) { const expectedValues = removeDuplicateListValues(supportedIssues.map(determineExpectedValue)); const receivedValue = util.getParsedType(result.value); return `invalid value: expected ${formatOneOfList(expectedValues)}, but got ${receivedValue}`; } } return 'invalid value doesn’t match expected union'; } return `missing ${result.pathItemKind}`; } //# sourceMappingURL=invalid-union.js.map