import { type Fn } from "@thi.ng/api/fn";
import type { ArgDef, ArgDefRequired, ArgSpec, KVDict, KVMultiDict, Tuple } from "./api.js";
/**
 * Returns a full {@link ArgSpec} for a boolean flag. The mere presence of this
 * arg will enable the flag.
 *
 * @param spec -
 */
export declare const flag: <S extends ArgDef>(spec: S) => S & {
    type: "flag";
    default: boolean;
    group: string;
};
/**
 * Returns a full {@link ArgSpec} for a string value arg.
 *
 * @param spec -
 */
export declare const string: <S extends ArgDef | ArgDefRequired<string>>(spec: S) => S & {
    type: "string";
    coerce: Fn<string, string>;
    hint: string;
    group: string;
};
/**
 * Multi-arg version of {@link string}. Returns a full {@link ArgSpec} for a
 * multi string value arg. This argument can be provided mutiple times with
 * values collected into an array.
 *
 * @param spec -
 */
export declare const strings: <S extends ArgDef | ArgDefRequired<unknown[]>>(spec: S & {
    delim?: string;
}) => S & {
    type: "strings";
    coerce: Fn<string[], unknown[]>;
    hint: string;
    group: string;
    delim: string;
    multi: true;
};
/**
 * Returns a full {@link ArgSpec} for a floating point value arg. The value
 * will be autoatically coerced into a number using {@link coerceFloat}.
 *
 * @param spec -
 */
export declare const float: <S extends ArgDef | ArgDefRequired<number>>(spec: S) => S & {
    type: "float";
    coerce: Fn<string, number>;
    hint: string;
    group: string;
};
/**
 * Multi-arg version of {@link float}. Returns a full {@link ArgSpec} for a
 * multi floating point value arg. This argument can be provided mutiple times
 * with values being coerced into numbers and collected into an array.
 *
 * @param spec -
 */
export declare const floats: <S extends ArgDef | ArgDefRequired<unknown[]>>(spec: S & {
    delim?: string;
}) => S & {
    type: "floats";
    coerce: Fn<string[], unknown[]>;
    hint: string;
    group: string;
    delim: string;
    multi: true;
};
/**
 * Returns a full {@link ArgSpec} for a single integer value arg. The value
 * will be autoatically coerced into a number using {@link coerceInt}.
 *
 * @param spec -
 */
export declare const int: <S extends ArgDef | ArgDefRequired<number>>(spec: S) => S & {
    type: "int";
    coerce: Fn<string, number>;
    hint: string;
    group: string;
};
/**
 * Multi-arg version of {@link int}. Returns a full {@link ArgSpec} for a multi
 * integer value arg. This argument can be provided mutiple times with values
 * being coerced into numbers and collected into an array.
 *
 * @param spec -
 */
export declare const ints: <S extends ArgDef | ArgDefRequired<unknown[]>>(spec: S & {
    delim?: string;
}) => S & {
    type: "ints";
    coerce: Fn<string[], unknown[]>;
    hint: string;
    group: string;
    delim: string;
    multi: true;
};
/**
 * Returns a full {@link ArgSpec} for a single hex integer value arg. The value
 * will be autoatically coerced into a number using {@link coerceHexInt}.
 *
 * @param spec -
 */
export declare const hex: <S extends ArgDef | ArgDefRequired<number>>(spec: S) => S & {
    type: "hex";
    coerce: Fn<string, number>;
    hint: string;
    group: string;
};
/**
 * Multi-arg version of {@link hex}. Returns a full {@link ArgSpec} for a multi
 * hex integer value arg. This argument can be provided mutiple times with
 * values being coerced into numbers and collected into an array.
 *
 * @param spec -
 */
export declare const hexes: <S extends ArgDef | ArgDefRequired<unknown[]>>(spec: S & {
    delim?: string;
}) => S & {
    type: "hexes";
    coerce: Fn<string[], unknown[]>;
    hint: string;
    group: string;
    delim: string;
    multi: true;
};
/**
 * Returns full {@link ArgSpec} for an enum-like string value arg. The raw CLI
 * value string will be automcatically validated using {@link coerceOneOf}.
 *
 * @param opts -
 * @param spec -
 */
export declare const oneOf: <K extends string, S extends ArgDef | ArgDefRequired<K>>(spec: S & {
    opts: readonly K[];
}) => S & {
    type: "oneOf";
    coerce: Fn<string, K>;
    desc: string;
    hint: string;
    group: string;
    opts: readonly K[];
};
/**
 * Multi-arg version of {@link oneOf}. Returns full {@link ArgSpec} for multiple
 * enum-like string value args. The raw CLI value strings will be automcatically
 * validated using {@link coerceOneOf} and collected into an array.
 *
 * @param opts -
 * @param spec -
 */
export declare const oneOfMulti: <K extends string, S extends ArgDef | ArgDefRequired<K[]>>(spec: S & {
    opts: readonly K[];
    delim?: string;
}) => S & {
    type: "oneOfMulti";
    coerce: Fn<string[], K[]>;
    desc: string;
    hint: string;
    group: string;
    multi: true;
    opts: readonly K[];
    delim?: string;
};
/**
 * Returns a full {@link ArgSpec} for multiple `key=value` pair args, coerced
 * into a result object.
 *
 * @remarks
 * The default delimiter (`=`) can be overridden. Also by default, key-only args
 * are allowed and will receive a `"true"` as their value. However, if `strict`
 * is true, only full KV pairs are allowed.
 *
 * @param spec -
 */
