Skip to content

Instantly share code, notes, and snippets.

@jkusachi
Created January 11, 2016 01:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkusachi/321aaa52714af6554d15 to your computer and use it in GitHub Desktop.
Save jkusachi/321aaa52714af6554d15 to your computer and use it in GitHub Desktop.
'use strict';
var filter = require('lodash/collection/filter');
var typeRegexes = {
/*eslint-disable */
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,
/*eslint-enable */
number: /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/,
integer: /^-?\d+$/,
digits: /^\d+$/,
alphanum: /^\w+$/i,
url: new RegExp(
"^" +
// protocol identifier
"(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional
// user:pass authentication
"(?:\\S+(?::\\S*)?@)?" +
"(?:" +
// IP address exclusion
// private & local networks
// "(?!(?:10|127)(?:\\.\\d{1,3}){3})" + // ** mod: allow local networks
// "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
// "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
// IP address dotted notation octets
// excludes loopback network 0.0.0.0
// excludes reserved space >= 224.0.0.0
// excludes network & broacast addresses
// (first & last IP address of each class)
"(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
"(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
"(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
"|" +
// host name
"(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" +
// domain name
"(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" +
// TLD identifier
"(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
")" +
// port number
"(?::\\d{2,5})?" +
// resource path
"(?:/\\S*)?" +
"$", 'i'
)
};
var validators = {
// Validates that a required field has been filled with a non blank value
required: {
validate: function(value) {
return /\S/.test(value);
},
errorMsg: function () {
return `is required`;
}
},
// Validates that a field is a valid type (email, integer, digits, alphanum, url)
type: {
validate: function(value, type) {
var regex = typeRegexes[type];
if (!regex) {
throw new Error('validator type `' + type + '` is not supported');
}
return regex.test(value);
},
errorMsg: function (type) {
return `is not valid ${type}`;
}
},
// Validates that the length of a string is at least as long as the given limit.
minlength: {
validate: function (value, requirement) {
return value.length >= requirement;
},
errorMsg: function () {
return `is shorter than ${requirement}`;
}
},
// Validates that the length of a string is not longer than the given limit.
maxlength: {
validate: function (value, requirement) {
return value.length <= requirement;
},
errorMsg: function (requirement) {
return `is longer than ${requirement}`;
}
},
// Validates that a given string length is between some minimum and maximum value.
length: {
validate: function (value, requirement) {
return value.length >= requirement.min && value.length <= requirement.max;
},
errorMsg: function (requirement) {
return `is not between ${requirement.min} and ${requirement.max}`;
}
},
// Validates that a given number is greater than or equal to some minimum number.
min: {
validate: function (value, requirement) {
return value >= requirement;
},
errorMsg: function (requirement) {
return `is smaller than ${requirement}`;
}
},
// Validates that a given number is less than or equal to some maximum number.
max: {
validate: function (value, requirement) {
return value <= requirement;
},
errorMsg: function (requirement) {
return `is larger than ${requirement}`;
}
},
// Validates that a given number is between some minimum and maximum number.
range: {
validate: function (value, requirement) {
return value >= requirement.min && value <= requirement.max;
},
errorMsg: function (requirement) {
return `is not between ${requirement.min} and ${requirement.max}`;
}
},
// Validates that a value matches a specific regular expression (regex).
pattern: {
validate: function(value, regexp) {
return regexp.test(value);
},
errorMsg: function (regexp) {
return `does not match pattern`;
}
}
};
var validatorsList = Object.keys(validators);
var validateNameByRawName = {};
function groupToUpperCase (match, group) {
return group.toUpperCase();
}
function toValidateName(validation) {
return 'validate' + validation
.replace(/^(.)/, groupToUpperCase)
.replace(/_(.)/g, groupToUpperCase);
}
validatorsList.forEach(function (validator) {
validateNameByRawName[validator] = toValidateName(validator);
});
function validate(value, props) {
var errors = filter(validatorsList, (validator) => {
var validateName = validateNameByRawName[validator];
return Object.prototype.hasOwnProperty.call(props, validateName);
})
.map((validator) => {
var validateName = validateNameByRawName[validator];
if (!validators[validator].validate(value, props[validateName])) {
return validators[validator].errorMsg(props[validateName]);
} else {
return null;
}
})
.filter((error) => error !== null);
return errors.length ? errors : null;
}
module.exports = {
isValid() {
return !validate(this.getValue(), this.props);
},
validate() {
return validate(this.getValue(), this.props);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment