Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

👁‍🗨 Strongly typed CLI development for Node.js

License

NotificationsYou must be signed in to change notification settings

privatenumber/cleye

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cleye

The intuitive command-line interface (CLI) development tool.

Features

  • Minimal API surface
  • Powerful flag parsing
  • Strongly typed parameters and flags
  • Command support
  • Help documentation generation (customizable too!)

Try it out online


Already a sponsor? Join the discussion in theDevelopment repo!

Install

npm i cleye

About

Cleye makes it very easy to develop command-line scripts in Node.js. It handles argv parsing to give you strongly typed parameters + flags and generates--help documentation based on the provided information.

Here's an example script that simply logs:Good morning/evening <name>!:

greet.js:

import{cli}from'cleye'// Parse argvconstargv=cli({name:'greet.js',// Define parametersparameters:['<first name>',// First name is required'[last name]'// Last name is optional],// Define flags/optionsflags:{// Parses `--time` as a stringtime:{type:String,description:'Time of day to greet (morning or evening)',default:'morning'}}})constname=[argv._.firstName,argv._.lastName].filter(Boolean).join(' ')if(argv.flags.time==='morning'){console.log(`Good morning${name}!`)}else{console.log(`Good evening${name}!`)}

🛠 In development, type hints are provided on parsed flags and parameters:



Type hints for Cleye's output are very verbose and readable

📖 Generated help documentation can be viewed with the--help flag:

$ node greet.js --helpgreet.jsUsage:  greet.js [flags...]<first name> [last name]Flags:  -h, --help                 Showhelp      --time<string>        Time of day to greet (morning or evening) (default:"morning")

✅ Run the script to see it in action:

$ node greet.js John Doe --time eveningGood evening John Doe!

Examples

Want to dive right into some code? Check out some of these examples:

Usage

Arguments

Arguments are values passed into the script that are not associated with any flags/options.

For example, in the following command, the first argument isfile-a.txt and the second isfile-b.txt:

$ my-script file-a.txt file-b.txt

Arguments can be accessed from the_ array-property of the returned object.

Example:

constargv=cli({/* ... */})// $ my-script file-a.txt file-b.txtargv._// => ["file-a.txt", "file-b.txt"] (string[])

Parameters

Parameters (akapositional arguments) are the names that map against argument values. Think of parameters as variable names and arguments as values associated with the variables.

Parameters can be defined in theparameters array-property to make specific arguments accessible by name. This is useful for writing more readable code, enforcing validation, and generating help documentation.

Parameters are defined in the following formats:

  • Required parameters are indicated by angle brackets (eg.<parameter name>).
  • Optional parameters are indicated by square brackets (eg.[parameter name]).
  • Spread parameters are indicated by... suffix (eg.<parameter name...> or[parameter name...]).

Note, required parameters cannot come after optional parameters, and spread parameters must be last.

Parameters can be accessed in camelCase on the_ property of the returned object.

Example:

constargv=cli({parameters:['<required parameter>','[optional parameter]','[optional spread...]']})// $ my-script a b c dargv._.requiredParameter// => "a" (string)argv._.optionalParameter// => "b" (string | undefined)argv._.optionalSpread// => ["c", "d"] (string[])

End-of-flags

End-of-flags (--) (akaend-of-options) allows users to pass in a subset of arguments. This is useful for passing in arguments that should be parsed separately from the rest of the arguments or passing in arguments that look like flags.

An example of this isnpm run:

$ npm run<script> --<script arguments>

The-- indicates that all arguments afterwards should be passed into thescript rather thannpm.

All end-of-flag arguments will be accessible fromargv._['--'].

Additionally, you can specify-- in theparameters array to parse end-of-flags arguments.

Example:

constargv=cli({name:'npm-run',parameters:['<script>','--','[arguments...]']})// $ npm-run echo -- hello worldargv._.script// => "echo" (string)argv._.arguments// => ["hello", "world] (string[])

Flags

Flags (aka Options) are key-value pairs passed into the script in the format--flag-name <value>.

For example, in the following command,--file-a has valuedata.json and--file-b has valuefile.txt:

