bob-core 2.1.0 → 3.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/cjs/package-I_hjzzxG.cjs +1 -0
  2. package/dist/cjs/src/Cli.d.ts +4 -6
  3. package/dist/cjs/src/Command.d.ts +27 -50
  4. package/dist/cjs/src/CommandParser.d.ts +48 -50
  5. package/dist/cjs/src/CommandRegistry.d.ts +5 -5
  6. package/dist/cjs/src/CommandSignatureParser.d.ts +22 -25
  7. package/dist/cjs/src/CommandWithSignature.d.ts +21 -25
  8. package/dist/cjs/src/Flags.d.ts +25 -0
  9. package/dist/cjs/src/commands/HelpCommand.d.ts +2 -0
  10. package/dist/cjs/src/contracts/index.d.ts +0 -1
  11. package/dist/cjs/src/errors/BadCommandArgument.d.ts +14 -0
  12. package/dist/cjs/src/errors/BadCommandFlag.d.ts +14 -0
  13. package/dist/cjs/src/errors/InvalidFlag.d.ts +9 -0
  14. package/dist/cjs/src/errors/MissingRequiredFlagValue.d.ts +7 -0
  15. package/dist/cjs/src/errors/index.d.ts +4 -4
  16. package/dist/cjs/src/index.d.ts +3 -2
  17. package/dist/cjs/src/index.js +5 -14
  18. package/dist/cjs/src/lib/helpers.d.ts +1 -0
  19. package/dist/cjs/src/lib/types.d.ts +72 -18
  20. package/dist/cjs/src/options/HelpOption.d.ts +11 -10
  21. package/dist/esm/package-DXx2gXIL.js +59 -0
  22. package/dist/esm/src/Cli.d.ts +4 -6
  23. package/dist/esm/src/Command.d.ts +27 -50
  24. package/dist/esm/src/CommandParser.d.ts +48 -50
  25. package/dist/esm/src/CommandRegistry.d.ts +5 -5
  26. package/dist/esm/src/CommandSignatureParser.d.ts +22 -25
  27. package/dist/esm/src/CommandWithSignature.d.ts +21 -25
  28. package/dist/esm/src/Flags.d.ts +25 -0
  29. package/dist/esm/src/commands/HelpCommand.d.ts +2 -0
  30. package/dist/esm/src/contracts/index.d.ts +0 -1
  31. package/dist/esm/src/errors/BadCommandArgument.d.ts +14 -0
  32. package/dist/esm/src/errors/BadCommandFlag.d.ts +14 -0
  33. package/dist/esm/src/errors/InvalidFlag.d.ts +9 -0
  34. package/dist/esm/src/errors/MissingRequiredFlagValue.d.ts +7 -0
  35. package/dist/esm/src/errors/index.d.ts +4 -4
  36. package/dist/esm/src/index.d.ts +3 -2
  37. package/dist/esm/src/index.js +926 -1070
  38. package/dist/esm/src/lib/helpers.d.ts +1 -0
  39. package/dist/esm/src/lib/types.d.ts +72 -18
  40. package/dist/esm/src/options/HelpOption.d.ts +11 -10
  41. package/package.json +11 -12
  42. package/dist/cjs/package-DYSfqWOt.cjs +0 -1
  43. package/dist/cjs/src/contracts/CommandOption.d.ts +0 -6
  44. package/dist/cjs/src/errors/BadCommandOption.d.ts +0 -12
  45. package/dist/cjs/src/errors/BadCommandParameter.d.ts +0 -12
  46. package/dist/cjs/src/errors/InvalidOption.d.ts +0 -9
  47. package/dist/cjs/src/errors/MissingRequiredOptionValue.d.ts +0 -7
  48. package/dist/cjs/src/lib/optionHelpers.d.ts +0 -5
  49. package/dist/cjs/src/lib/valueConverter.d.ts +0 -10
  50. package/dist/esm/package-uVOgoItG.js +0 -33
  51. package/dist/esm/src/contracts/CommandOption.d.ts +0 -6
  52. package/dist/esm/src/errors/BadCommandOption.d.ts +0 -12
  53. package/dist/esm/src/errors/BadCommandParameter.d.ts +0 -12
  54. package/dist/esm/src/errors/InvalidOption.d.ts +0 -9
  55. package/dist/esm/src/errors/MissingRequiredOptionValue.d.ts +0 -7
  56. package/dist/esm/src/lib/optionHelpers.d.ts +0 -5
  57. package/dist/esm/src/lib/valueConverter.d.ts +0 -10
