UNPKG

6.84 kBJavaScriptView Raw
1/*
2 * MIT License
3 *
4 * Copyright (c) 2019 nest-mods
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25/*
26 * https://github.com/intesso/debug-trace
27 */
28
29/**
30 * Module dependencies.
31 */
32
33var callsite = require('callsite')
34 , tty = require('tty')
35 , moment = require('moment')
36 , isatty = Boolean(tty.isatty(2) && process.stdout.getWindowSize)
37 , defaultColors = { log: '90', error: '91', warn: '93', info: '96', trace: '90' };
38
39// change stack index
40const stackIndex = 7;
41
42/**
43 * Store custom options
44 *
45 * @param {Object} options
46 * @api public
47 */
48
49module.exports = function debugTrace(options) {
50 options = options || {};
51 console.traceOptions = console.traceOptions || {};
52 console.traceOptions.cwd = options.cwd || process.cwd() + '/';
53 console.traceOptions.colors = typeof options.colors !== 'undefined' ? options.colors : true;
54 console.traceOptions.always = typeof options.always !== 'undefined' ? options.always : true;
55 console.traceOptions.right = typeof options.right !== 'undefined' ? options.right : false;
56 // if (typeof options.overwriteDebugLog === 'undefined' || options.overwriteDebugLog) overwriteDebugLog(options.overwriteDebugLog);
57 // if (typeof options.patchOutput === 'undefined' || options.patchOutput) patchOutput();
58};
59
60// function overwriteDebugLog(debugLog) {
61// debugLog = typeof debugLog === 'function' ? debugLog : console.log;
62// try {
63// var Debug = require('debug');
64// Debug.log = function log() {
65// return debugLog.apply(debugLog, arguments);
66// };
67// } catch (error) {
68// console.log('debug module is not installed');
69// }
70// }
71//
72// function patchOutput() {
73// var stdout = process.stdout.write;
74// var stderr = process.stderr.write;
75// process.stdout.write = function write() {
76// var stack = callsite();
77// var trace = stack[1];
78// if (trace.getFunctionName() === 'log') {
79// var args = [].slice.call(arguments);
80// if (typeof args[args.length - 1] === 'string') args[args.length - 1] = args[args.length - 1].replace(/\n$/g, '');
81// return console.log.apply(console.log, args);
82// }
83// return stdout.apply(process.stdout, arguments);
84// };
85// process.stderr.write = function write() {
86// var stack = callsite();
87// var trace = stack[1];
88// if (trace.getFunctionName() === 'log') {
89// var args = [].slice.call(arguments);
90// if (typeof args[args.length - 1] === 'string') args[args.length - 1] = args[args.length - 1].replace(/\n$/g, '');
91// return console.error.apply(console.error, args);
92// }
93// return stderr.apply(process.stderr, arguments);
94// };
95// }
96
97/**
98 * Overrides the console methods.
99 */
100
101;['error', 'log', 'info', 'warn', 'trace'].forEach(function(name) {
102 var fn = console[name];
103 console[name] = function() {
104 var args = arguments;
105 if (console._trace || console.traceOptions.always) {
106 if (args.length === 1) args = ['', args[0]];
107 if (Buffer.isBuffer(args[0])) {
108 args[0] = args[0].inspect();
109 } else if (typeof args[0] === 'object') {
110 args[0] = JSON.stringify(args[0], null, ' ');
111 }
112 var pad = (args[0] && !console.traceOptions.right || !isatty ? ' ' : '');
113 // when using the debug module: dig one level deeper in the stack
114 var stack = callsite();
115 var trace = stack[stackIndex];
116 // if (stack.length > 2 && trace.getFunctionName() === 'log') {
117 // trace = stack[3];
118 // trace.debug = true;
119 // }
120 // if (stack.length > 3 && trace.getFunctionName() === 'write') {
121 // trace = stack[4];
122 // trace.debug = true;
123 // }
124 // trace.debug = trace.debug || false;
125 args[0] = console.traceFormat(trace, name) + pad + args[0];
126 }
127 console._trace = false;
128 return fn.apply(this, args);
129 };
130});
131
132/**
133 * Overridable formatting function.
134 *
135 * @param {CallSite}
136 * @param {String} calling method
137 * @api public
138 */
139
140console.traceFormat = function(call, method) {
141 // call.filename = call.getFileName().replace(console.traceOptions.cwd, '');
142 var paths = call.getFileName().split('/');
143 call.filename = paths[paths.length - 1];
144 call.method = method;
145 call.functionName = call.getFunctionName() || 'anonymous';
146 call.getDate = function getDate() {
147 return moment().format('YYYY-MM-DD HH:mm:ss');
148 };
149
150 var str = console.format(call);
151 var color = '99';
152
153 if (!isatty) {
154 return str;
155 }
156
157 if (console.traceOptions.colors !== false) {
158 if (console.traceOptions.colors === undefined || console.traceOptions.colors[method] === undefined) {
159 color = defaultColors[method];
160 } else {
161 color = console.traceOptions.colors[method];
162 }
163 }
164
165 if (console.traceOptions.right) {
166 var rowWidth = process.stdout.getWindowSize()[0];
167 return '\033[s' + // save current position
168 '\033[' + rowWidth + 'D' + // move to the start of the line
169 '\033[' + (rowWidth - str.length) + 'C' + // align right
170 '\033[' + color + 'm' + str + '\033[39m' +
171 '\033[u'; // restore current position
172 } else {
173 return '\033[' + color + 'm' + str + '\033[39m';
174 }
175};
176
177
178/**
179 * Overridable string formatting function.
180 *
181 * @param {CallSite} CallSite Object pimped with additional properties.
182 * @api public
183 */
184console.format = function(c) {
185 // can not get the proxied method, omit it
186 if (c.filename.startsWith('log-invoke.decorator') && c.functionName === 'anonymous') {
187 return c.getDate();
188 }
189 return c.getDate() + ' [' + c.filename + ':' + c.getLineNumber() + '] ' + c.functionName;
190};
191
192/**
193 * Adds trace getter to the `console` object.
194 *
195 * @api public
196 */
197
198// function getter() {
199// this._trace = true;
200// return this;
201// }
202//
203// Object.defineProperty(console, 't', { get: getter });
204// Object.defineProperty(console, 'traced', { get: getter });