Skip to content

Commit

Permalink
fix: expose array element validation errors in zod resolver (#119)
Browse files Browse the repository at this point in the history
Co-authored-by: Young Min Kim <youngmink@netflix.com>
  • Loading branch information
aprilrd and Young Min Kim authored Jan 31, 2021
1 parent 115f041 commit ecee1e9
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 32 deletions.
17 changes: 17 additions & 0 deletions src/__snapshots__/zod.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,23 @@ Object {
"invalid_type": "Expected number, received string",
},
},
"likedUsers": Object {
"0": Object {
"id": Object {
"message": "Expected number, received string",
"type": "invalid_type",
"types": Object {
"invalid_type": "Expected number, received string",
},
},
},
"message": "Invalid input",
"type": "invalid_union",
"types": Object {
"invalid_type": "Expected undefined, received array",
"invalid_union": "Invalid input",
},
},
"password": Object {
"message": "Should be at least 8 characters",
"type": "too_small",
Expand Down
9 changes: 9 additions & 0 deletions src/zod.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ const schema = z
author: z.object({
id: z.number(),
}),
likedUsers: z
.array(
z.object({
id: z.number(),
}),
)
.optional(),
count: z.number().positive().int(),
date: z.date(),
url: z.string().url(),
Expand All @@ -36,6 +43,7 @@ describe('zodResolver', () => {
author: {
id: 1,
},
likedUsers: [{ id: 1 }],
count: 4,
date: new Date(),
url: 'https://github.com/react-hook-form/resolvers',
Expand Down Expand Up @@ -73,6 +81,7 @@ describe('zodResolver', () => {
author: {
id: '1',
},
likedUsers: [{ id: '1' }],
count: -5,
date: 'date',
password: 'R',
Expand Down
73 changes: 41 additions & 32 deletions src/zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,48 @@ const parseErrorSchema = (
return {};
}

return zodError.errors.reduce<Record<string, any>>(
(previous, { path, message, code: type }) => {
const currentPath = convertArrayToPathName(path);
const errors = [...zodError.errors];
let previous: Record<string, any> = {};

return {
...previous,
...(path
? previous[currentPath] && validateAllFieldCriteria
? {
[currentPath]: appendErrors(
currentPath,
validateAllFieldCriteria,
previous,
type,
message,
),
}
: {
[currentPath]: previous[currentPath] || {
message,
type,
...(validateAllFieldCriteria
? {
types: { [type]: message || true },
}
: {}),
},
}
: {}),
};
},
{},
);
for (const error of errors) {
const { path, message, code: type } = error;
const currentPath = convertArrayToPathName(path);

if ('unionErrors' in error) {
for (const subErrors of error.unionErrors.map((e) => e.errors)) {
errors.push(...subErrors);
}
}

previous = {
...previous,
...(path
? previous[currentPath] && validateAllFieldCriteria
? {
[currentPath]: appendErrors(
currentPath,
validateAllFieldCriteria,
previous,
type,
message,
),
}
: {
[currentPath]: previous[currentPath] || {
message,
type,
...(validateAllFieldCriteria
? {
types: { [type]: message || true },
}
: {}),
},
}
: {}),
};
}

return previous;
};

export const zodResolver = <T extends z.ZodSchema<any, any>>(
Expand Down

0 comments on commit ecee1e9

Please sign in to comment.