1 | 'use strict';
|
---|
2 |
|
---|
3 | /* eslint-disable
|
---|
4 | arrow-parens,
|
---|
5 | multiline-ternary,
|
---|
6 | consistent-return,
|
---|
7 | no-param-reassign,
|
---|
8 | prefer-destructuring
|
---|
9 | */
|
---|
10 | const noop = () => {};
|
---|
11 |
|
---|
12 | const levels = Symbol('levels');
|
---|
13 | const instance = Symbol('instance');
|
---|
14 |
|
---|
15 | class MethodFactory {
|
---|
16 | constructor(logger) {
|
---|
17 | this[levels] = {
|
---|
18 | TRACE: 0,
|
---|
19 | DEBUG: 1,
|
---|
20 | INFO: 2,
|
---|
21 | WARN: 3,
|
---|
22 | ERROR: 4,
|
---|
23 | SILENT: 5
|
---|
24 | };
|
---|
25 |
|
---|
26 | this[instance] = logger;
|
---|
27 | }
|
---|
28 |
|
---|
29 | set logger(logger) {
|
---|
30 | this[instance] = logger;
|
---|
31 | }
|
---|
32 |
|
---|
33 | get logger() {
|
---|
34 | return this[instance];
|
---|
35 | }
|
---|
36 |
|
---|
37 | get levels() {
|
---|
38 | return this[levels];
|
---|
39 | }
|
---|
40 |
|
---|
41 | get methods() {
|
---|
42 | return Object.keys(this.levels)
|
---|
43 | .map((key) => key.toLowerCase())
|
---|
44 | .filter((key) => key !== 'silent');
|
---|
45 | }
|
---|
46 |
|
---|
47 | distillLevel(level) {
|
---|
48 | let result = level;
|
---|
49 |
|
---|
50 | if (
|
---|
51 | typeof result === 'string' &&
|
---|
52 | typeof this.levels[result.toUpperCase()] !== 'undefined'
|
---|
53 | ) {
|
---|
54 | result = this.levels[result.toUpperCase()];
|
---|
55 | }
|
---|
56 |
|
---|
57 | if (this.levelValid(result)) {
|
---|
58 | return result;
|
---|
59 | }
|
---|
60 | }
|
---|
61 |
|
---|
62 | levelValid(level) {
|
---|
63 | if (
|
---|
64 | typeof level === 'number' && level >= 0 &&
|
---|
65 | level <= this.levels.SILENT
|
---|
66 | ) {
|
---|
67 | return true;
|
---|
68 | }
|
---|
69 |
|
---|
70 | return false;
|
---|
71 | }
|
---|
72 | /**
|
---|
73 | * Build the best logging method possible for this env
|
---|
74 | * Wherever possible we want to bind, not wrap, to preserve stack traces.
|
---|
75 | * Since we're targeting modern browsers, there's no need to wait for the
|
---|
76 | * console to become available.
|
---|
77 | */
|
---|
78 | // eslint-disable-next-line class-methods-use-this
|
---|
79 | make(method) {
|
---|
80 | if (method === 'debug') {
|
---|
81 | method = 'log';
|
---|
82 | }
|
---|
83 |
|
---|
84 | /* eslint-disable no-console */
|
---|
85 | if (typeof console[method] !== 'undefined') {
|
---|
86 | return this.bindMethod(console, method);
|
---|
87 | } else if (typeof console.log !== 'undefined') {
|
---|
88 | return this.bindMethod(console, 'log');
|
---|
89 | }
|
---|
90 |
|
---|
91 | /* eslint-enable no-console */
|
---|
92 | return noop;
|
---|
93 | }
|
---|
94 |
|
---|
95 | // eslint-disable-next-line class-methods-use-this
|
---|
96 | bindMethod(obj, name) {
|
---|
97 | const method = obj[name];
|
---|
98 |
|
---|
99 | if (typeof method.bind === 'function') {
|
---|
100 | return method.bind(obj);
|
---|
101 | }
|
---|
102 |
|
---|
103 | try {
|
---|
104 | return Function.prototype.bind.call(method, obj);
|
---|
105 | } catch (err) {
|
---|
106 | // Missing bind shim or IE8 + Modernizr, fallback to wrapping
|
---|
107 | return function result() {
|
---|
108 | // eslint-disable-next-line prefer-rest-params
|
---|
109 | return Function.prototype.apply.apply(method, [obj, arguments]);
|
---|
110 | };
|
---|
111 | }
|
---|
112 | }
|
---|
113 |
|
---|
114 | replaceMethods(logLevel) {
|
---|
115 | const level = this.distillLevel(logLevel);
|
---|
116 |
|
---|
117 | if (level == null) {
|
---|
118 | throw new Error(
|
---|
119 | `loglevel: replaceMethods() called with invalid level: ${logLevel}`
|
---|
120 | );
|
---|
121 | }
|
---|
122 |
|
---|
123 | if (!this.logger || this.logger.type !== 'LogLevel') {
|
---|
124 | throw new TypeError(
|
---|
125 | 'loglevel: Logger is undefined or invalid. Please specify a valid Logger instance.'
|
---|
126 | );
|
---|
127 | }
|
---|
128 |
|
---|
129 | this.methods.forEach((method) => {
|
---|
130 | this.logger[method] = (this.levels[method.toUpperCase()] < level)
|
---|
131 | ? noop
|
---|
132 | : this.make(method);
|
---|
133 | });
|
---|
134 |
|
---|
135 | // Define log.log as an alias for log.debug
|
---|
136 | this.logger.log = this.logger.debug;
|
---|
137 | }
|
---|
138 | }
|
---|
139 |
|
---|
140 | module.exports = MethodFactory;
|
---|