UNPKG

@naturalcycles/js-lib

Version:

Standard library for universal (browser + Node.js) javascript

53 lines (52 loc) 1.87 kB
import { _assert } from '../error/assert.js'; import { AppError } from '../error/error.util.js'; import { _stringify } from '../string/stringify.js'; export function getZodValidationFunction(schema) { return (input, opt) => { _assert(!opt?.mutateInput, 'mutateInput=true is not yet supported with Zod'); return zSafeValidate(input, schema); }; } export function zIsValid(value, schema) { const { success } = schema.safeParse(value); return success; } export function zValidate(value, schema) { const [err, data] = zSafeValidate(value, schema); if (err) throw err; return data; } export function zSafeValidate(input, schema) { const r = schema.safeParse(input); if (r.success) { return [null, r.data]; } return [new ZodValidationError(r.error, input, schema), r.data ?? input]; } export class ZodValidationError extends AppError { constructor(zodError, value, schema) { const message = createZodErrorMessage(zodError, schema, value); // const message = z.prettifyError(zodError) // todo: consider adopting it instead super(message, {}, { name: 'ZodValidationError' }); } } function createZodErrorMessage(err, schema, value) { let objectTitle = schema.description; if (typeof value === 'object' && value) { const inputName = schema.description || value.constructor?.name; const inputId = value['id']; objectTitle = [inputName, inputId].filter(Boolean).join('.'); } objectTitle ||= 'data'; return [ `Invalid ${objectTitle}`, '', 'Input:', _stringify(value), err.issues.length > 1 ? `\n${err.issues.length} issues:` : '', ...err.issues.slice(0, 100).map(i => { return [i.path.join('.'), i.message].filter(Boolean).join(': '); }), ].join('\n'); }