3 * This is the common logic for both the Node.js and web browser
4 * implementations of `debug()`.
6 * Expose `debug()` as the module.
9 exports = module.exports = createDebug.debug = createDebug['default'] = createDebug;
10 exports.coerce = coerce;
11 exports.disable = disable;
12 exports.enable = enable;
13 exports.enabled = enabled;
14 exports.humanize = require('ms');
17 * The currently active debug mode names, and names to skip.
24 * Map of special "%n" handling functions, for the debug "format" argument.
26 * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
29 exports.formatters = {};
32 * Previous log timestamp.
39 * @param {String} namespace
44 function selectColor(namespace) {
47 for (i in namespace) {
48 hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
49 hash |= 0; // Convert to 32bit integer
52 return exports.colors[Math.abs(hash) % exports.colors.length];
56 * Create a debugger with the given `namespace`.
58 * @param {String} namespace
63 function createDebug(namespace) {
67 if (!debug.enabled) return;
71 // set `diff` timestamp
72 var curr = +new Date();
73 var ms = curr - (prevTime || curr);
79 // turn the `arguments` into a proper Array
80 var args = new Array(arguments.length);
81 for (var i = 0; i < args.length; i++) {
82 args[i] = arguments[i];
85 args[0] = exports.coerce(args[0]);
87 if ('string' !== typeof args[0]) {
88 // anything else let's inspect with %O
92 // apply any `formatters` transformations
94 args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
95 // if we encounter an escaped % then don't increase the array index
96 if (match === '%%') return match;
98 var formatter = exports.formatters[format];
99 if ('function' === typeof formatter) {
100 var val = args[index];
101 match = formatter.call(self, val);
103 // now we need to remove `args[index]` since it's inlined in the `format`
104 args.splice(index, 1);
110 // apply env-specific formatting (colors, etc.)
111 exports.formatArgs.call(self, args);
113 var logFn = debug.log || exports.log || console.log.bind(console);
114 logFn.apply(self, args);
117 debug.namespace = namespace;
118 debug.enabled = exports.enabled(namespace);
119 debug.useColors = exports.useColors();
120 debug.color = selectColor(namespace);
122 // env-specific initialization logic for debug instances
123 if ('function' === typeof exports.init) {
131 * Enables a debug mode by namespaces. This can include modes
132 * separated by a colon and wildcards.
134 * @param {String} namespaces
138 function enable(namespaces) {
139 exports.save(namespaces);
144 var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
145 var len = split.length;
147 for (var i = 0; i < len; i++) {
148 if (!split[i]) continue; // ignore empty strings
149 namespaces = split[i].replace(/\*/g, '.*?');
150 if (namespaces[0] === '-') {
151 exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
153 exports.names.push(new RegExp('^' + namespaces + '$'));
159 * Disable debug output.
169 * Returns true if the given mode name is enabled, false otherwise.
171 * @param {String} name
176 function enabled(name) {
178 for (i = 0, len = exports.skips.length; i < len; i++) {
179 if (exports.skips[i].test(name)) {
183 for (i = 0, len = exports.names.length; i < len; i++) {
184 if (exports.names[i].test(name)) {
199 function coerce(val) {
200 if (val instanceof Error) return val.stack || val.message;