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.9 kB · 115 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116import type { StandardSchemaV1 } from "@standard-schema/spec";import { validate } from "./validate.ts";import { toKebabCase } from "./case.ts";
export type MatchResult = { matched: true; value: string | boolean; remainder: string[];} | { matched: false;};
export interface Matcher { (input: string[], path: string[]): MatchResult;}
export function matchAll(...matchers: Matcher[]): Matcher { return (input, path) => { for (let matcher of matchers) { let result = matcher(input, path); if (result.matched) { return result; } } return { matched: false }; };}
export function parseLongOption(aliases: string[]): Matcher { return (input, path) => { let [option, value, ...remainder] = input;
if (option === optionKey(path) || aliases.includes(option)) { return { matched: true, remainder, value }; } else { return { matched: false }; } };}
export function parseLongOptionEql(): Matcher { return (input, path) => { let [first, ...remainder] = input; let prefix = `${optionKey(path)}=`; if (first.startsWith(prefix)) { return { matched: true, remainder, value: first.replace(prefix, "") }; } else { return { matched: false }; } };}
export function parseSwitch( schema: StandardSchemaV1, aliases: string[],): Matcher { return (input, path) => { let [head, ...remainder] = input; if ( isBoolean(schema) && (head === optionKey(path) || aliases.includes(head)) ) { return { matched: true, value: true, remainder }; } else { return { matched: false }; } };}
export function parseNegativeSwitch(schema: StandardSchemaV1): Matcher { return (input, path) => { let [head, ...remainder] = input; if (isBoolean(schema) && head === negativeSwitchKey(path)) { return { matched: true, value: false, remainder }; } else { return { matched: false }; } };}
export function parseArgument(isArgument: boolean): Matcher { return (input) => { let [value, ...remainder] = input; if (isArgument && !value.startsWith("-")) { return { matched: true, value, remainder }; } else { return { matched: false }; } };}
export function optionKey(path: string[]): string { return `--${toKebabCase(path.join(".")).toLowerCase()}`;}
function negativeSwitchKey(path: string[]): string { return `--no-${toKebabCase(path.join(".")).toLowerCase()}`;}
export function primitive(val: string | boolean): string | number | boolean { if (typeof val === "boolean") { return val; } let numval = Number(val); if (typeof numval === "number" && !isNaN(numval)) { return numval; } else { return val; }}
export function isBoolean<S extends StandardSchemaV1<unknown>>( schema: S,): boolean { return !validate(schema, false).issues && !validate(schema, true).issues;}