avocado-type-checker
Version:
A javascript type checker. Also a tasty fruit with megafauna dispersal syndrome, leading to an evolutionary anachronism.
168 lines (146 loc) • 14.9 kB
JavaScript
;
var findByType = function(arr, typeName) {
if (!Array.isArray(arr)) {
throw new Error('arr needs to be an array');
}
if (typeof typeName !== 'string') {
throw new Error('typeName needs to be string');
}
for (var i = 0; i < arr.length; i++) {
if (arr[i].typeName === typeName) {
return i;
}
}
return -1;
};
var types = [];
// av's main function is a getter-setter-combo
// it expects a default value and a validation function
// the validation function should return the validated value or throw an exception
// it shouldn't return 'false' for non-validating values
var av = function (i, validate){
// we offer a shortcut to get types when only one argument is provided
if (arguments.length === 1) {
return av.type(i);
}
// we store the value in private scope
var _i;
// our getter-setter-combo including validation
var me = function (d){
if (!arguments.length) {
if (typeof _i === 'object'){
var o = {};
for (var prop in _i){
o[prop] = _i[prop]();
}
return o;
} else {
return _i;
}
}
_i = validate(d);
// if _i is an object we expose the getter/setter methods of its attributes
if (typeof _i === 'object'){
for (var prop_object in _i){
me[prop_object] = _i[prop_object];
}
}
};
// we initialize the getter-setter-combo with the provided value
me(i);
// return the getter-setter-combo (allows chaining, among other things)
return me;
};
av.type = function() {
var typeIndex;
var typeName;
var typeData;
if (arguments.length === 0) {
throw new Error('av.type requires at least one argument.');
}
typeName = arguments[0];
typeIndex = findByType(types, typeName);
// get a type by name
if (arguments.length === 1) {
if (typeIndex === -1) {
throw new Error('type not found');
}
return types[typeIndex].type;
// set a type by name
} else if (arguments.length === 2) {
typeData = arguments[1];
if (typeIndex !== -1) {
throw new Error('type specification already exists.');
}
if (typeof typeData === 'function') {
types.push({
typeName: typeName,
type: function(i) {
return av(i, typeData);
}
});
} else if (typeof typeData === 'object') {
types.push({
typeName: typeName,
type: function(i) {
return av(i, function(d) {
if (typeof d === 'object'){
var _i = {};
for (var prop in typeData){
_i[prop] = av.type(typeData[prop])(d[prop]);
}
return _i;
} else throw 'not a valid object';
});
}
});
} else {
throw new Error('argument 2 typeData must be either a function or object.');
}
return av;
}
throw new Error('invalid amount of arguments for av.type()');
};
// isValid allows you to test if a value (v) is a valid type (t)
av.isValid = function (t, v){
try {
t(v);
return true;
} catch (err) {
return false;
}
};
// a boolean type and its validation function
av.type('boolean', function (d){
if (typeof d === 'boolean') {
return d;
} else throw new Error('d is not boolean');
});
// http://stackoverflow.com/a/20779354/2266116
var isInteger = function (nVal){
return typeof nVal === 'number' && isFinite(nVal) && nVal > -9007199254740992 && nVal < 9007199254740992 && Math.floor(nVal) === nVal;
};
av.type('int', function(d) {
if(!isInteger(d)) {
throw new Error('d is not an integer');
}
return d;
});
av.type('float', function(d){
if(typeof d !== 'number') {
throw 'd is not a number';
}
return d;
});
av.type('string', function (d){
if (typeof d === 'string') {
return d;
} else throw 'd is not a string';
});
av.type('collection', function (d){
if (d && d.constructor === Array) {
return d;
} else throw 'not an array';
});
module.exports = av;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIi4uL3NyYy9maW5kQnlUeXBlLmpzIiwiLi4vc3JjL2F2b2NhZG8uanMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oYXJyLCB0eXBlTmFtZSkge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignYXJyIG5lZWRzIHRvIGJlIGFuIGFycmF5Jyk7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGVOYW1lICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcigndHlwZU5hbWUgbmVlZHMgdG8gYmUgc3RyaW5nJyk7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGlmIChhcnJbaV0udHlwZU5hbWUgPT09IHR5cGVOYW1lKSB7XG4gICAgICByZXR1cm4gaTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gLTE7XG59XG4iLCJpbXBvcnQgeyBkZWZhdWx0IGFzIGZpbmRCeVR5cGUgfSBmcm9tICcuL2ZpbmRCeVR5cGUnO1xuXG52YXIgdHlwZXMgPSBbXTtcblxuLy8gYXYncyBtYWluIGZ1bmN0aW9uIGlzIGEgZ2V0dGVyLXNldHRlci1jb21ib1xuLy8gaXQgZXhwZWN0cyBhIGRlZmF1bHQgdmFsdWUgYW5kIGEgdmFsaWRhdGlvbiBmdW5jdGlvblxuLy8gdGhlIHZhbGlkYXRpb24gZnVuY3Rpb24gc2hvdWxkIHJldHVybiB0aGUgdmFsaWRhdGVkIHZhbHVlIG9yIHRocm93IGFuIGV4Y2VwdGlvblxuLy8gaXQgc2hvdWxkbid0IHJldHVybiAnZmFsc2UnIGZvciBub24tdmFsaWRhdGluZyB2YWx1ZXNcbnZhciBhdiA9IGZ1bmN0aW9uIChpLCB2YWxpZGF0ZSl7XG4gIC8vIHdlIG9mZmVyIGEgc2hvcnRjdXQgdG8gZ2V0IHR5cGVzIHdoZW4gb25seSBvbmUgYXJndW1lbnQgaXMgcHJvdmlkZWRcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gYXYudHlwZShpKTtcbiAgfVxuXG4gIC8vIHdlIHN0b3JlIHRoZSB2YWx1ZSBpbiBwcml2YXRlIHNjb3BlXG4gIHZhciBfaTtcbiAgLy8gb3VyIGdldHRlci1zZXR0ZXItY29tYm8gaW5jbHVkaW5nIHZhbGlkYXRpb25cbiAgdmFyIG1lID0gZnVuY3Rpb24gKGQpe1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgaWYgKHR5cGVvZiBfaSA9PT0gJ29iamVjdCcpe1xuICAgICAgICB2YXIgbyA9IHt9O1xuICAgICAgICBmb3IgKHZhciBwcm9wIGluIF9pKXtcbiAgICAgICAgICBvW3Byb3BdID0gX2lbcHJvcF0oKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBfaTtcbiAgICAgIH1cbiAgICB9XG4gICAgX2kgPSB2YWxpZGF0ZShkKTtcbiAgICAvLyBpZiBfaSBpcyBhbiBvYmplY3Qgd2UgZXhwb3NlIHRoZSBnZXR0ZXIvc2V0dGVyIG1ldGhvZHMgb2YgaXRzIGF0dHJpYnV0ZXNcbiAgICBpZiAodHlwZW9mIF9pID09PSAnb2JqZWN0Jyl7XG4gICAgICBmb3IgKHZhciBwcm9wX29iamVjdCBpbiBfaSl7XG4gICAgICAgIG1lW3Byb3Bfb2JqZWN0XSA9IF9pW3Byb3Bfb2JqZWN0XTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8vIHdlIGluaXRpYWxpemUgdGhlIGdldHRlci1zZXR0ZXItY29tYm8gd2l0aCB0aGUgcHJvdmlkZWQgdmFsdWVcbiAgbWUoaSk7XG4gIC8vIHJldHVybiB0aGUgZ2V0dGVyLXNldHRlci1jb21ibyAoYWxsb3dzIGNoYWluaW5nLCBhbW9uZyBvdGhlciB0aGluZ3MpXG4gIHJldHVybiBtZTtcbn07XG5cbmF2LnR5cGUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHR5cGVJbmRleDtcbiAgdmFyIHR5cGVOYW1lO1xuICB2YXIgdHlwZURhdGE7XG5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2F2LnR5cGUgcmVxdWlyZXMgYXQgbGVhc3Qgb25lIGFyZ3VtZW50LicpO1xuICB9XG5cbiAgdHlwZU5hbWUgPSBhcmd1bWVudHNbMF07XG4gIHR5cGVJbmRleCA9IGZpbmRCeVR5cGUodHlwZXMsIHR5cGVOYW1lKTtcblxuICAvLyBnZXQgYSB0eXBlIGJ5IG5hbWVcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICBpZiAodHlwZUluZGV4ID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0eXBlIG5vdCBmb3VuZCcpO1xuICAgIH1cbiAgICByZXR1cm4gdHlwZXNbdHlwZUluZGV4XS50eXBlO1xuICAvLyBzZXQgYSB0eXBlIGJ5IG5hbWVcbiAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XG4gICAgdHlwZURhdGEgPSBhcmd1bWVudHNbMV07XG4gICAgaWYgKHR5cGVJbmRleCAhPT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndHlwZSBzcGVjaWZpY2F0aW9uIGFscmVhZHkgZXhpc3RzLicpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHR5cGVEYXRhID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0eXBlcy5wdXNoKHtcbiAgICAgICAgdHlwZU5hbWU6IHR5cGVOYW1lLFxuICAgICAgICB0eXBlOiBmdW5jdGlvbihpKSB7XG4gICAgICAgICAgcmV0dXJuIGF2KGksIHR5cGVEYXRhKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdHlwZURhdGEgPT09ICdvYmplY3QnKSB7XG4gICAgICB0eXBlcy5wdXNoKHtcbiAgICAgICAgdHlwZU5hbWU6IHR5cGVOYW1lLFxuICAgICAgICB0eXBlOiBmdW5jdGlvbihpKSB7XG4gICAgICAgICAgcmV0dXJuIGF2KGksIGZ1bmN0aW9uKGQpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZCA9PT0gJ29iamVjdCcpe1xuICAgICAgICAgICAgICB2YXIgX2kgPSB7fTtcbiAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiB0eXBlRGF0YSl7XG4gICAgICAgICAgICAgICAgX2lbcHJvcF0gPSBhdi50eXBlKHR5cGVEYXRhW3Byb3BdKShkW3Byb3BdKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gX2k7XG4gICAgICAgICAgICB9IGVsc2UgdGhyb3cgJ25vdCBhIHZhbGlkIG9iamVjdCc7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FyZ3VtZW50IDIgdHlwZURhdGEgbXVzdCBiZSBlaXRoZXIgYSBmdW5jdGlvbiBvciBvYmplY3QuJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF2O1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGFtb3VudCBvZiBhcmd1bWVudHMgZm9yIGF2LnR5cGUoKScpO1xufTtcblxuLy8gaXNWYWxpZCBhbGxvd3MgeW91IHRvIHRlc3QgaWYgYSB2YWx1ZSAodikgaXMgYSB2YWxpZCB0eXBlICh0KVxuYXYuaXNWYWxpZCA9IGZ1bmN0aW9uICh0LCB2KXtcbiAgdHJ5IHtcbiAgICB0KHYpO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbi8vIGEgYm9vbGVhbiB0eXBlIGFuZCBpdHMgdmFsaWRhdGlvbiBmdW5jdGlvblxuYXYudHlwZSgnYm9vbGVhbicsIGZ1bmN0aW9uIChkKXtcbiAgaWYgKHR5cGVvZiBkID09PSAnYm9vbGVhbicpIHtcbiAgICByZXR1cm4gZDtcbiAgfSBlbHNlIHRocm93IG5ldyBFcnJvcignZCBpcyBub3QgYm9vbGVhbicpO1xufSk7XG5cbi8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIwNzc5MzU0LzIyNjYxMTZcbnZhciBpc0ludGVnZXIgPSBmdW5jdGlvbiAoblZhbCl7XG4gIHJldHVybiB0eXBlb2YgblZhbCA9PT0gJ251bWJlcicgJiYgaXNGaW5pdGUoblZhbCkgJiYgblZhbCA+IC05MDA3MTk5MjU0NzQwOTkyICYmIG5WYWwgPCA5MDA3MTk5MjU0NzQwOTkyICYmIE1hdGguZmxvb3IoblZhbCkgPT09IG5WYWw7XG59O1xuXG5hdi50eXBlKCdpbnQnLCBmdW5jdGlvbihkKSB7XG4gIGlmKCFpc0ludGVnZXIoZCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2QgaXMgbm90IGFuIGludGVnZXInKTtcbiAgfVxuICByZXR1cm4gZDtcbn0pO1xuXG5hdi50eXBlKCdmbG9hdCcsIGZ1bmN0aW9uKGQpe1xuICBpZih0eXBlb2YgZCAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyAnZCBpcyBub3QgYSBudW1iZXInO1xuICB9XG4gIHJldHVybiBkO1xufSk7XG5cbmF2LnR5cGUoJ3N0cmluZycsIGZ1bmN0aW9uIChkKXtcbiAgaWYgKHR5cGVvZiBkID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBkO1xuICB9IGVsc2UgdGhyb3cgJ2QgaXMgbm90IGEgc3RyaW5nJztcbn0pO1xuXG5hdi50eXBlKCdjb2xsZWN0aW9uJywgZnVuY3Rpb24gKGQpe1xuICBpZiAoZCAmJiBkLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xuICAgIHJldHVybiBkO1xuICB9IGVsc2UgdGhyb3cgJ25vdCBhbiBhcnJheSc7XG59KTtcblxuZXhwb3J0IGRlZmF1bHQgYXY7XG5cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGlCQUFlLFNBQVMsR0FBRyxFQUFFLFFBQVEsRUFBRTtFQUNyQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtJQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7R0FDN0M7O0VBRUQsSUFBSSxPQUFPLFFBQVEsS0FBSyxR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