validx
Version:
Validation library for MobX
163 lines • 4.65 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validationContext = exports.ValidationContext = void 0;
const mobx_1 = require("mobx");
const utils_1 = require("./utils");
/**
* Implementation of the validation context.
*
* @export
* @class ValidationContext
* @implements {IValidationContext}
*/
class ValidationContext {
/**
* Initializes a new instance of ValidationContext.
*/
constructor() {
this.reset = (0, mobx_1.action)(this.reset);
this.addErrors = (0, mobx_1.action)(this.addErrors);
this.clearErrors = (0, mobx_1.action)(this.clearErrors);
this.validate = (0, mobx_1.action)(this.validate);
(0, mobx_1.extendObservable)(this, {
errorsMap: mobx_1.observable.map(),
get errors() {
return (0, utils_1.mapToObject)((0, mobx_1.toJS)(this.errorsMap));
},
get isValid() {
return (0, utils_1.every)(this.errors, (arr) => arr.length === 0);
},
}, {
errors: mobx_1.computed,
isValid: mobx_1.computed,
});
}
/**
* Resets the errors.
*
* @returns {IValidationContext}
*
* @memberOf ValidationContext
*/
reset() {
this.errorsMap.clear();
return this;
}
/**
* Validates the input object and stores any errors that may have occurred
* in `errors`.
*
* @template T The type of the object being validated.
* @param {T} obj
* @param {IValidationSchema<T>} schema
* @returns {IValidationContext}
*
* @memberOf ValidationContext
*/
validate(obj, schema) {
(0, utils_1.forEach)(schema, (validators, field) => {
const errors = this.ensureErrors(field);
const value = obj[field];
(0, utils_1.forEach)(validators, (validator) => {
if (!validator) {
return;
}
const opts = {
field,
value,
obj,
};
let msg = 'This field is invalid.';
const result = validator(opts);
if (result === true) {
return;
}
else if (result !== false) {
msg = result;
}
errors.push(msg);
});
});
this.cleanupErrors();
return this;
}
/**
* Adds errors to the context.
*/
addErrors(errors) {
(0, utils_1.forEach)(errors, (arr, field) => {
this.ensureErrors(field).push(...arr);
});
return this;
}
/**
* Gets the errors for the given field.
*/
getErrors(field) {
const errors = this.errors[field];
if (!errors) {
return [];
}
return errors.slice();
}
/**
* Gets the first error for the given field.
* If not found, returns undefined.
*/
getError(field) {
return this.getErrors(field)[0];
}
/**
* Removes errors for a particular field.
*/
clearErrors(field) {
this.errorsMap.set(field, []);
return this;
}
/**
* Ensures that an entry in the internal error map
* exists for the specified field.
*
* @private
* @param {string} field
* @returns
*
* @memberOf ValidationContext
*/
ensureErrors(field) {
let errors = this.errorsMap.get(field);
if (!errors) {
errors = mobx_1.observable.array([]);
this.errorsMap.set(field, errors);
}
return errors;
}
/**
* At the end of a validation run, if a field
* has no errors, it's entry in the error map
* is removed.
*
* @private
*
* @memberOf ValidationContext
*/
cleanupErrors() {
const entries = Array.from(this.errorsMap.entries()).filter(([, value]) => value.length === 0);
entries.forEach(([key]) => this.errorsMap.delete(key));
}
}
exports.ValidationContext = ValidationContext;
function validationContext(objectToValidate, schema) {
const v = new ValidationContext();
if (objectToValidate !== null && objectToValidate !== undefined) {
if (schema) {
v.validate = v.validate.bind(v, objectToValidate, schema);
}
else {
v.validate = v.validate.bind(v, objectToValidate);
}
}
return v;
}
exports.validationContext = validationContext;
//# sourceMappingURL=validation.js.map