CLI lite parser for Node and Deno
CliteParser generate CLI from a class (or plain object), each method generate a βcommandβ, each field generate an βoptionβ. example-lite.ts example :
#!/usr/bin/env -S deno run
import { cliteRun } from "jsr:@jersou/clite@0.5.0";
// or after "deno add @jersou/clite" : import { cliteRun } from "@jersou/clite";
// or for Node usage, after "npx jsr add @jersou/clite" (same import from "@jersou/clite")
class Tool {
retry = 2;
webUrl = "none"; // fields are converted to kebab case as global options
no_color; // β --no-color
main() {
console.log("main command", this);
}
up() {
console.log("up command", this);
}
down(force, timeout) {
console.log("down command", { force, timeout }, this);
}
}
cliteRun(new Tool());Run the commands with options and arguments
# βββββββββββββ options βββββββββββββ β command β β cmd args β
$ ./example-lite-lite.ts --retry=4 --web-url=tttt --no-color down true 14
down command { force: "true", timeout: "14" } Tool { retry: "4", webUrl: "tttt", no_color: true }
$ ./example-lite-lite.ts down true 14
down command { force: "true", timeout: "14" } Tool { retry: 2, webUrl: "none", no_color: undefined }
$ ./example-lite-lite.ts --retry=4 --web-url=tttt --no-color
main command Tool { retry: "4", webUrl: "tttt", no_color: true }
$ deno https://raw.githubusercontent.com/jersou/clite-parser/refs/heads/main/examples/example-lite-lite.ts --retry=4 --web-url=tttt --no-color down true 14
down command { force: "true", timeout: "14" } Tool { retry: "4", webUrl: "tttt", no_color: true }The help is generated automatically:

