UNPKG

@sebgroup/frontend-tools

Version:
250 lines (245 loc) 10 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var isEmpty = require('../isEmpty/isEmpty.js'); var isPhoneNumber = require('../isPhoneNumber/isPhoneNumber.js'); var isEmail = require('../isEmail/isEmail.js'); var deepCopy = require('../deepCopy/deepCopy.js'); var isStrongPassword = require('../isStrongPassword/isStrongPassword.js'); var isValidDate = require('../isValidDate/isValidDate.js'); var isDateBefore = require('../isDateBefore/isDateBefore.js'); var isDateAfter = require('../isDateAfter/isDateAfter.js'); class ValidatorModelItem { constructor(name, value) { this.value = null; this.specs = {}; this.validations = []; this.name = name; this.value = value; this.specs = {}; this.validations = []; } } class FormValidator { constructor(formObject) { this.formObject = new Map(); this.formObjectErrors = {}; this.customValidators = []; if (!isEmpty.isEmpty(formObject) && typeof formObject === "object") { const clone = deepCopy.deepCopy(formObject); this.originalFormObject = clone; for (const field in clone) { this.formObject.set(field, new ValidatorModelItem(field, clone[field])); } } } addValidation(fields, type, specs) { if (fields && fields instanceof Array && type && typeof type === "string" && this.isValidType(type)) { if (fields.length) { fields.map((field) => { if (this.formObject.has(field)) { this.formObject.get(field).validations.push(type); if (!isEmpty.isEmpty(specs)) { this.formObject.get(field).specs = Object.assign(Object.assign({}, this.formObject.get(field).specs), specs); } } }); } else { this.formObject.forEach((item) => { item.validations.push(type); if (!isEmpty.isEmpty(specs)) { item.specs = Object.assign(Object.assign({}, item.specs), specs); } }); } } return this; } /** * Add a custom validator that returns an error message if found * @param {Array<string>} errorFields The fields where the error is reported to * @param {function} validator The validator method * @returns {FormValidator} The form validator object * @example addValidator(["balance", "payment"], ["payment"], (balance: number, payment: number) => { return payment > balance ? "The payment exceeds your balance" : null; }); */ addCustomValidation(errorFields, validator) { if (errorFields && errorFields instanceof Array && errorFields.length && validator && validator instanceof Function) { this.customValidators.push({ errorFields, validator }); } return this; } /** * Get the error found in the form object. Has to be called after `validate` method has been called. * @returns {any} The form object object populated by validation errors, if found any. Otherwise, it's an empty object. */ getErrors() { return this.formObjectErrors; } /** * Get a specific error found during validation, if any. Has to be called after `validate` method has been called. * @returns {any} The error of the specific item in the form, if any. */ getError(name) { return this.formObjectErrors[name]; } /** * Validates the form object passed in the constructor * @returns {FormValidator} The form validator object */ validate() { this.formObject.forEach((item) => { if (item.validations.length) { let fieldError; let i = 0; do { fieldError = this.validateField(item.value, item.validations[i], item.specs); if (!isEmpty.isEmpty(fieldError)) { this.formObjectErrors[item.name] = fieldError; } i++; } while (i < item.validations.length && !fieldError); } }); if (this.customValidators.length) { this.customValidators.map((customValidator) => { const customValidatorError = customValidator.validator(this.originalFormObject); customValidator.errorFields.map((field) => { if (this.formObject.has(field) && !this.getError(field) && customValidatorError) { this.formObjectErrors[field] = customValidatorError; } }); }); } return this; } /** * Validate a parameter in the form formObject based on predefined set of criteria * @param {ValidatorModelItem} fieldObject The field object stored in the local formObject * @returns {string} The error found in the parameter */ validateField(value, type, specs) { let fieldError = null; // Don't validate an empty field if it's not required const date = new Date(value); const empty = isEmpty.isEmpty(value); if (empty && type !== "required") { return null; } const valid = isValidDate.isValidDate(date); switch (type) { case "required": return empty ? { errorCode: "empty" } : null; case "isDate": return valid ? null : { errorCode: "invalidDate" }; case "dateRange": if (valid) { if (specs.minDate) { fieldError = isDateBefore.isDateBefore(date, specs.minDate) ? { errorCode: "beforeMinDate", specs: { minDate: specs.minDate }, } : null; } if (!fieldError && specs.maxDate) { fieldError = isDateAfter.isDateAfter(date, specs.maxDate) ? { errorCode: "afterMaxDate", specs: { maxDate: specs.maxDate }, } : null; } return fieldError; } else { return null; } case "textLength": if (typeof value === "string") { if (specs.minLength) { fieldError = value.length < specs.minLength ? { errorCode: "lessThanMinLength", specs: { minLength: specs.minLength }, } : null; } if (!fieldError && specs.maxLength) { fieldError = value.length > specs.maxLength ? { errorCode: "moreThanMaxLength", specs: { maxLength: specs.maxLength }, } : null; } return fieldError; } else { return null; } case "valueRange": if (typeof value === "number") { if (specs.minValue) { fieldError = value < specs.minValue ? { errorCode: "lessThanMinValue", specs: { minValue: specs.minValue }, } : null; } if (!fieldError && specs.maxValue) { fieldError = value > specs.maxValue ? { errorCode: "moreThanMaxValue", specs: { maxValue: specs.maxValue }, } : null; } return fieldError; } else { return null; } case "validEmail": return isEmail.isEmail(value) ? null : { errorCode: "invalidEmail" }; case "strongPassword": return isStrongPassword.isStrongPassword(value) ? null : { errorCode: "weakPassword" }; case "isPhoneNumber": return isPhoneNumber.isPhoneNumber(value) ? null : { errorCode: "invalidPhoneNumber" }; } } // Helpers isValidType(type) { const availableValidationTypes = { required: true, isDate: true, dateRange: true, textLength: true, valueRange: true, validEmail: true, strongPassword: true, isPhoneNumber: true, }; return availableValidationTypes.hasOwnProperty(type); } } exports.FormValidator = FormValidator; //# sourceMappingURL=FormValidator.js.map