New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

cilly

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cilly - npm Package Compare versions

Comparing version 1.0.7 to 1.0.8

6

dist/presentation.js

@@ -37,2 +37,5 @@ "use strict";

}
if (opt.negatable) {
optString += ` (${token_parser_1.getNegatedFlag(opt.name[1])})`;
}
if (optString.length > maxOptionLength) {

@@ -47,5 +50,2 @@ maxOptionLength = optString.length;

optString = padToLength(optString, maxOptionLength + padding);
if (opt.negatable) {
optString += ` (${token_parser_1.getNegatedFlag(opt.name[1])})`;
}
if (opt.description) {

@@ -52,0 +52,0 @@ optString += ` ${opt.description}`;

{
"name": "cilly",
"version": "1.0.7",
"version": "1.0.8",
"description": "The last library you'll ever need for building intuitive, robust and flexible CLI tools with Node.js and TypeScript.",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -20,2 +20,4 @@ # Cilly

- [Hooks](#hooks)
- [onParse()](#onparse)
- [onProcess()](#onprocess)
- [Generating documentation](#generating-documentation)

@@ -31,6 +33,271 @@ - [Custom help handlers](#custom-help-handlers)

# Basic usage
With the file `build.ts`:
```typescript
#!/usr/local/bin/ts-node
import { CliCommand } from 'cilly'
function buildApartment(args, opts, extra) { ... }
function buildHouse(args, opts, extra) {
return `Built a house with ${opts.numRooms} rooms for ${opts.residents.length} people at ${args.address}, ${args.state}!`
}
// Main command, the CLI entrypoint
const cmd = new CliCommand('build')
.withHandler(() => { cmd.help() })
.withDescription('Builds houses or apartments')
.withOptions({
name: ['-r', '--num-rooms'],
defaultValue: 1,
description: 'The number of rooms',
args: [{ name: 'n', required: true }]
})
.withSubCommands(
// Subcommand for building houses
new CliCommand('house', { inheritOpts: true })
.withHandler(buildHouse)
.withDescription('Builds a house')
.withArguments(
{ name: 'address', required: true },
{ name: 'state', required: false }
)
.withOptions(
{
name: ['-re', '--residents'],
required: true,
description: 'The people living in the house ',
args: [{ name: 'residents', variadic: true }]
}
),
// Subcommand for building apartments
new CliCommand('apartment', { inheritOpts: true })
.withHandler(buildApartment)
.withDescription('Builds an apartment')
.withArguments({ name: 'address', required: true })
.withOptions(
{ name: ['-f', '--floor'], required: true, description: 'The floor of the apartment' },
{ name: ['-re', '--residents'], required: true, args: [{ name: 'residents', variadic: true }]},
)
)
const result = await cmd.process(process.argv)
// Input: build house "Code St. 12" "CA" -r=4 --residents "Anders Brams"
// Result: "Built a house with 4 rooms for 1 people at Code St. 12, CA!"
```
Running `build.ts --help` gives:
```
Usage: build [options]
Builds houses or apartments
Options:
-h, --help Display help for command
-r, --n-rooms [n] The number of rooms (default: 1)
Commands:
house <address> [state] [options]
apartment <address> [options]
```
Running `build.ts house --help`:
```
Usage: house <address> [state] [options]
Builds a house
Options:
-h, --help Display help for command
-r, --n-rooms <n> The number of rooms (default: 1)
-re, --residents [...residents] The people living in the house (required)
```
Running `build.ts house "Code St. 12, CA" -r 4 --residents "Anders Brams" "Joe Schmoe" "Jane Dane"` invokes `buildHouse()` with the arguments:
```typescript
args: {
address: 'Code St. 12',
state: 'CA'
},
opts: {
numRooms: 4,
residents: [
"Anders Brams",
"Joe Schmoe",
"Jane Dane"
]
},
extra: []
```
# Documentation
Before delving into the specifics of the package, a definition of the fundamental concepts is in order: **arguments** and **options**.
Arguments are simply values passed directly to a command or an option.
Options are named flags, e.g. `--option` that can also be assigned their own arguments.
## Arguments
Arguments are provided to a command with the `withArguments()` chain method.
The `withArguments()` method takes a list of `Argument` type options:
```typescript
type Argument = {
name: string, // The name of the argument
required?: boolean, // If true, throws an error if it's not provided
variadic?: boolean, // If true, parses a list of of argument values
description?: string, // Description of the argument (not shown in help, but provided in .dump())
defaultValue?: ArgumentValue, // The value of the argument if it's not provided
onParse?: OnParseHook, // Hook to run immediately when the argument is parsed from the command line
onProcess?: OnProcessHook, // Hook to run when all arguments and options have been parsed from the command line
validator?: Validator // Validation function used to validate the parsed value of the argument
}
```
Argument names must be dash-separated, alpabetic strings e.g. `my-house`, `email`, `docker-compose-file`, etc.
After parsing, arguments are accessible through their camelCased names in the `args` argument to the command handler, e.g.:
```typescript
new CliCommand('args-documentation-example')
.withArguments(
{ name: 'my-house' },
{ name: 'email' },
{ name: 'docker-compose-file' }
).withHandler((args, opts, extra) => {
console.log(args.myHouse)
console.log(args.email)
console.log(args.dockerComposeFile)
})
```
### Variadic arguments
To let an argument be parsed as a list of values, mark it as *variadic*:
```typescript
new CliCommand('download')
.withArguments({ name: 'websites', variadic: true })
// Terminal: download https://github.com https://abrams.dk https://npmjs.com
// args.websites = ['https://github.com', 'https://...'] in the command handler
```
Variadic arguments parse values from the command line until either
1. The variadic terminator `--` is parsed
2. An option name is parsed
3. The input stops
So it's perfectly possible to have two variadic arguments, they just need to be terminated:
```typescript
new CliCommand('download')
.withArguments(
{ name: 'websites', variadic: true },
{ name: 'files', variadic: true }
)
// Terminal: download https://github.com -- cilly-cli/cilly.git robots.txt
// args.websites = ['https://github.com', ...]
// args.files = ['cilly-cli/cilly.git', 'robots.txt']
```
## Options
Options are provided to a command with the `withOptions()` chain method.
The `withOptions()` method takes a list of `Option` type arguments:
```typescript
type Option = {
name: [string, string], // The short and long flag for the option
required?: boolean, // If true, throws an error if the option is not provided
negatable?: boolean, // Automatically registers a negating --no-* flag
args?: Argument[], // Parses arguments as the option value instead of a boolean flag
defaultValue?: OptionValue, // The default value of the option if it is not provided
description?: string, // Description of the option (shown in help)
onParse?: OnParseHook, // Hook to run immediately when the option is parsed from the command line
onProcess?: OnProcessHook, // Hook to run when all arguments and options have been parsed from the command line
validator?: Validator // Validation function used to validate the parsed value of the option
}
```
The option's name is provided as an array of two strings; the short and long flag name.
1. Short option names == argument names starting with `-`
2. Long option names == argument names starting with `--`
```typescript
new CliCommand('build')
.withOptions(
{ name: ['-r', '--rooms'] },
{ name: ['-s', '--street-name'] }
)
```
### Option arguments
Options can take arguments just like a command can.
In the command line, options can be assigned in two ways:
1. With `=` assignment, e.g. `build house --rooms=4`
2. With normal assignment, e.g. `build house --rooms 4`
Here's an example of an option with three arguments - in the `help` text, this would be shown as
```
Options:
-r, --residents <owner> [...adults] [...children]
```
```typescript
new CliCommand('build')
.withHandler((args, opts, extra) => {
console.log(opts)
})
.withOptions(
{ name: ['-r', '--residents'], args: [
{ name: 'owner', required: true }
{ name: 'adults', variadic: true, required: false, },
{ name: 'children', variadic: true, required: false }
]}
)
```
The above handler would print the following:
```typescript
{
residents: {
owner: ...,
adults: [...],
children: [...]
}
}
```
If an option only has a single argument, that argument is then collapsed into the option value so it's simpler to access:
```typescript
new CliCommand('build')
.withOptions(
{ name: ['-o', '--owner'], args: [
{ name: 'owner', required: true }
]}
)
```
Parsing the input `build --owner=anders` (or `build --owner anders`) would produce the following `opts` object:
```typescript
{
owner: 'anders'
}
```
### Negating flags
Sometimes, it's useful to allow users to explicitly negate an option flag.
For example, in the [hooks section](#hooks) we cover how hooks can be used to prompt users for option values if they are not provided.
It's good UX to allow the user to explicitly negate the flag when they don't want it so they can avoid being prompted.
To register a negating flag, simply set `negatable: true`:
```typescript
new CliCommand('batman')
.withOptions(
{ name: ['-p', '--parents'], negatable: true, description: 'Name of (living) parents' }
)
```
With this, users can pass `--no-parents` in the command line, which will set `opts.parents` to `false`.
This is also shown in the `help` text:
```
Usage: batman [options]
Options:
-p, --parents (--no-parents) Name of (living) parents
```
## Commands

@@ -41,2 +308,4 @@ ### Subcommands

## Hooks
### onParse()
### onProcess()
## Generating documentation

@@ -43,0 +312,0 @@ ## Custom help handlers

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc