vscroll
Version:
Virtual scroll engine
394 lines • 13.3 kB
JavaScript
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