1/** 2 * Module dependencies. 3 */ 4 5const tty = require('tty'); 6const util = require('util'); 7 8/** 9 * This is the Node.js implementation of `debug()`. 10 */ 11 12exports.init = init; 13exports.log = log; 14exports.formatArgs = formatArgs; 15exports.save = save; 16exports.load = load; 17exports.useColors = useColors; 18exports.destroy = util.deprecate( 19 () => {}, 20 'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.' 21); 22 23/** 24 * Colors. 25 */ 26 27exports.colors = [6, 2, 3, 4, 5, 1]; 28 29try { 30 // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json) 31 // eslint-disable-next-line import/no-extraneous-dependencies 32 const supportsColor = require('supports-color'); 33 34 if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { 35 exports.colors = [ 36 20, 37 21, 38 26, 39 27, 40 32, 41 33, 42 38, 43 39, 44 40, 45 41, 46 42, 47 43, 48 44, 49 45, 50 56, 51 57, 52 62, 53 63, 54 68, 55 69, 56 74, 57 75, 58 76, 59 77, 60 78, 61 79, 62 80, 63 81, 64 92, 65 93, 66 98, 67 99, 68 112, 69 113, 70 128, 71 129, 72 134, 73 135, 74 148, 75 149, 76 160, 77 161, 78 162, 79 163, 80 164, 81 165, 82 166, 83 167, 84 168, 85 169, 86 170, 87 171, 88 172, 89 173, 90 178, 91 179, 92 184, 93 185, 94 196, 95 197, 96 198, 97 199, 98 200, 99 201, 100 202, 101 203, 102 204, 103 205, 104 206, 105 207, 106 208, 107 209, 108 214, 109 215, 110 220, 111 221 112 ]; 113 } 114} catch (error) { 115 // Swallow - we only care if `supports-color` is available; it doesn't have to be. 116} 117 118/** 119 * Build up the default `inspectOpts` object from the environment variables. 120 * 121 * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js 122 */ 123 124exports.inspectOpts = Object.keys(process.env).filter(key => { 125 return /^debug_/i.test(key); 126}).reduce((obj, key) => { 127 // Camel-case 128 const prop = key 129 .substring(6) 130 .toLowerCase() 131 .replace(/_([a-z])/g, (_, k) => { 132 return k.toUpperCase(); 133 }); 134 135 // Coerce string value into JS value 136 let val = process.env[key]; 137 if (/^(yes|on|true|enabled)$/i.test(val)) { 138 val = true; 139 } else if (/^(no|off|false|disabled)$/i.test(val)) { 140 val = false; 141 } else if (val === 'null') { 142 val = null; 143 } else { 144 val = Number(val); 145 } 146 147 obj[prop] = val; 148 return obj; 149}, {}); 150 151/** 152 * Is stdout a TTY? Colored output is enabled when `true`. 153 */ 154 155function useColors() { 156 return 'colors' in exports.inspectOpts ? 157 Boolean(exports.inspectOpts.colors) : 158 tty.isatty(process.stderr.fd); 159} 160 161/** 162 * Adds ANSI color escape codes if enabled. 163 * 164 * @api public 165 */ 166 167function formatArgs(args) { 168 const {namespace: name, useColors} = this; 169 170 if (useColors) { 171 const c = this.color; 172 const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c); 173 const prefix = ` ${colorCode};1m${name} \u001B[0m`; 174 175 args[0] = prefix + args[0].split('\n').join('\n' + prefix); 176 args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m'); 177 } else { 178 args[0] = getDate() + name + ' ' + args[0]; 179 } 180} 181 182function getDate() { 183 if (exports.inspectOpts.hideDate) { 184 return ''; 185 } 186 return new Date().toISOString() + ' '; 187} 188 189/** 190 * Invokes `util.format()` with the specified arguments and writes to stderr. 191 */ 192 193function log(...args) { 194 return process.stderr.write(util.format(...args) + '\n'); 195} 196 197/** 198 * Save `namespaces`. 199 * 200 * @param {String} namespaces 201 * @api private 202 */ 203function save(namespaces) { 204 if (namespaces) { 205 process.env.DEBUG = namespaces; 206 } else { 207 // If you set a process.env field to null or undefined, it gets cast to the 208 // string 'null' or 'undefined'. Just delete instead. 209 delete process.env.DEBUG; 210 } 211} 212 213/** 214 * Load `namespaces`. 215 * 216 * @return {String} returns the previously persisted debug modes 217 * @api private 218 */ 219 220function load() { 221 return process.env.DEBUG; 222} 223 224/** 225 * Init logic for `debug` instances. 226 * 227 * Create a new `inspectOpts` object in case `useColors` is set 228 * differently for a particular `debug` instance. 229 */ 230 231function init(debug) { 232 debug.inspectOpts = {}; 233 234 const keys = Object.keys(exports.inspectOpts); 235 for (let i = 0; i < keys.length; i++) { 236 debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; 237 } 238} 239 240module.exports = require('./common')(exports); 241 242const {formatters} = module.exports; 243 244/** 245 * Map %o to `util.inspect()`, all on a single line. 246 */ 247 248formatters.o = function (v) { 249 this.inspectOpts.colors = this.useColors; 250 return util.inspect(v, this.inspectOpts) 251 .split('\n') 252 .map(str => str.trim()) 253 .join(' '); 254}; 255 256/** 257 * Map %O to `util.inspect()`, allowing multiple lines if needed. 258 */ 259 260formatters.O = function (v) { 261 this.inspectOpts.colors = this.useColors; 262 return util.inspect(v, this.inspectOpts); 263}; 264