104 lines
2.5 KiB
TypeScript
104 lines
2.5 KiB
TypeScript
import { parseArgs } from "node:util";
|
|
import { z } from "zod";
|
|
import { CLIError, MuseError } from "#lib";
|
|
import chalk from "chalk";
|
|
import { version } from "../../package.json" with { type: "json" };
|
|
|
|
export const USAGE = `
|
|
${chalk.bold("muse")} - Compile and validate Playbills for Proscenium
|
|
${chalk.dim(`v${version}`)}
|
|
|
|
Usage:
|
|
muse [/path/to/binding.yaml] <options>
|
|
|
|
Options:
|
|
--check Only load and check the current binding and resources, but do not compile
|
|
--outfile, -o Specify the output file path. If not specified, output to stdout
|
|
--watch, -w Watch the directory for changes and recompile
|
|
--renderer, -r Specify the output renderer. Options: json, html
|
|
--help, -h Show this help message
|
|
`.trim();
|
|
|
|
const Renderers = ["json", "html"] as const;
|
|
const RendererSchema = z.enum(Renderers);
|
|
type Renderer = z.infer<typeof RendererSchema>;
|
|
|
|
/**
|
|
* A shape representing the arguments passed to the CLI
|
|
*/
|
|
export interface CLIArguments {
|
|
inputFilePath: string;
|
|
|
|
options: {
|
|
check: boolean;
|
|
outfile: string;
|
|
help: boolean;
|
|
renderer: Renderer;
|
|
watch: boolean;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Given an array of CLI arguments, parse them into a structured object
|
|
*
|
|
* @param argv The arguments to parse
|
|
* @returns The parsed CLI arguments
|
|
*
|
|
* @throws {CLIError} if the arguments are invalid
|
|
*/
|
|
export function parseCLIArguments(argv: string[]): CLIArguments {
|
|
const { values: options, positionals: args } = parseArgs({
|
|
args: argv,
|
|
options: {
|
|
check: {
|
|
short: "c",
|
|
type: "boolean",
|
|
default: false,
|
|
},
|
|
outfile: {
|
|
short: "o",
|
|
type: "string",
|
|
default: "",
|
|
},
|
|
help: {
|
|
short: "h",
|
|
default: false,
|
|
type: "boolean",
|
|
},
|
|
renderer: {
|
|
short: "r",
|
|
default: "json",
|
|
type: "string",
|
|
},
|
|
watch: {
|
|
default: false,
|
|
type: "boolean",
|
|
},
|
|
},
|
|
strict: true,
|
|
allowPositionals: true,
|
|
});
|
|
|
|
// -- ARG VALIDATION -- //
|
|
if (options.check && options.outfile !== "") {
|
|
throw new CLIError("Cannot use --check and --outfile together");
|
|
}
|
|
|
|
const parsedRenderer = RendererSchema.safeParse(options.renderer);
|
|
|
|
if (!parsedRenderer.success) {
|
|
throw new MuseError(`Invalid renderer: ${parsedRenderer.data}`);
|
|
}
|
|
|
|
return {
|
|
inputFilePath: args[0] ?? "./binding.yaml",
|
|
|
|
options: {
|
|
check: options.check,
|
|
outfile: options.outfile,
|
|
help: options.help,
|
|
renderer: parsedRenderer.data,
|
|
watch: options.watch,
|
|
},
|
|
};
|
|
}
|