interface FlagT { default?: T, aliases?: string[], /** Shorthands, AKA only work with singular minus signs like -f; Multiple characters are allowed; Will not count as a full (like --f) flag alias; */ shorthands?: string|string[], type?: Z /** If enabled, sends/throws an error if the flag is present but no value is set, either with an assigned value (ie: ["--flag=value"]), or natural value (ie: ["--flag", "value"]) @default false */ requiredValue?: boolean /** If disabled, only accepts assigned values (ie: ["--flag=value"]) for flag values (ie: the would-have-been value will instead become input) @default true*/ acceptsNaturalValue?: boolean }; export type FlagTypes = "string" | "boolean" | "bigint" | "number" | "any"; export type FlagAny = FlagT | FlagT | FlagT | FlagT | FlagT export interface FlagsI { [key: readonly string]: FlagAny } export type DefaultParserOptsType = ParserOpts /** This object will be modified by parser */ export interface ParserOpts { flags?: Flags, /** Wether to allow versions of `-flag` as a singular and valid flag. @default false */ allowSingularDashLongFlags?: boolean = false /** Wether to allow flags not denoted in the flag property. @default true */ allowUnknownFlags?: boolean = true /** Wether to lowercase all flags key. Incompatible with camelCaseFlags option. @default true */ lowerCaseFlags?: boolean = true /** Wether to automatically resolve flag number values into numbers and boolean flags into booleans if flag type is explicitly set. @default true */ resolveFlagValueTypes?: boolean = true /** * Setting according flag to the inversed provided boolean value (defaulting to false if none is provided) with their '--no' variants unless a defined flag exists with that * name already; Additional informations in sub-properties. * @default * ```js * = { enabled: true, allowUnspacedNegatedFlags: true, shorthandNegation: true } * ``` */ automaticBooleanFlagNegation?: { /** Wether to automatically resolve boolean flags that are negated to the inverse boolean value. Requires resolveFlagValueTypes. @default true */ enabled?: boolean; /** Allows flags negated without a space (eg: "--noflag") to still be automatically resolved @default true */ allowUnspacedNegatedFlags?: boolean; /** Wether to negate shorthand flags with if an n is present before hand (eg: '-nf'). Providing a shorthand of 'n' will disable this feature. @default true */ shorthandNegation?: boolean; } /** Enable this option to silence any warnings about potentially unexpected behavior (eg: a flag's unset type being set to the default). @default false */ silenceWarnings?: boolean; /** Override to change how warnings are emitted @default console.warn */ warningLogger?(log: string): void; /** Default type for either unknown flags or flags without an explicit type being set @default "any" */ defaultFlagType?: FlagTypes; /** * Behavior when input does not follow the provided flags constraints (eg: flag assigned value (--flag=value) not being the correct type). * * Setting it to 'ignore' or 'log' is highly not recommended and will lead to undefined behavior. (eg: flags not meeting the configuration not being present * in the final returned object) * Setting this to 'ignore' will give the same undefined behavior as setting it to 'log', but without emitting any logs to `warningLogger`. * @default 'throw' */ behaviorOnInputError?: 'throw' | 'log' | 'log&exit' | 'ignore'; /** Wether to allow default flag values set to null being valid @default true */ allowNullDefaultFlagValues?: boolean; /** * If enabled, makes all input values lowercase after flag processing. It does not apply to 'values' that get naturally assigned to flags * (eg: `['--flag', 'VALUE']` -> `{ 'flag': 'VALUE' }`) * @default false */ lowerCaseInputValues?: boolean /** * If enabled, makes all string flag values lowercase. It applies to any string flag values, either naturally assigned (eg: `['--flag', 'VALUE']` -> `{ flags: { 'flag': 'value' } }`) * or directly assigned (eg: `['--flag=VALUE']` -> `{ flags: { 'flag': 'value' } }`) * @default false */ lowerCaseFlagValues?: boolean /** * If disabled, does not acknowledge or consume backslashes, making flag assignments (=) and designated flag characters (--) inescapable within flags * * * #### It needs to be noted that backslashes are only ever handled/consumed in flags AND if they impact special flag characters (ie: minus signs (-) and equal signs (=)); * The only exception is a backslash escaping a flag character (-) at the very beginning of a value (ie: '\--not_a_flag'), which will be consumed with this option * enabled but not counted as a flag (ie: `['\--not_a_flag']` -> `{ input: ['--not_a_flag'], flags: {} }`), and not consumed but also not counted as a flag with it * disabled (ie: `['\--not_a_flag']` -> `{ input: ['\--not_a_flag'], flags: {} }`). * @default true */ handleBackslashesForSpecialFlagChars?: boolean /** If enabled, automatically adds shorthands as valid flag aliases (eg: -f &-> --f) @default true */ addFlagShorthandsAsAliases?: boolean /** * If a function is provided, stops parsing when that function returns a truthy value. * * Adds any following args (including the matching arg) into the returned unparsed array. * * **Overrides shouldStopParsingStr** * @param arg - to-be parsed arg * @param index - index of the arg within the argv array * @param argv - argv array * @param argMeta - meta object containing informations about the arg (*properties subject to change) * @param input - input array, containing the currently parsed input values * @default null */ shouldStopParsingFunc?(arg: string, index: number, argv: string[], argMeta: argMeta, input: string[]): boolean /** * If a string is provided, stops parsing if the to-be parsed arg matches the string provided exactly. * The to-be parsed arg is not yet lowercased by any lowerCase* options, it is therefore recommended to use shouldStopParsingFunc instead if that is a requirement. * * Adds any following args (including the matching arg) into the returned unparsed array. * * **Overridden by shouldStopParsingFunc** * @default null */ shouldStopParsingStr?: null | string /** * If a function is provided, will only parse the provided arg if the provided function returns a truthy value. * * Runs after shouldStopParsingFunc * * Does not add filtered out args into the returned unparsed array. * * @param arg - to-be parsed arg * @param index - index of the arg within the argv array * @param argv - argv array * @param argMeta - meta object containing informations about the arg (*properties subject to change) * @param input - input array, containing the currently parsed input values * @default null */ parseFilterFunc?(arg: string, index: number, argv: string[], argMeta: argMeta, input: string[]): boolean /** * Allows multiple flag values & changes the returned flags to always be arrays, with the default being the first value if the flag was not set, or an * empty array if the flag does not have a default but was not present. * @example * ```js * const { flags } = parser(["--flag=hello", "--flag=world"], { * flags: { * defaultedFlag: { default: "missing", type: "string" }, * missingFlag: { type: "string" }, * }, * allowMultipleFlagValues: true, * allowUnknownFlags: true, * }); * flags === { flag: ["hello", "world"], defaultedFlag: ["missing"], missingFlag: [] } * ``` * @default false */ allowMultipleFlagValues?: boolean } export type argMeta = { /** Is set to true if the arg will be parsed as a flag */ isFlag: boolean; /** Is isFlag is true, the flag will be parsed as a shorthand */ isShorthand: boolean; /** Is isFlag is true, is set to the flag key without any leading flag characters (eg: `"--flag" -> "flag"`) */ flagKey: string; /** Is true if isFlag is true and the flag has an assigned value (ie: `arg === "--flag=value"`) */ hasFlagAssignedValue: boolean; /** Is hasFlagAssignedValue is true, is set to the flag's assigned value (eg: `"--flag=value" -> "value"`) */ flagAssignedValue: string; /** Is set to true if the arg will be treated as an input string, ie: if isFlag and isFlagNaturalValue are false */ isInput: boolean; /** Is set to true if this arg would be treated as the value to the most recently parsed flag (ie: `["--flag", "value"][1].argMeta.isFlagNaturalValue === true` ) */ isFlagNaturalValue: boolean; } function __type__getType(e: any) { return typeof e }; export type JSTypes = ReturnType; export type FlagReturnType = FlagType extends 'boolean' ? boolean : FlagType extends 'number' ? number : FlagType extends 'bigint' ? bigint : FlagType extends 'string' ? string : string | boolean | number | bigint; type ValueOf = T[keyof T]; type OptionalKeys = Pick & Partial>; type _OptionalIfFlagDefaultNotPresent = OptionalKeys>; type _ResolveFlagTypes = { [K in keyof Flags]: allowMultipleFlagValues extends true ? FlagReturnType[] : FlagReturnType } export type FlagsReturn = _ResolveFlagTypes< Opts['allowMultipleFlagValues'] extends true ? Opts['flags'] : _OptionalIfFlagDefaultNotPresent, Opts['allowMultipleFlagValues'] extends true ? true : false >;