export interface CLIConfig { // path to config file config_filepath: string, git_client: "gitea" | "github", log_file: string | undefined, // verbose logging verbose: boolean, // doesn't log to stdout/stderr (still logs to file if --log-file) quiet: boolean } export const defaults: CLIConfig = { config_filepath: "config.toml", git_client: "gitea", log_file: undefined, verbose: false, quiet: false } export class EmptyArgumentError extends Error {} export class NoValueExpected extends Error {} export class InvalidValue extends Error {} /** * Searches for first argument from flags options * Valid values don't start with dashes * @example Flag + Valid value * getFlagValue(["--config", "config.toml"], ["--config", "-c"]) * // result: "config.toml" * @example Flag + No value * getFlagValue(["-c", "--verbose"], ["--config", "-c"]) * // result: null * @example No Flag * getFlagValue(["config.toml"], ["--config", "-c"]) * // result: undefined * * @param args An array of all command-line arguments * @param flags An array of flag strings to search for * @return {string}: When a flag is found and has a valid value * @return {null}: When a flag is found but has no valid value * @return {undefined}: When no flag is found in the arguments * */ export function getFlagValue(args: string[], flags: string[]): string | null | undefined { const index = args.findIndex(arg => flags.includes(arg)) if (index == -1) return undefined if (index == args.length - 1) return null const next = args[index + 1]! if (next.startsWith("-")) { return null } return next } /** * Used for when the flag is optional, but a value is required if the flag appears. * @throws EmptyArgumentError when the flag is present but has no value. * @returns string | undefined — string when present with value, undefined when flag not present */ export function optionalStringFlag(args: string[], flags: string[]): string | undefined { const value = getFlagValue(args, flags) if (value === null) { const errorMessage = `${flags.join(", ")} flag requires a value` throw new EmptyArgumentError(errorMessage) } return value } export function optionalStringLiteralFlag