output.js 2.6 KB

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