pipe-dreams

Create pipeable commands String them together using standard unix methods such as

Usage no npm install needed!

<script type="module">
  import pipeDreams from 'https://cdn.skypack.dev/pipe-dreams';
</script>

README

Pipe Dreams

Create pipeable commands String them together using standard unix methods such as

Pre-Requesites

You must install node [and npm] before using.

Installation

npm

Install using npm

#!/bin/bash
npm install -g pipe-dreams

docker

Install with docker (experimental)

#!/bin/bash
git clone git@github.com:johnhenry/pipe-dreams.git
cd pipe-dreams
docker build -t pipe-dreams .
alias pipe-dreams='docker run -it pipe-dreams ./bin/index.js'

Usage

#!/bin/bash
pipe-dreams [command]

Commands

node

Pipe Data through node modules

#!/bin/bash
pipe-dreams node [options]

Push modules

Data can be fead from a module into standard output.

#!/bin/bash
pipe-dreams node [path to module]

A push module takes an init object and exports an event dispatcher that dispatches a 'message' event.

Example

The following example displays sends the current date to standard the output stream every 0.5 to 2.0 seconds

//file:///example/node/push/random-time.js
module.exports = () => {
  let messageFunc;
  const addEventListener = (event, func) => messageFunc = func;
  const interrupt = () => {
    if(messageFunc) messageFunc(new Date() + '\n');
    setTimeout(interrupt, Math.random() * 2000 + 500);
  };
  interrupt();
  return {addEventListener};
}
#file:///example/node/push/push-modules.sh
alias random-time='pipe-dreams node example/node/push/random-time.js'
#!/bin/bash
source example/node/push/push-modules.sh
#!/bin/bash
random-time
  Sun Jun 05 2016 12:51:37 GMT-0700 (PDT)
  Sun Jun 05 2016 12:51:39 GMT-0700 (PDT)
  Sun Jun 05 2016 12:51:40 GMT-0700 (PDT)
  Sun Jun 05 2016 12:51:43 GMT-0700 (PDT)
  Sun Jun 05 2016 12:51:44 GMT-0700 (PDT)
  Sun Jun 05 2016 12:51:46 GMT-0700 (PDT)
  Sun Jun 05 2016 12:51:49 GMT-0700 (PDT)

Pull modules

Data can be transformed and sent to standard output.

#!/bin/bash
pipe-dreams node [path to transformation module]

A pull module takes an init object and exports function. This function may either a flat object or a promise to be unwrapped.

If this command is the first in a series of commands, it will read input typed into the command line.

Example

The following example accepts user input and evaluates it

//file:///example/node/pull/js-eval.js
module.exports = (init) => (input) => JSON.stringify({input:input.stdin, output:eval(input.stdin)});
#file:///example/node/pull/pull-modules.sh
alias js-eval='pipe-dreams node example/node/pull/js-eval.js'
#!/bin/bash
source example/node/pull/pull-modules.sh
#!/bin/bash
js-eval
>1
{"input":"1", output:"1"}
>1+1
{"input":"1+1", output:"2"}

Dual modules

Modules can function as both push and pull modules.

Example

The following combines a push and a pull module into one.

//file:///example/node/pushpull/pushpull.js
module.exports = (init) => {
  return Object.assign(
    require('../pull/js-eval')(init),
    require('../push/random-time')(init));
};
#file:///example/node/pushpull/pushpull-modules.sh
alias push-pull='pipe-dreams node example/node/pushpull/pushpull.js'
#!/bin/bash
source example/node/pushpull/pushpull-modules.sh
#!/bin/bash
push-pull
>1
{"input":"1", output:"1"}
>1+1
{"input":"1+1", output:"2"}

Pipe Commands

Commands can be piped into one another

Example

The following example first sends the users's input to google, then extracts the title of the page from the response, and finally prompts the user for more input.

//file:///example/node/pull/query.js
const fetch = require('node-fetch');
module.exports = (init) => (query) => fetch(`${query.search}${query.stdin}`)
  .then(response=>response.text())
  .then(body=>JSON.stringify({body}));
//file:///example/node/pull/extract-title.js
const cheerio = require('cheerio');
module.exports = (init) => (response)=>{
  try{
    const $ = cheerio.load(JSON.parse(response.stdin).body);
    const title = $('title').html();
    return Promise.resolve(JSON.stringify({title}));
  }catch(error){
    return Promise.reject(error);
  }
}
//file:///example/node/pull/prompt-next.js
module.exports = (init) => (input) => input.stdin + '\nnext?\n';
#file:///example/node/pipe-commands.sh
alias duckduckgo-query='pipe-dreams node example/node/pull/query.js --init.search="https://duckduckgo.com/?q="'
alias google-query='pipe-dreams node example/node/pull/query.js --init.search="https://www.google.com/search?q="'
alias extract-title='pipe-dreams node example/node/pull/extract-title.js -u title'
alias prompt-next='pipe-dreams node example/node/pull/prompt-next.js'
alias search='duckduckgo-query | extract-title | prompt-next'
#!/bin/bash
source example/node/pipe-commands.sh
#!/bin/bash
search

Redirection

You can take advantage of standard unix redirection to create a fully modular application,

Example

In addition to displaying expected output, the following command will write successful responses and errors to files "success.log" and "error.log" respectively.

#file:///example/node/redirection.sh
source example/node/pull/pull-modules.sh &&
alias calculator='js-eval \
  1> >(>> success.log) 2> >(>> error.log) \
  | cat'
source example/node/redirection.sh
#!/bin/bash
calculator