Fast, minimalist, pluggable and functional command line parsing. Create CLIs easily. A wrapper package exporting everything from several Yaro packages.
A companion to Hela. Fast, minimalist, pluggable and functional command line parsing. Create CLIs easily. A wrapper package exporting everything from several Yaro packages. Creating CLI programs, easily. Deno support and ESM-only default. Similar to CAC, Yargs, and Sade, because there are different problems and viewpoints.
'https://esm.sh/yaro@6/src/index.js'
).More docs and better help output - soon!
But it's pretty straightforward:
Example
Making a git-like cli:
import { createCli, yaroCommand } from 'yaro';
// node ./examples/git-like.js --help
// `commit` is just an async function
const commit = yaroCommand('commit [...msg]', async (_options, message) => {
console.log('git commit -sS', JSON.stringify(message.flat().join(' ')));
});
// `add` is just an async function
const add = yaroCommand('add [...files]', 'git add files')
.option('-A, --all', 'add all files', true)
.action(async (_options, files) => {
console.log('git add files:', files);
});
// `remoteAdd` is just an async function
const remoteAdd = yaroCommand('remote add [foo] [bar]')
.option('-f, --force', 'some option here')
.option('--dry-run', 'Call without running', false)
.action(async (_options, foo, bar) => {
console.log('adding remote %s -> %s', foo, bar);
});
// git remote rm foo
// git remote del foo
// git remote remove foo
// git rerm foo
const remoteDelete = yaroCommand('remote rm <name>')
.alias('remote del', 'remote remove', 'rerm')
.option('--dry-run', 'Call without running', false)
.action(async (options, name) => {
console.log('git remote rm', name);
if (!options.foo) {
throw new Error('some fake random error, try passing --foo');
}
console.log('okkkk! foo is passed');
});
await createCli({
name: 'git-cli',
version: '3.1.1',
commands: {
add,
remoteAdd,
remoteDelete,
commit,
},
});
We are detecting by default if you pass just one yaroCommand
to the commands
object of
createCli
.
You can try this example with node examples/linter-cli.js foo bar qux
import proc from 'node:process';
import { createCli, isRequiredUtil, yaroCommand } from 'yaro';
// or Deno
// import { yaroCommand } from 'https://esm.sh/yaro@6'
const xaxa = yaroCommand(
'[foo] [...files]',
'Lint and format files with ESLint --fix and Prettier.',
)
.option('--cwd', 'Working directory, defaults to `process.cwd()`.', proc.cwd())
.option('--log', 'Log per changed file', false)
.option('-f, --force', 'Force lint, cleaning the cache.', false)
.option('-c, --config', 'Path to config file.', {
default: 'xaxa.config.js',
required: isRequiredUtil,
})
.option('--workspace-file', 'File path to write workspaces metadata.', {
default: 'hela-workspace.json',
required: isRequiredUtil,
// type: 'string',
// normalize: true,
})
.option('--verbose', 'Print more verbose output.', false)
.action(async (flags, ...args) => {
const files = args[0];
console.log('flags/options', flags);
console.log('files passed', files);
console.log('arguments', args);
// await lint(files, flags);
});
console.log({ xaxa });
// => {
// xaxa: [AsyncFunction: commandAction] {
// isYaroCommand: true,
// cli: {
// settings: [Object],
// usage: '[foo] [...files]',
// meta: [Object],
// aliases: [],
// alias: [Function (anonymous)],
// option: [Function (anonymous)],
// action: [Function (anonymous)],
// name: '___UNNAMED_COMMAND-1',
// args: [Array],
// parts: [Array]
// }
// }
// }
await createCli({
commands: { xaxa },
version: '3.2.1',
name: 'xaxa-cli',
});