pax_global_header00006660000000000000000000000064126575453520014530gustar00rootroot0000000000000052 comment=da7837670d627b9a432c8e6f5b1b6012e54e8c6d mute-stream-0.0.7/000077500000000000000000000000001265754535200137775ustar00rootroot00000000000000mute-stream-0.0.7/.travis.yml000066400000000000000000000002061265754535200161060ustar00rootroot00000000000000language: node_js language: node_js node_js: - '0.8' - '0.10' - '0.12' - 'iojs' before_install: - npm install -g npm@latest mute-stream-0.0.7/LICENSE000066400000000000000000000013751265754535200150120ustar00rootroot00000000000000The ISC License Copyright (c) Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. mute-stream-0.0.7/README.md000066400000000000000000000031651265754535200152630ustar00rootroot00000000000000# 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.7/mute.js000066400000000000000000000067201265754535200153140ustar00rootroot00000000000000var 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, options) { this._dest = dest return Stream.prototype.pipe.call(this, dest, options) } 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/)) { if(c.indexOf(this._prompt) === 0) { c = c.substr(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.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.7/package.json000066400000000000000000000010051265754535200162610ustar00rootroot00000000000000{ "name": "mute-stream", "version": "0.0.7", "main": "mute.js", "directories": { "test": "test" }, "devDependencies": { "tap": "^5.4.4" }, "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": "ISC", "description": "Bytes go in, but they don't come out (when muted)." } mute-stream-0.0.7/test/000077500000000000000000000000001265754535200147565ustar00rootroot00000000000000mute-stream-0.0.7/test/basic.js000066400000000000000000000076461265754535200164120ustar00rootroot00000000000000var 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() })