Skip to content

Commit

Permalink
refactor(resolvers): replace resolvers with typeschema
Browse files Browse the repository at this point in the history
* feat(resolvers): replace resolvers with typeschema

* Create changeset

* Update lock file

* Use changie instead
  • Loading branch information
decs authored Mar 3, 2024
1 parent fa718d7 commit fce9b0b
Show file tree
Hide file tree
Showing 14 changed files with 230 additions and 306 deletions.
3 changes: 3 additions & 0 deletions .changes/unreleased/Changed-20240303-012115.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kind: Changed
body: 'feat(resolvers): replace resolvers with typeschema'
time: 2024-03-03T01:21:15.163345-08:00
36 changes: 4 additions & 32 deletions __tests__/__snapshots__/validation.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,37 +1,9 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`FastestValidator Validation > should create resolve base on schema 1`] = `
{
"validate": [Function],
}
`;
exports[`Valibot Validation > should return false 1`] = `[AggregateError: Assertion failed]`;

exports[`FastestValidator Validation > should return false 1`] = `[Error: Validation failed]`;
exports[`Yoi Validation > should return false 1`] = `[AggregateError: Assertion failed]`;

exports[`Valibot Validation > should return false 1`] = `[ValiError: Invalid type]`;
exports[`Yup Validation > should return false 1`] = `[AggregateError: Assertion failed]`;

exports[`Yoi Validation > should return false 1`] = `[ValidationError: "email" is required]`;

exports[`Yup Validation > should create yup resolve base on schema 1`] = `
{
"validate": [Function],
}
`;

exports[`Yup Validation > should return false 1`] = `[ValidationError: age is a required field]`;

exports[`Zod Validation > should return false 1`] = `
[ZodError: [
{
"code": "too_small",
"minimum": 8,
"type": "string",
"inclusive": true,
"exact": false,
"message": "String must contain at least 8 character(s)",
"path": [
"username"
]
}
]]
`;
exports[`Zod Validation > should return false 1`] = `[AggregateError: Assertion failed]`;
24 changes: 8 additions & 16 deletions __tests__/hof.test.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
import * as yup from "yup";
import { withValidation, withValidations } from "../src";
import * as yup from 'yup';
import { withValidation, withValidations } from '../src';

const schema = yup.object().shape({
name: yup.string().required(),
});

