Huge commit. Multiple fixes. Refactored commands. Invitations, resources, template inspection, mnemonic stuff, cli utils, pretty printing, remove unreserve on start, fix connectino requirement for invitations, format cashAddress to lockingBytecode on send, lots and lots of other stuff.
This commit is contained in:
80
src/cli/arguments.ts
Normal file
80
src/cli/arguments.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* CLI Argument extraction and validation.
|
||||
*
|
||||
* Converts `-${key}` or `--${key}` to `key` in the args object.
|
||||
*/
|
||||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* Converts the CLI args to a key-value object and return the options object along with the other arguments still in the array.\
|
||||
* eg: `xo-cli mnemonic create page pencil stock planet limb cluster assault speak off joke private pioneer -v -o mnemonic.txt` will return:
|
||||
* {
|
||||
* args: ["mnemonic", "create", "page", "pencil", "stock", "planet", "limb", "cluster", "assault", "speak", "off", "joke", "private", "pioneer"],
|
||||
* options: {
|
||||
* output: "mnemonic.txt",
|
||||
* verbose: "true",
|
||||
* },
|
||||
* }
|
||||
*
|
||||
* @param args - The CLI args to convert.
|
||||
* @returns The key-value object.
|
||||
*/
|
||||
export function convertArgsToObject(args: string[]): { args: string[], options: Record<string, string> } {
|
||||
// Map of single-character short flags to their canonical long names
|
||||
const shortToFull: Record<string, string> = {
|
||||
'm': 'mnemonicFile',
|
||||
'o': 'output',
|
||||
'v': 'verbose',
|
||||
'h': 'help',
|
||||
};
|
||||
|
||||
// Flags that are always boolean and never consume the next argument as a value.
|
||||
// Uses the canonical (expanded) names so the check works after short-form resolution.
|
||||
const booleanFlags = new Set<string>([
|
||||
'verbose',
|
||||
'help',
|
||||
'autoInputs',
|
||||
'sign',
|
||||
'broadcast',
|
||||
]);
|
||||
|
||||
const positionalArgs: string[] = [];
|
||||
const optionsObject: Record<string, string> = {};
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
|
||||
// Collect non-option arguments as positional args
|
||||
if (!arg || !arg.startsWith("-")) {
|
||||
if (arg) positionalArgs.push(arg);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Format the option key:
|
||||
// - Remove the leading `-`s
|
||||
// - Convert kebab-case to camelCase
|
||||
// - Expand known short forms to their full names
|
||||
let key = arg.replace(/^-+/, "").replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
||||
key = shortToFull[key] ?? key;
|
||||
|
||||
// Known boolean flags never take a value
|
||||
if (booleanFlags.has(key)) {
|
||||
optionsObject[key] = "true";
|
||||
continue;
|
||||
}
|
||||
|
||||
const nextArg = args[i + 1];
|
||||
|
||||
// If there's no next arg or it starts with `-`, treat this as a boolean flag
|
||||
if (!nextArg || nextArg.startsWith("-")) {
|
||||
optionsObject[key] = "true";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Consume the next arg as the value and skip it in the next iteration
|
||||
optionsObject[key] = nextArg;
|
||||
i++;
|
||||
}
|
||||
|
||||
return { args: positionalArgs, options: optionsObject };
|
||||
}
|
||||
Reference in New Issue
Block a user