UNPKG

barrageapi

Version:

A library for sending data to Barrage, an advanced streaming analytics service from MIOsoft

95 lines (88 loc) 4.27 kB
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; }; };