$ my-script --file-a data.json --file-b=file.txt

Parsing features

Cleye's flag parsing is powered bytype-flag and comes with many features:

  • Array & Custom types
  • Flag delimiters:--flag value,--flag=value,--flag:value, and--flag.value
  • Combined aliases:-abcd 2-a -b -c -d 2
  • End of flags: Pass in-- to end flag parsing
  • Unknown flags: Unexpected flags stored inunknownFlags

Read thetype-flag docs to learn more.

Defining flags

Flags can be specified in theflag object-property, where the key is the flag name, and the value is a flag type function or an object that describes the flag.

The flag name is recommended to be in camelCase as it will be interpreted to parse kebab-case equivalents.

The flag type function can be any function that accepts a string and returns the parsed value. Default JavaScript constructors should cover most use-cases:String,Number,Boolean, etc.

The flag description object can be used to store additional information about the flag, such asalias,default, anddescription. To accept multiple values for a flag, wrap the type function in an array.

All of the provided information will be used to generate better help documentation.

Example:

constargv=cli({flags:{someBoolean:Boolean,someString:{type:String,description:'Some string flag',default:'n/a'},someNumber:{// Wrap the type function in an array to allow multiple valuestype:[Number],alias:'n',description:'Array of numbers. (eg. -n 1 -n 2 -n 3)'}}})// $ my-script --some-boolean --some-string hello --some-number 1 -n 2argv.flags.someBoolean// => true (boolean | undefined)argv.flags.someString// => "hello" (string)argv.flags.someNumber// => [1, 2] (number[])

Custom flag types & validation

Custom flag types can be created to validate flags and narrow types. Simply create a new function that accepts a string and returns the parsed value.

Here's an example with a customSize type that narrows the flag type to"small" | "medium" | "large":

constpossibleSizes=['small','medium','large']asconsttypeSizes=typeofpossibleSizes[number]// => "small" | "medium" | "large"// Custom type functionfunctionSize(size:Sizes){if(!possibleSizes.includes(size)){thrownewError(`Invalid size: "${size}"`)}returnsize}constargv=cli({flags:{size:{type:Size,description:'Size of the pizza (small, medium, large)'}}})// $ my-script --size largeargv.flags.size// => "large" ("small" | "medium" | "large")

Default flags

By default,Cleye will try to handle the--help, -h and--version flags.

Help flag

Handling--help, -h is enabled by default.

To disable it, sethelp tofalse. The help documentation can still be manually displayed by calling.showHelp(helpOptions) on the returned object.

Version flag

To enable handling--version, specify theversion property.

cli({version:'1.2.3'})
$ my-script --version1.2.3

The version is also shown in the help documentation. To opt out of handling--version while still showing the version in--help, pass the version intohelp.version.

Commands

Commands allow organizing multiple "scripts" into a single script. An example of this is thenpm install command, which is essentially an "install" script inside the "npm" script, adjacent to other commands likenpm run.

Defining commands

A command can be created by importing thecommand function and initializing it with a name. The rest of the options are the same as thecli function.

Pass the created command intocli option'scommands array-property to register it:

npm.js

import{cli,command}from'cleye'constargv=cli({name:'npm',version:'1.2.3',commands:[command({// Command namename:'install',parameters:['<package name>'],flags:{noSave:Boolean,saveDev:Boolean}})]})// $ npm install lodashargv.command// => "install" (string)argv._.packageName// => "lodash" (string)

Depending on the command given, the resulting type can be narrowed:

Command callback

When a CLI app has many commands, it's recommended to organize each command in its own file. With this structure, parsed output handling for each command is better placed where they are respectively defined rather than the singlecli output point. This can be done by passing a callback function into thecommand function (callbacks are supported in thecli function too).

Example:

install-command.js (install command using callback)

import{command}from'cleye'exportconstinstallCommand=command({// Command namename:'install',parameters:['<package name>'],flags:{noSave:Boolean,saveDev:Boolean}},(argv)=>{// $ npm install lodashargv._.packageName// => "lodash" (string)})

npm.js (CLI entry file)

import{installCommand}from'./install-command.js'cli({name:'npm',commands:[installCommand]})

Help documentation

Cleye uses all information provided to generate rich help documentation. The more information you give, the better the docs!

Help customization

The help document can be customized by passing arender(nodes, renderers) => string function tohelp.render.

Thenodes parameter contains an array of nodes that will be used to render the document. Therenderers parameter is an object of functions used to render the document. Each node has propertiestype anddata, wheretype corresponds to a property inrenderers anddata is passed into the render function.

Default renderers can be found in/src/render-help/renderers.ts.

Here's an example that adds an extra sentence at the end and also updates the flags table to use the= operator (--flag <value>--flag=<value>):

cli({// ...,help:{render(nodes,renderers){/* Modify nodes... */// Add some text at end of documentnodes.push('\nCheckout Cleye: https://github.com/privatenumber/cleye')/* Extend renderers... */// Make all flag examples use `=` as the separatorrenderers.flagOperator=()=>'='/* Render nodes and return help */returnrenderers.render(nodes)}}})

Responsive tables

Cleye's "Flags" table in the help document is responsive and wraps cell text content based on the column & terminal width. It also hasbreakpoints to display more vertically-optimized tables for narrower viewports.

This feature is powered byterminal-columns and can be configured via therenderers.table renderer.

Normal widthNarrow width

API

cli(options, callback?, argvs?)

Return type:

typeParsedArgv={// Parsed arguments_:string[]&Parameters// Parsed flagsflags:{[flagName:string]:InferredType}// Unexpected flagsunknownFlags:{[flagName:string]:(string|boolean)[]}// Method to print versionshowVersion:()=>void// Method to print helpshowHelp:(options:HelpOptions)=>void}

Function to parse argvs by declaring parameters and flags.

options

Options object to configurecli.

name

Type:string

Name of the script used in the help documentation.

version

Type:string

Version of the script used in the help documentation.

Passing this in enables auto-handling--version. To provide a version for the documentation without auto-handling--version, pass it intohelp.version.

parameters

Type:string[]

Parameter names to map onto arguments. Also used for validation and help documentation.

Parameters must be defined in the following formats:

FormatDescription
<parameter name>Required parameter
[parameter name]Optional parameter
<parameter name...>Required spread parameter (1 or more)
[parameter name...]Optional spread parameter (0 or more)

Required parameters must be defined before optional parameters, and spread parameters must be defined at the end.

flags

Type: An object that maps the flag name (in camelCase) to a flag type function or an object describing the flag:

PropertyTypeDescription
typeFunctionFlag value parsing function.
aliasstringSingle character alias for the flag.
defaultanyDefault value for the flag.
descriptionstringDescription of the flag shown in--help.
placeholderstringPlaceholder for the flag value shown in--help.
help

Type:false or an object with the following properties.

PropertyTypeDescription
versionstringVersion shown in--help.
descriptionstringDescription shown in--help.
usagestring | string[]Usage code examples shown in--help.
examplesstring | string[]Example code snippets shown in--help.
render(nodes, renderers) => stringFunction to customize the help document.

Handling--help, -h is enabled by default. To disable it, pass infalse.

commands

Type:Command[]

Array ofcommands to register.

ignoreArgv

Type:

typeIgnoreArgvCallback=(type:'known-flag'|'unknown-flag'|'argument',flagOrArgv:string,value:string|undefined,)=>boolean|void

A callback to ignore argv tokens from being parsed.

callback(parsed)

Type:

Optional callback function that is called when the script is invoked without a command.

argvs

Type:string[]

Default:process.argv.slice(2)

The raw parameters array to parse.

command(options, callback?)

options

PropertyTypeDescription
namestringRequired name used to invoke the command.
aliasstring | string[]Aliases used to invoke the command.
parametersstring[]Parameters for the command. Same asparameters.
flagsFlagsFlags for the command. Same asflags.
helpfalse | HelpOptionsHelp options for the command. Same ashelp.

callback(parsed)

Type:

Optional callback function that is called when the command is invoked.

Sponsors


[8]ページ先頭

©2009-2025 Movatter.jp