From e5b0cace2a49f05e1883dfa7278e49a5862c559c Mon Sep 17 00:00:00 2001 From: David Valin Date: Mon, 3 Apr 2023 14:27:42 +0200 Subject: [PATCH] [x] Avoid validate() to fail when there are no validation rules defined [x] Add generics to validation rules [x] Export and document validation rules parameters [x] Add some comments to validation rules for clarification --- src/howerest.sdkzer.ts | 22 ++++++++--- src/validation_rule.ts | 4 +- .../allowed_value_switch_validator.ts | 39 +++++++++++-------- src/validation_rules/email_validator.ts | 2 +- src/validation_rules/length_validator.ts | 15 ++++--- src/validation_rules/number_validator.ts | 15 ++++--- src/validation_rules/reg_exp_validator.ts | 10 +++-- 7 files changed, 68 insertions(+), 39 deletions(-) diff --git a/src/howerest.sdkzer.ts b/src/howerest.sdkzer.ts index 4dbd877..b233cc2 100644 --- a/src/howerest.sdkzer.ts +++ b/src/howerest.sdkzer.ts @@ -104,7 +104,7 @@ export class Sdkzer { // Reset previous invalid messages from previous validations this.invalidMessages = {}; let toValidateAttr, validationRule; - const toValidateAttrs = Object.keys(this.validationRules); + const toValidateAttrs = Object.keys(this.validationRules || {}); // Validate attribute's ValidationRules for(toValidateAttr of toValidateAttrs) { @@ -572,8 +572,20 @@ export interface ISdkzerConfigOptions { export { ValidationRule } from "./validation_rule"; export { RequiredValidator } from "./validation_rules/required_validator" -export { RegExpValidator } from "./validation_rules/reg_exp_validator" -export { NumberValidator } from "./validation_rules/number_validator" -export { LengthValidator } from "./validation_rules/length_validator" +export { + RegExpValidator, + IParams as IRegExpValidatorParams +} from "./validation_rules/reg_exp_validator" +export { + NumberValidator, + IParams as INumberValidatorParams +} from "./validation_rules/number_validator" +export { + LengthValidator, + IParams as ILengthValidatorParams +} from "./validation_rules/length_validator" export { EmailValidator } from "./validation_rules/email_validator" -export { AllowedValueSwitchValidator } from "./validation_rules/allowed_value_switch_validator" +export { + AllowedValueSwitchValidator, + IParams as IAllowedValueSwitchValidatorParams +} from "./validation_rules/allowed_value_switch_validator" diff --git a/src/validation_rule.ts b/src/validation_rule.ts index 8a8968c..23b0cb7 100644 --- a/src/validation_rule.ts +++ b/src/validation_rule.ts @@ -9,11 +9,11 @@ --------------------------------------------------------------------------- */ -export class ValidationRule implements IValidationRule { +export class ValidationRule implements IValidationRule { protected conditions: Array = []; public fromValue:any; public toValue:any - public params:object + public params: IParams private _invalidMessage = "Invalid"; constructor(params?:any) { diff --git a/src/validation_rules/allowed_value_switch_validator.ts b/src/validation_rules/allowed_value_switch_validator.ts index 30c7b83..7e0f1fd 100644 --- a/src/validation_rules/allowed_value_switch_validator.ts +++ b/src/validation_rules/allowed_value_switch_validator.ts @@ -1,30 +1,37 @@ import {ValidationRule} from '../validation_rule' -export class AllowedValueSwitchValidator extends ValidationRule { - // Sample declaration of allowed transition: +export interface IParams { + allowed: Array<{ + from: string; + to: any[]; + }> +} + +export class AllowedValueSwitchValidator extends ValidationRule { + // Sample declaration of allowed transition: - // { - // allowed: [ - // { from: "open", to: ["scheduled", "canceled", "closed"] }, - // { from: "close", to: ["open"] } - // ] - // } + // { + // allowed: [ + // { from: "open", to: ["scheduled", "canceled", "closed"] }, + // { from: "close", to: ["open"] } + // ] + // } protected conditions:Array = [ () => { let match:boolean = false, rule; - if (this.params && this.params['allowed'] && this.params['allowed'].length) { - for (let i = 0; i < this.params['allowed'].length; i++) { - rule = this.params['allowed'][i]; - if (rule['from'] && rule['to'] && rule['to'].length) { + if (this.params && this.params.allowed && this.params.allowed.length) { + for (let i = 0; i < this.params.allowed.length; i++) { + rule = this.params.allowed[i]; + if (rule.from && rule.to && rule.to.length) { // Origin value matched - if (rule['from'] === this.fromValue) { + if (rule.from === this.fromValue) { // Check that the destination value also allowed - for (let i2 = 0; i2 < rule['to'].length; i2++) { + for (let i2 = 0; i2 < rule.to.length; i2++) { if (!match) { - if (this.toValue === rule['to'][i2]) { + if (this.toValue === rule.to[i2]) { match = true; } } @@ -34,7 +41,7 @@ export class AllowedValueSwitchValidator extends ValidationRule { } } if (!match) { - this.addInvalidMessage(this.fromValue + " cannot change to '" + this.toValue + "'"); + this.addInvalidMessage(`${this.fromValue} cannot change to '${this.toValue}'`); } return match; diff --git a/src/validation_rules/email_validator.ts b/src/validation_rules/email_validator.ts index 550f27d..87939d0 100644 --- a/src/validation_rules/email_validator.ts +++ b/src/validation_rules/email_validator.ts @@ -8,7 +8,7 @@ export class EmailValidator extends ValidationRule { let match:boolean = true; const regExpValidator = new RegExpValidator({ rule: /^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i }); if (!regExpValidator.isValid(this.fromValue, this.toValue)) { - this.addInvalidMessage(this.toValue + ' is not a valid email address'); + this.addInvalidMessage(`${this.toValue} is not a valid email address`); match = false; } return match; diff --git a/src/validation_rules/length_validator.ts b/src/validation_rules/length_validator.ts index ef90de4..42ebbed 100644 --- a/src/validation_rules/length_validator.ts +++ b/src/validation_rules/length_validator.ts @@ -1,19 +1,22 @@ import {ValidationRule} from '../validation_rule' -interface LengthValidatorParams { min: number, max: number } +export interface IParams { + min: number; // min number of items in the array + max: number; // max number of items in the array +} -export class LengthValidator extends ValidationRule { +export class LengthValidator extends ValidationRule { protected conditions:Array = [ () => { let match:boolean = true; - if (this.toValue.length < this.params['min']) { + if (this.toValue.length < this.params.min) { match = false; - this.addInvalidMessage(`${this.toValue} contains less than ${this.params['min']} items`); + this.addInvalidMessage(`${this.toValue} contains less than ${this.params.min} items`); } - if (this.toValue.length > this.params['max']) { + if (this.toValue.length > this.params.max) { match = false; - this.addInvalidMessage(`${this.toValue} contains more than ${this.params['max']} items`); + this.addInvalidMessage(`${this.toValue} contains more than ${this.params.max} items`); } return match; diff --git a/src/validation_rules/number_validator.ts b/src/validation_rules/number_validator.ts index a0d5a13..92b4343 100644 --- a/src/validation_rules/number_validator.ts +++ b/src/validation_rules/number_validator.ts @@ -1,19 +1,22 @@ import {ValidationRule} from '../validation_rule' -interface NumberValidatorParams { min: number, max: number } +export interface IParams { + min: number; // min number value allowed + max: number; // max number value allowed +} -export class NumberValidator extends ValidationRule { +export class NumberValidator extends ValidationRule { protected conditions:Array = [ () => { let match:boolean = true; - if (this.toValue < this.params['min']) { + if (this.toValue < this.params.min) { match = false; - this.addInvalidMessage(this.toValue + " is smaller than " + this.params['min']); + this.addInvalidMessage(`${this.toValue} is smaller than ${this.params.min}`); } - if (this.toValue > this.params['max']) { + if (this.toValue > this.params.max) { match = false; - this.addInvalidMessage(this.toValue + " is bigger than " + this.params['max']); + this.addInvalidMessage(`${this.toValue} is bigger than ${this.params.max}`); } return match; diff --git a/src/validation_rules/reg_exp_validator.ts b/src/validation_rules/reg_exp_validator.ts index 776a919..f36102b 100644 --- a/src/validation_rules/reg_exp_validator.ts +++ b/src/validation_rules/reg_exp_validator.ts @@ -1,12 +1,16 @@ import {ValidationRule} from '../validation_rule' -export class RegExpValidator extends ValidationRule { +export interface IParams { + rule: RegExp +} + +export class RegExpValidator extends ValidationRule { protected conditions:Array = [ () => { let match:boolean = true; - if (!this.toValue || !this.toValue.match || !this.toValue.match(this.params['rule'])) { + if (!this.toValue || !this.toValue.match || !this.toValue.match(this.params.rule)) { match = false; - this.addInvalidMessage(this.toValue + " is not valid"); + this.addInvalidMessage(`${this.toValue} is not valid`); } return match; }