UNPKG

vscroll

Version:
394 lines 13.3 kB
import { __read, __spreadArray, __values } from "tslib"; export var ValidatorType; (function (ValidatorType) { ValidatorType["number"] = "must be a number"; ValidatorType["integer"] = "must be an integer"; ValidatorType["integerUnlimited"] = "must be an integer or infinity"; ValidatorType["moreOrEqual"] = "must be a number greater than (or equal to) {arg1}"; ValidatorType["itemList"] = "must be an array of items {arg1}"; ValidatorType["boolean"] = "must be a boolean"; ValidatorType["object"] = "must be an object"; ValidatorType["element"] = "must be an html element"; ValidatorType["function"] = "must be a function"; ValidatorType["funcOfxArguments"] = "must have {arg1} argument(s)"; ValidatorType["funcOfxAndMoreArguments"] = "must have at least {arg1} argument(s)"; ValidatorType["funcOfXToYArguments"] = "must have {arg1} to {arg2} arguments"; ValidatorType["oneOfCan"] = "can be present as only one item of {arg1} list"; ValidatorType["oneOfMust"] = "must be present as only one item of {arg1} list"; ValidatorType["or"] = "must satisfy at least 1 validator from {arg1} list"; ValidatorType["enum"] = "must belong to {arg1} list"; })(ValidatorType || (ValidatorType = {})); var getError = function (msg, args) { return (args || ['']).reduce(function (acc, arg, index) { return acc.replace("{arg".concat(index + 1, "}"), arg); }, msg); }; var getNumber = function (value) { return typeof value === 'number' || (typeof value === 'string' && value !== '') ? Number(value) : NaN; }; var onNumber = function (value) { var parsedValue = getNumber(value); var errors = []; if (Number.isNaN(parsedValue)) { errors.push(ValidatorType.number); } return { value: parsedValue, isSet: true, isValid: !errors.length, errors: errors }; }; var onInteger = function (value) { var errors = []; value = getNumber(value); var parsedValue = parseInt(String(value), 10); if (value !== parsedValue) { errors.push(ValidatorType.integer); } return { value: parsedValue, isSet: true, isValid: !errors.length, errors: errors }; }; var onIntegerUnlimited = function (value) { var parsedValue = value; var errors = []; value = getNumber(value); if (!Number.isFinite(value)) { parsedValue = value; } else { parsedValue = parseInt(String(value), 10); } if (value !== parsedValue) { errors.push(ValidatorType.integerUnlimited); } return { value: parsedValue, isSet: true, isValid: !errors.length, errors: errors }; }; var onMoreOrEqual = function (limit, fallback) { return function (value) { var result = onNumber(value); if (!result.isValid) { return result; } var parsedValue = result.value; var errors = []; if (parsedValue < limit) { if (!fallback) { errors.push(getError(ValidatorType.moreOrEqual, [String(limit)])); } else { parsedValue = limit; } } return { value: parsedValue, isSet: true, isValid: !errors.length, errors: errors }; }; }; var onBoolean = function (value) { var errors = []; var parsedValue = value; if (value === 'true') { parsedValue = true; } else if (value === 'false') { parsedValue = false; } if (typeof parsedValue !== 'boolean') { errors.push(ValidatorType.boolean); } return { value: parsedValue, isSet: true, isValid: !errors.length, errors: errors }; }; var onObject = function (value) { var errors = []; if (!value || Object.prototype.toString.call(value) !== '[object Object]') { errors.push(ValidatorType.object); } return { value: value, isSet: true, isValid: !errors.length, errors: errors }; }; var onHtmlElement = function (value) { var errors = []; if (!(value instanceof Element) && !(value instanceof Document)) { errors.push(ValidatorType.element); } return { value: value, isSet: true, isValid: !errors.length, errors: errors }; }; var onItemList = function (value) { var parsedValue = value; var errors = []; if (!Array.isArray(value)) { errors.push(ValidatorType.itemList); parsedValue = []; } else if (!value.length) { errors.push(getError(ValidatorType.itemList, ['with at least 1 item'])); } else if (value.length > 1) { var type = typeof value[0]; for (var i = value.length - 1; i >= 0; i--) { if (typeof value[i] !== type) { errors.push(getError(ValidatorType.itemList, ['of items of the same type'])); break; } } } return { value: parsedValue, isSet: true, isValid: !errors.length, errors: errors }; }; var onFunction = function (value) { var errors = []; if (typeof value !== 'function') { errors.push(ValidatorType.function); } return { value: value, isSet: true, isValid: !errors.length, errors: errors }; }; var onFunctionWithXArguments = function (argsCount) { return function (value) { var result = onFunction(value); if (!result.isValid) { return result; } value = result.value; var errors = []; if (value.length !== argsCount) { errors.push(getError(ValidatorType.funcOfxArguments, [String(argsCount)])); } return { value: value, isSet: true, isValid: !errors.length, errors: errors }; }; }; var onFunctionWithXAndMoreArguments = function (argsCount) { return function (value) { var result = onFunction(value); if (!result.isValid) { return result; } value = result.value; var errors = []; if (value.length < argsCount) { errors.push(getError(ValidatorType.funcOfxArguments, [String(argsCount)])); } return { value: value, isSet: true, isValid: !errors.length, errors: errors }; }; }; var onFunctionWithXToYArguments = function (from, to) { return function (value) { var result = onFunction(value); if (!result.isValid) { return result; } value = result.value; var errors = []; if (value.length < from || value.length > to) { errors.push(getError(ValidatorType.funcOfXToYArguments, [String(from), String(to)])); } return { value: value, isSet: true, isValid: !errors.length, errors: errors }; }; }; var onOneOf = function (tokens, must) { return function (value, context) { var errors = []; var isSet = value !== void 0; var noOneIsPresent = !isSet; var err = must ? ValidatorType.oneOfMust : ValidatorType.oneOfCan; if (!Array.isArray(tokens) || !tokens.length) { errors.push(getError(err, ['undefined'])); } else { for (var i = tokens.length - 1; i >= 0; i--) { var token = tokens[i]; if (typeof token !== 'string') { errors.push(getError(err, [tokens.join('", "')]) + ' (non-string token)'); break; } var isAnotherPresent = context && Object.prototype.hasOwnProperty.call(context, token); if (isSet && isAnotherPresent) { errors.push(getError(err, [tokens.join('", "')]) + " (".concat(token, " is present)")); break; } if (noOneIsPresent && isAnotherPresent) { noOneIsPresent = false; } } if (must && noOneIsPresent) { errors.push(getError(err, [tokens.join('", "')])); } } return { value: value, isSet: isSet, isValid: !errors.length, errors: errors }; }; }; var onOr = function (validators) { return function (value) { var errors = []; if (validators.every(function (validator) { return !validator.method(value).isValid; })) { errors.push(validators.map(function (v) { return v.type; }).join(' OR ')); } return { value: value, isSet: true, isValid: !errors.length, errors: errors }; }; }; var onEnum = function (list) { return function (value) { var errors = []; var values = Object.keys(list).filter(function (k) { return isNaN(Number(k)); }).map(function (k) { return list[k]; }); if (!values.some(function (item) { return item === value; })) { errors.push(getError(ValidatorType.enum, ['[' + values.join(',') + ']'])); } return { value: value, isSet: true, isValid: !errors.length, errors: errors }; }; }; export var VALIDATORS = { NUMBER: { type: ValidatorType.number, method: onNumber }, INTEGER: { type: ValidatorType.integer, method: onInteger }, INTEGER_UNLIMITED: { type: ValidatorType.integerUnlimited, method: onIntegerUnlimited }, MORE_OR_EQUAL: function (limit, fallback) { return ({ type: ValidatorType.moreOrEqual, method: onMoreOrEqual(limit, fallback) }); }, BOOLEAN: { type: ValidatorType.boolean, method: onBoolean }, OBJECT: { type: ValidatorType.object, method: onObject }, ITEM_LIST: { type: ValidatorType.itemList, method: onItemList }, ELEMENT: { type: ValidatorType.element, method: onHtmlElement }, FUNC: { type: ValidatorType.function, method: onFunction }, FUNC_WITH_X_ARGUMENTS: function (count) { return ({ type: ValidatorType.funcOfxArguments, method: onFunctionWithXArguments(count) }); }, FUNC_WITH_X_AND_MORE_ARGUMENTS: function (count) { return ({ type: ValidatorType.funcOfxAndMoreArguments, method: onFunctionWithXAndMoreArguments(count) }); }, FUNC_WITH_X_TO_Y_ARGUMENTS: function (from, to) { return ({ type: ValidatorType.funcOfXToYArguments, method: onFunctionWithXToYArguments(from, to) }); }, ONE_OF_CAN: function (list) { return ({ type: ValidatorType.oneOfCan, method: onOneOf(list, false) }); }, ONE_OF_MUST: function (list) { return ({ type: ValidatorType.oneOfMust, method: onOneOf(list, true) }); }, OR: function (list) { return ({ type: ValidatorType.or, method: onOr(list) }); }, ENUM: function (list) { return ({ type: ValidatorType.enum, method: onEnum(list) }); } }; var ValidatedData = /** @class */ (function () { function ValidatedData(context) { this.params = {}; this.contextErrors = []; this.errors = []; this.isValid = true; this.setContext(context); } ValidatedData.prototype.setContext = function (context) { if (!context || Object.prototype.toString.call(context) !== '[object Object]') { this.setCommonError('context is not an object'); this.isValidContext = false; } else { this.isValidContext = true; } this.context = context; }; ValidatedData.prototype.setValidity = function () { var _this = this; this.errors = Object.keys(this.params).reduce(function (acc, key) { return __spreadArray(__spreadArray([], __read(acc), false), __read(_this.params[key].errors), false); }, []); this.isValid = !this.errors.length; }; ValidatedData.prototype.setCommonError = function (error) { this.contextErrors.push(error); this.errors.push(error); this.isValid = false; }; ValidatedData.prototype.setParam = function (token, value) { if (!value.isValid) { value.errors = !value.isSet ? ["\"".concat(token, "\" must be set")] : value.errors.map(function (err) { return "\"".concat(token, "\" ").concat(err); }); } this.params[token] = value; this.setValidity(); }; ValidatedData.prototype.showErrors = function () { return this.errors.length ? 'validation failed: ' + this.errors.join(', ') : ''; }; return ValidatedData; }()); export { ValidatedData }; export var runValidator = function (current, validator, context) { var value = current.value, errors = current.errors; var result = validator.method(value, context); var _errors = __spreadArray(__spreadArray([], __read(errors), false), __read(result.errors), false); return { value: result.value, isSet: result.isSet, isValid: !_errors.length, errors: _errors }; }; var getDefault = function (value, prop) { var empty = value === void 0; var auto = !prop.mandatory && prop.defaultValue !== void 0; return { value: !empty ? value : (auto ? prop.defaultValue : void 0), isSet: !empty || auto, isValid: !empty || !prop.mandatory, errors: [] }; }; export var validateOne = function (context, name, prop) { var e_1, _a; var result = getDefault(context[name], prop); if (!result.isSet) { var oneOfMust = prop.validators.find(function (v) { return v.type === ValidatorType.oneOfMust; }); if (oneOfMust) { return runValidator(result, oneOfMust, context); } } else { try { for (var _b = __values(Object.values(prop.validators)), _c = _b.next(); !_c.done; _c = _b.next()) { var validator = _c.value; var current = runValidator(result, validator, context); if (!current.isValid && prop.defaultValue !== void 0) { return { value: prop.defaultValue, isSet: true, isValid: true, errors: [] }; } Object.assign(result, current); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } } return result; }; export var validate = function (context, params) { var data = new ValidatedData(context); Object.entries(params).forEach(function (_a) { var _b = __read(_a, 2), key = _b[0], prop = _b[1]; return data.setParam(key, data.isValidContext ? validateOne(data.context, key, prop) : getDefault(void 0, prop)); }); return data; }; //# sourceMappingURL=validation.js.map