Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vest sync validation #117

Merged
merged 2 commits into from
Jan 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,18 @@
},
"homepage": "https://react-hook-form.com",
"devDependencies": {
"@testing-library/jest-dom": "^5.11.8",
"@testing-library/react": "^11.2.2",
"@testing-library/user-event": "^12.6.0",
"@types/jest": "^26.0.19",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.3",
"@testing-library/user-event": "^12.6.2",
"@types/jest": "^26.0.20",
"@types/react": "^17.0.0",
"@typescript-eslint/eslint-plugin": "^4.11.1",
"@typescript-eslint/parser": "^4.11.1",
"@typescript-eslint/eslint-plugin": "^4.14.0",
"@typescript-eslint/parser": "^4.14.0",
"check-export-map": "^1.0.1",
"eslint": "^7.17.0",
"eslint-config-prettier": "^7.1.0",
"eslint-plugin-prettier": "^3.3.0",
"husky": "^4.3.6",
"eslint": "^7.18.0",
"eslint-config-prettier": "^7.2.0",
"eslint-plugin-prettier": "^3.3.1",
"husky": "^4.3.8",
"jest": "^26.6.3",
"joi": "^17.3.0",
"lint-staged": "^10.5.3",
Expand All @@ -129,12 +129,12 @@
"prettier": "^2.2.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-hook-form": "^6.14.0",
"semantic-release": "^17.3.1",
"superstruct": "^0.13.1",
"react-hook-form": "^6.14.2",
"semantic-release": "^17.3.6",
"superstruct": "^0.13.3",
"ts-jest": "^26.4.4",
"typescript": "^4.1.3",
"vest": "^2.2.3",
"vest": "^3.1.1",
"yup": "^0.32.8",
"zod": "^1.11.11"
},
Expand Down
113 changes: 113 additions & 0 deletions vest/src/__tests__/__snapshots__/vest.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`vestResolver should return all the error messages from vestResolver when validation fails and validateAllFieldCriteria set to true 1`] = `
Object {
"errors": Object {
"deepObject": Object {
"data": Object {
"message": "deepObject.data is required",
"type": "",
"types": Object {
"0": "deepObject.data is required",
},
},
},
"password": Object {
"message": "Password must be at least 5 chars",
"type": "",
"types": Object {
"0": "Password must be at least 5 chars",
"1": "Password must contain a digit",
"2": "Password must contain a symbol",
},
},
"username": Object {
"message": "Username is required",
"type": "",
"types": Object {
"0": "Username is required",
"1": "Must be longer than 3 chars",
},
},
},
"values": Object {},
}
`;

exports[`vestResolver should return all the error messages from vestResolver when validation fails and validateAllFieldCriteria set to true and \`mode: sync\` 1`] = `
Object {
"errors": Object {
"deepObject": Object {
"data": Object {
"message": "deepObject.data is required",
"type": "",
"types": Object {
"0": "deepObject.data is required",
},
},
},
"password": Object {
"message": "Password must be at least 5 chars",
"type": "",
"types": Object {
"0": "Password must be at least 5 chars",
"1": "Password must contain a digit",
"2": "Password must contain a symbol",
},
},
"username": Object {
"message": "Username is required",
"type": "",
"types": Object {
"0": "Username is required",
"1": "Must be longer than 3 chars",
},
},
},
"values": Object {},
}
`;

exports[`vestResolver should return single error message from vestResolver when validation fails and validateAllFieldCriteria set to false 1`] = `
Object {
"errors": Object {
"deepObject": Object {
"data": Object {
"message": "deepObject.data is required",
"type": "",
},
},
"password": Object {
"message": "Password must be at least 5 chars",
"type": "",
},
"username": Object {
"message": "Username is required",
"type": "",
},
},
"values": Object {},
}
`;

exports[`vestResolver should return single error message from vestResolver when validation fails and validateAllFieldCriteria set to false and \`mode: sync\` 1`] = `
Object {
"errors": Object {
"deepObject": Object {
"data": Object {
"message": "deepObject.data is required",
"type": "",
},
},
"password": Object {
"message": "Password must be at least 5 chars",
"type": "",
},
"username": Object {
"message": "Username is required",
"type": "",
},
},
"values": Object {},
}
`;
100 changes: 51 additions & 49 deletions vest/src/__tests__/vest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,23 @@ describe('vestResolver', () => {
data: 'test',
},
};
expect(await vestResolver(validationSuite)(data, {})).toEqual({
expect(await vestResolver(validationSuite)(data)).toEqual({
values: data,
errors: {},
});
});

