/** * Contains all configured adapters for the given environment. * * @type {Array} * @public */ var adapters = []; /** * Contains all modifier functions. * * @typs {Array} * @public */ var modifiers = []; /** * Our default logger. * * @public */ var logger = function devnull() {}; /** * Register a new adapter that will used to find environments. * * @param {Function} adapter A function that will return the possible env. * @returns {Boolean} Indication of a successful add. * @public */ function use(adapter) { if (~adapters.indexOf(adapter)) return false; adapters.push(adapter); return true; } /** * Assign a new log method. * * @param {Function} custom The log method. * @public */ function set(custom) { logger = custom; } /** * Check if the namespace is allowed by any of our adapters. * * @param {String} namespace The namespace that needs to be enabled * @returns {Boolean|Promise} Indication if the namespace is enabled by our adapters. * @public */ function enabled(namespace) { var async = []; for (var i = 0; i < adapters.length; i++) { if (adapters[i].async) { async.push(adapters[i]); continue; } if (adapters[i](namespace)) return true; } if (!async.length) return false; // // Now that we know that we Async functions, we know we run in an ES6 // environment and can use all the API's that they offer, in this case // we want to return a Promise so that we can `await` in React-Native // for an async adapter. // return new Promise(function pinky(resolve) { Promise.all( async.map(function prebind(fn) { return fn(namespace); }) ).then(function resolved(values) { resolve(values.some(Boolean)); }); }); } /** * Add a new message modifier to the debugger. * * @param {Function} fn Modification function. * @returns {Boolean} Indication of a successful add. * @public */ function modify(fn) { if (~modifiers.indexOf(fn)) return false; modifiers.push(fn); return true; } /** * Write data to the supplied logger. * * @param {Object} meta Meta information about the log. * @param {Array} args Arguments for console.log. * @public */ function write() { logger.apply(logger, arguments); } /** * Process the message with the modifiers. * * @param {Mixed} message The message to be transformed by modifers. * @returns {String} Transformed message. * @public */ function process(message) { for (var i = 0; i < modifiers.length; i++) { message = modifiers[i].apply(modifiers[i], arguments); } return message; } /** * Introduce options to the logger function. * * @param {Function} fn Calback function. * @param {Object} options Properties to introduce on fn. * @returns {Function} The passed function * @public */ function introduce(fn, options) { var has = Object.prototype.hasOwnProperty; for (var key in options) { if (has.call(options, key)) { fn[key] = options[key]; } } return fn; } /** * Nope, we're not allowed to write messages. * * @returns {Boolean} false * @public */ function nope(options) { options.enabled = false; options.modify = modify; options.set = set; options.use = use; return introduce(function diagnopes() { return false; }, options); } /** * Yep, we're allowed to write debug messages. * * @param {Object} options The options for the process. * @returns {Function} The function that does the logging. * @public */ function yep(options) { /** * The function that receives the actual debug information. * * @returns {Boolean} indication that we're logging. * @public */ function diagnostics() { var args = Array.prototype.slice.call(arguments, 0); write.call(write, options, process(args, options)); return true; } options.enabled = true; options.modify = modify; options.set = set; options.use = use; return introduce(diagnostics, options); } /** * Simple helper function to introduce various of helper methods to our given * diagnostics function. * * @param {Function} diagnostics The diagnostics function. * @returns {Function} diagnostics * @public */ module.exports = function create(diagnostics) { diagnostics.introduce = introduce; diagnostics.enabled = enabled; diagnostics.process = process; diagnostics.modify = modify; diagnostics.write = write; diagnostics.nope = nope; diagnostics.yep = yep; diagnostics.set = set; diagnostics.use = use; return diagnostics; }