pax_global_header00006660000000000000000000000064121706464210014515gustar00rootroot0000000000000052 comment=785b1ce3efa0bc0829498407600ec4b8f1e39842 mute-stream-0.0.4/000077500000000000000000000000001217064642100137615ustar00rootroot00000000000000mute-stream-0.0.4/LICENSE000066400000000000000000000024361217064642100147730ustar00rootroot00000000000000Copyright (c) Isaac Z. Schlueter ("Author") All rights reserved. The BSD License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mute-stream-0.0.4/README.md000066400000000000000000000031651217064642100152450ustar00rootroot00000000000000# mute-stream Bytes go in, but they don't come out (when muted). This is a basic pass-through stream, but when muted, the bytes are silently dropped, rather than being passed through. ## Usage ```javascript var MuteStream = require('mute-stream') var ms = new MuteStream(options) ms.pipe(process.stdout) ms.write('foo') // writes 'foo' to stdout ms.mute() ms.write('bar') // does not write 'bar' ms.unmute() ms.write('baz') // writes 'baz' to stdout // can also be used to mute incoming data var ms = new MuteStream input.pipe(ms) ms.on('data', function (c) { console.log('data: ' + c) }) input.emit('data', 'foo') // logs 'foo' ms.mute() input.emit('data', 'bar') // does not log 'bar' ms.unmute() input.emit('data', 'baz') // logs 'baz' ``` ## Options All options are optional. * `replace` Set to a string to replace each character with the specified string when muted. (So you can show `****` instead of the password, for example.) * `prompt` If you are using a replacement char, and also using a prompt with a readline stream (as for a `Password: *****` input), then specify what the prompt is so that backspace will work properly. Otherwise, pressing backspace will overwrite the prompt with the replacement character, which is weird. ## ms.mute() Set `muted` to `true`. Turns `.write()` into a no-op. ## ms.unmute() Set `muted` to `false` ## ms.isTTY True if the pipe destination is a TTY, or if the incoming pipe source is a TTY. ## Other stream methods... The other standard readable and writable stream methods are all available. The MuteStream object acts as a facade to its pipe source and destination. mute-stream-0.0.4/mute.js000066400000000000000000000064301217064642100152740ustar00rootroot00000000000000var Stream = require('stream') module.exports = MuteStream // var out = new MuteStream(process.stdout) // argument auto-pipes function MuteStream (opts) { Stream.apply(this) opts = 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 } MuteStream.prototype = Object.create(Stream.prototype) Object.defineProperty(MuteStream.prototype, 'constructor', { value: MuteStream, enumerable: false }) MuteStream.prototype.mute = function () { this.muted = true } MuteStream.prototype.unmute = function () { this.muted = false } Object.defineProperty(MuteStream.prototype, '_onpipe', { value: onPipe, enumerable: false, writable: true, configurable: true }) function onPipe (src) { this._src = src } Object.defineProperty(MuteStream.prototype, 'isTTY', { get: getIsTTY, set: setIsTTY, enumerable: true, configurable: true }) function getIsTTY () { return( (this._dest) ? this._dest.isTTY : (this._src) ? this._src.isTTY : false ) } // basically just get replace the getter/setter with a regular value function setIsTTY (isTTY) { Object.defineProperty(this, 'isTTY', { value: isTTY, enumerable: true, writable: true, configurable: true }) } Object.defineProperty(MuteStream.prototype, 'rows', { get: function () { return( this._dest ? this._dest.rows : this._src ? this._src.rows : undefined ) }, enumerable: true, configurable: true }) Object.defineProperty(MuteStream.prototype, 'columns', { get: function () { return( this._dest ? this._dest.columns : this._src ? this._src.columns : undefined ) }, enumerable: true, configurable: true }) MuteStream.prototype.pipe = function (dest) { this._dest = dest return Stream.prototype.pipe.call(this, dest) } MuteStream.prototype.pause = function () { if (this._src) return this._src.pause() } MuteStream.prototype.resume = function () { if (this._src) return this._src.resume() } MuteStream.prototype.write = function (c) { if (this.muted) { if (!this.replace) return true if (c.match(/^\u001b/)) { 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.substr(this._prompt.length) } c = c.toString().replace(/./g, this.replace) } } this.emit('data', c) } MuteStream.prototype.end = function (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') } function proxy (fn) { return function () { var d = this._dest var s = this._src if (d && d[fn]) d[fn].apply(d, arguments) if (s && s[fn]) s[fn].apply(s, arguments) }} MuteStream.prototype.destroy = proxy('destroy') MuteStream.prototype.destroySoon = proxy('destroySoon') MuteStream.prototype.close = proxy('close') mute-stream-0.0.4/package.json000066400000000000000000000010051217064642100162430ustar00rootroot00000000000000{ "name": "mute-stream", "version": "0.0.4", "main": "mute.js", "directories": { "test": "test" }, "devDependencies": { "tap": "~0.2.5" }, "scripts": { "test": "tap test/*.js" }, "repository": { "type": "git", "url": "git://github.com/isaacs/mute-stream" }, "keywords": [ "mute", "stream", "pipe" ], "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "license": "BSD", "description": "Bytes go in, but they don't come out (when muted)." } mute-stream-0.0.4/test/000077500000000000000000000000001217064642100147405ustar00rootroot00000000000000mute-stream-0.0.4/test/basic.js000066400000000000000000000076461217064642100163740ustar00rootroot00000000000000var Stream = require('stream') var tap = require('tap') var MS = require('../mute.js') // some marker objects var END = {} var PAUSE = {} var RESUME = {} function PassThrough () { Stream.call(this) this.readable = this.writable = true } PassThrough.prototype = Object.create(Stream.prototype, { constructor: { value: PassThrough }, write: { value: function (c) { this.emit('data', c) return true } }, end: { value: function (c) { if (c) this.write(c) this.emit('end') } }, pause: { value: function () { this.emit('pause') } }, resume: { value: function () { this.emit('resume') } } }) tap.test('incoming', function (t) { var ms = new MS var str = new PassThrough str.pipe(ms) var expect = ['foo', 'boo', END] ms.on('data', function (c) { t.equal(c, expect.shift()) }) ms.on('end', function () { t.equal(END, expect.shift()) t.end() }) str.write('foo') ms.mute() str.write('bar') ms.unmute() str.write('boo') ms.mute() str.write('blaz') str.end('grelb') }) tap.test('outgoing', function (t) { var ms = new MS var str = new PassThrough ms.pipe(str) var expect = ['foo', 'boo', END] str.on('data', function (c) { t.equal(c, expect.shift()) }) str.on('end', function () { t.equal(END, expect.shift()) t.end() }) ms.write('foo') ms.mute() ms.write('bar') ms.unmute() ms.write('boo') ms.mute() ms.write('blaz') ms.end('grelb') }) tap.test('isTTY', function (t) { var str = new PassThrough str.isTTY = true str.columns=80 str.rows=24 var ms = new MS t.equal(ms.isTTY, false) t.equal(ms.columns, undefined) t.equal(ms.rows, undefined) ms.pipe(str) t.equal(ms.isTTY, true) t.equal(ms.columns, 80) t.equal(ms.rows, 24) str.isTTY = false t.equal(ms.isTTY, false) t.equal(ms.columns, 80) t.equal(ms.rows, 24) str.isTTY = true t.equal(ms.isTTY, true) t.equal(ms.columns, 80) t.equal(ms.rows, 24) ms.isTTY = false t.equal(ms.isTTY, false) t.equal(ms.columns, 80) t.equal(ms.rows, 24) ms = new MS t.equal(ms.isTTY, false) str.pipe(ms) t.equal(ms.isTTY, true) str.isTTY = false t.equal(ms.isTTY, false) str.isTTY = true t.equal(ms.isTTY, true) ms.isTTY = false t.equal(ms.isTTY, false) t.end() }) tap.test('pause/resume incoming', function (t) { var str = new PassThrough var ms = new MS str.on('pause', function () { t.equal(PAUSE, expect.shift()) }) str.on('resume', function () { t.equal(RESUME, expect.shift()) }) var expect = [PAUSE, RESUME, PAUSE, RESUME] str.pipe(ms) ms.pause() ms.resume() ms.pause() ms.resume() t.equal(expect.length, 0, 'saw all events') t.end() }) tap.test('replace with *', function (t) { var str = new PassThrough var ms = new MS({replace: '*'}) str.pipe(ms) var expect = ['foo', '*****', 'bar', '***', 'baz', 'boo', '**', '****'] ms.on('data', function (c) { t.equal(c, expect.shift()) }) str.write('foo') ms.mute() str.write('12345') ms.unmute() str.write('bar') ms.mute() str.write('baz') ms.unmute() str.write('baz') str.write('boo') ms.mute() str.write('xy') str.write('xyzΩ') t.equal(expect.length, 0) t.end() }) tap.test('replace with ~YARG~', function (t) { var str = new PassThrough var ms = new MS({replace: '~YARG~'}) str.pipe(ms) var expect = ['foo', '~YARG~~YARG~~YARG~~YARG~~YARG~', 'bar', '~YARG~~YARG~~YARG~', 'baz', 'boo', '~YARG~~YARG~', '~YARG~~YARG~~YARG~~YARG~'] ms.on('data', function (c) { t.equal(c, expect.shift()) }) // also throw some unicode in there, just for good measure. str.write('foo') ms.mute() str.write('ΩΩ') ms.unmute() str.write('bar') ms.mute() str.write('Ω') ms.unmute() str.write('baz') str.write('boo') ms.mute() str.write('Ω') str.write('ΩΩ') t.equal(expect.length, 0) t.end() })