diff --git a/index.d.ts b/index.d.ts index df994e0..17a159d 100644 --- a/index.d.ts +++ b/index.d.ts @@ -24,7 +24,7 @@ isStream({}); export function isStream(stream: unknown): stream is Stream; /** -@returns Whether `stream` is a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable). +@returns Whether `stream` is a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable), an [`http.OutgoingMessage`](https://nodejs.org/api/http.html#class-httpoutgoingmessage), an [`http.ServerResponse`](https://nodejs.org/api/http.html#class-httpserverresponse) or an [`http.ClientRequest`](https://nodejs.org/api/http.html#class-httpserverresponse). @example ``` @@ -38,7 +38,7 @@ isWritableStream(fs.createWriteStrem('unicorn.txt')); export function isWritableStream(stream: unknown): stream is WritableStream; /** -@returns Whether `stream` is a [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable). +@returns Whether `stream` is a [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable) or an [`http.IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage). @example ``` diff --git a/index.js b/index.js index 887e601..29a552f 100644 --- a/index.js +++ b/index.js @@ -7,15 +7,22 @@ export function isStream(stream) { export function isWritableStream(stream) { return isStream(stream) && stream.writable !== false - && typeof stream._write === 'function' - && typeof stream._writableState === 'object'; + && typeof stream.write === 'function' + && typeof stream.end === 'function' + && typeof stream.writable === 'boolean' + && typeof stream.writableObjectMode === 'boolean' + && typeof stream.destroy === 'function' + && typeof stream.destroyed === 'boolean'; } export function isReadableStream(stream) { return isStream(stream) && stream.readable !== false - && typeof stream._read === 'function' - && typeof stream._readableState === 'object'; + && typeof stream.read === 'function' + && typeof stream.readable === 'boolean' + && typeof stream.readableObjectMode === 'boolean' + && typeof stream.destroy === 'function' + && typeof stream.destroyed === 'boolean'; } export function isDuplexStream(stream) { diff --git a/readme.md b/readme.md index c6f8c1b..2ea18aa 100644 --- a/readme.md +++ b/readme.md @@ -29,11 +29,11 @@ Returns a `boolean` for whether it's a [`Stream`](https://nodejs.org/api/stream. #### isWritableStream(stream) -Returns a `boolean` for whether it's a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable). +Returns a `boolean` for whether it's a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable), an [`http.OutgoingMessage`](https://nodejs.org/api/http.html#class-httpoutgoingmessage), an [`http.ServerResponse`](https://nodejs.org/api/http.html#class-httpserverresponse) or an [`http.ClientRequest`](https://nodejs.org/api/http.html#class-httpserverresponse). #### isReadableStream(stream) -Returns a `boolean` for whether it's a [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable). +Returns a `boolean` for whether it's a [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable) or an [`http.IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage). #### isDuplexStream(stream) diff --git a/test.js b/test.js index 92e79d3..2f78f35 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,6 @@ import fs from 'node:fs'; import Stream from 'node:stream'; +import http from 'node:http'; import net from 'node:net'; import test from 'ava'; import tempy from 'tempy'; @@ -20,6 +21,10 @@ test('isStream()', t => { t.true(isStream(new Stream.PassThrough())); t.true(isStream(fs.createReadStream('test.js'))); t.true(isStream(fs.createWriteStream(tempy.file()))); + t.true(isStream(new http.OutgoingMessage())); + t.true(isStream(new http.IncomingMessage())); + t.true(isStream(new http.ServerResponse({}))); + t.true(isStream(new http.ClientRequest('http://example.com'))); t.true(isStream(new net.Socket())); t.false(isStream({})); t.false(isStream(null)); @@ -33,10 +38,18 @@ test('isWritableStream()', t => { t.true(isWritableStream(new Stream.Transform())); t.true(isWritableStream(new Stream.PassThrough())); t.true(isWritableStream(fs.createWriteStream(tempy.file()))); + t.true(isWritableStream(new http.OutgoingMessage())); + t.true(isWritableStream(new http.ServerResponse({}))); + t.true(isWritableStream(new http.ClientRequest('http://example.com'))); t.true(isWritableStream(new net.Socket())); t.false(isWritableStream(new Stream.Stream())); t.false(isWritableStream(new Stream.Readable())); t.false(isWritableStream(fs.createReadStream('test.js'))); + t.false(isWritableStream(new http.IncomingMessage())); + t.false(isWritableStream({})); + t.false(isWritableStream(null)); + t.false(isWritableStream(undefined)); + t.false(isWritableStream('')); }); test('isReadableStream()', t => { @@ -45,30 +58,56 @@ test('isReadableStream()', t => { t.true(isReadableStream(new Stream.Transform())); t.true(isReadableStream(new Stream.PassThrough())); t.true(isReadableStream(fs.createReadStream('test.js'))); + t.true(isReadableStream(new http.IncomingMessage())); t.true(isReadableStream(new net.Socket())); t.false(isReadableStream(new Stream.Stream())); t.false(isReadableStream(new Stream.Writable())); t.false(isReadableStream(fs.createWriteStream(tempy.file()))); + t.false(isReadableStream(new http.OutgoingMessage())); + t.false(isReadableStream(new http.ServerResponse({}))); + t.false(isReadableStream(new http.ClientRequest('http://example.com'))); + t.false(isReadableStream({})); + t.false(isReadableStream(null)); + t.false(isReadableStream(undefined)); + t.false(isReadableStream('')); }); test('isDuplexStream()', t => { t.true(isDuplexStream(new Stream.Duplex())); t.true(isDuplexStream(new Stream.Transform())); t.true(isDuplexStream(new Stream.PassThrough())); + t.true(isDuplexStream(new net.Socket())); t.false(isDuplexStream(new Stream.Stream())); t.false(isDuplexStream(new Stream.Readable())); t.false(isDuplexStream(new Stream.Writable())); t.false(isDuplexStream(fs.createReadStream('test.js'))); t.false(isDuplexStream(fs.createWriteStream(tempy.file()))); + t.false(isDuplexStream(new http.OutgoingMessage())); + t.false(isDuplexStream(new http.IncomingMessage())); + t.false(isDuplexStream(new http.ServerResponse({}))); + t.false(isDuplexStream(new http.ClientRequest('http://example.com'))); + t.false(isDuplexStream({})); + t.false(isDuplexStream(null)); + t.false(isDuplexStream(undefined)); + t.false(isDuplexStream('')); }); test('isTransformStream()', t => { t.true(isTransformStream(new Stream.Transform())); t.true(isTransformStream(new Stream.PassThrough())); - t.false(isTransformStream(new Stream.Duplex())); t.false(isTransformStream(new Stream.Stream())); t.false(isTransformStream(new Stream.Readable())); t.false(isTransformStream(new Stream.Writable())); + t.false(isTransformStream(new Stream.Duplex())); t.false(isTransformStream(fs.createReadStream('test.js'))); t.false(isTransformStream(fs.createWriteStream(tempy.file()))); + t.false(isTransformStream(new http.OutgoingMessage())); + t.false(isTransformStream(new http.IncomingMessage())); + t.false(isTransformStream(new http.ServerResponse({}))); + t.false(isTransformStream(new http.ClientRequest('http://example.com'))); + t.false(isTransformStream(new net.Socket())); + t.false(isTransformStream({})); + t.false(isTransformStream(null)); + t.false(isTransformStream(undefined)); + t.false(isTransformStream('')); });