Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/a179346/validax
A clean way to validate JSON schema in Typescript
https://github.com/a179346/validax
json-schema json-schema-validator nodejs npm npm-package typescript validator
Last synced: 9 days ago
JSON representation
A clean way to validate JSON schema in Typescript
- Host: GitHub
- URL: https://github.com/a179346/validax
- Owner: a179346
- License: mit
- Created: 2021-05-14T00:40:08.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2022-12-26T21:07:23.000Z (almost 2 years ago)
- Last Synced: 2024-10-13T21:52:01.798Z (23 days ago)
- Topics: json-schema, json-schema-validator, nodejs, npm, npm-package, typescript, validator
- Language: TypeScript
- Homepage:
- Size: 161 KB
- Stars: 4
- Watchers: 2
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
> A clean way to validate JSON schema in Typescript
# Bookmark
- [Bookmark](#bookmark)
- [What is validax](#what-is-validax)
- [Installation](#installation)
- [Validax](#validax)
- [assert](#assert)
- [validate](#validate)
- [ConstraintBuilder](#constraintbuilder)
- [String](#string)
- [Number](#number)
- [Boolean](#boolean)
- [Class](#class)
- [CustomError](#customerror)
- [inParallel](#inparallel)
- [inSeries](#inseries)
- [isOneOf](#isoneof)
- [ArrayOf](#arrayof)
- [Tuple](#tuple)
- [CustomConstraint](#customconstraint)
- [validateOptions](#validateoptions)
- [Common issues](#common-issues)
- [1. Experimental support for decorators is a feature that is subject to change in a future release.](#1-experimental-support-for-decorators-is-a-feature-that-is-subject-to-change-in-a-future-release)
- [2. How to validate a nested object](#2-how-to-validate-a-nested-object)
# What is validax
A clean way to validate JSON schema in Typescript```ts
import { Validax, ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.Number().Decorator()
id!: number;
@ConstraintBuilder.String().Decorator()
name!: string;
}function userInput (input: any) {
Validax.assert(input, Person);
// input is Person here ...
}userInput({
id: 123,
name: 'John',
});
```# Installation
```bash
npm install validax
```# Validax
## assert> `Validax.assert(input, schema[, validateOptions])` -> `asserts input is schema`
assert input data match schemareference: [validateOptions](#validateoptions)
```ts
import { Validax, ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.String().Decorator()
name!: string;
}function userInput (input: any) {
try {
Validax.assert(input, Person);
// input is Person here ...
} catch (error) {
// input is not Person
}
}
```
## validate> `Validax.validate(input, schema[, validateOptions])` -> `input is schema`
validate input data is schemareference: [validateOptions](#validateoptions)
```ts
import { Validax, ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.String().Decorator()
name!: string;
}function userInput (input: any) {
if (Validax.validate(input, Person)) {
// input is Person here ...
}
}
```# ConstraintBuilder
## String> `ConstraintBuilder.String(options)` -> `CustomConstraint`
return a CustomConstraint to validate string value
```ts
import { ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.String().Decorator()
name!: string;
}
```
options
*Optional*
Type: `StringConstraintOptions`
```ts
type StringConstraintOptions = {
allowNull?: boolean,
allowUndefined?: boolean,
maxLength?: number,
minLength?: number,
regex?: RegExp,
}
```
## Number> `ConstraintBuilder.Number(options)` -> `CustomConstraint`
return a CustomConstraint to validate number value
```ts
import { ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.Number({ isInteger: true }).Decorator()
id!: number;
}
```
options
*Optional*
Type: `NumberConstraintOptions`
```ts
type NumberConstraintOptions = {
allowNull?: boolean,
allowUndefined?: boolean,
allowNaN?: boolean,
isFinite?: boolean,
isInteger?: boolean,
max?: number,
min?: number,
}
```
## Boolean> `ConstraintBuilder.Boolean(options)` -> `CustomConstraint`
return a CustomConstraint to validate boolean value
```ts
import { ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.Boolean().Decorator()
isVerifiedEmail!: boolean;
}
```
options
*Optional*
Type: `BooleanConstraintOptions`
```ts
type BooleanConstraintOptions = {
allowNull?: boolean,
allowUndefined?: boolean,
}
```
## Class> `ConstraintBuilder.Class(schema, options)` -> `CustomConstraint`
return a CustomConstraint to validate object
```ts
import { ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.String().Decorator()
name!: string;@ConstraintBuilder.Class(Person, { allowNull: true }).Decorator()
father: Person | null;
}
```
options
*Optional*
Type: `ClassConstraintOptions`
```ts
type ClassConstraintOptions = {
allowNull?: boolean,
allowUndefined?: boolean,
}
```
## CustomError> `ConstraintBuilder.CustomError(constraint, error)` -> `CustomConstraint`
return a CustomConstraint throw a custom error when validate property failed
```ts
import { ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.CustomError(
ConstraintBuilder.String(),
new Error('name is invalid.')
).Decorator()
name!: string;
}
```
## inParallel> `ConstraintBuilder.inParallel(constraints, error)` -> `CustomConstraint`
return a CustomConstraint with constraints
should pass one of the constraints ( || )
```ts
import { ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.inParallel([
ConstraintBuilder.String(),
ConstraintBuilder.Number()
], new Error('id is invalid.')).Decorator()
id!: string | number;
}
```
## inSeries> `ConstraintBuilder.inSeries(constraints)` -> `CustomConstraint`
return a CustomConstraint with constraints
should pass all constraints ( && )
```ts
import { ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.inSeries([
ConstraintBuilder.isOneOf([ 1, 2, 3 ], new Error('id is invalid')),
ConstraintBuilder.isOneOf([ 2, 3, 4 ], new Error('id is invalid')),
]).Decorator()
id!: 2 | 3;
}
```
## isOneOf> `ConstraintBuilder.isOneOf(availableVals, error)` -> `CustomConstraint`
return a CustomConstraint that check property is one of the available values
```ts
import { ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.isOneOf([ 1, 2, 3 ], new Error('id is invalid')).Decorator()
id!: 1 | 2 | 3;
}
```
## ArrayOf> `ConstraintBuilder.ArrayOf(constraint, options)` -> `CustomConstraint`
return a CustomConstraint that check property is an array of specific type
```ts
import { ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.ArrayOf(ConstraintBuilder.Number()).Decorator()
id!: number[];
}
```
options
*Optional*
Type: `ArrayOfConstraintOptions`
```ts
type ArrayOfConstraintOptions = {
allowNull?: boolean,
allowUndefined?: boolean,
maxLength?: number,
minLength?: number,
}
```
## Tuple> `ConstraintBuilder.Tuple(constraints, options)` -> `CustomConstraint`
return a CustomConstraint that check tuple value
```ts
import { ValidaxSchema, ConstraintBuilder } from 'validax';@ValidaxSchema()
class Person {
@ConstraintBuilder.Tuple([
ConstraintBuilder.Number(),
ConstraintBuilder.String(),
]).Decorator()
id!: [number, string];
}
```
options
*Optional*
Type: `TupleConstraintOptions`
```ts
type TupleConstraintOptions = {
allowNull?: boolean,
allowUndefined?: boolean,
allowExtraDataLength?: boolean,
}
```
# CustomConstraint> `new CustomConstraint(assertFunction)` -> `CustomConstraint`
```ts
import { ValidaxSchema, CustomConstraint } from 'validax';@ValidaxSchema()
class Person {
@new CustomConstraint((val) => {
if (!val || typeof val !== 'object')
throw new Error('foo is not an object');
if (typeof val.bar !== 'string')
throw new Error('foo.bar is not a string');
if (typeof val.bar2 !== 'number')
throw new Error('foo.bar2 is not a number');
}).Decorator()
foo!: {
bar: string;
bar2: number;
};
}
```
assertFunction
*Required*
Type: `AssertFunction`
```ts
/**
* return void when type check is pass
* throw error when type check is failed
*/
type AssertFunction = (val: any, className: string, propNames: string[], validateOptions?: validateOptions)=> void | never
```# validateOptions
```ts
interface validateOptions {
// not allow other keys in object if true
strict?: boolean;
}
```# Common issues
### 1. Experimental support for decorators is a feature that is subject to change in a future release.
> In `tsconfig.json`
> ```ts
> "emitDecoratorMetadata": true,
> "experimentalDecorators": true,
> ```### 2. How to validate a nested object
> [(1) ConstraintBuilder.Class](#class)
> ```ts
> import { ValidaxSchema, ConstraintBuilder } from 'validax';
>
> @ValidaxSchema()
> class Foo {
> @ConstraintBuilder.String().Decorator()
> bar!: string;
> @ConstraintBuilder.Number().Decorator()
> bar2!: number;
> }
>
> @ValidaxSchema()
> class Person {
> @ConstraintBuilder.Class(Foo).Decorator()
> foo!: Foo;
> }
> ```> [(2) CustomConstraint](#customconstraint)
> ```ts
> import { ValidaxSchema, CustomConstraint } from 'validax';
>
> @ValidaxSchema()
> class Person {
> @new CustomConstraint((val) => {
> if (!val || typeof val !== 'object')
> throw new Error('foo is not an object');
> if (typeof val.bar !== 'string')
> throw new Error('foo.bar is not a string');
> if (typeof val.bar2 !== 'number')
> throw new Error('foo.bar2 is not a number');
> }).Decorator()
> foo!: {
> bar: string;
> bar2: number;
> };
> }
> ```