Skip to content

Commit 61f63ef

Browse files
committed
Added errorMap option to zod adapter
1 parent e6f2d62 commit 61f63ef

File tree

2 files changed

+46
-8
lines changed

2 files changed

+46
-8
lines changed

src/lib/adapters/zod.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
import type { AnyZodObject, ZodDefault, ZodEffects, ZodType, ZodTypeDef, ZodUnion } from 'zod';
1+
import type {
2+
AnyZodObject,
3+
ZodDefault,
4+
ZodEffects,
5+
ZodErrorMap,
6+
ZodType,
7+
ZodTypeDef,
8+
ZodUnion
9+
} from 'zod';
210
import type { JSONSchema7 } from 'json-schema';
311
import {
412
type AdapterOptions,
@@ -54,9 +62,10 @@ export type ZodValidation<T extends ZodObjectTypes> =
5462

5563
async function validate<T extends ZodValidation<ZodObjectTypes>>(
5664
schema: T,
57-
data: unknown
65+
data: unknown,
66+
errorMap: ZodErrorMap | undefined
5867
): Promise<ValidationResult<Infer<T>>> {
59-
const result = await schema.safeParseAsync(data);
68+
const result = await schema.safeParseAsync(data, { errorMap });
6069
if (result.success) {
6170
return {
6271
data: result.data as Infer<T>,
@@ -71,22 +80,23 @@ async function validate<T extends ZodValidation<ZodObjectTypes>>(
7180

7281
function _zod<T extends ZodValidation<ZodObjectTypes>>(
7382
schema: T,
74-
options?: AdapterOptions<Infer<T>> & { config?: Partial<Options> }
83+
options?: AdapterOptions<Infer<T>> & { errorMap?: ZodErrorMap; config?: Partial<Options> }
7584
): ValidationAdapter<Infer<T>, InferIn<T>> {
7685
return createAdapter({
7786
superFormValidationLibrary: 'zod',
78-
validate: async (data) => validate(schema, data),
87+
validate: async (data) => validate(schema, data, options?.errorMap),
7988
jsonSchema: options?.jsonSchema ?? zodToJSONSchema(schema, options?.config),
8089
defaults: options?.defaults
8190
});
8291
}
8392

8493
function _zodClient<T extends ZodValidation<ZodObjectTypes>>(
85-
schema: T
94+
schema: T,
95+
options?: { errorMap?: ZodErrorMap }
8696
): ClientValidationAdapter<Infer<T>, InferIn<T>> {
8797
return {
8898
superFormValidationLibrary: 'zod',
89-
validate: async (data) => validate(schema, data)
99+
validate: async (data) => validate(schema, data, options?.errorMap)
90100
};
91101
}
92102

src/tests/superValidate.test.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { defaults as schemaDefaults } from '$lib/defaults.js';
1818
///// Adapters //////////////////////////////////////////////////////
1919

2020
import { zod, zodToJSONSchema } from '$lib/adapters/zod.js';
21-
import { z } from 'zod';
21+
import { z, type ZodErrorMap } from 'zod';
2222

2323
import { valibot } from '$lib/adapters/valibot.js';
2424
import * as v from 'valibot';
@@ -628,6 +628,34 @@ describe('Zod', () => {
628628
expect(() => zod(schema)).toThrow(Error);
629629
});
630630

631+
it('with the errorMap option', async () => {
632+
const schema = z.object({
633+
num: z.number().int()
634+
});
635+
636+
const options: { errorMap?: ZodErrorMap } = {
637+
errorMap: (error, ctx) => {
638+
if (error.code === z.ZodIssueCode.invalid_type) {
639+
return { message: 'Not an integer.' };
640+
}
641+
return { message: ctx.defaultError };
642+
}
643+
};
644+
645+
const adapter = zod(schema, options);
646+
647+
const form = await superValidate(
648+
// @ts-expect-error Testing errorMap with invalid type
649+
{ num: 'abc' },
650+
adapter
651+
);
652+
expect(form.valid).toBe(false);
653+
expect(form.errors.num).toEqual(['Not an integer.']);
654+
655+
const sameAdapter = zod(schema, options);
656+
expect(sameAdapter).toBe(adapter);
657+
});
658+
631659
schemaTest(zod(schema));
632660
});
633661

0 commit comments

Comments
 (0)