Skip to content

Commit

Permalink
Add support for HTTP stream instances (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky authored Feb 19, 2024
1 parent 6913e34 commit 45e90c2
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 9 deletions.
4 changes: 2 additions & 2 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
Expand All @@ -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
```
Expand Down
15 changes: 11 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
41 changes: 40 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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));
Expand All @@ -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 => {
Expand All @@ -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(''));
});

0 comments on commit 45e90c2

Please sign in to comment.