Skip to content

Commit

Permalink
Merge pull request #3 from Kikobeats/piping
Browse files Browse the repository at this point in the history
feat: add piping support
  • Loading branch information
Kikobeats authored Dec 12, 2023
2 parents e140dde + b90416a commit 1897076
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,22 @@ It's recommended to bind **tinyspawn** to `$`:
const $ = require('tinyspawn')
```

After that, pass the command (with arguments) to execute as first argument:
After that, pass the command (with arguments) to be executed as first argument:

```js
const { stdout } = await $(`node -e 'console.log("hello world")'`)
console.log(stdout) // => 'hello world'
```

Additionally, you can pass [spawn#options](https://nodejs.org/api/child_process.html#child_processspawncommand-args-options) as second argument:
You can pass any [spawn#options](https://nodejs.org/api/child_process.html#child_processspawncommand-args-options) as second argument:

```js
const { stdout } = $(`node -e 'console.log("hello world")'`, {
shell: true
})
```

Any of the [ChildProcess](https://nodejs.org/api/child_process.html#class-childprocess) instance properties are available as part of the output:
The output is a [ChildProcess](https://nodejs.org/api/child_process.html#class-childprocess) instance:

```js
const {
Expand All @@ -60,6 +60,19 @@ const {
} = await $('date')
```

### Piping

Since **tinyspawn** returns a [ChildProcess](https://nodejs.org/api/child_process.html#class-childprocess) instance, you can use it for interacting with other Node.js streams:

```js
// It's a childProcess instance
const subprocess = $('echo 1234567890')
subprocess.stdout.pipe(process.stdout) // => 1234567890

// And it's a promise too
await subprocess
```

### JSON parsing

**tinyspawn** has been designed to work with CLI commands that outputs json.
Expand Down
8 changes: 6 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ const parse = (stream, { json } = {}) => (encoding, start, end) => {

const extend = defaults => (input, options) => {
const [cmd, ...args] = input.split(' ').filter(Boolean)
let childProcess

return new Promise((resolve, reject) => {
const promise = new Promise((resolve, reject) => {
const opts = { ...defaults, ...options }
const childProcess = spawn(cmd, args, opts)
childProcess = spawn(cmd, args, opts)

const stdout = eos(childProcess, 'stdout')
const stderr = eos(childProcess, 'stderr')

Expand All @@ -38,6 +40,8 @@ const extend = defaults => (input, options) => {
reject(error)
})
})

return Object.assign(promise, childProcess)
}

const $ = extend()
Expand Down
21 changes: 21 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict'

const { Writable } = require('stream')
const { EOL } = require('os')
const test = require('ava')

const $ = require('..').extend({ shell: true })
Expand Down Expand Up @@ -54,3 +56,22 @@ test('$.json', async t => {
const { stdout } = await require('..').json('curl https://geolocation.microlink.io')
t.true(!!stdout.ip.address)
})

test('piping subprocess', async t => {
const stream = new Writable({
construct (callback) {
this.buffer = []
callback()
},
write (chunk, encoding, callback) {
this.buffer.push(chunk)
callback()
}
})

const subprocess = $('echo 1234567890')
subprocess.stdout.pipe(stream)
await subprocess

t.is(stream.buffer.toString(), `1234567890${EOL}`)
})

0 comments on commit 1897076

Please sign in to comment.