UNPKG

9.11 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3 typeof define === 'function' && define.amd ? define(factory) :
4 (global.consola = factory());
5}(this, (function () { 'use strict';
6
7 var Types = {
8 // Level 0
9 fatal: {
10 level: 0
11 },
12 error: {
13 level: 0
14 },
15 // Level 1
16 warn: {
17 level: 1
18 },
19 // Level 2
20 log: {
21 level: 2
22 },
23 // Level 3
24 info: {
25 level: 3
26 },
27 success: {
28 level: 3
29 },
30 // Level 4
31 debug: {
32 level: 4
33 },
34 // Level 5
35 trace: {
36 level: 5
37 },
38 // Silent
39 silent: {
40 level: Infinity
41 },
42 // Legacy
43 ready: {
44 level: 3
45 },
46 start: {
47 level: 3
48 }
49 };
50
51 function isPlainObject(obj) {
52 return Object.prototype.toString.call(obj) === '[object Object]';
53 }
54 function isLogObj(arg) {
55 // Should be plain object
56 // Also contains either message or args field
57 return isPlainObject(arg) && Boolean(arg.message || arg.args);
58 }
59
60 let paused = false;
61 const queue = [];
62 class Consola {
63 constructor(options = {}) {
64 this._reporters = options.reporters || [];
65 this._types = options.types || Types;
66 this._level = options.level != null ? options.level : 3;
67 this._defaults = options.defaults || {};
68 this._async = typeof options.async !== 'undefined' ? options.async : null;
69 this._stdout = options.stdout;
70 this._stderr = options.stdout;
71 this._mockFn = options.mockFn; // Create logger functions for current instance
72
73 for (const type in this._types) {
74 this[type] = this._wrapLogFn(Object.assign({
75 type
76 }, this._types[type], this._defaults));
77 } // Use _mockFn if is set
78
79
80 if (this._mockFn) {
81 this.mockTypes();
82 }
83 }
84
85 get level() {
86 return this._level;
87 }
88
89 set level(newLevel) {
90 // Ensure that newLevel does not exceeds type level boundaries
91 let min = 0;
92 let max = 0;
93
94 for (const typeName in this._types) {
95 const type = this._types[typeName];
96
97 if (type.level > max) {
98 max = type.level;
99 } else if (type.level < min) {
100 min = type.level;
101 }
102 } // Set level
103
104
105 this._level = Math.min(max, Math.max(min, newLevel));
106 }
107
108 get stdout() {
109 return this._stdout || console._stdout; // eslint-disable-line no-console
110 }
111
112 get stderr() {
113 return this._stderr || console._stderr; // eslint-disable-line no-console
114 }
115
116 create(options) {
117 return new Consola(Object.assign({
118 reporters: this._reporters,
119 level: this._level,
120 types: this._types,
121 defaults: this._defaults,
122 stdout: this._stdout,
123 stderr: this._stderr,
124 mockFn: this._mockFn
125 }, options));
126 }
127
128 addReporter(reporter) {
129 this._reporters.push(reporter);
130
131 return this;
132 }
133
134 removeReporter(reporter) {
135 if (reporter) {
136 const i = this._reporters.indexOf(reporter);
137
138 if (i >= 0) {
139 return this._reporters.splice(i, 1);
140 }
141 } else {
142 this._reporters.splice(0);
143 }
144
145 return this;
146 }
147
148 setReporters(reporters) {
149 this._reporters = Array.isArray(reporters) ? reporters : [reporters];
150 }
151
152 withDefaults(defaults) {
153 return this.create({
154 defaults: Object.assign({}, this._defaults, defaults)
155 });
156 }
157
158 withTag(tag) {
159 return this.withDefaults({
160 tag: this._defaults.tag ? this._defaults.tag + ':' + tag : tag
161 });
162 }
163
164 wrapAll() {
165 this.wrapConsole();
166 this.wrapStd();
167 }
168
169 restoreAll() {
170 this.restoreConsole();
171 this.restoreStd();
172 }
173
174 wrapConsole() {
175 for (const type in this._types) {
176 // Backup original value
177 if (!console['__' + type]) {
178 // eslint-disable-line no-console
179 console['__' + type] = console[type]; // eslint-disable-line no-console
180 } // Override
181
182
183 console[type] = this[type]; // eslint-disable-line no-console
184 }
185 }
186
187 restoreConsole() {
188 for (const type in this._types) {
189 // Restore if backup is available
190 if (console['__' + type]) {
191 // eslint-disable-line no-console
192 console[type] = console['__' + type]; // eslint-disable-line no-console
193
194 delete console['__' + type]; // eslint-disable-line no-console
195 }
196 }
197 }
198
199 wrapStd() {
200 this._wrapStream(this.stdout, 'log');
201
202 this._wrapStream(this.stderr, 'log');
203 }
204
205 _wrapStream(stream, type) {
206 if (!stream) {
207 return;
208 } // Backup original value
209
210
211 if (!stream.__write) {
212 stream.__write = stream.write;
213 } // Override
214
215
216 stream.write = data => {
217 this[type](String(data).trim());
218 };
219 }
220
221 restoreStd() {
222 this._restoreStream(this.stdout);
223
224 this._restoreStream(this.stderr);
225 }
226
227 _restoreStream(stream) {
228 if (!stream) {
229 return;
230 }
231
232 if (stream.__write) {
233 stream.write = stream.__write;
234 delete stream.__write;
235 }
236 }
237
238 pauseLogs() {
239 paused = true;
240 }
241
242 resumeLogs() {
243 paused = false; // Process queue
244
245 const _queue = queue.splice(0);
246
247 for (const item of _queue) {
248 item[0]._logFn(item[1], item[2]);
249 }
250 }
251
252 mockTypes(mockFn) {
253 this._mockFn = mockFn || this._mockFn;
254
255 if (typeof this._mockFn !== 'function') {
256 return;
257 }
258
259 for (const type in this._types) {
260 this[type] = this._mockFn(type, this._types[type]) || this[type];
261 }
262 }
263
264 _wrapLogFn(defaults) {
265 function logFn() {
266 if (paused) {
267 queue.push([this, defaults, arguments]);
268 return;
269 }
270
271 return this._logFn(defaults, arguments);
272 }
273
274 return logFn.bind(this);
275 }
276
277 _logFn(defaults, args) {
278 if (defaults.level > this._level) {
279 return this._async ? Promise.resolve(false) : false;
280 } // Construct a new log object
281
282
283 const logObj = Object.assign({
284 date: new Date(),
285 args: []
286 }, defaults); // Consume arguments
287
288 if (args.length === 1 && isLogObj(args[0])) {
289 Object.assign(logObj, args[0]);
290 } else {
291 logObj.args = Array.from(args);
292 } // Aliases
293
294
295 if (logObj.message) {
296 logObj.args.unshift(logObj.message);
297 delete logObj.message;
298 }
299
300 if (logObj.additional) {
301 if (!Array.isArray(logObj.additional)) {
302 logObj.additional = logObj.additional.split('\n');
303 }
304
305 logObj.args.push('\n' + logObj.additional.join('\n'));
306 delete logObj.additional;
307 } // Log
308
309
310 if (this._async) {
311 return this._logAsync(logObj);
312 } else {
313 this._log(logObj);
314 }
315 }
316
317 _log(logObj) {
318 for (const reporter of this._reporters) {
319 reporter.log(logObj, {
320 async: false,
321 stdout: this.stdout,
322 stderr: this.stderr
323 });
324 }
325 }
326
327 _logAsync(logObj) {
328 return Promise.all(this._reporters.map(reporter => reporter.log(logObj, {
329 async: true,
330 stdout: this.stdout,
331 stderr: this.stderr
332 })));
333 }
334
335 } // Legacy support
336
337 Consola.prototype.add = Consola.prototype.addReporter;
338 Consola.prototype.remove = Consola.prototype.removeReporter;
339 Consola.prototype.clear = Consola.prototype.removeReporter;
340 Consola.prototype.withScope = Consola.prototype.withTag;
341 Consola.prototype.mock = Consola.prototype.mockTypes;
342 Consola.prototype.pause = Consola.prototype.pauseLogs;
343 Consola.prototype.resume = Consola.prototype.resumeLogs;
344
345 const TYPE_COLOR_MAP = {
346 'info': 'cyan'
347 };
348 const LEVEL_COLOR_MAP = {
349 0: 'red',
350 1: 'yellow',
351 2: 'white',
352 3: 'green'
353 };
354
355 class BrowserReporter {
356 constructor(options) {
357 this.options = Object.assign({}, options);
358 }
359
360 log(logObj) {
361 // consoleLogFn
362 let consoleLogFn = console[logObj.type]; // eslint-disable-line no-console
363
364 if (!consoleLogFn) {
365 consoleLogFn = console[logObj.level < 2 ? 'error' : 'log']; // eslint-disable-line no-console
366 } // Type
367
368
369 const type = logObj.type.toUpperCase(); // Styles
370
371 const color = TYPE_COLOR_MAP[logObj.type] || LEVEL_COLOR_MAP[logObj.level];
372 const styleColor = `color: ${color}; background-color: inherit;`;
373 const styleInherit = `color: inherit; background-color: inherit;`;
374 const styleAdditional = `color: ${logObj.additionalColor || 'grey'}; background-color: inherit;`; // Date
375
376 const date = new Date(logObj.date).toLocaleTimeString(); // Log to the console
377
378 consoleLogFn(`%c[${type}]%c[${date}]%c`, styleColor, styleAdditional, styleInherit, ...logObj.args);
379 }
380
381 }
382
383 if (!window.consola) {
384 // Create new consola instance
385 window.consola = new Consola({
386 reporters: [new BrowserReporter()]
387 });
388 }
389
390 var browser = window.consola;
391
392 return browser;
393
394})));