import commander from "commander"; import * as inquirer from "inquirer"; export namespace ArgumentParser { export type Inquiry = ( command: commander.Command, prompt: (opt?: inquirer.StreamOptions) => inquirer.PromptModule, action: (closure: (options: Partial) => Promise) => Promise, ) => Promise; export interface Prompt { select: ( name: string, ) => ( message: string, ) => (choices: Choice[]) => Promise; boolean: (name: string) => (message: string) => Promise; } export const parse = async ( inquiry: ( command: commander.Command, prompt: Prompt, action: ( closure: (options: Partial) => Promise, ) => Promise, ) => Promise, ): Promise => { // TAKE OPTIONS const action = (closure: (options: Partial) => Promise) => new Promise((resolve, reject) => { commander.program.action(async (options) => { try { resolve(await closure(options)); } catch (exp) { reject(exp); } }); commander.program.parseAsync().catch(reject); }); const select = (name: string) => (message: string) => async (choices: Choice[]): Promise => ( await inquirer.createPromptModule()({ type: "list", name, message, choices, }) )[name]; const boolean = (name: string) => async (message: string) => ( await inquirer.createPromptModule()({ type: "confirm", name, message, }) )[name] as boolean; const output: T | Error = await (async () => { try { return await inquiry( commander.program, { select, boolean }, action, ); } catch (error) { return error as Error; } })(); // RETURNS if (output instanceof Error) throw output; return output; }; }