UNPKG

@adonisjs/ace

Version:

Commandline apps framework used by AdonisJs

382 lines (381 loc) 11 kB
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[];