@chzky/cliparser
v0.1.7
Published
## 安装 ```bash npm install @chzky/cliparser ```
Readme
@chzky/cliparser : 简易的命令行接口 (CLI) 解析器库。
安装
npm install @chzky/cliparser概述
@chzky/cliparser 的核心思想是通过一个配置对象来定义整个 CLI 的结构。这个配置对象包含了 CLI 的名称、版本、描述以及一系列的子命令。每个子命令又可以拥有自己的描述、别名、用法、默认动作以及嵌套的子命令。
最独特的功能是,您可以将命令的实际执行逻辑(action)定义为一个函数,或者是一个指向 TypeScript 模块的字符串(例如 import.meta.dirname + '/run.ts' 或 import.meta.dirname + '/run.ts' + ':' + 'test')。当使用文件路径时,cliparser 会动态导入并执行相应的函数,这使得 CLI 的结构更加模块化和可维护。
使用
1. 定义 CLI 配置
您可以直接在 TypeScript 中定义 CLI 配置,也可以使用 JSON 文件。
TypeScript 配置示例
// cli.ts
import { create_command, create_action, Parser } from "@chzky/cliparser";
// 假设 run.ts 存在于同一目录
// run.ts 内容示例:
// export default function mainAction(options: any, args: string[]) {
// console.log('Default action executed!', { options, args });
// }
// export function test(options: any, args: string[]) {
// console.log('Test action executed!', { options, args });
// }
const cliConfig = {
name: "my-cli",
version: "1.0.0",
description: "这是一个我的自定义 CLI 工具",
commands: [
create_command({
name: "hello",
description: "打招呼命令",
alias: "hi",
default: {
action: create_action((options, args) => {
console.log(`Hello, ${options.name || 'World'}!`);
if (args.length > 0) {
console.log("Arguments:", args);
}
}),
options: [
{
name: "-n --name <value:string>",
description: "你的名字",
},
],
args: ["[message:string]"]
},
}),
create_command({
name: "run-script",
description: "运行外部脚本",
default: {
action: import.meta.dirname + "/run.ts", // 默认导出函数
options: [
{
name: "--mode <value:string>",
description: "运行模式",
},
],
},
commands: [
create_command({
name: "test-func",
description: "运行外部脚本中的特定函数",
default: {
action: import.meta.dirname + "/run.ts" + ":" + "test", // 导出名为 'test' 的函数
options: [
{
name: "-v --verbose",
description: "详细模式",
},
],
},
}),
],
}),
],
};
const parser = new Parser(cliConfig);
// 在 Deno 环境中运行
if (import.meta.main) {
parser.parse(Deno.args).then(result => {
if (result.is_ok) {
console.log("CLI 执行成功:", result.unwrap());
} else {
console.error("CLI 执行失败:", result.unwrap_err());
}
});
}JSON 配置示例
如果您更喜欢使用 JSON 配置,需要确保 JSON 文件中引用的 TypeScript 模块路径是正确的。当使用 Parser.from() 方法加载 JSON 文件时,cliparser 会自动根据 JSON 文件的路径推断 import.meta.dirname 的值,从而正确解析相对路径。
// config.json
{
"name": "my-json-cli",
"version": "0.0.1",
"description": "一个通过 JSON 配置的 CLI",
"commands": [
{
"name": "greet",
"alias": "g",
"description": "向某人打招呼",
"usage": "greet <name>",
"default": {
"args": ["<name:string>"],
"options": [
{
"name": "-e --emoji <char:string>",
"description": "添加一个表情符号",
"alone": false,
"action": "./actions.ts:addEmoji"
}
],
"action": "./actions.ts:greetAction"
}
},
{
"name": "calc",
"description": "简单的计算器",
"commands": [
{
"name": "add",
"description": "加法",
"default": {
"args": ["<num1:number>", "<num2:number>"],
"action": "./actions.ts:add"
}
},
{
"name": "subtract",
"description": "减法",
"default": {
"args": ["<num1:number>", "<num2:number>"],
"action": "./actions.ts:subtract"
}
}
]
}
]
}// actions.ts (用于 config.json 的示例 actions)
export function greetAction(options: any, args: string[]) {
const name = args[0];
const emoji = options.emoji || "";
console.log(`Hello, ${name}${emoji}!`);
}
export function addEmoji(value: string) {
// 这里的 value 是 --emoji 选项的值
return value; // 通常这里会直接处理并返回,或修改外部状态
}
export function add(options: any, args: number[]) {
console.log(`Sum: ${args[0] + args[1]}`);
}
export function subtract(options: any, args: number[]) {
console.log(`Difference: ${args[0] - args[1]}`);
}// main.ts (用于加载 config.json)
import { Parser } from "@chzky/cliparser";
import { resolve } from "jsr:@std/path";
// 在 Deno 环境中运行
if (import.meta.main) {
const configPath = resolve(import.meta.dirname, "./config.json"); // 确保路径正确
const parser = Parser.from(configPath);
parser.parse(Deno.args).then(result => {
if (result.is_ok) {
console.log("CLI 执行成功:", result.unwrap());
} else {
console.error("CLI 执行失败:", result.unwrap_err());
}
});
}2. 运行 CLI
假设您将 TypeScript 配置保存在 cli.ts 中:
deno run --allow-read --allow-env cli.ts hello --name Alice
# 输出: Hello, Alice!
deno run --allow-read --allow-env cli.ts hello There
# 输出: Hello, World!
# Arguments: [ 'There' ]
deno run --allow-read --allow-env cli.ts run-script
# 运行 run.ts 的默认导出
deno run --allow-read --allow-env cli.ts run-script test-func -v
# 运行 run.ts 中名为 'test' 的导出函数假设您将 JSON 配置保存在 config.json 中,并使用 main.ts 加载:
deno run --allow-read --allow-env main.ts greet Bob --emoji ✨
# 输出: Hello, Bob✨!
deno run --allow-read --allow-env main.ts calc add 5 3
# 输出: Sum: 8API
Parser 类
用于创建和解析 CLI。
new Parser(config: CLIConfig)config: 一个CLIConfig对象,定义了 CLI 的结构。
static from(jsonpath: string): Parser- 从指定的 JSON 配置文件中加载 CLI 配置。
jsonpath: JSON 配置文件的路径。- 返回一个
Parser实例。
parse(args: string[]): Promise<Result<ParseResult, Error>>- 解析命令行参数并执行相应的命令动作。
args: 命令行参数数组(通常是Deno.args)。- 返回一个
Promise,解析为一个Result对象。- 如果成功,
Ok包含ParseResult(一个对象,包含options、args和cmd信息)。 - 如果失败,
Err包含一个Error对象。
- 如果成功,
create_command(option: CommandConfig): CommandConfig
辅助函数,用于更清晰地创建命令配置对象。
option: 一个CommandConfig对象,定义了单个命令的属性。
create_action(action_handler: ActionHandler | string): ActionHandler | string
辅助函数,用于更清晰地创建命令或选项的动作。
action_handler: 可以是一个直接的函数,也可以是一个字符串,格式为modulePath或modulePath:functionName。
CLIConfig 接口
interface CLIConfig {
name: string;
version: string;
description: string;
commands: CommandConfig[];
}CommandConfig 接口
interface CommandConfig {
name: string;
description: string;
alias?: string;
usage?: string | string[];
default?: {
args?: string[];
options?: OptionConfig[];
action: ActionHandler | string;
};
commands?: CommandConfig[];
}OptionConfig 接口
interface OptionConfig {
name: string; // 例如: "-p --port <value:number>"
description?: string;
args?: string[]; // 例如: ["<port1:string>", "[port2:string]"]
alone?: boolean; // 如果为 true,则此选项不能与其他非默认选项一起使用
action?: ActionHandler | string; // 如果定义,将覆盖默认行为
group?: string; // 用于 help 输出中选项的分组
}ActionHandler 类型
type ActionHandler = (options: Record<string, any>, args: any[]) => Promise<void> | void;