argument-validator
Version:
Simple Argument Validator for JavaScript
234 lines (181 loc) • 5.84 kB
JavaScript
(function () {
/*
* We only define the is/has* functions and use the
* demand() function to build the demands, also the
* getDemandMethodNameByValidatorKey() (yeh, I know it's an ugly name :()
* build the demand method based in the .is/has methods
*/
var v = { };
if (typeof module !== 'undefined' && module.exports) {
module.exports = v;
} else {
this.ArgumentValidator = v;
}
var demand = function (demandMethodName, validator) {
return function (value /* ... more args, name */) {
if (validator.apply(v, arguments)) {
return true;
}
var name = null;
if (arguments.length > 1) {
var name = Array.prototype.slice.call(arguments, -1)[0];
}
if (v.isJson(value)) {
value = JSON.stringify(value);
}
var msg = "Invalid " + demandMethodName + " value: " + value;
if (v.isString(name)) {
msg += "\nArgument Name: " + name;
}
if (v.isArray(arguments[1])) {
msg += "\nKeys: " + arguments[1].join(", ");
}
throw new Error(msg);
}
};
var getDemandMethodNameByValidatorKey = function (key) {
var prefix = [ 'is', 'has' ];
var prefixLength = null;
for (var i = 0; i < prefix.length; i++) {
prefixLength = prefix[i].length;
if (key.slice(0, prefixLength) === prefix[i]) {
break;
}
}
var demandMethodName = key.slice(prefixLength + 1);
var firstLetter = key.slice(prefixLength, prefixLength + 1).toLowerCase();
var name = firstLetter + demandMethodName;
return name;
};
var hasKeysWith = function (validator, obj, keys) {
if (!v.isObjectOrEmpty(obj) || !v.isArrayOrEmpty(keys)) {
return false;
}
var length = keys.length;
for (var i = 0; i < length; i++) {
if (!Object.prototype.hasOwnProperty.call(obj, keys[i])) {
return false;
}
if (!validator(obj[keys[i]])) {
return false;
}
}
return true;
};
var isArrayOf = function (validator, arr) {
if (!v.isArray(arr)) {
return false;
}
var length = arr.length;
for (var i = 0; i < length; i++) {
if (!validator(arr[i])) {
return false;
}
}
return true;
};
v.isNotNull = function (value) {
return value !== null && value !== undefined;
};
v.isInstanceOf = function(type, value) {
return value instanceof type;
};
v.isType = function (type, value) {
return Object.prototype.toString.call(value) === "[object " + type + "]";
};
v.isBoolean = function (value) {
return ([ 1, 0, true, false ].indexOf(value) > -1);
};
v.isStringOrEmpty = function (value) {
return v.isType("String", value);
};
v.isString = function (value) {
if (!v.isStringOrEmpty(value)) {
return false;
}
return /\S/.test(value);
};
v.isNumber = function (value) {
if (!v.isType('Number', value)) {
return false;
}
return isFinite(value) && !isNaN(parseFloat(value));
};
v.isArrayOrEmpty = function (arr) {
return v.isType("Array", arr);
};
v.isArray = function (arr) {
if (!v.isArrayOrEmpty(arr)) {
return false;
}
return arr.length > 0;
};
v.isArrayOfNumbers = function (arr) {
return isArrayOf(v.isNumber, arr);
};
v.isArrayOfObjects = function (arr) {
return isArrayOf(v.isObject, arr);
};
v.isObjectOrEmpty = function (obj) {
return v.isType("Object", obj);
};
v.isObject = function (obj) {
if (!v.isObjectOrEmpty(obj)) {
return false;
}
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
return true;
}
}
return false;
};
v.isJson = function (value) {
if (!v.isObjectOrEmpty(value)) {
return false;
}
try {
JSON.stringify(value);
} catch (err) {
return false;
}
return true;
};
v.isJsonString = function (value) {
if (!v.isString(value)) {
return false;
}
try {
JSON.parse(value);
} catch (err) {
return false;
}
return true;
};
v.hasKeys = function (obj, keys) {
return hasKeysWith(v.isNotNull, obj, keys);
};
v.hasKeysWithNumber = v.hasNumberKeys = function (obj, keys) {
return hasKeysWith(v.isNumber, obj, keys);
};
v.hasKeysWithString = v.hasStringKeys = function (obj, keys) {
return hasKeysWith(v.isString, obj, keys);
};
v.hasKeysWithObject = v.hasObjectKeys = function (obj, keys) {
return hasKeysWith(v.isObject, obj, keys);
};
v.hasKeysWithStringOrEmpty = v.hasStringOrEmptyKeys = function (obj, keys) {
return hasKeysWith(v.isStringOrEmpty, obj, keys);
};
v.hasKeysWithObjectOrEmpty = v.hasObjectOrEmptyKeys = function (obj, keys) {
return hasKeysWith(v.isObjectOrEmpty, obj, keys);
};
v.isFunction = function (value) {
return v.isInstanceOf(Function, value);
};
// build demand functions
for (var key in v) {
var demandMethodName = getDemandMethodNameByValidatorKey(key);
v[demandMethodName] = demand(demandMethodName, v[key]);
}
}).call(this);