From 4c565e6a36354754ddb5d76bc0295021be191c1f Mon Sep 17 00:00:00 2001 From: Sukairo-02 Date: Sat, 29 Jun 2024 21:26:00 +0300 Subject: [PATCH] Added config option to omit undefined keys from handler options --- package.json | 2 +- src/command-core.ts | 18 ++++++++-- src/help-themes.ts | 82 ++++++++++++++++++++++----------------------- 3 files changed, 57 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index 9c12df0..cb63ab6 100755 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@drizzle-team/brocli", "type": "module", "author": "Drizzle Team", - "version": "0.2.4", + "version": "0.3.0", "description": "Typed CLI command runner", "license": "Apache-2.0", "sideEffects": false, diff --git a/src/command-core.ts b/src/command-core.ts index 39ddbfc..1b2d46c 100755 --- a/src/command-core.ts +++ b/src/command-core.ts @@ -28,6 +28,7 @@ export type BroCliConfig = { argSource?: string[]; help?: HelpHandler; version?: string | Function; + omitKeysOfUndefinedOptions?: boolean; }; export type GenericCommandHandler = (options?: Record | undefined) => any; @@ -406,7 +407,11 @@ const parseArg = ( }; }; -const parseOptions = (command: Command, args: string[]): Record | undefined => { +const parseOptions = ( + command: Command, + args: string[], + omitKeysOfUndefinedOptions?: boolean, +): Record | undefined => { const options = command.options; const optEntries = Object.entries(options ?? {} as Exclude); @@ -436,7 +441,13 @@ const parseOptions = (command: Command, args: string[]): Record { const argSource = config?.argSource ?? process.argv; const version = config?.version; const helpHandler = config?.help ?? defaultTheme; + const omitKeysOfUndefinedOptions = config?.omitKeysOfUndefinedOptions ?? false; const cmds = [...processedCmds, helpCommand(processedCmds, helpHandler)]; let args = argSource.slice(2, argSource.length); @@ -565,7 +577,7 @@ export const rawCli = async (commands: Command[], config?: BroCliConfig) => { if (!command) throw unknownCommand(); args = [...args.slice(0, index), ...args.slice(index + 1, args.length)]; - options = parseOptions(command, args); + options = parseOptions(command, args, omitKeysOfUndefinedOptions); cmd = command; await cmd.handler(options); diff --git a/src/help-themes.ts b/src/help-themes.ts index 9ffb04c..a4ef121 100644 --- a/src/help-themes.ts +++ b/src/help-themes.ts @@ -1,46 +1,46 @@ import type { Command, HelpHandler } from './command-core'; import type { GenericProcessedOptions } from './option-builder'; -// export const defaultTheme: HelpHandler = (calledFor) => { -// if (Array.isArray(calledFor)) { -// const cmds = calledFor.filter((cmd) => !cmd.hidden); - -// const tableCmds = cmds.map((cmd) => ({ -// name: cmd.name, -// aliases: cmd.aliases ? cmd.aliases.join(', ') : '-', -// description: cmd.description ?? '-', -// })); - -// console.log(`Here's the list of all available commands:`); -// console.table(tableCmds); -// console.log( -// 'To read the details about any particular command type: help [commandName] | help --command= | help -c ', -// ); -// } else { -// const options = calledFor.options -// ? Object.values(calledFor.options).filter((opt) => !opt.config?.isHidden).map( -// ({ config: opt }) => ({ -// name: opt.name, -// aliases: opt.aliases.length ? `${opt.aliases.join(', ')}` : '-', -// description: opt.description ?? '-', -// type: opt.type, -// required: opt.isRequired ? '✓' : '✗', -// }), -// ) -// : undefined; - -// console.log( -// `Command: ${calledFor.name}${calledFor.aliases ? ` [${calledFor.aliases.join(', ')}]` : ''}${ -// calledFor.description ? ` - ${calledFor.description}` : '' -// }`, -// ); - -// if (!options?.length) return; - -// console.log('\nOptions:'); -// console.table(options); -// } -// }; +export const defaultTheme: HelpHandler = (calledFor) => { + if (Array.isArray(calledFor)) { + const cmds = calledFor.filter((cmd) => !cmd.hidden); + + const tableCmds = cmds.map((cmd) => ({ + name: cmd.name, + aliases: cmd.aliases ? cmd.aliases.join(', ') : '-', + description: cmd.description ?? '-', + })); + + console.log(`Here's the list of all available commands:`); + console.table(tableCmds); + console.log( + 'To read the details about any particular command type: help [commandName] | help --command= | help -c ', + ); + } else { + const options = calledFor.options + ? Object.values(calledFor.options).filter((opt) => !opt.config?.isHidden).map( + ({ config: opt }) => ({ + name: opt.name, + aliases: opt.aliases.length ? `${opt.aliases.join(', ')}` : '-', + description: opt.description ?? '-', + type: opt.type, + required: opt.isRequired ? '✓' : '✗', + }), + ) + : undefined; + + console.log( + `Command: ${calledFor.name}${calledFor.aliases ? ` [${calledFor.aliases.join(', ')}]` : ''}${ + calledFor.description ? ` - ${calledFor.description}` : '' + }`, + ); + + if (!options?.length) return; + + console.log('\nOptions:'); + console.table(options); + } +}; // Root help const rootHelp = (commands: Command[]) => { @@ -195,7 +195,7 @@ const commandHelp = (command: Command) => { }; // Theme core -export const defaultTheme: HelpHandler = (calledFor) => { +export const defaultThemeWIP: HelpHandler = (calledFor) => { if (Array.isArray(calledFor)) { rootHelp(calledFor); } else {