123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- const Stream = require('stream')
- class MuteStream extends Stream {
- #isTTY = null
- constructor (opts = {}) {
- super(opts)
- this.writable = this.readable = true
- this.muted = false
- this.on('pipe', this._onpipe)
- this.replace = opts.replace
- // For readline-type situations
- // This much at the start of a line being redrawn after a ctrl char
- // is seen (such as backspace) won't be redrawn as the replacement
- this._prompt = opts.prompt || null
- this._hadControl = false
- }
- #destSrc (key, def) {
- if (this._dest) {
- return this._dest[key]
- }
- if (this._src) {
- return this._src[key]
- }
- return def
- }
- #proxy (method, ...args) {
- if (typeof this._dest?.[method] === 'function') {
- this._dest[method](...args)
- }
- if (typeof this._src?.[method] === 'function') {
- this._src[method](...args)
- }
- }
- get isTTY () {
- if (this.#isTTY !== null) {
- return this.#isTTY
- }
- return this.#destSrc('isTTY', false)
- }
- // basically just get replace the getter/setter with a regular value
- set isTTY (val) {
- this.#isTTY = val
- }
- get rows () {
- return this.#destSrc('rows')
- }
- get columns () {
- return this.#destSrc('columns')
- }
- mute () {
- this.muted = true
- }
- unmute () {
- this.muted = false
- }
- _onpipe (src) {
- this._src = src
- }
- pipe (dest, options) {
- this._dest = dest
- return super.pipe(dest, options)
- }
- pause () {
- if (this._src) {
- return this._src.pause()
- }
- }
- resume () {
- if (this._src) {
- return this._src.resume()
- }
- }
- write (c) {
- if (this.muted) {
- if (!this.replace) {
- return true
- }
- // eslint-disable-next-line no-control-regex
- if (c.match(/^\u001b/)) {
- if (c.indexOf(this._prompt) === 0) {
- c = c.slice(this._prompt.length)
- c = c.replace(/./g, this.replace)
- c = this._prompt + c
- }
- this._hadControl = true
- return this.emit('data', c)
- } else {
- if (this._prompt && this._hadControl &&
- c.indexOf(this._prompt) === 0) {
- this._hadControl = false
- this.emit('data', this._prompt)
- c = c.slice(this._prompt.length)
- }
- c = c.toString().replace(/./g, this.replace)
- }
- }
- this.emit('data', c)
- }
- end (c) {
- if (this.muted) {
- if (c && this.replace) {
- c = c.toString().replace(/./g, this.replace)
- } else {
- c = null
- }
- }
- if (c) {
- this.emit('data', c)
- }
- this.emit('end')
- }
- destroy (...args) {
- return this.#proxy('destroy', ...args)
- }
- destroySoon (...args) {
- return this.#proxy('destroySoon', ...args)
- }
- close (...args) {
- return this.#proxy('close', ...args)
- }
- }
- module.exports = MuteStream
|