mute.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. var Stream = require('stream')
  2. module.exports = MuteStream
  3. // var out = new MuteStream(process.stdout)
  4. // argument auto-pipes
  5. function MuteStream (opts) {
  6. Stream.apply(this)
  7. opts = opts || {}
  8. this.writable = this.readable = true
  9. this.muted = false
  10. this.on('pipe', this._onpipe)
  11. this.replace = opts.replace
  12. // For readline-type situations
  13. // This much at the start of a line being redrawn after a ctrl char
  14. // is seen (such as backspace) won't be redrawn as the replacement
  15. this._prompt = opts.prompt || null
  16. this._hadControl = false
  17. }
  18. MuteStream.prototype = Object.create(Stream.prototype)
  19. Object.defineProperty(MuteStream.prototype, 'constructor', {
  20. value: MuteStream,
  21. enumerable: false
  22. })
  23. MuteStream.prototype.mute = function () {
  24. this.muted = true
  25. }
  26. MuteStream.prototype.unmute = function () {
  27. this.muted = false
  28. }
  29. Object.defineProperty(MuteStream.prototype, '_onpipe', {
  30. value: onPipe,
  31. enumerable: false,
  32. writable: true,
  33. configurable: true
  34. })
  35. function onPipe (src) {
  36. this._src = src
  37. }
  38. Object.defineProperty(MuteStream.prototype, 'isTTY', {
  39. get: getIsTTY,
  40. set: setIsTTY,
  41. enumerable: true,
  42. configurable: true
  43. })
  44. function getIsTTY () {
  45. return( (this._dest) ? this._dest.isTTY
  46. : (this._src) ? this._src.isTTY
  47. : false
  48. )
  49. }
  50. // basically just get replace the getter/setter with a regular value
  51. function setIsTTY (isTTY) {
  52. Object.defineProperty(this, 'isTTY', {
  53. value: isTTY,
  54. enumerable: true,
  55. writable: true,
  56. configurable: true
  57. })
  58. }
  59. Object.defineProperty(MuteStream.prototype, 'rows', {
  60. get: function () {
  61. return( this._dest ? this._dest.rows
  62. : this._src ? this._src.rows
  63. : undefined )
  64. }, enumerable: true, configurable: true })
  65. Object.defineProperty(MuteStream.prototype, 'columns', {
  66. get: function () {
  67. return( this._dest ? this._dest.columns
  68. : this._src ? this._src.columns
  69. : undefined )
  70. }, enumerable: true, configurable: true })
  71. MuteStream.prototype.pipe = function (dest) {
  72. this._dest = dest
  73. return Stream.prototype.pipe.call(this, dest)
  74. }
  75. MuteStream.prototype.pause = function () {
  76. if (this._src) return this._src.pause()
  77. }
  78. MuteStream.prototype.resume = function () {
  79. if (this._src) return this._src.resume()
  80. }
  81. MuteStream.prototype.write = function (c) {
  82. if (this.muted) {
  83. if (!this.replace) return true
  84. if (c.match(/^\u001b/)) {
  85. this._hadControl = true
  86. return this.emit('data', c)
  87. } else {
  88. if (this._prompt && this._hadControl &&
  89. c.indexOf(this._prompt) === 0) {
  90. this._hadControl = false
  91. this.emit('data', this._prompt)
  92. c = c.substr(this._prompt.length)
  93. }
  94. c = c.toString().replace(/./g, this.replace)
  95. }
  96. }
  97. this.emit('data', c)
  98. }
  99. MuteStream.prototype.end = function (c) {
  100. if (this.muted) {
  101. if (c && this.replace) {
  102. c = c.toString().replace(/./g, this.replace)
  103. } else {
  104. c = null
  105. }
  106. }
  107. if (c) this.emit('data', c)
  108. this.emit('end')
  109. }
  110. function proxy (fn) { return function () {
  111. var d = this._dest
  112. var s = this._src
  113. if (d && d[fn]) d[fn].apply(d, arguments)
  114. if (s && s[fn]) s[fn].apply(s, arguments)
  115. }}
  116. MuteStream.prototype.destroy = proxy('destroy')
  117. MuteStream.prototype.destroySoon = proxy('destroySoon')
  118. MuteStream.prototype.close = proxy('close')