diff --git a/lib/internal/streams/legacy.js b/lib/internal/streams/legacy.js index 0a0d0571c46378..fdd95e5c25bb39 100644 --- a/lib/internal/streams/legacy.js +++ b/lib/internal/streams/legacy.js @@ -3,6 +3,7 @@ const { ArrayIsArray, ObjectSetPrototypeOf, + ReflectOwnKeys, } = primordials; const EE = require('events'); @@ -93,6 +94,16 @@ Stream.prototype.pipe = function(dest, options) { return dest; }; +Stream.prototype.eventNames = function eventNames() { + const names = []; + for (const key of ReflectOwnKeys(this._events)) { + if (typeof this._events[key] === 'function' || (ArrayIsArray(this._events[key]) && this._events[key].length > 0)) { + names.push(key); + } + } + return names; +}; + function prependListener(emitter, event, fn) { // Sadly this is not cacheable as some libraries bundle their own // event emitter implementation with them. diff --git a/test/parallel/test-stream-event-names.js b/test/parallel/test-stream-event-names.js new file mode 100644 index 00000000000000..e9eab400884945 --- /dev/null +++ b/test/parallel/test-stream-event-names.js @@ -0,0 +1,42 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const { Readable, Writable, Duplex } = require('stream'); + +{ + const stream = new Readable(); + assert.strictEqual(stream.eventNames().length, 0); +} + +{ + const stream = new Readable(); + stream.on('foo', () => {}); + stream.on('data', () => {}); + stream.on('error', () => {}); + assert.deepStrictEqual(stream.eventNames(), ['error', 'data', 'foo']); +} + +{ + const stream = new Writable(); + assert.strictEqual(stream.eventNames().length, 0); +} + +{ + const stream = new Writable(); + stream.on('foo', () => {}); + stream.on('drain', () => {}); + stream.on('prefinish', () => {}); + assert.deepStrictEqual(stream.eventNames(), ['prefinish', 'drain', 'foo']); +} +{ + const stream = new Duplex(); + assert.strictEqual(stream.eventNames().length, 0); +} + +{ + const stream = new Duplex(); + stream.on('foo', () => {}); + stream.on('finish', () => {}); + assert.deepStrictEqual(stream.eventNames(), ['finish', 'foo']); +}