@adonisjs/ace
Version:
A CLI framework for Node.js
322 lines (321 loc) • 8.54 kB
TypeScript
import type { cliui } from '@poppinss/cliui';
import type { Arguments, Options } from 'yargs-parser';
import type { HookHandler } from '@poppinss/hooks/types';
import type { Kernel } from './kernel.js';
/**
* Parsed output of yargs
*/
export type YargsOutput = Arguments;
/**
* Parsed output from the parser
*/
export type ParsedOutput = YargsOutput & {
nodeArgs: string[];
/**
* Parsed arguments
*/
args: (any | any[])[];
/**
* Left over arguments after parsing flags
* and args
*/
_: Array<string | number>;
/**
* An array of unknown flags that were parsed
*/
unknownFlags: string[];
/**
* List of parsed flags
*/
flags: {
[argName: string]: any;
};
};
/**
* The UI primitives used by commands
*/
export type UIPrimitives = ReturnType<typeof cliui>;
/**
* All loaders must adhere to the LoadersContract
*/
export interface LoadersContract<Command extends AbstractBaseCommand> {
/**
* The method should return an array of commands metadata
*/
getMetaData(): Promise<CommandMetaData[]>;
/**
* The method should return the command instance by command
* name
*/
getCommand(command: CommandMetaData): Promise<Command | null>;
}
/**
* Command executor is used to create a new instance of the command
* and run it.
*/
export interface ExecutorContract<Command extends AbstractBaseCommand> {
/**
* Create a new instance of the command
*/
create(command: Command, parsedOutput: ParsedOutput, kernel: Kernel<Command>): Promise<InstanceType<Command>> | InstanceType<Command>;
/**
* Run the command
*/
run<Instance extends InstanceType<Command>>(command: Instance, kernel: Kernel<Command>): Promise<Instance>;
}
/**
* Parser options accepted by the yargs to process
* flags
*/
export type FlagsParserOptions = {
all: string[];
array?: string[];
boolean?: Options['boolean'];
string?: Options['string'];
number?: Options['boolean'];
default?: Options['default'];
coerce?: Options['coerce'];
alias?: Options['alias'];
count?: Options['count'];
};
/**
* The options accepted by the arguments parser
*/
export type ArgumentsParserOptions = {
type: 'string' | 'spread';
default?: any;
parse?: (value: any) => any;
};
/**
* Options for defining an argument
*/
export type BaseArgument<T> = {
name: string;
argumentName: string;
required?: boolean;
description?: string;
default?: T;
};
/**
* Type for a string argument
*/
export type StringArgument<T> = BaseArgument<T> & {
type: 'string';
/**
* Whether or not to allow empty values. When set to false,
* the validation will fail if the argument is provided
* an empty string
*
* Defaults to false
*/
allowEmptyValue?: boolean;
parse?: (input: T) => T;
};
/**
* Type for a spread argument
*/
export type SpreadArgument<T extends any> = BaseArgument<T> & {
type: 'spread';
/**
* Whether or not to allow empty values. When set to false,
* the validation will fail if the argument is provided
* an empty string
*
* Defaults to false
*/
allowEmptyValue?: boolean;
parse?: (input: T extends any[] ? T : [T]) => T;
};
/**
* A union of known arguments
*/
export type Argument = StringArgument<any> | SpreadArgument<any>;
/**
* Base properties for a flag
*/
export type BaseFlag<T> = {
name: string;
flagName: string;
required?: boolean;
default?: T;
description?: string;
alias?: string | string[];
};
/**
* String flag
*/
export type StringFlag<T> = BaseFlag<T> & {
type: 'string';
/**
* Whether or not to allow empty values. When set to false,
* the validation will fail if the flag is mentioned but
* no value is provided
*
* Defaults to false
*/
allowEmptyValue?: boolean;
parse?: (input: T) => T;
};
/**
* Boolean flag
*/
export type BooleanFlag<T> = BaseFlag<T> & {
type: 'boolean';
/**
* Whether or not to display the negated variant in the
* help output.
*
* Applicable for boolean flags only
*
* Defaults to false
*/
showNegatedVariantInHelp?: boolean;
parse?: (input: T) => T;
};
/**
* Number flag
*/
export type NumberFlag<T> = BaseFlag<T> & {
type: 'number';
parse?: (input: T) => T;
};
/**
* An array of string flag
*/
export type ArrayFlag<T extends any> = BaseFlag<T> & {
type: 'array';
/**
* Whether or not to allow empty values. When set to false,
* the validation will fail if the flag is mentioned but
* no value is provided
*
* Defaults to false
*/
allowEmptyValue?: boolean;
parse?: (input: T) => T;
};
/**
* A union of known flags
*/
export type Flag = StringFlag<any> | BooleanFlag<any> | NumberFlag<any> | ArrayFlag<any>;
/**
* Command metdata required to display command help.
*/
export type CommandMetaData = {
/**
* Help text for the command
*/
help?: string | string[];
/**
* The name of the command
*/
commandName: string;
/**
* The command description to show on the help
* screen
*/
description: string;
/**
* Command namespace. The namespace is extracted
* from the command name
*/
namespace: string | null;
/**
* Command aliases. The same command can be run using
* these aliases as well.
*/
aliases: string[];
/**
* Flags accepted by the command
*/
flags: Omit<Flag, 'parse'>[];
/**
* Args accepted by the command
*/
args: Omit<Argument, 'parse'>[];
/**
* Command configuration options
*/
options: CommandOptions;
} & Record<string, any>;
/**
* Static set of command options
*/
export type CommandOptions = {
/**
* Whether or not to allow for unknown flags. If set to false,
* the command will not run when unknown flags are provided
* through the CLI
*
* Defaults to false
*/
allowUnknownFlags?: boolean;
/**
* When flag set to true, the kernel will not trigger the termination
* process unless the command explicitly calls the terminate method.
*
* Defaults to false
*/
staysAlive?: boolean;
} & Record<string, any>;
/**
* Finding hook handler and data
*/
export type FindingHookArgs = [[string], [string]];
export type FindingHookHandler = HookHandler<FindingHookArgs[0], FindingHookArgs[1]>;
/**
* Found hook handler and data
*/
export type LoadingHookArgs = [[CommandMetaData], [CommandMetaData]];
export type LoadingHookHandler = HookHandler<LoadingHookArgs[0], LoadingHookArgs[1]>;
/**
* Found hook handler and data
*/
export type LoadedHookArgs<Command extends AbstractBaseCommand> = [[Command], [Command]];
export type LoadedHookHandler<Command extends AbstractBaseCommand> = HookHandler<LoadedHookArgs<Command>[0], LoadedHookArgs<Command>[1]>;
/**
* Executing hook handler and data
*/
export type ExecutingHookArgs<Command> = [[Command, boolean], [Command, boolean]];
export type ExecutingHookHandler<Command> = HookHandler<ExecutingHookArgs<Command>[0], ExecutingHookArgs<Command>[1]>;
/**
* Executed hook handler and data
*/
export type ExecutedHookArgs<Command> = ExecutingHookArgs<Command>;
export type ExecutedHookHandler<Command> = ExecutingHookHandler<Command>;
/**
* A listener that listeners for flags when they are mentioned.
*/
export type FlagListener<Command extends AbstractBaseCommand> = (command: Command, kernel: Kernel<Command>, parsedOutput: ParsedOutput) => any | Promise<any>;
/**
* Commands and options list table
*/
export type ListTable = {
columns: {
option: string;
description: string;
}[];
heading: string;
};
/**
* A union of data types allowed for the info key-value pair
*/
export type AllowedInfoValues = number | boolean | string | string[] | number[] | boolean[];
/**
* Abstract command defines the mandatory properties on a
* command class needed by the internals of ace.
*/
export type AbstractBaseCommand = {
commandName: string;
options: CommandOptions;
serialize(): CommandMetaData;
validate(parsedOutput: ParsedOutput): void;
getParserOptions(options?: FlagsParserOptions): {
flagsParserOptions: Required<FlagsParserOptions>;
argumentsParserOptions: ArgumentsParserOptions[];
};
new (...args: any[]): {
hydrate(): void;
exitCode?: number;
};
};