mixcli 3.0.10 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -1,1126 +1,4 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
- var __spreadValues = (a, b) => {
12
- for (var prop in b || (b = {}))
13
- if (__hasOwnProp.call(b, prop))
14
- __defNormalProp(a, prop, b[prop]);
15
- if (__getOwnPropSymbols)
16
- for (var prop of __getOwnPropSymbols(b)) {
17
- if (__propIsEnum.call(b, prop))
18
- __defNormalProp(a, prop, b[prop]);
19
- }
20
- return a;
21
- };
22
- var __export = (target, all) => {
23
- for (var name in all)
24
- __defProp(target, name, { get: all[name], enumerable: true });
25
- };
26
- var __copyProps = (to, from, except, desc) => {
27
- if (from && typeof from === "object" || typeof from === "function") {
28
- for (let key of __getOwnPropNames(from))
29
- if (!__hasOwnProp.call(to, key) && key !== except)
30
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
31
- }
32
- return to;
33
- };
34
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
35
- // If the importer is in node compatibility mode or this is not an ESM
36
- // file that has been converted to a CommonJS file using a Babel-
37
- // compatible transform (i.e. "__esModule" has not been set), then set
38
- // "default" to the CommonJS "module.exports" for node compatibility.
39
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
40
- mod
41
- ));
42
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
43
- var __async = (__this, __arguments, generator) => {
44
- return new Promise((resolve, reject) => {
45
- var fulfilled = (value) => {
46
- try {
47
- step(generator.next(value));
48
- } catch (e) {
49
- reject(e);
50
- }
51
- };
52
- var rejected = (value) => {
53
- try {
54
- step(generator.throw(value));
55
- } catch (e) {
56
- reject(e);
57
- }
58
- };
59
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
60
- step((generator = generator.apply(__this, __arguments)).next());
61
- });
62
- };
63
-
64
- // src/index.ts
65
- var src_exports = {};
66
- __export(src_exports, {
67
- BREAK: () => BREAK,
68
- MixCli: () => MixCli,
69
- MixCommand: () => MixCommand,
70
- MixOption: () => MixOption,
71
- addBuiltInOptions: () => addBuiltInOptions,
72
- createFileByTemplate: () => createFileByTemplate,
73
- fileExists: () => fileExists,
74
- fixIndent: () => fixIndent,
75
- getId: () => getId,
76
- importModule: () => importModule,
77
- isDebug: () => isDebug,
78
- isEnablePrompts: () => isEnablePrompts,
79
- mkDirs: () => mkDirs,
80
- mkdir: () => mkdir,
81
- outputDebug: () => outputDebug,
82
- outputStr: () => outputStr,
83
- readFile: () => readFile,
84
- showError: () => showError,
85
- writeFile: () => writeFile
86
- });
87
- module.exports = __toCommonJS(src_exports);
88
-
89
- // src/cli.ts
90
- var import_string = require("flex-tools/string");
91
- var import_liteEvent = require("flex-tools/events/liteEvent");
92
- var import_logsets2 = __toESM(require("logsets"));
93
- var import_assignObject = require("flex-tools/object/assignObject");
94
-
95
- // src/command.ts
96
- var import_commander2 = require("commander");
97
- var import_prompts = __toESM(require("prompts"));
98
-
99
- // src/option.ts
100
- var import_commander = require("commander");
101
-
102
- // src/utils.ts
103
- var import_art_template = __toESM(require("art-template"));
104
- var import_fs_extra = __toESM(require("fs-extra"));
105
- var import_node_path = __toESM(require("path"));
106
- var import_promisify = require("flex-tools/func/promisify");
107
- var import_logsets = __toESM(require("logsets"));
108
- function outputStr(str, vars) {
109
- import_logsets.default.log(fixIndent(str), vars);
110
- }
111
- function fixIndent(text, indent) {
112
- let indentValue = indent == void 0 || indent === true ? 0 : typeof indent == "number" ? indent : -1;
113
- if (indentValue == -1)
114
- return text;
115
- let lines = text.split("\n");
116
- let minSpaceCount = lines.reduce((minCount, line, index) => {
117
- var _a;
118
- if (index == 0)
119
- return minCount;
120
- const spaceCount = ((_a = line.match(/^\s*/)) == null ? void 0 : _a[0].length) || 0;
121
- return Math.min(minCount, spaceCount);
122
- }, 9999);
123
- lines = lines.map((line) => line.substring(minSpaceCount));
124
- return lines.join("\n");
125
- }
126
- function addBuiltInOptions(command) {
127
- command.option("--work-dirs <values...>", "\u6307\u5B9A\u5DE5\u4F5C\u76EE\u5F55", { hidden: true, optional: true, required: true, prompt: false });
128
- command.option("--disable-prompts", "\u7981\u7528\u6240\u6709\u4EA4\u4E92\u63D0\u793A", { hidden: true, prompt: false });
129
- command.option("--debug-cli", "\u663E\u793A\u8C03\u8BD5\u4FE1\u606F", { hidden: true, prompt: false });
130
- }
131
- function isDebug() {
132
- return process.argv.includes("--debug-cli");
133
- }
134
- function isEnablePrompts() {
135
- return !process.argv.includes("--disable-prompts");
136
- }
137
- function outputDebug(message, ...args) {
138
- let vars = args.length == 1 && typeof args[0] == "function" ? args[0]() : args;
139
- if (isDebug())
140
- import_logsets.default.log(`[MixCli] ${message}`, ...vars);
141
- }
142
- var fileExists = (0, import_promisify.promisify)(import_fs_extra.default.exists, {
143
- parseCallback: (results) => {
144
- return results[0];
145
- }
146
- });
147
- var readFile = (0, import_promisify.promisify)(import_fs_extra.default.readFile);
148
- var writeFile = (0, import_promisify.promisify)(import_fs_extra.default.writeFile);
149
- var mkdir = (0, import_promisify.promisify)(import_fs_extra.default.mkdir);
150
- function createFileByTemplate(_0, _1) {
151
- return __async(this, arguments, function* (targetFile, tmplFile, vars = {}) {
152
- tmplFile = import_node_path.default.isAbsolute(tmplFile) ? tmplFile : import_node_path.default.join(process.cwd(), tmplFile);
153
- if (!import_fs_extra.default.existsSync(tmplFile)) {
154
- throw new Error("\u6A21\u677F\u6587\u4EF6\u4E0D\u5B58\u5728:" + tmplFile);
155
- }
156
- targetFile = import_node_path.default.isAbsolute(targetFile) ? targetFile : import_node_path.default.join(process.cwd(), targetFile);
157
- const outPath = import_node_path.default.dirname(targetFile);
158
- if (!(yield fileExists(outPath))) {
159
- yield mkdir(outPath, { recursive: true });
160
- }
161
- const template = (0, import_art_template.default)(tmplFile, yield readFile(tmplFile, { encoding: "utf-8" }));
162
- yield writeFile(targetFile, template(vars), { encoding: "utf-8" });
163
- return targetFile;
164
- });
165
- }
166
- function mkDirs(_0, _1) {
167
- return __async(this, arguments, function* (dirs, { callback, base }) {
168
- if (!Array.isArray(dirs))
169
- throw new Error("dirs\u53C2\u6570\u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32\u6570\u7EC4");
170
- for (let dir of dirs) {
171
- if (!import_node_path.default.isAbsolute(dir))
172
- dir = import_node_path.default.join(base || process.cwd(), dir);
173
- if (typeof callback == "function")
174
- callback(dir);
175
- yield mkdir(dir, { recursive: true });
176
- }
177
- });
178
- }
179
- function showError(e) {
180
- if (isDebug()) {
181
- outputDebug("\u5BFC\u5165\u547D\u4EE4<>\u51FA\u9519:{}", e.stack);
182
- } else {
183
- console.error(e);
184
- }
185
- }
186
- function getId() {
187
- return Math.random().toString(36).substr(2);
188
- }
189
- function importModule(file) {
190
- return __async(this, null, function* () {
191
- let module2;
192
- try {
193
- module2 = require(file);
194
- } catch (e) {
195
- try {
196
- const cmd = yield import(`file://${file}`);
197
- module2 = cmd.default;
198
- } catch (e2) {
199
- throw e2;
200
- }
201
- }
202
- return module2;
203
- });
204
- }
205
-
206
- // src/prompt.ts
207
- var promptTypeMap = {
208
- boolean: "confirm",
209
- string: "text",
210
- number: "number",
211
- array: "list"
212
- };
213
- var supportedPromptTypes = ["text", "password", "invisible", "number", "confirm", "list", "toggle", "select", "multiselect", "autocomplete", "date", "autocompleteMultiselect"];
214
- var PromptManager = class {
215
- // 对应的FlexOption或FlexArgument
216
- constructor(promptable, promptArgs) {
217
- this._promptable = promptable;
218
- this.args = promptArgs === void 0 ? "auto" : promptArgs;
219
- }
220
- /**
221
- * 返回输入的是否是有效的prompt类型
222
- * @param type
223
- * @returns
224
- */
225
- isValid(type) {
226
- return supportedPromptTypes.includes(String(type));
227
- }
228
- /**
229
- * 推断是否需要提示
230
- *
231
- */
232
- isNeed(input, defaultValue) {
233
- const promptArg = this.args;
234
- const inputValue = input || defaultValue;
235
- const hasInput = !(inputValue === void 0);
236
- if (promptArg === true)
237
- return true;
238
- if (promptArg === false)
239
- return false;
240
- if (typeof promptArg == "object") {
241
- return !hasInput;
242
- }
243
- if (typeof promptArg == "string" && supportedPromptTypes.includes(promptArg)) {
244
- return !hasInput;
245
- }
246
- if (this._promptable.argChoices && this._promptable.argChoices.indexOf(inputValue) == -1) {
247
- return true;
248
- }
249
- return !hasInput;
250
- }
251
- /**
252
- * 返回生成prompt对象
253
- *
254
- * @param inputValue 从命令行输入的值
255
- */
256
- get(inputValue) {
257
- const { description, promptChoices, validate, defaultValue } = this._promptable;
258
- let input = inputValue || defaultValue;
259
- if (!this.isNeed(input, defaultValue))
260
- return;
261
- let promptType = this.infer(inputValue);
262
- const prompt = __spreadValues({
263
- type: promptType,
264
- name: this._promptable.name(),
265
- message: description,
266
- initial: input
267
- }, typeof this.args == "object" ? this.args : {});
268
- prompt.validate = validate == null ? void 0 : validate.bind(this._promptable);
269
- if (promptType == "multiselect")
270
- prompt.instructions = false;
271
- if (["select", "multiselect"].includes(promptType)) {
272
- let index = promptChoices == null ? void 0 : promptChoices.findIndex((item) => item.value == input);
273
- prompt.initial = index == -1 ? void 0 : index;
274
- }
275
- if (Array.isArray(promptChoices)) {
276
- prompt.choices = promptChoices;
277
- }
278
- return prompt;
279
- }
280
- /**
281
- * 推断prompt类型
282
- *
283
- * @param inputValue 从命令行输入的值
284
- */
285
- infer(inputValue) {
286
- const { argChoices, variadic, defaultValue } = this._promptable;
287
- let input = inputValue || defaultValue;
288
- let promptType = /(\<[\w\.]+\>)|(\[[\w\.]+\])/.test(this._promptable.flags) ? "text" : "confirm";
289
- let promptArg = this.args;
290
- if (this.isValid(promptArg)) {
291
- promptType = promptArg;
292
- } else {
293
- if (typeof promptArg == "object") {
294
- promptType = promptArg.type;
295
- } else {
296
- if (argChoices) {
297
- promptType = variadic ? "multiselect" : "select";
298
- } else {
299
- const datatype = Array.isArray(defaultValue) ? "array" : typeof defaultValue;
300
- if (Array.isArray(input) || variadic) {
301
- promptType = "list";
302
- } else {
303
- if (datatype in promptTypeMap) {
304
- promptType = promptTypeMap[datatype];
305
- }
306
- }
307
- }
308
- }
309
- }
310
- outputDebug("\u9009\u9879<{}> -> \u63D0\u793A\u7C7B\u578B<{}>", [this._promptable.name(), promptType]);
311
- return promptType;
312
- }
313
- };
314
-
315
- // src/option.ts
316
- var MixOption = class extends import_commander.Option {
317
- constructor(flags, description, optsOrDefault) {
318
- super(flags, description);
319
- let params = {};
320
- if (arguments.length == 3 && typeof arguments[2] == "object") {
321
- params = Object.assign({}, arguments[2]);
322
- } else if (arguments.length == 3) {
323
- params.default = arguments[2];
324
- }
325
- if (params.prompt === void 0)
326
- params.prompt = "auto";
327
- if (params.default)
328
- this.default(params.default, params.defaultDescription);
329
- if (params.choices)
330
- this.choices(params.choices);
331
- if (params.conflicts)
332
- this.conflicts(params.conflicts);
333
- if (params.env)
334
- this.env(params.env);
335
- if (params.argParser)
336
- this.argParser(params.argParser);
337
- if (params.hideHelp)
338
- this.hideHelp(params.hideHelp);
339
- if (params.hidden)
340
- this.hidden = params.hidden;
341
- if (params.mandatory)
342
- this.makeOptionMandatory(params.mandatory);
343
- if (params.implies)
344
- this.implies(params.implies);
345
- if (params.optional)
346
- this.optional = params.optional;
347
- if (typeof params.validate == "function")
348
- this._validate = params.validate.bind(this);
349
- if (params.required) {
350
- this.required = params.required;
351
- if (!this._validate)
352
- this._validate = (value) => String(value).length > 0;
353
- }
354
- this.prompt = new PromptManager(this, params.prompt);
355
- }
356
- validate(value) {
357
- if (typeof this._validate == "function") {
358
- return this._validate(value);
359
- } else {
360
- return true;
361
- }
362
- }
363
- // @ts-ignore
364
- choices(values) {
365
- if (!this.promptChoices) {
366
- this.promptChoices = values.map((choice) => {
367
- if (typeof choice == "object") {
368
- return choice;
369
- } else {
370
- return { title: choice, value: choice };
371
- }
372
- });
373
- }
374
- super.choices(this.promptChoices.map((item) => item.value));
375
- }
376
- resetChoices() {
377
- super.choices(this.promptChoices.map((item) => item.value));
378
- }
379
- addChoice(value) {
380
- if (!this.promptChoices || !Array.isArray(this.promptChoices))
381
- this.promptChoices = [];
382
- this.promptChoices.push(typeof value == "string" ? { title: value, value } : value);
383
- this.resetChoices();
384
- }
385
- removeChoice(value) {
386
- var _a;
387
- this.promptChoices = (_a = this.promptChoices) == null ? void 0 : _a.filter((choice) => choice.value !== value);
388
- this.resetChoices();
389
- }
390
- clearChoice() {
391
- this.promptChoices = [];
392
- this.resetChoices();
393
- }
394
- /**
395
- * 返回选项的提示对象
396
- *
397
- * @remarks
398
- *
399
- *
400
- *
401
- * @param inputValue
402
- * @returns
403
- */
404
- getPrompt(inputValue) {
405
- var _a;
406
- return (_a = this.prompt) == null ? void 0 : _a.get(inputValue);
407
- }
408
- };
409
-
410
- // src/command.ts
411
- var import_node_path2 = __toESM(require("path"));
412
- var import_node_fs = __toESM(require("fs"));
413
- var BREAK = Symbol("BREAK_ACTION");
414
- var MixCommand = class extends import_commander2.Command {
415
- // 是否启用交互提示
416
- constructor(name) {
417
- super(name);
418
- this._beforeHooks = [];
419
- this._afterHooks = [];
420
- this._customPrompts = [];
421
- this._optionValues = {};
422
- // 命令行输入的选项值
423
- this._actions = [];
424
- // 允许多个action
425
- this._enable_prompts = true;
426
- const self = this;
427
- if (!this.isRoot)
428
- addBuiltInOptions(this);
429
- this.hook("preAction", function() {
430
- return __async(this, arguments, function* () {
431
- self._optionValues = self.getOptionValues(this.hookedCommand);
432
- try {
433
- yield self.preActionHook.apply(self, arguments);
434
- } catch (e) {
435
- }
436
- });
437
- });
438
- }
439
- /**
440
- * 是否是根命令
441
- */
442
- get isRoot() {
443
- return !!!this.parent;
444
- }
445
- get actions() {
446
- return this._actions;
447
- }
448
- get beforeHooks() {
449
- return this._beforeHooks;
450
- }
451
- get afterHooks() {
452
- return this._afterHooks;
453
- }
454
- get fullname() {
455
- let names = [this.name()];
456
- let parent = this.parent;
457
- while (parent) {
458
- if (parent.name() !== "root") {
459
- names.unshift(parent.name());
460
- }
461
- parent = parent.parent;
462
- }
463
- return names.join(".");
464
- }
465
- /**
466
- * 返回根命令
467
- */
468
- root() {
469
- let root = this;
470
- while (root && root.parent != null) {
471
- root = root.parent;
472
- }
473
- return root;
474
- }
475
- action(fn) {
476
- const actionFunc = arguments[0];
477
- if (arguments.length == 1 && typeof actionFunc == "function") {
478
- this._actions.push({
479
- id: Math.random().toString(36).substring(2),
480
- enhance: false,
481
- fn: actionFunc
482
- });
483
- } else if (arguments.length == 2 && typeof actionFunc == "function" && typeof arguments[1] == "object") {
484
- const actionFn = arguments[0];
485
- const actionOpts = Object.assign({ at: "append" }, arguments[1]);
486
- if (actionOpts.at == "replace")
487
- this._actions = [];
488
- const actionItem = {
489
- id: actionOpts.id || Math.random().toString(36).substring(2),
490
- enhance: actionOpts.enhance == void 0 ? true : actionOpts.enhance,
491
- fn: actionFn
492
- };
493
- if (typeof actionOpts.at == "number") {
494
- this._actions.splice(Number(actionOpts.at), 0, actionItem);
495
- } else if (["append", "before"].includes(actionOpts.at)) {
496
- this._actions.push(actionItem);
497
- } else if (["preappend", "after"].includes(actionOpts.at)) {
498
- this._actions.splice(0, 0, actionItem);
499
- } else {
500
- this._actions.push(actionItem);
501
- }
502
- } else {
503
- console.log("[mixcli] action params error");
504
- }
505
- return super.action(this.getWrapperedAction());
506
- }
507
- /**
508
- * 读取命令配置值,包括父命令提供的配置选项
509
- * @param command
510
- */
511
- getOptionValues(command) {
512
- let opts = {};
513
- let parent = command;
514
- while (parent) {
515
- Object.assign(opts, parent._optionValues);
516
- parent = parent.parent;
517
- }
518
- return opts;
519
- }
520
- /**
521
- * 本函数在运行时子类进行action生成该命令的action
522
- */
523
- getWrapperedAction() {
524
- return this.wrapperWorkDirsAction(this.wrapperChainActions());
525
- }
526
- /**
527
- * 向上查找所有祖先命令
528
- */
529
- getAncestorCommands() {
530
- let cmds = [];
531
- let cmd = this;
532
- while (cmd) {
533
- cmd = cmd.parent;
534
- if (cmd) {
535
- cmds.push(cmd);
536
- }
537
- }
538
- return cmds;
539
- }
540
- /***
541
- * 将所有actions包装成一个链式调用的函数
542
- */
543
- wrapperChainActions() {
544
- const self = this;
545
- return function() {
546
- return __async(this, arguments, function* () {
547
- const args = Array.from(arguments);
548
- let preValue;
549
- let actionOpts = {}, actionArgs = [], cmd;
550
- if (args.length >= 2) {
551
- cmd = args[args.length - 1];
552
- actionOpts = args[args.length - 2];
553
- actionArgs = args.slice(0, args.length - 2);
554
- }
555
- yield self.executeBeforeHooks({ args: actionArgs, options: actionOpts, command: cmd });
556
- try {
557
- for (let action of self._actions) {
558
- try {
559
- if (action.enhance) {
560
- outputDebug("\u6267\u884C<{}>: args={}, options={}", () => [
561
- self.name(),
562
- actionArgs,
563
- actionOpts
564
- ]);
565
- preValue = yield action.fn.call(this, {
566
- command: cmd,
567
- value: preValue,
568
- args: actionArgs,
569
- options: actionOpts
570
- });
571
- } else {
572
- preValue = yield action.fn.apply(this, args);
573
- }
574
- if (preValue === BREAK)
575
- break;
576
- } catch (e) {
577
- outputDebug("\u547D\u4EE4{}\u7684Action({})\u6267\u884C\u51FA\u9519:{}", [self.name, action.id, e]);
578
- throw e;
579
- }
580
- }
581
- } finally {
582
- yield self.executeAfterHooks({
583
- value: preValue,
584
- args: actionArgs,
585
- options: actionOpts,
586
- command: cmd
587
- });
588
- }
589
- });
590
- };
591
- }
592
- /**
593
- * 当传入--work-dirs时用来处理工作目录
594
- */
595
- wrapperWorkDirsAction(fn) {
596
- const self = this;
597
- return function() {
598
- return __async(this, arguments, function* () {
599
- let workDirs = self._optionValues.workDirs;
600
- if (!workDirs) {
601
- return yield fn.apply(this, Array.from(arguments));
602
- }
603
- if (!Array.isArray(workDirs))
604
- workDirs = workDirs.split(",");
605
- workDirs = workDirs.reduce((dirs, dir) => {
606
- if (typeof dir == "string")
607
- dirs.push(...dir.split(","));
608
- return dirs;
609
- }, []);
610
- for (let workDir of workDirs) {
611
- const cwd = process.cwd();
612
- try {
613
- if (!import_node_path2.default.isAbsolute(workDir))
614
- workDir = import_node_path2.default.join(cwd, workDir);
615
- if (import_node_fs.default.existsSync(workDir) && import_node_fs.default.statSync(workDir).isDirectory()) {
616
- outputDebug("\u5207\u6362\u5230\u5DE5\u4F5C\u76EE\u5F55:{}", workDir);
617
- process.chdir(workDir);
618
- yield fn.apply(this, Array.from(arguments));
619
- } else {
620
- outputDebug("\u65E0\u6548\u7684\u5DE5\u4F5C\u76EE\u5F55:{}", workDir);
621
- }
622
- } catch (e) {
623
- throw e;
624
- } finally {
625
- process.chdir(cwd);
626
- }
627
- }
628
- });
629
- };
630
- }
631
- getOption(name) {
632
- return this.options.find((option) => option.name() == name);
633
- }
634
- /**
635
- * 添加一个Before钩子
636
- * @param listener
637
- * @param scope =false时代表只在本命令执行,=true时代表在本命令及其子命令执行
638
- * @returns
639
- */
640
- before(listener, scope = true) {
641
- this._beforeHooks.push([listener, scope]);
642
- return this;
643
- }
644
- executeBeforeHooks(args) {
645
- return __async(this, null, function* () {
646
- const hooks = this.beforeHooks.map(
647
- ([hook, scope]) => [hook, scope, this]
648
- );
649
- this.getAncestorCommands().forEach((cmd) => {
650
- hooks.unshift(
651
- ...cmd.beforeHooks.map(([hook, scope]) => {
652
- return [hook, scope, cmd];
653
- })
654
- );
655
- });
656
- for (let [hook, scope, cmd] of hooks) {
657
- if (!scope)
658
- continue;
659
- yield hook.call(cmd, args);
660
- }
661
- });
662
- }
663
- /**
664
- * 添加一个After钩子
665
- * @param listener
666
- * @param scope =false时代表只在本命令执行,=true时代表在本命令及其子命令执行
667
- * @returns
668
- */
669
- after(listener, scope = true) {
670
- this._afterHooks.push([listener, scope]);
671
- return this;
672
- }
673
- executeAfterHooks(args) {
674
- return __async(this, null, function* () {
675
- const hooks = this.afterHooks.map(
676
- ([hook, scope]) => [hook, scope, this]
677
- );
678
- this.getAncestorCommands().forEach((cmd) => {
679
- hooks.push(
680
- ...cmd.afterHooks.map(([hook, scope]) => {
681
- return [hook, scope, cmd];
682
- })
683
- );
684
- });
685
- for (let [hook, scope, cmd] of hooks) {
686
- if (!scope)
687
- continue;
688
- yield hook.call(cmd, args);
689
- }
690
- });
691
- }
692
- preActionHook(thisCommand, actionCommand) {
693
- return __async(this, null, function* () {
694
- if (this.isEnablePrompts()) {
695
- const questions = [
696
- ...this.generateAutoPrompts(),
697
- ...this._customPrompts
698
- ];
699
- if (questions.length > 0) {
700
- const results = yield (0, import_prompts.default)(questions);
701
- Object.entries(results).forEach(([key, value]) => {
702
- thisCommand.setOptionValue(key, value);
703
- });
704
- }
705
- }
706
- });
707
- }
708
- isEnablePrompts() {
709
- if (isEnablePrompts() === false) {
710
- return false;
711
- } else {
712
- return this._enable_prompts;
713
- }
714
- }
715
- /**
716
- * 生成选项自动提示
717
- *
718
- * @remarks
719
- * FlexCli要求所有未提供默认值的Option自动生成提示
720
- *
721
- * - 未提供默认值,并且是必选的参数Option
722
- * - 指定了choices但未提供有效值的Option
723
- *
724
- */
725
- generateAutoPrompts() {
726
- const options = this.options;
727
- const optionPromports = options.filter((option) => !option.hidden && option instanceof MixOption).map((option) => option.getPrompt(this._optionValues[option.name()])).filter((prompt) => prompt);
728
- outputDebug("\u547D\u4EE4<{}>\u81EA\u52A8\u751F\u6210{}\u4E2A\u9009\u9879\u63D0\u793A:{}", [
729
- this.name(),
730
- optionPromports.length,
731
- optionPromports.map((prompt) => `${prompt.name}(${prompt.type})`).join(",")
732
- ]);
733
- return optionPromports;
734
- }
735
- option(flags, description, options) {
736
- const option = new MixOption(...arguments);
737
- if (option.required && !this.isEnablePrompts())
738
- option.mandatory = true;
739
- return this.addOption(option);
740
- }
741
- /**
742
- * 添加提示
743
- *
744
- * @remarks
745
- *
746
- * 添加一些自定义提示
747
- *
748
- *
749
- * @param questions
750
- * @param show 是否显示提示信息,auto表示只有在用户没有提供option的值时才显示提示信息,always表示总是显示提示信息,never表示不显示提示信息
751
- * @returns
752
- */
753
- prompt(questions) {
754
- this._customPrompts.push(...Array.isArray(questions) ? questions : [questions]);
755
- return this;
756
- }
757
- /**
758
- *
759
- * 选择命令并执行
760
- *
761
- * @remorks
762
- *
763
- * 当命令具有多个子命令时,并且没有提供默认子命令时,提示用户选择一个子命令
764
- *
765
- */
766
- selectCommands() {
767
- return __async(this, null, function* () {
768
- const choices = this.commands.map((command2) => ({
769
- title: `${command2.description()}(${command2.name()})`,
770
- value: command2.name()
771
- }));
772
- const result = yield (0, import_prompts.default)({
773
- type: "select",
774
- name: "command",
775
- message: "\u8BF7\u9009\u62E9\u547D\u4EE4:",
776
- choices
777
- });
778
- const command = this.commands.find((command2) => command2.name() === result.command);
779
- yield command == null ? void 0 : command.parseAsync([result.command], { from: "user" });
780
- });
781
- }
782
- /**
783
- * 禁用/启用所有提示
784
- */
785
- disablePrompts() {
786
- this._enable_prompts = false;
787
- return this;
788
- }
789
- enablePrompts() {
790
- this._enable_prompts = true;
791
- return this;
792
- }
793
- };
794
-
795
- // src/finder.ts
796
- var import_getPackageJson = require("flex-tools/package/getPackageJson");
797
- var import_getPackageRootPath = require("flex-tools/package/getPackageRootPath");
798
- var import_glob = require("glob");
799
- var import_node_fs2 = __toESM(require("fs"));
800
- var import_node_path3 = __toESM(require("path"));
801
- function getMatchedDependencies(entry) {
802
- const pacakgeMacher = this.options.include;
803
- if (!(pacakgeMacher instanceof RegExp))
804
- return [];
805
- const { dependencies = {}, devDependencies = {}, peerDependencies = {}, optionalDependencies = {}, bundleDependencies = {} } = (0, import_getPackageJson.getPackageJson)(entry);
806
- const packageNames = [
807
- ...Object.keys(dependencies),
808
- ...Object.keys(devDependencies),
809
- ...Object.keys(peerDependencies),
810
- ...Object.keys(optionalDependencies),
811
- ...Object.keys(bundleDependencies)
812
- ];
813
- return packageNames.filter((name) => name !== "@voerka/cli" && pacakgeMacher.test(name));
814
- }
815
- function isMatched(str, reg) {
816
- const regexps = reg ? Array.isArray(reg) ? reg : [reg] : [];
817
- return regexps.some((regexp) => {
818
- if (typeof regexp === "string") {
819
- return new RegExp(regexp).test(str);
820
- } else if (regexp instanceof RegExp) {
821
- return regexp.test(str);
822
- } else {
823
- return false;
824
- }
825
- });
826
- }
827
- function findCliPaths(packageName, entry) {
828
- const includeMacher = this.options.include;
829
- const excludeMacher = this.options.exclude;
830
- if (!includeMacher)
831
- return [];
832
- const packageRoot = (0, import_getPackageRootPath.getPackageRootPath)(entry || process.cwd());
833
- const packagePath = packageName ? import_node_path3.default.dirname(require.resolve(packageName, { paths: [packageRoot] })) : packageRoot;
834
- if (!packagePath) {
835
- outputDebug("MixCli\u53EA\u80FD\u8FD0\u884C\u5728Nodejs\u73AF\u5883");
836
- return [];
837
- }
838
- const packageNames = getMatchedDependencies.call(this, packagePath);
839
- const cliDirs = [];
840
- if (entry !== void 0)
841
- cliDirs.push(import_node_path3.default.join(packagePath, this.options.cliDir));
842
- packageNames.filter((name) => {
843
- return isMatched(name, includeMacher) && !isMatched(name, excludeMacher);
844
- }).forEach((name) => {
845
- outputDebug("\u5339\u914D\u5305:{}", `${packageName ? name + " <- " + packageName : name}`);
846
- try {
847
- const packageEntry = import_node_path3.default.dirname(require.resolve(name, { paths: packagePath ? [packagePath] : [process.cwd()] }));
848
- const packageCliDir = import_node_path3.default.join(packageEntry, this.options.cliDir);
849
- let dependencies = getMatchedDependencies.call(this, packageEntry);
850
- cliDirs.push(...dependencies.reduce((result, dependencie) => {
851
- outputDebug("\u5339\u914D\u5305:{}", `${dependencie} <- ${name}`);
852
- result.push(...findCliPaths.call(this, dependencie, packageEntry));
853
- return result;
854
- }, []));
855
- if (import_node_fs2.default.existsSync(packageCliDir)) {
856
- cliDirs.push(packageCliDir);
857
- }
858
- } catch (e) {
859
- outputDebug("\u89E3\u6790\u5305<{}>\u8DEF\u5F84\u51FA\u9519\uFF1A{}", [name, e.stack]);
860
- }
861
- });
862
- return [...new Set(cliDirs)];
863
- }
864
- function findCommands(cli) {
865
- return __async(this, null, function* () {
866
- const cliDirs = findCliPaths.call(cli);
867
- const commands = [];
868
- const files = [];
869
- cliDirs.forEach((dir) => {
870
- (0, import_glob.globSync)("*", {
871
- cwd: dir,
872
- absolute: true
873
- }).forEach((file) => {
874
- const baseName = import_node_path3.default.basename(file);
875
- if (baseName.startsWith("_"))
876
- return;
877
- const ext = import_node_path3.default.extname(file).toLowerCase();
878
- if ([".js", ".cjs", ".mjs"].includes(ext)) {
879
- files.push(file);
880
- } else if (import_node_fs2.default.statSync(file).isDirectory()) {
881
- files.push(import_node_path3.default.join(file, "index.js"));
882
- files.push(import_node_path3.default.join(file, "index.cjs"));
883
- files.push(import_node_path3.default.join(file, "index.mjs"));
884
- }
885
- });
886
- });
887
- for (let file of files) {
888
- if (!import_node_fs2.default.existsSync(file))
889
- continue;
890
- try {
891
- outputDebug("\u5BFC\u5165\u547D\u4EE4:{}", file);
892
- if (file.endsWith(".cjs") || file.endsWith(".js")) {
893
- commands.push(yield importModule(file));
894
- } else if (file.endsWith(".mjs")) {
895
- const cmd = yield import(`file://${file}`);
896
- commands.push(cmd.default);
897
- }
898
- } catch (e) {
899
- outputDebug(e);
900
- }
901
- }
902
- return commands;
903
- });
904
- }
905
-
906
- // src/cli.ts
907
- var import_asyncSignal = require("flex-tools/async/asyncSignal");
908
- var import_string_prototype = __toESM(require("string.prototype.replaceall"));
909
- import_string_prototype.default.shim();
910
- var MixCli = class extends import_liteEvent.LiteEvent {
911
- constructor(options) {
912
- super();
913
- this.findSignals = [];
914
- this.options = (0, import_assignObject.assignObject)({
915
- name: "mixcli",
916
- package: null,
917
- cliDir: "cli",
918
- prompt: "auto"
919
- }, options);
920
- this.createRootCommand();
921
- }
922
- get context() {
923
- return this.options.context;
924
- }
925
- get name() {
926
- return this.options.name;
927
- }
928
- /**
929
- * 是否禁用了所有的交互提示
930
- */
931
- get isDisabledPrompts() {
932
- return this.root.rawArgs.includes("--no-prompts");
933
- }
934
- /**
935
- * 扫描当前工程的依赖,加载匹配include的依赖下的命令
936
- */
937
- installCommands() {
938
- return __async(this, null, function* () {
939
- const cmders = yield findCommands(this);
940
- for (let cmder of cmders) {
941
- try {
942
- if (typeof cmder === "function") {
943
- let cmds = cmder(this);
944
- cmds = cmds ? Array.isArray(cmds) ? cmds : [cmds] : [];
945
- this.register(() => cmds);
946
- }
947
- } catch (e) {
948
- }
949
- }
950
- });
951
- }
952
- /**
953
- * 创建根命令
954
- *
955
- */
956
- createRootCommand() {
957
- this.root = new MixCommand(this.name);
958
- this.root.helpOption("-h, --help").action(() => {
959
- if (this.options.logo)
960
- import_logsets2.default.log(fixIndent(this.options.logo, 2));
961
- console.log();
962
- let title = this.options.title || this.options.name;
963
- if (Array.isArray(title)) {
964
- import_logsets2.default.log(String(title[0]).firstUpper(), [...title.slice(1)]);
965
- } else {
966
- import_logsets2.default.log(`${title.firstUpper()} Version: {}`, this.options.version);
967
- }
968
- if (this.options.description)
969
- import_logsets2.default.log(import_logsets2.default.colors.darkGray(this.options.description));
970
- console.log();
971
- this.root.help();
972
- });
973
- addBuiltInOptions(this.root);
974
- if (this.options.before)
975
- this.root.hook("preAction", this.options.before);
976
- if (this.options.after)
977
- this.root.hook("postAction", this.options.after);
978
- }
979
- /**
980
- * 添加帮助选项
981
- *
982
- * @param text 帮助文本
983
- * @param position 显示位置,可选值:before|after|beforeAll|afterAll
984
- * @param fixIndent 是否自动修正缩进,如果为true,则会自动修正缩进,当显示多行时文本时,会自动修正缩进
985
- *
986
- */
987
- addHelp(text, { pos = "beforeAll", alignIndent = true }) {
988
- if (alignIndent)
989
- text = fixIndent(text, alignIndent);
990
- this.root.addHelpText(pos, text);
991
- }
992
- /**
993
- * 注册一个命令
994
- * @param cmd
995
- */
996
- register(cmd) {
997
- if (typeof cmd == "function") {
998
- let result = cmd(this);
999
- let cmds = result instanceof Array ? result : result == void 0 ? [] : [result];
1000
- for (let cmd2 of cmds) {
1001
- if (cmd2 instanceof MixCommand) {
1002
- if (this.hasCommand(cmd2.name())) {
1003
- import_logsets2.default.error(`Command <${cmd2.name()}> has been registered!`);
1004
- } else {
1005
- this.root.addCommand(cmd2);
1006
- cmd2._cli = this;
1007
- this.emit("register", cmd2.fullname, true);
1008
- }
1009
- }
1010
- }
1011
- } else {
1012
- import_logsets2.default.error("Invalid command");
1013
- }
1014
- }
1015
- hasCommand(name) {
1016
- return this.root.commands.some((c) => c.name() == name);
1017
- }
1018
- /**
1019
- * 根据命令名称查找命令
1020
- *
1021
- * @remarks
1022
- *
1023
- * find("dev")
1024
- * find("dev.microservice") 支持多级命令
1025
- * find("abc",DevCommand) 允许指定从DevCommand下开始查找abc命令
1026
- *
1027
- * @param name
1028
- */
1029
- get(name) {
1030
- const names = name.split(".");
1031
- let curCmd = this.root;
1032
- let resultCmd;
1033
- while (names.length > 0) {
1034
- const topName = names.shift();
1035
- const r = curCmd.commands.find((c) => c.name() == topName);
1036
- if (r && names.length == 0) {
1037
- resultCmd = r;
1038
- }
1039
- curCmd = r;
1040
- }
1041
- return resultCmd;
1042
- }
1043
- /**
1044
- * 查找一个命令
1045
- *
1046
- * 如果命令不存在,则等待命令注册后再返回
1047
- *
1048
- * 在多包场景下,如果命令在其他包中注册并且该包中的命令还没注册,则会等待命令注册后再返回
1049
- *
1050
- * @param name
1051
- * @returns
1052
- */
1053
- find(name) {
1054
- const cmd = this.get(name);
1055
- if (cmd) {
1056
- return Promise.resolve(cmd);
1057
- } else {
1058
- const signal = (0, import_asyncSignal.asyncSignal)();
1059
- this.findSignals.push(signal);
1060
- return new Promise((resolve) => {
1061
- let listener;
1062
- listener = this.on("register", (fullname) => {
1063
- if (fullname == `${this.name}.${name}`) {
1064
- listener.off();
1065
- signal.resolve();
1066
- this.findSignals = this.findSignals.filter((s) => s != signal);
1067
- resolve(this.get(name));
1068
- }
1069
- }, { objectify: true });
1070
- });
1071
- }
1072
- }
1073
- /**
1074
- * 判断命令是否存在
1075
- *
1076
- * @param name
1077
- * @returns
1078
- */
1079
- exists(name) {
1080
- if (name in this.root.commands) {
1081
- return true;
1082
- } else {
1083
- return this.get(name) != void 0;
1084
- }
1085
- }
1086
- /**
1087
- * 运行命令行程序
1088
- */
1089
- run() {
1090
- this.installCommands().then(() => {
1091
- return Promise.all(this.findSignals.map((signal) => signal(1e4))).then(() => {
1092
- this.root.parseAsync(process.argv);
1093
- });
1094
- });
1095
- }
1096
- /**
1097
- * 创建一个命令
1098
- *
1099
- *
1100
- */
1101
- create() {
1102
- }
1103
- };
1104
- // Annotate the CommonJS export names for ESM import in node:
1105
- 0 && (module.exports = {
1106
- BREAK,
1107
- MixCli,
1108
- MixCommand,
1109
- MixOption,
1110
- addBuiltInOptions,
1111
- createFileByTemplate,
1112
- fileExists,
1113
- fixIndent,
1114
- getId,
1115
- importModule,
1116
- isDebug,
1117
- isEnablePrompts,
1118
- mkDirs,
1119
- mkdir,
1120
- outputDebug,
1121
- outputStr,
1122
- readFile,
1123
- showError,
1124
- writeFile
1125
- });
1
+ var U=Object.defineProperty;var _=Object.getOwnPropertySymbols;var K=Object.prototype.hasOwnProperty,z=Object.prototype.propertyIsEnumerable;var j=(s,n,t)=>n in s?U(s,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[n]=t,D=(s,n)=>{for(var t in n||(n={}))K.call(n,t)&&j(s,t,n[t]);if(_)for(var t of _(n))z.call(n,t)&&j(s,t,n[t]);return s};var g=(s=>typeof require!="undefined"?require:typeof Proxy!="undefined"?new Proxy(s,{get:(n,t)=>(typeof require!="undefined"?require:n)[t]}):s)(function(s){if(typeof require!="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+s+'" is not supported')});var l=(s,n,t)=>new Promise((e,i)=>{var o=a=>{try{p(t.next(a))}catch(c){i(c)}},r=a=>{try{p(t.throw(a))}catch(c){i(c)}},p=a=>a.done?e(a.value):Promise.resolve(a.value).then(o,r);p((t=t.apply(s,n)).next())});import"flex-tools/string";import{LiteEvent as nt}from"flex-tools/events/liteEvent";import f from"logsets";import{assignObject as rt}from"flex-tools/object/assignObject";import{Command as Z}from"commander";import L from"prompts";import{Option as Y}from"commander";import{isPlainObject as V}from"flex-tools/typecheck/isPlainObject";import{isNumber as J}from"flex-tools/typecheck/isNumber";import x from"fs-extra";import E from"node:path";import{promisify as b}from"flex-tools/func/promisify";import H from"logsets";function ft(s,n){H.log(C(s),n)}function C(s,n){if((n==null||n===!0?0:typeof n=="number"?n:-1)==-1)return s;let e=s.split(`
2
+ `),i=e.reduce((o,r,p)=>{var c;if(p==0)return o;let a=((c=r.match(/^\s*/))==null?void 0:c[0].length)||0;return Math.min(o,a)},9999);return e=e.map(o=>o.substring(i)),e.join(`
3
+ `)}function M(s){s.option("--work-dirs <values...>","\u6307\u5B9A\u5DE5\u4F5C\u76EE\u5F55",{hidden:!0,optional:!0,required:!0,prompt:!1}),s.option("--disable-prompts","\u7981\u7528\u6240\u6709\u4EA4\u4E92\u63D0\u793A",{hidden:!0,prompt:!1}),s.option("--debug-cli","\u663E\u793A\u8C03\u8BD5\u4FE1\u606F",{hidden:!0,prompt:!1})}function R(){return process.argv.includes("--debug-cli")}function T(){return process.argv.includes("--disable-prompts")}function m(s,...n){let t=n.length==1&&typeof n[0]=="function"?n[0]():n;R()&&H.log(`[MixCli] ${s}`,...t)}var dt=b(x.exists,{parseCallback:s=>s[0]}),ht=b(x.readFile),gt=b(x.writeFile),G=b(x.mkdir);function yt(e,i){return l(this,arguments,function*(s,{callback:n,base:t}){if(!Array.isArray(s))throw new Error("dirs\u53C2\u6570\u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32\u6570\u7EC4");for(let o of s)E.isAbsolute(o)||(o=E.join(t||process.cwd(),o)),typeof n=="function"&&n(o),yield G(o,{recursive:!0})})}function xt(s){R()?m("\u5BFC\u5165\u547D\u4EE4<>\u51FA\u9519:{}",s.stack):console.error(s)}function bt(s){return s.replace(/-([a-z])/g,(n,t)=>t.toUpperCase())}function Ct(){return Math.random().toString(36).substr(2)}function S(s){return l(this,null,function*(){let n;try{n=g(s)}catch(t){try{n=(yield import(`file://${s}`)).default}catch(e){throw e}}return n})}var I={boolean:"confirm",string:"text",number:"number",array:"list",date:"date"},Q=["text","password","invisible","number","confirm","list","toggle","select","multiselect","autocomplete","date","autocompleteMultiselect"],P=class{constructor(n,t){this.cliOption=n;this.params=t}isValidPromptType(n){return Q.includes(String(n))}isNeedPrompt(n,t){let e=this.params,i=n||t,o=i!==void 0;return e===!0?!0:e===!1?!1:e==="auto"||V(e)?!o:typeof e=="string"&&this.isValidPromptType(e)?!0:/(\<s*\w\s*\>)/.test(this.cliOption.flags)?!o:this.cliOption.argChoices&&this.cliOption.argChoices.indexOf(i)==-1?!0:!o}_getChoices(){var e;let n=[],t=(e=this.cliOption.params)==null?void 0:e.choices;if(this.cliOption.argChoices)n=this.cliOption.argChoices.map(i=>typeof i=="string"?{title:i,value:i}:i);else if(t)n=typeof t=="function"?t:[];else return[];return n}infer(n){let{variadic:t,defaultValue:e}=this.cliOption,i=n||e,o="text",r=this.params;if(this.isValidPromptType(r))o=r;else if(V(r))o=r.type;else{let p=/(\[\s*\w+\.\.\.\s*])|(\<\s*\w+\.\.\.\s*>)/.test(this.cliOption.flags),a=/(\<s*\w+\s*\>)|(\[\w+\])/.test(this.cliOption.flags),c=!/(\[\s*\w+s*])|(\<\s*\w+\s*>)/.test(this.cliOption.flags),y=J(e),A=e&&e instanceof Date,h=Array.isArray(i)?"array":i instanceof Date?"date":typeof i,d=this.cliOption.params;if(d&&d.choices){let w=d.choices;c&&Array.isArray(w)&&w.length==2?o="toggle":o=t?"multiselect":"select"}else p?o="list":A?o="date":y?o="number":a?o="text":c||typeof e=="boolean"?o="confirm":h in I&&(o=I[h])}return m("\u9009\u9879<{}> -> \u63D0\u793A\u7C7B\u578B<{}>",[this.cliOption.name(),o]),o}get(n){var p;let{description:t,defaultValue:e}=this.cliOption,i=n||e;if(!this.isNeedPrompt(i,e))return;let o=this.infer(n),r=D({type:o,name:this.cliOption.attributeName(),message:t,initial:i},typeof this.params=="object"?this.params:{});if(r.validate=(p=this.cliOption.params)==null?void 0:p.validate,o=="multiselect"&&(r.instructions=!1),r.choices=r.choices||this._getChoices(),["select","multiselect"].includes(o)||o=="toggle"&&Array.isArray(r.choices)&&(r.active||(r.active=r.choices[0].value),r.inactive||(r.inactive=r.choices[1].value)),i&&typeof r.initial!="function"&&r.choices&&Array.isArray(r.choices))if(o=="select"){let a=Array.isArray(r.choices)?r.choices.findIndex(c=>c.value==i):-1;a!=-1&&(r.initial=a)}else o=="multiselect"&&r.choices.forEach(a=>{(Array.isArray(i)&&i.includes(a.value)||a.value==i)&&(a.selected=!0)});return r}};var O=class extends Y{constructor(t,e,i){super(t,e);this.params=i;this.__MIX_OPTION__=!0;this._setOption(i||{}),this.prompt=new P(this,i==null?void 0:i.prompt)}_setOption(t){t.default&&this.default(t.default,t.defaultDescription),t.conflicts&&this.conflicts(t.conflicts),t.envVar&&this.env(t.envVar),t.parseArg&&this.argParser(t.parseArg),t.hidden&&(this.hidden=t.hidden),t.mandatory&&this.makeOptionMandatory(t.mandatory),t.implies&&this.implies(t.implies),t.optional&&(this.optional=t.optional),t.variadic&&(this.variadic=t.variadic),t.negate&&(this.negate=t.negate),t.preset&&this.preset(t.preset),t.required&&(this.required=t.required),Array.isArray(t.choices)&&this.choices(t.choices.map(e=>typeof e=="string"?e:e.value))}getPrompt(t){var e;return(e=this.prompt)==null?void 0:e.get(t)}};import N from"node:path";import $ from"node:fs";var tt=Symbol("BREAK_ACTION"),v=class extends Z{constructor(t){super(t);this.__MIX_COMMAND__=!0;this._beforeHooks=[];this._afterHooks=[];this._customPrompts=[];this._optionValues={};this._actions=[];this._enable_prompts=!0;let e=this;this.isRoot||M(this),this.hook("preAction",function(){return l(this,arguments,function*(){e._optionValues=e.getOptionValues(this.hookedCommand),yield e.preActionHook.apply(e,arguments)})})}get isRoot(){return this.parent==null}get optionValues(){return this._optionValues}get actions(){return this._actions}get beforeHooks(){return this._beforeHooks}get afterHooks(){return this._afterHooks}get fullname(){let t=[this.name()],e=this.parent;for(;e;)e.name()!=="root"&&t.unshift(e.name()),e=e.parent;return t.join(".")}root(){let t=this;for(;t&&t.parent!=null;)t=t.parent;return t}action(){let t=arguments[0];if(arguments.length==1&&typeof t=="function")this._actions.push({id:Math.random().toString(36).substring(2),enhance:!1,fn:t});else if(arguments.length==2&&typeof t=="function"&&typeof arguments[1]=="object"){let e=arguments[0],i=Object.assign({at:"append"},arguments[1]);i.at=="replace"&&(this._actions=[]);let o={id:i.id||Math.random().toString(36).substring(2),enhance:i.enhance==null?!0:i.enhance,fn:e};typeof i.at=="number"?this._actions.splice(Number(i.at),0,o):["append","before"].includes(i.at)?this._actions.push(o):["preappend","after"].includes(i.at)?this._actions.splice(0,0,o):this._actions.push(o)}else console.log("[mixcli] action params error");return super.action(this.getWrapperedAction())}getOptionValues(t){let e={},i=t;for(;i;)Object.assign(e,i.optionValues),i=i.parent;return e}getWrapperedAction(){return this.wrapperWorkDirsAction(this.wrapperChainActions())}getAncestorCommands(){let t=[],e=this;for(;e;)e=e.parent,e&&t.push(e);return t}wrapperChainActions(){let t=this;return function(){return l(this,arguments,function*(){let e=Array.from(arguments),i,o={},r=[],p;e.length>=2&&(p=e[e.length-1],o=e[e.length-2],r=e.slice(0,e.length-2)),yield t.executeBeforeHooks({args:r,options:o,command:p});try{for(let a of t._actions)try{if(a.enhance?(m("\u6267\u884C<{}>: args={}, options={}",()=>[t.name(),r,o]),i=yield a.fn.call(this,{command:p,value:i,args:r,options:o})):i=yield a.fn.apply(this,e),i===tt)break}catch(c){throw m("\u547D\u4EE4{}\u7684Action({})\u6267\u884C\u51FA\u9519:{}",[t.name,a.id,c]),c}}finally{yield t.executeAfterHooks({value:i,args:r,options:o,command:p})}})}}wrapperWorkDirsAction(t){let e=this;return function(){return l(this,arguments,function*(){let i=e._optionValues.workDirs;if(!i)return yield t.apply(this,Array.from(arguments));Array.isArray(i)||(i=i.split(",")),i=i.reduce((o,r)=>(typeof r=="string"&&o.push(...r.split(",")),o),[]);for(let o of i){let r=process.cwd();try{N.isAbsolute(o)||(o=N.join(r,o)),$.existsSync(o)&&$.statSync(o).isDirectory()?(m("\u5207\u6362\u5230\u5DE5\u4F5C\u76EE\u5F55:{}",o),process.chdir(o),yield t.apply(this,Array.from(arguments))):m("\u65E0\u6548\u7684\u5DE5\u4F5C\u76EE\u5F55:{}",o)}finally{process.chdir(r)}}})}}getOption(t){return this.options.find(e=>e.name()==t)}before(t,e=!0){return this._beforeHooks.push([t,e]),this}executeBeforeHooks(t){return l(this,null,function*(){let e=this.beforeHooks.map(([i,o])=>[i,o,this]);this.getAncestorCommands().forEach(i=>{e.unshift(...i.beforeHooks.map(([o,r])=>[o,r,i]))});for(let[i,o,r]of e)o&&(yield i.call(r,t))})}after(t,e=!0){return this._afterHooks.push([t,e]),this}executeAfterHooks(t){return l(this,null,function*(){let e=this.afterHooks.map(([i,o])=>[i,o,this]);this.getAncestorCommands().forEach(i=>{e.push(...i.afterHooks.map(([o,r])=>[o,r,i]))});for(let[i,o,r]of e)o&&(yield i.call(r,t))})}preActionHook(t){return l(this,null,function*(){if(this.isEnablePrompts()){let e=[...this.generateAutoPrompts(),...this._customPrompts];if(e.length>0){let i=yield L(e);Object.entries(i).forEach(([o,r])=>{t.setOptionValue(o,r)})}}})}isEnablePrompts(){return T()?!1:this._enable_prompts}generateAutoPrompts(){let e=this.options.filter(i=>!i.hidden&&i.__MIX_OPTION__).map(i=>i.getPrompt(this._optionValues[i.attributeName()])).filter(i=>i);return m("\u547D\u4EE4<{}>\u81EA\u52A8\u751F\u6210{}\u4E2A\u9009\u9879\u63D0\u793A:{}",[this.name(),e.length,e.map(i=>`${i.name}(${i.type})`).join(",")]),e}option(t,e,i){let o=new O(t,e,i);return o.required&&!this.isEnablePrompts()&&(o.mandatory=!0),this.addOption(o)}prompt(t){return this._customPrompts.push(...Array.isArray(t)?t:[t]),this}selectCommands(){return l(this,null,function*(){let t=this.commands.map(o=>({title:`${o.description()}(${o.name()})`,value:o.name()})),e=yield L({type:"select",name:"command",message:"\u8BF7\u9009\u62E9\u547D\u4EE4:",choices:t}),i=this.commands.find(o=>o.name()===e.command);yield i==null?void 0:i.parseAsync([e.command],{from:"user"})})}disablePrompts(){return this._enable_prompts=!1,this}enablePrompts(){return this._enable_prompts=!0,this}};import{getPackageJson as et}from"flex-tools/package/getPackageJson";import{getPackageRootPath as it}from"flex-tools/package/getPackageRootPath";import{globSync as ot}from"glob";import k from"node:fs";import u from"node:path";function B(s){let n=this.options.include;if(!(n instanceof RegExp))return[];let{dependencies:t={},devDependencies:e={},peerDependencies:i={},optionalDependencies:o={},bundleDependencies:r={}}=et(s);return[...Object.keys(t),...Object.keys(e),...Object.keys(i),...Object.keys(o),...Object.keys(r)].filter(a=>a!=="@voerka/cli"&&n.test(a))}function q(s,n){return(n?Array.isArray(n)?n:[n]:[]).some(e=>typeof e=="string"?new RegExp(e).test(s):e instanceof RegExp?e.test(s):!1)}function F(s,n){let t=this.options.include,e=this.options.exclude;if(!t)return[];let i=it(n||process.cwd()),o=s?u.dirname(g.resolve(s,{paths:[i]})):i;if(!o)return m("MixCli\u53EA\u80FD\u8FD0\u884C\u5728Nodejs\u73AF\u5883"),[];let r=B.call(this,o),p=[];return n!==void 0&&p.push(u.join(o,this.options.cliDir)),r.filter(a=>q(a,t)&&!q(a,e)).forEach(a=>{m("\u5339\u914D\u5305:{}",`${s?a+" <- "+s:a}`);try{let c=u.dirname(g.resolve(a,{paths:o?[o]:[process.cwd()]})),y=u.join(c,this.options.cliDir),A=B.call(this,c);p.push(...A.reduce((h,d)=>(m("\u5339\u914D\u5305:{}",`${d} <- ${a}`),h.push(...F.call(this,d,c)),h),[])),k.existsSync(y)&&p.push(y)}catch(c){m("\u89E3\u6790\u5305<{}>\u8DEF\u5F84\u51FA\u9519\uFF1A{}",[a,c.stack])}}),[...new Set(p)]}function W(s){return l(this,null,function*(){let n=F.call(s),t=[],e=[];n.forEach(i=>{ot("*",{cwd:i,absolute:!0}).forEach(o=>{if(u.basename(o).startsWith("_"))return;let p=u.extname(o).toLowerCase();[".js",".cjs",".mjs"].includes(p)?e.push(o):k.statSync(o).isDirectory()&&(e.push(u.join(o,"index.js")),e.push(u.join(o,"index.cjs")),e.push(u.join(o,"index.mjs")))})});for(let i of e)if(k.existsSync(i))try{if(m("\u5BFC\u5165\u547D\u4EE4:{}",i),i.endsWith(".cjs")||i.endsWith(".js"))t.push(yield S(i));else if(i.endsWith(".mjs")){let o=yield import(`file://${i}`);t.push(o.default)}}catch(o){m(o)}return t})}import{asyncSignal as st}from"flex-tools/async/asyncSignal";import at from"string.prototype.replaceall";at.shim();var X=class extends nt{constructor(t){super();this.findSignals=[];this.options=rt({name:"mixcli",package:null,cliDir:"cli",prompt:"auto",ignoreError:!1},t),this.createRootCommand()}get context(){return this.options.context}get name(){return this.options.name}get isDisabledPrompts(){return this.root.rawArgs.includes("--no-prompts")}installCommands(){return l(this,null,function*(){let t=yield W(this);for(let e of t)try{if(typeof e=="function"){let i=e(this);i=i?Array.isArray(i)?i:[i]:[],this.register(()=>i)}}catch(i){m("\u6CE8\u518C\u547D\u4EE4\u5931\u8D25:{}",i.stack)}})}createRootCommand(){this.root=new v(this.name),this.root.helpOption("-h, --help").action(()=>{this.options.logo&&f.log(C(this.options.logo,2)),console.log();let t=this.options.title||this.options.name;Array.isArray(t)?f.log(String(t[0]).firstUpper(),[...t.slice(1)]):f.log(`${t.firstUpper()} Version: {}`,this.options.version),this.options.description&&f.log(f.colors.darkGray(this.options.description)),console.log(),this.root.help()}),M(this.root),this.options.before&&this.root.hook("preAction",this.options.before),this.options.after&&this.root.hook("postAction",this.options.after)}addHelp(t,{pos:e="beforeAll",alignIndent:i=!0}){i&&(t=C(t,i)),this.root.addHelpText(e,t)}register(t){if(typeof t=="function"){let e=t(this),i=e instanceof Array?e:e==null?[]:[e];for(let o of i)o.__MIX_COMMAND__?this.hasCommand(o.name())?f.error(`Command <${o.name()}> has been registered!`):(m("\u6CE8\u518C\u547D\u4EE4:{}",o.fullname),this.root.addCommand(o),o._cli=this,this.emit("register",o.fullname,!0)):f.error(`Command <${o.toString()}> is not a valid command!`)}else f.error("Invalid command")}hasCommand(t){return this.root.commands.some(e=>e.name()==t)}get(t){let e=t.split("."),i=this.root,o;for(;e.length>0;){let r=e.shift(),p=i.commands.find(a=>a.name()==r);p&&e.length==0&&(o=p),i=p}return o}find(t){let e=this.get(t);if(e)return Promise.resolve(e);{let i=st();return this.findSignals.push(i),new Promise(o=>{let r;r=this.on("register",p=>{p==`${this.name}.${t}`&&(r.off(),i.resolve(),this.findSignals=this.findSignals.filter(a=>a!=i),o(this.get(t)))},{objectify:!0})})}}exists(t){return t in this.root.commands?!0:this.get(t)!=null}run(){this.installCommands().then(()=>Promise.all(this.findSignals.map(t=>t(1e4))).then(()=>{this.root.parseAsync(process.argv)}))}};export{tt as BREAK,X as MixCli,v as MixCommand,O as MixOption,P as MixOptionPrompt,M as addBuiltInOptions,dt as fileExists,C as fixIndent,Ct as getId,bt as hyphenToCamelCase,S as importModule,R as isDebug,T as isDisablePrompts,yt as mkDirs,G as mkdir,m as outputDebug,ft as outputStr,I as promptTypeMap,ht as readFile,xt as showError,Q as supportedPromptTypes,gt as writeFile};
1126
4
  //# sourceMappingURL=index.js.map