@@ -1,1079 +1,935 @@
1
- import y from "prompts";
2
- import a from "chalk";
3
- import q from "minimist";
4
- import I from "node:fs";
5
- import x from "node:path";
6
- class S {
7
- logger;
8
- constructor(t) {
9
- this.logger = t.logger;
10
- }
11
- /**
12
- * Logger methods
13
- */
14
- log(...t) {
15
- this.logger.log(...t);
16
- }
17
- info(...t) {
18
- this.logger.info(...t);
19
- }
20
- warn(...t) {
21
- this.logger.warn(...t);
22
- }
23
- error(...t) {
24
- this.logger.error(...t);
25
- }
26
- debug(...t) {
27
- this.logger.debug(...t);
28
- }
29
- /**
30
- * Prompt utils
31
- */
32
- async askForConfirmation(t = "Do you want to continue?", e) {
33
- return (await y({
34
- type: "confirm",
35
- name: "value",
36
- message: t,
37
- initial: e ?? !1
38
- })).value;
39
- }
40
- async askForInput(t, e, i) {
41
- return (await y({
42
- type: "text",
43
- name: "value",
44
- message: t,
45
- initial: e,
46
- ...i
47
- }))?.value ?? null;
48
- }
49
- async askForDate(t, e, i) {
50
- return (await y({
51
- type: "date",
52
- name: "value",
53
- message: t,
54
- initial: e,
55
- ...i
56
- }))?.value ?? null;
57
- }
58
- async askForList(t, e, i) {
59
- return (await y({
60
- type: "list",
61
- name: "value",
62
- message: t,
63
- initial: e,
64
- ...i
65
- }))?.value ?? null;
66
- }
67
- async askForToggle(t, e, i) {
68
- return (await y({
69
- type: "toggle",
70
- name: "value",
71
- message: t,
72
- initial: e,
73
- ...i
74
- }))?.value ?? null;
75
- }
76
- async askForSelect(t, e, i) {
77
- if (e.length === 0)
78
- throw new Error("No options provided");
79
- const n = [];
80
- for (const o of e)
81
- typeof o == "string" ? n.push({ title: o, value: o }) : n.push(o);
82
- return (await y({
83
- type: "select",
84
- name: "value",
85
- message: t,
86
- choices: n,
87
- ...i
88
- }))?.value ?? null;
89
- }
90
- newLoader(t = "", e = ["⠙", "⠘", "⠰", "⠴", "⠤", "⠦", "⠆", "⠃", "⠋", "⠉"], i = 100) {
91
- let n = t, s = null, o = 0;
92
- const u = setInterval(function() {
93
- s && (process.stdout.write(new TextEncoder().encode("\r" + " ".repeat(s.length + 5) + "\r")), s = null), process.stdout.write(new TextEncoder().encode("\r" + e[o++] + " " + n)), o = o % e.length;
94
- }, i), m = () => {
95
- clearInterval(u), process.stdout.write(new TextEncoder().encode("\r" + " ".repeat(n.length + 5) + "\r"));
96
- };
97
- return {
98
- [Symbol.dispose]: m,
99
- [Symbol.asyncDispose]: m,
100
- updateText: (h) => {
101
- s = n, n = h;
102
- },
103
- stop: m
104
- };
105
- }
1
+ import e from "prompts";
2
+ import t from "chalk";
3
+ import n from "minimist";
4
+ import r from "node:fs";
5
+ import i from "node:path";
6
+ //#region src/CommandIO.ts
7
+ var a = class {
8
+ logger;
9
+ constructor(e) {
10
+ this.logger = e.logger;
11
+ }
12
+ log(...e) {
13
+ this.logger.log(...e);
14
+ }
15
+ info(...e) {
16
+ this.logger.info(...e);
17
+ }
18
+ warn(...e) {
19
+ this.logger.warn(...e);
20
+ }
21
+ error(...e) {
22
+ this.logger.error(...e);
23
+ }
24
+ debug(...e) {
25
+ this.logger.debug(...e);
26
+ }
27
+ async askForConfirmation(t = "Do you want to continue?", n) {
28
+ return (await e({
29
+ type: "confirm",
30
+ name: "value",
31
+ message: t,
32
+ initial: n ?? !1
33
+ })).value;
34
+ }
35
+ async askForInput(t, n, r) {
36
+ return (await e({
37
+ type: "text",
38
+ name: "value",
39
+ message: t,
40
+ initial: n,
41
+ ...r
42
+ }))?.value ?? null;
43
+ }
44
+ async askForDate(t, n, r) {
45
+ return (await e({
46
+ type: "date",
47
+ name: "value",
48
+ message: t,
49
+ initial: n,
50
+ ...r
51
+ }))?.value ?? null;
52
+ }
53
+ async askForList(t, n, r) {
54
+ return (await e({
55
+ type: "list",
56
+ name: "value",
57
+ message: t,
58
+ initial: n,
59
+ ...r
60
+ }))?.value ?? null;
61
+ }
62
+ async askForToggle(t, n, r) {
63
+ return (await e({
64
+ type: "toggle",
65
+ name: "value",
66
+ message: t,
67
+ initial: n,
68
+ ...r
69
+ }))?.value ?? null;
70
+ }
71
+ async askForSelect(t, n, r) {
72
+ if (n.length === 0) throw Error("No options provided");
73
+ let i = [];
74
+ for (let e of n) typeof e == "string" ? i.push({
75
+ title: e,
76
+ value: e
77
+ }) : i.push(e);
78
+ return (await e({
79
+ type: "select",
80
+ name: "value",
81
+ message: t,
82
+ choices: i,
83
+ ...r
84
+ }))?.value ?? null;
85
+ }
86
+ newLoader(e = "", t = [
87
+ "⠙",
88
+ "⠘",
89
+ "⠰",
90
+ "⠴",
91
+ "⠤",
92
+ "⠦",
93
+ "",
94
+ "⠃",
95
+ "",
96
+ "⠉"
97
+ ], n = 100) {
98
+ let r = e, i = null, a = 0, o = setInterval(function() {
99
+ i &&= (process.stdout.write(new TextEncoder().encode("\r" + " ".repeat(i.length + 5) + "\r")), null), process.stdout.write(new TextEncoder().encode("\r" + t[a++] + " " + r)), a %= t.length;
100
+ }, n), s = () => {
101
+ clearInterval(o), process.stdout.write(new TextEncoder().encode("\r" + " ".repeat(r.length + 5) + "\r"));
102
+ };
103
+ return {
104
+ [Symbol.dispose]: s,
105
+ [Symbol.asyncDispose]: s,
106
+ updateText: (e) => {
107
+ i = r, r = e;
108
+ },
109
+ stop: s
110
+ };
111
+ }
112
+ }, o = class extends Error {
113
+ $type = "BobError";
114
+ }, s = class extends o {
115
+ constructor(e, t = {}) {
116
+ super(`Flag ${e} is not recognized`), this.flag = e, this.flagsSchema = t;
117
+ }
118
+ pretty(e) {
119
+ e.log(""), e.log(` ${t.bold.white.bgRed(" ERROR ")} Flag ${t.bold.yellow(this.flag)} is not recognized.`);
120
+ let n = Object.entries(this.flagsSchema);
121
+ if (n.length > 0) {
122
+ e.log(""), e.log(` ${t.dim("Available flags:")}`), e.log("");
123
+ let r = n.map(([e, t]) => {
124
+ let n = t.alias ? typeof t.alias == "string" ? [t.alias] : t.alias : [], r = Array.isArray(t.type) ? `[${t.type[0]}]` : t.type === "enum" && t.options ? t.options.join(" | ") : t.type;
125
+ return {
126
+ nameWithAlias: `--${e}${n.length > 0 ? n.map((e) => `, -${e}`).join("") : ""}`,
127
+ description: t.description || "",
128
+ typeDisplay: r
129
+ };
130
+ }), i = Math.max(...r.map((e) => e.nameWithAlias.length));
131
+ for (let n of r) {
132
+ let r = " ".repeat(i - n.nameWithAlias.length + 2);
133
+ e.log(` ${t.green(n.nameWithAlias)}${r}${n.description} ${t.dim(`(${n.typeDisplay})`)}`);
134
+ }
135
+ }
136
+ e.log("");
137
+ }
138
+ }, c = class extends o {
139
+ constructor(e) {
140
+ super(`Argument "${e}" is required.`), this.argument = e;
141
+ }
142
+ pretty(e) {
143
+ e.log(""), e.log(` ${t.bold.white.bgRed(" ERROR ")} Argument ${t.bold.yellow(this.argument)} is required.`), e.log("");
144
+ }
145
+ }, l = class extends o {
146
+ constructor(e) {
147
+ super(`Flag "${e}" is required.`), this.flag = e;
148
+ }
149
+ pretty(e) {
150
+ e.log(""), e.log(` ${t.bold.white.bgRed(" ERROR ")} Flag ${t.bold.yellow(this.flag)} is required.`), e.log("");
151
+ }
152
+ }, u = class extends o {
153
+ constructor(e, t) {
154
+ let n = `Argument "${e.arg}" value is invalid.`;
155
+ e.reason ? n += ` Reason: ${e.reason}` : n += ` Value: "${e.value}"`, super(n), this.detail = e, this.argDefinition = t;
156
+ }
157
+ pretty(e) {
158
+ let n = [];
159
+ if (this.detail.reason != null && n.push(["Reason", this.detail.reason]), this.detail.value != null && n.push(["Value", this.detail.value]), this.argDefinition?.help != null && n.push(["Help", t.green(this.argDefinition.help)]), e.log(""), e.log(` ${t.bold.white.bgRed(" ERROR ")} Argument ${t.bold.yellow(this.detail.arg)} value is invalid.`), n.length > 0) {
160
+ e.log("");
161
+ let r = Math.max(...n.map(([e]) => e.length));
162
+ for (let [i, a] of n) e.log(` ${" ".repeat(r - i.length)}${t.dim(i)} ${a}`);
163
+ }
164
+ e.log("");
165
+ }
166
+ }, d = class extends o {
167
+ constructor(e, t) {
168
+ let n = `Flag "${e.flag}" value is invalid.`;
169
+ e.reason ? n += ` Reason: ${e.reason}` : n += ` Value: "${e.value}"`, super(n), this.param = e, this.flagDefinition = t;
170
+ }
171
+ pretty(e) {
172
+ let n = [];
173
+ if (this.param.reason != null && n.push(["Reason", this.param.reason]), this.param.value != null && n.push(["Value", this.param.value]), this.flagDefinition?.help != null && n.push(["Help", t.green(this.flagDefinition.help)]), e.log(""), e.log(` ${t.bold.white.bgRed(" ERROR ")} Flag ${t.bold.yellow(this.param.flag)} value is invalid.`), n.length > 0) {
174
+ e.log("");
175
+ let r = Math.max(...n.map(([e]) => e.length));
176
+ for (let [i, a] of n) e.log(` ${" ".repeat(r - i.length)}${t.dim(i)} ${a}`);
177
+ }
178
+ e.log("");
179
+ }
180
+ }, f = class extends o {
181
+ constructor(e) {
182
+ super(`Command "${e}" not found.`), this.command = e;
183
+ }
184
+ pretty(e) {
185
+ e.log(""), e.log(` ${t.bold.white.bgRed(" ERROR ")} Command ${t.bold.yellow(this.command)} not found.`), e.log("");
186
+ }
187
+ }, p = class extends o {
188
+ constructor(e, t) {
189
+ super(`Too many arguments provided. Expected ${e}, got ${t}.`), this.expected = e, this.received = t;
190
+ }
191
+ pretty(e) {
192
+ e.log(""), e.log(` ${t.bold.white.bgRed(" ERROR ")} Too many arguments. Expected ${t.bold.yellow(String(this.expected))}, got ${t.bold.yellow(String(this.received))}.`), e.log("");
193
+ }
194
+ }, m = class {
195
+ flags;
196
+ parsedFlags = null;
197
+ args;
198
+ parsedArguments = null;
199
+ io;
200
+ shouldPromptForMissingFlags = !0;
201
+ shouldValidateUnknownFlags = !0;
202
+ shouldRejectExtraArguments = !1;
203
+ constructor(e) {
204
+ this.opts = e, this.io = e.io, this.flags = e.flags, this.args = e.args;
205
+ }
206
+ async init(e) {
207
+ let { _: t, ...r } = n(e);
208
+ return this.shouldValidateUnknownFlags && this.validateUnknownFlags(r), this.parsedFlags = await this.handleOptions(r), this.parsedArguments = await this.handleArguments(t), {
209
+ flags: this.parsedFlags,
210
+ args: this.parsedArguments
211
+ };
212
+ }
213
+ async validate() {
214
+ for (let e in this.flags) {
215
+ let t = this.flags[e], n = this.parsedFlags?.[e], r = this.isEmptyValue(n), i = "multiple" in t && t.multiple;
216
+ if (t.required && r) throw new l(e);
217
+ if (!r && t.validate) {
218
+ let r = i && Array.isArray(n) ? n : [n];
219
+ for (let n of r) {
220
+ let r = await t.validate(n);
221
+ if (r !== !0) throw new d({
222
+ flag: e,
223
+ reason: r,
224
+ value: n
225
+ });
226
+ }
227
+ }
228
+ }
229
+ for (let e in this.args) {
230
+ let t = this.args[e], n = this.parsedArguments?.[e], r = this.isEmptyValue(n), i = "multiple" in t && t.multiple;
231
+ if (t.required && r) {
232
+ if (!this.shouldPromptForMissingFlags) throw new c(e);
233
+ let n = await this.promptForArgument(e, t);
234
+ if (n && this.parsedArguments) {
235
+ this.parsedArguments[e] = await this.parseValue(n, t, {
236
+ name: e,
237
+ isArg: !0
238
+ });
239
+ continue;
240
+ }
241
+ throw new c(e);
242
+ }
243
+ if (!r && t.validate) {
244
+ let r = i && Array.isArray(n) ? n : [n];
245
+ for (let n of r) {
246
+ let r = await t.validate(n);
247
+ if (r !== !0) throw new u({
248
+ arg: e,
249
+ reason: r,
250
+ value: n
251
+ });
252
+ }
253
+ }
254
+ }
255
+ }
256
+ flag(e, t) {
257
+ if (!this.parsedFlags) throw Error("Flags have not been parsed yet. Call init() first.");
258
+ return this.isEmptyValue(this.parsedFlags[e]) && t !== void 0 ? t : this.parsedFlags[e];
259
+ }
260
+ async setFlag(e, t) {
261
+ if (!this.parsedFlags) throw Error("Flags have not been parsed yet. Call init() first.");
262
+ if (!(e in this.flags)) throw new s(e, this.flags);
263
+ if (this.flags[e].validate) {
264
+ let n = await this.flags[e].validate(t);
265
+ if (n !== !0) throw new d({
266
+ flag: e,
267
+ reason: n,
268
+ value: t
269
+ });
270
+ }
271
+ this.parsedFlags[e] = t;
272
+ }
273
+ argument(e, t) {
274
+ if (!this.parsedArguments) throw Error("Arguments have not been parsed yet. Call init() first.");
275
+ return this.isEmptyValue(this.parsedArguments[e]) && t !== void 0 ? t : this.parsedArguments[e];
276
+ }
277
+ async setArgument(e, t) {
278
+ if (!this.parsedArguments) throw Error("Arguments have not been parsed yet. Call init() first.");
279
+ if (!(e in this.args)) throw new u({
280
+ arg: e,
281
+ reason: `Argument "${e}" is not recognized`
282
+ });
283
+ if (this.args[e].validate) {
284
+ let n = await this.args[e].validate(t);
285
+ if (n !== !0) throw new u({
286
+ arg: e,
287
+ reason: n,
288
+ value: t
289
+ });
290
+ }
291
+ this.parsedArguments[e] = t;
292
+ }
293
+ isEmptyValue(e) {
294
+ return e == null || typeof e == "string" && e.trim() === "" || Array.isArray(e) && e.length === 0;
295
+ }
296
+ validateUnknownFlags(e) {
297
+ let t = /* @__PURE__ */ new Set();
298
+ for (let e in this.flags) {
299
+ t.add(e);
300
+ let n = this.flags[e];
301
+ for (let e of n.alias ?? []) t.add(e);
302
+ }
303
+ for (let n in e) if (!t.has(n)) throw new s(n, this.flags);
304
+ }
305
+ async handleOptions(e) {
306
+ let t = {};
307
+ for (let n in this.flags) t[n] = await this.resolveFlagValue(n, this.flags[n], e);
308
+ return t;
309
+ }
310
+ async handleArguments(e) {
311
+ let t = {}, n = [...e], r = Object.keys(this.args).length;
312
+ for (let e in this.args) {
313
+ let r = this.args[e];
314
+ if ("multiple" in r && r.multiple) {
315
+ t[e] = await this.parseValue(n, r, {
316
+ name: e,
317
+ isArg: !0
318
+ }), n.length = 0;
319
+ continue;
320
+ }
321
+ t[e] = await this.parseValue(n.shift(), r, {
322
+ name: e,
323
+ isArg: !0
324
+ });
325
+ }
326
+ if (this.shouldRejectExtraArguments && n.length > 0) throw new p(r, r + n.length);
327
+ return t;
328
+ }
329
+ async resolveFlagValue(e, t, n) {
330
+ let r, i = [e];
331
+ t.alias && i.push(...Array.isArray(t.alias) ? t.alias : [t.alias]);
332
+ for (let e of i) if (e in n) {
333
+ r = n[e];
334
+ break;
335
+ }
336
+ return this.parseValue(r, t, { name: e });
337
+ }
338
+ async parseValue(e, t, n) {
339
+ if (this.isEmptyValue(e)) return typeof t.default == "function" ? await t.default() : t.default;
340
+ if ("multiple" in t && t.multiple) {
341
+ Array.isArray(e) || (e = [e]);
342
+ let r = [];
343
+ for (let i of e) r.push(await this.safeParse(i, t, n));
344
+ return r;
345
+ }
346
+ return this.safeParse(e, t, n);
347
+ }
348
+ async safeParse(e, t, n) {
349
+ try {
350
+ return t.parse(e, this.opts.ctx);
351
+ } catch (t) {
352
+ if (!n) throw t;
353
+ let r = t instanceof Error ? t.message : String(t);
354
+ throw n.isArg ? new u({
355
+ arg: n.name,
356
+ value: e,
357
+ reason: r
358
+ }) : new d({
359
+ flag: n.name,
360
+ value: e,
361
+ reason: r
362
+ });
363
+ }
364
+ }
365
+ disablePrompting() {
366
+ return this.shouldPromptForMissingFlags = !1, this;
367
+ }
368
+ allowUnknownFlags() {
369
+ return this.shouldValidateUnknownFlags = !1, this;
370
+ }
371
+ strictMode() {
372
+ return this.shouldRejectExtraArguments = !0, this;
373
+ }
374
+ async promptForArgument(e, n) {
375
+ let r = n.type;
376
+ if (r === "enum" && n.options) {
377
+ let r = `${t.yellow.bold(e)} is required`;
378
+ n.description && (r += `: ${t.gray(`(${n.description})`)}`), r += ` ${t.green("(enum)")}\n`;
379
+ let i = n.options.map((e) => ({
380
+ title: e,
381
+ value: e
382
+ }));
383
+ return await this.io.askForSelect(r, i);
384
+ }
385
+ let i = "multiple" in n && n.multiple;
386
+ if (!i && !["string", "number"].includes(r)) return null;
387
+ let a = `${t.yellow.bold(e)} is required`;
388
+ return n.description && (a += `: ${t.gray(`(${n.description})`)}`), a += ` ${t.green(`(${r}${i ? "[]" : ""})`)}\n`, i ? (a += "Please provide one or more values, separated by commas:\n", await this.io.askForList(a, void 0, {
389
+ separator: ",",
390
+ validate: (e) => {
391
+ if (this.isEmptyValue(e) && n.required) return "Please enter at least one value";
392
+ for (let t of e.split(",")) {
393
+ let e = n.validate ? n.validate(t) : !0;
394
+ if (e !== !0) return typeof e == "string" ? `${t} ${e}` : `Invalid value: "${t.trim()}"`;
395
+ }
396
+ return !0;
397
+ }
398
+ })) : await this.io.askForInput(a, void 0, {
399
+ type: r === "number" ? "number" : "secret" in n && n.secret ? "password" : "text",
400
+ validate: (e) => {
401
+ if (this.isEmptyValue(e) && n.required) return "This value is required";
402
+ let t = n.validate ? n.validate(e) : !0;
403
+ return t === !0 ? !0 : typeof t == "string" ? t : "Invalid value";
404
+ }
405
+ });
406
+ }
407
+ }, h = {
408
+ string(e) {
409
+ return {
410
+ default: e?.multiple ? [] : null,
411
+ parse: (e) => {
412
+ if (typeof e == "boolean") throw Error(`Expected a string, got boolean "${e}"`);
413
+ return String(e);
414
+ },
415
+ ...e,
416
+ type: "string"
417
+ };
418
+ },
419
+ number(e) {
420
+ return {
421
+ default: e?.multiple ? [] : null,
422
+ validate(t) {
423
+ return e?.min !== void 0 && t < e.min ? `is below minimum ${e.min}` : e?.max !== void 0 && t > e.max ? `exceeds maximum ${e.max}` : !0;
424
+ },
425
+ parse: (e) => {
426
+ let t = typeof e == "number" ? e : Number(e);
427
+ if (isNaN(t)) throw Error("must be a valid number");
428
+ return t;
429
+ },
430
+ ...e,
431
+ type: "number"
432
+ };
433
+ },
434
+ boolean(e) {
435
+ return {
436
+ default: !1,
437
+ parse: (e) => {
438
+ if (typeof e == "boolean") return e;
439
+ let t = String(e).toLowerCase();
440
+ return t === "true" || t === "1" ? !0 : t === "false" || t === "0" ? !1 : !!e;
441
+ },
442
+ ...e,
443
+ type: "boolean"
444
+ };
445
+ },
446
+ enum(e) {
447
+ return {
448
+ default: e.multiple ? [] : null,
449
+ validate(t) {
450
+ return e.options.includes(t) ? !0 : `must be one of: ${e.options.map((e) => `"${e}"`).join(", ")}`;
451
+ },
452
+ parse: (e) => String(e),
453
+ ...e,
454
+ type: "enum"
455
+ };
456
+ },
457
+ file(e) {
458
+ return {
459
+ default: null,
460
+ parse: (e) => String(e),
461
+ validate(t) {
462
+ return e?.exists && !r.existsSync(t) ? "file does not exist" : !0;
463
+ },
464
+ ...e,
465
+ type: "file"
466
+ };
467
+ },
468
+ directory(e) {
469
+ return {
470
+ default: null,
471
+ parse: (e) => String(e),
472
+ validate(t) {
473
+ return e?.exists && !(r.existsSync(t) && r.lstatSync(t).isDirectory()) ? "directory does not exist" : !0;
474
+ },
475
+ ...e,
476
+ type: "directory"
477
+ };
478
+ },
479
+ url(e) {
480
+ return {
481
+ default: null,
482
+ parse: (e) => new URL(String(e)),
483
+ ...e,
484
+ type: "url"
485
+ };
486
+ },
487
+ custom(e) {
488
+ return (t) => ({
489
+ default: e?.multiple || t?.multiple ? [] : null,
490
+ parse: (e) => e,
491
+ ...e,
492
+ ...t,
493
+ type: "custom"
494
+ });
495
+ }
496
+ }, g = h;
497
+ //#endregion
498
+ //#region src/lib/string.ts
499
+ function _(e) {
500
+ return Array(e + 5).join(" ");
106
501
  }
107
- class f extends Error {
108
- $type = "BobError";
502
+ //#endregion
503
+ //#region src/options/HelpOption.ts
504
+ function v(e) {
505
+ let t = e.type;
506
+ return Array.isArray(t) ? `[${t[0]}]` : t === "enum" && e.options ? `enum: ${e.options.join("|")}` : t;
109
507
  }
110
- function F(r) {
111
- if (r === "string" || r === "number") return null;
112
- if (r === "boolean") return !1;
113
- if (Array.isArray(r) && r.length === 1) {
114
- if (r[0] === "string") return [];
115
- if (r[0] === "number") return [];
116
- }
117
- throw new Error("Invalid option type: " + r);
118
- }
119
- function E(r) {
120
- return typeof r == "string" || Array.isArray(r) ? F(r) : r.default !== void 0 ? r.default : F(r.type);
121
- }
122
- function g(r) {
123
- return typeof r == "string" || Array.isArray(r) ? {
124
- alias: [],
125
- default: E(r),
126
- description: "",
127
- required: !1,
128
- secret: !1,
129
- type: r,
130
- variadic: !1
131
- } : {
132
- alias: r.alias ? Array.isArray(r.alias) ? r.alias : [r.alias] : [],
133
- default: r.default ?? E(r.type),
134
- description: r.description ?? "",
135
- required: r.required ?? !1,
136
- secret: r.secret ?? !1,
137
- type: r.type,
138
- variadic: r.variadic ?? !1
139
- };
140
- }
141
- class b extends f {
142
- constructor(t, e = {}) {
143
- super(`Invalid option ${t} in not recognized`), this.option = t, this.optionsSchema = e;
144
- }
145
- pretty(t) {
146
- const e = Object.entries(this.optionsSchema);
147
- if (e.length > 0) {
148
- t.log(`
149
- ${a.yellow("Available options")}:`);
150
- for (const [i, n] of e) {
151
- const s = g(n), o = s.alias ? typeof s.alias == "string" ? [s.alias] : s.alias : [], u = Array.isArray(s.type) ? `[${s.type[0]}]` : s.type, m = `--${i}${o.length > 0 ? o.map((l) => `, -${l}`).join("") : ""}`, h = " ".repeat(30 - m.length);
152
- t.log(` ${a.green(m)} ${h} ${s.description || "\b"} ${a.white(`(${u})`)}`);
153
- }
154
- t.log("");
155
- }
156
- t.log(`${a.white.bgRed(" ERROR ")} Option ${a.bold.yellow(this.option)} is not recognized.`);
157
- }
158
- }
159
- class k extends f {
160
- constructor(t) {
161
- super(`Argument "${t}" is required.`), this.argument = t;
162
- }
163
- pretty(t) {
164
- t.log(`${a.white.bgRed(" ERROR ")} Argument ${a.bold.yellow(this.argument)} is required.`);
165
- }
166
- }
167
- class D extends f {
168
- constructor(t) {
169
- super(`Argument "${t}" is required.`), this.option = t;
170
- }
171
- pretty(t) {
172
- t.log(`${a.white.bgRed(" ERROR ")} Option ${a.bold.yellow(this.option)} is required.`);
173
- }
174
- }
175
- class Q extends f {
176
- constructor(t) {
177
- let e = `Argument "${t.param}" value is invalid.`;
178
- t.reason ? e += ` Reason: ${t.reason}` : e += ` Value: "${t.value}"`, super(e), this.param = t;
179
- }
180
- pretty(t) {
181
- t.log(` ${a.white.bgRed(" ERROR ")} Argument ${a.bold.yellow(this.param.param)} value is invalid. `), (this.param.value || this.param.reason) && t.log(""), this.param.value && t.log(` ${a.blue("Value")}: ${this.param.value}`), this.param.reason && t.log(` ${a.yellow("Reason")}: ${this.param.reason}`);
182
- }
183
- }
184
- class C extends f {
185
- constructor(t) {
186
- let e = `Option "${t.option}" value is invalid.`;
187
- t.reason ? e += ` Reason: ${t.reason}` : e += ` Value: "${t.value}"`, super(e), this.param = t;
188
- }
189
- pretty(t) {
190
- t.log(` ${a.white.bgRed(" ERROR ")} Option ${a.bold.yellow(this.param.option)} value is invalid. `), (this.param.value || this.param.reason) && t.log(""), this.param.value && t.log(` ${a.blue("Value")}: ${this.param.value}`), this.param.reason && t.log(` ${a.yellow("Reason")}: ${this.param.reason}`);
191
- }
192
- }
193
- class H extends f {
194
- constructor(t) {
195
- super(`Command "${t}" not found.`), this.command = t;
196
- }
197
- pretty(t) {
198
- t.log(`${a.bgRed(" ERROR ")} Command ${a.yellow(this.command)} not found.`);
199
- }
200
- }
201
- class P extends f {
202
- constructor(t, e) {
203
- super(`Too many arguments provided. Expected ${t}, got ${e}.`), this.expected = t, this.received = e;
204
- }
205
- pretty(t) {
206
- t.log(
207
- `${a.white.bgRed(" ERROR ")} Too many arguments provided. Expected ${a.bold.yellow(String(this.expected))}, got ${a.bold.yellow(String(this.received))}.`
208
- );
209
- }
210
- }
211
- function w(r, t, e, i) {
212
- if (r == null)
213
- return i ?? null;
214
- if (t === "string")
215
- return String(r);
216
- if (t === "number") {
217
- const n = Number(r);
218
- if (isNaN(n))
219
- throw new C({
220
- option: e,
221
- reason: `Expected a number, got "${r}"`
222
- });
223
- return n;
224
- }
225
- if (t === "boolean")
226
- return typeof r == "boolean" ? r : r === "true" || r === "1" ? !0 : r === "false" || r === "0" ? !1 : !!r;
227
- if (Array.isArray(t)) {
228
- const n = t[0], s = Array.isArray(r) ? r : [r];
229
- if (n === "string")
230
- return s.map((o) => String(o));
231
- if (n === "number")
232
- return s.map((o) => {
233
- const u = Number(o);
234
- if (isNaN(u))
235
- throw new C({
236
- option: e,
237
- reason: `Expected array of numbers, got "${o}" in array`
238
- });
239
- return u;
240
- });
241
- }
242
- return r;
243
- }
244
- class N {
245
- options;
246
- parsedOptions = null;
247
- arguments;
248
- parsedArguments = null;
249
- io;
250
- shouldPromptForMissingOptions = !0;
251
- shouldValidateUnknownOptions = !0;
252
- shouldRejectExtraArguments = !1;
253
- constructor(t) {
254
- this.options = t.options, this.arguments = t.arguments, this.io = t.io;
255
- }
256
- // === PUBLIC METHODS ===
257
- /**
258
- * Parses raw command-line arguments into structured options and arguments
259
- * @param args - Raw command line arguments (typically from process.argv.slice(2))
260
- * @returns Object containing parsed options and arguments
261
- * @throws {InvalidOption} If an naan option is provided
262
- * @throws {BadCommandOption} If a value cannot be converted to the expected type
263
- */
264
- init(t) {
265
- const { _: e, ...i } = q(t);
266
- return this.shouldValidateUnknownOptions && this.validateUnknownOptions(i), this.parsedOptions = this.handleOptions(i), this.parsedArguments = this.handleArguments(e), {
267
- options: this.parsedOptions,
268
- arguments: this.parsedArguments
269
- };
270
- }
271
- /**
272
- * Validates the parsed options and arguments
273
- * @throws {Error} If validation fails
274
- */
275
- async validate() {
276
- for (const t in this.options)
277
- if (g(this.options[t]).required && (this.parsedOptions?.[t] === void 0 || this.parsedOptions?.[t] === null))
278
- throw new D(t);
279
- for (const t in this.arguments) {
280
- const e = g(this.arguments[t]), i = this.parsedArguments?.[t];
281
- if (e.required && i == null) {
282
- if (this.shouldPromptForMissingOptions) {
283
- const n = await this.promptForArgument(t, e);
284
- if (n && this.parsedArguments) {
285
- this.parsedArguments[t] = w(n, e.type, t);
286
- continue;
287
- }
288
- }
289
- throw new k(t);
290
- }
291
- if (e.required && e.variadic && Array.isArray(i) && i.length === 0) {
292
- if (this.shouldPromptForMissingOptions) {
293
- const n = await this.promptForArgument(t, e);
294
- if (n && this.parsedArguments) {
295
- this.parsedArguments[t] = w(n, e.type, t);
296
- continue;
297
- }
298
- }
299
- throw new k(t);
300
- }
301
- }
302
- }
303
- /**
304
- * Retrieves a parsed option value by name
305
- * @param name - The option name
306
- * @param defaultValue - Optional default value if option is not set
307
- * @returns The typed option value
308
- * @throws {Error} If init() has not been called yet
309
- */
310
- option(t, e) {
311
- if (!this.parsedOptions)
312
- throw new Error("Options have not been parsed yet. Call init() first.");
313
- return this.isEmptyValue(this.parsedOptions[t]) && e !== void 0 ? e : this.parsedOptions[t];
314
- }
315
- setOption(t, e) {
316
- if (!this.parsedOptions)
317
- throw new Error("Options have not been parsed yet. Call init() first.");
318
- if (!(t in this.options))
319
- throw new b(t, this.options);
320
- this.parsedOptions[t] = e;
321
- }
322
- /**
323
- * Retrieves a parsed argument value by name
324
- * @param name - The argument name
325
- * @param defaultValue - Optional default value if argument is not set
326
- * @returns The typed argument value
327
- * @throws {Error} If init() has not been called yet
328
- */
329
- argument(t, e) {
330
- if (!this.parsedArguments)
331
- throw new Error("Arguments have not been parsed yet. Call init() first.");
332
- return this.isEmptyValue(this.parsedArguments[t]) && e !== void 0 ? e : this.parsedArguments[t];
333
- }
334
- setArgument(t, e) {
335
- if (!this.parsedArguments)
336
- throw new Error("Arguments have not been parsed yet. Call init() first.");
337
- if (!(t in this.arguments))
338
- throw new b(t, this.arguments);
339
- this.parsedArguments[t] = e;
340
- }
341
- // === PRIVATE HELPERS ===
342
- /**
343
- * Checks if a value should be considered "empty" for default value purposes
344
- * @param value - The value to check
345
- * @returns true if the value is null, undefined, or an empty array
346
- */
347
- isEmptyValue(t) {
348
- return t == null || Array.isArray(t) && t.length === 0;
349
- }
350
- /**
351
- * Validates that all provided options are recognized
352
- * @throws {InvalidOption} If an unknown option is found
353
- */
354
- validateUnknownOptions(t) {
355
- const e = /* @__PURE__ */ new Set();
356
- for (const i in this.options) {
357
- e.add(i);
358
- const n = g(this.options[i]);
359
- for (const s of n.alias)
360
- e.add(s);
361
- }
362
- for (const i in t)
363
- if (!e.has(i))
364
- throw new b(i, this.options);
365
- }
366
- /**
367
- * Processes named options from minimist output
368
- */
369
- handleOptions(t) {
370
- const e = {};
371
- for (const i in this.options) {
372
- const n = g(this.options[i]);
373
- e[i] = this.resolveOptionValue(i, n, t);
374
- }
375
- return e;
376
- }
377
- /**
378
- * Processes positional arguments from minimist output
379
- */
380
- handleArguments(t) {
381
- const e = {}, i = [...t], n = Object.keys(this.arguments).length;
382
- for (const s in this.arguments) {
383
- const o = g(this.arguments[s]);
384
- if (o.variadic) {
385
- e[s] = this.handleVariadicArgument(s, o, i), i.length = 0;
386
- continue;
387
- }
388
- e[s] = this.resolveArgumentValue(s, o, i.shift());
389
- }
390
- if (this.shouldRejectExtraArguments && i.length > 0)
391
- throw new P(n, n + i.length);
392
- return e;
393
- }
394
- /**
395
- * Handles variadic arguments that consume all remaining positional values
396
- */
397
- handleVariadicArgument(t, e, i) {
398
- return i.length ? w(i, e.type, t, e.default) : e.default;
399
- }
400
- /**
401
- * Resolves a single positional argument value with defaults and type conversion
402
- * Note: Does not validate required arguments - validation happens in subclass validate() methods
403
- */
404
- resolveArgumentValue(t, e, i) {
405
- return i === void 0 ? e.default : w(i, e.type, t, e.default);
406
- }
407
- /**
408
- * Resolves an option value from the parsed option values object
409
- * Handles alias resolution, defaults, and type conversion
410
- */
411
- resolveOptionValue(t, e, i) {
412
- let n;
413
- const s = [t, ...e.alias];
414
- for (const o of s)
415
- if (o in i) {
416
- n = i[o];
417
- break;
418
- }
419
- if (n === void 0) {
420
- if (e.required)
421
- throw new C({
422
- option: t,
423
- reason: "Required option is missing"
424
- });
425
- return e.default;
426
- }
427
- return w(n, e.type, t, e.default);
428
- }
429
- optionDefinitions() {
430
- const t = {};
431
- for (const e in this.options)
432
- t[e] = g(this.options[e]);
433
- return t;
434
- }
435
- argumentDefinitions() {
436
- const t = {};
437
- for (const e in this.arguments)
438
- t[e] = g(this.arguments[e]);
439
- return t;
440
- }
441
- availableOptions() {
442
- return Object.keys(this.options);
443
- }
444
- availableArguments() {
445
- return Object.keys(this.arguments);
446
- }
447
- /**
448
- * Disables prompting for missing argument values
449
- * Useful for non-interactive environments
450
- */
451
- disablePrompting() {
452
- return this.shouldPromptForMissingOptions = !1, this;
453
- }
454
- allowUnknownOptions() {
455
- return this.shouldValidateUnknownOptions = !1, this;
456
- }
457
- strictMode() {
458
- return this.shouldRejectExtraArguments = !0, this;
459
- }
460
- /**
461
- * Prompts the user to provide a missing argument value via CommandIO
462
- * Used by validate() when shouldPromptForMissingArgs is enabled
463
- * @param argumentName - The name of the missing argument
464
- * @param argDef - The argument's definition for type and description
465
- * @returns The user-provided value, or null if none given
466
- */
467
- async promptForArgument(t, e) {
468
- if (!Array.isArray(e.type) && !["string", "number", "secret"].includes(e.type))
469
- return null;
470
- let i = `${a.yellow.bold(t)} is required`;
471
- return e.description && (i += `: ${a.gray(`(${e.description})`)}`), i += ` ${a.green(`(${e.type}${e.variadic == !0 ? "[]" : ""})`)}
472
- `, Array.isArray(e.type) ? (i += `Please provide one or more values, separated by commas:
473
- `, await this.io.askForList(i, void 0, {
474
- separator: ",",
475
- validate: (n) => {
476
- if (!n.length)
477
- return "Please enter at least one value";
478
- if (e.type[0] === "number") {
479
- for (const s of n.split(","))
480
- if (isNaN(Number(s)))
481
- return "Please enter only valid numbers";
482
- }
483
- return !0;
484
- }
485
- })) : await this.io.askForInput(i, void 0, {
486
- type: e.type === "number" ? "number" : e.secret ? "password" : "text",
487
- validate: (n) => {
488
- if (n == null || typeof n == "string" && !n.length)
489
- return "This value is required";
490
- if (e.type === "number") {
491
- const s = Number(n);
492
- if (isNaN(s))
493
- return "Please enter a valid number";
494
- } else if (e.type === "string" && (typeof n != "string" || !n.length))
495
- return "Please enter a valid text";
496
- return !0;
497
- }
498
- });
499
- }
500
- }
501
- function O(r) {
502
- return new Array(r + 5).join(" ");
503
- }
504
- class M {
505
- type = "boolean";
506
- option = "help";
507
- alias = ["h"];
508
- default = !1;
509
- description = `Display help for the given command. When no command is given display help for the ${a.green("list")} command`;
510
- async handler() {
511
- const t = this.parser.argumentDefinitions(), e = this.parser.optionDefinitions(), i = Object.entries(t), n = Object.entries(e), s = n.map(([l, d]) => {
512
- const p = Array.isArray(d.alias) ? d.alias : d.alias ? [d.alias] : [];
513
- return {
514
- name: l,
515
- ...d,
516
- optionWithAlias: `--${l}${p.map((c) => `, -${c}`).join("")}`
517
- };
518
- }), o = i.filter(([, l]) => l.required);
519
- this.io.log(a.yellow("Description:")), this.io.log(` ${this.description}
520
- `), this.io.log(a.yellow("Usage:")), this.io.log(` ${this.command} ${o.length > 0 ? o.map(([l]) => `<${l}>`).join(" ") : "\b"} [options]`);
521
- const u = Math.max(...s.map((l) => l.optionWithAlias.length), 0), m = Math.max(...i.map(([l]) => l.length), 0), h = m > u ? m : u;
522
- if (i.length > 0) {
523
- this.io.log(`
524
- ${a.yellow("Arguments")}:`);
525
- for (const [l, d] of i) {
526
- const p = O(h - l.length);
527
- let c = ` ${a.green(l)} ${p} ${d.description ?? "\b"}`;
528
- if (d.default !== void 0 && !d.required) {
529
- const L = (Array.isArray(d.type) ? `[${d.type[0]}]` : d.type) === "array" || Array.isArray(d.type) ? JSON.stringify(d.default) : d.default;
530
- c += ` ${a.yellow(`[default: ${L}]`)}`;
531
- }
532
- d.variadic && (c += ` ${a.white("(variadic)")}`), this.io.log(c);
533
- }
534
- }
535
- if (n.length > 0) {
536
- this.io.log(`
537
- ${a.yellow("Options")}:`);
538
- for (const l of s) {
539
- const d = O(h - l.optionWithAlias.length);
540
- let p = `${a.green(l.optionWithAlias)} ${d} ${l.description ?? "\b"}`;
541
- if (l.type) {
542
- const c = Array.isArray(l.type) ? `[${l.type[0]}]` : l.type;
543
- p += ` ${a.white(`(${c})`)}`;
544
- }
545
- if (l.default !== void 0 && !l.required) {
546
- const R = (Array.isArray(l.type) ? `[${l.type[0]}]` : l.type) === "array" || Array.isArray(l.type) ? JSON.stringify(l.default) : l.default;
547
- p += ` ${a.yellow(`[default: ${R}]`)}`;
548
- }
549
- this.io.log(p);
550
- }
551
- }
552
- if (this.commandsExamples.length > 0) {
553
- this.io.log(`
554
- ${a.yellow("Examples")}:`);
555
- let l = process.argv[0].split("/").pop();
556
- l === "node" && (l += " " + process.argv[1].split("/").pop());
557
- for (const [d, p] of this.commandsExamples.entries())
558
- d > 0 && this.io.log(""), this.io.log(` ${p.description}
559
- `), this.io.log(` ${a.green(`${l} ${p.command}`)}`);
560
- }
561
- return -1;
562
- }
563
- }
564
- class A {
565
- $type = "BobCommand";
566
- _command;
567
- description;
568
- group;
569
- commandsExamples = [];
570
- get command() {
571
- return this._command;
572
- }
573
- ctx;
574
- io;
575
- parser;
576
- disablePromptingFlag = !1;
577
- allowUnknownOptionsFlag = !1;
578
- hiddenFlag = !1;
579
- disableDefaultOptionsFlag = !1;
580
- strictModeFlag = !1;
581
- _preHandler;
582
- _handler;
583
- tmp;
584
- defaultOptions() {
585
- return this.disableDefaultOptionsFlag ? [] : [new M()];
586
- }
587
- newCommandParser(t) {
588
- return new N({
589
- io: t.io,
590
- options: t.options,
591
- arguments: t.arguments
592
- });
593
- }
594
- newCommandIO(t) {
595
- return new S(t);
596
- }
597
- constructor(t, e) {
598
- this._command = t, this.description = e?.description ?? "", this.group = e?.group, this.tmp = {
599
- options: e?.options ?? {},
600
- arguments: e?.arguments ?? {}
601
- };
602
- const i = this.defaultOptions();
603
- if (i.length > 0)
604
- for (const n of i)
605
- this.tmp.options[n.option] = n;
606
- }
607
- disablePrompting() {
608
- return this.disablePromptingFlag = !0, this;
609
- }
610
- allowUnknownOptions() {
611
- return this.allowUnknownOptionsFlag = !0, this;
612
- }
613
- hidden() {
614
- return this.hiddenFlag = !0, this;
615
- }
616
- get isHidden() {
617
- return this.hiddenFlag;
618
- }
619
- disableDefaultOptions() {
620
- return this.disableDefaultOptionsFlag = !0, this;
621
- }
622
- strictMode() {
623
- return this.strictModeFlag = !0, this;
624
- }
625
- preHandler(t) {
626
- return this._preHandler = t, this;
627
- }
628
- handler(t) {
629
- return this._handler = t, this;
630
- }
631
- options(t) {
632
- return this.tmp = {
633
- options: {
634
- ...this.tmp?.options ?? {},
635
- ...t
636
- },
637
- arguments: this.tmp?.arguments ?? {}
638
- }, this;
639
- }
640
- arguments(t) {
641
- return this.tmp = {
642
- options: this.tmp?.options ?? {},
643
- arguments: {
644
- ...this.tmp?.arguments ?? {},
645
- ...t
646
- }
647
- }, this;
648
- }
649
- async run(t) {
650
- if (!this._handler && !this.handle)
651
- throw new Error(`No handler defined for command ${this.command || "(unknown)"}`);
652
- let e;
653
- if (this.ctx = t.ctx, this.io = this.newCommandIO({
654
- logger: t.logger
655
- }), t && "args" in t) {
656
- const n = this.tmp?.options ?? {};
657
- for (const s of this.defaultOptions())
658
- s.option in n || (n[s.option] = s);
659
- this.parser = this.newCommandParser({
660
- io: this.io,
661
- options: n,
662
- arguments: this.tmp?.arguments ?? {}
663
- }), this.allowUnknownOptionsFlag && this.parser.allowUnknownOptions(), this.strictModeFlag && this.parser.strictMode(), e = this.parser.init(t.args);
664
- for (const s of this.defaultOptions())
665
- if (e.options[s.option] === !0) {
666
- const o = await s.handler.call(this);
667
- if (o && o !== 0)
668
- return o;
669
- }
670
- this.disablePromptingFlag && this.parser.disablePrompting(), await this.parser.validate();
671
- } else
672
- e = {
673
- options: t.options,
674
- arguments: t.arguments
675
- };
676
- if (!this._preHandler && this.preHandle && (this._preHandler = this.preHandle.bind(this)), this._preHandler) {
677
- const n = await this._preHandler(t.ctx, e);
678
- if (n && n !== 0)
679
- return n;
680
- }
681
- if (!this._handler && this.handle)
682
- this._handler = this.handle.bind(this);
683
- else if (!this._handler)
684
- throw new Error(`No handler defined for command ${this.command || "(unknown)"}`);
685
- return await this._handler(t.ctx, e) ?? 0;
686
- }
687
- }
688
- class $ extends N {
689
- command;
690
- constructor(t) {
691
- const e = $.parseSignature(t.signature, t.helperDefinitions, t.defaultOptions);
692
- super({
693
- io: t.io,
694
- options: e.options,
695
- arguments: e.arguments
696
- }), this.command = e.command;
697
- }
698
- /**
699
- * Parses command signature string into command name and parameter schemas
700
- * Example: "migrate {name} {--force}" -> { command: "migrate", arguments: {name: ...}, options: {force: ...} }
701
- */
702
- static parseSignature(t, e, i) {
703
- const [n, ...s] = t.split(/\{(.*?)\}/g).map((m) => m.trim()).filter(Boolean), o = {}, u = {};
704
- for (const m of s) {
705
- const { name: h, isOption: l, definition: d } = $.parseParamSignature(m, e);
706
- l ? o[h] = d : u[h] = d;
707
- }
708
- for (const m of i)
709
- o[m.option] = {
710
- type: m.type,
711
- required: m.required,
712
- alias: m.alias,
713
- variadic: m.variadic ?? !1,
714
- description: m.description,
715
- default: m.default ?? null
716
- };
717
- return {
718
- command: n,
719
- options: o,
720
- arguments: u
721
- };
722
- }
723
- /**
724
- * Parses a single parameter signature like "{name}" or "{--force}" or "{files*}"
725
- * Extracts name, type, default value, aliases, description, etc.
726
- *
727
- * Signature syntax:
728
- * - {arg} -> required string argument
729
- * - {arg?} -> optional argument
730
- * - {arg=default} -> argument with default value
731
- * - {arg*} -> variadic argument (array)
732
- * - {arg:desc} -> argument with description
733
- * - {--opt} -> boolean option
734
- * - {--opt=} -> string option
735
- * - {--opt|o} -> option with alias
736
- */
737
- static parseParamSignature(t, e) {
738
- let i = t, n = !1;
739
- const s = {
740
- required: !0,
741
- type: "string",
742
- description: void 0,
743
- default: null,
744
- variadic: !1
745
- };
746
- if (i.includes(":")) {
747
- const [o, u] = i.split(":");
748
- i = o.trim(), s.description = u.trim();
749
- }
750
- if (i.includes("=")) {
751
- const [o, u] = i.split("=");
752
- i = o.trim(), s.default = u.trim(), s.required = !1, typeof s.default == "string" && !s.default.length ? s.default = null : s.default === "true" ? (s.default = !0, s.type = "boolean") : s.default === "false" && (s.default = !1, s.type = "boolean");
753
- } else i.startsWith("--") && (s.required = !1, s.default = !1, s.type = "boolean");
754
- if (i.includes("|")) {
755
- const [o, ...u] = i.split("|");
756
- i = o.trim(), s.alias = u.map((m) => m.trim());
757
- }
758
- return i.startsWith("--") && (n = !0, i = i.slice(2)), s.default === "*" && (s.default = [], s.type = ["string"]), i.endsWith("?") && (s.required = !1, i = i.slice(0, -1)), i.endsWith("*") && (s.type = ["string"], s.variadic = !0, s.default = [], i = i.slice(0, -1)), s.description = s.description ?? e[i] ?? e[`--${i}`], { name: i, isOption: n, definition: s };
759
- }
760
- }
761
- class X extends A {
762
- helperDefinitions = {};
763
- get command() {
764
- return this.parser ? this.parser.command : this.signature.split(" ")[0];
765
- }
766
- newCommandParser(t) {
767
- return new $({
768
- io: t.io,
769
- signature: this.signature,
770
- helperDefinitions: this.helperDefinitions,
771
- defaultOptions: this.defaultOptions()
772
- });
773
- }
774
- constructor() {
775
- super("");
776
- }
777
- option(t, e = null) {
778
- return this.parser.option(t, e);
779
- }
780
- argument(t, e = null) {
781
- return this.parser.argument(t, e);
782
- }
783
- // Prompt utils
784
- async askForConfirmation(...t) {
785
- return this.io.askForConfirmation(...t);
786
- }
787
- async askForInput(...t) {
788
- return this.io.askForInput(...t);
789
- }
790
- async askForSelect(...t) {
791
- return this.io.askForSelect(...t);
792
- }
793
- newLoader(...t) {
794
- return this.io.newLoader(...t);
795
- }
796
- }
797
- class V {
798
- level;
799
- constructor(t = {}) {
800
- this.level = t.level ?? "info";
801
- }
802
- shouldLog(t) {
803
- const e = ["debug", "info", "warn", "error"], i = e.indexOf(this.level);
804
- return e.indexOf(t) >= i;
805
- }
806
- setLevel(t) {
807
- this.level = t;
808
- }
809
- getLevel() {
810
- return this.level;
811
- }
812
- log(...t) {
813
- console.log(...t);
814
- }
815
- info(...t) {
816
- this.shouldLog("info") && console.log(...t);
817
- }
818
- warn(...t) {
819
- this.shouldLog("warn") && console.warn(...t);
820
- }
821
- error(...t) {
822
- this.shouldLog("error") && console.error(...t);
823
- }
824
- debug(...t) {
825
- this.shouldLog("debug") && console.log(...t);
826
- }
827
- }
828
- class B {
829
- /**
830
- * Generate bigrams (character pairs) from a string
831
- */
832
- getBigrams(t) {
833
- const e = [], i = t.toLowerCase();
834
- for (let n = 0; n < i.length - 1; n++)
835
- e.push(i.slice(n, n + 2));
836
- return e;
837
- }
838
- /**
839
- * Calculate Dice's Coefficient similarity between two strings (0-1 scale)
840
- */
841
- calculateSimilarity(t, e) {
842
- if (t === e) return 1;
843
- if (t.length < 2 || e.length < 2) return 0;
844
- const i = this.getBigrams(t), n = this.getBigrams(e), s = new Set(n);
845
- let o = 0;
846
- for (const u of i)
847
- s.has(u) && (o++, s.delete(u));
848
- return 2 * o / (i.length + n.length);
849
- }
850
- /**
851
- * Find best matching string and ratings for all candidates
852
- */
853
- findBestMatch(t, e) {
854
- const i = e.map((o) => ({
855
- target: o,
856
- rating: this.calculateSimilarity(t, o)
857
- }));
858
- let n = 0, s = i[0]?.rating ?? 0;
859
- for (let o = 1; o < i.length; o++)
860
- i[o].rating > s && (s = i[o].rating, n = o);
861
- return {
862
- ratings: i,
863
- bestMatch: i[n],
864
- bestMatchIndex: n
865
- };
866
- }
867
- }
868
- function j(r) {
869
- return typeof r == "object" && r !== null && "$type" in r && r.$type === "BobError";
870
- }
871
- function v(r) {
872
- return typeof r == "object" && r !== null && (r instanceof A || "$type" in r && r.$type === "BobCommand");
873
- }
874
- class T {
875
- commands = {};
876
- io;
877
- logger;
878
- stringSimilarity;
879
- newCommandIO(t) {
880
- return new S(t);
881
- }
882
- constructor(t) {
883
- this.logger = t?.logger ?? new V(), this.io = this.newCommandIO({
884
- logger: this.logger
885
- }), this.stringSimilarity = t?.stringSimilarity ?? new B();
886
- }
887
- getAvailableCommands() {
888
- return Object.keys(this.commands);
889
- }
890
- getCommands() {
891
- return Object.values(this.commands);
892
- }
893
- importFile = async (t) => (await import(t)).default;
894
- commandResolver = async (t) => {
895
- let e = await this.importFile(t);
896
- return e ? (e && typeof e == "object" && "default" in e && (e = e.default), typeof e == "function" ? new e() : v(e) ? e : null) : null;
897
- };
898
- withCommandResolver(t) {
899
- return this.commandResolver = t, this;
900
- }
901
- withFileImporter(t) {
902
- return this.importFile = t, this;
903
- }
904
- registerCommand(t, e = !1) {
905
- if (!v(t))
906
- throw new Error("Invalid command, it must extend the Command class.");
907
- const i = t.command;
908
- if (!i)
909
- throw new Error("Cannot register a command with no name.");
910
- if (!e && this.commands[i])
911
- throw new Error(`Command ${i} already registered.`);
912
- this.commands[i] = t;
913
- }
914
- async loadCommandsPath(t) {
915
- for await (const e of this.listCommandsFiles(t))
916
- try {
917
- const i = await this.commandResolver(e);
918
- v(i) && this.registerCommand(i);
919
- } catch (i) {
920
- throw new Error(`Command ${e} failed to load. ${i}`, {
921
- cause: i
922
- });
923
- }
924
- }
925
- async runCommand(t, e, ...i) {
926
- const n = typeof e == "string" ? this.commands[e] : e, s = typeof e == "string" ? e : n.command;
927
- if (!n) {
928
- const o = await this.suggestCommand(s);
929
- return o ? await this.runCommand(t, o, ...i) : 1;
930
- }
931
- return await n.run({
932
- ctx: t,
933
- logger: this.logger,
934
- args: i
935
- }) ?? 0;
936
- }
937
- async suggestCommand(t) {
938
- const e = this.getAvailableCommands(), { bestMatch: i, bestMatchIndex: n, ratings: s } = this.stringSimilarity.findBestMatch(t, e), o = s.filter((u) => u.rating > 0.3).map((u) => u.target);
939
- if (i && (i.rating > 0 && o.length <= 1 || i.rating > 0.7 && o.length > 1)) {
940
- const u = e[n];
941
- return await this.askRunSimilarCommand(t, u) ? u : null;
942
- }
943
- if (o.length) {
944
- this.io.error(`${a.bgRed(" ERROR ")} Command ${a.yellow(t)} not found.
945
- `);
946
- const u = await this.io.askForSelect(a.green("Did you mean to run one of these commands instead?"), o);
947
- if (u)
948
- return u;
949
- }
950
- throw new H(t);
951
- }
952
- async askRunSimilarCommand(t, e) {
953
- return this.io.error(`${a.bgRed(" ERROR ")} Command ${a.yellow(t)} not found.
954
- `), this.io.askForConfirmation(`${a.green(`Do you want to run ${a.yellow(e)} instead?`)} `);
955
- }
956
- async *listCommandsFiles(t) {
957
- const e = I.readdirSync(t, { withFileTypes: !0 });
958
- for (const i of e) {
959
- const n = x.resolve(t, i.name);
960
- if (i.isDirectory())
961
- yield* this.listCommandsFiles(x.resolve(t, i.name));
962
- else {
963
- if (!n.endsWith(".ts") && !n.endsWith(".js") && !n.endsWith(".mjs") && !n.endsWith(".cjs"))
964
- continue;
965
- yield n;
966
- }
967
- }
968
- }
508
+ var y = h.boolean({
509
+ alias: ["h"],
510
+ handler: (e, n, r) => {
511
+ if (!e) return { shouldStop: !1 };
512
+ let i = r.args, a = r.flags, o = Object.entries(i), s = Object.entries(a), c = s.map(([e, t]) => {
513
+ let n = Array.isArray(t.alias) ? t.alias : t.alias ? [t.alias] : [];
514
+ return {
515
+ name: e,
516
+ ...t,
517
+ flagWithAlias: `--${e}${n.map((e) => `, -${e}`).join("")}`
518
+ };
519
+ }), l = o.filter(([, e]) => e.required);
520
+ console.log(t.yellow("Description:")), console.log(` ${r.description}\n`), console.log(t.yellow("Usage:")), console.log(` ${r.command} ${l.length > 0 ? l.map(([e]) => `<${e}>`).join(" ") : "\b"} [options]`);
521
+ let u = Math.max(...c.map((e) => e.flagWithAlias.length), 0), d = Math.max(...o.map(([e]) => e.length), 0), f = d > u ? d : u;
522
+ if (o.length > 0) {
523
+ console.log(`\n${t.yellow("Arguments")}:`);
524
+ for (let [e, n] of o) {
525
+ let r = _(f - e.length), i = ` ${t.green(e)} ${r} ${n.description ?? "\b"}`;
526
+ if (n.default !== void 0 && !n.required) {
527
+ let e = typeof n.default == "function" ? "[function]" : n.multiple ? JSON.stringify(n.default) : n.default;
528
+ i += ` ${t.yellow(`[default: ${e}]`)}`;
529
+ }
530
+ "multiple" in n && n.multiple && (i += ` ${t.white("(variadic)")}`), console.log(i);
531
+ }
532
+ }
533
+ if (s.length > 0) {
534
+ console.log(`\n${t.yellow("Options")}:`);
535
+ for (let e of c) {
536
+ let n = _(f - e.flagWithAlias.length), r = ` ${t.green(e.flagWithAlias)} ${n} ${e.description ?? "\b"}`;
537
+ if (e.type && (r += ` ${t.white(`(${v(e)})`)}`), e.default !== void 0 && !e.required) {
538
+ let n = typeof e.default == "function" ? "(function)" : e.default;
539
+ r += ` ${t.yellow(`[default: ${n}]`)}`;
540
+ }
541
+ console.log(r);
542
+ }
543
+ }
544
+ let p = r.examples ?? [];
545
+ if (p.length > 0) {
546
+ console.log(`\n${t.yellow("Examples")}:`);
547
+ let e = process.argv[0].split("/").pop();
548
+ e === "node" && (e += " " + process.argv[1].split("/").pop());
549
+ for (let [n, r] of p.entries()) n > 0 && console.log(""), console.log(` ${r.description}\n`), console.log(` ${t.green(`${e} ${r.command}`)}`);
550
+ }
551
+ return { shouldStop: !0 };
552
+ }
553
+ }), b = class {
554
+ $type = "BobCommand";
555
+ static command = "";
556
+ static description = "";
557
+ static group;
558
+ static args = {};
559
+ static flags = {};
560
+ static examples = [];
561
+ static hidden = !1;
562
+ static disableDefaultOptions = !1;
563
+ static disablePrompting = !1;
564
+ static allowUnknownFlags = !1;
565
+ static strictMode = !1;
566
+ ctx;
567
+ io;
568
+ parser;
569
+ static baseFlags = { help: y };
570
+ newCommandParser(e) {
571
+ return new m({
572
+ io: e.io,
573
+ ctx: e.ctx,
574
+ flags: e.flags,
575
+ args: e.args
576
+ });
577
+ }
578
+ newCommandIO(e) {
579
+ return new a(e);
580
+ }
581
+ async run(e) {
582
+ let t = this.constructor;
583
+ this.ctx = e.ctx, this.io = this.newCommandIO({ logger: e.logger });
584
+ let n;
585
+ if ("flags" in e) n = {
586
+ flags: e.flags,
587
+ args: e.args
588
+ };
589
+ else {
590
+ this.parser = this.newCommandParser({
591
+ ctx: this.ctx,
592
+ io: this.io,
593
+ flags: t.disableDefaultOptions ? t.flags : {
594
+ ...t.baseFlags,
595
+ ...t.flags
596
+ },
597
+ args: t.args
598
+ }), t.allowUnknownFlags && this.parser.allowUnknownFlags(), t.strictMode && this.parser.strictMode(), t.disablePrompting && this.parser.disablePrompting();
599
+ let r = await this.parser.init(e.args);
600
+ for (let n in r.flags) {
601
+ let i = r.flags[n], a = t.flags[n] || t.baseFlags[n];
602
+ if (a && a.handler) {
603
+ let n = a.handler(i, e.ctx, t);
604
+ if (n && n.shouldStop) return -1;
605
+ }
606
+ }
607
+ await this.parser.validate(), n = {
608
+ flags: r.flags,
609
+ args: r.args
610
+ };
611
+ }
612
+ if (this.preHandle) {
613
+ let e = await this.preHandle();
614
+ if (e && e !== 0) return e;
615
+ }
616
+ return await this.handle(this.ctx, n) ?? 0;
617
+ }
618
+ }, x = class {
619
+ level;
620
+ constructor(e = {}) {
621
+ this.level = e.level ?? "info";
622
+ }
623
+ shouldLog(e) {
624
+ let t = [
625
+ "debug",
626
+ "info",
627
+ "warn",
628
+ "error"
629
+ ], n = t.indexOf(this.level);
630
+ return t.indexOf(e) >= n;
631
+ }
632
+ setLevel(e) {
633
+ this.level = e;
634
+ }
635
+ getLevel() {
636
+ return this.level;
637
+ }
638
+ log(...e) {
639
+ console.log(...e);
640
+ }
641
+ info(...e) {
642
+ this.shouldLog("info") && console.log(...e);
643
+ }
644
+ warn(...e) {
645
+ this.shouldLog("warn") && console.warn(...e);
646
+ }
647
+ error(...e) {
648
+ this.shouldLog("error") && console.error(...e);
649
+ }
650
+ debug(...e) {
651
+ this.shouldLog("debug") && console.log(...e);
652
+ }
653
+ }, S = class {
654
+ getBigrams(e) {
655
+ let t = [], n = e.toLowerCase();
656
+ for (let e = 0; e < n.length - 1; e++) t.push(n.slice(e, e + 2));
657
+ return t;
658
+ }
659
+ calculateSimilarity(e, t) {
660
+ if (e === t) return 1;
661
+ if (e.length < 2 || t.length < 2) return 0;
662
+ let n = this.getBigrams(e), r = this.getBigrams(t), i = new Set(r), a = 0;
663
+ for (let e of n) i.has(e) && (a++, i.delete(e));
664
+ return 2 * a / (n.length + r.length);
665
+ }
666
+ findBestMatch(e, t) {
667
+ let n = t.map((t) => ({
668
+ target: t,
669
+ rating: this.calculateSimilarity(e, t)
670
+ })), r = 0, i = n[0]?.rating ?? 0;
671
+ for (let e = 1; e < n.length; e++) n[e].rating > i && (i = n[e].rating, r = e);
672
+ return {
673
+ ratings: n,
674
+ bestMatch: n[r],
675
+ bestMatchIndex: r
676
+ };
677
+ }
678
+ };
679
+ //#endregion
680
+ //#region src/lib/helpers.ts
681
+ function C(e) {
682
+ return typeof e == "object" && !!e && "$type" in e && e.$type === "BobError";
969
683
  }
970
- class W {
971
- logger;
972
- constructor(t) {
973
- this.logger = t;
974
- }
975
- handle(t) {
976
- if (j(t))
977
- return t.pretty(this.logger), -1;
978
- throw t;
979
- }
684
+ function w(e) {
685
+ return typeof e == "function" && e.prototype instanceof b;
980
686
  }
981
- class _ extends A {
982
- constructor(t) {
983
- super("help", {
984
- description: a.bold("Show help information about the CLI and its commands")
985
- }), this.opts = t;
986
- }
987
- async handle() {
988
- const t = this.opts.commandRegistry.getCommands().filter((m) => !m.isHidden), e = this.opts.cliName ?? "Bob CLI", i = this.opts.cliVersion ?? "0.0.0", n = (await import("../package-uVOgoItG.js"))?.default?.version ?? "0.0.0";
989
- this.io.log(`${e} ${a.green(i)} (core: ${a.yellow(n)})
687
+ //#endregion
688
+ //#region src/CommandRegistry.ts
689
+ var T = class {
690
+ commands = {};
691
+ io;
692
+ logger;
693
+ stringSimilarity;
694
+ newCommandIO(e) {
695
+ return new a(e);
696
+ }
697
+ constructor(e) {
698
+ this.logger = e?.logger ?? new x(), this.io = this.newCommandIO({ logger: this.logger }), this.stringSimilarity = e?.stringSimilarity ?? new S();
699
+ }
700
+ getAvailableCommands() {
701
+ return Object.keys(this.commands);
702
+ }
703
+ getCommands() {
704
+ return Object.values(this.commands);
705
+ }
706
+ importFile = async (e) => (await import(e)).default;
707
+ commandResolver = async (e) => {
708
+ let t = await this.importFile(e);
709
+ return t ? (t && typeof t == "object" && "default" in t && (t = t.default), typeof t == "function" && w(t) ? t : null) : null;
710
+ };
711
+ withCommandResolver(e) {
712
+ return this.commandResolver = e, this;
713
+ }
714
+ withFileImporter(e) {
715
+ return this.importFile = e, this;
716
+ }
717
+ registerCommand(e, t = !1) {
718
+ if (!w(e)) throw Error("Invalid command, it must extend the Command class.");
719
+ let n = e.command;
720
+ if (!n) throw Error(`Cannot register a command with no name. ${e.name} `);
721
+ if (!t && this.commands[n]) throw Error(`Command ${n} already registered.`);
722
+ this.commands[n] = e;
723
+ }
724
+ async loadCommandsPath(e) {
725
+ for await (let t of this.listCommandsFiles(e)) try {
726
+ let e = await this.commandResolver(t);
727
+ w(e) && this.registerCommand(e);
728
+ } catch (e) {
729
+ throw Error(`Command ${t} failed to load. ${e}`, { cause: e });
730
+ }
731
+ }
732
+ async runCommand(e, t, ...n) {
733
+ let r;
734
+ if (typeof t == "string") {
735
+ let i = this.commands[t];
736
+ if (!i) {
737
+ let r = await this.suggestCommand(t);
738
+ return r ? await this.runCommand(e, r, ...n) : 1;
739
+ }
740
+ r = new i();
741
+ } else r = w(t) ? new t() : t;
742
+ return await r.run({
743
+ ctx: e,
744
+ logger: this.logger,
745
+ args: n
746
+ }) ?? 0;
747
+ }
748
+ async suggestCommand(e) {
749
+ let n = this.getAvailableCommands(), { bestMatch: r, bestMatchIndex: i, ratings: a } = this.stringSimilarity.findBestMatch(e, n), o = a.filter((e) => e.rating > .3).map((e) => e.target);
750
+ if (r && (r.rating > 0 && o.length <= 1 || r.rating > .7 && o.length > 1)) {
751
+ let t = n[i];
752
+ return await this.askRunSimilarCommand(e, t) ? t : null;
753
+ }
754
+ if (o.length) {
755
+ this.io.error(`${t.bgRed(" ERROR ")} Command ${t.yellow(e)} not found.\n`);
756
+ let n = await this.io.askForSelect(t.green("Did you mean to run one of these commands instead?"), o);
757
+ if (n) return n;
758
+ }
759
+ throw new f(e);
760
+ }
761
+ async askRunSimilarCommand(e, n) {
762
+ return this.io.error(`${t.bgRed(" ERROR ")} Command ${t.yellow(e)} not found.\n`), this.io.askForConfirmation(`${t.green(`Do you want to run ${t.yellow(n)} instead?`)} `);
763
+ }
764
+ async *listCommandsFiles(e) {
765
+ let t = r.readdirSync(e, { withFileTypes: !0 });
766
+ for (let n of t) {
767
+ let t = i.resolve(e, n.name);
768
+ if (n.isDirectory()) yield* this.listCommandsFiles(i.resolve(e, n.name));
769
+ else {
770
+ if (!t.endsWith(".ts") && !t.endsWith(".js") && !t.endsWith(".mjs") && !t.endsWith(".cjs")) continue;
771
+ yield t;
772
+ }
773
+ }
774
+ }
775
+ }, E = class e {
776
+ static parse(t, n = {}) {
777
+ let [r, ...i] = t.split(/\{(.*?)\}/g).map((e) => e.trim()).filter(Boolean), a = {}, o = {};
778
+ for (let t of i) {
779
+ let { name: r, isFlag: i, definition: s } = e.parseParamSignature(t, n);
780
+ i ? a[r] = s : o[r] = s;
781
+ }
782
+ return {
783
+ command: r,
784
+ flags: a,
785
+ args: o
786
+ };
787
+ }
788
+ static parseParamSignature(e, t) {
789
+ let n = e, r = !1, i, a, o, s = !1, c = !1, l = !0;
790
+ if (n.includes(":")) {
791
+ let [e, t] = n.split(":");
792
+ n = e.trim(), i = t.trim();
793
+ }
794
+ if (n.includes("=")) {
795
+ let [e, t] = n.split("=");
796
+ n = e.trim();
797
+ let r = t.trim();
798
+ l = !1, r.length ? r === "*" ? (c = !0, a = []) : r === "true" ? (s = !0, a = !0) : r === "false" ? (s = !0, a = !1) : a = r : a = null;
799
+ } else n.startsWith("--") && (s = !0, l = !1, a = !1);
800
+ if (n.includes("|")) {
801
+ let [e, ...t] = n.split("|");
802
+ n = e.trim(), o = t.map((e) => e.trim());
803
+ }
804
+ n.startsWith("--") && (r = !0, n = n.slice(2)), n.endsWith("?") && (l = !1, n = n.slice(0, -1)), n.endsWith("*") && (c = !0, l = !0, a = [], n = n.slice(0, -1)), i = i ?? t[n] ?? t[`--${n}`];
805
+ let u, d = r ? h : g;
806
+ return u = s ? h.boolean({
807
+ description: i,
808
+ alias: o,
809
+ ...a === void 0 ? {} : { default: a }
810
+ }) : c ? d.string({
811
+ description: i,
812
+ alias: o,
813
+ multiple: !0,
814
+ ...l ? { required: !0 } : {},
815
+ default: a ?? []
816
+ }) : d.string({
817
+ description: i,
818
+ alias: o,
819
+ ...l ? { required: !0 } : {},
820
+ ...a === void 0 ? {} : { default: a }
821
+ }), {
822
+ name: n,
823
+ isFlag: r,
824
+ definition: u
825
+ };
826
+ }
827
+ }, D = class extends b {
828
+ static signature = "";
829
+ static helperDefinitions = {};
830
+ static get command() {
831
+ return this.signature.split(/\s/)[0] || "";
832
+ }
833
+ async run(e) {
834
+ let t = this.constructor;
835
+ if (t.signature && !Object.prototype.hasOwnProperty.call(t, "_signatureParsed")) {
836
+ let e = E.parse(t.signature, t.helperDefinitions), n = Object.prototype.hasOwnProperty.call(t, "flags") ? t.flags : {}, r = Object.prototype.hasOwnProperty.call(t, "args") ? t.args : {};
837
+ t.flags = {
838
+ ...e.flags,
839
+ ...n
840
+ }, t.args = {
841
+ ...e.args,
842
+ ...r
843
+ }, Object.defineProperty(t, "_signatureParsed", { value: !0 });
844
+ }
845
+ return super.run(e);
846
+ }
847
+ flag(e, t = null) {
848
+ return this.parser.flag(e, t);
849
+ }
850
+ argument(e, t = null) {
851
+ return this.parser.argument(e, t);
852
+ }
853
+ }, O = class {
854
+ logger;
855
+ constructor(e) {
856
+ this.logger = e;
857
+ }
858
+ handle(e) {
859
+ if (C(e)) return e.pretty(this.logger), -1;
860
+ throw e;
861
+ }
862
+ }, k = class extends b {
863
+ static command = "help";
864
+ static description = t.bold("Show help information about the CLI and its commands");
865
+ constructor(e) {
866
+ super(), this.opts = e;
867
+ }
868
+ async handle() {
869
+ let e = this.opts.commandRegistry.getCommands().filter((e) => !e.hidden), n = this.opts.cliName ?? "Bob CLI", r = this.opts.cliVersion ?? "0.0.0", i = (await import("../package-DXx2gXIL.js"))?.default?.version ?? "0.0.0";
870
+ this.io.log(`${n} ${t.green(r)} (core: ${t.yellow(i)})
990
871
 
991
- ${a.yellow("Usage")}:
872
+ ${t.yellow("Usage")}:
992
873
  command [options] [arguments]
993
874
 
994
- ${a.yellow("Available commands")}:
875
+ ${t.yellow("Available commands")}:
995
876
  `);
996
- const s = Math.max(...t.map((m) => m.command.length)) ?? 0, o = {};
997
- for (const m of t) {
998
- const h = m.group ?? m.command.split(":")[0];
999
- o[h] || (o[h] = []), o[h].push(m);
1000
- }
1001
- const u = Object.entries(o).sort(([m], [h]) => m.toLowerCase().localeCompare(h.toLowerCase())).sort(([, m], [, h]) => m.length - h.length);
1002
- for (const [m, h] of u) {
1003
- const l = h.length > 1;
1004
- l && this.io.log(a.yellow(`${m}:`));
1005
- const d = h.sort((p, c) => p.command.toLowerCase().localeCompare(c.command.toLowerCase()));
1006
- for (const p of d) {
1007
- let c = O(s - p.command.length);
1008
- l && (c = c.slice(2)), this.io.log(`${l ? " " : ""}${a.green(p.command)} ${c} ${p.description}`);
1009
- }
1010
- }
1011
- }
1012
- }
1013
- class Y {
1014
- ctx;
1015
- logger;
1016
- commandRegistry;
1017
- exceptionHandler;
1018
- helpCommand;
1019
- newCommandRegistry(t) {
1020
- return new T(t);
1021
- }
1022
- newHelpCommand(t) {
1023
- return new _(t);
1024
- }
1025
- newExceptionHandler(t) {
1026
- return new W(t.logger);
1027
- }
1028
- constructor(t = {}) {
1029
- this.ctx = t.ctx, this.logger = t.logger ?? new V(), this.commandRegistry = this.newCommandRegistry({
1030
- logger: this.logger
1031
- }), this.exceptionHandler = this.newExceptionHandler({
1032
- logger: this.logger
1033
- }), this.helpCommand = this.newHelpCommand({
1034
- cliName: t.name,
1035
- cliVersion: t.version,
1036
- commandRegistry: this.commandRegistry
1037
- });
1038
- }
1039
- withCommandResolver(t) {
1040
- return this.commandRegistry.withCommandResolver(t), this;
1041
- }
1042
- withFileImporter(t) {
1043
- return this.commandRegistry.withFileImporter(t), this;
1044
- }
1045
- async withCommands(...t) {
1046
- for (const e of t)
1047
- typeof e == "string" ? await this.commandRegistry.loadCommandsPath(e) : typeof e == "function" ? this.registerCommand(new e()) : this.registerCommand(e);
1048
- }
1049
- async runCommand(t, ...e) {
1050
- return t ? await this.commandRegistry.runCommand(this.ctx ?? {}, t, ...e).catch(this.exceptionHandler.handle.bind(this.exceptionHandler)) : await this.runHelpCommand();
1051
- }
1052
- async runHelpCommand() {
1053
- return await this.runCommand(this.helpCommand);
1054
- }
1055
- registerCommand(t) {
1056
- this.commandRegistry.registerCommand(t);
1057
- }
1058
- }
1059
- export {
1060
- C as BadCommandOption,
1061
- Q as BadCommandParameter,
1062
- f as BobError,
1063
- Y as Cli,
1064
- A as Command,
1065
- S as CommandIO,
1066
- H as CommandNotFoundError,
1067
- N as CommandParser,
1068
- T as CommandRegistry,
1069
- $ as CommandSignatureParser,
1070
- X as CommandWithSignature,
1071
- W as ExceptionHandler,
1072
- M as HelpOption,
1073
- b as InvalidOption,
1074
- V as Logger,
1075
- k as MissingRequiredArgumentValue,
1076
- D as MissingRequiredOptionValue,
1077
- B as StringSimilarity,
1078
- P as TooManyArguments
877
+ let a = Math.max(...e.map((e) => e.command.length)) ?? 0, o = {};
878
+ for (let t of e) {
879
+ let e = t.group ?? t.command.split(":")[0];
880
+ o[e] || (o[e] = []), o[e].push(t);
881
+ }
882
+ let s = Object.entries(o).sort(([e], [t]) => e.toLowerCase().localeCompare(t.toLowerCase())).sort(([, e], [, t]) => e.length - t.length);
883
+ for (let [e, n] of s) {
884
+ let r = n.length > 1;
885
+ r && this.io.log(t.yellow(`${e}:`));
886
+ let i = n.sort((e, t) => e.command.toLowerCase().localeCompare(t.command.toLowerCase()));
887
+ for (let e of i) {
888
+ let n = _(a - e.command.length);
889
+ r && (n = n.slice(2)), this.io.log(`${r ? " " : ""}${t.green(e.command)} ${n} ${e.description}`);
890
+ }
891
+ }
892
+ }
893
+ }, A = class {
894
+ ctx;
895
+ logger;
896
+ commandRegistry;
897
+ exceptionHandler;
898
+ helpCommand;
899
+ newCommandRegistry(e) {
900
+ return new T(e);
901
+ }
902
+ newHelpCommand(e) {
903
+ return new k(e);
904
+ }
905
+ newExceptionHandler(e) {
906
+ return new O(e.logger);
907
+ }
908
+ constructor(e = {}) {
909
+ this.ctx = e.ctx, this.logger = e.logger ?? new x(), this.commandRegistry = this.newCommandRegistry({ logger: this.logger }), this.exceptionHandler = this.newExceptionHandler({ logger: this.logger }), this.helpCommand = this.newHelpCommand({
910
+ cliName: e.name,
911
+ cliVersion: e.version,
912
+ commandRegistry: this.commandRegistry
913
+ });
914
+ }
915
+ withCommandResolver(e) {
916
+ return this.commandRegistry.withCommandResolver(e), this;
917
+ }
918
+ withFileImporter(e) {
919
+ return this.commandRegistry.withFileImporter(e), this;
920
+ }
921
+ async withCommands(...e) {
922
+ for (let t of e) typeof t == "string" ? await this.commandRegistry.loadCommandsPath(t) : typeof t == "function" ? this.registerCommand(t) : this.registerCommand(t.constructor);
923
+ }
924
+ async runCommand(e, ...t) {
925
+ return e ? await this.commandRegistry.runCommand(this.ctx ?? {}, e, ...t).catch(this.exceptionHandler.handle.bind(this.exceptionHandler)) : await this.runHelpCommand();
926
+ }
927
+ async runHelpCommand() {
928
+ return await this.runCommand(this.helpCommand);
929
+ }
930
+ registerCommand(e) {
931
+ this.commandRegistry.registerCommand(e);
932
+ }
1079
933
  };
934
+ //#endregion
935
+ export { g as Args, u as BadCommandArgument, d as BadCommandFlag, o as BobError, A as Cli, b as Command, a as CommandIO, f as CommandNotFoundError, m as CommandParser, T as CommandRegistry, E as CommandSignatureParser, D as CommandWithSignature, O as ExceptionHandler, h as Flags, y as HelpCommandFlag, s as InvalidFlag, x as Logger, c as MissingRequiredArgumentValue, l as MissingRequiredFlagValue, S as StringSimilarity, p as TooManyArguments };