UNPKG

decline-ts

Version:

Composable command-line parser for TypeScript - a (partial) porting of Scala decline using fp-ts

147 lines (146 loc) 6.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Opts = void 0; const fp_ts_1 = require("fp-ts"); const function_1 = require("fp-ts/function"); const Command_1 = require("./Command"); const ValidatedNea_1 = require("./ValidatedNea"); const URI_ = 'Opts'; var Opts; (function (Opts) { /** * Constructors */ Opts.pure = (a) => ({ _tag: 'Pure', a }); Opts.app = (f, fa) => ({ _tag: 'App', f, a: fa }); Opts.orElse = (a, b) => ({ _tag: 'OrElse', a, b }); function single(opt) { return { _tag: 'Single', opt }; } Opts.single = single; function repeated(opt) { return { _tag: 'Repeated', opt }; } Opts.repeated = repeated; function subcommand(arg) { return isCommand(arg) ? { _tag: 'Subcommand', command: arg } : o => ({ _tag: 'Subcommand', command: Command_1.Command(arg)(o) }); } Opts.subcommand = subcommand; const Validate = (value, vNea) => ({ _tag: 'Validate', value, validate: vNea }); Opts.helpFlag = (flag) => ({ _tag: 'HelpFlag', flag }); Opts.unit = Opts.pure(undefined); function option(codec = fp_ts_1.either.right) { return ({ long, help, short = '', metavar }) => function_1.pipe(single(Opt.regular(Name.namesFor(long, short), metavar, help)), Opts.mapValidated(codec)); } Opts.option = option; function options(codec = fp_ts_1.either.right) { return ({ long, help, short = '', metavar }) => function_1.pipe(repeated(Opt.regular(Name.namesFor(long, short), metavar, help)), Opts.mapValidated(args => fp_ts_1.readonlyNonEmptyArray.readonlyNonEmptyArray.traverse(stringValidation)(args, codec))); } Opts.options = options; Opts.flag = ({ long, help, short = '' }) => single(Opt.flag(Name.namesFor(long, short), help)); Opts.flags = ({ long, help, short = '' }) => function_1.pipe(repeated(Opt.flag(Name.namesFor(long, short), help)), Opts.map(l => l.length)); function argument(codec = fp_ts_1.either.right) { return (metavar = '') => function_1.pipe(single(Opt.argument(metavar)), Opts.mapValidated(codec)); } Opts.argument = argument; function argumentS(codec = fp_ts_1.either.right) { return metavar => function_1.pipe(repeated(Opt.argument(metavar)), Opts.mapValidated(args => fp_ts_1.readonlyNonEmptyArray.readonlyNonEmptyArray.traverse(stringValidation)(args, codec))); } Opts.argumentS = argumentS; function param(codec = fp_ts_1.either.right) { return metavar => function_1.pipe(single(Opt.argument(metavar)), Opts.mapValidated(codec)); } Opts.param = param; function params(codec = fp_ts_1.either.right) { return metavar => function_1.pipe(repeated(Opt.argument(metavar)), Opts.mapValidated(args => fp_ts_1.readonlyNonEmptyArray.readonlyNonEmptyArray.traverse(fp_ts_1.either.getValidation(fp_ts_1.readonlyNonEmptyArray.getSemigroup()))(args, codec))); } Opts.params = params; /** * Methods */ Opts.mapValidated = (f) => (fa) => fa._tag === 'Validate' ? Validate(fa.value, function_1.flow(fa.validate, fp_ts_1.either.chain(f))) : Validate(fa, f); Opts.validate = (message) => (pred) => (fa) => function_1.pipe(fa, Opts.mapValidated(a => (pred(a) ? ValidatedNea_1.ValidatedNea.right(a) : ValidatedNea_1.ValidatedNea.left(message)))); Opts.withDefault = (fy) => Opts.alt(() => Opts.pure(fy())); Opts.orNone = (fa) => function_1.pipe(fa, Opts.map(fp_ts_1.option.some), Opts.withDefault(() => fp_ts_1.option.none)); Opts.orEmpty = (fa) => function_1.pipe(fa, Opts.withDefault(() => [])); Opts.orFalse = (fa) => function_1.pipe(fa, Opts.map(() => true), Opts.withDefault(() => false)); Opts.asHelp = (fa) => function_1.pipe(fa, Opts.map(() => { }), Opts.helpFlag); Opts.map = (f) => (fa) => Opts.mapValidated(function_1.flow(f, fp_ts_1.either.right))(fa); Opts.ap = (fab) => (fa) => Opts.app(fab, fa); Opts.alt = (that) => (fa) => Opts.orElse(fa, that()); /** * Instance */ Opts.URI = URI_; Opts.opts = { URI: Opts.URI, map: (fa, f) => function_1.pipe(fa, Opts.map(f)), ap: (fab, fa) => function_1.pipe(fa, Opts.ap(fab)), alt: (fa, that) => function_1.pipe(fa, Opts.alt(that)), }; let Name; (function (Name) { // eslint-disable-next-line no-shadow Name.longName = (flag) => ({ _tag: 'LongName', flag }); // eslint-disable-next-line no-shadow Name.shortName = (flag) => ({ _tag: 'ShortName', flag }); Name.stringify = (name) => name._tag === 'LongName' ? `--${name.flag}` : `-${name.flag}`; Name.namesFor = (long, short) => fp_ts_1.readonlyArray.cons(Name.longName(long), short.split('').map(Name.shortName)); Name.eq = fp_ts_1.eq.getStructEq({ _tag: fp_ts_1.eq.eqString, flag: fp_ts_1.eq.eqString, }); })(Name = Opts.Name || (Opts.Name = {})); let Opt; (function (Opt) { Opt.regular = (names, metavar, help) => ({ _tag: 'Regular', names, metavar, help, }); // eslint-disable-next-line no-shadow Opt.flag = (names, help) => ({ _tag: 'Flag', names, help, }); // eslint-disable-next-line no-shadow Opt.argument = (metavar) => ({ _tag: 'Argument', metavar }); const regularEq = fp_ts_1.eq.getStructEq({ names: fp_ts_1.readonlyArray.getEq(Name.eq), metavar: fp_ts_1.eq.eqString, help: fp_ts_1.eq.eqString, }); const flagEq = fp_ts_1.eq.getStructEq({ names: fp_ts_1.readonlyArray.getEq(Name.eq), help: fp_ts_1.eq.eqString, }); const argumentEq = fp_ts_1.eq.getStructEq({ metavar: fp_ts_1.eq.eqString, }); function eq() { return { equals: (x, y) => { switch (x._tag) { case 'Regular': return y._tag === 'Regular' ? regularEq.equals(x, y) : false; case 'Flag': return y._tag === 'Flag' ? flagEq.equals(x, y) : false; case 'Argument': return y._tag === 'Argument' ? argumentEq.equals(x, y) : false; } }, }; } Opt.eq = eq; })(Opt = Opts.Opt || (Opts.Opt = {})); })(Opts = exports.Opts || (exports.Opts = {})); const stringValidation = fp_ts_1.either.getValidation(fp_ts_1.readonlyNonEmptyArray.getSemigroup()); const tagKey = '_tag'; const tagVal = 'Command'; const isCommand = (arg) => function_1.pipe(fp_ts_1.readonlyRecord.lookup(tagKey, arg), fp_ts_1.option.exists(t => t === tagVal));