@adonisjs/ace
Version:
Commandline apps framework used by AdonisJs
382 lines (381 loc) • 11 kB
TypeScript
import * as ui from '@poppinss/cliui';
import { ParsedOptions } from 'getopts';
import { PromptContract } from '@poppinss/prompts';
import { ApplicationContract, AppEnvironments } from '@ioc:Adonis/Core/Application';
/**
* Settings excepted by the command
*/
export declare type CommandSettings = {
loadApp?: boolean;
stayAlive?: boolean;
environment?: AppEnvironments;
} & {
[key: string]: any;
};
/**
* The types of flags can be defined on a command.
*/
export declare type FlagTypes = 'string' | 'number' | 'boolean' | 'array' | 'numArray';
/**
* The types of arguments can be defined on a command.
*/
export declare type ArgTypes = 'string' | 'spread';
/**
* The shape of command argument
*/
export declare type CommandArg = {
propertyName: string;
name: string;
type: ArgTypes;
required: boolean;
description?: string;
};
/**
* The shape of a command flag
*/
export declare type CommandFlag = {
propertyName: string;
name: string;
type: FlagTypes;
description?: string;
alias?: string;
};
/**
* The handler that handles the global
* flags
*/
export declare type GlobalFlagHandler = (value: any, parsed: ParsedOptions, command?: CommandConstructorContract) => any;
/**
* Shape of grouped commands. Required when displaying
* help
*/
export declare type CommandsGroup = {
group: string;
commands: SerializedCommand[];
}[];
/**
* The shared properties that exists on the command implementation
* as well as it's serialized version
*/
export declare type SerializedCommand = {
args: CommandArg[];
aliases: string[];
settings: CommandSettings;
flags: CommandFlag[];
commandName: string;
description: string;
};
/**
* Command constructor shape with it's static properties
*/
export interface CommandConstructorContract extends SerializedCommand {
new (application: ApplicationContract, kernel: KernelContract, ...args: any[]): CommandContract;
/**
* A boolean to know if the command has been booted or not. We initialize some
* static properties to the class during the boot process.
*/
booted: boolean;
/**
* Boot the command. You won't have to run this method by yourself. Ace will internally
* boot the commands by itself.
*/
boot(): void;
/**
* Add an argument directly on the command without using the decorator
*/
$addArgument(options: Partial<CommandArg>): void;
/**
* Add a flag directly on the command without using the decorator
*/
$addFlag(options: Partial<CommandFlag>): void;
}
/**
* The shape of command class
*/
export interface CommandContract {
parsed?: ParsedOptions;
error?: any;
exitCode?: number;
logger: typeof ui.logger;
prompt: PromptContract;
colors: typeof ui.logger.colors;
ui: typeof ui;
generator: GeneratorContract;
kernel: KernelContract;
/**
* The flag is set to true, when the command is executed as the main command
* from the terminal.
*
* However, set to false when command is executed programmatically.
*/
readonly isMain: boolean;
/**
* The flag is set to true, when the commandline is in interactive mode.
* Can be disabled manually via the kernel
*/
readonly isInteractive: boolean;
onExit(callback: () => Promise<void> | void): this;
exit(): Promise<void>;
exec(): Promise<any>;
handle?(...args: any[]): Promise<any>;
run?(...args: any[]): Promise<any>;
prepare?(...args: any[]): Promise<any>;
completed?(...args: any[]): Promise<any>;
}
/**
* Shape of the serialized command inside the manifest JSON file.
*/
export declare type ManifestCommand = SerializedCommand & {
commandPath: string;
};
/**
* Shape of defined aliases
*/
export declare type Aliases = {
[key: string]: string;
};
/**
* Shape of the manifest JSON file
*/
export declare type ManifestNode = {
commands: {
[command: string]: ManifestCommand;
};
aliases: Aliases;
};
/**
* Manifest loader interface
*/
export interface ManifestLoaderContract {
booted: boolean;
boot(): Promise<void>;
/**
* Returns the base path for a given command. Helps in loading
* the command relative from that path
*/
getCommandBasePath(commandName: string): string | undefined;
/**
* Returns manifest command node. One must load the command
* in order to use it
*/
getCommand(commandName: string): {
basePath: string;
command: ManifestCommand;
} | undefined;
/**
* Find if a command exists or not
*/
hasCommand(commandName: string): boolean;
/**
* Load command from the disk. Make sure to use [[hasCommand]] before
* calling this method
*/
loadCommand(commandName: string): Promise<CommandConstructorContract>;
/**
* Returns an array of manifest commands by concatenating the
* commands and aliases from all the manifest files
*/
getCommands(): {
commands: ManifestCommand[];
aliases: Aliases;
};
}
/**
* Callbacks for different style of hooks
*/
export declare type FindHookCallback = (command: SerializedCommand | null) => Promise<any> | any;
export declare type RunHookCallback = (command: CommandContract) => Promise<any> | any;
/**
* Shape of ace kernel
*/
export interface KernelContract {
/**
* The exit code to be used for exiting the process. One should use
* this to exit the process
*/
exitCode?: number;
/**
* Reference to the process error. It can come from the command, flags
* or any other intermediate code.
*/
error?: Error;
/**
* Reference to the default command. Feel free to overwrite it
*/
defaultCommand: CommandConstructorContract;
/**
* A map of locally registered commands
*/
commands: {
[name: string]: CommandConstructorContract;
};
/**
* Registered command aliases
*/
aliases: Aliases;
/**
* A map of global flags
*/
flags: {
[name: string]: CommandFlag & {
handler: GlobalFlagHandler;
};
};
/**
* Register before hooks
*/
before(action: 'run', callback: RunHookCallback): this;
before(action: 'find', callback: FindHookCallback): this;
before(action: 'run' | 'find', callback: RunHookCallback | FindHookCallback): this;
/**
* Register after hooks
*/
after(action: 'run', callback: RunHookCallback): this;
after(action: 'find', callback: FindHookCallback): this;
after(action: 'run' | 'find', callback: RunHookCallback | FindHookCallback): this;
/**
* Register a command directly via class
*/
register(commands: CommandConstructorContract[]): this;
/**
* Register a global flag
*/
flag(name: string, handler: GlobalFlagHandler, options: Partial<Exclude<CommandFlag, 'name' | 'propertyName'>>): this;
/**
* Register the manifest loader
*/
useManifest(manifestLoacder: ManifestLoaderContract): this;
/**
* Register an on exit callback listener. It should always
* exit the process
*/
onExit(callback: (kernel: this) => void | Promise<void>): this;
/**
* Preload the manifest file
*/
preloadManifest(): void;
/**
* Get command suggestions
*/
getSuggestions(name: string, distance?: number): string[];
/**
* Find a command using the command line `argv`
*/
find(argv: string[]): Promise<CommandConstructorContract | null>;
/**
* Run the default command
*/
runDefaultCommand(): Promise<any>;
/**
* Handle the command line argv to execute commands
*/
handle(args: string[]): Promise<any>;
/**
* Execute a command by its name and args
*/
exec(commandName: string, args: string[]): Promise<CommandContract>;
/**
* Print help for all commands or a given command
*/
printHelp(command?: CommandConstructorContract, commandsToAppend?: ManifestCommand[], aliasesToAppend?: Record<string, string>): void;
/**
* Find if a command is the main command. Main commands are executed
* directly from the terminal
*/
isMain(command: CommandContract): boolean;
/**
* Find if CLI process is interactive.
*/
isInteractive: boolean;
/**
* Toggle isInteractive state
*/
interactive(state: boolean): this;
/**
* Find if console output is mocked
*/
isMockingConsoleOutput: boolean;
/**
* Enforce mocking the console output. Command logs, tables, prompts
* will be mocked
*/
mockConsoleOutput(): this;
/**
* Trigger exit flow
*/
exit(command: CommandContract, error?: any): Promise<void>;
}
/**
* Template generator options
*/
export declare type GeneratorFileOptions = {
pattern?: 'pascalcase' | 'camelcase' | 'snakecase' | 'dashcase';
form?: 'singular' | 'plural';
formIgnoreList?: string[];
suffix?: string;
prefix?: string;
extname?: string;
};
/**
* Shape of the individual generator file
*/
export interface GeneratorFileContract {
state: 'persisted' | 'removed' | 'pending';
/**
* Define path to the stub template. You can also define inline text instead
* of relying on a template file, but do make sure to set `raw=true` inside
* the options when using inline text.
*/
stub(fileOrContents: string, options?: {
raw: boolean;
}): this;
/**
* Instruct to use mustache templating syntax, instead of template literals
*/
useMustache(): this;
/**
* The relative path to the destination directory.
*/
destinationDir(directory: string): this;
/**
* Define a custom application root. Otherwise `process.cwd()` is used.
*/
appRoot(directory: string): this;
/**
* Apply data to the stub
*/
apply(contents: any): this;
/**
* Get file properties as a JSON object
*/
toJSON(): {
filename: string;
filepath: string;
extension: string;
contents: string;
relativepath: string;
state: 'persisted' | 'removed' | 'pending';
};
}
/**
* Shape of the files generator
*/
export interface GeneratorContract {
/**
* Add a new file to the files generator. You can add multiple files
* together and they will be created when `run` is invoked.
*/
addFile(name: string, options?: GeneratorFileOptions): GeneratorFileContract;
/**
* Run the generator and create all files registered using `addFiles`
*/
run(): Promise<GeneratorFileContract[]>;
/**
* Clear the registered files from the generator
*/
clear(): void;
}
/**
* Filter function for filtering files during the `readdir` scan
*/
export declare type CommandsListFilterFn = ((name: string) => boolean) | string[];