An efficient, object centric auto generated command line interface.
Package includes:
- Cli engine, and supporting classes.
- Internal logger with contexts, common timestamp generation and a colors.
- VSCode snippets
- Load and save configuration from/to file.
npm install lamaani/infer
To define a simple cli,
const {Cli} = require('@lamaani/infer')
const cli = new Cli({name: 'my_cli'})
// Add other commands
cli.default(
async ({arg = null, flag = false}) => {
console.info('Recived argument: ' + arg)
console.info('Flag is: ' + flag)
},
{
arg: {
type: 'named',
aliases: ['a'],
},
flag: {
type: 'flag',
},
}
)
if (require.main == module)
cli.parse().catch((err) => {
console.error(err)
process.exit(err.code || 1)
})
With cascading commands,
const Cli = require('@lamaani/infer').Cli
const cli = new Cli({name: 'myapp'})
const myrunner = new MyRunner()
// optional sub menu:
cli.set('run', {}, {description: 'stuff to run'})
// Using a class to define the arguments.
// the command: myapp run class
cli.set('run class', myrunner, {
description: 'Get options from a class',
action: (options) => myrunner.run(options),
})
// Directly define the arguments.
cli.set(
'run special',
{
arg: {
type: 'named',
aliases: ['a'],
},
flag: {
type: 'flag',
},
},
{
description: 'run an anonymous action.',
action: (options) => console.log(JSON.stringify(options, null, 2)),
}
)
if (require.main == module)
cli.parse().catch((err) => {
console.error(err)
process.exit(err.code || 1)
})
Where MyRunner is,
/** @typedef {import('lamaani/infer').CliArgument} CliArgument */
class MyRunner {
constructor() {
// arguments that start with __$
// are cli arguments, and will
// be set to this object when parsed.
/** Yet another argument */
this.arg = 'default value'
/** @type {CliArgument} */
this.__$arg = {
type: 'named',
enviromentVariable: 'IFR_ARG',
default: this.arg,
description: 'Yet another argument',
}
}
run(options) {}
}
To show help,
my_app --help
In infer
, all commands are constructed as sentences, an example for a simple command would be,
myapp run special case positional_1 --flag --arg val positional_2
This above command would be translated to,
command_name='myapp run special case'
command_options={
positional: ['positional_1','positional_2']
named: {
flag: true,
arg: 'val'
}
}
Named arguments or flags are not position dependent, therefore, the following is equivalent to the above,
myapp --flag run special --arg val case positional_1 positional_2
- There are no combined flags, i.e. no
-wWyDt
. - Arguments are parsed only as,
- Single letters:
a
->-a
- Multi letters:
arg
->--arg
- Single letters:
- Positional arguments are only allowed for the final command, otherwise all positional arguments are parsed as commands.
named
- a regular named argument. Any value.--arg, -a
flag
- A named argument, but no value (true if exists, in config you must set the value).--flag, -f
positional
- An argument that follows the command. Will be added to an array.env
- An argument that would not appear in the CLI, but rather is only loaded from the environment variable. (Can be assigned in config)overflow
- Catch all for any argument after the positional arguments. Allows unknown number of input arguments.transfer
- Catch any argument after the symbol--
. This allows separation of command arguments from arguments that need transferring to another command.
Name | description | possible values | default |
---|---|---|---|
type | The argument type | ['named', 'flag', 'positional', 'env', 'overflow', 'transfer'] |
named |
field_name | The name of the field to update on the parent object | [any] | The field name in the object |
match | The name of the argument to match if named or flag |
[any] | the field name, where any non letter or number is replaced with - |
default | the default value. | [any] | [null] |
environmentVariable | The matching environment variable. If exits, will be taken instead of default. The env in nodejs will be updated to match the field value. | [string] | If env then the field_name, otherwise null |
aliases | Array, the possible command aliases | string[] | [] |
description | The argument description. | [string] | null |
parse | Method: (val)=>[any] . Called before any assignment. |
[function] | null |
doNotAssignToParent | If true, dose not assign the argument to its parent. | true /false |
false |
doNotAssignToEnv | If true, dose not assign the argument to the environment variable. | true /false |
false |
canBeStored | If true, allows this argument to be stored to disk (will appear in the configuration file) | true /false |
true |
To add a file configuration manager,
const cli = new (require('infer').Cli)()
const fs = require('fs')
const CliConfigCommand = require('zlib-cli/CliConfigCommand')
new CliConfigCommand(
Cli,
// command to load the configuration as a javascript object.
() => require('./my_config.json'),
// command to save the configuration to file.
(config) => {
fs.writeFileSync('./my_config.json', JSON.stringify(config))
}
)
Then,
# to list
myapp config list
# myapp config get [command with dots] [named/flag]
myapp config get run.special.case arg
$> 48
# myapp config set [command with dots] [named/flag] [val/empty to remove]
myapp config set run.special.case arg 42
const Logger = require('infer').Logger
const logger = new Logger()
const sub_logger = logger.create('sub')
const sub_sub_logger = logger.create('sub-sub')
logger.level = 0
console.log('Normal log')
console.log()
logger.debug('lama')
logger.info('lama')
logger.warn('lama')
logger.error('lama')
logger.fatal('lama')
logger.trace('lama')
console.log()
console.log('With log symbols')
console.log()
logger.debug('lama', '=>')
logger.info('lama', '=>')
logger.warn('lama', '=>')
logger.error('lama', '=>')
logger.fatal('lama', '=>')
logger.trace('lama', '*')
console.log()
console.log('Sub loggers')
console.log()
sub_sub_logger.info('lama-sub-sub')
sub_logger.info('lama-sub')
logger.info('lama-parent')
Are welcome, please post issues or PR's if needed.
Add an issue (or better submit PR) if you need these.
- XCom
- Examples (other than TL;DR)
Copyright ©
Zav Shotan
and other contributors.
It is free software, released under the MIT licence, and may be redistributed under the terms specified in LICENSE
.