it('should return values from vestResolver with `mode: sync` when validation pass', async () => {
const data = {
username: 'asdda',
password: 'asddfg123!',
deepObject: {
data: 'test',
},
};
expect(
await vestResolver(validationSuite, undefined, { mode: 'sync' })(data),
).toEqual({
values: data,
errors: {},
});
Expand All @@ -55,25 +71,21 @@ describe('vestResolver', () => {
},
};

expect(await vestResolver(validationSuite)(data, {})).toEqual({
values: {},
errors: {
username: {
type: '',
message: 'Username is required',
},
password: {
type: '',
message: 'Password must be at least 5 chars',
},
deepObject: {
data: {
type: '',
message: 'deepObject.data is required',
},
},
expect(await vestResolver(validationSuite)(data)).toMatchSnapshot();
});

it('should return single error message from vestResolver when validation fails and validateAllFieldCriteria set to false and `mode: sync`', async () => {
const data = {
username: '',
password: 'a',
deepObject: {
data: '',
},
});
};

expect(
await vestResolver(validationSuite, undefined, { mode: 'sync' })(data),
).toMatchSnapshot();
});

it('should return all the error messages from vestResolver when validation fails and validateAllFieldCriteria set to true', async () => {
Expand All @@ -85,36 +97,26 @@ describe('vestResolver', () => {
},
};

expect(await vestResolver(validationSuite, {})(data, {}, true)).toEqual({
values: {},
errors: {
username: {
type: '',
message: 'Username is required',
types: {
0: 'Username is required',
1: 'Must be longer than 3 chars',
},
},
password: {
type: '',
message: 'Password must be at least 5 chars',
types: {
0: 'Password must be at least 5 chars',
1: 'Password must contain a digit',
2: 'Password must contain a symbol',
},
},
deepObject: {
data: {
type: '',
message: 'deepObject.data is required',
types: {
0: 'deepObject.data is required',
},
},
},
expect(
await vestResolver(validationSuite)(data, {}, true),
).toMatchSnapshot();
});

it('should return all the error messages from vestResolver when validation fails and validateAllFieldCriteria set to true and `mode: sync`', async () => {
const data = {
username: '',
password: 'a',
deepObject: {
data: '',
},
});
};

expect(
await vestResolver(validationSuite, undefined, { mode: 'sync' })(
data,
{},
true,
),
).toMatchSnapshot();
});
});
7 changes: 2 additions & 5 deletions vest/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@ export type ICreateResult = ReturnType<typeof Vest.create>;

export type Resolver = (
schema: ICreateResult,
options?: any,
schemaOptions?: never,
resolverOptions?: { mode: 'async' | 'sync' },
) => <TFieldValues extends FieldValues, TContext>(
values: UnpackNestedValue<TFieldValues>,
context?: TContext,
validateAllFieldCriteria?: boolean,
) => Promise<ResolverResult<TFieldValues>>;

export type VestErrors = Record<string, string[]>;

export type Promisify = <T extends ICreateResult, K>(
fn: T,
) => (args: K) => Promise<Vest.IVestResult>;
30 changes: 17 additions & 13 deletions vest/src/vest.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { transformToNestObject } from 'react-hook-form';
import * as Vest from 'vest';
import type { Promisify, VestErrors, Resolver } from './types';

const promisify: Promisify = (validatorFn) => (...args) =>
new Promise((resolve) => validatorFn(...args).done(resolve as Vest.DoneCB));
import promisify from 'vest/promisify';
import { DraftResult, IVestResult } from 'vest/vestResult';
import type { VestErrors, Resolver } from './types';

const parseErrorSchema = (
vestError: VestErrors,
Expand All @@ -30,17 +28,23 @@ const parseErrorSchema = (
}, {});
};

export const vestResolver: Resolver = (schema, _ = {}) => async (
values,
_context,
validateAllFieldCriteria = false,
) => {
const validateSchema = promisify(schema);
const result = await validateSchema(values);
export const vestResolver: Resolver = (
schema,
_,
{ mode } = { mode: 'async' },
) => async (values, _context, validateAllFieldCriteria = false) => {
let result: IVestResult | DraftResult;
if (mode === 'async') {
const validateSchema = promisify(schema);
result = await validateSchema(values);
} else {
result = schema(values);
}

const errors = result.getErrors();

if (!result.hasErrors()) {
return { values: values as any, errors: {} };
return { values, errors: {} };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏 thanks for fixing the type.

}

return {
Expand Down
Loading