hazmat
Version:
Validation and sanitization of input parameters
160 lines (133 loc) • 4.96 kB
JavaScript
// Actual Hazmat Code
var HazmatBuilder = function(_,root) {
// top level module
var Hazmat = function(config) {
this.config = config || {};
if(!_.isObject(this.config)) {
throw new Error('Hazmat is not initialized properly');
}
this.fail = _.isFunction(this.config.fail) ? this.config.fail : Hazmat.fail;
this.warn = _.isFunction(this.config.warn) ? this.config.warn : Hazmat.warn;
this.log = _.isFunction(this.config.log) ? this.config.log : Hazmat.log;
};
_.extend(Hazmat, {
// constants
ID_REGEX : /^[\_A-Za-z0-9]+$/,
// factory
create : function(config) {
return new Hazmat(config);
},
// noConflict
noConflict : function() {
root.Hazmat = Hazmat.original;
return Hazmat;
},
// default log function
log : function() {
if(console && _.isFunction(console.log)) {
console.log.apply(console, arguments);
}
},
// default fail function
fail : function(_reason, _data) {
var reason = _reason || "", data = _data || {};
Hazmat.log('Hazmat Failure::', reason, data);
throw new Error('Hazmat Failure '+reason.toString());
},
// default warn function
warn : function(_reason, _data) {
var reason = _reason || "", data = _data || {};
Hazmat.log('Hazmat Warning::', reason, data);
},
// global fixers
fixDomId : function(_value) {
if(_.isString(_value) && _value.length > 0) {
return _value.replace(/[^A-Za-z0-9\_]/g,'');
} else {
return null;
}
},
// global testers
isDomId : function(value) {
return _.isString(value) && value.match(Hazmat.ID_REGEX);
},
__placeholder : true
});
_.extend(Hazmat.prototype, {
_safeValue : function(name, value, fallback, type) {
// make fallback safe and eat exceptions
var _fallback = fallback;
if(_.isFunction(fallback)) {
fallback = _.once(function() {
try {
return _fallback.apply(this, arguments);
} catch(e) {
}
});
}
if(type.checker(value)) {
return value;
} else if(type.evalFallback && _.isFunction(fallback) && type.checker(fallback(value))){
this.warn('Expected valid '+type.name+' for '+name+' but was able to sanitize it:', [value, fallback(value)]);
return fallback(value);
} else if(type.checker(_fallback)){
this.warn('Expected valid '+type.name+' for '+name+' but was able to fallback to default value:', [value, _fallback]);
return _fallback;
} else {
this.fail('Expected valid '+type.name+' for '+name+' but received:', value);
}
},
safeString : function(name, value, fallback) {
return this._safeValue(name, value, fallback, {name: 'String', checker: _.isString, evalFallback:true});
},
safeStringOrNull : function(name, value, fallback) {
if(value == null) {
return value;
} else {
return this._safeValue(name, value, fallback, {name: 'String', checker: _.isString, evalFallback:true});
}
},
safeDomId : function(name, value, fallback) {
return this._safeValue(name, value, fallback, {name: 'DOM ID', checker: Hazmat.isDomId, evalFallback:true});
},
safeFunction : function(name, value, fallback) {
return this._safeValue(name, value, fallback, {name: 'Function', checker: _.isFunction, evalFallback:false});
},
safeFunctionOrNull : function(name, value, fallback) {
if(value == null) {
return value;
} else {
return this._safeValue(name, value, fallback, {name: 'Function', checker: _.isFunction, evalFallback:false});
}
},
safeObject : function(name, value, fallback) {
return this._safeValue(name, value, fallback, {name: 'Object', checker: _.isObject, evalFallback:false});
},
safeObjectOrNull : function(name, value, fallback) {
if(value == null) {
return value;
} else {
return this._safeValue(name, value, fallback, {name: 'Object', checker: _.isObject, evalFallback:false});
}
},
safeArray : function(name, value, fallback) {
return this._safeValue(name, value, fallback, {name: 'Array', checker: _.isArray, evalFallback:false});
},
safeArrayOfElements : function(name, value, elementValidator, fallback) {
var safeArray = this._safeValue(name, value, fallback, {name: 'Array', checker: _.isArray, evalFallback:false});
return _.map(safeArray, elementValidator);
},
__placeholder:true
});
return Hazmat;
};
// Integration with Node.js/Browser
if(typeof window !== 'undefined' && typeof window._ !== 'undefined') {
var hazmat = HazmatBuilder(window._, window);
hazmat.original = window.Hazmat;
window.Hazmat = hazmat;
} else {
var _ = require('underscore');
var hazmat = HazmatBuilder(_);
_.extend(exports,hazmat);
}