⭕ Validax ⭕
A clean way to validate JSON schema in Typescript
Bookmark
- Bookmark
- What is validax
- Installation
- Validax
- ConstraintBuilder
- CustomConstraint
- validateOptions
- Common issues
What is validax
A clean way to validate JSON schema in Typescript
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
npm install validax
Validax
assert
Validax.assert(input, schema[, validateOptions])
->asserts input is schema
assert input data match schema
reference: validateOptions
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 schema
reference: validateOptions
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
import { ValidaxSchema, ConstraintBuilder } from 'validax';
@ValidaxSchema()
class Person {
@ConstraintBuilder.String().Decorator()
name!: string;
}
options
Optional
Type: StringConstraintOptions
type StringConstraintOptions = {
allowNull?: boolean,
allowUndefined?: boolean,
maxLength?: number,
minLength?: number,
regex?: RegExp,
}
Number
ConstraintBuilder.Number(options)
->CustomConstraint
return a CustomConstraint to validate number value
import { ValidaxSchema, ConstraintBuilder } from 'validax';
@ValidaxSchema()
class Person {
@ConstraintBuilder.Number({ isInteger: true }).Decorator()
id!: number;
}
options
Optional
Type: NumberConstraintOptions
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
import { ValidaxSchema, ConstraintBuilder } from 'validax';
@ValidaxSchema()
class Person {
@ConstraintBuilder.Boolean().Decorator()
isVerifiedEmail!: boolean;
}
options
Optional
Type: BooleanConstraintOptions
type BooleanConstraintOptions = {
allowNull?: boolean,
allowUndefined?: boolean,
}
Class
ConstraintBuilder.Class(schema, options)
->CustomConstraint
return a CustomConstraint to validate object
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
type ClassConstraintOptions = {
allowNull?: boolean,
allowUndefined?: boolean,
}
CustomError
ConstraintBuilder.CustomError(constraint, error)
->CustomConstraint
return a CustomConstraint throw a custom error when validate property failed
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 ( || )
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 ( && )
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
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
import { ValidaxSchema, ConstraintBuilder } from 'validax';
@ValidaxSchema()
class Person {
@ConstraintBuilder.ArrayOf(ConstraintBuilder.Number()).Decorator()
id!: number[];
}
options
Optional
Type: ArrayOfConstraintOptions
type ArrayOfConstraintOptions = {
allowNull?: boolean,
allowUndefined?: boolean,
maxLength?: number,
minLength?: number,
}
Tuple
ConstraintBuilder.Tuple(constraints, options)
->CustomConstraint
return a CustomConstraint that check tuple value
import { ValidaxSchema, ConstraintBuilder } from 'validax';
@ValidaxSchema()
class Person {
@ConstraintBuilder.Tuple([
ConstraintBuilder.Number(),
ConstraintBuilder.String(),
]).Decorator()
id!: [number, string];
}
options
Optional
Type: TupleConstraintOptions
type TupleConstraintOptions = {
allowNull?: boolean,
allowUndefined?: boolean,
allowExtraDataLength?: boolean,
}
CustomConstraint
new CustomConstraint(assertFunction)
->CustomConstraint
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
/**
* 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
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
"emitDecoratorMetadata": true, "experimentalDecorators": true,
2. How to validate a nested object
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; }
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; }; }