Object schema type
Schema package have a Object schema type, to validate object structures.
Object have properties, and properties can be of any type, including ObjectType
.
ObjectType
The code below creates a validation schema for a User
class object.
class User {
name: string;
age: number;
email: string;
constructor(data?: Partial<User>) {
Object.assign(this, data);
}
}
const schema = ObjectType<User>({
name: StringType().isRequired(),
age: NumberType().min(18),
email: StringType().isEmail()
});
let validation = await schema.check(
new User({
name: 'Sublime',
age: 19,
email: 'schema@websublime.com'
})
);
expect(validation.isValid).toBeTruthy();
expect(validation.hasError).toBeFalsy();
expect(validation.properties.age.hasError).toBeFalsy();
expect(validation.properties.age.isValid).toBeTruthy();
expect(validation.properties.email.hasError).toBeFalsy();
expect(validation.properties.email.isValid).toBeTruthy();
Example of an invalid model.
class User {
name: string;
age: number;
email: string;
constructor(data?: Partial<User>) {
Object.assign(this, data);
}
}
const schema = ObjectType<User>({
name: StringType().isRequired(),
age: NumberType().min(18),
email: StringType().isEmail()
});
let validation = await schema.check(
new User({
name: 'Kid',
age: 9,
email: 'I do not have email yet'
})
);
expect(validation.isValid).toBeFalsy();
expect(validation.hasError).toBeFalsy(); // the errors are at property level
expect(validation.properties.age.hasError).toBeTruthy();
const [ageError] = validation.properties.age.errors;
console.log(ageError.i18n); // ERRORS.NUMBER.MIN
console.log(ageError.key); // age
expect(validation.properties.email.hasError).toBeTruthy();
const [emailError] = validation.properties.email.errors;
console.log(emailError.i18n); // ERRORS.STRING.IS_EMAIL
console.log(emailError.key); // email
Nested object.
Example of a nested object validation.
class Profile {
age: number;
weight?: number;
height: number;
constructor(data?: Partial<Profile>) {
Object.assign(this, data);
}
}
class User {
name: string;
email: string;
profile: Profile;
constructor(data?: Partial<User>) {
Object.assign(this, data);
const { profile = null } = data || {};
this.profile = new Profile(profile);
}
}
const schema = ObjectType<User>({
name: StringType().isRequired(),
email: StringType().isEmail(),
profile: ObjectType<Profile>({
age: NumberType()
.min(18)
.isRequired(),
height: NumberType(),
weight: NumberType()
.isRequired()
.max(120)
}).isRequired()
});
let validation = await schema.check(
new User({
name: 'Sublime',
email: 'schema@websublime.com',
profile: {
age: 22,
height: 175,
weight: 75
}
})
);
expect(validation.isValid).toBeTruthy();
expect(validation.hasError).toBeFalsy(); // the errors are at property level
Let's see the validation object in case of an error.
// ...
validation = await schema.check(
new User({
email: 'schema@websublime.com',
profile: {
age: 22,
height: 175,
weight: 125
}
})
);
console.log(JSON.stringify(validation, null, 4));
JSON ouput of the validation object:
{
"errors": [],
"hasError": false,
"isValid": false,
"properties": {
"name": {
"errors": [
{
"key": "name", // key in the context of the object
"constraints": null,
"value": null,
"i18n": "ERRORS.IS_REQUIRED"
}
],
"hasError": true,
"isValid": false
},
"email": {
"errors": [],
"hasError": false,
"isValid": true
},
"profile": {
"errors": [],
"hasError": false, // Object Profile don't hold errors.
"isValid": false, // Object Profile not valid.
"properties": {
"age": {
"errors": [],
"hasError": false,
"isValid": true
},
"height": {
"errors": [],
"hasError": false,
"isValid": true
},
"weight": {
"errors": [
{
"key": "weight",
"constraints": {
"max": 120 // Error model have a constraint
}, // object showing the validation contraint.
"value": 125,
"i18n": "ERRORS.NUMBER.MAX"
}
],
"hasError": true,
"isValid": false
}
}
}
}
}