Skip to content

Commit

Permalink
Require Node.js 8, add TypeScript definition (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
BendingBender authored and sindresorhus committed Mar 11, 2019
1 parent 32a3c39 commit 4ddb7f0
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 11 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Expand Up @@ -2,4 +2,3 @@ language: node_js
node_js:
- '10'
- '8'
- '6'
2 changes: 1 addition & 1 deletion buffer-stream.js
Expand Up @@ -2,7 +2,7 @@
const {PassThrough: PassThroughStream} = require('stream');

module.exports = options => {
options = Object.assign({}, options);
options = {...options};

const {array} = options;
let {encoding} = options;
Expand Down
66 changes: 66 additions & 0 deletions index.d.ts
@@ -0,0 +1,66 @@
/// <reference types="node"/>
import {Stream} from 'stream';

export interface Options {
/**
* Maximum length of the returned string. If it exceeds this value before the stream ends, the promise will be rejected with a `MaxBufferError` error.
*
* @default Infinity
*/
readonly maxBuffer?: number;
}

export interface OptionsWithEncoding<EncodingType = BufferEncoding>
extends Options {
/**
* [Encoding](https://nodejs.org/api/buffer.html#buffer_buffer) of the incoming stream.
*
* @default 'utf8'
*/
readonly encoding?: EncodingType;
}

declare const getStream: {
/**
* Get the `stream` as a string.
*
* @returns A promise that resolves when the end event fires on the stream, indicating that there is no more data to be read. The stream is switched to flowing mode.
*/
(stream: Stream, options?: OptionsWithEncoding): Promise<string>;

/**
* Get the `stream` as a buffer.
*
* It honors the `maxBuffer` option as above, but it refers to byte length rather than string length.
*/
buffer(stream: Stream, options?: OptionsWithEncoding): Promise<Buffer>;

/**
* Get the `stream` as an array of values.
*
* It honors both the `maxBuffer` and `encoding` options. The behavior changes slightly based on the encoding chosen:
*
* - When `encoding` is unset, it assumes an [object mode stream](https://nodesource.com/blog/understanding-object-streams/) and collects values emitted from `stream` unmodified. In this case `maxBuffer` refers to the number of items in the array (not the sum of their sizes).
* - When `encoding` is set to `buffer`, it collects an array of buffers. `maxBuffer` refers to the summed byte lengths of every buffer in the array.
* - When `encoding` is set to anything else, it collects an array of strings. `maxBuffer` refers to the summed character lengths of every string in the array.
*/
array<StreamObjectModeType = unknown>(
stream: Stream,
options?: Options
): Promise<StreamObjectModeType[]>;
array(
stream: Stream,
options: OptionsWithEncoding<'buffer'>
): Promise<Buffer[]>;
array(
stream: Stream,
options: OptionsWithEncoding<BufferEncoding>
): Promise<string[]>;
};

export default getStream;

export class MaxBufferError extends Error {
readonly name: 'MaxBufferError';
constructor();
}
18 changes: 12 additions & 6 deletions index.js
Expand Up @@ -9,17 +9,20 @@ class MaxBufferError extends Error {
}
}

function getStream(inputStream, options) {
async function getStream(inputStream, options) {
if (!inputStream) {
return Promise.reject(new Error('Expected a stream'));
}

options = Object.assign({maxBuffer: Infinity}, options);
options = {
maxBuffer: Infinity,
...options
};

const {maxBuffer} = options;

let stream;
return new Promise((resolve, reject) => {
await new Promise((resolve, reject) => {
const rejectPromise = error => {
if (error) { // A null check
error.bufferedData = stream.getBufferedValue();
Expand All @@ -42,10 +45,13 @@ function getStream(inputStream, options) {
rejectPromise(new MaxBufferError());
}
});
}).then(() => stream.getBufferedValue());
});

return stream.getBufferedValue();
}

module.exports = getStream;
module.exports.buffer = (stream, options) => getStream(stream, Object.assign({}, options, {encoding: 'buffer'}));
module.exports.array = (stream, options) => getStream(stream, Object.assign({}, options, {array: true}));
module.exports.default = getStream;
module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'});
module.exports.array = (stream, options) => getStream(stream, {...options, array: true});
module.exports.MaxBufferError = MaxBufferError;
27 changes: 27 additions & 0 deletions index.test-d.ts
@@ -0,0 +1,27 @@
import * as fs from 'fs';
import {expectType} from 'tsd-check';
import getStream, {MaxBufferError} from '.';

const stream = fs.createReadStream('foo');

expectType<Promise<string>>(getStream(stream));
expectType<Promise<string>>(getStream(stream, {maxBuffer: 10}));
expectType<Promise<string>>(getStream(stream, {encoding: 'utf8'}));

expectType<Promise<Buffer>>(getStream.buffer(stream));
expectType<Promise<Buffer>>(getStream.buffer(stream, {maxBuffer: 10}));
expectType<Promise<Buffer>>(getStream.buffer(stream, {encoding: 'utf8'}));

expectType<Promise<unknown>>(getStream.array(stream));
expectType<Promise<{}>>(getStream.array<{}>(stream));
expectType<Promise<unknown>>(getStream.array(stream, {maxBuffer: 10}));
expectType<Promise<Buffer[]>>(getStream.array(stream, {encoding: 'buffer'}));
expectType<Promise<Buffer[]>>(
getStream.array(stream, {maxBuffer: 10, encoding: 'buffer'})
);
expectType<Promise<string[]>>(getStream.array(stream, {encoding: 'utf8'}));
expectType<Promise<string[]>>(
getStream.array(stream, {maxBuffer: 10, encoding: 'utf8'})
);

expectType<typeof MaxBufferError>(MaxBufferError);
9 changes: 6 additions & 3 deletions package.json
Expand Up @@ -10,13 +10,14 @@
"url": "sindresorhus.com"
},
"engines": {
"node": ">=6"
"node": ">=8"
},
"scripts": {
"test": "xo && ava"
"test": "xo && ava && tsd-check"
},
"files": [
"index.js",
"index.d.ts",
"buffer-stream.js"
],
"keywords": [
Expand All @@ -39,8 +40,10 @@
"pump": "^3.0.0"
},
"devDependencies": {
"ava": "^1.2.1",
"@types/node": "^11.10.5",
"ava": "^1.3.1",
"into-stream": "^4.0.0",
"tsd-check": "^0.3.0",
"xo": "^0.24.0"
}
}

0 comments on commit 4ddb7f0

Please sign in to comment.