All files / core/lib zod-i18n.ts

94.44% Statements 34/36
86% Branches 43/50
100% Functions 1/1
94.44% Lines 34/36

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85      57x   17x 17x 17x       17x 4x   4x 1x 3x 1x     2x       1x       1x           13x 5x 5x       8x 1x 1x       7x 4x 4x 4x       3x 1x 1x       2x       2x 1x       1x       1x 1x         17x     57x      
import { z } from 'zod'
import i18next from 'i18next'
 
const zodErrorMap = (issue: any, ctx: any) => {
    // Explicitly handle ctx being undefined or null
    const defaultError = ctx && ctx.defaultError ? ctx.defaultError : undefined
    let message = defaultError || issue.message
    const code = issue.code as string
 
    // Loose comparison for Zod 4 compatibility where enums might have changed
    // Loose comparison for Zod 4 compatibility where enums might have changed
    if (code === 'invalid_type') {
        const data = ctx?.data !== undefined ? ctx.data : (issue as any).input
 
        if (data === undefined || data === null) {
            message = i18next.t('validation.required', 'This field is required')
        } else if ((issue as any).received === 'Invalid Date') {
            message = i18next.t('validation.invalid_date', {
                defaultValue: defaultError,
            })
        } else if (
            (issue as any).received === 'Infinity' ||
            (issue as any).received === '-Infinity'
        ) {
            message = i18next.t('validation.not_finite', {
                defaultValue: defaultError,
            })
        } else {
            message = i18next.t('validation.invalid_type', {
                expected: (issue as any).expected,
                received: (issue as any).received,
                defaultValue: defaultError,
            })
        }
    } else if (code === 'too_small') {
        const type = (issue as any).type || (issue as any).origin
        message = i18next.t(`validation.too_small.${type}`, {
            count: Number((issue as any).minimum),
            defaultValue: defaultError,
        })
    } else if (code === 'too_big') {
        const type = (issue as any).type || (issue as any).origin
        message = i18next.t(`validation.too_big.${type}`, {
            count: Number((issue as any).maximum),
            defaultValue: defaultError,
        })
    } else if (code === 'invalid_string' || code === 'invalid_format') {
        const validation = (issue as any).validation || (issue as any).format
        Eif (typeof validation === 'string') {
            message = i18next.t(`validation.invalid_string.${validation}`, {
                defaultValue: defaultError,
            })
        }
    } else if (code === 'invalid_enum_value' || code === 'invalid_value') {
        const options = (issue as any).options || []
        message = i18next.t('validation.invalid_enum_value', {
            options: options.join(', '),
            defaultValue: defaultError,
        })
    I} else if (code === 'invalid_date') {
        message = i18next.t('validation.invalid_date', {
            defaultValue: defaultError,
        })
    } else if (code === 'not_multiple_of') {
        message = i18next.t('validation.not_multiple_of', {
            multipleOf: Number((issue as any).multipleOf),
            defaultValue: defaultError,
        })
    I} else if (code === 'not_finite') {
        message = i18next.t('validation.not_finite', {
            defaultValue: defaultError,
        })
    E} else if (code === 'custom') {
        message = i18next.t('validation.custom', {
            defaultValue: defaultError,
        })
    }
 
    return { message }
}
 
z.setErrorMap(zodErrorMap as any)
 
export default zodErrorMap