Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/bombshell-dev/configliere. A statically typed entry-point router for command-line applications
Something went wrong. Try again.
2.7 kB · 119 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120import { boolean as decode } from "./decode.ts";import { dasherize } from "./dasherize.ts";import { type Param, param, schema } from "./param.ts";import { brand, type Check, type Fold, type ParamElement, type Unary,} from "./pipeline.ts";import type { CLIRead, ReadCLI } from "./read.ts";import type { Flag } from "./tokenize.ts";import type { AnyRoute, Definition, Schema } from "./types.ts";
export function toggle< const N extends string, const E extends readonly Unary[],>( named: Definition<N>, ...elements: E & Check<Param<N, boolean>, E>): ElementOf<N, Fold<Param<N, boolean>, E>> { const added = elements.reduce<unknown>( (value, element) => element(value as never), { ...param(named, binding(named.name), schema(bool)), decode, }, ) as Param<string, unknown>;
return brand<ElementOf<N, Fold<Param<N, boolean>, E>>>( (route: AnyRoute) => { let phases = [...route.phases]; let phase = phases.pop()!; phases.push({ ...phase, params: { ...phase.params, [added.name]: added, }, });
return { ...route, phases, }; }, );}
type ValueOf<P> = P extends Param<string, infer T> ? T : never;
type ElementOf<N extends string, P> = P extends Param<N, unknown> ? ParamElement<N, ValueOf<P>> : never;
function binding( name: string,): <P extends Param<string, unknown>>(param: P) => P { const stem = dasherize(name); const yes = `--${stem}`; const no = `--no-${stem}`;
return (param) => ({ ...param, cli: { read: reader(name), syntax: { type: "option", label: `${yes}, ${no}`, }, }, });}
function reader(name: string): ReadCLI { const stem = dasherize(name); const yes = `--${stem}`; const no = `--no-${stem}`;
return (tokens): CLIRead => { let claim = tokens.claimOne((token): token is Flag => { return token.type === "flag" && (token.text === yes || token.text === no); }); let [flag] = claim.tokens;
return flag ? { claim, result: { ok: true, value: { exists: true, value: flag.text === yes }, issues: [], }, } : { claim, result: { ok: true, value: { exists: false }, issues: [], }, }; };}
const bool: Schema<boolean> = { "~standard": { version: 1, vendor: "configliere", validate(value) { return typeof value === "undefined" ? { value: false } : typeof value === "boolean" ? { value } : { issues: [{ message: "expected boolean" }] }; }, },};