Skip to content

Commit

Permalink
Merge branch 'master' of github.com:akibrk/ts-validator
Browse files Browse the repository at this point in the history
  • Loading branch information
akibrk committed Apr 4, 2023
2 parents 3d198bb + 0fe0d2e commit bdb6228
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 48 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## Change Log


### 7/14/2022 Version 2.2.1

- Fix array validation

### 27/2022 Version 2.2.0

- Fix interface import
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class CaseClass {

---

### 3. Class Model
### 3. Class Model/ Interface

```ts
import { Validator } from '@akibrk/validator';
Expand All @@ -96,6 +96,13 @@ class Login {
public password: string = '';
}

// Or

interface ILogin {
email: string;
password: string;
}

const loginValidator = new Validator<Login>({
email: {
type: Type.string,
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@akibrk/validator",
"version": "2.2.1",
"version": "2.2.2",
"description": "Lightweight validation library for typescript",
"main": "dist/index.js",
"bin": "dist/index.js",
Expand Down
42 changes: 40 additions & 2 deletions src/spec/classValidator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,56 @@ describe('Class Validator', () => {
},
});

interface Product {
name: string;
tags: string[];
}

const productValidator = new Validator<Product>({
name: {
type: Type.string,
required: true,
},
tags: {
type: Type.array,
required: true,
maxLength: 2,
minLength: 1,
},
});

const A_PRODUCT: Product = {
name: 'krisiponno',
tags: ['agriculture', 'food'],
};

const B_PRODUCT: Product = {
name: 'krisiponno',
tags: ['agriculture', 'food', 'delivery'],
};

it('Checks missing properties', () => {
expect(loginValidator.isValid({})).toBeFalsy();
expect(loginValidator.isValid({ email: 'akib' })).toBeFalsy();
});

it('Has no error', () => {
it('Valid login model', () => {
expect(loginValidator.validate({ email: 'akib', password: 'test' }).length).toBe(0);
expect(loginValidator.isValid({ email: 'akib', password: 'test' })).toBeTruthy();
});

it('Has one error', () => {
it('Login has one error', () => {
expect(loginValidator.validate({ email: 'akib', password: null }).length).toBe(1);
expect(loginValidator.isValid({ email: 'akib', password: null })).toBeFalsy();
});

it('Product has array of tags', () => {
expect(productValidator.validate(A_PRODUCT).length).toBe(0);
expect(productValidator.isValid(A_PRODUCT)).toBeTruthy();
});

it('Product has more than max tags', () => {
expect(productValidator.validate(B_PRODUCT).length).toBe(1);
expect(productValidator.isValid(B_PRODUCT)).toBeFalsy();
});
});
2 changes: 1 addition & 1 deletion src/validator/ClassValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class Validator<T> {

for (let prop in this.rules) {
const propError = validateRule(payload[prop], prop, this.rules[prop]);
if (propError && propError.errors.length) {
if (propError) {
errors.push(propError);
}
}
Expand Down
111 changes: 71 additions & 40 deletions src/validator/Shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,16 @@ export function validateRule(obj: any, propName: string, rule: ValidationRule):
let vError: ValidationError = new VError(propName);

// If there isn't a rule defined for the property ignore it
if (!rule) {
return rule;
}

if (rule.allowNull) {
if (!rule || rule.allowNull) {
return undefined;
}

if (rule.required) {
if (typeof obj === undefined || typeof obj === null) {
if (!obj || typeof obj === 'undefined') {
vError.errors.push({
message: `Field is required, missing field: ${propName}`,
});
return vError;
}
}

Expand Down Expand Up @@ -59,7 +56,6 @@ export function validateRule(obj: any, propName: string, rule: ValidationRule):
}
}
break;

case Type.mobile:
if (typeof obj !== Type.string) {
vError.errors.push({
Expand Down Expand Up @@ -89,49 +85,84 @@ export function validateRule(obj: any, propName: string, rule: ValidationRule):
}
}
break;
default:
case Type.array:
if (typeof obj !== 'object') {
vError.errors.push({
message: `Invalid type, expected ${rule.type} got ${obj === null ? 'null' : typeof obj}`,
});
}
if (rule.minLength) {
if (obj.length < rule.minLength) {
vError.errors.push({
message: `Invalid '${propName}', must be equal or longer than ${rule.minLength}`,
});
}
}

if (rule.maxLength) {
if (obj.length > rule.maxLength) {
vError.errors.push({
message: `Invalid '${propName}', must be equal or shorter than ${rule.maxLength}`,
});
}
}
break;
case Type.string:
if (rule.type !== typeof obj) {
vError.errors.push({
message: `Invalid type, expected ${rule.type} got ${obj === null ? 'null' : typeof obj}`,
});
} else {
if (rule.type === Type.string) {
if (rule.minLength) {
if (obj.length < rule.minLength) {
vError.errors.push({
message: `Invalid '${propName}', must be equal or longer than ${rule.minLength}`,
});
}
}
break;
}

if (rule.maxLength) {
if (obj.length > rule.maxLength) {
vError.errors.push({
message: `Invalid '${propName}', must be equal or shorter than ${rule.maxLength}`,
});
}
}
} else if (rule.type === Type.number) {
if (rule.min) {
if (obj < rule.min) {
vError.errors.push({
message: `Invalid '${propName}', must be equal or larger than ${rule.min}`,
});
}
}
if (rule.minLength) {
if (obj.length < rule.minLength) {
vError.errors.push({
message: `Invalid '${propName}', must be equal or longer than ${rule.minLength}`,
});
}
}

if (rule.max) {
if (obj > rule.max) {
vError.errors.push({
message: `Invalid '${propName}', must be equal or less than ${rule.max}`,
});
}
}
if (rule.maxLength) {
if (obj.length > rule.maxLength) {
vError.errors.push({
message: `Invalid '${propName}', must be equal or shorter than ${rule.maxLength}`,
});
}
}
break;
case Type.number:
if (rule.type !== typeof obj) {
vError.errors.push({
message: `Invalid type, expected ${rule.type} got ${obj === null ? 'null' : typeof obj}`,
});
break;
}
if (rule.min) {
if (obj < rule.min) {
vError.errors.push({
message: `Invalid '${propName}', must be equal or larger than ${rule.min}`,
});
}
}

if (rule.max) {
if (obj > rule.max) {
vError.errors.push({
message: `Invalid '${propName}', must be equal or less than ${rule.max}`,
});
}
}
break;
default:
if (rule.type !== typeof obj) {
vError.errors.push({
message: `Invalid type, expected ${rule.type} got ${obj === null ? 'null' : typeof obj}`,
});
}
}

return vError;
return vError.errors.length ? vError : undefined;
}

import { ValidationResult } from 'types';
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@
"experimentalDecorators": true
},
"exclude": [

"dist"
]
}

0 comments on commit bdb6228

Please sign in to comment.