Repository URL to install this package:
|
Version:
1.2.18 ▾
|
import {
defineFinal,
} from 'chain-able-boost'
import {
isFunction,
isString,
isObj,
isArray,
isError,
fromArgumentsToArray,
NO_OP,
} from 'modules/exotic'
/**
* @module debugeh
*/
exports = module.exports = createDebug.debug = createDebug.default = createDebug
exports.coerce = coerce
exports.disable = disable
exports.disableMatching = disableMatching
exports.enable = enable
exports.enabled = enabled
exports.humanize = require('ms')
/**
* The currently active debug mode names, and names to skip.
*/
exports.names = []
exports.skips = []
exports.disabledNames = []
/**
* Map of special "%n" handling functions, for the debug "format" argument.
*
* Valid key names are a single, lower or upper-case letter
* @example "n" and "N".
*/
exports.formatters = {}
/**
* Previous log timestamp.
*/
let prevTime
/**
* Select a color.
* @param {String} namespace
* @return {Number}
* @api private
*/
function selectColor(namespace) {
let hash = 0
let i
// this is lame
for (i in namespace) {
hash = ((hash << 5) - hash) + namespace.charCodeAt(i)
// Convert to 32bit integer
hash |= 0
}
return exports.colors[Math.abs(hash) % exports.colors.length]
}
/**
* Create a debugger with the given `namespace`.
*
* @param {String} namespace
* @return {Function}
* @api public
*/
function createDebug(namespace) {
function debug() {
// disabled?
if (!debug.enabled) {
return
}
let self = debug
// set `diff` timestamp
let curr = +new Date()
let ms = curr - (prevTime || curr)
self.diff = ms
self.prev = prevTime
self.curr = curr
prevTime = curr
// turn the `arguments` into a proper Array
let args = fromArgumentsToArray.apply(this, arguments)
args[0] = exports.coerce(args[0])
if (isString(args[0]) === false) {
// anything else let's inspect with %O
args.unshift('%O')
}
// apply any `formatters` transformations
// @todo - split
let index = 0
args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
// if we encounter an escaped % then don't increase the array index
if (match === '%%') {
return match
}
index++
let formatter = exports.formatters[format]
if (isFunction(formatter)) {
let val = args[index]
match = formatter.call(self, val)
// now we need to remove `args[index]` since it's inlined in the `format`
args.splice(index, 1)
index--
}
return match
})
// apply env-specific formatting (colors, etc.)
let safety = exports.formatArgs
? exports.formatArgs.call(self, args)
: ''
// if disabled, ignore
for (let i = 0; i < exports.disabledNames.length; i++) {
if (exports.disabledNames[i].test(self.namespace)) {
return NO_OP
}
}
// WORKS
return Function.prototype.apply.bind(console.log, console, args)
}
debug.namespace = namespace
debug.enabled = exports.enabled(namespace)
debug.useColors = exports.useColors()
debug.color = selectColor(namespace)
// env-specific initialization logic for debug instances
if (isFunction(exports.init)) {
exports.init(debug)
}
return debug
}
/**
* Enables a debug mode by namespaces. This can include modes
* separated by a colon and wildcards.
*
* @param {String} namespaces
* @api public
*/
function enable(namespaces) {
exports.save(namespaces)
let split = (namespaces || '').split(/[\s,]+/)
let len = split.length
for (let i = 0; i < len; i++) {
if (!split[i]) {
continue
}
// ignore empty strings
namespaces = split[i].replace(/\*/g, '.*?')
if (namespaces[0] === '-') {
exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'))
} else {
exports.names.push(new RegExp('^' + namespaces + '$'))
}
}
}
/**
* Disable debug output.
*
* @name disableWhere
* @api public
*/
function disableMatching(regexp) {
exports.disabledNames.push(regexp)
}
/**
* Disable debug output.
*
* @api public
*/
function disable() {
exports.enable('')
}
/**
* Returns true if the given mode name is enabled, false otherwise.
*
* @name isEnabled
* @param {String} name
* @return {Boolean}
* @api public
*/
function enabled(name) {
let i
let len
// @todo @perf could iterate 1 loop
for (i = 0, len = exports.skips.length; i < len; i++) {
if (exports.skips[i].test(name)) {
return false
}
}
for (i = 0, len = exports.names.length; i < len; i++) {
if (exports.names[i].test(name)) {
return true
}
}
return false
}
/**
* Coerce `val`.
*
* @param {any} val
* @return {any}
* @api private
*/
function coerce(val) {
// if (isError(val)) {
// return val.stack || val.message
// }
return val
}
// @todo defineFinal
defineFinal(console, 'named', createDebug)
defineFinal(console, 'event', createDebug('event'))
defineFinal(console, 'action', createDebug('action'))
// defineFinal(console, 'dev', createDebug('dev'))
// defineFinal(console, 'eh', createDebug)