describe("withValidation", () => {
it("should return function", () => {
expect(withValidation({
schema,
type: "Yup",
mode: "query",
})).toMatchSnapshot();
describe('withValidation', () => {
it('should return function', () => {
expect(withValidation({ schema, mode: 'query' })).toMatchSnapshot();
});
});

describe("withValidations", () => {
it("should return function", () => {
expect(withValidations([{
schema,
type: "Yup",
mode: "body",
}])).toMatchSnapshot();
describe('withValidations', () => {
it('should return function', () => {
expect(withValidations([{ schema, mode: 'body' }])).toMatchSnapshot();
});
});
146 changes: 32 additions & 114 deletions __tests__/validation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,40 @@ import Joi from 'joi';
import * as valibot from 'valibot';
import * as yup from 'yup';
import { z } from 'zod';

import { createResolver } from '../src/validation';
import { typeschemaResolver } from '../src/resolver';

describe('Yup Validation', () => {
it('should create yup resolve base on schema', () => {
const resolver = createResolver('Yup', {});
expect(resolver).toMatchSnapshot();
});

it('should return true', () => {
it('should return true', async () => {
const schema = yup.object().shape({
name: yup.string().required(),
age: yup
.number()
.required()
.positive()
.integer(),
age: yup.number().required().positive().integer(),
email: yup.string().email(),
website: yup.string().url(),
createdOn: yup.date().default(function() {
createdOn: yup.date().default(function () {
return new Date();
}),
});
const resolver = createResolver('Yup', schema);
const isValid = resolver.validate({
const resolver = typeschemaResolver(schema);
const isValid = await resolver.validate({
name: 'jimmy',
age: 24,
});
expect(isValid).toBeTruthy();
});

it('should return false', () => {
it('should return false', async () => {
const schema = yup.object().shape({
name: yup.string().required(),
age: yup
.number()
.required()
.positive()
.integer(),
age: yup.number().required().positive().integer(),
email: yup.string().email(),
website: yup.string().url(),
createdOn: yup.date().default(function() {
createdOn: yup.date().default(function () {
return new Date();
}),
});
const resolver = createResolver('Yup', schema);
const resolver = typeschemaResolver(schema);
try {
resolver.validate({
await resolver.validate({
name: 'jimmy',
});
} catch (error) {
Expand All @@ -58,117 +44,58 @@ describe('Yup Validation', () => {
});
});

describe('FastestValidator Validation', () => {
it('should create resolve base on schema', () => {
const resolver = createResolver('FastestValidator', {});
expect(resolver).toMatchSnapshot();
});

it('should return true', () => {
const schema = {
id: { type: 'number', positive: true, integer: true },
name: { type: 'string', min: 3, max: 255 },
status: 'boolean', // short-hand def
};
const resolver = createResolver('FastestValidator', schema);
const isValid = resolver.validate({
id: 5,
name: 'John',
status: true,
});
expect(isValid).toBeTruthy();
});

it('should return false', () => {
const schema = {
id: { type: 'number', positive: true, integer: true },
name: { type: 'string', min: 3, max: 255 },
status: 'boolean', // short-hand def
};
const resolver = createResolver('FastestValidator', schema);
try {
resolver.validate({
id: 2,
name: 'Adam',
});
} catch (error) {
expect(error).toMatchSnapshot();
}
});
});

describe('Yoi Validation', () => {
it('should create yoi resolve base on schema', () => {
try {
createResolver('Joi', {});
} catch (error) {
expect(error).toMatchSnapshot();
}
});

it('should return true', () => {
it('should return true', async () => {
const schema = Joi.object({
dob: Joi.date().iso(),
email: Joi.string()
.email()
.required(),
email: Joi.string().email().required(),
name: Joi.string().required(),
});

const resolver = createResolver('Joi', schema);
const isValid = resolver.validate({
const resolver = typeschemaResolver(schema);
const isValid = await resolver.validate({
name: 'Huynh Duc Dung',
email: '[email protected]',
dob: 1988,
});
expect(isValid).toBeTruthy();
});

it('should return false', () => {
it('should return false', async () => {
const schema = Joi.object({
dob: Joi.date().iso(),
email: Joi.string()
.email()
.required(),
email: Joi.string().email().required(),
name: Joi.string().required(),
});
const resolver = createResolver('Joi', schema);
const resolver = typeschemaResolver(schema);
try {
resolver.validate({});
await resolver.validate({});
} catch (error) {
expect(error).toMatchSnapshot();
}
});
});

describe('Zod Validation', () => {
it('should create zod resolve base on schema', () => {
try {
createResolver('Zod', {});
} catch (error) {
expect(error).toMatchSnapshot();
}
});

it('should return true', () => {
it('should return true', async () => {
const schema = z.object({
username: z.string(),
});

const resolver = createResolver('Zod', schema);
const isValid = resolver.validate({
const resolver = typeschemaResolver(schema);
const isValid = await resolver.validate({
username: 'jellydn',
});
expect(isValid).toBeTruthy();
});

it('should return false', () => {
it('should return false', async () => {
const schema = z.object({
username: z.string().min(8),
});
const resolver = createResolver('Zod', schema);
const resolver = typeschemaResolver(schema);
try {
resolver.validate({
await resolver.validate({
username: 'jellydn',
});
} catch (error) {
Expand All @@ -178,38 +105,29 @@ describe('Zod Validation', () => {
});

describe('Valibot Validation', () => {
it('should create zod resolve base on schema', () => {
try {
createResolver('Valibot', {});
} catch (error) {
expect(error).toMatchSnapshot();
}
});

it('should return true', () => {
it('should return true', async () => {
const schema = valibot.object({
username: valibot.string(),
});

const resolver = createResolver('Valibot', schema);
const isValid = resolver.validate({
const resolver = typeschemaResolver(schema);
const isValid = await resolver.validate({
username: 'jellydn',
});
expect(isValid).toBeTruthy();
});

it('should return false', () => {
it('should return false', async () => {
const schema = valibot.object({
age: valibot.number()
age: valibot.number(),
});
const resolver = createResolver('Valibot', schema);
const resolver = typeschemaResolver(schema);
try {
resolver.validate({
await resolver.validate({
age: '35',
});
} catch (error) {
expect(error).toMatchSnapshot();
}
});
});

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"trailingComma": "es5"
},
"dependencies": {
"type-fest": "4.10.3"
"@typeschema/main": "^0.13.7"
},
"devDependencies": {
"@size-limit/preset-small-lib": "11.0.2",
Expand All @@ -72,6 +72,10 @@
"@types/jest": "29.5.12",
"@types/react": "18.2.61",
"@types/react-dom": "18.2.19",
"@typeschema/joi": "^0.13.3",
"@typeschema/valibot": "^0.13.4",
"@typeschema/yup": "^0.13.3",
"@typeschema/zod": "^0.13.3",
"@typescript-eslint/eslint-plugin": "7.1.0",
"@typescript-eslint/parser": "7.1.0",
"@vitest/ui": "1.3.1",
Expand Down
Loading

0 comments on commit fce9b0b

Please sign in to comment.