UNPKG

react-formawesome-core

Version:
237 lines (194 loc) 7.13 kB
# Validators There are two ways to define validation rules: - with `ModelValidator`, wich use decorators - with `SchemaValidator`, wich use plain object Both of them extends `AbstractValidator`, that provides common interface. ## AbstractValidator ### Public interface Class require to implement two methods: - Getter for name of model/schema ```ts public get modelName(): string; ``` - Validate method ```ts public validate: async (groups?: Array<string>) => Promise<void> ``` And provide implemented methods: - List of attributes of provided model/schema ```ts public get modelAttributes(): Array<string> ``` - Object with attribte name: value ```ts public get modelValues(): {[key: string]: string | boolean | number} ``` - Object with attribute name: error description ```ts public get modelErrors(): {[key: string]: string} ``` - Method for setting model value ```ts public setModelValue: (attribute: string, value: string | boolean | number) => void; ``` - Method for setting default values ```ts public setDefaults: (defaults: {[key: string]: string | boolean | number}) => void; ``` - Method for rolling back to settled defaults ```ts public dropToDefaults: () => void; ``` - Method for clear all values ```ts public clear: () => void; ``` - Method for manual adding errors ```ts public addErrors: (errors: errors: Array<{ attribute: string, details: string }>) => void; ``` ### Internal interface Class have two protected containers: - Container for errors ```ts protected modelErrorsContainer: Map<string, Array<{ attribute: string, details: string }>> ``` - Container of model/schema ```ts protected modelContainer: { instance: {[key: string]: string | boolean | number}; defaults: {[key: string]: string | boolean | number}; } ``` `INSTANCE` - object or class that describe attributes and rules. *`ALL ATTRIBUTES SHOULD BE INITIALIZED, EVEN WITH UNDEFINED VALUE!`* #### WRONG: ```ts class SomeModel { public someField: string; } ``` #### RIGHT: ```ts class SomeModel { public someField: string = undefined; // or null, string, number, boolean. } ``` `ERRORS CONTAINER` - "Map" instance, that contains failed results of validation. Key of "Map" is group name, value is array of attributes and error decription. Class provide `handleErrors` helper for handling errors: ```ts protected handleErrors: (errors, groups) => void; ``` - `errors` - array of errors, that generated by `ClassValidator.validate` method. - `groups` - array of groups So, correct usage will be: ```ts public validate = async (groups?: Array<string>): Promise<void> => { const errors = await ClassValidator.validate(/*SOME_ARGUMENTS*/); this.handleErrors(errors, groups); } ``` For correct work of validator, there should be created correct instance and defaults. All public method depends on two internal methods. ## ModelValidator ```ts import * as ClassValidator from "class-validator" import { ModelValidator } from "react-formawesome-core"; class UserModel { @ClassValidator.MinLength(4, { groups: ["name", "personal"] }) public name: string = undefined; @ClassValidator.MinLength(4, { groups: ["surname", "personal"] }) public surname: string = undefined; @ClassValidator.IsNumberString( { groups: ["address"] }) public address: string = undefined; } // Create instance and provide model class and defaults const validator = new ModelValidator(UserModel, { name: "John", surname: "-", address: "LA" }); ``` ## SchemaValidator ```ts import { SchemaValidator } from "react-formawesome-core"; const UserSchema = { name: "UserSchema", properties: { name: [ { type: "minLength", constraints: [4], groups: ["name", "personal"] } ], surname: [ { type: "minLength", constraints: [4], groups: ["surname", "personal"] } ], address: [ { type: "isNumberString", groups: ["address"] } ] } }; // Create instance and provide schema and defaults const validator = new SchemaValidator(UserSchema, { name: "John", surname: "-", address: "LA" }); ``` ## Error cases ```ts // For both of validators validator.setDefaults({}) // Throw error: defaults is an empty object validator.setDefaults("") // Throw error: defaults is not an object validator.setDefaults(() => undefined) // Throw error: defaults is not an object validator.setModelValue(/*Not string value*/, false) // Throw error: attribute is not a string validator.setModelValue("unexpectedAttribute", false) // Throw error: attribute is not exist in model/schema validator.setModelValue("name", {}) // Throw error: value is not a string validator.setModelValue("name", () => undefined) // Throw error: value is not a string validator.addErrors(/*Not array value*/) // Throw error: error is not an array validator.addErrors([{attribute: /*Not string value*/}]) // Throw error: attribute is not a string validator.addErrors([{attribute: "unexpectedAttribute"}]) // Throw error: attribute is not exist in model/schema validator.addErrors([{attribute: "name", details: /*Not string value*/}]) // Throw error: details is not a string (async () => { await validator.validate(["not defined group"]) // Throw error: Group does not defined in model/schema })(); // For ModelValidator new ModelValidator({}) // Throw error: Model is not a function new ModelValidator("") // Throw error: Model is not a function new ModelValidator(CorrectModel, "") // Throw error: defaults is not an object new ModelValidator(CorrectModel, {}) // Throw error: defaults is empty new ModelValidator(CorrectModel, { nonExistField: "" }) // Throw error: nonExistField does not exist in Model // For SchemaValidator new SchemaValidator({}) // Throw error: name is undefined new SchemaValidator({name: /*Non string value*/}) // Throw error: name is not a string new SchemaValidator({name: "Ok"}) // Throw error: properties is undefined new SchemaValidator({name: "Ok", properties: /*Non object*/}) // Throw error: properties is not an object new SchemaValidator(CorrectSchema, "") // Throw error: defaults is not an object new SchemaValidator(CorrectSchema, {}) // Throw error: defaults is empty new SchemaValidator(CorrectSchema, { nonExistField: "" }) // Throw error: nonExistField does not exist in Schema ``` ### Validator config Allow configure the validator behavior ```ts { skipAttributeCheck?: boolean; // do not throw error when passed attribute does not exist in the model/schema } ``` ```ts new SchemaValidator(CorrectSchema, undefined, { skipAttributeCheck: true }); new ModelValidator(CorrectModel, undefined, { skipAttributeCheck: true }); ```