Skip to content

Commit

Permalink
Remove encoding option (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky authored Aug 8, 2023
1 parent 73fed4a commit 64cba16
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 55 deletions.
11 changes: 1 addition & 10 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,6 @@ export type Options = {
readonly maxBuffer?: number;
};

export type OptionsWithEncoding<EncodingType = BufferEncoding> = {
/**
The [encoding](https://nodejs.org/api/buffer.html#buffers-and-character-encodings) of the incoming stream.
@default 'utf8'
*/
readonly encoding?: EncodingType;
} & Options;

/**
Get the given `stream` as a string.
Expand Down Expand Up @@ -58,7 +49,7 @@ console.log(await getStream(stream));
// ~~
```
*/
export default function getStream(stream: Stream, options?: OptionsWithEncoding): Promise<string>;
export default function getStream(stream: Stream, options?: Options): Promise<string>;

/**
Get the given `stream` as a buffer.
Expand Down
50 changes: 29 additions & 21 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {Buffer} from 'node:buffer';
import {compose, PassThrough as PassThroughStream} from 'node:stream';

export class MaxBufferError extends Error {
name = 'MaxBufferError';
Expand All @@ -9,45 +8,54 @@ export class MaxBufferError extends Error {
}
}

export default async function getStream(inputStream, options = {}) {
if (!inputStream) {
throw new Error('Expected a stream');
}

const {maxBuffer = Number.POSITIVE_INFINITY, encoding = 'utf8'} = options;
const isBuffer = encoding === 'buffer';
export async function getStreamAsBuffer(stream, options) {
return getStreamContents(stream, chunkTypes.buffer, options);
}

const stream = new PassThroughStream({encoding: isBuffer ? undefined : encoding});
export default async function getStream(stream, options) {
return getStreamContents(stream, chunkTypes.string, options);
}

const newStream = compose(inputStream, stream);
const getStreamContents = async (stream, {convertChunk, getContents}, {maxBuffer = Number.POSITIVE_INFINITY} = {}) => {
if (!stream) {
throw new Error('Expected a stream');
}

let length = 0;
const chunks = [];

const getBufferedValue = () => isBuffer ? Buffer.concat(chunks, length) : chunks.join('');

try {
for await (const chunk of newStream) {
chunks.push(chunk);
length += chunk.length;
for await (const chunk of stream) {
const convertedChunk = convertChunk(chunk);
chunks.push(convertedChunk);
length += convertedChunk.length;

if (length > maxBuffer) {
throw new MaxBufferError();
}
}

return getBufferedValue();
return getContents(chunks, length);
} catch (error) {
try {
error.bufferedData = getBufferedValue();
error.bufferedData = getContents(chunks, length);
// This throws when the buffered data is larger than the maximum length
// for a string or buffer
} catch {}

throw error;
}
}
};

export async function getStreamAsBuffer(stream, options) {
return getStream(stream, {...options, encoding: 'buffer'});
}
const convertChunkToBuffer = chunk => Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);

const getContentsAsBuffer = (chunks, length) => Buffer.concat(chunks, length);

const convertChunkToString = chunk => typeof chunk === 'string' ? chunk : chunk.toString();

const getContentsAsString = chunks => chunks.join('');

const chunkTypes = {
buffer: {convertChunk: convertChunkToBuffer, getContents: getContentsAsBuffer},
string: {convertChunk: convertChunkToString, getContents: getContentsAsString},
};
1 change: 0 additions & 1 deletion index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const stream = fs.createReadStream('foo') as Stream;

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

expectType<Promise<Buffer>>(getStreamAsBuffer(stream));
expectType<Promise<Buffer>>(getStreamAsBuffer(stream, {maxBuffer: 10}));
Expand Down
7 changes: 0 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,6 @@ Get the given `stream` as a string.

Type: `object`

##### encoding

Type: `string`\
Default: `'utf8'`

The [encoding](https://nodejs.org/api/buffer.html#buffers-and-character-encodings) of the incoming stream.

##### maxBuffer

Type: `number`\
Expand Down
16 changes: 0 additions & 16 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import getStream, {getStreamAsBuffer, MaxBufferError} from './index.js';

const fixtureString = 'unicorn\n';
const fixtureBuffer = Buffer.from(fixtureString);
const fixtureHex = fixtureBuffer.toString('hex');
const fixtureBase64Url = fixtureBuffer.toString('base64url');

const shortString = 'abc';
const longString = `${shortString}d`;
Expand All @@ -27,24 +25,10 @@ const getStreamToBuffer = async (t, inputStream) => {
t.true(result.equals(fixtureBuffer));
};

const getStreamToHex = async (t, inputStream) => {
const result = await setup(inputStream, {encoding: 'hex'});
t.is(result, fixtureHex);
};

const getStreamToBase64Url = async (t, inputStream) => {
const result = await setup(inputStream, {encoding: 'base64Url'});
t.is(result, fixtureBase64Url);
};

test('get stream from buffer to utf8', getStreamToUtf8, fixtureBuffer);
test('get stream from buffer to buffer', getStreamToBuffer, fixtureBuffer);
test('get stream from buffer to hex', getStreamToHex, fixtureBuffer);
test('get stream from buffer to base64url', getStreamToBase64Url, fixtureBuffer);
test('get stream from utf8 to utf8', getStreamToUtf8, fixtureString);
test('get stream from utf8 to buffer', getStreamToBuffer, fixtureString);
test('get stream from utf8 to hex', getStreamToHex, fixtureString);
test('get stream from utf8 to base64url', getStreamToBase64Url, fixtureString);

test('getStream should not affect additional listeners attached to the stream', async t => {
t.plan(3);
Expand Down

0 comments on commit 64cba16

Please sign in to comment.