ox-argv-parser/types.d.ts
Oxtaly 86b8cfcfaa Addition: opts.allowMultipleFlagValues & more accurate return flag types
opts.allowMultipleFlagValues -> returns flag values as array and add duplicate flags to the array instead of picking the last one (eg ["--foo", "hello", "--foo=world!"] -> { foo: ["hello", "world!"] }).
    Flag return types are now typed as Partials if a default is not present and opts.allowMultipleFlagValues is not enabled.
2025-06-15 05:18:54 +02:00

191 lines
10 KiB
TypeScript

interface FlagT<T, Z> {
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<string, "string"> | FlagT<boolean, "boolean"> | FlagT<number, "number"> | FlagT<bigint, "bigint"> | FlagT<string | number | bigint | boolean, "any">
export interface FlagsI { [key: readonly string]: FlagAny }
export type DefaultParserOptsType = ParserOpts<FlagsI>
/** This object will be modified by parser */
export interface ParserOpts<Flags extends FlagsI> {
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<typeof __type__getType>;
export type FlagReturnType<FlagType extends FlagTypes> =
FlagType extends 'boolean' ? boolean
: FlagType extends 'number' ? number
: FlagType extends 'bigint' ? bigint
: FlagType extends 'string' ? string
: string | boolean | number | bigint;
type ValueOf<T> = T[keyof T];
type OptionalKeys<T, K extends keyof T> = Pick<T, K> & Partial<Omit<T, K>>;
type _OptionalIfFlagDefaultNotPresent<T> = OptionalKeys<T, ValueOf<{ [V in keyof T]: 'default' extends keyof T[V] ? never : V }>>;
type _ResolveFlagTypes<Flags extends FlagsI, allowMultipleFlagValues extends boolean> = {
[K in keyof Flags]: allowMultipleFlagValues extends true
? FlagReturnType<Flags[K]['type']>[]
: FlagReturnType<Flags[K]['type']>
}
export type FlagsReturn<Opts extends ParserOpts> = _ResolveFlagTypes<
Opts['allowMultipleFlagValues'] extends true ? Opts['flags'] : _OptionalIfFlagDefaultNotPresent<Opts['flags']>,
Opts['allowMultipleFlagValues'] extends true ? true : false
>;