diff options
Diffstat (limited to 'node_modules/loglevelnext/lib')
| -rw-r--r-- | node_modules/loglevelnext/lib/LogLevel.js | 78 | ||||
| -rw-r--r-- | node_modules/loglevelnext/lib/MethodFactory.js | 119 |
2 files changed, 197 insertions, 0 deletions
diff --git a/node_modules/loglevelnext/lib/LogLevel.js b/node_modules/loglevelnext/lib/LogLevel.js new file mode 100644 index 00000000..8f00411e --- /dev/null +++ b/node_modules/loglevelnext/lib/LogLevel.js @@ -0,0 +1,78 @@ +'use strict'; + +/* global window: true */ +const PrefixFactory = require('../factory/PrefixFactory'); +const MethodFactory = require('./MethodFactory'); + +const defaults = { + factory: null, + level: 'warn', + name: +new Date(), + prefix: null +}; + +module.exports = class LogLevel { + constructor(options) { + // implement for some _very_ loose type checking. avoids getting into a + // circular require between MethodFactory and LogLevel + this.type = 'LogLevel'; + this.options = Object.assign({}, defaults, options); + this.methodFactory = options.factory; + + if (!this.methodFactory) { + const factory = options.prefix ? new PrefixFactory(this, options.prefix) : new MethodFactory(this); + this.methodFactory = factory; + } + + if (!this.methodFactory.logger) { + this.methodFactory.logger = this; + } + + this.name = options.name || '<unknown>'; + + // this.level is a setter, do this after setting up the factory + this.level = this.options.level; + } + + get factory() { + return this.methodFactory; + } + + set factory(factory) { + factory.logger = this; + this.methodFactory = factory; + this.methodFactory.replaceMethods(this.level); + } + + disable() { + this.level = this.levels.SILENT; + } + + enable() { + this.level = this.levels.TRACE; + } + + get level() { + return this.currentLevel; + } + + set level(logLevel) { + const level = this.methodFactory.distillLevel(logLevel); + + if (level == null) { + throw new Error(`loglevelnext: setLevel() called with invalid level: ${logLevel}`); + } + + this.currentLevel = level; + this.methodFactory.replaceMethods(level); + + if (typeof console === 'undefined' && level < this.levels.SILENT) { + // eslint-disable-next-line no-console + console.warn('loglevelnext: console is undefined. The log will produce no output.'); + } + } + + get levels() { // eslint-disable-line class-methods-use-this + return this.methodFactory.levels; + } +}; diff --git a/node_modules/loglevelnext/lib/MethodFactory.js b/node_modules/loglevelnext/lib/MethodFactory.js new file mode 100644 index 00000000..cdf7038d --- /dev/null +++ b/node_modules/loglevelnext/lib/MethodFactory.js @@ -0,0 +1,119 @@ +'use strict'; + +const noop = () => {}; +const levels = Symbol('valid log levels'); +const instance = Symbol('a log instance'); + +module.exports = class MethodFactory { + constructor(logger) { + this[instance] = logger; + this[levels] = { + TRACE: 0, + DEBUG: 1, + INFO: 2, + WARN: 3, + ERROR: 4, + SILENT: 5 + }; + } + + get levels() { + return this[levels]; + } + + get logger() { + return this[instance]; + } + + set logger(logger) { + this[instance] = logger; + } + + get methods() { + return Object.keys(this.levels) + .map(key => key.toLowerCase()) + .filter(key => key !== 'silent'); + } + + // eslint-disable-next-line class-methods-use-this + bindMethod(obj, methodName) { + const method = obj[methodName]; + if (typeof method.bind === 'function') { + return method.bind(obj); + } + + try { + return Function.prototype.bind.call(method, obj); + } catch (e) { + // Missing bind shim or IE8 + Modernizr, fallback to wrapping + return function result() { + // eslint-disable-next-line prefer-rest-params + return Function.prototype.apply.apply(method, [obj, arguments]); + }; + } + } + + distillLevel(level) { + let result = level; + + if (typeof result === 'string' && typeof this.levels[result.toUpperCase()] !== 'undefined') { + result = this.levels[result.toUpperCase()]; + } + + if (this.levelValid(result)) { + return result; + } + } + + levelValid(level) { + if (typeof level === 'number' && level >= 0 && level <= this.levels.SILENT) { + return true; + } + + return false; + } + + /** + * Build the best logging method possible for this env + * Wherever possible we want to bind, not wrap, to preserve stack traces. + * Since we're targeting modern browsers, there's no need to wait for the + * console to become available. + */ + // eslint-disable-next-line class-methods-use-this + make(methodName) { + if (methodName === 'debug') { + methodName = 'log'; + } + + /* eslint-disable no-console */ + if (typeof console[methodName] !== 'undefined') { + return this.bindMethod(console, methodName); + } else if (typeof console.log !== 'undefined') { + return this.bindMethod(console, 'log'); + } + + /* eslint-enable no-console */ + return noop; + } + + replaceMethods(logLevel) { + const level = this.distillLevel(logLevel); + + if (level == null) { + throw new Error(`loglevelnext: replaceMethods() called with invalid level: ${logLevel}`); + } + + if (!this.logger || this.logger.type !== 'LogLevel') { + throw new TypeError('loglevelnext: Logger is undefined or invalid. Please specify a valid Logger instance.'); + } + + this.methods.forEach((methodName) => { + const { [methodName.toUpperCase()]: methodLevel } = this.levels; + + this.logger[methodName] = (methodLevel < level) ? noop : this.make(methodName); + }); + + // Define log.log as an alias for log.debug + this.logger.log = this.logger.debug; + } +}; |
