# @pawelgalazka/cli

> Functions based CLI framework

Latest version **2.0.3** (published 2020-04-26) · MIT license · 0 weekly downloads

> **Deprecated.** This package is deprecated.

## Install

```sh
npm install @pawelgalazka/cli
pnpm add @pawelgalazka/cli
yarn add @pawelgalazka/cli
bun add @pawelgalazka/cli
```

## Health

**Score 10/100 (F)** — status: deprecated.

Negative: deprecated.

## Facts

| | |
|---|---|
| Version | 2.0.3 |
| Published | 2020-04-26 |
| First published | 2019-02-09 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Node | >=8.6.0 |
| Dependencies | 4 |
| Unpacked size | 32.1 KB |
| Known vulnerabilities | 0 (+6 in 1 direct dependencies) |
| Install scripts | no |
| GitHub stars | 9 |
| Author | Pawel Galazka |
| Maintainers | pawelgalazka |
| Keywords | cli, option, parser, command, commander |

## Links

- npm: https://www.npmjs.com/package/@pawelgalazka/cli
- Repository: https://github.com/pawelgalazka/cli
- Homepage: https://github.com/pawelgalazka/cli#readme
- Issues: https://github.com/pawelgalazka/cli/issues
- npm.io page: https://npm.io/package/@pawelgalazka/cli

## Dependencies (4)

