@magic/cli
@magic/cli
declarative cli sanitization and execution for @magic
sanitizes cli flags from aliases to default names rewrites process.argv accordingly provides autogenerated --help output (that can be customized) also handles commands and environment for you
exports a commonjs file that allows to launch mjs files as clis
install
be in a nodejs project
npm i --save-dev @magic/clicaveats
there are some quirks that need some careful consideration when designing a cli api.
depending on your requirements, these caveats may or may not apply.
last argument
if your last argument does not have a corresponding flag, it will still be assigned to the last flag prior to it.
workaround
do not design a cli with a trailing command.
option argument and command name clash
if one of your options gets an argument that is equal to a command, this command will be executed.
workaround
do not name your commands like the possible arguments.
flag arguments can not start with a dash
cli arguments that start with a - will always be treated as flags, not values.
workaround
do not design a cli that accepts arguments that start with a -
those issues might get addressed in the future.
Usage
full api example
#!/usr/bin/env nodeimport cli from '@magic/cli/src/index.mjs''const { argv, env, commands } = cli({commands: [['cmd1', 'cmd1alias'],'cmd2',],options: [['--flag1', '-f1'],['--flag2', '-f2'],],default: {'--default-key': 'default-value',},single: ['--default-key',],required: ['--default-key',],pure: true, // do neither change process.argv nor process.envpureArgv: true, // do not change process.argvpureEnv: true, // do not change process.env})
options / argv
argv mappings will handle options and option aliases
using the cli file above
then, in your terminal / bash
bin.mjs -f1 arg1 arg2 -f2resulting process.argv
process.argv = ['/path/to/bin/node','/path/to/bin.mjs','--flag1''arg1','arg2','--flag2',]
returned javascript object
argv === { '--flag1': ['arg1', arg2], '--flag2': []}commands
cli commands can be handled too.
import cli from '@magic/cli/src/index.mjs'const args = {commands: [['dev', 'development', 'start'],'serve',],}const argv = cli(args)// call./bin.mjs dev serve// results:{cmds: ['dev', 'serve'],commands: ['dev', 'serve'],}
help output
@magic/cli will derive a help text from your configuration.
help itself can be configured to provide better error messages.
simple help message
import cli from '@magic/cli/src/index.mjs'const args = {commands: [['magic', 'm']],options: [['--spell', '-s']],prepend: 'prepend',append: 'append',help: 'custom help text',}const argv = cli(args)// running./bin.mjs// without arguments// help output@magic/cli wrapped cli.custom help textcli commandsmagic - aliases: ["m"]possible command line flags:--spell - aliases: ["-s"]environment switches:dev: set NODE_ENV to development - aliases ["development"]
detailed help message
the help property will accept an object which maps to the args object.
import cli from '@magic/cli/src/index.mjs'const args = {commands: [['magic', 'm']],options: [['--spell', '-s']],prepend: 'prepend',append: 'append',help: {name: 'cli name',text: 'custom help text',commands: {magic: 'magic info help text',},options: {'--spell': 'cast a simple spell',},env: ['dev', 'set environment to development'],},}const argv = cli(args)// running./bin.mjs// without arguments// help outputcli namecustom help textcommands:magic - aliases: ["m"]flags:--spell - aliases: ["-s"]environment switches:dev: set process.NODE_ENV to development - aliases ["development"]
clean
some cli arguments will be expected to return a string instead of a list of arguments.
this can be achieved using the single array
const args = {options: [['--single', '-s']],single: ['--single'],}const res = cli(args)console.log(res)
required
some cli arguments will be required.
this can be achieved using the required array.
if a required field is missing, a error message and the help will be shown.
const args = {options: [['--required', '-r']],required: ['--required'],}const res = cli(args)console.log(res)
config
there are some configuration parameters that can be passed to the cli function
pure
const args = {pure: false, // set to true to prevent changes to process.argv and process.envpureEnv: false, // set to true to prevent changes to process.envpureArgv: false, // set to true to prevent changes to process.argv}cli(args)
prepend/append
process.argv values can be prepended and appended
import cli from '@magic/cli/src/index.mjs'const args = {prepend: ['prepended']append: ['appended']}cli(args)
default
use this to set default process.argv key: value pairs that should be set if they are not
import cli from '@magic/cli/src/index.mjs'const args = {options: [['--default-key'],],default: {'--default-key': 'default-value',},}const argv = cli(args)// returns{argv: {'--default-key': 'default-value',},}
helpers
@magic/cli exports multiple promisified child_process commands.
exec
import cli from '@magic/cli'const execOptions = {// any child_process.exec options}const {err,stderr,stdout} = await cli.exec('cmd --flag Flag', execOptions)
execFile
const execFileOptions = {// any child_process.execFile options}const {err,stderr,stdout,} = await cli.execFile('/path/to/file.x', ['--flag', 'Flag'], execFileOptions)
spawn
const spawnOptions = {// any child_process.spawn options}const spawnedProcess = cli.spawn('program', ['--flag', 'Flag'], spawnOptions)
source
the source for this page is in the docsrc directory and gets built and published to github using @magic/core