barrageapi
Version:
A library for sending data to Barrage, an advanced streaming analytics service from MIOsoft
95 lines (88 loc) • 4.27 kB
JavaScript
if (!Number.isInteger) {
Number.isInteger = function isInteger(nVal) {
return typeof nVal === 'number' &&
isFinite(nVal) &&
nVal > -9007199254740992 &&
nVal < 9007199254740992 &&
Math.floor(nVal) === nVal;
};
}
module.exports = exports = function () {
var self = this;
//Built in JS types
var availableTypes = ["Object", "Array", "Arguments", "Function", "Error", "Date", "RegExp", "Math", "JSON", "Number", "String", "Boolean", "Null", "Undefined"];
/**
* Checks the type of a variable
* @param {Object} value The variable to test
* @param {string} type The type that the variable should be
* @param {boolean} required If true, a null/undefined value will cause the check to fail.
* @return {boolean} Returns true if the type check passed, false otherwise.
*/
this.types = function (value, type, required) {
if ((type !== 'null' || type !== 'undefined') && value == null) { return !required; }
var typeCheckingFunction = this.typeFunctions[type.toLowerCase()];
if (typeCheckingFunction) {
return typeCheckingFunction(value);
}
console.error("Unknown Type '" + type + "'encountered when checking '" + value + "'");
return false;
};
this.typeFunctions = {
//Add complex types here or add them at runtime with addType()
'integer' : function (value) {
var pass = Number.isInteger(value);
if (!pass) { console.warn("Value '" + value + "' is not of type integer"); }
return pass;
},
'untyped' : function () { return true; }
};
//Add type checking functions for the built-in types
availableTypes.forEach(function (name) {
self.typeFunctions[name.toLowerCase()] = function (value) {
var pass = Object.prototype.toString.call(value) === "[object " + name + "]";
if (!pass) { console.warn("Value '" + value + "' is not of type " + name); }
return pass;
};
});
/**
* Adds a new type. This new type can be used by types() with {{typeName}}
* If a type already exists, you'll have to remove it first if you want to change its function.
* @param {string} typeName The name of the new type
* @param {function} func A function that returns true if its first argument is of type typeName, false otherwise.
*/
this.addType = function (typeName, func) {
if (!this.checkArguments(arguments, ['string', 'function'])) { return; }
if (this.typeFunctions[typeName.toLowerCase()]) { console.log("Type already exists"); return; }
if (typeName[typeName.length - 1] === "?") { console.log("Last character of typename cannot be a question mark ('?')."); return; }
this.typeFunctions[typeName.toLowerCase()] = func;
};
/**
* Remove an existing type.
* @param {string} typeName The name of the type to remove
*/
this.removeType = function (typeName) {
if (!this.checkArguments(arguments, ['string'])) { return; }
typeName = typeName.toLowerCase();
if (availableTypes.indexOf(typeName.charAt(0).toUpperCase() + typeName.slice(1).toLowerCase()) > -1) { console.warn("You can not delete a built-in type"); return; }
if (!this.typeFunctions[typeName]) { console.log("Type does not exist"); return; }
delete this.typeFunctions[typeName];
};
/**
* Checks all arguments of a function and returns true if all of them match a set of types.
* @param {Arguments} args The arguments object from a function.
* @param {Array} types An array of strings equal in length to arguments that specifies what type each argument is.
* @return {boolean} Returns true if all types are correct, false otherwise.
*/
//TODO stop leaking arguments
this.checkArguments = function (args, types) {
if (!(this.types(args, 'arguments', true) && this.types(types, 'array', true))) { return false; }
if (args.length > types.length) { console.error("Arguments length must be less than or equal to Types length"); }
for (var i = 0; i < types.length; i++) {
if (!this.types(types[i], 'string', true)) { continue; }
var isRequired = types[i][types[i].length - 1] !== "?";
var typeName = (isRequired) ? types[i] : types[i].substring(0, types[i].length - 1);
if (!this.types(args[i], typeName, isRequired)) { return false; }
}
return true;
};
};