UNPKG

@thi.ng/args

Version:

Declarative, functional CLI argument/options parser, value coercions, sub-commands etc.

146 lines (145 loc) 3.13 kB
import { identity } from "@thi.ng/api/fn"; import { repeat } from "@thi.ng/strings/repeat"; import { coerceFloat, coerceFloats, coerceHexInt, coerceHexInts, coerceInt, coerceInts, coerceJson, coerceKV, coerceOneOf, coerceTuple } from "./coerce.js"; const $single = (coerce, hint) => (spec) => ({ coerce, hint, group: "main", ...spec }); const $multi = (coerce, hint) => (spec) => ({ hint: $hint(hint, spec.delim), multi: true, coerce, group: "main", ...spec }); const $hint = (hint, delim) => hint + (delim ? `[${delim}..]` : ""); const flag = (spec) => ({ flag: true, default: false, group: "flags", ...spec }); const string = $single(identity, "STR"); const strings = $multi(identity, "STR"); const float = $single(coerceFloat, "NUM"); const hex = $single(coerceHexInt, "HEX"); const int = $single(coerceInt, "INT"); const floats = $multi(coerceFloats, "NUM"); const hexes = $multi(coerceHexInts, "HEX"); const ints = $multi(coerceInts, "INT"); const json = (spec) => ({ coerce: coerceJson, hint: "JSON", group: "main", ...spec }); const $desc = (opts, prefix) => `${prefix ? prefix + ": " : ""}${opts.map((x) => `"${x}"`).join(", ")}`; const oneOf = (opts, spec) => ({ coerce: coerceOneOf(opts), hint: "ID", group: "main", ...spec, desc: $desc(opts, spec.desc) }); const oneOfMulti = (opts, spec) => ({ coerce: (values) => values.map(coerceOneOf(opts)), hint: $hint("ID", spec.delim), multi: true, group: "main", ...spec, desc: $desc(opts, spec.desc) }); const kvPairs = (spec, delim = "=", strict) => ({ coerce: coerceKV(delim, strict), hint: `key${delim}val`, multi: true, group: "main", ...spec }); const kvPairsMulti = (spec, delim = "=", strict) => ({ coerce: coerceKV(delim, strict, true), hint: `key${delim}val(s)`, multi: true, group: "main", ...spec }); const tuple = (coerce, size2, spec, delim = ",") => ({ coerce: coerceTuple(coerce, size2, delim), hint: [...repeat("N", size2)].join(delim), group: "main", ...spec }); const size = (size2, spec, delim = "x") => tuple(coerceInt, size2, spec, delim); const vec = (size2, spec, delim = ",") => tuple(coerceFloat, size2, spec, delim); const ARG_DRY_RUN = { dryRun: flag({ desc: "Dry run (no changes applied)" }) }; const ARG_QUIET = { quiet: flag({ alias: "q", desc: "Disable all logging" }) }; const ARG_VERBOSE = { verbose: flag({ alias: "v", desc: "Display extra information" }) }; const ARG_OUT_DIR = (defaultVal, desc) => ({ outDir: string({ alias: "O", desc: "Output directory" + (desc ?? ""), hint: "PATH", default: defaultVal, optional: !!defaultVal }) }); const ARG_OUT_FILE = (defaultVal, desc) => ({ outFile: string({ alias: "o", desc: "Output file" + (desc ?? ""), hint: "PATH", default: defaultVal, optional: !!defaultVal }) }); export { ARG_DRY_RUN, ARG_OUT_DIR, ARG_OUT_FILE, ARG_QUIET, ARG_VERBOSE, flag, float, floats, hex, hexes, int, ints, json, kvPairs, kvPairsMulti, oneOf, oneOfMulti, size, string, strings, tuple, vec };