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:
2026-04-06 11:56:09 +00:00
parent b475b23beb
commit 55c75501d5
24 changed files with 3284 additions and 77 deletions

80
src/cli/arguments.ts Normal file
View 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 };
}