output.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. 'use strict';
  2. const colors = require('./utils/colors');
  3. const chalk = require('chalk');
  4. const stringWidth = require('string-width');
  5. const readline = require('readline');
  6. class Debugger {
  7. constructor () {
  8. this.enabled = true;
  9. this.capturing = false;
  10. this.capturedMessages = [];
  11. }
  12. enable () {
  13. this.enabled = true;
  14. }
  15. capture () {
  16. this.enabled = true;
  17. this.capturing = true;
  18. }
  19. endCapture () {
  20. this.enabled = false;
  21. this.capturing = false;
  22. this.capturedMessages = [];
  23. }
  24. log () {
  25. if (this.enabled) {
  26. this.captureConsole(Array.from(arguments), console.log);
  27. }
  28. }
  29. info (message) {
  30. if (this.enabled) {
  31. const titleFormatted = colors.formatTitle('info', 'I');
  32. this.log(titleFormatted, message);
  33. }
  34. }
  35. note (message) {
  36. if (this.enabled) {
  37. const titleFormatted = colors.formatTitle('note', 'N');
  38. this.log(titleFormatted, message);
  39. }
  40. }
  41. title (severity, title, subtitle) {
  42. if (this.enabled) {
  43. const date = new Date();
  44. const dateString = chalk.grey(date.toLocaleTimeString());
  45. const titleFormatted = colors.formatTitle(severity, title);
  46. const subTitleFormatted = colors.formatText(severity, subtitle);
  47. const message = `${titleFormatted} ${subTitleFormatted}`
  48. // In test environment we don't include timestamp
  49. if(process.env.NODE_ENV === 'test') {
  50. this.log(message);
  51. this.log();
  52. return;
  53. }
  54. // Make timestamp appear at the end of the line
  55. let logSpace = process.stdout.columns - stringWidth(message) - stringWidth(dateString)
  56. if (logSpace <= 0) {
  57. logSpace = 10
  58. }
  59. this.log(`${message}${' '.repeat(logSpace)}${dateString}`);
  60. this.log();
  61. }
  62. }
  63. clearConsole () {
  64. if (!this.capturing && this.enabled && process.stdout.isTTY) {
  65. // Fill screen with blank lines. Then move to 0 (beginning of visible part) and clear it
  66. const blank = '\n'.repeat(process.stdout.rows)
  67. console.log(blank)
  68. readline.cursorTo(process.stdout, 0, 0)
  69. readline.clearScreenDown(process.stdout)
  70. }
  71. }
  72. captureLogs (fun) {
  73. try {
  74. this.capture();
  75. fun.call();
  76. return this.capturedMessages;
  77. } catch (e) {
  78. throw e;
  79. } finally {
  80. this.endCapture();
  81. }
  82. }
  83. captureConsole (args, method) {
  84. if (this.capturing) {
  85. this.capturedMessages.push(chalk.stripColor(args.join(' ')).trim());
  86. } else {
  87. method.apply(console, args);
  88. }
  89. }
  90. }
  91. function capitalizeFirstLetter (string) {
  92. return string.charAt(0).toUpperCase() + string.slice(1);
  93. }
  94. module.exports = new Debugger();