Skip to content

Commit

Permalink
Merge branch 'release/v1.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
rousan committed Mar 8, 2019
2 parents 9b1b087 + 3f824b2 commit ef964a6
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
extends: airbnb-base
rules:
no-underscore-dangle: 0
58 changes: 57 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
# Created by https://www.gitignore.io/api/node,macos
# Edit at https://www.gitignore.io/?templates=node,macos

### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### Node ###
# Logs
logs
*.log
Expand All @@ -20,7 +52,7 @@ coverage
# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
Expand Down Expand Up @@ -56,6 +88,30 @@ typings/

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

yarn.lock
package-lock.json

# End of https://www.gitignore.io/api/node,macos
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
language: node_js
node_js:
- "8"
before_script:
- npm install
- npm install -g codecov
script:
- npm test
- npm run report-coverage
- codecov -f coverage/coverage.lcov
67 changes: 66 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,67 @@
[![Build Status](https://travis-ci.org/rousan/read-all.svg?branch=develop)](https://travis-ci.org/rousan/read-all)
[![codecov](https://codecov.io/gh/rousan/read-all/branch/develop/graph/badge.svg)](https://codecov.io/gh/rousan/read-all)
[![NPM version](https://img.shields.io/npm/v/node-read-all.svg)](https://www.npmjs.com/package/node-read-all)
[![NPM total downloads](https://img.shields.io/npm/dt/node-read-all.svg)](https://www.npmjs.com/package/node-read-all)
[![Contributors](https://img.shields.io/github/contributors/rousan/read-all.svg)](https://github.com/rousan/read-all/graphs/contributors)
[![License](https://img.shields.io/github/license/rousan/read-all.svg)](https://github.com/rousan/read-all/blob/master/LICENSE)

# read-all
Read all data from a Readable stream in nodejs

Read all data from a Readable stream and get notified when Promise is resolved.

## Installation

Using npm:

```bash
$ npm install node-read-all
```

Using yarn:

```bash
$ yarn add node-read-all
```

## Usage

```javascript
const fs = require('fs');
const readAll = require('node-read-all');

const rStream = fs.createReadStream('file.txt');
rStream.setEncoding('utf8');
readAll(rStream)
.then(data => console.log(data))
.catch(console.error.bind(console));
```

When stream is in object mode:

```javascript
const { Transform } = require('stream');
const readAll = require('node-read-all');

const transformStream = new Transform({
readableObjectMode: true,
transform(chunk, encoding, callback) {
this.push({ value: chunk.toString() });
callback();
},
});

readAll(transformStream)
.then(data => console.log(data))
.catch(console.error.bind(console));

setTimeout(() => {
transformStream.write('a');
transformStream.write('b');
transformStream.write('c');
transformStream.end();
}, 1000);
```

## Contributing

Your PRs and stars are always welcome.
34 changes: 34 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module.exports = stream => new Promise((res, rej) => {
if (!stream.readable) {
rej(new Error('Stream must be a Readable Stream'));
return;
}

const isObjectMode = stream._readableState.objectMode;
let data;

stream.on('data', (chunk) => {
if (isObjectMode) {
data = data || [];
data.push(chunk);
} else if (chunk instanceof Buffer) {
data = data || Buffer.alloc(0);
data = Buffer.concat([data, chunk]);
} else {
data = data || '';
data = data.concat(chunk);
}
});

stream.on('end', () => {
res(data);
});

stream.on('error', (err) => {
rej(err);
});

stream.on('close', () => {
res(data);
});
});
55 changes: 55 additions & 0 deletions index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* global describe, it */
/* eslint-disable no-unused-expressions */

const { Transform } = require('stream');
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
const intoStream = require('into-stream');
const streamBuffers = require('stream-buffers');
const readAll = require('./');

chai.use(chaiAsPromised);
chai.should();

describe('readAll', () => {
it('should read all data when stream has encoding', () => {
const data = 'I will eat your all data';
const rStream = intoStream(data);
rStream.setEncoding('utf8');
return readAll(rStream).should.eventually.equal(data);
});

it('should read all data when stream hasn\'t encoding', () => {
const data = 'I will eat your all data';
const rStream = intoStream(data);
return readAll(rStream)
.then(buf => buf.equals(Buffer.from(data)))
.should.eventually.be.true;
});

it('should return an array of objects when stream is in object mode', () => {
const transformStream = new Transform({
readableObjectMode: true,
transform(chunk, encoding, callback) {
this.push({ value: chunk.toString() });
callback();
},
});

setTimeout(() => {
transformStream.write('a');
transformStream.write('b');
transformStream.write('c');
transformStream.end();
});

return readAll(transformStream)
.should.eventually
.be.eql([{ value: 'a' }, { value: 'b' }, { value: 'c' }]);
});

it('should throw error when input stream is not Readable', () => {
const writableStream = new streamBuffers.WritableStreamBuffer();
return readAll(writableStream).should.be.rejectedWith(Error);
});
});
44 changes: 44 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "node-read-all",
"version": "1.0.0",
"description": "Read all data from a Readable stream with Promise",
"main": "index.js",
"scripts": {
"test": "nyc --reporter=html --reporter=text mocha *.spec.js",
"report-coverage": "nyc report --reporter=text-lcov > coverage/coverage.lcov"
},
"repository": {
"type": "git",
"url": "git+https://github.com/rousan/read-all.git"
},
"keywords": [
"node",
"stream",
"readable",
"read",
"all",
"buffer",
"bytes",
"promise",
"async",
"await"
],
"author": "Rousan Ali <rousanali786@gmail.com> (https://rousan.io)",
"license": "MIT",
"bugs": {
"url": "https://github.com/rousan/read-all/issues"
},
"homepage": "https://github.com/rousan/read-all#readme",
"dependencies": {},
"devDependencies": {
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"eslint": "^5.15.1",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-plugin-import": "^2.16.0",
"into-stream": "^4.0.0",
"mocha": "^6.0.2",
"nyc": "^13.3.0",
"stream-buffers": "^3.0.2"
}
}

0 comments on commit ef964a6

Please sign in to comment.