Schema types
Schema package, have all types needed to describe a javascript object:
Properties
Schema package have 4 properties types, each one with it own built in validation rules:
- StringType
- NumberType
- BooleanType
- DateType
StringType
The code below creates a validation schema for a property of type string that should have a minLength of 5.
const schema = StringType().minLength(5);
let validation = await schema.check('abcde');
expect(validation.hasError).toBeFalsy();
expect(validation.isValid).toBeTruthy();
validation = await schema.check('abcd');
expect(validation.hasError).toBeTruthy();
expect(validation.isValid).toBeFalsy();
const [error] = validation.errors;
console.log(error.i18n); // ERRORS.STRING.MIN_LENGTH
Now let see what's happens if we add more than one validation. The string must have min length of 5, and must contains numbers.
Next code also show how to add a custom message to a validation rule.
And show what happens if we pass diferent type from what is expected.
const schema = StringType()
.minLength(5, 'CUSTOM_MESSAGE')
.containsNumber();
let validation = await schema.check('abc');
expect(validation.hasError).toBeTruthy();
const [minLengthError, containsNumberError] = validation.errors;
console.log(minLengthError.i18n); // CUSTOM_MESSAGE
console.log(containsNumberError.i18n); // ERRORS.STRING.CONTAINS_NUMBER
validation = await schema.check(55 as any);
expect(validation.hasError).toBeTruthy();
let [error] = validation.errors;
console.log(error.i18n); // ERRORS.STRING.INVALID_TYPE
validation = await schema.check('a5b');
expect(validation.hasError).toBeTruthy();
[error] = validation.errors;
console.log(error.i18n); // CUSTOM_MESSAGE
Note
The order in which validation rules are defined is the order they are executed, and the order in which they appers in the validation.errors
array.
Schema validation will not execute any validation rules if the value is empty (null or undefined) unless the property schema is marked as required.
const schema = StringType()
.minLength(5)
.containsNumber();
let validation = await schema.check(null);
expect(validation.hasError).toBeFalsy();
validation = await schema.check(undefined);
expect(validation.hasError).toBeFalsy();
const requiredSchema = StringType()
.minLength(5)
.isRequired()
.containsNumber();
validation = await requiredSchema.check(null);
expect(validation.hasError).toBeTruthy();
validation = await requiredSchema.check(undefined);
expect(validation.hasError).toBeTruthy();
expect(validation.errors.length).toBe(1);
const [error] = validation.errors;
console.log(error.i18n); // ERRORS.IS_REQUIRED
Note
The required rule is always the first to run. If an type is required, and that condition is not met, it will not execute next validation rules.
NumberType
The code below creates a validation schema for a property of type number
that should have a min value of 5.
const schema = NumberType().min(5);
let validation = await schema.check(5);
expect(validation.hasError).toBeFalsy();
expect(validation.isValid).toBeTruthy();
validation = await schema.check(4);
expect(validation.hasError).toBeTruthy();
expect(validation.isValid).toBeFalsy();
const [error] = validation.errors;
console.log(error.i18n); // ERRORS.NUMBER.MIN
Now let see what's happens if we add more than one validation. The number
must have min value of 5, and must be an integer.
Next code also show how to add a custom message to a validation rule.
And show what happens if we pass diferent type from what is expected.
const schema = NumberType()
.min(5, 'CUSTOM_MESSAGE')
.isInteger();
let validation = await schema.check(2.5);
expect(validation.hasError).toBeTruthy();
const [minError, isIntegerError] = validation.errors;
console.log(minError.i18n); // CUSTOM_MESSAGE
console.log(isIntegerError.i18n); // ERRORS.NUMBER.IS_INTEGER
validation = await schema.check('6' as any);
expect(validation.hasError).toBeTruthy();
let [error] = validation.errors;
console.log(error.i18n); // ERRORS.NUMBER.INVALID_TYPE
validation = await schema.check(4);
expect(validation.hasError).toBeTruthy();
[error] = validation.errors;
console.log(error.i18n); // CUSTOM_MESSAGE
Required vs non required property NumberType
const schema = NumberType()
.min(5)
.isInteger();
let validation = await schema.check(null);
expect(validation.hasError).toBeFalsy();
validation = await schema.check(undefined);
expect(validation.hasError).toBeFalsy();
const requiredSchema = NumberType()
.min(5)
.isInteger()
.isRequired();
validation = await requiredSchema.check(null);
expect(validation.hasError).toBeTruthy();
validation = await requiredSchema.check(undefined);
expect(validation.hasError).toBeTruthy();
expect(validation.errors.length).toBe(1);
const [error] = validation.errors;
console.log(error.i18n); // ERRORS.IS_REQUIRED
BooleanType
BooleanType do not have any built in validation besides isRequired and boolean
type validation.
const schema = BooleanType();
let validation = await schema.check(null);
expect(validation.hasError).toBeFalsy();
expect(validation.isValid).toBeTruthy();
const requiredSchema = BooleanType().isRequired();
validation = await requiredSchema.check(null);
expect(validation.hasError).toBeTruthy();
expect(validation.isValid).toBeFalsy();
validation = await requiredSchema.check(false);
expect(validation.hasError).toBeFalsy();
expect(validation.isValid).toBeTruthy();
validation = await requiredSchema.check('true' as any);
expect(validation.hasError).toBeTruthy();
expect(validation.isValid).toBeFalsy();
const [error] = validation.errors;
console.log(error.i18n); // ERRORS.BOOLEAN.INVALID_TYPE
DateType
DateType validation is a validation schema for new Date
object. It as some built in validation, but you can extend it and add more using date-fns
package.
const schema = DateType();
let validation = await schema.check(null);
expect(validation.hasError).toBeFalsy();
expect(validation.isValid).toBeTruthy();
const requiredSchema = DateType().isRequired();
validation = await requiredSchema.check(null);
expect(validation.hasError).toBeTruthy();
expect(validation.isValid).toBeFalsy();
// Can be a valid iso string
validation = await requiredSchema.check('2022-01-01');
expect(validation.hasError).toBeFalsy();
expect(validation.isValid).toBeTruthy();
validation = await requiredSchema.check('true' as any);
expect(validation.hasError).toBeTruthy();
expect(validation.isValid).toBeFalsy();
const [error] = validation.errors;
console.log(error.i18n); //ERRORS.DATE.INVALID_TYPE
Note
DateType property can be a Date
object, a valid ISO date string
, or a number
. Any valid value we can pass to the constructor new Date()