get-stream
Advanced tools
Comparing version 6.0.1 to 7.0.0
144
index.d.ts
@@ -1,5 +0,5 @@ | ||
/// <reference types="node"/> | ||
import {Stream} from 'stream'; | ||
import {type Stream} from 'node:stream'; | ||
import {type Buffer} from 'node:buffer'; | ||
declare class MaxBufferErrorClass extends Error { | ||
export class MaxBufferError extends Error { | ||
readonly name: 'MaxBufferError'; | ||
@@ -9,98 +9,70 @@ constructor(); | ||
declare namespace getStream { | ||
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. | ||
export type 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; | ||
} | ||
@default Infinity | ||
*/ | ||
readonly maxBuffer?: number; | ||
}; | ||
interface OptionsWithEncoding<EncodingType = BufferEncoding> extends Options { | ||
/** | ||
[Encoding](https://nodejs.org/api/buffer.html#buffer_buffer) of the incoming stream. | ||
@default 'utf8' | ||
*/ | ||
readonly encoding?: EncodingType; | ||
} | ||
type MaxBufferError = MaxBufferErrorClass; | ||
} | ||
declare const getStream: { | ||
export type OptionsWithEncoding<EncodingType = BufferEncoding> = { | ||
/** | ||
Get the `stream` as a string. | ||
The [encoding](https://nodejs.org/api/buffer.html#buffers-and-character-encodings) of the incoming stream. | ||
@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. | ||
@default 'utf8' | ||
*/ | ||
readonly encoding?: EncodingType; | ||
} & Options; | ||
@example | ||
``` | ||
import * as fs from 'fs'; | ||
import getStream = require('get-stream'); | ||
/** | ||
Get the given `stream` as a string. | ||
(async () => { | ||
const stream = fs.createReadStream('unicorn.txt'); | ||
@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. | ||
console.log(await getStream(stream)); | ||
// ,,))))))));, | ||
// __)))))))))))))), | ||
// \|/ -\(((((''''((((((((. | ||
// -*-==//////(('' . `)))))), | ||
// /|\ ))| o ;-. '((((( ,(, | ||
// ( `| / ) ;))))' ,_))^;(~ | ||
// | | | ,))((((_ _____------~~~-. %,;(;(>';'~ | ||
// o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~ | ||
// ; ''''```` `: `:::|\,__,%% );`'; ~ | ||
// | _ ) / `:|`----' `-' | ||
// ______/\/~ | / / | ||
// /~;;.____/;;' / ___--,-( `;;;/ | ||
// / // _;______;'------~~~~~ /;;/\ / | ||
// // | | / ; \;;,\ | ||
// (<_ | ; /',/-----' _> | ||
// \_| ||_ //~;~~~~~~~~~ | ||
// `\_| (,~~ | ||
// \~\ | ||
// ~~ | ||
})(); | ||
``` | ||
*/ | ||
(stream: Stream, options?: getStream.OptionsWithEncoding): Promise<string>; | ||
@example | ||
``` | ||
import fs from 'node:fs'; | ||
import getStream from 'get-stream'; | ||
/** | ||
Get the `stream` as a buffer. | ||
const stream = fs.createReadStream('unicorn.txt'); | ||
It honors the `maxBuffer` option as above, but it refers to byte length rather than string length. | ||
*/ | ||
buffer( | ||
stream: Stream, | ||
options?: getStream.Options | ||
): Promise<Buffer>; | ||
console.log(await getStream(stream)); | ||
// ,,))))))));, | ||
// __)))))))))))))), | ||
// \|/ -\(((((''''((((((((. | ||
// -*-==//////(('' . `)))))), | ||
// /|\ ))| o ;-. '((((( ,(, | ||
// ( `| / ) ;))))' ,_))^;(~ | ||
// | | | ,))((((_ _____------~~~-. %,;(;(>';'~ | ||
// o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~ | ||
// ; ''''```` `: `:::|\,__,%% );`'; ~ | ||
// | _ ) / `:|`----' `-' | ||
// ______/\/~ | / / | ||
// /~;;.____/;;' / ___--,-( `;;;/ | ||
// / // _;______;'------~~~~~ /;;/\ / | ||
// // | | / ; \;;,\ | ||
// (<_ | ; /',/-----' _> | ||
// \_| ||_ //~;~~~~~~~~~ | ||
// `\_| (,~~ | ||
// \~\ | ||
// ~~ | ||
``` | ||
*/ | ||
export default function getStream(stream: Stream, options?: OptionsWithEncoding): Promise<string>; | ||
/** | ||
Get the `stream` as an array of values. | ||
/** | ||
Get the given `stream` as a buffer. | ||
It honors both the `maxBuffer` and `encoding` options. The behavior changes slightly based on the encoding chosen: | ||
It honors the `maxBuffer` option as above, but it refers to byte length rather than string length. | ||
- 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>( | ||
stream: Stream, | ||
options?: getStream.Options | ||
): Promise<StreamObjectModeType[]>; | ||
array( | ||
stream: Stream, | ||
options: getStream.OptionsWithEncoding<'buffer'> | ||
): Promise<Buffer[]>; | ||
array( | ||
stream: Stream, | ||
options: getStream.OptionsWithEncoding<BufferEncoding> | ||
): Promise<string[]>; | ||
@example | ||
``` | ||
import {getStreamAsBuffer} from 'get-stream'; | ||
MaxBufferError: typeof MaxBufferErrorClass; | ||
}; | ||
const stream = fs.createReadStream('unicorn.png'); | ||
export = getStream; | ||
console.log(await getStreamAsBuffer(stream)); | ||
``` | ||
*/ | ||
export function getStreamAsBuffer(stream: Stream, options?: Options): Promise<Buffer>; |
79
index.js
@@ -1,17 +0,14 @@ | ||
'use strict'; | ||
const {constants: BufferConstants} = require('buffer'); | ||
const stream = require('stream'); | ||
const {promisify} = require('util'); | ||
const bufferStream = require('./buffer-stream'); | ||
import {Buffer, constants as BufferConstants} from 'node:buffer'; | ||
import {PassThrough as PassThroughStream} from 'node:stream'; | ||
import {pipeline as streamPipeline} from 'node:stream/promises'; | ||
const streamPipelinePromisified = promisify(stream.pipeline); | ||
export class MaxBufferError extends Error { | ||
name = 'MaxBufferError'; | ||
class MaxBufferError extends Error { | ||
constructor() { | ||
super('maxBuffer exceeded'); | ||
this.name = 'MaxBufferError'; | ||
} | ||
} | ||
async function getStream(inputStream, options) { | ||
export default async function getStream(inputStream, options) { | ||
if (!inputStream) { | ||
@@ -22,41 +19,47 @@ throw new Error('Expected a stream'); | ||
options = { | ||
maxBuffer: Infinity, | ||
...options | ||
maxBuffer: Number.POSITIVE_INFINITY, | ||
...options, | ||
}; | ||
const {maxBuffer} = options; | ||
const stream = bufferStream(options); | ||
let {encoding = 'utf8'} = options; | ||
const isBuffer = encoding === 'buffer'; | ||
await new Promise((resolve, reject) => { | ||
const rejectPromise = error => { | ||
// Don't retrieve an oversized buffer. | ||
if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) { | ||
error.bufferedData = stream.getBufferedValue(); | ||
} | ||
if (isBuffer) { | ||
encoding = null; | ||
} | ||
reject(error); | ||
}; | ||
const stream = new PassThroughStream(); | ||
(async () => { | ||
try { | ||
await streamPipelinePromisified(inputStream, stream); | ||
resolve(); | ||
} catch (error) { | ||
rejectPromise(error); | ||
} | ||
})(); | ||
if (encoding) { | ||
stream.setEncoding(encoding); | ||
} | ||
stream.on('data', () => { | ||
if (stream.getBufferedLength() > maxBuffer) { | ||
rejectPromise(new MaxBufferError()); | ||
await streamPipeline(inputStream, stream); | ||
let length = 0; | ||
const chunks = []; | ||
const getBufferedValue = () => isBuffer ? Buffer.concat(chunks, length) : chunks.join(''); | ||
for await (const chunk of stream) { | ||
chunks.push(chunk); | ||
length += chunk.length; | ||
if (length > maxBuffer) { | ||
const error = new MaxBufferError(); | ||
if (length <= BufferConstants.MAX_LENGTH) { | ||
error.bufferedData = getBufferedValue(); | ||
} | ||
}); | ||
}); | ||
return stream.getBufferedValue(); | ||
throw error; | ||
} | ||
} | ||
return getBufferedValue(); | ||
} | ||
module.exports = 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; | ||
export async function getStreamAsBuffer(stream, options) { | ||
return getStream(stream, {...options, encoding: 'buffer'}); | ||
} |
{ | ||
"name": "get-stream", | ||
"version": "6.0.1", | ||
"description": "Get a stream as a string, buffer, or array", | ||
"version": "7.0.0", | ||
"description": "Get a stream as a string or buffer", | ||
"license": "MIT", | ||
@@ -13,4 +13,6 @@ "repository": "sindresorhus/get-stream", | ||
}, | ||
"type": "module", | ||
"exports": "./index.js", | ||
"engines": { | ||
"node": ">=10" | ||
"node": ">=16" | ||
}, | ||
@@ -22,4 +24,3 @@ "scripts": { | ||
"index.js", | ||
"index.d.ts", | ||
"buffer-stream.js" | ||
"index.d.ts" | ||
], | ||
@@ -39,12 +40,12 @@ "keywords": [ | ||
"readablestream", | ||
"array", | ||
"object" | ||
"object", | ||
"concat" | ||
], | ||
"devDependencies": { | ||
"@types/node": "^14.0.27", | ||
"ava": "^2.4.0", | ||
"into-stream": "^5.0.0", | ||
"tsd": "^0.13.1", | ||
"xo": "^0.24.0" | ||
"@types/node": "^20.2.4", | ||
"ava": "^5.3.0", | ||
"into-stream": "^8.0.0", | ||
"tsd": "^0.28.1", | ||
"xo": "^0.54.2" | ||
} | ||
} |
124
readme.md
# get-stream | ||
> Get a stream as a string, buffer, or array | ||
> Get a stream as a string or buffer | ||
## Install | ||
```sh | ||
npm install get-stream | ||
``` | ||
$ npm install get-stream | ||
``` | ||
@@ -14,31 +14,29 @@ ## Usage | ||
```js | ||
const fs = require('fs'); | ||
const getStream = require('get-stream'); | ||
import fs from 'node:fs'; | ||
import getStream from 'get-stream'; | ||
(async () => { | ||
const stream = fs.createReadStream('unicorn.txt'); | ||
const stream = fs.createReadStream('unicorn.txt'); | ||
console.log(await getStream(stream)); | ||
/* | ||
,,))))))));, | ||
__)))))))))))))), | ||
\|/ -\(((((''''((((((((. | ||
-*-==//////(('' . `)))))), | ||
/|\ ))| o ;-. '((((( ,(, | ||
( `| / ) ;))))' ,_))^;(~ | ||
| | | ,))((((_ _____------~~~-. %,;(;(>';'~ | ||
o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~ | ||
; ''''```` `: `:::|\,__,%% );`'; ~ | ||
| _ ) / `:|`----' `-' | ||
______/\/~ | / / | ||
/~;;.____/;;' / ___--,-( `;;;/ | ||
/ // _;______;'------~~~~~ /;;/\ / | ||
// | | / ; \;;,\ | ||
(<_ | ; /',/-----' _> | ||
\_| ||_ //~;~~~~~~~~~ | ||
`\_| (,~~ | ||
\~\ | ||
~~ | ||
*/ | ||
})(); | ||
console.log(await getStream(stream)); | ||
/* | ||
,,))))))));, | ||
__)))))))))))))), | ||
\|/ -\(((((''''((((((((. | ||
-*-==//////(('' . `)))))), | ||
/|\ ))| o ;-. '((((( ,(, | ||
( `| / ) ;))))' ,_))^;(~ | ||
| | | ,))((((_ _____------~~~-. %,;(;(>';'~ | ||
o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~ | ||
; ''''```` `: `:::|\,__,%% );`'; ~ | ||
| _ ) / `:|`----' `-' | ||
______/\/~ | / / | ||
/~;;.____/;;' / ___--,-( `;;;/ | ||
/ // _;______;'------~~~~~ /;;/\ / | ||
// | | / ; \;;,\ | ||
(<_ | ; /',/-----' _> | ||
\_| ||_ //~;~~~~~~~~~ | ||
`\_| (,~~ | ||
\~\ | ||
~~ | ||
*/ | ||
``` | ||
@@ -52,3 +50,3 @@ | ||
Get the `stream` as a string. | ||
Get the given `stream` as a string. | ||
@@ -64,3 +62,3 @@ #### options | ||
[Encoding](https://nodejs.org/api/buffer.html#buffer_buffer) of the incoming stream. | ||
The [encoding](https://nodejs.org/api/buffer.html#buffers-and-character-encodings) of the incoming stream. | ||
@@ -72,35 +70,44 @@ ##### maxBuffer | ||
Maximum length of the returned string. If it exceeds this value before the stream ends, the promise will be rejected with a `getStream.MaxBufferError` error. | ||
Maximum length of the returned string. If it exceeds this value before the stream ends, the promise will be rejected with a `MaxBufferError` error. | ||
### getStream.buffer(stream, options?) | ||
### getStreamAsBuffer(stream, options?) | ||
Get the `stream` as a buffer. | ||
Get the given `stream` as a buffer. | ||
It honors the `maxBuffer` option as above, but it refers to byte length rather than string length. | ||
### getStream.array(stream, options?) | ||
```js | ||
import {getStreamAsBuffer} from 'get-stream'; | ||
Get the `stream` as an array of values. | ||
const stream = fs.createReadStream('unicorn.png'); | ||
It honors both the `maxBuffer` and `encoding` options. The behavior changes slightly based on the encoding chosen: | ||
console.log(await getStreamAsBuffer(stream)); | ||
``` | ||
- 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). | ||
## Errors | ||
- 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. | ||
If the input stream emits an `error` event, the promise will be rejected with the error. The buffered data will be attached to the `bufferedData` property of the error. | ||
- 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. | ||
```js | ||
import getStream from 'get-stream'; | ||
## Errors | ||
try { | ||
await getStream(streamThatErrorsAtTheEnd('unicorn')); | ||
} catch (error) { | ||
console.log(error.bufferedData); | ||
//=> 'unicorn' | ||
} | ||
``` | ||
If the input stream emits an `error` event, the promise will be rejected with the error. The buffered data will be attached to the `bufferedData` property of the error. | ||
## Tip | ||
You may not need this package if all you need is a string: | ||
```js | ||
(async () => { | ||
try { | ||
await getStream(streamThatErrorsAtTheEnd('unicorn')); | ||
} catch (error) { | ||
console.log(error.bufferedData); | ||
//=> 'unicorn' | ||
} | ||
})() | ||
import fs from 'node:fs'; | ||
const stream = fs.createReadStream('unicorn.txt', {encoding: 'utf8'}); | ||
const array = await stream.toArray(); | ||
console.log(array.join('')); | ||
``` | ||
@@ -112,3 +119,3 @@ | ||
This module accepts a stream instead of being one and returns a promise instead of using a callback. The API is simpler and it only supports returning a string, buffer, or array. It doesn't have a fragile type inference. You explicitly choose what you want. And it doesn't depend on the huge `readable-stream` package. | ||
This module accepts a stream instead of being one and returns a promise instead of using a callback. The API is simpler and it only supports returning a string or buffer. It doesn't have a fragile type inference. You explicitly choose what you want. And it doesn't depend on the huge `readable-stream` package. | ||
@@ -118,13 +125,2 @@ ## Related | ||
- [get-stdin](https://github.com/sindresorhus/get-stdin) - Get stdin as a string or buffer | ||
--- | ||
<div align="center"> | ||
<b> | ||
<a href="https://tidelift.com/subscription/pkg/npm-get-stream?utm_source=npm-get-stream&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a> | ||
</b> | ||
<br> | ||
<sub> | ||
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies. | ||
</sub> | ||
</div> | ||
- [into-stream](https://github.com/sindresorhus/into-stream) - The opposite of this package |
Yes
9328
5
109
121