export declare const kvPairs: <S extends ArgDef | ArgDefRequired<KVDict>>(spec: S & {
    delim?: string;
    strict?: boolean;
}) => S & {
    type: "kvPairs";
    coerce: Fn<string[], KVDict>;
    hint: string;
    group: string;
    multi: true;
    kvDelim?: string;
    strict?: boolean;
    split: false;
};
/**
 * Like {@link kvPairs}, but coerces KV pairs into a result {@link KVMultiDict}
 * which supports multiple values per given key (each key's values are collected
 * into arrays).
 *
 * @param spec -
 */
export declare const kvPairsMulti: <S extends ArgDef | ArgDefRequired<KVMultiDict>>(spec: S & {
    delim?: string;
    strict?: boolean;
}) => S & {
    type: "kvPairsMulti";
    coerce: Fn<string[], KVMultiDict>;
    hint: string;
    group: string;
    multi: true;
    delim?: string;
    strict?: boolean;
};
/**
 * Returns a full {@link ArgSpec} for a fixed `size` tuple extracted from a
 * single value string. The individual values are delimited by `delim` (default:
 * `,`) and will be coerced into their target type via `coerce`. The result
 * tuple will be wrapped in a {@link Tuple} instance.
 *
 * @remarks
 * An error will be thrown if the number of extracted values differs from the
 * specified tuple size or any value coercion fails.
 *
 * @example
 * ```ts tangle:../export/tuple.ts
 * import { coerceInt, parse, tuple, type Tuple } from "@thi.ng/args";
 *
 * interface A {
 *   a?: Tuple<number>;
 * }
 *
 * console.log(
 *   parse<A>(
 *     { a: tuple({ size: 2, coerce: coerceInt }) },
 *     ["--a", "1,2"],
 *     { start: 0 }
 *   )
 * );
 * // {
 * //   result: { a: Tuple { value: [1, 2] } },
 * //   index: 2,
 * //   rest: [],
 * //   done: true
 * // }
 * ```
 *
 * @param spec -
 */
export declare const tuple: <T, S extends ArgDef | ArgDefRequired<Tuple<T>>>(spec: S & {
    size: number;
    coerce: Fn<string, T>;
    delim?: string;
}) => S & {
    type: "tuple";
    coerce: Fn<string, Tuple<T>>;
    hint: string;
    group: string;
    size: number;
    delim?: string;
};
/**
 * Syntax sugar for `tuple(size, coerceInt, {...})`. See {@link tuple} for
 * further details.
 *
 * @param spec -
 */
export declare const size: <S extends ArgDef | ArgDefRequired<Tuple<number>>>(spec: S & {
    size: number;
    delim?: string;
}) => S & {
    coerce: (x: string) => number;
    size: number;
    delim?: string;
} & {
    type: "tuple";
    coerce: Fn<string, Tuple<number>>;
    hint: string;
    group: string;
    size: number;
    delim?: string;
};
/**
 * Syntax sugar for `tuple(size, coerceFloat, {...})`. See {@link tuple} for
 * further details.
 *
 * @param spec -
 */
export declare const vec: <S extends ArgDef | ArgDefRequired<Tuple<number>>>(spec: S & {
    size: number;
    delim?: string;
}) => S & {
    coerce: (x: string) => number;
    size: number;
    delim?: string;
} & {
    type: "tuple";
    coerce: Fn<string, Tuple<number>>;
    hint: string;
    group: string;
    size: number;
    delim?: string;
};
/**
 * Returns full {@link ArgSpec} for a JSON value arg. The raw CLI value string
 * will be automcatically coerced using {@link coerceJson}.
 *
 * @param spec -
 */
export declare const json: <T, S extends ArgDef | ArgDefRequired<T>>(spec: S) => S & {
    type: "json";
    coerce: Fn<string, T>;
    hint: string;
    group: string;
};
/**
 * Index which maps arg type IDs to their factory functions
 */
export declare const ARG_TYPES: Record<string, Fn<any, ArgSpec<any>>>;
/**
 * Re-usable preset arg spec for a `--dry-run` flag.
 */
export declare const ARG_DRY_RUN: {
    dryRun: {
        desc: string;
    } & {
        type: "flag";
        default: boolean;
        group: string;
    };
};
/**
 * Re-usable preset arg spec for a `--quiet` / `-q` flag.
 */
export declare const ARG_QUIET: {
    quiet: {
        alias: string;
        desc: string;
    } & {
        type: "flag";
        default: boolean;
        group: string;
    };
};
/**
 * Re-usable preset arg spec for a `--verbose` / `-v` flag.
 */
export declare const ARG_VERBOSE: {
    verbose: {
        alias: string;
        desc: string;
    } & {
        type: "flag";
        default: boolean;
        group: string;
    };
};
/**
 * Higher-order re-usable preset arg spec for a `--out-dir` / `-O` arg. Accepts
 * optional default value (e.g. sourced from an env var). If the the
 * `defaultVal` is defined, the arg is declared as optional, otherwise
 * mandatory.
 *
 * @param defaultVal
 * @param desc
 */
export declare const ARG_OUT_DIR: <T extends string | undefined>(defaultVal?: string, desc?: string) => {
    outDir: ReturnType<typeof string> & (T extends string ? {
        default: string;
    } : {
        optional: false;
    });
};
/**
 * Higher-order re-usable preset arg spec for a `--out-file` / `-o` arg. Accepts
 * optional default value (e.g. sourced from an env var). If the the
 * `defaultVal` is defined, the arg is declared as optional, otherwise
 * mandatory.
 *
 * @param defaultVal
 * @param desc
 */
export declare const ARG_OUT_FILE: <T extends string | undefined>(defaultVal?: T, desc?: string) => {
    outFile: ReturnType<typeof string> & (T extends string ? {
        default: string;
    } : {
        optional: false;
    });
};
//# sourceMappingURL=args.d.ts.map