- [chalk](https://npm.io/package/chalk.md) 2.4.2
- [lodash](https://npm.io/package/lodash.md) 4.17.15
- [@pawelgalazka/cli-args](https://npm.io/package/@pawelgalazka/cli-args.md) 1.1.3
- [@pawelgalazka/middleware](https://npm.io/package/@pawelgalazka/middleware.md) 1.0.0

## Alternatives

- [@salesforce/cli](https://npm.io/package/@salesforce/cli.md) — 389.7K weekly downloads
- [@mintlify/cli](https://npm.io/package/@mintlify/cli.md) — 208.9K weekly downloads
- [@grafana/e2e-selectors](https://npm.io/package/@grafana/e2e-selectors.md) — 128.7K weekly downloads
- [mintlify](https://npm.io/package/mintlify.md) — 112.0K weekly downloads
- [@intlayer/cli](https://npm.io/package/@intlayer/cli.md) — 22.8K weekly downloads

## Recent versions

- 2.0.3 (latest) — 2020-04-26
- 2.0.2 — 2019-04-19
- 2.0.1 — 2019-04-19
- 2.0.0 — 2019-04-16
- 2.0.0-beta.1 — 2019-02-10
- 1.4.1 — 2019-02-09
- 1.3.5 — 2019-02-09
- 1.3.4 — 2019-02-09

## README

# CLI ![node version](https://img.shields.io/node/v/%40pawelgalazka%2Fcli.svg) [![Build Status](https://travis-ci.org/pawelgalazka/cli.svg?branch=master)](https://travis-ci.org/pawelgalazka/cli) [![npm version](https://badge.fury.io/js/%40pawelgalazka%2Fcli.svg)](https://badge.fury.io/js/%40pawelgalazka%2Fcli)
Functions based CLI framework

- [Quick start](#quick-start)
- [Add help](#add-help)
- [Add commands](#add-commands)
- [Add namespaces](#add-namespaces)
- [Add middleware](#add-middleware)
- [Use TypeScript](#use-typescript)

## Quick Start

```sh
$ npm install @pawelgalazka/cli --save
$ touch yourScript.js                    # add your script file
$ chmod a+x ./yourScript.js              # add execute permissions
```

`yourScript.js`:
```js
#!/usr/bin/env node
const { cli } = require('@pawelgalazka/cli')

cli((options, name = '', surname = '') => {
  console.log(`Hello ${name} ${surname}!`)
  if (options.yay) {
    console.log('YAY!')
  }
})
```

```sh
$ ./yourScript.js Pawel Galazka
Hello Pawel Galazka!
```

```sh
$ ./yourScript.js Pawel Galazka --yay
Hello Pawel Galazka!
YAY!
```

## Add help

```js
#!/usr/bin/env node
const { cli, withHelp } = require('@pawelgalazka/cli')

cli(withHelp((options, name = '', surname = '') => {
  console.log(`Hello ${name} ${surname}!`)
  if (options.yay) {
    console.log('YAY!')
  }
}, 'Script description'))
```

```sh
$ ./yourScript.js --help
Usage: yourScript.js

Script description
```

You can also add more detailed `help` which will print out info
about options and params:

```js
#!/usr/bin/env node
const { cli, help } = require('@pawelgalazka/cli')

function command(options, name = '', surname = '') {
  console.log(`Hello ${name} ${surname}!`)
  if (options.yay) {
    console.log('YAY!')
  }  
}

help(command, 'Script description', {
  options: {
    yay: 'print yay'
  },
  params: ['name', 'surname']
})

cli(command)
```

```sh
$ ./yourScript.js --help
Usage: yourScript.js [options] [name surname]

Script description

Options:

  --yay       print yay
```

## Add commands

```js
const { cli, help } = require('@pawelgalazka/cli')

help(cmd1, 'Description of first command')

function cmd1(options) {
  console.log('First command')
}

help(cmd2, 'Description of second command')

function cmd2(options) {
  console.log('Second command')
}

help(defaultCmd, 'Description of default command')
function defaultCmd(options) {
  console.log('Default command')
}

cli({
  cmd1,
  cmd2,
  default: defaultCmd
})
```

```sh
$ ./yourScript.js cmd1
First command
$ ./yourScript.js
Default command
```

Mutlicommand version of cli can as well accept `options` and params which
will be passed to proper function. `--help` generation is handled too.

## Add namespaces

To better organise commands, it is possible to group them in namespaces:

```js
const test = {
  unit (options) {
    console.log('Doing unit testing!')
  }

  e2e (options) {
    console.log('Doing e2e testing!')
  }
}

cli({
  test
})
```

```sh
$ ./yourScript.js test:unit
Doing unit testing!
```

Because namespace is just an object with functions, namespace 
can be created also from a module:

`./commands/test.js`:
```javascript
function unit () {
  console.log('Doing unit testing!')
}

function e2e () {
  console.log('Doing e2e testing!')
}

module.exports = {
  unit,
  integration
}
```

`./yourScript.js`
```js
const test = require('./commands/test')

cli({
  test
})
```

```bash
$ ./yourScript.js test:unit
Doing unit testing!
```

## Add middleware

You can customise behaviour of `cli` framework by middleware system. `cli`
itself is build on chain of middlewares.

To add custom middleware:

```js
#!/usr/bin/env node
const { cli, useMiddlewares } = require('@pawelgalazka/cli')

const customMiddleware = next => ({ 
    options, 
    params,
    command,
    definition, 
    namespace
  }) => {

  const nextParams = params.map(param => param.toUpperCase())
  // Run next middleware
  next({ options, params: nextParams, command, definition, namespace })
}

cli((options, name = '', surname = '') => {
  console.log(`Hello ${name} ${surname}!`)
}, useMiddlewares([customMiddleware]))
```

```sh
$ ./yourScript.js Pawel Galazka
Hello PAWEL GALAZKA!
```

What `useMiddlewares` does, it takes your middleware and puts it within the chain
with default middlewares, which looks like this:

```js
[
    errorsHandler(logger),
    argsParser(argv),
    commandFinder,
    helper(logger, argv),
    validator,
    rawArgsParser(argv),
    ...middlewares, // here goes your middlewares
    commandCaller
]
```

So custom middlewares gets called right before calling command function. You
can totally customise the chain by not using `useMiddlewares`. You can provide an array
of middlewares directly to `cli` as a second argument, instead of `useMiddlewares` call.
By this default chain of middlewares will get overwritten.

## Use TypeScript

`cli` has support for `TypeScript`. `TS` types are included within the
library, so you can write your scripts fully in `TypeScript` with usage
of `ts-node`:

```sh
$ npm install ts-node --save-dev
```

`yourScript.ts`:
```ts
#!/usr/bin/env ts-node
import { cli } from '@pawelgalazka/cli'

cli((options, name = '', surname = '') => {
  console.log(`Hello ${name} ${surname}!`)
})
```

---
_Source: https://npm.io/package/@pawelgalazka/cli · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
