Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

CordovaLogger.js 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. Licensed to the Apache Software Foundation (ASF) under one
  3. or more contributor license agreements. See the NOTICE file
  4. distributed with this work for additional information
  5. regarding copyright ownership. The ASF licenses this file
  6. to you under the Apache License, Version 2.0 (the
  7. "License"); you may not use this file except in compliance
  8. with the License. You may obtain a copy of the License at
  9. http://www.apache.org/licenses/LICENSE-2.0
  10. Unless required by applicable law or agreed to in writing,
  11. software distributed under the License is distributed on an
  12. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  13. KIND, either express or implied. See the License for the
  14. specific language governing permissions and limitations
  15. under the License.
  16. */
  17. const ansi = require('ansi');
  18. const EventEmitter = require('events').EventEmitter;
  19. const EOL = require('os').EOL;
  20. const formatError = require('./util/formatError');
  21. const INSTANCE_KEY = Symbol.for('org.apache.cordova.common.CordovaLogger');
  22. /**
  23. * @typedef {'verbose'|'normal'|'warn'|'info'|'error'|'results'} CordovaLoggerLevel
  24. */
  25. /**
  26. * Implements logging facility that anybody could use.
  27. *
  28. * Should not be instantiated directly! `CordovaLogger.get()` method should be
  29. * used instead to acquire the logger instance.
  30. */
  31. class CordovaLogger {
  32. // Encapsulate the default logging level values with constants:
  33. static get VERBOSE () { return 'verbose'; }
  34. static get NORMAL () { return 'normal'; }
  35. static get WARN () { return 'warn'; }
  36. static get INFO () { return 'info'; }
  37. static get ERROR () { return 'error'; }
  38. static get RESULTS () { return 'results'; }
  39. /**
  40. * Static method to create new or acquire existing instance.
  41. *
  42. * @returns {CordovaLogger} Logger instance
  43. */
  44. static get () {
  45. // This singleton instance pattern is based on the ideas from
  46. // https://derickbailey.com/2016/03/09/creating-a-true-singleton-in-node-js-with-es6-symbols/
  47. if (Object.getOwnPropertySymbols(global).indexOf(INSTANCE_KEY) === -1) {
  48. global[INSTANCE_KEY] = new CordovaLogger();
  49. }
  50. return global[INSTANCE_KEY];
  51. }
  52. constructor () {
  53. /** @private */
  54. this.levels = {};
  55. /** @private */
  56. this.colors = {};
  57. /** @private */
  58. this.stdout = process.stdout;
  59. /** @private */
  60. this.stderr = process.stderr;
  61. /** @private */
  62. this.stdoutCursor = ansi(this.stdout);
  63. /** @private */
  64. this.stderrCursor = ansi(this.stderr);
  65. this.addLevel(CordovaLogger.VERBOSE, 1000, 'grey');
  66. this.addLevel(CordovaLogger.NORMAL, 2000);
  67. this.addLevel(CordovaLogger.WARN, 2000, 'yellow');
  68. this.addLevel(CordovaLogger.INFO, 3000, 'blue');
  69. this.addLevel(CordovaLogger.ERROR, 5000, 'red');
  70. this.addLevel(CordovaLogger.RESULTS, 10000);
  71. this.setLevel(CordovaLogger.NORMAL);
  72. }
  73. /**
  74. * Emits log message to process' stdout/stderr depending on message's
  75. * severity and current log level. If severity is less than current
  76. * logger's level, then the message is ignored.
  77. *
  78. * @param {CordovaLoggerLevel} logLevel - The message's log level. The
  79. * logger should have corresponding level added (via logger.addLevel),
  80. * otherwise `CordovaLogger.NORMAL` level will be used.
  81. *
  82. * @param {string} message - The message, that should be logged to
  83. * process's stdio.
  84. *
  85. * @returns {CordovaLogger} Return the current instance, to allow chaining.
  86. */
  87. log (logLevel, message) {
  88. // if there is no such logLevel defined, or provided level has
  89. // less severity than active level, then just ignore this call and return
  90. if (!this.levels[logLevel] || this.levels[logLevel] < this.levels[this.logLevel]) {
  91. // return instance to allow to chain calls
  92. return this;
  93. }
  94. var isVerbose = this.logLevel === CordovaLogger.VERBOSE;
  95. var cursor = this.stdoutCursor;
  96. if (message instanceof Error || logLevel === CordovaLogger.ERROR) {
  97. message = formatError(message, isVerbose);
  98. cursor = this.stderrCursor;
  99. }
  100. var color = this.colors[logLevel];
  101. if (color) {
  102. cursor.bold().fg[color]();
  103. }
  104. cursor.write(message).reset().write(EOL);
  105. return this;
  106. }
  107. /**
  108. * Adds a new level to logger instance.
  109. *
  110. * This method also creates a shortcut method to log events with the level
  111. * provided.
  112. * (i.e. after adding new level 'debug', the method `logger.debug(message)`
  113. * will exist, equal to `logger.log('debug', message)`)
  114. *
  115. * @param {CordovaLoggerLevel} level - A log level name. The levels with
  116. * the following names are added by default to every instance: 'verbose',
  117. * 'normal', 'warn', 'info', 'error', 'results'.
  118. *
  119. * @param {number} severity - A number that represents level's severity.
  120. *
  121. * @param {string} color - A valid color name, that will be used to log
  122. * messages with this level. Any CSS color code or RGB value is allowed
  123. * (according to ansi documentation:
  124. * https://github.com/TooTallNate/ansi.js#features).
  125. *
  126. * @returns {CordovaLogger} Return the current instance, to allow chaining.
  127. */
  128. addLevel (level, severity, color) {
  129. this.levels[level] = severity;
  130. if (color) {
  131. this.colors[level] = color;
  132. }
  133. // Define own method with corresponding name
  134. if (!this[level]) {
  135. Object.defineProperty(this, level, {
  136. get () { return this.log.bind(this, level); }
  137. });
  138. }
  139. return this;
  140. }
  141. /**
  142. * Sets the current logger level to provided value.
  143. *
  144. * If logger doesn't have level with this name, `CordovaLogger.NORMAL` will
  145. * be used.
  146. *
  147. * @param {CordovaLoggerLevel} logLevel - Level name. The level with this
  148. * name should be added to logger before.
  149. *
  150. * @returns {CordovaLogger} Current instance, to allow chaining.
  151. */
  152. setLevel (logLevel) {
  153. this.logLevel = this.levels[logLevel] ? logLevel : CordovaLogger.NORMAL;
  154. return this;
  155. }
  156. /**
  157. * Adjusts the current logger level according to the passed options.
  158. *
  159. * @param {Object|Array<string>} opts - An object or args array with
  160. * options.
  161. *
  162. * @returns {CordovaLogger} Current instance, to allow chaining.
  163. */
  164. adjustLevel (opts) {
  165. if (opts.verbose || (Array.isArray(opts) && opts.includes('--verbose'))) {
  166. this.setLevel('verbose');
  167. } else if (opts.silent || (Array.isArray(opts) && opts.includes('--silent'))) {
  168. this.setLevel('error');
  169. }
  170. return this;
  171. }
  172. /**
  173. * Attaches logger to EventEmitter instance provided.
  174. *
  175. * @param {EventEmitter} eventEmitter - An EventEmitter instance to attach
  176. * the logger to.
  177. *
  178. * @returns {CordovaLogger} Current instance, to allow chaining.
  179. */
  180. subscribe (eventEmitter) {
  181. if (!(eventEmitter instanceof EventEmitter)) {
  182. throw new Error('Subscribe method only accepts an EventEmitter instance as argument');
  183. }
  184. eventEmitter.on('verbose', this.verbose)
  185. .on('log', this.normal)
  186. .on('info', this.info)
  187. .on('warn', this.warn)
  188. .on('warning', this.warn)
  189. // Set up event handlers for logging and results emitted as events.
  190. .on('results', this.results);
  191. return this;
  192. }
  193. }
  194. module.exports = CordovaLogger;