c4spar / deno-cliffy Goto Github PK
View Code? Open in Web Editor NEWCommand line framework for deno π¦ Including Commandline-Interfaces, Prompts, CLI-Table, Arguments Parser and more...
Home Page: https://cliffy.io
License: MIT License
Command line framework for deno π¦ Including Commandline-Interfaces, Prompts, CLI-Table, Arguments Parser and more...
Home Page: https://cliffy.io
License: MIT License
await new Command()
.option('--test', 'Test description')
.option('--test2 [val:boolean]', 'Test2 description')
.parse(['-h']);
Atm both flags have an optional booelan value but only --test2
should have an optional value.
--help
should output:
--test - Test description
--test2 [val:boolean] - Test2 description
Using - as a filename to mean stdin.
myCommand --someOptions -
new Command()
.name("myCommand")
.option("--someOptions", "desc")
.option("-", "stdin")
.action((options: Options) => console.log(options.stdin))
// or using a Symbol
.action((options: Options) => console.log(options[cliffy.stdin]))
Like unix commands, such as :
cat -
Use deno fmt
for code formatting as soon as dprint and deno fmt supports a configuration file:
Provide a way to access the actual command in action handlers espacialy for global option's and command's.
Solution 1
Add new parameter (breaking change):
new Command()
.option( '-h, --help', 'Description ...', {
global: true,
action: ( cmd, options, ...args ) => {
// in case the global option was called on a child command,
// {cmd} musst be the child command.
showHelp( cmd );
}
} )
.action( ( cmd, options, ...args ) => {
showHelp( cmd );
} )
Solution 2
Merge cmd and options (if you want to merge the options into another object, you will merge also the command instance):
new Command()
.option( '-h, --help', 'Description ...', {
global: true,
action: ( cmd, ...args ) => {
showHelp( cmd );
}
} )
.action( ( cmd, ...args ) => {
showHelp( cmd );
} )
Solution 3
Bind command to action handler (this binding is ugly):
new Command()
.option( '-h, --help', 'Description ...', {
global: true,
action: function (options, ...args) {
showHelp( this );
}
} )
.action( function ( options, ...args ) {
showHelp( this );
} )
Windows Terminal supports emoji:
deno run https://deno.land/std/examples/welcome.ts
However, cliffy Prompt with emoji prints garbled output instead
import { Input } from "https://deno.land/x/cliffy/prompt/mod.ts";
const name: string = await Input.prompt( {message: `What's your name?`, pointer: 'π¦' } );
deno run --unstable https://gist.githubusercontent.com/prcdpr/a202eabe338fc47bcc5e1c80b987f974/raw/39ac37c59ad0efc8bb7b03b02225e7eaafde5bd7/cliffy-prompt-emoji.ts
Code gist to test can be found here https://gist.github.com/prcdpr/a202eabe338fc47bcc5e1c80b987f974
Add an option for min and max selectable items to GenericList
prompt.
Given an option with both depends
and default
value like so:
await new Command()
.option( '--flag1', 'flag 1' )
.option( '--flag2 <val:string>', 'flag 2', {depends: ['flag1'], default: 'example'} )
.parse( Deno.args );
Cliffy thinks flag2
is always set and complains:
Option --flag2 depends on option: --flag1
whenever flag1
is missing even though flag2
only has its default value set.
https://deno.land/x/cliffy/prompt.ts import url 404
It should be possible to define nested sub commands via namespaces.
await new command()
.command( 'command1 [arg]' )
.description( 'First level sub command' )
.action( console.log )
.command( 'command1.command2 [arg]' )
.description( 'Second level sub command' )
.action( console.log )
.parse();
Add a prompt module which opens the default text editor for editing files or string values.
Options:
Hi @c4spar and thanks for the awesome work you're doing!
I was wondering if it's possible to disable the help
command while keeping the --help
option working. I'm using BaseCommand
, manually registering the --help
option and calling command.help()
in the option handler, but I get
[ERROR:COMMAND] No help command registered.
I'd actually need to achieve the same result with the completions
command, if it can be.
Thanks!
I have an application that needs to capture and handle OS signals (SIGINT), but it seems like inputs and Select has hardcoded logic for control+c, ending with a Deno.exit(0)
. I would like to be able to tell cliffy to not exit immediately, but to give me control to properly clean things up before exiting. I'd be up for making a PR for any solution that is of interest. One idea is to offer a callback option.
Currently the --allow-env
flag is required to execute a command. A command should be executable without this flag.
Add minLength and maxLength to List
prompt.
On invalid validation show error message.
Add minLength and maxLength to Input
prompt.
On invalid validation show error message.
At the moment the parse method returns an object with an options object and an args array.
const { options, args } = await new Command()
.arguments( '<cmd:string> [env:string] [dirs...:string]' )
.parse(Deno.args);
console.log('cmd:', args[0]);
The command should return an args array with named args:
const { options, args } = await new Command()
.arguments( '<cmd:string> [env:string] [dirs...:string]' )
.parse(Deno.args);
console.log('cmd:', args[0]);
console.log('cmd:', args.cmd);
Given the following configuration:
import { Command } from 'https://deno.land/x/[email protected]/command.ts';
await new Command()
.option( '--db <database:string>', 'use given db' )
.command( 'cmd1', new Command()
.option( '--arg1', 'Arg 1' )
.action( ( source: string, destination: string ) => {
console.log( 'cmd1 called' );
} )
)
.command( 'cmd2', new Command()
.option( '--arg2', 'Arg 2' )
.action( ( source: string, destination: string ) => {
console.log( 'cmd2 called' );
} )
)
.parse( Deno.args );
I would expect --db
to become a shared option across the cmd1 and cmd2 subcommands. It seems thatβs not the way cliffy handles this currently.
Instead, passing --db
before the command name aborts with Unknown command: cmd1
, passing it after yields Unknown option: --db
.
Complete code documentation.
Documentation is available on: https://doc.deno.land/https/deno.land/x/cliffy/packages/command/mod.ts
Hidden commands should be ignored in help and completions command.
I'd like to make a command that runs a process in Deno.
Kind of like npm run test -- --grep="pattern"
.
I would then get the args and feed them with Deno.run
to another process.
But I can't determine the options in advance, how can I create such command?
Currently, the completions command supports only zsh completions.
Add also support for bash completions.
The command class and the command action handler should also return the literal arguments array which is return by the parseFlags()
method.
deno run file.ts arg1 arg2 -- --flag1 val arg1
const { args, options, cmd, literal } = await new Command()
// ...
.parse( [ 'arg1', 'arg2', '--', '--flag1', 'val', 'arg1' ] );
console.log( literal ); // <-- [ '--flag1', 'val', 'arg1' ]
Provide also a way to access literal arguments inside a command action handler.
Add a prompt module for credentials input.
*
If enabled, all arguments starting from the first non option argument will be interpreted as raw argument. This makes it possible to pass flags as value to an executable without using --
.
Hello Everyone,
there is an issue with the table package where an Error is thrown if the length of a single word in the cell is longer than maxCellWidth
. In this case fillLength
becomes negative and an error is thrown because .repeat
is called with a negative count value.
deno-cliffy/packages/table/lib/table.ts
Line 215 in 87d1b0f
I assume the solution would be some kind of hard wrap if the word gets longer than maxCellWidth
.
Using cliffy 0.7.0
, when I run any command that shows a help message containing environment variables I get the following error:
error: Uncaught TypeError: Cannot read property 'length' of undefined
if ( details.name.length > 3 ) {
^
at HelpCommand.parseArgsDefinition (https://deno.land/x/[email protected]/packages/command/lib/base-command.ts:780:31)
at HelpCommand.highlight (https://deno.land/x/[email protected]/packages/command/commands/help.ts:214:21)
at https://deno.land/x/[email protected]/packages/command/commands/help.ts:159:26
at Array.map (<anonymous>)
at getEnvVars (https://deno.land/x/[email protected]/packages/command/commands/help.ts:157:25)
at renderHelp (https://deno.land/x/[email protected]/packages/command/commands/help.ts:86:39)
at HelpCommand.getHelp (https://deno.land/x/[email protected]/packages/command/commands/help.ts:198:9)
at HelpCommand.show (https://deno.land/x/[email protected]/packages/command/commands/help.ts:32:45)
at VrCommand.help (https://deno.land/x/[email protected]/packages/command/lib/base-command.ts:1181:31)
at Object.action (https://deno.land/x/[email protected]/packages/command/lib/default-command.ts:22:26)
The env variables are declared as as stated in the documentation:
VAR_NAME=<value:string>
It looks like parseArgsDefinition()
expects the whole <value:string>
type declaration as argument, while envVar.type
only contains string
.
Hey there,
thanks for this pretty amazing module! Unfortunately I encountered this weird bug.
const email = await Input.prompt(
{
message: `What's your email?`
},
);
I cannot type an email containing the letter "c" (the c doesn't display).
Platform: mac
Deno: 1.0.0
deno-cliffy: 0.7.1
In my particular use case I'd need to accept a variable number of cli arguments (including options) unrelated to cliffy after a series of valid args, for example:
mycmd --myoption mysubcmd myarg other args and --options
|
cliffy args <-|-> other args
To do this I've been using a variadic argument in mysubcmd
new Command()
.command('mysubcmd [myarg] [otherArgs...]');
but I didn't take into account that --options
could break it
[ERROR:...] Unknown option --options
Do you have any suggestions on how to accomplish this?
Using --foo
and --foo-a
produces different results when used with -h
.
import { Command } from "https://x.nest.land/[email protected]/packages/command/mod.ts";
new Command()
.option("--foo-a", "foo", { default: true })
.action((_) => {})
.parse(Deno.args);
import { Command } from "https://x.nest.land/[email protected]/packages/command/mod.ts";
new Command()
.option("--foo", "foo", { default: true })
.action((_) => {})
.parse(Deno.args);
Custom types should be not printed in the help output.
Deno can't access imports like this:
import { ... } from 'https://deno.land/[email protected]/fmt/colors.ts';
This results in an error when trying to run a script that uses cliffy:
Download https://deno.land/[email protected]/fmt/colors.ts
error: Import 'https://deno.land/[email protected]/fmt/colors.ts' failed: 403 Forbidden
Local dev environments are not likely to be affected due to caching; however, running scripts on new machines does display this error.
The official Deno docs do not include the "v" in the import. See https://deno.land/[email protected]/fmt/colors.ts
Updating imports to use a version without the "v" prefix allows the import to work:
import { ... } from 'https://deno.land/[email protected]/fmt/colors.ts';
Currently, it's not possible to create options such as --no-check
.
I would like to be able to declare this option because the --check
option doesn't make sense in my case.
import { Command } from "https://x.nest.land/[email protected]/command/mod.ts";
new Command()
.option("--no-check", "desc")
.action(() => {})
.parse();
> deno run -A --unstable foo.ts
[...]
Error: Unknown option: --no-check
Hidden otpions should be ignored in help and completions command.
First of all, this is an awesome project, and I've been enjoying using it!
While implementing an authentication CLI command, I noticed the value of the password that I was pasting in the console was not being captured correctly into the variable.
When pasting into the console, the value pasted is not equal to the value capture by Cliffy Prompt.
// script.ts
import { Secret } from "https://raw.githubusercontent.com/c4spar/deno-cliffy/v0.11.2/prompt.ts";
const password = await Secret.prompt({message:"Password:",hidden:true})
console.log(password)
0123456789abcdefghijklmnopqrstuvwxyz
to your clipboard.deno run --unstable script.ts
0123456789abcdefghijklmnopqrstuvwxyz
08gow
Given the following code derived from your examples:
import { Input } from "https://deno.land/x/cliffy/prompt.ts";
const name: string = await Input.prompt(`What's your name?`);
console.log("Your name is", name);
will come up with three errors:
error: TS2322 [ERROR]: Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
const name: string = await Input.prompt(`What's your name?`);
~~~~
at file:///C:/Users/felix/dev/deno/test.ts:3:7
TS2339 [ERROR]: Property 'setRaw' does not exist on type 'typeof Deno'.
Deno.setRaw( 0, true );
~~~~~~
at https://deno.land/x/cliffy/packages/prompt/lib/read-line.ts:14:10
TS2339 [ERROR]: Property 'setRaw' does not exist on type 'typeof Deno'.
Deno.setRaw( 0, false );
~~~~~~
at https://deno.land/x/cliffy/packages/prompt/lib/read-line.ts:16:10
Found 3 errors.
I used deno 1.0.1 on Windows.
code:
// @ts-nocheck
import { parseFlags, OptionType, InputCLI, Confirm, Select } from './deps.ts';
class OgoneCLI {
public static async init() {
parseFlags(Deno.args, {
flags: [
{
name: 'create',
aliases: ['c', "create"],
type: OptionType.STRING,
}
],
parse: (type, option, argument, value) => {
switch(option.name) {
case 'create':
OgoneCLI.promptCreation(value);
break;
}
return value;
}
});
}
public static async promptCreation(value: string) {
switch(true) {
case value && ['comp', 'component', 'c'].includes(value):
const cssLang: string = await Select.prompt({
messsage: 'CSS pre-processor ?',
options: [
{ name: 'Sass', value: 'sass' },
{ name: 'Denolus', value: 'denolus' },
]
});
console.warn(cssLang);
break;
}
}
}
if (import.meta.main) {
OgoneCLI.init();
}
Hi,
Cliffy prompts look pretty dope but one of the most useful prompts IMO would be the auto-complete prompt (example).
Would you consider adding it?
I tried to port enquirer to Deno (see PR 316) but the discrepancies in the key events APIs make it pretty tough and the maintainer couldn't get a look so I'm stuck. I'm thinking that it may be a better option to have a new strong prompt lib in Deno rather than porting a NodeJS lib with all the complexity it adds (my PR was huge).
Hi!
First, thanks for the work on this library. I'm new to Deno and TypeScript but have found the API for this lib intuitive as it's similar to command suite libs I've used in other languages.
I got a bit stuck when I implemented an action handler though, as I wasn't sure where to find the IFlags
type. I got to it eventually from looking through the codebase but it might be helpful to mention where to find or include that dependency in the examples and docs.
Options:
Change return type of GenericPrompt.prompt()
method from Promise<T | undefined>
to Promise<T>
.
Command
class and provide an easy way to register them manually.BaseCommand
(is not needed if we regiser no default options and comands)HelpCommand
to a separate help()
method to decouple --help
option and HelpCommand
.Solution 1:
await new Command()
// available in all sub commands (can be overridden in child command's)
.option( '-h, --help', 'Description ...', { global: true, action: help() } )
// or implement Option class
.option( '-h, --help', new HelpOption().global() )
// available in all sub commands (can be overridden in child command's)
.command( 'help', new HelpCommand().global() )
// available only in main command
.command( 'completions', new CompletionsCommand() )
.parse();
Solution 2:
Implement .use()
method:
await new Command()
// register help option & command with defaults...
.use( help() )
// ... or with custom flag names.
.use( help( {
global: true,
flags: '-h, --help',
command: 'help'
} ) )
// register completions command with default's.
.use( completions() )
.parse();
function help( opts? ) {
return ( cmd: Command ) => {
cmd.option( '-h, --help', 'Help description.', { global: true, action: help() } )
.command( 'help', new HelpCommand().global() );
};
}
function completions( opts? ) {
return ( cmd: Command ) => {
cmd.command( 'completions', new CompletionsCommand() )
};
}
The return type of the .parse()
method from the Command
class should be generic.
interface MyArgs {
[0]: string;
[1]?: number;
arg1: string;
arg2?: number;
}
interface MyOptions {
opt1: string;
opt2?: number;
}
const {options, args} = new Command<MyArgs, MyOptions>()
.arguments('<arg1:string> [arg2:number]')
.option('--opt1 <val:string>', 'Option 1', {required: true})
.option('--opt2 <val:number>', 'Option 2')
.parse(Deno.args);
// and / or
const {options, args} = new Command()
.arguments('<arg1:string> [arg2:number]')
.option('--opt1 <val:string>', 'Option 1', {required: true})
.option('--opt2 <val:number>', 'Option 2')
.parse<MyArgs, MyOptions>(Deno.args);
I'm currently getting a 404 when trying to retrieve v0.12.1 from deno land. However, v0.12.0 is available. Did the Deno webhook fail while notifying Deno of the new tag?
Available: https://deno.land/x/[email protected]
Not Found: https://deno.land/x/[email protected]
> deno run https://deno.land/x/[email protected]/command.ts
Download https://deno.land/x/[email protected]/command.ts
error: Import 'https://deno.land/x/[email protected]/command.ts' failed: 404 Not Found
Context: I would to be able to do:
--opt
and
--opt value
with
.option("--opt <value:string>", "desc")
Why then ?
Because I need to have a default value when --opt
is used but this default value cannot be known in advance.
Perhaps in the form of:
.option("--opt <value:string>", "desc", { allowEmpty: true })
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.