UNPKG

@eeue56/baner

Version:

Flag parsing library in Typescript

158 lines (157 loc) 9.29 kB
export type Err<error> = { kind: "Err"; error: error; }; export type Ok<value> = { kind: "Ok"; value: value; }; export type Result<value> = Ok<value> | Err<string>; export declare function Ok<const value>(value: value): Result<value>; export declare function Err<const value>(error: string): Result<value>; declare const OneOf: unique symbol; type OneOf<x extends readonly string[]> = typeof OneOf; declare const VariableList: unique symbol; type VariableList<x extends FlagArgument<VariableListBasicTypes>> = typeof VariableList; declare const List: unique symbol; type List<x extends readonly FlagArgument<BasicTypes>[]> = typeof List; export type BasicTypes = string | number | boolean; export type VariableListBasicTypes = BasicTypes | OneOf<readonly string[]>; export type BaseParseableTypes = BasicTypes | OneOf<readonly string[]> | VariableList<BaseVariableListFlagArgument<VariableListBasicTypes>> | List<readonly BaseFlagArgument<BasicTypes>[]>; export type KnownTypes = BaseParseableTypes; export type BaseVariableListFlagArgument<flagType extends VariableListBasicTypes> = flagType extends BasicTypes ? BaseFlagArgument<flagType> : flagType extends OneOf<readonly string[]> ? OneOfArgument<readonly string[]> : never; export type BaseFlagArgument<flagType extends BasicTypes> = flagType extends string ? StringArgument<string> : flagType extends number ? NumberArgument<number> : flagType extends boolean ? BooleanArgument<boolean> : never; export type FlagArgument<flagType extends BaseParseableTypes> = flagType extends BasicTypes ? BaseFlagArgument<flagType> : flagType extends OneOf<infer inner> ? OneOfArgument<inner> : flagType extends VariableList<infer inner> ? VariableListArgument<inner> : flagType extends List<infer inner> ? ListArgument<inner> : never; type InferVariableListFlagType<flagArgument extends VariableListArgument<FlagArgument<VariableListBasicTypes>>> = flagArgument extends VariableListArgument<infer inner> ? inner extends StringArgument<string> ? string[] : inner extends NumberArgument<number> ? number[] : inner extends BooleanArgument<boolean> ? boolean[] : inner extends OneOfArgument<infer union> ? readonly union[number][] : "never" : never; type InferListFlagTypeRecursive<inner extends readonly FlagArgument<BasicTypes>[]> = inner extends readonly [infer first, ...infer rest] ? first extends StringArgument<string> ? rest extends readonly FlagArgument<BasicTypes>[] ? [string, ...InferListFlagTypeRecursive<rest>] : [string] : first extends NumberArgument<number> ? rest extends readonly FlagArgument<BasicTypes>[] ? [number, ...InferListFlagTypeRecursive<rest>] : [number] : first extends BooleanArgument<boolean> ? rest extends readonly FlagArgument<BasicTypes>[] ? [boolean, ...InferListFlagTypeRecursive<rest>] : [boolean] : [] : inner extends StringArgument<string> ? [string] : inner extends NumberArgument<number> ? [number] : inner extends BooleanArgument<boolean> ? [boolean] : []; type InferListFlagType<flagArgument extends ListArgument<readonly FlagArgument<BasicTypes>[]>> = flagArgument extends ListArgument<infer inner> ? InferListFlagTypeRecursive<inner> : never; type InferOneOfFlagType<flagArgument extends OneOfArgument<readonly string[]>> = flagArgument extends OneOfArgument<infer inner> ? inner extends readonly string[] ? inner[number] : inner : never; export type InferFlagArgumentType<flagArgument extends FlagArgument<KnownTypes>> = flagArgument extends StringArgument<string> ? string : flagArgument extends NumberArgument<number> ? number : flagArgument extends BooleanArgument<boolean> ? boolean : flagArgument extends OneOfArgument<infer inner> ? InferOneOfFlagType<flagArgument> : flagArgument extends VariableListArgument<infer inner> ? InferVariableListFlagType<flagArgument> : flagArgument extends ListArgument<readonly FlagArgument<BasicTypes>[]> ? InferListFlagType<flagArgument> : never; /** * A result from a flag: contains the flag name, if it was present in the arguments, * and whether the arguments were parsed as described. */ export type FlagResult<flagArgument extends FlagArgument<KnownTypes>, name extends string> = { flag: Flag<flagArgument, name>; isPresent: boolean; arguments: Result<InferFlagArgumentType<flagArgument>>; }; export type StringArgument<encode extends string> = { kind: "StringArgument"; }; /** * An argument parser that treats an argument as a string */ export declare function string(): FlagArgument<string>; export type NumberArgument<encode extends number> = { kind: "NumberArgument"; }; /** * An argument parser that treats an argument as a number */ export declare function number(): NumberArgument<number>; export type BooleanArgument<encode extends boolean> = { kind: "BooleanArgument"; }; /** * An argument parser that treats an argument as a boolean */ export declare function boolean(): BooleanArgument<boolean>; /** * An argument parser that always passes */ export declare function empty(): FlagArgument<true>; export type ListArgument<flagTypes extends readonly FlagArgument<BasicTypes>[]> = { kind: "ListArgument"; items: flagTypes; }; /** * An argument parser that treats an argument as a list */ export declare function list<const flagTypes extends readonly FlagArgument<BasicTypes>[]>(flagArgumentParsers: flagTypes): ListArgument<flagTypes>; export type VariableListArgument<flagType extends FlagArgument<VariableListBasicTypes>> = { kind: "VariableListArgument"; item: flagType; }; /** * An argument parser that treats an argument as a list */ export declare function variableList<flagType extends FlagArgument<VariableListBasicTypes>>(flagArgumentParser: flagType): VariableListArgument<flagType>; export type OneOfArgument<encode extends readonly string[]> = { kind: "OneOfArgument"; items: encode; }; /** * An argument parser that treats an argument as an enum */ export declare function oneOf<const encode extends readonly string[]>(items: encode): OneOfArgument<encode>; export type Short<flagArgument extends FlagArgument<KnownTypes>, name extends string> = { kind: "Short"; name: name; help: string; parser: flagArgument; }; export type Long<flagArgument extends FlagArgument<KnownTypes>, name extends string> = { kind: "Long"; name: name; help: string; parser: flagArgument; }; export type Both<flagArgument extends FlagArgument<KnownTypes>, name extends string> = { kind: "Both"; shortName: string; longName: name; help: string; parser: flagArgument; }; export type Flag<flagType extends FlagArgument<KnownTypes>, name extends string> = Short<flagType, name> | Long<flagType, name> | Both<flagType, name>; /** * A short flag, like -y */ export declare function shortFlag<const flagArgument extends FlagArgument<KnownTypes>, const name extends string>(name: name, help: string, parser: flagArgument): Short<flagArgument, name>; /** * A long flag, like --yes */ export declare function longFlag<const flagArgument extends FlagArgument<KnownTypes>, const name extends string>(name: name, help: string, parser: flagArgument): Long<flagArgument, name>; /** * A short or long flag, like -y or --yes */ export declare function bothFlag<const flagArgument extends FlagArgument<KnownTypes>, const name extends string>(shortName: string, longName: name, help: string, parser: flagArgument): Both<flagArgument, name>; export type InferFlagType<x extends Flag<FlagArgument<BaseParseableTypes>, string>> = x extends Flag<FlagArgument<infer flagType>, infer name> ? flagType : never; export type InferFlagName<x extends Flag<FlagArgument<BaseParseableTypes>, string>> = x extends Flag<infer flagType, infer name> ? name : never; export type InferFlagResultType<x extends FlagResult<FlagArgument<KnownTypes>, string>> = x extends FlagResult<infer flagArgument, infer name> ? InferFlagArgumentType<flagArgument> : never; export type ProgramParser<flagTypes extends readonly Flag<FlagArgument<KnownTypes>, string>[]> = { flags: { [k in flagTypes[number] as InferFlagName<k>]: k; }; }; /** * A Program contains all arguments given to it, and an record of all the flags */ export type Program<flagTypes extends readonly Flag<FlagArgument<KnownTypes>, string>[]> = { args: readonly string[]; readonly flags: { [k in flagTypes[number] as InferFlagName<k>]: FlagResult<k["parser"], InferFlagName<k>>; }; }; /** * Extracted values from a parsed program */ export type ProgramValues<flags extends readonly Flag<FlagArgument<KnownTypes>, string>[]> = { [k in flags[number] as InferFlagName<k>]: InferFlagArgumentType<k["parser"]> | undefined; }; /** * Infer a Program from a given parser, e.g: * ``` * function handleFlag(program: ProgramOf<typeof parser>) {} * ``` */ export type ProgramOf<parser extends ProgramParser<readonly Flag<FlagArgument<KnownTypes>, string>[]>> = parser extends ProgramParser<infer flags> ? Program<flags> : never; /** * Infer a ProgramValues from a given parser, e.g: * ``` * function handleFlag(yes: ProgramValuesOf<typeof parser>["yes"]) {} * ``` */ export type ProgramValuesOf<parser extends ProgramParser<readonly Flag<FlagArgument<KnownTypes>, string>[]>> = parser extends ProgramParser<infer flags> ? ProgramValues<flags> : never; export {};