Skip to content

The Grand Feature TODO #8

@nullishamy

Description

@nullishamy

All the TODO/WIP features:

Argument types:

  • Files (opt: normalise, absolute)
  • Dates
  • Relative time (plugged in via an existing parser)
  • Counts
  • Enums / restricted strings
  • Bounding / checking capabilities for all types
  • Decimals
  • BigInts
  • "Rest" type (-- syntax), dumps into a named argument on the result (just a raw string with the rest of the arg string)
  • Min/max on positionals, greedy/lazy behaviour

Parsing

  • Support = in flags --flag=value
  • Utility for hiding the binary name (argv.slice(2))
  • Required / optional commands, minimum required commands
  • Coercion can indicate to the parser to skip this value (see: Default commands)
  • Negated booleans --no-[key] (customisable prefix)
  • Specifying a key multiple times (with it being a multi type) will add to the array
  • Specifying a key multiple times (no multi type) will error
  • Utility for composition of argument types
  • Middlewares

Argument features

  • Environment fallback (with automatic prefixing, respects optionality)
  • Config file fallback (similar format to env, k=v)
  • "Implies", if x is set, so must y (inverse dependency)

Configurable features

  • "Rest" type enable / error
  • = in flags
  • Negated bools
  • Environment fallback
  • Config file fallback
  • Multi key behaviour / array interaction
  • Which fallback commands are enabled OOTB
  • Short flag grouping / error
  • Deprecation is error (per command?)
  • Prefix used for boolean negation (default "no")
  • Wrapping on help (also util for terminal width)

Command features

  • Deprecation (in CommandOpts)
  • Hidden (not shown in help) (opts ^ )
  • "Global" / inherited arguments
  • Default "no-op" command type for the defaults

Builtins

We should have a default implementation of these, with a mechanism to override.

At present, this can be implemented with a custom type which prints information and then exits.
However, this should be cleaner than just process.exit() in the coercer.

We should also have support for a "fallback" command, the command that gets run as a default if no recognised one is passed.

Perhaps these should have their own method?:

parser
	.default('help', <Command>)
	.default('fallback', <Command>)
	.command(['cmd'], <Command>)
  • Help
  • Shell completion
  • Version
  • Default/fallback command
  • Selected locale (for help / errors)

Short flag grouping

  • Complete?

We should support grouping of short flags and the like. This should mean that we treat a "long" short flag (> 1 char) as a single flag if a matching one is found, or as a group of single flags if not. Something lke:

const short = "-abc"
const longShort = flags.get(short)

if (longShort) {
	return longShort
}

const parts = short.split()
const flagsInGroup = []

for (const part of parts) {
	const groupMember = flags.get(part)
	if (!groupMember) {
		// Error, unknown flag
	}
	flagsInGroup.push(groupMember)
}

return flagsInGroup

We should accumulate errors in the group stage so that we can present more useful information to the user.
This accumulation will mean parsing can return ParseError[] instead of ParseError (singular).

Shell completion

  • Complete?

We should support this. Again, pluggable with sane defaults.

Suggest fixes for incorrect arguments

We should offer advice to users about which options are similar to their input. This should be a pluggable system as we do not want the project to have runtime dependencies, and developers may have their own taste / requirements for the system.

We will use a prefix tree internally as the default implementation, but the user can also plug their own in.

We can write tests based on a well known solution and provide examples for such.

Prompting support

  • Complete?
    This should work OOTB already, but we should add tests with something like inquirer.

Outside of Node

  • Platforms integrated
  • Write platforms objects for other platforms
  • Write tests for other platforms
    We should not use node specific tools in the default prelude. Node should be opt in.
    We should make a platform type object that will house all the platform specific details, and patch those in the browser.

Localisation

We should support some sort of localisation, ideally without defaults [in other languages] due to maintenance burden,
but end users can provide their own

Type level testing

We should test our type system logic with something like tsd

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions