type KebabToCamel<S extends string> = S extends `${infer First}-${infer Rest}` ? `${First}${Capitalize<KebabToCamel<Rest>>}` : S;
type TrimLeft<S extends string> = S extends ` ${infer Rest}` ? TrimLeft<Rest> : S extends `,${infer Rest}` ? TrimLeft<Rest> : S;
type TrimRight<S extends string> = S extends `${infer Rest} ` ? TrimRight<Rest> : S extends `${infer Rest},` ? TrimRight<Rest> : S;
type Trim<S extends string> = TrimLeft<TrimRight<S>>;
type HasArgument<S extends string> = S extends `${string}<${string}>` ? true : false;
type IsVariadic<S extends string> = S extends `${string}<${string}...>` ? true : false;
type RemoveArgument<S extends string> = S extends `${infer Before}<${string}>` ? Trim<Before> : S;
type ExtractArgumentContent<S extends string> = S extends `${string}<${infer Content}>` ? Content : never;
type IsEnumArg<S extends string> = S extends `${string}|${string}` ? true : false;
type ParseEnumValues<S extends string> = S extends `${infer A}|${infer Rest}` ? A | ParseEnumValues<Rest> : S;
type ExtractInlineEnum<S extends string> = HasArgument<S> extends true ? ExtractArgumentContent<S> extends infer Content ? Content extends string ? IsEnumArg<Content> extends true ? ParseEnumValues<Content> : never : never : never : never;
type ExtractLong<S extends string, HasArg extends boolean> = S extends `--no-${infer Name}` ? (HasArg extends true ? KebabToCamel<`no-${Name extends `${infer N} ${string}` ? N : Name extends `${infer N},${string}` ? N : Name}`> : KebabToCamel<Name extends `${infer N} ${string}` ? N : Name extends `${infer N},${string}` ? N : Name>) : S extends `--${infer Name}` ? (KebabToCamel<Name extends `${infer N} ${string}` ? N : Name extends `${infer N},${string}` ? N : Name>) : never;
type ExtractShort<S extends string> = S extends `-${infer C}${infer Rest}` ? (C extends '-' ? never : Rest extends '' ? C : Rest extends ` ${string}` ? C : Rest extends `,${string}` ? C : C) : never;
type ParseSegment<S extends string, HasArg extends boolean> = S extends `--${string}` ? ExtractLong<S, HasArg> : S extends `-${string}` ? ExtractShort<S> : never;
type SplitByComma<S extends string, HasArg extends boolean> = S extends `${infer A},${infer Rest}` ? SplitBySpace<Trim<A>, HasArg> | SplitByComma<Trim<Rest>, HasArg> : SplitBySpace<Trim<S>, HasArg>;
type SplitBySpace<S extends string, HasArg extends boolean> = S extends `${infer A} ${infer Rest}` ? ParseSegment<Trim<A>, HasArg> | SplitBySpace<Trim<Rest>, HasArg> : ParseSegment<S, HasArg>;
type ExtractNames<S extends string, HasArg extends boolean> = SplitByComma<Trim<S>, HasArg>;
type ExtractOptionNames<S extends string> = ExtractNames<RemoveArgument<S>, HasArgument<S>>;
type InferValueType<S extends string, TypeOpt extends string | undefined, EnumOpt extends readonly string[] | undefined> = EnumOpt extends readonly [infer First, ...infer Rest] ? First | (Rest extends readonly string[] ? Rest[number] : never) : ExtractInlineEnum<S> extends never ? TypeOpt extends 'integer' | 'number' ? number : TypeOpt extends 'string' ? string : string : ExtractInlineEnum<S>;
type DetermineOptionType<S extends string, TypeOpt extends string | undefined = undefined, EnumOpt extends readonly string[] | undefined = undefined> = TypeOpt extends 'boolean' ? boolean : TypeOpt extends 'integer' | 'number' ? HasArgument<S> extends true ? IsVariadic<S> extends true ? number[] : number : number : TypeOpt extends 'string' ? HasArgument<S> extends true ? IsVariadic<S> extends true ? string[] : string : string : HasArgument<S> extends true ? IsVariadic<S> extends true ? InferValueType<S, TypeOpt, EnumOpt>[] : InferValueType<S, TypeOpt, EnumOpt> : boolean;
type OptionRecord<S extends string, TypeOpt extends string | undefined = undefined, EnumOpt extends readonly string[] | undefined = undefined, IsRequired extends boolean = false, HasNonUndefinedDefault extends boolean = false> = IsRequired extends true ? {
    [K in ExtractOptionNames<S>]: DetermineOptionType<S, TypeOpt, EnumOpt>;
} : HasNonUndefinedDefault extends true ? {
    [K in ExtractOptionNames<S>]: DetermineOptionType<S, TypeOpt, EnumOpt>;
} : {
    [K in ExtractOptionNames<S>]?: DetermineOptionType<S, TypeOpt, EnumOpt>;
};
type ExtractType<O> = O extends {
    type: infer T extends string;
} ? T : undefined;
type ExtractEnum<O> = O extends {
    enum: infer E extends readonly string[];
} ? E : undefined;
type ExtractRequired<O> = O extends {
    required: true;
} ? true : false;
type ExtractHasDefault<O> = O extends {
    default: undefined;
} ? false : O extends {
    default: any;
} ? true : false;
type OptionRecordFrom<N extends string, O = {}> = OptionRecord<N, ExtractType<O>, ExtractEnum<O>, ExtractRequired<O>, ExtractHasDefault<O>>;
type OptionInfer<N extends string, O> = OptionRecordFrom<N, O>;
export type { OptionInfer };
