valirator
Version:
Powerful javascript by schema validation tool
1,637 lines (1,437 loc) • 44.5 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.valirator = {}));
}(this, function (exports) { 'use strict';
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(source, true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(source).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _toArray(arr) {
return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest();
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
}
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance");
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
/**
* @description
* Empty function
*/
function noop() {}
/**
* @description
* Check if type
*
* @param obj
* @param {string} typeStr - type string like: '[object Object]', '[object Array]' and etc
* @returns {boolean}
*/
function isType(obj, typeStr) {
return Object.prototype.toString.call(obj) === typeStr;
}
/**
* @description
* Check if is Object
*
* @param obj
* @returns {boolean}
*/
function isObject(obj) {
return isType(obj, '[object Object]');
}
/**
* @description
* Check if is Array
*
* @param obj
* @returns {boolean}
*/
function isArray(obj) {
return isType(obj, '[object Array]');
}
/**
* @description
* Check if is Function
*
* @param obj
* @returns {boolean}
*/
function isFunction(obj) {
return isType(obj, '[object Function]');
}
/**
* @description
* Check if is String
*
* @param obj
* @returns {boolean}
*/
function isString(obj) {
return isType(obj, '[object String]');
}
/**
* @description
* Check if is Date
*
* @param obj
* @returns {boolean}
*/
function isDate(obj) {
return isType(obj, '[object Date]');
}
/**
* @description
* Check if is Number
*
* @param obj
* @returns {boolean}
*/
function isNumber(obj) {
return isType(obj, '[object Number]') && !isNaN(obj);
}
/**
* @description
* Check if is Boolean
*
* @param obj
* @returns {boolean}
*/
function isBoolean(obj) {
return isType(obj, '[object Boolean]');
}
/**
* @description
* Check if is Empty
* Empty string -> true
* Empty array -> true
* Empty object -> true
*
* Anything else -> false
*
* @param obj
* @returns {boolean}
*/
function isEmpty(obj) {
return obj === '' || isArray(obj) && obj.length === 0 || isObject(obj) && Object.keys(obj).length === 0;
}
/**
* @description
* Check if is Null
*
* @param obj
* @returns {boolean}
*/
function isNull(obj) {
return isType(obj, '[object Null]');
}
/**
* @description
* Check if is Undefined
*
* @param obj
* @returns {boolean}
*/
function isUndefined(obj) {
return isType(obj, '[object Undefined]');
}
/**
* @description
* Check is is Null or Undefined
*
* @param obj
* @returns {boolean}
*/
function isNullOrUndefined(obj) {
return isNull(obj) || isUndefined(obj);
}
/**
* @description
* Check is object is defined (not null, not undefined, not empty string, object or array
*
* @param obj
* @returns {boolean}
*/
function isDefined(obj) {
return !(isNullOrUndefined(obj) || isEmpty(obj));
}
/**
* @description
* Safe convert to String
*
* @param obj
* @returns {string}
*/
function toString(obj) {
return String(obj);
}
/**
* @description
* Safe indexOf
*
* @param array
* @param value
* @returns {Number}
*/
function indexOf(array, value) {
if (!isArray(array)) {
return -1;
}
return array.indexOf(value);
}
/**
* @description
* Safe check if value in array
*
* @param array
* @param value
* @returns {boolean}
*/
function inArray(array, value) {
return isArray(array) && indexOf(array, value) !== -1;
}
/**
* @description
* Cast item to array
*
* @param array
* @returns {Array}
*/
function castArray(array) {
return isArray(array) ? array : [array];
}
/**
* @description
* Safe check is object has property
*
* @param obj
* @param {string} prop - property name
* @returns {boolean}
*/
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
/**
* @description
* Safe set prototype
*
* @param obj
* @param proto
* @returns {Object}
*/
function setPrototypeOf(obj, proto) {
if (Object.setPrototypeOf) {
return Object.setPrototypeOf(obj, proto);
}
obj.__proto__ = proto;
return obj;
}
/**
* @description
* Safe get prototype
*
* @param obj
* @returns {*}
*/
function getPrototypeOf(obj) {
if (Object.getPrototypeOf) {
return Object.getPrototypeOf(obj);
}
return obj.__proto__;
}
/**
* @description
* Get property value
*
* @param {Object} obj
* @param {string} path
* @param fallback - fallback value
* @returns {*}
*/
function getProperty(obj) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
var fallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var result = obj;
var prop = toString(path);
if (path === '') {
return result;
}
if (!isDefined(obj)) {
return fallback;
}
do {
if (isObject(result)) {
if (hasOwnProperty(result, prop)) {
return result[prop];
}
var _prop$split = prop.split('.'),
_prop$split2 = _toArray(_prop$split),
first = _prop$split2[0],
rest = _prop$split2.slice(1);
result = result[first];
prop = rest.join('.');
} else {
break;
}
} while (prop);
if (result === null || result === undefined) {
return fallback;
}
return result;
}
/**
* @description
* Get property override in chain
*
* @param {Object} context
* @param {string} prop
* @returns {*}
*/
function getPropertyOverride(context, prop) {
if (!context) {
return false;
}
return isFunction(context[prop]) ? context[prop] : getPropertyOverride(getPrototypeOf(context), prop);
}
/**
* @description
* Handle Promise or PromiseLike object
*
* @param {Promise|PromiseLike} promise
* @returns {Promise|PromiseLike}
*/
function handlePromise(promise) {
if (promise && promise.then) {
return promise;
}
return {
then: function then(cb) {
return handlePromise(cb(promise));
},
catch: noop,
value: promise,
isPromiseLike: true
};
}
/**
* @description
* Handle array of Promises or PromiseLike objects
*
* @param promises
* @returns {Promise|PromiseLike}
*/
function handlePromises(promises) {
var isAnyPromiseNotPromiseLike = promises.some(function (promise) {
return promise && promise.then && !promise.isPromiseLike;
});
if (isAnyPromiseNotPromiseLike) {
return Promise.all(promises);
}
var results = promises.map(function (promise) {
return promise.value;
});
return handlePromise(results);
}
/**
* @description
* Format message for rule
*
* @param {string|Function} message - message template
* @param {*} actual - actual value
* @param {*} expected - expected value
* @param {string} property - validating property
* @param {Object} obj - validating object
* @param {Function} rule - validating function
* @returns {Promise<string>|PromiseLike<string>}
*/
function formatMessage() {
var message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'No default message for rule "%{rule}"';
var actual = arguments.length > 1 ? arguments[1] : undefined;
var expected = arguments.length > 2 ? arguments[2] : undefined;
var property = arguments.length > 3 ? arguments[3] : undefined;
var obj = arguments.length > 4 ? arguments[4] : undefined;
var rule = arguments.length > 5 ? arguments[5] : undefined;
var lookup = {
actual: actual,
expected: expected,
property: property,
rule: rule
};
var formattedMessage = isFunction(message) ? message(actual, expected, property, obj) : isString(message) ? message.replace(/%\{([a-z]+)\}/gi, function (_, match) {
return lookup[match.toLowerCase()] || '';
}) : message;
return handlePromise(formattedMessage);
}
/**
* @typedef {Object} PromiseLike
* @property {Function} then
* @property {Function} catch
* @property {*} value
* @property {boolean} isPromiseLike
*/
/**
*
* @param value
* @param divisibleBy
* @returns {boolean}
*/
function divisibleByRule(value, divisibleBy) {
if (!isDefined(value)) {
return true;
}
var multiplier = Math.max(toString(value - Math.floor(value)).length - 2, toString(divisibleBy - Math.floor(divisibleBy)).length - 2);
multiplier = multiplier > 0 ? Math.pow(10, multiplier) : 1;
return value * multiplier % (divisibleBy * multiplier) === 0;
}
divisibleByRule.ruleName = 'divisibleBy';
divisibleByRule.defaultMessage = 'must be divisible by %{expected}';
/**
*
* @param value
* @param e
* @returns {boolean}
*/
function enumRule(value, e) {
if (!isDefined(value)) {
return true;
}
return inArray(e, value);
}
enumRule.ruleName = 'enum';
enumRule.defaultMessage = 'must be present in given enumerator';
/* eslint-disable no-control-regex,no-useless-escape */
var FORMATS = {
int: /^-?\d+$/,
float: /^-?\d+\.\d+$/,
number: /^-?\d+\.?\d*$/,
email: /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i,
ip: /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i,
ipv6: /^([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}$/,
time: /^\d{2}:\d{2}:\d{2}$/,
date: /^\d{4}-\d{2}-\d{2}$/,
'date-time': /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:.\d{1,3})?Z$/,
color: /^#[a-z0-9]{6}|#[a-z0-9]{3}|(?:rgb\(\s*(?:[+-]?\d+%?)\s*,\s*(?:[+-]?\d+%?)\s*,\s*(?:[+-]?\d+%?)\s*\))aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow$/i,
'host-name': /^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])/,
url: /^(https?|ftp|git):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,
regex: {
test: function test(value) {
try {
new RegExp(value);
} catch (e) {
return false;
}
return true;
}
}
};
/**
*
* @param value
* @param format
* @returns {boolean}
*/
function formatRule(value, format) {
if (!isDefined(value)) {
return true;
}
if (!FORMATS[format]) {
throw new Error("Unknown format \"".concat(format, "\""));
}
return FORMATS[format].test(value);
}
formatRule.ruleName = 'format';
formatRule.defaultMessage = 'is not a valid %{expected}';
/**
*
* @param name
* @param format
*/
function addFormatToFormatRule(name, format) {
if (isString(format)) {
FORMATS[name] = new RegExp(format);
} else if (isFunction(format)) {
FORMATS[name] = {
test: format
};
} else {
FORMATS[name] = format;
}
}
/**
*
* @param value
* @param lessThan
* @returns {boolean}
*/
function lessThanRule(value, lessThan) {
return value < lessThan;
}
lessThanRule.ruleName = 'lessThan';
lessThanRule.defaultMessage = 'must be less than %{expected}';
/**
*
* @param value
* @param lessThanProperty
* @param obj
* @returns {boolean}
*/
function lessThanPropertyRule(value, lessThanProperty, obj) {
return value < obj[lessThanProperty];
}
lessThanPropertyRule.ruleName = 'lessThanProperty';
lessThanPropertyRule.defaultMessage = 'must be less than %{expected}';
/**
*
* @param value
* @param moreThan
* @returns {boolean}
*/
function moreThanRule(value, moreThan) {
return value > moreThan;
}
moreThanRule.ruleName = 'moreThan';
moreThanRule.defaultMessage = 'must be greater than %{expected}';
/**
*
* @param value
* @param moreThanProperty
* @param obj
* @returns {boolean}
*/
function moreThanPropertyRule(value, moreThanProperty, obj) {
return value > obj[moreThanProperty];
}
moreThanPropertyRule.ruleName = 'moreThanProperty';
moreThanPropertyRule.defaultMessage = 'must be greater than %{expected}';
/**
*
* @param value
* @param matchTo
* @returns {boolean}
*/
function matchToRule(value, matchTo) {
return value === matchTo;
}
matchToRule.ruleName = 'matchTo';
matchToRule.defaultMessage = 'should match to %{expected}';
/**
*
* @param value
* @param matchToProperty
* @param obj
* @returns {boolean}
*/
function matchToPropertyRule(value, matchToProperty, obj) {
return castArray(matchToProperty).every(function (to) {
return obj[to] === value;
});
}
matchToPropertyRule.ruleName = ['matchToProperty', 'matchToProperties'];
matchToPropertyRule.defaultMessage = 'should match to %{expected}';
/**
*
* @param value
* @param notMatchTo
* @returns {*}
*/
function notMatchToRule(value, notMatchTo) {
return castArray(notMatchTo).every(function (not) {
return not !== value;
});
}
notMatchToRule.ruleName = 'notMatchTo';
notMatchToRule.defaultMessage = 'should not match to %{expected}';
/**
*
* @param value
* @param notMatchToProperty
* @param obj
* @returns {*}
*/
function notMatchToPropertyRule(value, notMatchToProperty, obj) {
return castArray(notMatchToProperty).every(function (not) {
return obj[not] !== value;
});
}
notMatchToPropertyRule.ruleName = ['notMatchToProperty', 'notMatchToProperties'];
notMatchToPropertyRule.defaultMessage = 'should not match to %{expected}';
/**
*
* @param value
* @param max
* @returns {boolean}
*/
function maxRule(value, max) {
if (!isDefined(value)) {
return true;
}
return value <= max;
}
maxRule.ruleName = 'max';
maxRule.defaultMessage = 'must be less than or equal to %{expected}';
/**
*
* @param value
* @param maxItems
* @returns {boolean}
*/
function maxItemsRule(value, maxItems) {
if (!isDefined(value)) {
return true;
}
return isArray(value) && value.length <= maxItems;
}
maxItemsRule.ruleName = 'maxItems';
maxItemsRule.defaultMessage = 'must contain less than %{expected} items';
/**
*
* @param value
* @param maxLength
* @returns {boolean}
*/
function maxLengthRule(value, maxLength) {
if (!isDefined(value)) {
return true;
}
return value.length <= maxLength;
}
maxLengthRule.ruleName = 'maxLength';
maxLengthRule.defaultMessage = 'is too long (maximum is %{expected} characters)';
/**
*
* @param value
* @param min
* @returns {boolean}
*/
function minRule(value, min) {
if (!isDefined(value)) {
return true;
}
return value >= min;
}
minRule.ruleName = 'min';
minRule.defaultMessage = 'must be greater than or equal to %{expected}';
/**
*
* @param value
* @param minItems
* @returns {boolean}
*/
function minItemsRule(value, minItems) {
if (!isDefined(value)) {
return true;
}
return isArray(value) && value.length >= minItems;
}
minItemsRule.ruleName = 'minItems';
minItemsRule.defaultMessage = 'must contain more than %{expected} items';
/**
*
* @param value
* @param minLength
* @returns {boolean}
*/
function minLengthRule(value, minLength) {
if (!isDefined(value)) {
return true;
}
return value.length >= minLength;
}
minLengthRule.ruleName = 'minLength';
minLengthRule.defaultMessage = 'is too short (minimum is %{expected} characters)';
/**
*
* @param value
* @param patterns
* @returns {boolean}
*/
function patternRule(value, patterns) {
if (!isDefined(value)) {
return true;
}
patterns = castArray(patterns).map(function (pattern) {
return isString(pattern) ? new RegExp(pattern) : pattern;
});
return patterns.every(function (pattern) {
return pattern.test(value);
});
}
patternRule.ruleName = 'pattern';
patternRule.defaultMessage = 'invalid input';
/**
*
* @param value
* @param required
* @returns {*}
*/
function requiredRule(value, required) {
if (isBoolean(required) && !required) {
return true;
}
if (isObject(required)) {
var allowEmpty = required.allowEmpty,
allowZero = required.allowZero;
if (isBoolean(allowEmpty)) {
return allowEmpty && value === '';
}
if (isBoolean(allowZero)) {
return allowZero && value === 0;
}
}
return !!value && isDefined(value);
}
requiredRule.ruleName = 'required';
requiredRule.defaultMessage = 'is required';
function checkValueType(value, type) {
switch (type) {
case 'boolean':
return isBoolean(value);
case 'number':
return isNumber(value);
case 'string':
return isString(value);
case 'date':
return isDate(value);
case 'object':
return isObject(value);
case 'array':
return isArray(value);
default:
return true;
}
}
/**
*
* @param value
* @param type
* @returns {boolean}
*/
function typeRule(value, type) {
if (!isDefined(value)) {
return true;
}
var types = type;
if (!Array.isArray(type)) {
types = [type];
}
return types.some(function (type) {
return checkValueType(value, type);
});
}
typeRule.ruleName = 'type';
typeRule.defaultMessage = 'must be of %{expected} type';
/**
*
* @param value
* @param uniqueItems
* @returns {boolean}
*/
function uniqueItemsRule(value, uniqueItems) {
if (!isDefined(value)) {
return true;
}
if (!uniqueItems) {
return true;
}
var hash = {};
var i = 0,
ln = value.length;
for (; i < ln; i++) {
var key = JSON.stringify(value[i]);
if (hash[key]) {
return false;
}
hash[key] = true;
}
return true;
}
uniqueItemsRule.ruleName = 'uniqueItems';
uniqueItemsRule.defaultMessage = 'must hold an unique set of values';
var rules = /*#__PURE__*/Object.freeze({
divisibleByRule: divisibleByRule,
enumRule: enumRule,
formatRule: formatRule,
addFormatToFormatRule: addFormatToFormatRule,
lessThanRule: lessThanRule,
lessThanPropertyRule: lessThanPropertyRule,
moreThanRule: moreThanRule,
moreThanPropertyRule: moreThanPropertyRule,
matchToRule: matchToRule,
matchToPropertyRule: matchToPropertyRule,
notMatchToRule: notMatchToRule,
notMatchToPropertyRule: notMatchToPropertyRule,
maxRule: maxRule,
maxItemsRule: maxItemsRule,
maxLengthRule: maxLengthRule,
minRule: minRule,
minItemsRule: minItemsRule,
minLengthRule: minLengthRule,
patternRule: patternRule,
requiredRule: requiredRule,
typeRule: typeRule,
uniqueItemsRule: uniqueItemsRule
});
var rulesStorage = {};
/**
* Register validation rule
*
* @param {string} name - rule name
* @param {Function} rule - rule function
* @param {string|Function} message - rule message
*/
function registerRule(name, rule, message) {
if (hasOwnProperty(rulesStorage, name)) {
console.warn("[WARNING]: Trying to override defined rule '".concat(name, "'. Please use 'overrideRule' function instead."));
}
rulesStorage[name] = {
name: name,
message: message,
check: rule
};
}
/**
* Register batch validation rule
*
* @param {Array} rules - rules to register
*/
function registerRules(rules) {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = rules[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var rule = _step.value;
if (rule && rule.ruleName) {
var ruleNames = castArray(rule.ruleName);
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = ruleNames[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var ruleName = _step2.value;
registerRule(ruleName, rule, rule.defaultMessage);
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
/**
* Check if rule is registered
*
* @param {string} name - rule name
* @returns {boolean}
*/
function hasRule(name) {
return hasOwnProperty(rulesStorage, name);
}
/**
* Get rule by name
*
* @param {string} name
* @returns {{name, message, check}}
*/
function getRule(name) {
return rulesStorage[name] || {};
}
/**
* Override rule by name
*
* @param {string} name - rule name
* @param {Function} rule - rule function
* @param {string|Function} message - rule message
*/
function overrideRule(name, rule, message) {
if (hasRule(name)) {
var defaultRule = getRule(name);
defaultRule.check = rule;
defaultRule.message = message || defaultRule.message;
}
}
/**
* Override rule message by name
*
* @param {string} name - rule name
* @param {string|Function} message - rule message
*/
function overrideRuleMessage(name, message) {
if (hasRule(name)) {
var defaultRule = getRule(name);
defaultRule.message = message;
}
}
registerRules(Object.values(rules));
/**
* @typedef ValidationResult
* @property {boolean} isValid - check if validation result has not errors
* @property {boolean} hasErrors - check if validation result has errors
* @property {boolean} hasErrorsOfTypes - check if validation result has errors of specific types
* @property {*} getErrors - get validation result errors
* @property {*} getFirstErrors - get first validation result errors
* @property {Array<*>} getErrorsAsArray - get validation result errors as array
* @property {string} getFirstError - get first validation result error
*
* ValidationResult is util class that contain information about errors and any level
*
* @param {Object} errors - validation errors
* @returns {ValidationResult}
*/
function ValidationResult() {
var errors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var protoOfErrors = getPrototypeOf(errors);
var that = _objectSpread2({}, protoOfErrors, {}, errors);
var keys = [].concat(_toConsumableArray(Object.keys(errors)), _toConsumableArray(Object.keys(protoOfErrors)));
Object.defineProperties(that, {
isValid: {
value: function isValid() {
return !this.hasErrors();
}
},
hasErrors: {
value: function hasErrors() {
return keys.some(function (key) {
if (that[key].hasErrors) {
return that[key].hasErrors();
}
return that[key];
});
}
},
hasErrorsOfTypes: {
value: function hasErrorsOfTypes() {
for (var _len = arguments.length, types = new Array(_len), _key = 0; _key < _len; _key++) {
types[_key] = arguments[_key];
}
return keys.some(function (key) {
if (types.indexOf(key) !== -1) {
return true;
}
if (that[key].hasErrorsOfTypes) {
var _that$key;
return (_that$key = that[key]).hasErrorsOfTypes.apply(_that$key, types);
}
return false;
});
}
},
getErrors: {
value: function getErrors(includeEmptyErrors) {
return keys.reduce(function (result, key) {
var subErrors = that[key].getErrors ? that[key].getErrors(includeEmptyErrors) : that[key];
if (Object.keys(subErrors).length || includeEmptyErrors) {
return _objectSpread2({}, result, _defineProperty({}, key, subErrors));
}
return result;
}, {});
}
},
getFirstErrors: {
value: function getFirstErrors(includeEmptyErrors) {
return keys.reduce(function (result, key, index) {
var subErrors = that[key].getFirstErrors ? that[key].getFirstErrors(includeEmptyErrors) : that[key];
if (!isString(result) && isObject(that[key]) && (Object.keys(subErrors).length || includeEmptyErrors)) {
return _objectSpread2({}, result, _defineProperty({}, key, subErrors));
}
return index === 0 ? subErrors : result;
}, {});
}
},
getErrorsAsArray: {
value: function getErrorsAsArray(includeEmptyErrors) {
return keys.map(function (key) {
var subErrors = that[key].getErrorsAsArray ? that[key].getErrorsAsArray(includeEmptyErrors) : that[key];
if (subErrors.length || includeEmptyErrors) {
return subErrors;
}
return null;
}, {}).filter(function (error) {
return isDefined(error);
});
}
},
getFirstError: {
value: function getFirstError() {
for (var _len2 = arguments.length, exclude = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
exclude[_key2] = arguments[_key2];
}
return (this.getErrorsAsArray(exclude) || [])[0];
}
}
});
return that;
}
/**
* @description
* Main endpoint for validation
* Validate anything by specified schema
*
* @param {Object|Function} schema - Validation schema
* @param {Object|Array} anything - Anything to validate
* @returns {Promise<ValidationResult>}
*
* @example
* import { validate } from 'valirator';
*
* const schema = {
* FirstName: {
* required: true,
* },
* LastName: {
* required: true,
* },
* };
*
* const obj = {
* FirstName: 'Bob',
* };
*
* const validationResult = await validate(schema, obj);
*/
function validate(schema, anything) {
return handlePromise(isFunction(schema) ? schema(anything) : schema).then(function (builtSchema) {
return validateProperty(undefined, anything, builtSchema);
});
}
/**
* @description
* Wrapper on validate function for sync validation
* Can be used if no async operation defined (rule or message)
*
* @param {Object|Function} schema - Validation schema
* @param {Object|Array} anything - Anything to validate
* @returns {ValidationResult}
*/
function validateSync(schema, anything) {
var promise = validate(isFunction(schema) ? schema(anything) : schema, anything);
return promise && promise.value;
}
/**
*
* @param obj
* @param schema
* @param overrides
* @returns {Promise<ValidationResult>}
*/
function validateObject(obj, schema) {
var overrides = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var initial = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : obj;
var keys = Object.keys(schema);
var promises = keys.map(function (property) {
return validateProperty(property, obj, schema, overrides, initial);
});
return handlePromises(promises).then(function (results) {
var errors = {};
results.forEach(function (result, i) {
errors[keys[i]] = result;
});
return new ValidationResult(errors);
});
}
/**
*
* @param obj
* @param schema
* @param overrides
* @returns {ValidationResult}
*/
function validateObjectSync(obj, schema, overrides) {
var initial = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : obj;
var promise = validateObject(obj, schema, overrides, initial);
return promise && promise.value;
}
/**
*
* @param array
* @param schema
* @param overrides
* @returns {Promise<ValidationResult>}
*/
function validateArray(array, schema) {
var overrides = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var initial = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : array;
var promises = (array || []).map(function (item) {
return validateObject(item, schema, overrides, initial);
});
return handlePromises(promises).then(function (results) {
var errors = {};
results.forEach(function (result, i) {
errors[i] = result;
});
return new ValidationResult(errors);
});
}
/**
*
* @param array
* @param schema
* @param overrides
* @returns {ValidationResult}
*/
function validateArraySync(array, schema, overrides) {
var initial = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : array;
var promise = validateArray(array, schema, overrides, initial);
return promise && promise.value;
}
/**
*
* @param property
* @param obj
* @param schema
* @param overrides
* @returns {Promise<ValidationResult>}
*/
function validateProperty(property, obj) {
var schema = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var overrides = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var initial = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : obj;
var propertyValue = getProperty(schema, property, {});
var __isArray__ = propertyValue.__isArray__,
propertyRules = propertyValue.rules,
_propertyValue$messag = propertyValue.messages,
propertyMessages = _propertyValue$messag === void 0 ? {} : _propertyValue$messag,
_propertyValue$overri = propertyValue.overrides,
propertyOverrides = _propertyValue$overri === void 0 ? {} : _propertyValue$overri,
propertyProperties = propertyValue.properties;
var _overrides$rules = overrides.rules,
overriddenRules = _overrides$rules === void 0 ? {} : _overrides$rules,
_overrides$messages = overrides.messages,
overriddenMessages = _overrides$messages === void 0 ? {} : _overrides$messages;
if (!propertyRules && !propertyProperties) {
var propertyKeys = Object.keys(propertyValue);
var hasRuleProperty = propertyKeys.some(function (key) {
return hasRule(key) || hasOwnProperty(overriddenRules, key) || isFunction(propertyValue[key]);
});
if (hasRuleProperty) {
propertyRules = propertyValue;
}
}
if (!propertyRules && !propertyProperties) {
propertyProperties = propertyValue;
}
if (!propertyRules) {
propertyRules = {};
}
if (!propertyProperties) {
propertyProperties = {};
}
setPrototypeOf(propertyOverrides, overrides);
setPrototypeOf(propertyRules, overriddenRules);
setPrototypeOf(propertyMessages, overriddenMessages);
var value = getProperty(obj, property);
return validateValue(value, propertyRules, propertyMessages, obj, property, schema, initial).then(function (valueValidationResult) {
if (propertyProperties) {
var subValidationCallback = function subValidationCallback(subValidationResult) {
setPrototypeOf(valueValidationResult, subValidationResult);
return new ValidationResult(valueValidationResult);
};
if (isArray(value) || __isArray__) {
return validateArray(value, propertyProperties, propertyOverrides, initial).then(subValidationCallback);
} else {
return validateObject(value, propertyProperties, propertyOverrides, initial).then(subValidationCallback);
}
}
return new ValidationResult(valueValidationResult);
});
}
/**
*
* @param property
* @param obj
* @param schema
* @param overrides
* @returns {ValidationResult}
*/
function validatePropertySync(property, obj, schema, overrides) {
var promise = validateProperty(property, obj, schema, overrides);
return promise && promise.value;
}
/**
*
* @param value
* @param rules
* @param messages
* @param obj
* @param property
* @param schema
* @returns {Promise<ValidationResult>}
*/
function validateValue(value) {
var rules = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var messages = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var obj = arguments.length > 3 ? arguments[3] : undefined;
var property = arguments.length > 4 ? arguments[4] : undefined;
var schema = arguments.length > 5 ? arguments[5] : undefined;
var initial = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : obj;
var keys = Object.keys(rules);
var promises = keys.map(function (rule) {
var expected = rules[rule];
var message = messages[rule];
return validateRule(rule, expected, value, message, rules, messages, obj, property, schema, initial);
});
return handlePromises(promises).then(function (results) {
var errors = {};
results.forEach(function (result, i) {
if (result) {
errors[keys[i]] = result;
}
});
return new ValidationResult(errors);
});
}
/**
*
* @param value
* @param rules
* @param messages
* @param obj
* @param property
* @param schema
* @returns {ValidationResult}
*/
function validateValueSync(value, rules, messages, obj, property, schema) {
var promise = validateValue(value, rules, messages, obj, property, schema);
return promise && promise.value;
}
/**
*
* @param rule
* @param expected
* @param value
* @param message
* @param rules
* @param messages
* @param obj
* @param property
* @param schema
* @returns {Promise<boolean>}
*/
function validateRule(rule, expected, value, message, rules, messages, obj, property, schema) {
var initial = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : obj;
var _getRule = getRule(rule),
_getRule$check = _getRule.check,
defaultRule = _getRule$check === void 0 ? noop : _getRule$check,
defaultMessage = _getRule.message;
var overriddenRule = rules && (getPropertyOverride(rules, rule) || rules[rule]);
var overriddenMessage = messages && (getPropertyOverride(messages, rule) || messages[rule]);
var ruleFn = isFunction(overriddenRule) ? overriddenRule : defaultRule;
var ruleMsg = overriddenMessage || message || defaultMessage;
var expects = castArray(expected);
var validations = expects.map(function (exp) {
return handlePromise(ruleFn(value, exp, obj, property, schema, defaultRule, initial));
});
return handlePromises(validations).then(function (results) {
var hasValidResult = results.some(function (result) {
return result === true;
});
if (!hasValidResult) {
var result = results.find(function (result) {
return result !== true;
});
if (isString(result)) {
return result;
} else if (result !== true) {
return formatMessage(ruleMsg, value, expects.join(', '), getProperty(schema, "".concat(property, ".alias")) || property, obj, rule);
}
}
});
}
/**
*
* @param rule
* @param expected
* @param value
* @param message
* @param rules
* @param messages
* @param obj
* @param property
* @param schema
* @returns {boolean}
*/
function validateRuleSync(rule, expected, value, message, rules, messages, obj, property, schema) {
var promise = validateRule(rule, expected, value, message, rules, messages, obj, property, schema);
return promise && promise.value;
}
/**
*
* @param schema
* @param onlyFirstErrors
* @returns {ngValidatorFn}
*/
function ngValidator(schema, onlyFirstErrors) {
return function ngValidatorFn(control) {
var validationResult = validateSync(schema, control.value);
return onlyFirstErrors ? validationResult.getFirstErrors() : validationResult.getErrors();
};
}
/**
*
* @param schema
* @param onlyFirstErrors
* @returns {ngAsyncValidatorFn}
*/
function ngAsyncValidator(schema, onlyFirstErrors) {
return function ngAsyncValidatorFn(control) {
return validate(schema, control.value).then(function (validationResult) {
return onlyFirstErrors ? validationResult.getFirstErrors() : validationResult.getErrors();
});
};
}
/**
*
* @param schema
* @param allErrors
* @returns {reduxFormValidatorFn}
*/
function reduxFormValidator(schema, allErrors) {
return function reduxFormValidatorFn(values) {
var validationResult = validateSync(schema, values);
return allErrors ? validationResult.getErrors() : validationResult.getFirstErrors();
};
}
/**
*
* @param schema
* @param allErrors
* @returns {reduxFormAsyncValidatorFn}
*/
function reduxFormAsyncValidator(schema, allErrors) {
return function reduxFormAsyncValidatorFn(values) {
return validate(schema, values).then(function (validationResult) {
return allErrors ? validationResult.getErrors() : validationResult.getFirstErrors();
});
};
}
var index = /*#__PURE__*/Object.freeze({
ngValidator: ngValidator,
ngAsyncValidator: ngAsyncValidator,
reduxFormValidator: reduxFormValidator,
reduxFormAsyncValidator: reduxFormAsyncValidator
});
/**
* ValidationSchema is util class that
*
* @param {Object} schema -
* @constructor
*/
function ValidationSchema(schema) {
this._schema = schema;
this.validate = function (obj) {
return validate(schema, obj);
};
this.validateSync = function (obj) {
return validateSync(schema, obj);
};
this.validateProperty = function (property, obj) {
return validateProperty(property, obj, schema);
};
this.validatePropertySync = function (property, obj) {
return validatePropertySync(property, obj);
};
}
exports.ValidationResult = ValidationResult;
exports.ValidationSchema = ValidationSchema;
exports.default = validate;
exports.getRule = getRule;
exports.hasRule = hasRule;
exports.libs = index;
exports.overrideRule = overrideRule;
exports.overrideRuleMessage = overrideRuleMessage;
exports.registerRule = registerRule;
exports.registerRules = registerRules;
exports.rules = rules;
exports.validate = validate;
exports.validateArray = validateArray;
exports.validateArraySync = validateArraySync;
exports.validateObject = validateObject;
exports.validateObjectSync = validateObjectSync;
exports.validateProperty = validateProperty;
exports.validatePropertySync = validatePropertySync;
exports.validateRule = validateRule;
exports.validateRuleSync = validateRuleSync;
exports.validateSync = validateSync;
exports.validateValue = validateValue;
exports.validateValueSync = validateValueSync;
Object.defineProperty(exports, '__esModule', { value: true });
}));
//# sourceMappingURL=valirator.umd.js.map