mixcli 3.0.0 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +9 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +9 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -7
- package/readme.md +2 -1
- package/src/cli.ts +253 -0
- package/src/command.ts +451 -0
- package/src/finder.ts +142 -0
- package/src/index.ts +4 -0
- package/src/option.ts +102 -0
- package/src/oslocate.js +148 -0
- package/src/prompt.ts +180 -0
- package/src/utils.ts +128 -0
package/dist/index.d.mts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { LiteEvent } from 'flex-tools/events/liteEvent';
|
2
2
|
import { Option, Command } from 'commander';
|
3
3
|
import { PromptObject } from 'prompts';
|
4
|
-
import * as
|
4
|
+
import * as flex_tools_types_asyncFunction from 'flex-tools/types/asyncFunction';
|
5
5
|
|
6
6
|
type PromptType = "text" | "password" | "invisible" | "number" | "confirm" | "list" | "toggle" | "select" | "multiselect" | "autocomplete" | "date" | "autocompleteMultiselect";
|
7
7
|
type PromptParam = 'auto' | boolean | PromptType | PromptObject;
|
@@ -382,10 +382,10 @@ declare function isEnablePrompts(): boolean;
|
|
382
382
|
* @param args
|
383
383
|
*/
|
384
384
|
declare function outputDebug(message: string, ...args: any[]): void;
|
385
|
-
declare const fileExists:
|
386
|
-
declare const readFile:
|
387
|
-
declare const writeFile:
|
388
|
-
declare const mkdir:
|
385
|
+
declare const fileExists: flex_tools_types_asyncFunction.AsyncFunction;
|
386
|
+
declare const readFile: flex_tools_types_asyncFunction.AsyncFunction;
|
387
|
+
declare const writeFile: flex_tools_types_asyncFunction.AsyncFunction;
|
388
|
+
declare const mkdir: flex_tools_types_asyncFunction.AsyncFunction;
|
389
389
|
/**
|
390
390
|
* 基于artTemplate模板生成文件
|
391
391
|
*
|
package/dist/index.d.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { LiteEvent } from 'flex-tools/events/liteEvent';
|
2
2
|
import { Option, Command } from 'commander';
|
3
3
|
import { PromptObject } from 'prompts';
|
4
|
-
import * as
|
4
|
+
import * as flex_tools_types_asyncFunction from 'flex-tools/types/asyncFunction';
|
5
5
|
|
6
6
|
type PromptType = "text" | "password" | "invisible" | "number" | "confirm" | "list" | "toggle" | "select" | "multiselect" | "autocomplete" | "date" | "autocompleteMultiselect";
|
7
7
|
type PromptParam = 'auto' | boolean | PromptType | PromptObject;
|
@@ -382,10 +382,10 @@ declare function isEnablePrompts(): boolean;
|
|
382
382
|
* @param args
|
383
383
|
*/
|
384
384
|
declare function outputDebug(message: string, ...args: any[]): void;
|
385
|
-
declare const fileExists:
|
386
|
-
declare const readFile:
|
387
|
-
declare const writeFile:
|
388
|
-
declare const mkdir:
|
385
|
+
declare const fileExists: flex_tools_types_asyncFunction.AsyncFunction;
|
386
|
+
declare const readFile: flex_tools_types_asyncFunction.AsyncFunction;
|
387
|
+
declare const writeFile: flex_tools_types_asyncFunction.AsyncFunction;
|
388
|
+
declare const mkdir: flex_tools_types_asyncFunction.AsyncFunction;
|
389
389
|
/**
|
390
390
|
* 基于artTemplate模板生成文件
|
391
391
|
*
|
package/dist/index.js
CHANGED
@@ -69,10 +69,10 @@ var require_package = __commonJS({
|
|
69
69
|
"package.json"(exports, module2) {
|
70
70
|
module2.exports = {
|
71
71
|
name: "mixcli",
|
72
|
-
version: "3.0.
|
72
|
+
version: "3.0.2",
|
73
73
|
description: "Develop command line tool scaffolding for monorepo",
|
74
|
-
repository: "https://github.com/zhangfisher/
|
75
|
-
homepage: "https://zhangfisher.github.io/
|
74
|
+
repository: "https://github.com/zhangfisher/mixcli.git",
|
75
|
+
homepage: "https://zhangfisher.github.io/mixcli/",
|
76
76
|
main: "./dist/index.js",
|
77
77
|
module: "./dist/index.mjs",
|
78
78
|
types: "./dist/index.d.ts",
|
@@ -83,6 +83,7 @@ var require_package = __commonJS({
|
|
83
83
|
},
|
84
84
|
files: [
|
85
85
|
"dist",
|
86
|
+
"src",
|
86
87
|
"readme.md",
|
87
88
|
"package.json"
|
88
89
|
],
|
@@ -93,11 +94,11 @@ var require_package = __commonJS({
|
|
93
94
|
"@types/prompts": "^2.4.4",
|
94
95
|
"@voerkai18n/runtime": "^2.0.8",
|
95
96
|
"art-template": "^4.13.2",
|
96
|
-
commander: "^
|
97
|
-
"flex-tools": "^1.3.
|
97
|
+
commander: "^12.0.0",
|
98
|
+
"flex-tools": "^1.3.60",
|
98
99
|
"fs-extra": "^11.1.1",
|
99
|
-
glob: "^10.3.
|
100
|
-
logsets: "^1.3.
|
100
|
+
glob: "^10.3.12",
|
101
|
+
logsets: "^1.3.8",
|
101
102
|
prompts: "^2.4.2",
|
102
103
|
"string.prototype.replaceall": "^1.0.7"
|
103
104
|
},
|
@@ -520,7 +521,7 @@ var MixCommand = class extends import_commander2.Command {
|
|
520
521
|
this._actions.push(actionItem);
|
521
522
|
}
|
522
523
|
} else {
|
523
|
-
console.log("[
|
524
|
+
console.log("[mixcli] action params error");
|
524
525
|
}
|
525
526
|
return super.action(this.getWrapperedAction());
|
526
527
|
}
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/index.ts","../src/cli.ts","../src/command.ts","../src/option.ts","../src/utils.ts","../src/prompt.ts","../src/finder.ts"],"sourcesContent":["{\n \"name\": \"mixcli\",\n \"version\": \"3.0.0\",\n \"description\": \"Develop command line tool scaffolding for monorepo\",\n \"repository\": \"https://github.com/zhangfisher/mixed-cli.git\",\n \"homepage\": \"https://zhangfisher.github.io/mixed-cli/\",\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"scripts\": {\n \"build\": \"tsup\",\n \"build:watch\": \"tsup --watch\",\n \"release\": \"npm publish\"\n },\n \"files\": [\n \"dist\",\n \"readme.md\",\n \"package.json\"\n ],\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"dependencies\": {\n \"@types/prompts\": \"^2.4.4\",\n \"@voerkai18n/runtime\": \"^2.0.8\",\n \"art-template\": \"^4.13.2\",\n \"commander\": \"^11.0.0\",\n \"flex-tools\": \"^1.3.27\",\n \"fs-extra\": \"^11.1.1\",\n \"glob\": \"^10.3.4\",\n \"logsets\": \"^1.3.7\",\n \"prompts\": \"^2.4.2\",\n \"string.prototype.replaceall\": \"^1.0.7\"\n },\n \"devDependencies\": {\n \"@types/fs-extra\": \"^11.0.1\",\n \"@types/node\": \"^20.5.7\",\n \"typescript\": \"^5.2.2\"\n }\n}\n","export * from \"./cli\"\r\nexport * from \"./utils\"\r\nexport * from \"./command\"\r\nexport * from \"./option\"","#!/usr/bin/env node\nimport \"flex-tools/string\"\nimport { LiteEvent, LiteEventSubscriber } from \"flex-tools/events/liteEvent\"\nimport { Command } from \"commander\"\nimport logsets from \"logsets\"\n\nimport { assignObject } from \"flex-tools/object/assignObject\"\nimport { MixCommand } from \"./command\"\nimport { addBuiltInOptions, fixIndent } from './utils';\nimport { findCommands } from \"./finder\"\nimport { asyncSignal } from \"flex-tools/async/asyncSignal\"\n// @ts-ignore\nimport replaceAll from 'string.prototype.replaceall'\nreplaceAll.shim() \n\nexport interface MixCliOptions{\n name:string,\n title?:string | (string | boolean | number)[],\n description?:string,\n version?:string\n // 定义显示帮助信息\n logo?:string ,\n // 在根命令执行前执行==commander的preAction\n before?:(thisCommand:Command,actionCommand:Command)=>void,\n // 在根命令执行后执行==commander的postAction\n after?:(thisCommand:Command,actionCommand:Command)=>void, \n // flexcli运行时会在当前工程的package.json的依赖中查找以prefix/开头的包,然后自动加载其cli目录下的命令\n // 例如:prefix=myapp,则会自动加载flex-cli-xxx包中的cli目录下的命令\n // 如prefix=myapp, cliPath=\"cmds\",则会自动加载flex-cli-xxx包中的cmds目录下的命令\n include?:string | RegExp | string[] | RegExp[],\n // 忽略查找正则表达式\n exclude?:string | RegExp | string[] | RegExp[],\n // flexcli会在当前工程的以prefix/开头下查找命令声明\n // / pattern默认值是cli,即会在当前工程的以prefix/开头的包下查找cli目录下的命令\n // 指定cli所在的目录,默认值是cli,要遍历该目录下的所有js文件作为命令导出\n cliDir?:string \n context?:Record<string,any> // 传递给命令的共享上下文,所有命令均可要使用 \n // 默认是否启用交互提示, auto当没有值时,会根据当前是否在终端中运行来决定是否启用交互提示\n // 为false时,禁用所有交互提示,为true时,启用所有交互提示 \n prompt?:'auto' | boolean \n}\n\n \n \n\nexport type MixCliCommand = (cli:MixCli)=>MixCommand | MixCommand[] | void\n\n\nexport type MixCliEvents = \n \"register\" // 当命令注册时触发\n\nexport class MixCli extends LiteEvent<any,MixCliEvents>{\n options:Required<MixCliOptions> \n root!:Command \n private findSignals:any[]=[]\n constructor(options?:MixCliOptions){\n super()\n this.options= assignObject({\n name:\"mixcli\",\n package:null,\n cliDir:\"cli\",\n prompt:'auto'\n },options) \n this.createRootCommand() \n } \n get context(){return this.options.context}\n get name(){return this.options.name}\n /**\n * 是否禁用了所有的交互提示\n */\n get isDisabledPrompts(){\n return(this.root as any).rawArgs.includes(\"--no-prompts\") \n } \n /**\n * 扫描当前工程的依赖,加载匹配include的依赖下的命令\n */\n private async installCommands(){\n const cmders = await findCommands(this)\n for(let cmder of cmders){\n try{\n if(typeof(cmder)===\"function\"){\n let cmds = cmder(this)\n cmds =cmds ? (Array.isArray(cmds) ? cmds : [cmds]) : []\n this.register(()=>cmds) \n }\n }catch(e:any){\n }\n }\n } \n /**\n * 创建根命令\n * \n */\n private createRootCommand(){\n this.root = new MixCommand(this.name);\n this.root \n .helpOption('-h, --help') \n .version(require(\"../package.json\").version,\"-v, --version\") \n .action(()=>{ \n if(this.options.logo) logsets.log(fixIndent(this.options.logo,2))\n console.log()\n // 显示标题\n let title = this.options.title|| this.options.name\n if(Array.isArray(title)){\n logsets.log(String(title[0]).firstUpper(),[...title.slice(1)])\n }else{\n logsets.log(`${title.firstUpper()} Version: {}`,this.options.version)\n } \n // @ts-ignore\n if(this.options.description) logsets.log(logsets.colors.darkGray(this.options.description)) \n console.log()\n this.root.help() \n }) \n addBuiltInOptions(this.root)\n if(this.options.before) this.root.hook('preAction',this.options.before)\n if(this.options.after) this.root.hook('postAction',this.options.after) \n } \n /**\n * 添加帮助选项\n * \n * @param text 帮助文本\n * @param position 显示位置,可选值:before|after|beforeAll|afterAll\n * @param fixIndent 是否自动修正缩进,如果为true,则会自动修正缩进,当显示多行时文本时,会自动修正缩进\n * \n */\n public addHelp(text:string,{pos='beforeAll',alignIndent=true}:{pos:'before'|'after' | 'beforeAll' | 'afterAll',alignIndent?:boolean | number}){\n if(alignIndent) text = fixIndent(text,alignIndent)\n this.root.addHelpText(pos,text)\n }\n\n /**\n * 注册一个命令\n * @param cmd \n */\n register(cmd:MixCliCommand){\n if(typeof(cmd)==\"function\"){\n let result = cmd(this)\n let cmds = result instanceof Array ? result : (result==undefined ? [] : [result])\n for(let cmd of cmds){\n if(cmd instanceof MixCommand){\n if(this.hasCommand(cmd.name())){\n logsets.error(`Command <${cmd.name()}> has been registered!`)\n }else{\n this.root.addCommand(cmd) ;\n (cmd as any)._cli = this\n this.emit(\"register\",cmd.fullname,true)\n } \n }\n } \n }else{\n logsets.error(\"Invalid command\")\n } \n }\n\n hasCommand(name:string):boolean{\n return this.root.commands.some(c=>c.name()==name)\n }\n\n /**\n * 根据命令名称查找命令\n * \n * @remarks\n * \n * find(\"dev\")\n * find(\"dev.microservice\") 支持多级命令\n * find(\"abc\",DevCommand) 允许指定从DevCommand下开始查找abc命令\n * \n * @param name \n */\n get(name:string):MixCommand | undefined{\n const names=name.split(\".\")\n let curCmd:Command = this.root\n let resultCmd:MixCommand | undefined\n while(names.length>0){\n const topName = names.shift()\n const r = curCmd.commands.find(c=>c.name()==topName) as MixCommand\n if(r && names.length==0){\n resultCmd = r\n }\n curCmd = r\n } \n return resultCmd \n }\n /**\n * 查找一个命令\n * \n * 如果命令不存在,则等待命令注册后再返回\n * \n * 在多包场景下,如果命令在其他包中注册并且该包中的命令还没注册,则会等待命令注册后再返回\n * \n * @param name \n * @returns \n */\n find(name:string):Promise<MixCommand | undefined>{\n const cmd = this.get(name)\n if(cmd){\n return Promise.resolve(cmd) \n }else{\n const signal = asyncSignal()\n this.findSignals.push(signal)\n return new Promise<MixCommand | undefined>((resolve)=>{\n let listener:LiteEventSubscriber\n listener = this.on(\"register\",(fullname:string)=>{\n if(fullname==`${this.name}.${name}`){\n listener.off()\n signal.resolve()\n this.findSignals = this.findSignals.filter(s=>s!=signal)\n resolve(this.get(name))\n }\n },{objectify:true}) as LiteEventSubscriber\n })\n } \n }\n /**\n * 判断命令是否存在\n * \n * @param name \n * @returns \n */\n exists(name:string):boolean{\n if(name in this.root.commands){\n return true\n }else{\n return this.get(name) != undefined\n }\n } \n \n /**\n * 运行命令行程序\n */\n run(){ \n // 为什么有findSignal这玩意,解决什么问题?\n // 当我们要扩展command时,通过get(\"命令名称\")来获取已经注册的命令的方式有个缺陷\n // 就是如果对命令的注册顺序有严格的要求,比如调用get('dev')时要求dev命令必须已经存在\n // 这对动态包的命令注册扩展开发体验不好\n // 所以引入find(\"命令名称\")来获取命令,该方法可以获取到后注册的命令\n // 其副作用是,在run时,可能find还没有运行到,从而导致在帮助信息里面看不到扩展的信息(实际上是已经生效的)\n // 所以我们在find里面注入一个异步信号来解决此问题\n this.installCommands().then(()=>{\n return Promise.all(this.findSignals.map(signal=>signal(10000))).then(()=>{\n this.root.parseAsync(process.argv); \n })\n }) \n }\n /**\n * 创建一个命令\n * \n * \n */\n create(){\n }\n}\n ","import { Command, Option } from \"commander\";\r\nimport prompts, { PromptObject } from \"prompts\";\r\nimport { MixOption, type MixedOptionParams } from \"./option\";\r\nimport { addBuiltInOptions, isEnablePrompts, outputDebug } from \"./utils\";\r\nimport path from \"node:path\";\r\nimport fs from \"node:fs\";\r\nimport type { AsyncFunction } from \"flex-tools\";\r\n\r\nexport type ICommandHookListener = ({\r\n\targs,\r\n\toptions,\r\n\tcommand,\r\n}: {\r\n\targs: any[];\r\n\toptions: Record<string, any>;\r\n\tcommand: MixCommand;\r\n}) => void | Promise<void>;\r\n\r\nexport type BeforeCommandHookListener = ({\r\n\targs,\r\n\toptions,\r\n\tcommand,\r\n}: {\r\n\targs: any[];\r\n\toptions: Record<string, any>;\r\n\tcommand: MixCommand;\r\n}) => void | Promise<void>;\r\nexport type AfterCommandHookListener = ({\r\n\tvalue,\r\n\targs,\r\n\toptions,\r\n\tcommand,\r\n}: {\r\n\tvalue: any;\r\n\targs: any[];\r\n\toptions: Record<string, any>;\r\n\tcommand: MixCommand;\r\n}) => void | Promise<void>;\r\n\r\nexport interface ActionOptions {\r\n\tid: string;\r\n\tat: \"replace\" | \"before\" | \"after\" | \"preappend\" | \"append\" | number;\r\n\t// 函数签名类型,即采用原始的commander的action函数签名,还是mixed-cli的action函数签名\r\n\tenhance: boolean;\r\n}\r\n\r\nexport interface ActionRegistry extends Omit<ActionOptions, \"at\"> {\r\n\tfn: Function;\r\n}\r\n\r\n// 原始的Action动作函数\r\nexport type OriginalAction = (...args: any[]) => void | Promise<void>;\r\n// 增强的Action函数签名\r\nexport type EnhanceAction = ({\r\n\targs,\r\n\toptions,\r\n\tvalue,\r\n\tcommand,\r\n}: {\r\n\targs: any[];\r\n\toptions: Record<string, any>;\r\n\tvalue: any;\r\n\tcommand: MixCommand;\r\n}) => void | Promise<any>;\r\n\r\n// 执行action的返回结果\r\nexport const BREAK = Symbol(\"BREAK_ACTION\"); // 中止后续的action执行\r\n\r\nexport class MixCommand extends Command {\r\n\tprivate _beforeHooks: [BeforeCommandHookListener, boolean][] = [];\r\n\tprivate _afterHooks: [AfterCommandHookListener, boolean][] = [];\r\n\tprivate _customPrompts: PromptObject[] = [];\r\n\tprivate _optionValues: Record<string, any> = {}; // 命令行输入的选项值\r\n\tprivate _actions: ActionRegistry[] = []; // 允许多个action\r\n\tprivate _enable_prompts: boolean = true; // 是否启用交互提示\r\n\tconstructor(name?: string) {\r\n\t\tsuper(name);\r\n\t\tconst self = this;\r\n\t\tif (!this.isRoot) addBuiltInOptions(this);\r\n\t\tthis.hook(\"preAction\", async function (this: any) {\r\n\t\t\tself._optionValues = self.getOptionValues(this.hookedCommand);\r\n\t\t\ttry {\r\n\t\t\t\t// @ts-ignore\r\n\t\t\t\tawait self.preActionHook.apply(self, arguments);\r\n\t\t\t} catch {}\r\n\t\t});\r\n\t}\r\n\t/**\r\n\t * 是否是根命令\r\n\t */\r\n\tget isRoot() {\r\n\t\treturn !!!this.parent;\r\n\t}\r\n\tget actions() {\r\n\t\treturn this._actions;\r\n\t}\r\n\tget beforeHooks() {\r\n\t\treturn this._beforeHooks;\r\n\t}\r\n\tget afterHooks() {\r\n\t\treturn this._afterHooks;\r\n\t}\r\n\tget fullname() {\r\n\t\tlet names = [this.name()];\r\n\t\tlet parent = this.parent;\r\n\t\twhile (parent) {\r\n\t\t\tif (parent.name() !== \"root\") {\r\n\t\t\t\tnames.unshift(parent.name());\r\n\t\t\t}\r\n\t\t\tparent = parent.parent;\r\n\t\t}\r\n\t\treturn names.join(\".\");\r\n\t}\r\n\r\n\t/**\r\n\t * 返回根命令\r\n\t */\r\n\troot() {\r\n\t\tlet root: MixCommand | null | undefined = this;\r\n\t\twhile (root && root.parent != null) {\r\n\t\t\troot = root.parent as unknown as MixCommand;\r\n\t\t}\r\n\t\treturn root;\r\n\t}\r\n\taction(fn: EnhanceAction, options: ActionOptions): this;\r\n\taction(fn: OriginalAction): this;\r\n\taction(fn: OriginalAction): this {\r\n\t\tconst actionFunc = arguments[0];\r\n\t\tif (arguments.length == 1 && typeof actionFunc == \"function\") {\r\n\t\t\t// 原始方式\r\n\t\t\tthis._actions.push({\r\n\t\t\t\tid: Math.random().toString(36).substring(2),\r\n\t\t\t\tenhance: false,\r\n\t\t\t\tfn: actionFunc,\r\n\t\t\t});\r\n\t\t} else if (\r\n\t\t\targuments.length == 2 &&\r\n\t\t\ttypeof actionFunc == \"function\" &&\r\n\t\t\ttypeof arguments[1] == \"object\"\r\n\t\t) {\r\n\t\t\t// 增强模式\r\n\t\t\tconst actionFn = arguments[0];\r\n\t\t\tconst actionOpts: ActionOptions = Object.assign({ at: \"append\" }, arguments[1]);\r\n\t\t\tif (actionOpts.at == \"replace\") this._actions = [];\r\n\t\t\tconst actionItem = {\r\n\t\t\t\tid: actionOpts.id || Math.random().toString(36).substring(2),\r\n\t\t\t\tenhance: actionOpts.enhance == undefined ? true : actionOpts.enhance,\r\n\t\t\t\tfn: actionFn,\r\n\t\t\t} as const;\r\n\t\t\tif (typeof actionOpts.at == \"number\") {\r\n\t\t\t\tthis._actions.splice(Number(actionOpts.at), 0, actionItem);\r\n\t\t\t} else if ([\"append\", \"before\"].includes(actionOpts.at)) {\r\n\t\t\t\tthis._actions.push(actionItem);\r\n\t\t\t} else if ([\"preappend\", \"after\"].includes(actionOpts.at)) {\r\n\t\t\t\tthis._actions.splice(0, 0, actionItem);\r\n\t\t\t} else {\r\n\t\t\t\tthis._actions.push(actionItem);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tconsole.log(\"[mixed-cli] action params error\");\r\n\t\t}\r\n\t\treturn super.action(this.getWrapperedAction());\r\n\t}\r\n\r\n\t/**\r\n\t * 读取命令配置值,包括父命令提供的配置选项\r\n\t * @param command\r\n\t */\r\n\tprivate getOptionValues(command: Command) {\r\n\t\tlet opts = {};\r\n\t\tlet parent: Command | null = command;\r\n\t\twhile (parent) {\r\n\t\t\tObject.assign(opts, (parent as MixCommand)._optionValues);\r\n\t\t\tparent = parent.parent;\r\n\t\t}\r\n\t\treturn opts;\r\n\t}\r\n\t/**\r\n\t * 本函数在运行时子类进行action生成该命令的action\r\n\t */\r\n\tprivate getWrapperedAction() {\r\n\t\treturn this.wrapperWorkDirsAction(this.wrapperChainActions());\r\n\t}\r\n\r\n\t/**\r\n\t * 向上查找所有祖先命令\r\n\t */\r\n\tprivate getAncestorCommands(): MixCommand[] {\r\n\t\tlet cmds: MixCommand[] = [];\r\n\t\tlet cmd: MixCommand | null = this;\r\n\t\twhile (cmd) {\r\n\t\t\tcmd = cmd.parent as MixCommand;\r\n\t\t\tif (cmd) {\r\n\t\t\t\tcmds.push(cmd);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn cmds;\r\n\t}\r\n\t/***\r\n\t * 将所有actions包装成一个链式调用的函数\r\n\t */\r\n\tprivate wrapperChainActions() {\r\n\t\tconst self = this;\r\n\t\treturn async function (this: any) {\r\n\t\t\tconst args = Array.from(arguments); // 原始输入的参数\r\n\t\t\tlet preValue: any; // 保存上一个action的返回值\r\n\t\t\t//解析参数, 0-1个参数为options,最后一个参数为command\r\n\t\t\tlet actionOpts: Record<string, any> = {},\r\n\t\t\t\tactionArgs: any[] = [],\r\n\t\t\t\tcmd: any;\r\n\t\t\tif (args.length >= 2) {\r\n\t\t\t\tcmd = args[args.length - 1]; // 最后一个command\r\n\t\t\t\tactionOpts = args[args.length - 2];\r\n\t\t\t\tactionArgs = args.slice(0, args.length - 2);\r\n\t\t\t}\r\n\t\t\tawait self.executeBeforeHooks({ args: actionArgs, options: actionOpts, command: cmd });\r\n\t\t\ttry {\r\n\t\t\t\tfor (let action of self._actions) {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tif (action.enhance) {\r\n\t\t\t\t\t\t\t// 增强模式\r\n\t\t\t\t\t\t\toutputDebug(\"执行<{}>: args={}, options={}\", () => [\r\n\t\t\t\t\t\t\t\tself.name(),\r\n\t\t\t\t\t\t\t\tactionArgs,\r\n\t\t\t\t\t\t\t\tactionOpts,\r\n\t\t\t\t\t\t\t]);\r\n\t\t\t\t\t\t\tpreValue = await action.fn.call(this, {\r\n\t\t\t\t\t\t\t\tcommand: cmd,\r\n\t\t\t\t\t\t\t\tvalue: preValue,\r\n\t\t\t\t\t\t\t\targs: actionArgs,\r\n\t\t\t\t\t\t\t\toptions: actionOpts,\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t// 原始模式\r\n\t\t\t\t\t\t\tpreValue = await action.fn.apply(this, args);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (preValue === BREAK) break;\r\n\t\t\t\t\t} catch (e) {\r\n\t\t\t\t\t\toutputDebug(\"命令{}的Action({})执行出错:{}\", [self.name, action.id, e]);\r\n\t\t\t\t\t\tthrow e;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} finally {\r\n\t\t\t\tawait self.executeAfterHooks({\r\n\t\t\t\t\tvalue: preValue,\r\n\t\t\t\t\targs: actionArgs,\r\n\t\t\t\t\toptions: actionOpts,\r\n\t\t\t\t\tcommand: cmd,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t};\r\n\t}\r\n\t/**\r\n\t * 当传入--work-dirs时用来处理工作目录\r\n\t */\r\n\tprivate wrapperWorkDirsAction(fn: AsyncFunction) {\r\n\t\tconst self = this;\r\n\t\treturn async function (this: any) {\r\n\t\t\tlet workDirs = self._optionValues.workDirs;\r\n\t\t\t// 未指定工作目录参数\r\n\t\t\tif (!workDirs) {\r\n\t\t\t\treturn await fn.apply(this, Array.from(arguments));\r\n\t\t\t}\r\n\t\t\tif (!Array.isArray(workDirs)) workDirs = workDirs.split(\",\");\r\n\t\t\tworkDirs = workDirs.reduce((dirs: any[], dir: string) => {\r\n\t\t\t\tif (typeof dir == \"string\") dirs.push(...dir.split(\",\"));\r\n\t\t\t\treturn dirs;\r\n\t\t\t}, []);\r\n\t\t\tfor (let workDir of workDirs) {\r\n\t\t\t\tconst cwd = process.cwd();\r\n\t\t\t\ttry {\r\n\t\t\t\t\tif (!path.isAbsolute(workDir)) workDir = path.join(cwd, workDir);\r\n\t\t\t\t\tif (fs.existsSync(workDir) && fs.statSync(workDir).isDirectory()) {\r\n\t\t\t\t\t\toutputDebug(\"切换到工作目录:{}\", workDir);\r\n\t\t\t\t\t\tprocess.chdir(workDir); // 切换\r\n\t\t\t\t\t\tawait fn.apply(this, Array.from(arguments));\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\toutputDebug(\"无效的工作目录:{}\", workDir);\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\tthrow e;\r\n\t\t\t\t} finally {\r\n\t\t\t\t\tprocess.chdir(cwd);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t};\r\n\t}\r\n\tgetOption(name: string): MixOption {\r\n\t\treturn this.options.find((option) => option.name() == name) as unknown as MixOption;\r\n\t}\r\n\t/**\r\n\t * 添加一个Before钩子\r\n\t * @param listener\r\n\t * @param scope =false时代表只在本命令执行,=true时代表在本命令及其子命令执行\r\n\t * @returns\r\n\t */\r\n\tbefore(listener: BeforeCommandHookListener, scope: boolean = true) {\r\n\t\tthis._beforeHooks.push([listener, scope]);\r\n\t\treturn this;\r\n\t}\r\n\tprivate async executeBeforeHooks(args: any) {\r\n\t\tconst hooks: [BeforeCommandHookListener, boolean, MixCommand][] = this.beforeHooks.map(\r\n\t\t\t([hook, scope]) => [hook, scope, this]\r\n\t\t);\r\n\t\tthis.getAncestorCommands().forEach((cmd: MixCommand) => {\r\n\t\t\thooks.unshift(\r\n\t\t\t\t...cmd.beforeHooks.map(([hook, scope]) => {\r\n\t\t\t\t\treturn [hook, scope, cmd] as [BeforeCommandHookListener, boolean, MixCommand];\r\n\t\t\t\t})\r\n\t\t\t);\r\n\t\t});\r\n\t\tfor (let [hook, scope, cmd] of hooks) {\r\n\t\t\tif (!scope) continue;\r\n\t\t\tawait hook.call(cmd, args);\r\n\t\t}\r\n\t}\r\n\t/**\r\n\t * 添加一个After钩子\r\n\t * @param listener\r\n\t * @param scope =false时代表只在本命令执行,=true时代表在本命令及其子命令执行\r\n\t * @returns\r\n\t */\r\n\tafter(listener: AfterCommandHookListener, scope: boolean = true) {\r\n\t\tthis._afterHooks.push([listener, scope]);\r\n\t\treturn this;\r\n\t}\r\n\tprivate async executeAfterHooks(args: any) {\r\n\t\tconst hooks: [AfterCommandHookListener, boolean, MixCommand][] = this.afterHooks.map(\r\n\t\t\t([hook, scope]) => [hook, scope, this]\r\n\t\t);\r\n\t\tthis.getAncestorCommands().forEach((cmd: MixCommand) => {\r\n\t\t\thooks.push(\r\n\t\t\t\t...cmd.afterHooks.map(([hook, scope]) => {\r\n\t\t\t\t\treturn [hook, scope, cmd] as [BeforeCommandHookListener, boolean, MixCommand];\r\n\t\t\t\t})\r\n\t\t\t);\r\n\t\t});\r\n\t\tfor (let [hook, scope, cmd] of hooks) {\r\n\t\t\tif (!scope) continue; //=false时不执行\r\n\t\t\tawait hook.call(cmd, args);\r\n\t\t}\r\n\t}\r\n\tprivate async preActionHook(thisCommand: Command, actionCommand: Command) {\r\n\t\tif (this.isEnablePrompts()) {\r\n\t\t\t// 自动生成提示\r\n\t\t\tconst questions: PromptObject[] = [\r\n\t\t\t\t...this.generateAutoPrompts(),\r\n\t\t\t\t...this._customPrompts,\r\n\t\t\t];\r\n\t\t\t// 用户提示\r\n\t\t\tif (questions.length > 0) {\r\n\t\t\t\tconst results = await prompts(questions);\r\n\t\t\t\tObject.entries(results).forEach(([key, value]) => {\r\n\t\t\t\t\tthisCommand.setOptionValue(key, value);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tprivate isEnablePrompts() {\r\n\t\tif (isEnablePrompts() === false) {\r\n\t\t\t// 命令行参数禁用了提示,优先级最高\r\n\t\t\treturn false;\r\n\t\t} else {\r\n\t\t\treturn this._enable_prompts;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 生成选项自动提示\r\n\t *\r\n\t * @remarks\r\n\t * FlexCli要求所有未提供默认值的Option自动生成提示\r\n\t *\r\n\t * - 未提供默认值,并且是必选的参数Option\r\n\t * - 指定了choices但未提供有效值的Option\r\n\t *\r\n\t */\r\n\tprivate generateAutoPrompts(): PromptObject[] {\r\n\t\tconst options = this.options as unknown as MixOption[];\r\n\t\tconst optionPromports = options\r\n\t\t\t.filter((option) => !option.hidden && option instanceof MixOption)\r\n\t\t\t.map((option) => option.getPrompt(this._optionValues[option.name()]))\r\n\t\t\t.filter((prompt) => prompt) as PromptObject[];\r\n\t\toutputDebug(\"命令<{}>自动生成{}个选项提示:{}\", [\r\n\t\t\tthis.name(),\r\n\t\t\toptionPromports.length,\r\n\t\t\toptionPromports.map((prompt) => `${prompt.name}(${prompt.type})`).join(\",\"),\r\n\t\t]);\r\n\t\treturn optionPromports;\r\n\t}\r\n\toption(flags: string, description?: string | undefined, defaultValue?: any): this;\r\n\toption(flags: string, description?: string | undefined, options?: MixedOptionParams): this {\r\n\t\t// @ts-ignore\r\n\t\tconst option = new MixOption(...arguments);\r\n\t\tif (option.required && !this.isEnablePrompts()) option.mandatory = true;\r\n\t\treturn this.addOption(option as unknown as Option);\r\n\t}\r\n\r\n\t/**\r\n\t * 添加提示\r\n\t *\r\n\t * @remarks\r\n\t *\r\n\t * 添加一些自定义提示\r\n\t *\r\n\t *\r\n\t * @param questions\r\n\t * @param show 是否显示提示信息,auto表示只有在用户没有提供option的值时才显示提示信息,always表示总是显示提示信息,never表示不显示提示信息\r\n\t * @returns\r\n\t */\r\n\tprompt(questions: PromptObject | PromptObject[]) {\r\n\t\tthis._customPrompts.push(...(Array.isArray(questions) ? questions : [questions]));\r\n\t\treturn this;\r\n\t}\r\n\t/**\r\n\t *\r\n\t * 选择命令并执行\r\n\t *\r\n\t * @remorks\r\n\t *\r\n\t * 当命令具有多个子命令时,并且没有提供默认子命令时,提示用户选择一个子命令\r\n\t *\r\n\t */\r\n\tasync selectCommands() {\r\n\t\tconst choices = this.commands.map((command) => ({\r\n\t\t\ttitle: `${command.description()}(${command.name()})`,\r\n\t\t\tvalue: command.name(),\r\n\t\t}));\r\n\t\tconst result = await prompts({\r\n\t\t\ttype: \"select\",\r\n\t\t\tname: \"command\",\r\n\t\t\tmessage: \"请选择命令:\",\r\n\t\t\tchoices,\r\n\t\t});\r\n\t\t// 重新解析命令行参数标志,\r\n\t\tconst command = this.commands.find((command) => command.name() === result.command);\r\n\t\tawait command?.parseAsync([result.command], { from: \"user\" });\r\n\t}\r\n\t/**\r\n\t * 禁用/启用所有提示\r\n\t */\r\n\tdisablePrompts() {\r\n\t\tthis._enable_prompts = false;\r\n\t\treturn this;\r\n\t}\r\n\tenablePrompts() {\r\n\t\tthis._enable_prompts = true;\r\n\t\treturn this;\r\n\t}\r\n}\r\n","import { Option } from 'commander'\nimport { PromptObject } from 'prompts'\nimport { IPromptable, IPromptableOptions, PromptChoice, PromptManager } from './prompt'\n\n\nexport interface MixedOptionParams extends IPromptableOptions{\n hidden?:boolean\n defaultDescription?:string // 默认值的描述 \n conflicts?:string | string[]\n env?:string\n argParser?:<T>(value: string, previous: T) => T \n hideHelp?:boolean\n mandatory?: boolean \n implies?:{[key:string]:any} \n}\n\n\nexport class MixOption extends Option implements IPromptable{\n // 是否提示用户输入\n prompt?: PromptManager \n promptChoices?:PromptChoice[]\n private _validate?: (value: any) => boolean \n constructor(flags: string, description?: string | undefined,optsOrDefault?:any) {\n super(flags, description)\n let params:MixedOptionParams = {}\n if(arguments.length==3 && typeof arguments[2] == \"object\"){\n params = Object.assign({ },arguments[2]) \n }else if(arguments.length==3){\n params.default = arguments[2]\n }\n if(params.prompt===undefined) params.prompt = 'auto'\n if(params.default) this.default(params.default,params.defaultDescription)\n if(params.choices) this.choices(params.choices)\n if(params.conflicts) this.conflicts(params.conflicts)\n if(params.env) this.env(params.env)\n if(params.argParser) this.argParser(params.argParser)\n if(params.hideHelp) this.hideHelp(params.hideHelp)\n if(params.hidden) this.hidden = params.hidden\n if(params.mandatory) this.makeOptionMandatory(params.mandatory)\n if(params.implies) this.implies(params.implies) \n if(params.optional) this.optional=params.optional\n if(typeof(params.validate)=='function') this._validate = params.validate.bind(this)\n if(params.required) {\n this.required = params.required\n if(!this._validate ) this._validate = (value:any)=>String(value).length>0\n }\n this.prompt = new PromptManager(this as IPromptable,params.prompt)\n } \n validate(value: any): boolean {\n if(typeof(this._validate)=='function'){\n return this._validate(value)\n }else{\n return true\n }\n }\n // @ts-ignore\n choices(values:(PromptChoice | string)[]){\n if(!this.promptChoices){\n this.promptChoices = values.map(choice=>{\n if(typeof(choice)=='object'){\n return choice\n }else{\n return {title:choice,value:choice} \n }\n })\n } \n super.choices(this.promptChoices.map((item:any)=>item.value)) \n } \n\n private resetChoices(){\n super.choices(this.promptChoices!.map((item:any)=>item.value)) \n }\n\n addChoice(value:PromptChoice | string){\n if(!this.promptChoices || !Array.isArray(this.promptChoices)) this.promptChoices = []\n this.promptChoices!.push(typeof(value)=='string' ? {title:value,value} : value)\n this.resetChoices()\n }\n removeChoice(value:any){\n this.promptChoices =this.promptChoices?.filter(choice=>choice.value!==value)\n this.resetChoices()\n }\n clearChoice(){\n this.promptChoices = []\n this.resetChoices()\n }\n\n \n /**\n * 返回选项的提示对象\n * \n * @remarks\n * \n *\n * \n * @param inputValue \n * @returns \n */\n getPrompt(inputValue?:any): PromptObject | undefined {\n return this.prompt?.get(inputValue)\n } \n}","import artTemplate from \"art-template\"\r\nimport fs from \"fs-extra\"\r\nimport path from \"node:path\"\r\nimport { promisify } from \"flex-tools/func/promisify\"\r\nimport logsets from \"logsets\" \r\n/**\r\n * \r\n * 在控制台输出一个字符串\r\n * 本方法会将字符串中的每一行空格去掉\r\n * \r\n * @remarks\r\n * \r\n * outputStr(String.raw`\r\n * a\r\n * b`)\r\n * \r\n * 会输出\r\n * a\r\n * b\r\n *\r\n * 此功能可以用于输出多行字符串时,保持代码的缩进格式,而不会影响输出结果\r\n * \r\n * @param str : 要输出的字符串\r\n * @param vars : 用于替换字符串中的变量\r\n * \r\n */\r\nexport function outputStr(str:string,vars?:Record<string,any> | any[]){ \r\n logsets.log(fixIndent(str),vars)\r\n}\r\n\r\n/**\r\n * 修正多行字符串的缩进\r\n * \r\n * @param text \r\n * @param indent \r\n * @returns \r\n */\r\nexport function fixIndent(text:string,indent?:boolean | number):string{\r\n let indentValue = (indent==undefined || indent===true) ? 0 : (typeof(indent)=='number' ? indent : -1)\r\n if(indentValue==-1) return text // 不修正缩进\r\n let lines:string[] = text.split(\"\\n\")\r\n let minSpaceCount = lines.reduce<number>((minCount,line,index)=>{\r\n if(index==0) return minCount\r\n const spaceCount = line.match(/^\\s*/)?.[0].length || 0\r\n return Math.min(minCount,spaceCount)\r\n },9999)\r\n lines = lines.map(line=>line.substring(minSpaceCount))\r\n return lines.join(\"\\n\")\r\n}\r\n\r\n/**\r\n * 增加内置选项\r\n * @param command \r\n */\r\nexport function addBuiltInOptions(command:any){ \r\n command.option(\"--work-dirs <values...>\",\"指定工作目录\",{hidden:true,optional:true,required:true,prompt:false})\r\n command.option(\"--disable-prompts\",\"禁用所有交互提示\",{hidden:true,prompt:false}) \r\n command.option(\"--debug-cli\",\"显示调试信息\",{hidden:true,prompt:false})\r\n}\r\n\r\n\r\n/**\r\n * 是否命令行中包含了--debug-cli选项\r\n */\r\nexport function isDebug(){\r\n return process.argv.includes(\"--debug-cli\")\r\n}\r\nexport function isEnablePrompts(){ \r\n return !process.argv.includes(\"--disable-prompts\")\r\n}\r\n\r\n/**\r\n * 打印调试信息\r\n * @param message \r\n * @param args \r\n */\r\nexport function outputDebug(message:string,...args:any[]){ \r\n let vars = (args.length == 1 && typeof(args[0])=='function') ? args[0]() : args\r\n if(isDebug()) logsets.log(`[MixCli] ${message}`,...vars)\r\n}\r\n\r\nexport const fileExists = promisify(fs.exists,{\r\n parseCallback:(results)=>{\r\n return results[0]\r\n }\r\n})\r\nexport const readFile = promisify(fs.readFile)\r\nexport const writeFile = promisify(fs.writeFile)\r\nexport const mkdir = promisify(fs.mkdir)\r\n\r\n/**\r\n * 基于artTemplate模板生成文件\r\n * \r\n * @param {*} tmplFile \r\n * @param {*} vars \r\n */\r\nexport async function createFileByTemplate(targetFile:string,tmplFile:string,vars:Record<string,any>={}){\r\n tmplFile=path.isAbsolute(tmplFile)? tmplFile : path.join(process.cwd(),tmplFile)\r\n if(!fs.existsSync(tmplFile)){\r\n throw new Error(\"模板文件不存在:\"+tmplFile)\r\n }\r\n targetFile=path.isAbsolute(targetFile)? targetFile : path.join(process.cwd(),targetFile)\r\n const outPath = path.dirname(targetFile)\r\n if(!await fileExists(outPath)){\r\n await mkdir(outPath,{recursive:true})\r\n } \r\n const template = artTemplate(tmplFile,await readFile(tmplFile,{encoding:\"utf-8\"})); \r\n await writeFile(targetFile,template(vars),{encoding:\"utf-8\"})\r\n return targetFile\r\n}\r\n\r\n/** \r\n * 创建目录 \r\n * \r\n * \r\n * \r\n * @param {String[]} dirs 要创建的目录列表,类型为字符串数组 \r\n * @param callback 创建目录过程中的回调函数,类型为异步函数,接收一个参数 dir,表示当前正在创建的目录 \r\n * @returns 该函数返回一个 Promise 对象,表示创建目录的操作是否完成 \r\n */\r\nexport async function mkDirs(dirs:string[],{callback,base}:{callback?:Function,base?:string}){\r\n if(!Array.isArray(dirs)) throw new Error(\"dirs参数必须为字符串数组\")\r\n for(let dir of dirs){\r\n if(!path.isAbsolute(dir)) dir = path.join(base || process.cwd(),dir)\r\n if(typeof(callback)=='function') callback(dir)\r\n await mkdir(dir,{recursive:true})\r\n }\r\n}","import { PromptObject } from \"prompts\" \nimport { outputDebug } from \"./utils\"\n \n\nexport type PromptType = \"text\" | \"password\" | \"invisible\" | \"number\"| \"confirm\"| \"list\"| \"toggle\"| \"select\" | \"multiselect\" | \"autocomplete\" | \"date\" | \"autocompleteMultiselect\"\n\nexport type PromptParam = 'auto' | boolean | PromptType | PromptObject\nexport type InputPromptParam = PromptParam | ((value:any)=>PromptParam) | boolean\nexport type PromptParamDefaultValue = string | boolean | string[] \n\nexport const promptTypeMap:Record<string,string> = {\n boolean:\"confirm\",\n string:\"text\",\n number:\"number\", \n array:\"list\", \n} \n\nexport const supportedPromptTypes = [\"text\",\"password\",\"invisible\", \"number\", \"confirm\" , \"list\", \"toggle\" , \"select\" , \"multiselect\" , \"autocomplete\" , \"date\" , \"autocompleteMultiselect\"]\nexport interface PromptChoice {\n title: string;\n value?: any;\n disabled?: boolean | undefined;\n selected?: boolean | undefined;\n description?: string | undefined;\n}\n\n\n\nexport interface IPromptableOptions{\n required?: boolean; // A value must be supplied when the option is specified.\n optional?: boolean; // A value is optional when the option is specified.\n default?:PromptParamDefaultValue\n choices?:(PromptChoice | any)[] // 选项值的可选值\n prompt?:InputPromptParam\n validate?:(value: any) => boolean\n}\n\n\nexport interface IPromptable{\n name():string \n description?:string\n flags:string\n promptChoices?:PromptChoice[]\n argChoices?:string[]\n variadic?:boolean\n defaultValue?:PromptParamDefaultValue\n input?:any \n required?:boolean\n validate?: (value: any) => boolean \n getPrompt(inputValue?:any):PromptObject | undefined \n}\n\n/**\n * 供command.option()使用的参数对象\n */\nexport interface PromptableObject{\n \n\n}\n\n\n/**\n * 负责生成prompt对象\n * \n */\nexport class PromptManager{\n args:InputPromptParam \n private _promptable:IPromptable // 对应的FlexOption或FlexArgument\n constructor(promptable:IPromptable,promptArgs?:InputPromptParam){ \n this._promptable = promptable\n this.args= promptArgs===undefined ? 'auto' : promptArgs\n }\n\n /**\n * 返回输入的是否是有效的prompt类型\n * @param type \n * @returns \n */\n isValid(type:any){\n return supportedPromptTypes.includes(String(type))\n }\n /**\n * 推断是否需要提示\n * \n */\n isNeed(input:any,defaultValue?:any){\n \n const promptArg = this.args\n const inputValue = input || defaultValue\n // 是否有输入值,即在命令行输入了值\n const hasInput = !(inputValue === undefined)\n // 1. 显式指定了_prompt为true,则需要提示,后续进行提示类型的推断,可能不会准确\n if(promptArg===true) return true\n if(promptArg===false) return false \n\n // 2. 提供了一个prompt对象,并且没有在命令行输入值,则需要提示\n if(typeof(promptArg)=='object'){\n return !hasInput\n }\n\n // 3. 指定了内置的prompt类型,如prompt='password',则使用password类型提示输入\n if(typeof(promptArg) == 'string' && supportedPromptTypes.includes(promptArg)){\n return !hasInput\n }\n \n // 4. 判断输入是否有效,则显示提示\n if(this._promptable.argChoices && this._promptable.argChoices.indexOf(inputValue) == -1){\n return true\n } \n return !hasInput\n }\n /**\n * 返回生成prompt对象\n * \n * @param inputValue 从命令行输入的值\n */\n get(inputValue?:any){\n const {description,promptChoices,validate,defaultValue} = this._promptable\n let input = inputValue || defaultValue\n // 判断是否需要输入提示\n if(!this.isNeed(input,defaultValue)) return\n // 推断prompt类型\n let promptType = this.infer(inputValue)\n const prompt = {\n type:promptType, \n name:this._promptable.name(),\n message:description,\n initial: input,\n ...typeof(this.args) == 'object' ? this.args : {}\n } as PromptObject\n // 指定了验证函数,用来验证输入值是否有效\n prompt.validate = validate?.bind(this._promptable)\n if(promptType=='multiselect') prompt.instructions=false\n if(['select','multiselect'].includes(promptType)){\n let index = promptChoices?.findIndex(item=>item.value==input)\n prompt.initial = index==-1 ? undefined : index\n } \n // 选项值的可选值\n if(Array.isArray(promptChoices)) {\n prompt.choices =promptChoices\n }\n return prompt\n }\n /**\n * 推断prompt类型\n * \n * @param inputValue 从命令行输入的值\n */\n infer(inputValue?:any){\n const {argChoices,variadic,defaultValue} = this._promptable\n let input = inputValue || defaultValue\n // 如果选择指定了\"-p [value]或[value...]\",则使用text类型,如果没有要求输入值,则使用confirm类型\n let promptType = /(\\<[\\w\\.]+\\>)|(\\[[\\w\\.]+\\])/.test(this._promptable.flags) ? 'text' : 'confirm'\n let promptArg = this.args\n if(this.isValid(promptArg)){ // 显式指定了prompt类型\n promptType = promptArg as string\n }else{ // 未显式指定prompt类型,需要按一定规则推断类型\n if(typeof(promptArg)=='object'){\n promptType = promptArg.type as string\n }else{\n if(argChoices){ // 提供多个可选值时\n promptType = variadic ? 'multiselect' : 'select'\n }else{\n const datatype:string = Array.isArray(defaultValue) ? 'array' : typeof(defaultValue) \n // 如果输入值班是数组,则使用list类型,允许使用逗号分隔的多个值\n if(Array.isArray(input) || variadic){\n promptType = \"list\"\n }else{\n if(datatype in promptTypeMap){\n promptType = promptTypeMap[datatype]\n }\n }\n }\n }\n }\n outputDebug(\"选项<{}> -> 提示类型<{}>\",[this._promptable.name(),promptType])\n return promptType\n }\n\n}","import { getPackageRootPath } from 'flex-tools';\r\nimport type { MixCli } from './cli';\r\nimport { globSync } from 'glob'\r\nimport { MixCliCommand } from './cli';\r\nimport { isDebug, outputDebug } from './utils';\r\nimport fs from \"node:fs\"\r\nimport path from \"node:path\"\r\nimport { getPackageJson } from \"flex-tools/package/getPackageJson\"\r\n\r\n/**\r\n * \r\n * 在当前工程中查找符合FlexCli.prefix约定的命令 \r\n * \r\n * - 读取当前包的package.json\r\n * - 找出所有以cli.prefix开头的依赖\r\n * - 加载这些依赖的目录下的匹配cli.pattern的命令\r\n * - 加载加载这样命令\r\n * \r\n */\r\n \r\n\r\nexport function getMatchedDependencies(this:MixCli,entry:string):string[]{\r\n const pacakgeMacher = this.options.include\r\n if(!(pacakgeMacher instanceof RegExp)) return []\r\n \r\n // 找出当前包的所有依赖\r\n const { dependencies={},devDependencies={},peerDependencies={},optionalDependencies={},bundleDependencies={} } = getPackageJson(entry)\r\n const packageNames = [\r\n ...Object.keys(dependencies),\r\n ...Object.keys(devDependencies),\r\n ...Object.keys(peerDependencies),\r\n ...Object.keys(optionalDependencies),\r\n ...Object.keys(bundleDependencies)\r\n ]\r\n return packageNames.filter(name=>name!==\"@voerka/cli\" && pacakgeMacher.test(name))\r\n}\r\n\r\nfunction isMatched(str:string,reg?:string | RegExp | string[] | RegExp[]):boolean{\r\n // let regexps:RegExp[]=[]\r\n const regexps = reg ? (Array.isArray(reg) ? reg : [reg]) : []\r\n return regexps.some(regexp=>{\r\n if(typeof regexp === \"string\"){\r\n return (new RegExp(regexp)).test(str)\r\n }else if(regexp instanceof RegExp){\r\n return regexp.test(str)\r\n }else{\r\n return false\r\n }\r\n })\r\n}\r\n\r\nexport function findCliPaths(this:MixCli,packageName?:string ,entry?:string):string[]{\r\n const includeMacher = this.options.include\r\n const excludeMacher = this.options.exclude\r\n if(!includeMacher) return []\r\n const packageRoot = getPackageRootPath(entry || process.cwd())\r\n const packagePath = packageName ? path.dirname(require.resolve(packageName,{paths:[packageRoot as string]})) : packageName!\r\n\r\n // 找出当前包的所有依赖\r\n const packageNames = getMatchedDependencies.call(this,packagePath)\r\n\r\n const cliDirs:string[]=[]\r\n \r\n if(entry!==undefined) cliDirs.push(path.join(packagePath,this.options.cliDir))\r\n packageNames.filter(name=>{\r\n return isMatched(name,includeMacher) && !isMatched(name,excludeMacher) \r\n })\r\n .forEach(name=>{\r\n outputDebug(\"匹配包:{}\",`${packageName ? name+\" <- \"+packageName : name}`)\r\n try{\r\n const packageEntry = path.dirname(require.resolve(name,{paths:packagePath ? [packagePath] : [process.cwd()]}))\r\n const packageCliDir =path.join(packageEntry,this.options.cliDir!) \r\n // 查找当前包的所属工程的依赖\r\n let dependencies = getMatchedDependencies.call(this,packageEntry)\r\n cliDirs.push(...dependencies.reduce<string[]>((result,dependencie)=>{\r\n outputDebug(\"匹配包:{}\",`${dependencie} <- ${name}`)\r\n result.push(...findCliPaths.call(this,dependencie,packageEntry))\r\n return result\r\n },[])) \r\n if(fs.existsSync(packageCliDir)){\r\n cliDirs.push(packageCliDir)\r\n }\r\n }catch(e:any){\r\n outputDebug(\"解析包<{}>路径出错:{}\",[name,e.stack])\r\n } \r\n })\r\n // 由于一些包可能存在循环依赖,所以需要去重\r\n return [...new Set(cliDirs)]\r\n}\r\n\r\n\r\nfunction showError(e:any){\r\n if(isDebug()){\r\n outputDebug(\"导入命令<>出错:{}\",e.stack)\r\n }else{\r\n console.error(e)\r\n } \r\n\r\n}\r\n\r\n/**\r\n * \r\n * 扫描当前工程中所有符合条件的命令\r\n * \r\n * @param cli \r\n * \r\n */\r\nexport async function findCommands(cli:MixCli){ \r\n const cliDirs = findCliPaths.call(cli)\r\n const commands:MixCliCommand[] = []\r\n const files = [] as string[]\r\n cliDirs.forEach(dir=>{\r\n files.push(...globSync(\"*\",{\r\n cwd:dir,\r\n absolute :true \r\n }).filter((file:string)=>(file.endsWith(\".js\") || file.endsWith(\".cjs\") || file.endsWith(\".mjs\")) && !fs.statSync(file).isDirectory()))\r\n })\r\n for(let file of files){ \r\n try{\r\n outputDebug(\"导入命令:{}\",file)\r\n if(file.endsWith(\".cjs\") || file.endsWith(\".js\")){\r\n commands.push(require(file))\r\n }else if(file.endsWith(\".mjs\")){\r\n const cmd = await import(`file://${file}`)\r\n commands.push(cmd.default)\r\n } \r\n }catch(e:any){\r\n if(e.code===\"ERR_REQUIRE_ESM\"){ \r\n try{\r\n const cmd = await import(`file://${file.replace(\".js\",\".mjs\")}`)\r\n commands.push(cmd.default)\r\n }catch(err){\r\n showError(err)\r\n }\r\n }else{\r\n showError(e) \r\n }\r\n }\r\n }\r\n return commands\r\n}\r\n\r\n"],"mappings":"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","names":["module","import_logsets","import_commander","logsets","fs","path","artTemplate","import_node_path","path","fs","prompts","command","import_node_fs","import_node_path","path","fs","replaceAll","logsets","cmd"]}
|
1
|
+
{"version":3,"sources":["../package.json","../src/index.ts","../src/cli.ts","../src/command.ts","../src/option.ts","../src/utils.ts","../src/prompt.ts","../src/finder.ts"],"sourcesContent":["{\n \"name\": \"mixcli\",\n \"version\": \"3.0.2\",\n \"description\": \"Develop command line tool scaffolding for monorepo\",\n \"repository\": \"https://github.com/zhangfisher/mixcli.git\",\n \"homepage\": \"https://zhangfisher.github.io/mixcli/\",\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"scripts\": {\n \"build\": \"tsup\",\n \"build:watch\": \"tsup --watch\",\n \"release\": \"npm publish\"\n },\n \"files\": [\n \"dist\",\n \"src\",\n \"readme.md\",\n \"package.json\"\n ],\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"dependencies\": {\n \"@types/prompts\": \"^2.4.4\",\n \"@voerkai18n/runtime\": \"^2.0.8\",\n \"art-template\": \"^4.13.2\",\n \"commander\": \"^12.0.0\",\n \"flex-tools\": \"^1.3.60\",\n \"fs-extra\": \"^11.1.1\",\n \"glob\": \"^10.3.12\",\n \"logsets\": \"^1.3.8\",\n \"prompts\": \"^2.4.2\",\n \"string.prototype.replaceall\": \"^1.0.7\"\n },\n \"devDependencies\": {\n \"@types/fs-extra\": \"^11.0.1\",\n \"@types/node\": \"^20.5.7\",\n \"typescript\": \"^5.2.2\"\n }\n}\n","export * from \"./cli\"\r\nexport * from \"./utils\"\r\nexport * from \"./command\"\r\nexport * from \"./option\"","#!/usr/bin/env node\nimport \"flex-tools/string\"\nimport { LiteEvent, LiteEventSubscriber } from \"flex-tools/events/liteEvent\"\nimport { Command } from \"commander\"\nimport logsets from \"logsets\"\n\nimport { assignObject } from \"flex-tools/object/assignObject\"\nimport { MixCommand } from \"./command\"\nimport { addBuiltInOptions, fixIndent } from './utils';\nimport { findCommands } from \"./finder\"\nimport { asyncSignal } from \"flex-tools/async/asyncSignal\"\n// @ts-ignore\nimport replaceAll from 'string.prototype.replaceall'\nreplaceAll.shim() \n\nexport interface MixCliOptions{\n name:string,\n title?:string | (string | boolean | number)[],\n description?:string,\n version?:string\n // 定义显示帮助信息\n logo?:string ,\n // 在根命令执行前执行==commander的preAction\n before?:(thisCommand:Command,actionCommand:Command)=>void,\n // 在根命令执行后执行==commander的postAction\n after?:(thisCommand:Command,actionCommand:Command)=>void, \n // flexcli运行时会在当前工程的package.json的依赖中查找以prefix/开头的包,然后自动加载其cli目录下的命令\n // 例如:prefix=myapp,则会自动加载flex-cli-xxx包中的cli目录下的命令\n // 如prefix=myapp, cliPath=\"cmds\",则会自动加载flex-cli-xxx包中的cmds目录下的命令\n include?:string | RegExp | string[] | RegExp[],\n // 忽略查找正则表达式\n exclude?:string | RegExp | string[] | RegExp[],\n // flexcli会在当前工程的以prefix/开头下查找命令声明\n // / pattern默认值是cli,即会在当前工程的以prefix/开头的包下查找cli目录下的命令\n // 指定cli所在的目录,默认值是cli,要遍历该目录下的所有js文件作为命令导出\n cliDir?:string \n context?:Record<string,any> // 传递给命令的共享上下文,所有命令均可要使用 \n // 默认是否启用交互提示, auto当没有值时,会根据当前是否在终端中运行来决定是否启用交互提示\n // 为false时,禁用所有交互提示,为true时,启用所有交互提示 \n prompt?:'auto' | boolean \n}\n\n \n \n\nexport type MixCliCommand = (cli:MixCli)=>MixCommand | MixCommand[] | void\n\n\nexport type MixCliEvents = \n \"register\" // 当命令注册时触发\n\nexport class MixCli extends LiteEvent<any,MixCliEvents>{\n options:Required<MixCliOptions> \n root!:Command \n private findSignals:any[]=[]\n constructor(options?:MixCliOptions){\n super()\n this.options= assignObject({\n name:\"mixcli\",\n package:null,\n cliDir:\"cli\",\n prompt:'auto'\n },options) \n this.createRootCommand() \n } \n get context(){return this.options.context}\n get name(){return this.options.name}\n /**\n * 是否禁用了所有的交互提示\n */\n get isDisabledPrompts(){\n return(this.root as any).rawArgs.includes(\"--no-prompts\") \n } \n /**\n * 扫描当前工程的依赖,加载匹配include的依赖下的命令\n */\n private async installCommands(){\n const cmders = await findCommands(this)\n for(let cmder of cmders){\n try{\n if(typeof(cmder)===\"function\"){\n let cmds = cmder(this)\n cmds =cmds ? (Array.isArray(cmds) ? cmds : [cmds]) : []\n this.register(()=>cmds) \n }\n }catch(e:any){\n }\n }\n } \n /**\n * 创建根命令\n * \n */\n private createRootCommand(){\n this.root = new MixCommand(this.name);\n this.root \n .helpOption('-h, --help') \n .version(require(\"../package.json\").version,\"-v, --version\") \n .action(()=>{ \n if(this.options.logo) logsets.log(fixIndent(this.options.logo,2))\n console.log()\n // 显示标题\n let title = this.options.title|| this.options.name\n if(Array.isArray(title)){\n logsets.log(String(title[0]).firstUpper(),[...title.slice(1)])\n }else{\n logsets.log(`${title.firstUpper()} Version: {}`,this.options.version)\n } \n // @ts-ignore\n if(this.options.description) logsets.log(logsets.colors.darkGray(this.options.description)) \n console.log()\n this.root.help() \n }) \n addBuiltInOptions(this.root)\n if(this.options.before) this.root.hook('preAction',this.options.before)\n if(this.options.after) this.root.hook('postAction',this.options.after) \n } \n /**\n * 添加帮助选项\n * \n * @param text 帮助文本\n * @param position 显示位置,可选值:before|after|beforeAll|afterAll\n * @param fixIndent 是否自动修正缩进,如果为true,则会自动修正缩进,当显示多行时文本时,会自动修正缩进\n * \n */\n public addHelp(text:string,{pos='beforeAll',alignIndent=true}:{pos:'before'|'after' | 'beforeAll' | 'afterAll',alignIndent?:boolean | number}){\n if(alignIndent) text = fixIndent(text,alignIndent)\n this.root.addHelpText(pos,text)\n }\n\n /**\n * 注册一个命令\n * @param cmd \n */\n register(cmd:MixCliCommand){\n if(typeof(cmd)==\"function\"){\n let result = cmd(this)\n let cmds = result instanceof Array ? result : (result==undefined ? [] : [result])\n for(let cmd of cmds){\n if(cmd instanceof MixCommand){\n if(this.hasCommand(cmd.name())){\n logsets.error(`Command <${cmd.name()}> has been registered!`)\n }else{\n this.root.addCommand(cmd) ;\n (cmd as any)._cli = this\n this.emit(\"register\",cmd.fullname,true)\n } \n }\n } \n }else{\n logsets.error(\"Invalid command\")\n } \n }\n\n hasCommand(name:string):boolean{\n return this.root.commands.some(c=>c.name()==name)\n }\n\n /**\n * 根据命令名称查找命令\n * \n * @remarks\n * \n * find(\"dev\")\n * find(\"dev.microservice\") 支持多级命令\n * find(\"abc\",DevCommand) 允许指定从DevCommand下开始查找abc命令\n * \n * @param name \n */\n get(name:string):MixCommand | undefined{\n const names=name.split(\".\")\n let curCmd:Command = this.root\n let resultCmd:MixCommand | undefined\n while(names.length>0){\n const topName = names.shift()\n const r = curCmd.commands.find(c=>c.name()==topName) as MixCommand\n if(r && names.length==0){\n resultCmd = r\n }\n curCmd = r\n } \n return resultCmd \n }\n /**\n * 查找一个命令\n * \n * 如果命令不存在,则等待命令注册后再返回\n * \n * 在多包场景下,如果命令在其他包中注册并且该包中的命令还没注册,则会等待命令注册后再返回\n * \n * @param name \n * @returns \n */\n find(name:string):Promise<MixCommand | undefined>{\n const cmd = this.get(name)\n if(cmd){\n return Promise.resolve(cmd) \n }else{\n const signal = asyncSignal()\n this.findSignals.push(signal)\n return new Promise<MixCommand | undefined>((resolve)=>{\n let listener:LiteEventSubscriber\n listener = this.on(\"register\",(fullname:string)=>{\n if(fullname==`${this.name}.${name}`){\n listener.off()\n signal.resolve()\n this.findSignals = this.findSignals.filter(s=>s!=signal)\n resolve(this.get(name))\n }\n },{objectify:true}) as LiteEventSubscriber\n })\n } \n }\n /**\n * 判断命令是否存在\n * \n * @param name \n * @returns \n */\n exists(name:string):boolean{\n if(name in this.root.commands){\n return true\n }else{\n return this.get(name) != undefined\n }\n } \n \n /**\n * 运行命令行程序\n */\n run(){ \n // 为什么有findSignal这玩意,解决什么问题?\n // 当我们要扩展command时,通过get(\"命令名称\")来获取已经注册的命令的方式有个缺陷\n // 就是如果对命令的注册顺序有严格的要求,比如调用get('dev')时要求dev命令必须已经存在\n // 这对动态包的命令注册扩展开发体验不好\n // 所以引入find(\"命令名称\")来获取命令,该方法可以获取到后注册的命令\n // 其副作用是,在run时,可能find还没有运行到,从而导致在帮助信息里面看不到扩展的信息(实际上是已经生效的)\n // 所以我们在find里面注入一个异步信号来解决此问题\n this.installCommands().then(()=>{\n return Promise.all(this.findSignals.map(signal=>signal(10000))).then(()=>{\n this.root.parseAsync(process.argv); \n })\n }) \n }\n /**\n * 创建一个命令\n * \n * \n */\n create(){\n }\n}\n ","import { Command, Option } from \"commander\";\r\nimport prompts, { PromptObject } from \"prompts\";\r\nimport { MixOption, type MixedOptionParams } from \"./option\";\r\nimport { addBuiltInOptions, isEnablePrompts, outputDebug } from \"./utils\";\r\nimport path from \"node:path\";\r\nimport fs from \"node:fs\";\r\nimport type { AsyncFunction } from \"flex-tools\";\r\n\r\nexport type ICommandHookListener = ({\r\n\targs,\r\n\toptions,\r\n\tcommand,\r\n}: {\r\n\targs: any[];\r\n\toptions: Record<string, any>;\r\n\tcommand: MixCommand;\r\n}) => void | Promise<void>;\r\n\r\nexport type BeforeCommandHookListener = ({\r\n\targs,\r\n\toptions,\r\n\tcommand,\r\n}: {\r\n\targs: any[];\r\n\toptions: Record<string, any>;\r\n\tcommand: MixCommand;\r\n}) => void | Promise<void>;\r\nexport type AfterCommandHookListener = ({\r\n\tvalue,\r\n\targs,\r\n\toptions,\r\n\tcommand,\r\n}: {\r\n\tvalue: any;\r\n\targs: any[];\r\n\toptions: Record<string, any>;\r\n\tcommand: MixCommand;\r\n}) => void | Promise<void>;\r\n\r\nexport interface ActionOptions {\r\n\tid: string;\r\n\tat: \"replace\" | \"before\" | \"after\" | \"preappend\" | \"append\" | number;\r\n\t// 函数签名类型,即采用原始的commander的action函数签名,还是mixcli的action函数签名\r\n\tenhance: boolean;\r\n}\r\n\r\nexport interface ActionRegistry extends Omit<ActionOptions, \"at\"> {\r\n\tfn: Function;\r\n}\r\n\r\n// 原始的Action动作函数\r\nexport type OriginalAction = (...args: any[]) => void | Promise<void>;\r\n// 增强的Action函数签名\r\nexport type EnhanceAction = ({\r\n\targs,\r\n\toptions,\r\n\tvalue,\r\n\tcommand,\r\n}: {\r\n\targs: any[];\r\n\toptions: Record<string, any>;\r\n\tvalue: any;\r\n\tcommand: MixCommand;\r\n}) => void | Promise<any>;\r\n\r\n// 执行action的返回结果\r\nexport const BREAK = Symbol(\"BREAK_ACTION\"); // 中止后续的action执行\r\n\r\nexport class MixCommand extends Command {\r\n\tprivate _beforeHooks: [BeforeCommandHookListener, boolean][] = [];\r\n\tprivate _afterHooks: [AfterCommandHookListener, boolean][] = [];\r\n\tprivate _customPrompts: PromptObject[] = [];\r\n\tprivate _optionValues: Record<string, any> = {}; // 命令行输入的选项值\r\n\tprivate _actions: ActionRegistry[] = []; // 允许多个action\r\n\tprivate _enable_prompts: boolean = true; // 是否启用交互提示\r\n\tconstructor(name?: string) {\r\n\t\tsuper(name);\r\n\t\tconst self = this;\r\n\t\tif (!this.isRoot) addBuiltInOptions(this);\r\n\t\tthis.hook(\"preAction\", async function (this: any) {\r\n\t\t\tself._optionValues = self.getOptionValues(this.hookedCommand);\r\n\t\t\ttry {\r\n\t\t\t\t// @ts-ignore\r\n\t\t\t\tawait self.preActionHook.apply(self, arguments);\r\n\t\t\t} catch {}\r\n\t\t});\r\n\t}\r\n\t/**\r\n\t * 是否是根命令\r\n\t */\r\n\tget isRoot() {\r\n\t\treturn !!!this.parent;\r\n\t}\r\n\tget actions() {\r\n\t\treturn this._actions;\r\n\t}\r\n\tget beforeHooks() {\r\n\t\treturn this._beforeHooks;\r\n\t}\r\n\tget afterHooks() {\r\n\t\treturn this._afterHooks;\r\n\t}\r\n\tget fullname() {\r\n\t\tlet names = [this.name()];\r\n\t\tlet parent = this.parent;\r\n\t\twhile (parent) {\r\n\t\t\tif (parent.name() !== \"root\") {\r\n\t\t\t\tnames.unshift(parent.name());\r\n\t\t\t}\r\n\t\t\tparent = parent.parent;\r\n\t\t}\r\n\t\treturn names.join(\".\");\r\n\t}\r\n\r\n\t/**\r\n\t * 返回根命令\r\n\t */\r\n\troot() {\r\n\t\tlet root: MixCommand | null | undefined = this;\r\n\t\twhile (root && root.parent != null) {\r\n\t\t\troot = root.parent as unknown as MixCommand;\r\n\t\t}\r\n\t\treturn root;\r\n\t}\r\n\taction(fn: EnhanceAction, options: ActionOptions): this;\r\n\taction(fn: OriginalAction): this;\r\n\taction(fn: OriginalAction): this {\r\n\t\tconst actionFunc = arguments[0];\r\n\t\tif (arguments.length == 1 && typeof actionFunc == \"function\") {\r\n\t\t\t// 原始方式\r\n\t\t\tthis._actions.push({\r\n\t\t\t\tid: Math.random().toString(36).substring(2),\r\n\t\t\t\tenhance: false,\r\n\t\t\t\tfn: actionFunc,\r\n\t\t\t});\r\n\t\t} else if (\r\n\t\t\targuments.length == 2 &&\r\n\t\t\ttypeof actionFunc == \"function\" &&\r\n\t\t\ttypeof arguments[1] == \"object\"\r\n\t\t) {\r\n\t\t\t// 增强模式\r\n\t\t\tconst actionFn = arguments[0];\r\n\t\t\tconst actionOpts: ActionOptions = Object.assign({ at: \"append\" }, arguments[1]);\r\n\t\t\tif (actionOpts.at == \"replace\") this._actions = [];\r\n\t\t\tconst actionItem = {\r\n\t\t\t\tid: actionOpts.id || Math.random().toString(36).substring(2),\r\n\t\t\t\tenhance: actionOpts.enhance == undefined ? true : actionOpts.enhance,\r\n\t\t\t\tfn: actionFn,\r\n\t\t\t} as const;\r\n\t\t\tif (typeof actionOpts.at == \"number\") {\r\n\t\t\t\tthis._actions.splice(Number(actionOpts.at), 0, actionItem);\r\n\t\t\t} else if ([\"append\", \"before\"].includes(actionOpts.at)) {\r\n\t\t\t\tthis._actions.push(actionItem);\r\n\t\t\t} else if ([\"preappend\", \"after\"].includes(actionOpts.at)) {\r\n\t\t\t\tthis._actions.splice(0, 0, actionItem);\r\n\t\t\t} else {\r\n\t\t\t\tthis._actions.push(actionItem);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tconsole.log(\"[mixcli] action params error\");\r\n\t\t}\r\n\t\treturn super.action(this.getWrapperedAction());\r\n\t}\r\n\r\n\t/**\r\n\t * 读取命令配置值,包括父命令提供的配置选项\r\n\t * @param command\r\n\t */\r\n\tprivate getOptionValues(command: Command) {\r\n\t\tlet opts = {};\r\n\t\tlet parent: Command | null = command;\r\n\t\twhile (parent) {\r\n\t\t\tObject.assign(opts, (parent as MixCommand)._optionValues);\r\n\t\t\tparent = parent.parent;\r\n\t\t}\r\n\t\treturn opts;\r\n\t}\r\n\t/**\r\n\t * 本函数在运行时子类进行action生成该命令的action\r\n\t */\r\n\tprivate getWrapperedAction() {\r\n\t\treturn this.wrapperWorkDirsAction(this.wrapperChainActions());\r\n\t}\r\n\r\n\t/**\r\n\t * 向上查找所有祖先命令\r\n\t */\r\n\tprivate getAncestorCommands(): MixCommand[] {\r\n\t\tlet cmds: MixCommand[] = [];\r\n\t\tlet cmd: MixCommand | null = this;\r\n\t\twhile (cmd) {\r\n\t\t\tcmd = cmd.parent as MixCommand;\r\n\t\t\tif (cmd) {\r\n\t\t\t\tcmds.push(cmd);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn cmds;\r\n\t}\r\n\t/***\r\n\t * 将所有actions包装成一个链式调用的函数\r\n\t */\r\n\tprivate wrapperChainActions() {\r\n\t\tconst self = this;\r\n\t\treturn async function (this: any) {\r\n\t\t\tconst args = Array.from(arguments); // 原始输入的参数\r\n\t\t\tlet preValue: any; // 保存上一个action的返回值\r\n\t\t\t//解析参数, 0-1个参数为options,最后一个参数为command\r\n\t\t\tlet actionOpts: Record<string, any> = {},\r\n\t\t\t\tactionArgs: any[] = [],\r\n\t\t\t\tcmd: any;\r\n\t\t\tif (args.length >= 2) {\r\n\t\t\t\tcmd = args[args.length - 1]; // 最后一个command\r\n\t\t\t\tactionOpts = args[args.length - 2];\r\n\t\t\t\tactionArgs = args.slice(0, args.length - 2);\r\n\t\t\t}\r\n\t\t\tawait self.executeBeforeHooks({ args: actionArgs, options: actionOpts, command: cmd });\r\n\t\t\ttry {\r\n\t\t\t\tfor (let action of self._actions) {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tif (action.enhance) {\r\n\t\t\t\t\t\t\t// 增强模式\r\n\t\t\t\t\t\t\toutputDebug(\"执行<{}>: args={}, options={}\", () => [\r\n\t\t\t\t\t\t\t\tself.name(),\r\n\t\t\t\t\t\t\t\tactionArgs,\r\n\t\t\t\t\t\t\t\tactionOpts,\r\n\t\t\t\t\t\t\t]);\r\n\t\t\t\t\t\t\tpreValue = await action.fn.call(this, {\r\n\t\t\t\t\t\t\t\tcommand: cmd,\r\n\t\t\t\t\t\t\t\tvalue: preValue,\r\n\t\t\t\t\t\t\t\targs: actionArgs,\r\n\t\t\t\t\t\t\t\toptions: actionOpts,\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t// 原始模式\r\n\t\t\t\t\t\t\tpreValue = await action.fn.apply(this, args);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (preValue === BREAK) break;\r\n\t\t\t\t\t} catch (e) {\r\n\t\t\t\t\t\toutputDebug(\"命令{}的Action({})执行出错:{}\", [self.name, action.id, e]);\r\n\t\t\t\t\t\tthrow e;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} finally {\r\n\t\t\t\tawait self.executeAfterHooks({\r\n\t\t\t\t\tvalue: preValue,\r\n\t\t\t\t\targs: actionArgs,\r\n\t\t\t\t\toptions: actionOpts,\r\n\t\t\t\t\tcommand: cmd,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t};\r\n\t}\r\n\t/**\r\n\t * 当传入--work-dirs时用来处理工作目录\r\n\t */\r\n\tprivate wrapperWorkDirsAction(fn: AsyncFunction) {\r\n\t\tconst self = this;\r\n\t\treturn async function (this: any) {\r\n\t\t\tlet workDirs = self._optionValues.workDirs;\r\n\t\t\t// 未指定工作目录参数\r\n\t\t\tif (!workDirs) {\r\n\t\t\t\treturn await fn.apply(this, Array.from(arguments));\r\n\t\t\t}\r\n\t\t\tif (!Array.isArray(workDirs)) workDirs = workDirs.split(\",\");\r\n\t\t\tworkDirs = workDirs.reduce((dirs: any[], dir: string) => {\r\n\t\t\t\tif (typeof dir == \"string\") dirs.push(...dir.split(\",\"));\r\n\t\t\t\treturn dirs;\r\n\t\t\t}, []);\r\n\t\t\tfor (let workDir of workDirs) {\r\n\t\t\t\tconst cwd = process.cwd();\r\n\t\t\t\ttry {\r\n\t\t\t\t\tif (!path.isAbsolute(workDir)) workDir = path.join(cwd, workDir);\r\n\t\t\t\t\tif (fs.existsSync(workDir) && fs.statSync(workDir).isDirectory()) {\r\n\t\t\t\t\t\toutputDebug(\"切换到工作目录:{}\", workDir);\r\n\t\t\t\t\t\tprocess.chdir(workDir); // 切换\r\n\t\t\t\t\t\tawait fn.apply(this, Array.from(arguments));\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\toutputDebug(\"无效的工作目录:{}\", workDir);\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\tthrow e;\r\n\t\t\t\t} finally {\r\n\t\t\t\t\tprocess.chdir(cwd);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t};\r\n\t}\r\n\tgetOption(name: string): MixOption {\r\n\t\treturn this.options.find((option) => option.name() == name) as unknown as MixOption;\r\n\t}\r\n\t/**\r\n\t * 添加一个Before钩子\r\n\t * @param listener\r\n\t * @param scope =false时代表只在本命令执行,=true时代表在本命令及其子命令执行\r\n\t * @returns\r\n\t */\r\n\tbefore(listener: BeforeCommandHookListener, scope: boolean = true) {\r\n\t\tthis._beforeHooks.push([listener, scope]);\r\n\t\treturn this;\r\n\t}\r\n\tprivate async executeBeforeHooks(args: any) {\r\n\t\tconst hooks: [BeforeCommandHookListener, boolean, MixCommand][] = this.beforeHooks.map(\r\n\t\t\t([hook, scope]) => [hook, scope, this]\r\n\t\t);\r\n\t\tthis.getAncestorCommands().forEach((cmd: MixCommand) => {\r\n\t\t\thooks.unshift(\r\n\t\t\t\t...cmd.beforeHooks.map(([hook, scope]) => {\r\n\t\t\t\t\treturn [hook, scope, cmd] as [BeforeCommandHookListener, boolean, MixCommand];\r\n\t\t\t\t})\r\n\t\t\t);\r\n\t\t});\r\n\t\tfor (let [hook, scope, cmd] of hooks) {\r\n\t\t\tif (!scope) continue;\r\n\t\t\tawait hook.call(cmd, args);\r\n\t\t}\r\n\t}\r\n\t/**\r\n\t * 添加一个After钩子\r\n\t * @param listener\r\n\t * @param scope =false时代表只在本命令执行,=true时代表在本命令及其子命令执行\r\n\t * @returns\r\n\t */\r\n\tafter(listener: AfterCommandHookListener, scope: boolean = true) {\r\n\t\tthis._afterHooks.push([listener, scope]);\r\n\t\treturn this;\r\n\t}\r\n\tprivate async executeAfterHooks(args: any) {\r\n\t\tconst hooks: [AfterCommandHookListener, boolean, MixCommand][] = this.afterHooks.map(\r\n\t\t\t([hook, scope]) => [hook, scope, this]\r\n\t\t);\r\n\t\tthis.getAncestorCommands().forEach((cmd: MixCommand) => {\r\n\t\t\thooks.push(\r\n\t\t\t\t...cmd.afterHooks.map(([hook, scope]) => {\r\n\t\t\t\t\treturn [hook, scope, cmd] as [BeforeCommandHookListener, boolean, MixCommand];\r\n\t\t\t\t})\r\n\t\t\t);\r\n\t\t});\r\n\t\tfor (let [hook, scope, cmd] of hooks) {\r\n\t\t\tif (!scope) continue; //=false时不执行\r\n\t\t\tawait hook.call(cmd, args);\r\n\t\t}\r\n\t}\r\n\tprivate async preActionHook(thisCommand: Command, actionCommand: Command) {\r\n\t\tif (this.isEnablePrompts()) {\r\n\t\t\t// 自动生成提示\r\n\t\t\tconst questions: PromptObject[] = [\r\n\t\t\t\t...this.generateAutoPrompts(),\r\n\t\t\t\t...this._customPrompts,\r\n\t\t\t];\r\n\t\t\t// 用户提示\r\n\t\t\tif (questions.length > 0) {\r\n\t\t\t\tconst results = await prompts(questions);\r\n\t\t\t\tObject.entries(results).forEach(([key, value]) => {\r\n\t\t\t\t\tthisCommand.setOptionValue(key, value);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tprivate isEnablePrompts() {\r\n\t\tif (isEnablePrompts() === false) {\r\n\t\t\t// 命令行参数禁用了提示,优先级最高\r\n\t\t\treturn false;\r\n\t\t} else {\r\n\t\t\treturn this._enable_prompts;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 生成选项自动提示\r\n\t *\r\n\t * @remarks\r\n\t * FlexCli要求所有未提供默认值的Option自动生成提示\r\n\t *\r\n\t * - 未提供默认值,并且是必选的参数Option\r\n\t * - 指定了choices但未提供有效值的Option\r\n\t *\r\n\t */\r\n\tprivate generateAutoPrompts(): PromptObject[] {\r\n\t\tconst options = this.options as unknown as MixOption[];\r\n\t\tconst optionPromports = options\r\n\t\t\t.filter((option) => !option.hidden && option instanceof MixOption)\r\n\t\t\t.map((option) => option.getPrompt(this._optionValues[option.name()]))\r\n\t\t\t.filter((prompt) => prompt) as PromptObject[];\r\n\t\toutputDebug(\"命令<{}>自动生成{}个选项提示:{}\", [\r\n\t\t\tthis.name(),\r\n\t\t\toptionPromports.length,\r\n\t\t\toptionPromports.map((prompt) => `${prompt.name}(${prompt.type})`).join(\",\"),\r\n\t\t]);\r\n\t\treturn optionPromports;\r\n\t}\r\n\toption(flags: string, description?: string | undefined, defaultValue?: any): this;\r\n\toption(flags: string, description?: string | undefined, options?: MixedOptionParams): this {\r\n\t\t// @ts-ignore\r\n\t\tconst option = new MixOption(...arguments);\r\n\t\tif (option.required && !this.isEnablePrompts()) option.mandatory = true;\r\n\t\treturn this.addOption(option as unknown as Option);\r\n\t}\r\n\r\n\t/**\r\n\t * 添加提示\r\n\t *\r\n\t * @remarks\r\n\t *\r\n\t * 添加一些自定义提示\r\n\t *\r\n\t *\r\n\t * @param questions\r\n\t * @param show 是否显示提示信息,auto表示只有在用户没有提供option的值时才显示提示信息,always表示总是显示提示信息,never表示不显示提示信息\r\n\t * @returns\r\n\t */\r\n\tprompt(questions: PromptObject | PromptObject[]) {\r\n\t\tthis._customPrompts.push(...(Array.isArray(questions) ? questions : [questions]));\r\n\t\treturn this;\r\n\t}\r\n\t/**\r\n\t *\r\n\t * 选择命令并执行\r\n\t *\r\n\t * @remorks\r\n\t *\r\n\t * 当命令具有多个子命令时,并且没有提供默认子命令时,提示用户选择一个子命令\r\n\t *\r\n\t */\r\n\tasync selectCommands() {\r\n\t\tconst choices = this.commands.map((command) => ({\r\n\t\t\ttitle: `${command.description()}(${command.name()})`,\r\n\t\t\tvalue: command.name(),\r\n\t\t}));\r\n\t\tconst result = await prompts({\r\n\t\t\ttype: \"select\",\r\n\t\t\tname: \"command\",\r\n\t\t\tmessage: \"请选择命令:\",\r\n\t\t\tchoices,\r\n\t\t});\r\n\t\t// 重新解析命令行参数标志,\r\n\t\tconst command = this.commands.find((command) => command.name() === result.command);\r\n\t\tawait command?.parseAsync([result.command], { from: \"user\" });\r\n\t}\r\n\t/**\r\n\t * 禁用/启用所有提示\r\n\t */\r\n\tdisablePrompts() {\r\n\t\tthis._enable_prompts = false;\r\n\t\treturn this;\r\n\t}\r\n\tenablePrompts() {\r\n\t\tthis._enable_prompts = true;\r\n\t\treturn this;\r\n\t}\r\n}\r\n","import { Option } from 'commander'\nimport { PromptObject } from 'prompts'\nimport { IPromptable, IPromptableOptions, PromptChoice, PromptManager } from './prompt'\n\n\nexport interface MixedOptionParams extends IPromptableOptions{\n hidden?:boolean\n defaultDescription?:string // 默认值的描述 \n conflicts?:string | string[]\n env?:string\n argParser?:<T>(value: string, previous: T) => T \n hideHelp?:boolean\n mandatory?: boolean \n implies?:{[key:string]:any} \n}\n\n\nexport class MixOption extends Option implements IPromptable{\n // 是否提示用户输入\n prompt?: PromptManager \n promptChoices?:PromptChoice[]\n private _validate?: (value: any) => boolean \n constructor(flags: string, description?: string | undefined,optsOrDefault?:any) {\n super(flags, description)\n let params:MixedOptionParams = {}\n if(arguments.length==3 && typeof arguments[2] == \"object\"){\n params = Object.assign({ },arguments[2]) \n }else if(arguments.length==3){\n params.default = arguments[2]\n }\n if(params.prompt===undefined) params.prompt = 'auto'\n if(params.default) this.default(params.default,params.defaultDescription)\n if(params.choices) this.choices(params.choices)\n if(params.conflicts) this.conflicts(params.conflicts)\n if(params.env) this.env(params.env)\n if(params.argParser) this.argParser(params.argParser)\n if(params.hideHelp) this.hideHelp(params.hideHelp)\n if(params.hidden) this.hidden = params.hidden\n if(params.mandatory) this.makeOptionMandatory(params.mandatory)\n if(params.implies) this.implies(params.implies) \n if(params.optional) this.optional=params.optional\n if(typeof(params.validate)=='function') this._validate = params.validate.bind(this)\n if(params.required) {\n this.required = params.required\n if(!this._validate ) this._validate = (value:any)=>String(value).length>0\n }\n this.prompt = new PromptManager(this as IPromptable,params.prompt)\n } \n validate(value: any): boolean {\n if(typeof(this._validate)=='function'){\n return this._validate(value)\n }else{\n return true\n }\n }\n // @ts-ignore\n choices(values:(PromptChoice | string)[]){\n if(!this.promptChoices){\n this.promptChoices = values.map(choice=>{\n if(typeof(choice)=='object'){\n return choice\n }else{\n return {title:choice,value:choice} \n }\n })\n } \n super.choices(this.promptChoices.map((item:any)=>item.value)) \n } \n\n private resetChoices(){\n super.choices(this.promptChoices!.map((item:any)=>item.value)) \n }\n\n addChoice(value:PromptChoice | string){\n if(!this.promptChoices || !Array.isArray(this.promptChoices)) this.promptChoices = []\n this.promptChoices!.push(typeof(value)=='string' ? {title:value,value} : value)\n this.resetChoices()\n }\n removeChoice(value:any){\n this.promptChoices =this.promptChoices?.filter(choice=>choice.value!==value)\n this.resetChoices()\n }\n clearChoice(){\n this.promptChoices = []\n this.resetChoices()\n }\n\n \n /**\n * 返回选项的提示对象\n * \n * @remarks\n * \n *\n * \n * @param inputValue \n * @returns \n */\n getPrompt(inputValue?:any): PromptObject | undefined {\n return this.prompt?.get(inputValue)\n } \n}","import artTemplate from \"art-template\"\r\nimport fs from \"fs-extra\"\r\nimport path from \"node:path\"\r\nimport { promisify } from \"flex-tools/func/promisify\"\r\nimport logsets from \"logsets\" \r\n/**\r\n * \r\n * 在控制台输出一个字符串\r\n * 本方法会将字符串中的每一行空格去掉\r\n * \r\n * @remarks\r\n * \r\n * outputStr(String.raw`\r\n * a\r\n * b`)\r\n * \r\n * 会输出\r\n * a\r\n * b\r\n *\r\n * 此功能可以用于输出多行字符串时,保持代码的缩进格式,而不会影响输出结果\r\n * \r\n * @param str : 要输出的字符串\r\n * @param vars : 用于替换字符串中的变量\r\n * \r\n */\r\nexport function outputStr(str:string,vars?:Record<string,any> | any[]){ \r\n logsets.log(fixIndent(str),vars)\r\n}\r\n\r\n/**\r\n * 修正多行字符串的缩进\r\n * \r\n * @param text \r\n * @param indent \r\n * @returns \r\n */\r\nexport function fixIndent(text:string,indent?:boolean | number):string{\r\n let indentValue = (indent==undefined || indent===true) ? 0 : (typeof(indent)=='number' ? indent : -1)\r\n if(indentValue==-1) return text // 不修正缩进\r\n let lines:string[] = text.split(\"\\n\")\r\n let minSpaceCount = lines.reduce<number>((minCount,line,index)=>{\r\n if(index==0) return minCount\r\n const spaceCount = line.match(/^\\s*/)?.[0].length || 0\r\n return Math.min(minCount,spaceCount)\r\n },9999)\r\n lines = lines.map(line=>line.substring(minSpaceCount))\r\n return lines.join(\"\\n\")\r\n}\r\n\r\n/**\r\n * 增加内置选项\r\n * @param command \r\n */\r\nexport function addBuiltInOptions(command:any){ \r\n command.option(\"--work-dirs <values...>\",\"指定工作目录\",{hidden:true,optional:true,required:true,prompt:false})\r\n command.option(\"--disable-prompts\",\"禁用所有交互提示\",{hidden:true,prompt:false}) \r\n command.option(\"--debug-cli\",\"显示调试信息\",{hidden:true,prompt:false})\r\n}\r\n\r\n\r\n/**\r\n * 是否命令行中包含了--debug-cli选项\r\n */\r\nexport function isDebug(){\r\n return process.argv.includes(\"--debug-cli\")\r\n}\r\nexport function isEnablePrompts(){ \r\n return !process.argv.includes(\"--disable-prompts\")\r\n}\r\n\r\n/**\r\n * 打印调试信息\r\n * @param message \r\n * @param args \r\n */\r\nexport function outputDebug(message:string,...args:any[]){ \r\n let vars = (args.length == 1 && typeof(args[0])=='function') ? args[0]() : args\r\n if(isDebug()) logsets.log(`[MixCli] ${message}`,...vars)\r\n}\r\n\r\nexport const fileExists = promisify(fs.exists,{\r\n parseCallback:(results)=>{\r\n return results[0]\r\n }\r\n})\r\nexport const readFile = promisify(fs.readFile)\r\nexport const writeFile = promisify(fs.writeFile)\r\nexport const mkdir = promisify(fs.mkdir)\r\n\r\n/**\r\n * 基于artTemplate模板生成文件\r\n * \r\n * @param {*} tmplFile \r\n * @param {*} vars \r\n */\r\nexport async function createFileByTemplate(targetFile:string,tmplFile:string,vars:Record<string,any>={}){\r\n tmplFile=path.isAbsolute(tmplFile)? tmplFile : path.join(process.cwd(),tmplFile)\r\n if(!fs.existsSync(tmplFile)){\r\n throw new Error(\"模板文件不存在:\"+tmplFile)\r\n }\r\n targetFile=path.isAbsolute(targetFile)? targetFile : path.join(process.cwd(),targetFile)\r\n const outPath = path.dirname(targetFile)\r\n if(!await fileExists(outPath)){\r\n await mkdir(outPath,{recursive:true})\r\n } \r\n const template = artTemplate(tmplFile,await readFile(tmplFile,{encoding:\"utf-8\"})); \r\n await writeFile(targetFile,template(vars),{encoding:\"utf-8\"})\r\n return targetFile\r\n}\r\n\r\n/** \r\n * 创建目录 \r\n * \r\n * \r\n * \r\n * @param {String[]} dirs 要创建的目录列表,类型为字符串数组 \r\n * @param callback 创建目录过程中的回调函数,类型为异步函数,接收一个参数 dir,表示当前正在创建的目录 \r\n * @returns 该函数返回一个 Promise 对象,表示创建目录的操作是否完成 \r\n */\r\nexport async function mkDirs(dirs:string[],{callback,base}:{callback?:Function,base?:string}){\r\n if(!Array.isArray(dirs)) throw new Error(\"dirs参数必须为字符串数组\")\r\n for(let dir of dirs){\r\n if(!path.isAbsolute(dir)) dir = path.join(base || process.cwd(),dir)\r\n if(typeof(callback)=='function') callback(dir)\r\n await mkdir(dir,{recursive:true})\r\n }\r\n}","import { PromptObject } from \"prompts\" \nimport { outputDebug } from \"./utils\"\n \n\nexport type PromptType = \"text\" | \"password\" | \"invisible\" | \"number\"| \"confirm\"| \"list\"| \"toggle\"| \"select\" | \"multiselect\" | \"autocomplete\" | \"date\" | \"autocompleteMultiselect\"\n\nexport type PromptParam = 'auto' | boolean | PromptType | PromptObject\nexport type InputPromptParam = PromptParam | ((value:any)=>PromptParam) | boolean\nexport type PromptParamDefaultValue = string | boolean | string[] \n\nexport const promptTypeMap:Record<string,string> = {\n boolean:\"confirm\",\n string:\"text\",\n number:\"number\", \n array:\"list\", \n} \n\nexport const supportedPromptTypes = [\"text\",\"password\",\"invisible\", \"number\", \"confirm\" , \"list\", \"toggle\" , \"select\" , \"multiselect\" , \"autocomplete\" , \"date\" , \"autocompleteMultiselect\"]\nexport interface PromptChoice {\n title: string;\n value?: any;\n disabled?: boolean | undefined;\n selected?: boolean | undefined;\n description?: string | undefined;\n}\n\n\n\nexport interface IPromptableOptions{\n required?: boolean; // A value must be supplied when the option is specified.\n optional?: boolean; // A value is optional when the option is specified.\n default?:PromptParamDefaultValue\n choices?:(PromptChoice | any)[] // 选项值的可选值\n prompt?:InputPromptParam\n validate?:(value: any) => boolean\n}\n\n\nexport interface IPromptable{\n name():string \n description?:string\n flags:string\n promptChoices?:PromptChoice[]\n argChoices?:string[]\n variadic?:boolean\n defaultValue?:PromptParamDefaultValue\n input?:any \n required?:boolean\n validate?: (value: any) => boolean \n getPrompt(inputValue?:any):PromptObject | undefined \n}\n\n/**\n * 供command.option()使用的参数对象\n */\nexport interface PromptableObject{\n \n\n}\n\n\n/**\n * 负责生成prompt对象\n * \n */\nexport class PromptManager{\n args:InputPromptParam \n private _promptable:IPromptable // 对应的FlexOption或FlexArgument\n constructor(promptable:IPromptable,promptArgs?:InputPromptParam){ \n this._promptable = promptable\n this.args= promptArgs===undefined ? 'auto' : promptArgs\n }\n\n /**\n * 返回输入的是否是有效的prompt类型\n * @param type \n * @returns \n */\n isValid(type:any){\n return supportedPromptTypes.includes(String(type))\n }\n /**\n * 推断是否需要提示\n * \n */\n isNeed(input:any,defaultValue?:any){\n \n const promptArg = this.args\n const inputValue = input || defaultValue\n // 是否有输入值,即在命令行输入了值\n const hasInput = !(inputValue === undefined)\n // 1. 显式指定了_prompt为true,则需要提示,后续进行提示类型的推断,可能不会准确\n if(promptArg===true) return true\n if(promptArg===false) return false \n\n // 2. 提供了一个prompt对象,并且没有在命令行输入值,则需要提示\n if(typeof(promptArg)=='object'){\n return !hasInput\n }\n\n // 3. 指定了内置的prompt类型,如prompt='password',则使用password类型提示输入\n if(typeof(promptArg) == 'string' && supportedPromptTypes.includes(promptArg)){\n return !hasInput\n }\n \n // 4. 判断输入是否有效,则显示提示\n if(this._promptable.argChoices && this._promptable.argChoices.indexOf(inputValue) == -1){\n return true\n } \n return !hasInput\n }\n /**\n * 返回生成prompt对象\n * \n * @param inputValue 从命令行输入的值\n */\n get(inputValue?:any){\n const {description,promptChoices,validate,defaultValue} = this._promptable\n let input = inputValue || defaultValue\n // 判断是否需要输入提示\n if(!this.isNeed(input,defaultValue)) return\n // 推断prompt类型\n let promptType = this.infer(inputValue)\n const prompt = {\n type:promptType, \n name:this._promptable.name(),\n message:description,\n initial: input,\n ...typeof(this.args) == 'object' ? this.args : {}\n } as PromptObject\n // 指定了验证函数,用来验证输入值是否有效\n prompt.validate = validate?.bind(this._promptable)\n if(promptType=='multiselect') prompt.instructions=false\n if(['select','multiselect'].includes(promptType)){\n let index = promptChoices?.findIndex(item=>item.value==input)\n prompt.initial = index==-1 ? undefined : index\n } \n // 选项值的可选值\n if(Array.isArray(promptChoices)) {\n prompt.choices =promptChoices\n }\n return prompt\n }\n /**\n * 推断prompt类型\n * \n * @param inputValue 从命令行输入的值\n */\n infer(inputValue?:any){\n const {argChoices,variadic,defaultValue} = this._promptable\n let input = inputValue || defaultValue\n // 如果选择指定了\"-p [value]或[value...]\",则使用text类型,如果没有要求输入值,则使用confirm类型\n let promptType = /(\\<[\\w\\.]+\\>)|(\\[[\\w\\.]+\\])/.test(this._promptable.flags) ? 'text' : 'confirm'\n let promptArg = this.args\n if(this.isValid(promptArg)){ // 显式指定了prompt类型\n promptType = promptArg as string\n }else{ // 未显式指定prompt类型,需要按一定规则推断类型\n if(typeof(promptArg)=='object'){\n promptType = promptArg.type as string\n }else{\n if(argChoices){ // 提供多个可选值时\n promptType = variadic ? 'multiselect' : 'select'\n }else{\n const datatype:string = Array.isArray(defaultValue) ? 'array' : typeof(defaultValue) \n // 如果输入值班是数组,则使用list类型,允许使用逗号分隔的多个值\n if(Array.isArray(input) || variadic){\n promptType = \"list\"\n }else{\n if(datatype in promptTypeMap){\n promptType = promptTypeMap[datatype]\n }\n }\n }\n }\n }\n outputDebug(\"选项<{}> -> 提示类型<{}>\",[this._promptable.name(),promptType])\n return promptType\n }\n\n}","import { getPackageRootPath } from 'flex-tools';\r\nimport type { MixCli } from './cli';\r\nimport { globSync } from 'glob'\r\nimport { MixCliCommand } from './cli';\r\nimport { isDebug, outputDebug } from './utils';\r\nimport fs from \"node:fs\"\r\nimport path from \"node:path\"\r\nimport { getPackageJson } from \"flex-tools/package/getPackageJson\"\r\n\r\n/**\r\n * \r\n * 在当前工程中查找符合FlexCli.prefix约定的命令 \r\n * \r\n * - 读取当前包的package.json\r\n * - 找出所有以cli.prefix开头的依赖\r\n * - 加载这些依赖的目录下的匹配cli.pattern的命令\r\n * - 加载加载这样命令\r\n * \r\n */\r\n \r\n\r\nexport function getMatchedDependencies(this:MixCli,entry:string):string[]{\r\n const pacakgeMacher = this.options.include\r\n if(!(pacakgeMacher instanceof RegExp)) return []\r\n \r\n // 找出当前包的所有依赖\r\n const { dependencies={},devDependencies={},peerDependencies={},optionalDependencies={},bundleDependencies={} } = getPackageJson(entry)\r\n const packageNames = [\r\n ...Object.keys(dependencies),\r\n ...Object.keys(devDependencies),\r\n ...Object.keys(peerDependencies),\r\n ...Object.keys(optionalDependencies),\r\n ...Object.keys(bundleDependencies)\r\n ]\r\n return packageNames.filter(name=>name!==\"@voerka/cli\" && pacakgeMacher.test(name))\r\n}\r\n\r\nfunction isMatched(str:string,reg?:string | RegExp | string[] | RegExp[]):boolean{\r\n // let regexps:RegExp[]=[]\r\n const regexps = reg ? (Array.isArray(reg) ? reg : [reg]) : []\r\n return regexps.some(regexp=>{\r\n if(typeof regexp === \"string\"){\r\n return (new RegExp(regexp)).test(str)\r\n }else if(regexp instanceof RegExp){\r\n return regexp.test(str)\r\n }else{\r\n return false\r\n }\r\n })\r\n}\r\n\r\nexport function findCliPaths(this:MixCli,packageName?:string ,entry?:string):string[]{\r\n const includeMacher = this.options.include\r\n const excludeMacher = this.options.exclude\r\n if(!includeMacher) return []\r\n const packageRoot = getPackageRootPath(entry || process.cwd())\r\n const packagePath = packageName ? path.dirname(require.resolve(packageName,{paths:[packageRoot as string]})) : packageName!\r\n\r\n // 找出当前包的所有依赖\r\n const packageNames = getMatchedDependencies.call(this,packagePath)\r\n\r\n const cliDirs:string[]=[]\r\n \r\n if(entry!==undefined) cliDirs.push(path.join(packagePath,this.options.cliDir))\r\n packageNames.filter(name=>{\r\n return isMatched(name,includeMacher) && !isMatched(name,excludeMacher) \r\n })\r\n .forEach(name=>{\r\n outputDebug(\"匹配包:{}\",`${packageName ? name+\" <- \"+packageName : name}`)\r\n try{\r\n const packageEntry = path.dirname(require.resolve(name,{paths:packagePath ? [packagePath] : [process.cwd()]}))\r\n const packageCliDir =path.join(packageEntry,this.options.cliDir!) \r\n // 查找当前包的所属工程的依赖\r\n let dependencies = getMatchedDependencies.call(this,packageEntry)\r\n cliDirs.push(...dependencies.reduce<string[]>((result,dependencie)=>{\r\n outputDebug(\"匹配包:{}\",`${dependencie} <- ${name}`)\r\n result.push(...findCliPaths.call(this,dependencie,packageEntry))\r\n return result\r\n },[])) \r\n if(fs.existsSync(packageCliDir)){\r\n cliDirs.push(packageCliDir)\r\n }\r\n }catch(e:any){\r\n outputDebug(\"解析包<{}>路径出错:{}\",[name,e.stack])\r\n } \r\n })\r\n // 由于一些包可能存在循环依赖,所以需要去重\r\n return [...new Set(cliDirs)]\r\n}\r\n\r\n\r\nfunction showError(e:any){\r\n if(isDebug()){\r\n outputDebug(\"导入命令<>出错:{}\",e.stack)\r\n }else{\r\n console.error(e)\r\n } \r\n\r\n}\r\n\r\n/**\r\n * \r\n * 扫描当前工程中所有符合条件的命令\r\n * \r\n * @param cli \r\n * \r\n */\r\nexport async function findCommands(cli:MixCli){ \r\n const cliDirs = findCliPaths.call(cli)\r\n const commands:MixCliCommand[] = []\r\n const files = [] as string[]\r\n cliDirs.forEach(dir=>{\r\n files.push(...globSync(\"*\",{\r\n cwd:dir,\r\n absolute :true \r\n }).filter((file:string)=>(file.endsWith(\".js\") || file.endsWith(\".cjs\") || file.endsWith(\".mjs\")) && !fs.statSync(file).isDirectory()))\r\n })\r\n for(let file of files){ \r\n try{\r\n outputDebug(\"导入命令:{}\",file)\r\n if(file.endsWith(\".cjs\") || file.endsWith(\".js\")){\r\n commands.push(require(file))\r\n }else if(file.endsWith(\".mjs\")){\r\n const cmd = await import(`file://${file}`)\r\n commands.push(cmd.default)\r\n } \r\n }catch(e:any){\r\n if(e.code===\"ERR_REQUIRE_ESM\"){ \r\n try{\r\n const cmd = await import(`file://${file.replace(\".js\",\".mjs\")}`)\r\n commands.push(cmd.default)\r\n }catch(err){\r\n showError(err)\r\n }\r\n }else{\r\n showError(e) \r\n }\r\n }\r\n }\r\n return commands\r\n}\r\n\r\n"],"mappings":"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","names":["module","import_logsets","import_commander","logsets","fs","path","artTemplate","import_node_path","path","fs","prompts","command","import_node_fs","import_node_path","path","fs","replaceAll","logsets","cmd"]}
|
package/dist/index.mjs
CHANGED
@@ -51,10 +51,10 @@ var require_package = __commonJS({
|
|
51
51
|
"package.json"(exports, module) {
|
52
52
|
module.exports = {
|
53
53
|
name: "mixcli",
|
54
|
-
version: "3.0.
|
54
|
+
version: "3.0.2",
|
55
55
|
description: "Develop command line tool scaffolding for monorepo",
|
56
|
-
repository: "https://github.com/zhangfisher/
|
57
|
-
homepage: "https://zhangfisher.github.io/
|
56
|
+
repository: "https://github.com/zhangfisher/mixcli.git",
|
57
|
+
homepage: "https://zhangfisher.github.io/mixcli/",
|
58
58
|
main: "./dist/index.js",
|
59
59
|
module: "./dist/index.mjs",
|
60
60
|
types: "./dist/index.d.ts",
|
@@ -65,6 +65,7 @@ var require_package = __commonJS({
|
|
65
65
|
},
|
66
66
|
files: [
|
67
67
|
"dist",
|
68
|
+
"src",
|
68
69
|
"readme.md",
|
69
70
|
"package.json"
|
70
71
|
],
|
@@ -75,11 +76,11 @@ var require_package = __commonJS({
|
|
75
76
|
"@types/prompts": "^2.4.4",
|
76
77
|
"@voerkai18n/runtime": "^2.0.8",
|
77
78
|
"art-template": "^4.13.2",
|
78
|
-
commander: "^
|
79
|
-
"flex-tools": "^1.3.
|
79
|
+
commander: "^12.0.0",
|
80
|
+
"flex-tools": "^1.3.60",
|
80
81
|
"fs-extra": "^11.1.1",
|
81
|
-
glob: "^10.3.
|
82
|
-
logsets: "^1.3.
|
82
|
+
glob: "^10.3.12",
|
83
|
+
logsets: "^1.3.8",
|
83
84
|
prompts: "^2.4.2",
|
84
85
|
"string.prototype.replaceall": "^1.0.7"
|
85
86
|
},
|
@@ -480,7 +481,7 @@ var MixCommand = class extends Command {
|
|
480
481
|
this._actions.push(actionItem);
|
481
482
|
}
|
482
483
|
} else {
|
483
|
-
console.log("[
|
484
|
+
console.log("[mixcli] action params error");
|
484
485
|
}
|
485
486
|
return super.action(this.getWrapperedAction());
|
486
487
|
}
|