Help description
The decorator @help can also be used, see the next section.
Optional fields _<filed or method name>_help or _<filed or method name>_desc
are displayed as description in the help (_desc is deprecated) :
#!/usr/bin/env -S deno run -A
import { cliteRun } from "jsr:@jersou/clite@0.5.0";
class Tool {
_help = "This tool is a little example of CliteParser"; // optional description
retry = 2;
webUrl = "none"; // fields are converted to kebab case as global options
no_color?: string | boolean; // β --no-color
_no_color_help = "skip colorize"; // optional description for "no_color" field
_up_help = "create and start"; // optional description for "up" command
main() {
console.log("main command", this);
}
up() {
console.log("up command", this);
}
down(force: boolean, timeout: number) {
console.log("down command", { force, timeout }, this);
}
}
if (import.meta.main) { // if the file is imported, do not execute this block
cliteRun(new Tool());
}
Help description with the @help decorator
import { cliteRun, help } from "jsr:@jersou/clite@0.5.0";
@help("This tool is a little example of CliteParser")
class Tool {
retry = 2;
webUrl = "none"; // fields are converted to kebab case as global options
@help("skip colorize") // optional description for "no_color" field
no_color?: string | boolean; // β --no-color
main() {
console.log("main command", this);
}
@help("create and start") // optional description for "up" command
up() {
console.log("up command", this);
}
down(force: boolean, timeout: number) {
console.log("down command", { force, timeout }, this);
}
}
cliteRun(new Tool());Default command
- If there is only one method/command => this method is the default
- If the main method exist => main is the default
- else => no default method
$ ./example-lite.ts
main command Tool { retry: 2, webUrl: "none", no_color: undefined }Ignore _* methods and fields (in the help)
Fields and methods that start with β_β are ignored.
_privateData = 12;
_privmethod() {
console.log("this method is not visible in the help (starts with '_')");
}Note: this βprivateβ method can be run by the CLI, itβs useful during the development.
Note2: js private fields #* are also ignored :
#privateData = 12;
#privmethod() {
console.log("this method is not visible in the help (starts with '#')");
}Plain Object
A plain JS Object can be used :
import { cliteRun } from "jsr:@jersou/clite@0.5.0";
cliteRun({
retry: 2,
main() {
console.log("main command", this);
},
_up_help: "create and start the services",
up(svc: string, timeout = 10) {
console.log("up command", { svc, timeout, retry: this.retry });
},
down(svc: string) {
console.log("down command", { svc, retry: this.retry });
},
});$ ./plain_object_lite.ts --retry=77 up foo 123
up command { svc: "foo", timeout: "123", retry: "77" }
$ /plain_object_lite.ts --help
Usage: <Object file> [Options] [command [command args]]
Commands:
main (default)
up <svc> <timeout> create and start the services
down <svc>
Options:
--retry=<RETRY> (default "2")
--help Show this helpBoolean options
$ ./example-lite.ts
main command Tool { retry: 2, webUrl: "none", no_color: undefined }
$ ./example-lite.ts --no-color
main command Tool { retry: 2, webUrl: "none", no_color: true }
$ ./example-lite.ts --no-color=false
main command Tool { retry: 2, webUrl: "none", no_color: "false" }
$ ./example-lite.ts --no-color=true
main command Tool { retry: 2, webUrl: "none", no_color: "true" }Warning
All options and command arguments are strings ! There is no boolean/number/β¦ conversion !
CliteRunConfig
cliteRun(new Tool(), < optional CliteRunConfig > )
type CliteRunConfig = {
args?: string[]; // default : Deno.args or process.argv.slice(2)
dontPrintResult?: boolean; // default false : false, print the command return
noCommand?: boolean; // no default command : do not run "main" methode if no arg
printHelpOnError?: boolean; // print the help if an error is thrown and then re-throw the error
mainFile?: string; // allows to change the name of the file in the help, instead of the default <{Class name} file>
meta?: ImportMeta; // import.meta to use : don't run if the file is imported, and use import.meta.url in the help
};Return value
If the method run by cliteRun return a value != undefined, it will be print in
stdout.
This behavior can be disabled with the config :
cliteRun(new Tool(), { dontPrintResult: true })
noCommand
cliteRun(new Tool(), { noCommand: true }); β ./example-no-command.ts ---help
give :
This tool is a "no-command" example of CliteParser usage
Usage: <Tool file> [Options] [args]
Options:
--retry=<RETRY> (default "2")
--web-url=<WEB_URL> web URL ... (default "none")
--no-color=<NO_COLOR> skip colorize
--help Show this helpprintHelpOnError
Print the help if an error is thrown and then re-throw the error:
import { cliteRun } from "jsr:@jersou/clite@0.5.0";
export class Tool {
throw = "true";
main() {
if (this.throw === "true") {
throw new Error("add --throw=false option !");
}
console.log("OK !");
}
}
cliteRun(new Tool(), { printHelpOnError: true });To print help on specific error without printHelpOnError=true, use
{ cause: { clite: true } } :
import { cliteRun } from "jsr:@jersou/clite@0.5.0";
export class Tool {
noThrow = false;
main() {
if (!this.noThrow) {
throw new Error("add --no-throw option !", { cause: { clite: true } });
}
console.log("OK !");
}
}
cliteRun(new Tool());mainFile
Allows to change the name of the file in the help, instead of the default for
example <Tool file>.
cliteRun(new Tool(), { mainFile: "my-tool" });β¦will change the usage line in the help :
Usage: my-tool [Options] [command [command args]]meta
Use meta to avoid the import.meta.main check :
if (import.meta.main) { // if the file is imported, do not execute this block
cliteRun(new Tool());
}is equivalent to :
cliteRun(new Tool(), { meta: import.meta });The basename of import.meta.url will be used in the generated help, as βmainFileβ.
This feature does not work with NodeJS (no import.meta.main).
Node support : npx jsr add @jersou/clite
Run npx jsr add @jersou/clite and then, import with
import { cliteRun } from "@jersou/clite"; :
import { cliteRun } from "@jersou/clite"; // after "npx jsr add @jersou/clite"
class Tool { ... }
cliteRun(new Tool());See node usage examples :