diff --git a/packages/validator-zod/README.md b/packages/validator-zod/README.md index 4ddec1ab..7872917b 100644 --- a/packages/validator-zod/README.md +++ b/packages/validator-zod/README.md @@ -101,3 +101,28 @@ const schema = z.object({ const { form } = createForm>(/* ... */); ``` + +## Error messages + +The `validator` function accepts a `params` option that will be forwarded to zod, including [a contextual errorMap](https://zod.dev/ERROR_HANDLING?id=contextual-error-map) used to customize error messages. This parameter can be passed as second argument to the `validateSchema` function. + +```javascript +import { validator } from '@felte/validator-zod'; +import { z } from 'zod'; + +const schema = z.object({ + email: z.string().email().nonempty(), + password: z.string().nonempty(), +}); + +const errorMap: zod.ZodErrorMap = (error) => { + // Error messages logic + return { message: '' }; +}; + +const { form } = createForm({ + // ... + extend: validator({ schema }, { errorMap }), // or `validateSchema(schema, { errorMap })` + // ... +}); +``` diff --git a/packages/validator-zod/src/index.ts b/packages/validator-zod/src/index.ts index 8b236f19..96b1888f 100644 --- a/packages/validator-zod/src/index.ts +++ b/packages/validator-zod/src/index.ts @@ -7,15 +7,17 @@ import type { Extender, } from '@felte/common'; import { _update } from '@felte/common'; -import type { ZodError, ZodSchema } from 'zod'; +import type { ParseParams, ZodError, ZodSchema } from 'zod'; export type ValidatorConfig = { schema: ZodSchema; level?: 'error' | 'warning'; + params?: Partial; }; export function validateSchema( - schema: ZodSchema + schema: ZodSchema, + params?: Partial ): ValidationFunction { function walk( error: ZodError, @@ -45,7 +47,7 @@ export function validateSchema( return async function validate( values: Data ): Promise | undefined> { - const result = await schema.safeParseAsync(values); + const result = await schema.safeParseAsync(values, params); if (!result.success) { let err = {} as AssignableErrors; err = walk(result.error, err); @@ -57,12 +59,13 @@ export function validateSchema( export function validator({ schema, level = 'error', + params, }: ValidatorConfig): Extender { return function extender( currentForm: CurrentForm ): ExtenderHandler { if (currentForm.stage !== 'SETUP') return {}; - const validateFn = validateSchema(schema); + const validateFn = validateSchema(schema, params); currentForm.addValidator(validateFn, { level }); return {}; }; diff --git a/packages/validator-zod/tests/validator.spec.ts b/packages/validator-zod/tests/validator.spec.ts index daa7d3e2..3e8667fe 100644 --- a/packages/validator-zod/tests/validator.spec.ts +++ b/packages/validator-zod/tests/validator.spec.ts @@ -363,4 +363,23 @@ describe('Validator zod', () => { expect(errors).to.deep.equal({ type: ['Oops'] }); }); + + test('forwards parse parameters to zod', async () => { + const schema = z.object({ foo: z.literal('foo') }); + + const errorMap: ZodErrorMap = () => { + return { message: 'Oops' }; + }; + + const { validate, errors } = createForm({ + initialValues: { foo: 'bar' }, + extend: validator({ schema, params: { errorMap } }), + }); + + await validate(); + + expect(get(errors)).to.deep.equal({ + foo: ['Oops'], + }); + }); });