bob-core 3.0.0-beta.4 → 3.0.0-beta.6

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 (183) hide show
  1. package/README.md +3 -3
  2. package/dist/cjs/{src/Cli.d.ts → Cli.d.ts} +20 -0
  3. package/dist/cjs/Command.d.ts +91 -0
  4. package/dist/cjs/CommandParser.d.ts +122 -0
  5. package/dist/cjs/{src/CommandRegistry.d.ts → CommandRegistry.d.ts} +12 -0
  6. package/dist/cjs/ExceptionHandler.d.ts +14 -0
  7. package/dist/cjs/HelpFlag.d.ts +27 -0
  8. package/dist/cjs/StringSimilarity.d.ts +31 -0
  9. package/dist/cjs/args/index.d.ts +131 -0
  10. package/dist/{esm/src → cjs}/errors/BadCommandArgument.d.ts +4 -2
  11. package/dist/cjs/{src/errors → errors}/BadCommandFlag.d.ts +4 -2
  12. package/dist/cjs/errors/BobError.d.ts +13 -0
  13. package/dist/cjs/errors/CommandNotFoundError.d.ts +9 -0
  14. package/dist/{esm/src → cjs}/errors/InvalidFlag.d.ts +4 -2
  15. package/dist/cjs/errors/MissingRequiredArgumentValue.d.ts +9 -0
  16. package/dist/cjs/errors/MissingRequiredFlagValue.d.ts +9 -0
  17. package/dist/cjs/errors/TooManyArguments.d.ts +10 -0
  18. package/dist/cjs/errors/ValidationError.d.ts +10 -0
  19. package/dist/{esm/src → cjs}/errors/renderError.d.ts +2 -2
  20. package/dist/cjs/flags/boolean.d.ts +20 -0
  21. package/dist/cjs/flags/custom.d.ts +12 -0
  22. package/dist/cjs/flags/directory.d.ts +27 -0
  23. package/dist/cjs/flags/file.d.ts +27 -0
  24. package/dist/cjs/flags/helpers.d.ts +9 -0
  25. package/dist/cjs/flags/index.d.ts +160 -0
  26. package/dist/cjs/flags/number.d.ts +32 -0
  27. package/dist/cjs/flags/option.d.ts +8 -0
  28. package/dist/cjs/flags/string.d.ts +19 -0
  29. package/dist/cjs/flags/url.d.ts +19 -0
  30. package/dist/cjs/index.js +10 -0
  31. package/dist/cjs/{src/lib → lib}/helpers.d.ts +1 -1
  32. package/dist/cjs/lib/types.d.ts +99 -0
  33. package/dist/cjs/shared/ask-helpers.d.ts +7 -0
  34. package/dist/cjs/shared/flagsUtils.d.ts +5 -0
  35. package/dist/cjs/ux/askForConfirmation.d.ts +10 -0
  36. package/dist/cjs/{src/ux → ux}/askForToggle.d.ts +5 -1
  37. package/dist/cjs/ux/helpers.d.ts +6 -0
  38. package/dist/{esm/src → cjs}/ux/index.d.ts +30 -2
  39. package/dist/esm/{src/Cli.d.ts → Cli.d.ts} +20 -0
  40. package/dist/esm/Command.d.ts +91 -0
  41. package/dist/esm/CommandParser.d.ts +122 -0
  42. package/dist/esm/{src/CommandRegistry.d.ts → CommandRegistry.d.ts} +12 -0
  43. package/dist/esm/ExceptionHandler.d.ts +14 -0
  44. package/dist/esm/HelpFlag.d.ts +27 -0
  45. package/dist/esm/StringSimilarity.d.ts +31 -0
  46. package/dist/esm/args/index.d.ts +131 -0
  47. package/dist/{cjs/src → esm}/errors/BadCommandArgument.d.ts +4 -2
  48. package/dist/esm/{src/errors → errors}/BadCommandFlag.d.ts +4 -2
  49. package/dist/esm/errors/BobError.d.ts +13 -0
  50. package/dist/esm/errors/CommandNotFoundError.d.ts +9 -0
  51. package/dist/{cjs/src → esm}/errors/InvalidFlag.d.ts +4 -2
  52. package/dist/esm/errors/MissingRequiredArgumentValue.d.ts +9 -0
  53. package/dist/esm/errors/MissingRequiredFlagValue.d.ts +9 -0
  54. package/dist/esm/errors/TooManyArguments.d.ts +10 -0
  55. package/dist/esm/errors/ValidationError.d.ts +10 -0
  56. package/dist/{cjs/src → esm}/errors/renderError.d.ts +2 -2
  57. package/dist/esm/flags/boolean.d.ts +20 -0
  58. package/dist/esm/flags/custom.d.ts +12 -0
  59. package/dist/esm/flags/directory.d.ts +27 -0
  60. package/dist/esm/flags/file.d.ts +27 -0
  61. package/dist/esm/flags/helpers.d.ts +9 -0
  62. package/dist/esm/flags/index.d.ts +160 -0
  63. package/dist/esm/flags/number.d.ts +32 -0
  64. package/dist/esm/flags/option.d.ts +8 -0
  65. package/dist/esm/flags/string.d.ts +19 -0
  66. package/dist/esm/flags/url.d.ts +19 -0
  67. package/dist/esm/{src/index.js → index.js} +346 -267
  68. package/dist/esm/{src/lib → lib}/helpers.d.ts +1 -1
  69. package/dist/esm/lib/types.d.ts +99 -0
  70. package/dist/esm/shared/ask-helpers.d.ts +7 -0
  71. package/dist/esm/shared/flagsUtils.d.ts +5 -0
  72. package/dist/esm/ux/askForConfirmation.d.ts +10 -0
  73. package/dist/esm/{src/ux → ux}/askForToggle.d.ts +5 -1
  74. package/dist/esm/ux/helpers.d.ts +6 -0
  75. package/dist/{cjs/src → esm}/ux/index.d.ts +30 -2
  76. package/package.json +1 -1
  77. package/dist/cjs/package-BYPkkzPN.cjs +0 -1
  78. package/dist/cjs/src/Command.d.ts +0 -48
  79. package/dist/cjs/src/CommandParser.d.ts +0 -110
  80. package/dist/cjs/src/ExceptionHandler.d.ts +0 -6
  81. package/dist/cjs/src/HelpFlag.d.ts +0 -12
  82. package/dist/cjs/src/StringSimilarity.d.ts +0 -26
  83. package/dist/cjs/src/args/index.d.ts +0 -67
  84. package/dist/cjs/src/errors/BobError.d.ts +0 -5
  85. package/dist/cjs/src/errors/CommandNotFoundError.d.ts +0 -7
  86. package/dist/cjs/src/errors/MissingRequiredArgumentValue.d.ts +0 -7
  87. package/dist/cjs/src/errors/MissingRequiredFlagValue.d.ts +0 -7
  88. package/dist/cjs/src/errors/TooManyArguments.d.ts +0 -8
  89. package/dist/cjs/src/errors/ValidationError.d.ts +0 -3
  90. package/dist/cjs/src/flags/boolean.d.ts +0 -9
  91. package/dist/cjs/src/flags/custom.d.ts +0 -9
  92. package/dist/cjs/src/flags/directory.d.ts +0 -14
  93. package/dist/cjs/src/flags/file.d.ts +0 -14
  94. package/dist/cjs/src/flags/helpers.d.ts +0 -3
  95. package/dist/cjs/src/flags/index.d.ts +0 -76
  96. package/dist/cjs/src/flags/number.d.ts +0 -17
  97. package/dist/cjs/src/flags/option.d.ts +0 -6
  98. package/dist/cjs/src/flags/string.d.ts +0 -8
  99. package/dist/cjs/src/flags/url.d.ts +0 -8
  100. package/dist/cjs/src/index.js +0 -10
  101. package/dist/cjs/src/lib/types.d.ts +0 -59
  102. package/dist/cjs/src/shared/ask-helpers.d.ts +0 -7
  103. package/dist/cjs/src/ux/askForConfirmation.d.ts +0 -5
  104. package/dist/cjs/src/ux/helpers.d.ts +0 -1
  105. package/dist/esm/package-LkysKcR6.js +0 -60
  106. package/dist/esm/src/Command.d.ts +0 -48
  107. package/dist/esm/src/CommandParser.d.ts +0 -110
  108. package/dist/esm/src/ExceptionHandler.d.ts +0 -6
  109. package/dist/esm/src/HelpFlag.d.ts +0 -12
  110. package/dist/esm/src/StringSimilarity.d.ts +0 -26
  111. package/dist/esm/src/args/index.d.ts +0 -67
  112. package/dist/esm/src/errors/BobError.d.ts +0 -5
  113. package/dist/esm/src/errors/CommandNotFoundError.d.ts +0 -7
  114. package/dist/esm/src/errors/MissingRequiredArgumentValue.d.ts +0 -7
  115. package/dist/esm/src/errors/MissingRequiredFlagValue.d.ts +0 -7
  116. package/dist/esm/src/errors/TooManyArguments.d.ts +0 -8
  117. package/dist/esm/src/errors/ValidationError.d.ts +0 -3
  118. package/dist/esm/src/flags/boolean.d.ts +0 -9
  119. package/dist/esm/src/flags/custom.d.ts +0 -9
  120. package/dist/esm/src/flags/directory.d.ts +0 -14
  121. package/dist/esm/src/flags/file.d.ts +0 -14
  122. package/dist/esm/src/flags/helpers.d.ts +0 -3
  123. package/dist/esm/src/flags/index.d.ts +0 -76
  124. package/dist/esm/src/flags/number.d.ts +0 -17
  125. package/dist/esm/src/flags/option.d.ts +0 -6
  126. package/dist/esm/src/flags/string.d.ts +0 -8
  127. package/dist/esm/src/flags/url.d.ts +0 -8
  128. package/dist/esm/src/lib/types.d.ts +0 -59
  129. package/dist/esm/src/shared/ask-helpers.d.ts +0 -7
  130. package/dist/esm/src/ux/askForConfirmation.d.ts +0 -5
  131. package/dist/esm/src/ux/helpers.d.ts +0 -1
  132. /package/dist/cjs/{src/CommandSignatureParser.d.ts → CommandSignatureParser.d.ts} +0 -0
  133. /package/dist/cjs/{src/CommandWithSignature.d.ts → CommandWithSignature.d.ts} +0 -0
  134. /package/dist/cjs/{src/Logger.d.ts → Logger.d.ts} +0 -0
  135. /package/dist/cjs/{src/commands → commands}/HelpCommand.d.ts +0 -0
  136. /package/dist/cjs/{src/contracts → contracts}/LoggerContract.d.ts +0 -0
  137. /package/dist/cjs/{src/contracts → contracts}/index.d.ts +0 -0
  138. /package/dist/cjs/{src/errors → errors}/index.d.ts +0 -0
  139. /package/dist/cjs/{src/index.d.ts → index.d.ts} +0 -0
  140. /package/dist/cjs/{src/lib → lib}/string.d.ts +0 -0
  141. /package/dist/cjs/{src/shared → shared}/parsers.d.ts +0 -0
  142. /package/dist/cjs/{src/ux → ux}/askForCheckbox.d.ts +0 -0
  143. /package/dist/cjs/{src/ux → ux}/askForEditor.d.ts +0 -0
  144. /package/dist/cjs/{src/ux → ux}/askForExpand.d.ts +0 -0
  145. /package/dist/cjs/{src/ux → ux}/askForFileSelector.d.ts +0 -0
  146. /package/dist/cjs/{src/ux → ux}/askForInput.d.ts +0 -0
  147. /package/dist/cjs/{src/ux → ux}/askForList.d.ts +0 -0
  148. /package/dist/cjs/{src/ux → ux}/askForNumber.d.ts +0 -0
  149. /package/dist/cjs/{src/ux → ux}/askForPassword.d.ts +0 -0
  150. /package/dist/cjs/{src/ux → ux}/askForRawList.d.ts +0 -0
  151. /package/dist/cjs/{src/ux → ux}/askForSearch.d.ts +0 -0
  152. /package/dist/cjs/{src/ux → ux}/askForSelect.d.ts +0 -0
  153. /package/dist/cjs/{src/ux → ux}/keyValue.d.ts +0 -0
  154. /package/dist/cjs/{src/ux → ux}/loader.d.ts +0 -0
  155. /package/dist/cjs/{src/ux → ux}/progressBar.d.ts +0 -0
  156. /package/dist/cjs/{src/ux → ux}/table.d.ts +0 -0
  157. /package/dist/cjs/{src/ux → ux}/types.d.ts +0 -0
  158. /package/dist/esm/{src/CommandSignatureParser.d.ts → CommandSignatureParser.d.ts} +0 -0
  159. /package/dist/esm/{src/CommandWithSignature.d.ts → CommandWithSignature.d.ts} +0 -0
  160. /package/dist/esm/{src/Logger.d.ts → Logger.d.ts} +0 -0
  161. /package/dist/esm/{src/commands → commands}/HelpCommand.d.ts +0 -0
  162. /package/dist/esm/{src/contracts → contracts}/LoggerContract.d.ts +0 -0
  163. /package/dist/esm/{src/contracts → contracts}/index.d.ts +0 -0
  164. /package/dist/esm/{src/errors → errors}/index.d.ts +0 -0
  165. /package/dist/esm/{src/index.d.ts → index.d.ts} +0 -0
  166. /package/dist/esm/{src/lib → lib}/string.d.ts +0 -0
  167. /package/dist/esm/{src/shared → shared}/parsers.d.ts +0 -0
  168. /package/dist/esm/{src/ux → ux}/askForCheckbox.d.ts +0 -0
  169. /package/dist/esm/{src/ux → ux}/askForEditor.d.ts +0 -0
  170. /package/dist/esm/{src/ux → ux}/askForExpand.d.ts +0 -0
  171. /package/dist/esm/{src/ux → ux}/askForFileSelector.d.ts +0 -0
  172. /package/dist/esm/{src/ux → ux}/askForInput.d.ts +0 -0
  173. /package/dist/esm/{src/ux → ux}/askForList.d.ts +0 -0
  174. /package/dist/esm/{src/ux → ux}/askForNumber.d.ts +0 -0
  175. /package/dist/esm/{src/ux → ux}/askForPassword.d.ts +0 -0
  176. /package/dist/esm/{src/ux → ux}/askForRawList.d.ts +0 -0
  177. /package/dist/esm/{src/ux → ux}/askForSearch.d.ts +0 -0
  178. /package/dist/esm/{src/ux → ux}/askForSelect.d.ts +0 -0
  179. /package/dist/esm/{src/ux → ux}/keyValue.d.ts +0 -0
  180. /package/dist/esm/{src/ux → ux}/loader.d.ts +0 -0
  181. /package/dist/esm/{src/ux → ux}/progressBar.d.ts +0 -0
  182. /package/dist/esm/{src/ux → ux}/table.d.ts +0 -0
  183. /package/dist/esm/{src/ux → ux}/types.d.ts +0 -0
@@ -1,4 +1,4 @@
1
1
  import { Command } from '../Command.js';
2
2
  import { BobError } from '../errors/index.js';
3
- export declare function isBobError(err: Error): err is BobError;
3
+ export declare function isBobError(err: unknown): err is BobError;
4
4
  export declare function isBobCommandClass(cls: unknown): cls is typeof Command;
@@ -0,0 +1,99 @@
1
+ import { Command } from '../Command.js';
2
+ import { UX } from '../ux/index.js';
3
+ export type ContextDefinition = any;
4
+ export type CustomOptions = Record<string, unknown>;
5
+ export type FlagKind = 'string' | 'number' | 'boolean' | 'option' | 'file' | 'directory' | 'url' | 'custom';
6
+ /**
7
+ * Options handed to a flag's `parse`, `ask`, and `handler` callbacks.
8
+ *
9
+ * `definition` is typed as the canonical {@link FlagDefinition}. Builder-specific
10
+ * extras (`options`, `min`, `max`, `exists`, `secret`) live directly on
11
+ * {@link FlagDefinition}, so handlers can read them without `any` casts while still
12
+ * being honest that they are optional at the type level.
13
+ */
14
+ export type FlagOpts<C extends ContextDefinition = ContextDefinition, P extends CustomOptions = CustomOptions> = {
15
+ name: string;
16
+ ux: UX;
17
+ ctx: C;
18
+ definition: FlagDefinition<C, P>;
19
+ cmd: typeof Command;
20
+ };
21
+ export type FlagDefinition<T = any, C extends CustomOptions = CustomOptions> = {
22
+ [key in keyof C]: C[keyof C];
23
+ } & {
24
+ parse: (input: any, opts: FlagOpts<any, C>) => T;
25
+ type?: FlagKind;
26
+ ask?: (opts: FlagOpts) => Promise<any>;
27
+ description?: string;
28
+ required?: boolean;
29
+ default?: T | T[] | null | (() => T | T[] | null) | (() => Promise<T | T[] | null>);
30
+ multiple?: boolean;
31
+ help?: string;
32
+ alias?: string | readonly string[];
33
+ handler?: (value: T, opts: FlagOpts) => {
34
+ shouldStop: boolean;
35
+ } | void;
36
+ };
37
+ export type InitFlagDefinition<T = any, C extends CustomOptions = CustomOptions> = Omit<FlagDefinition<T, C>, 'parse'> & {
38
+ parse?: (input: any, opts: FlagOpts<any, C>) => T;
39
+ };
40
+ /** Infers the runtime return type of a flag definition, accounting for `multiple`. */
41
+ export type InferFlagReturn<O> = O extends {
42
+ parse: (...args: any[]) => infer R;
43
+ } ? O extends {
44
+ multiple: true;
45
+ } ? [R] extends [Array<unknown>] ? R : R[] : R : never;
46
+ /**
47
+ * `true` when the parsed value cannot be `null`:
48
+ * - `required: true`
49
+ * - `multiple: true` (always an array)
50
+ * - `default` resolves to a value where neither `null` nor `undefined` is in the union
51
+ * (covers `T`, `T[]`, `() => T`, `() => Promise<T>`)
52
+ */
53
+ type IsGuaranteed<O> = O extends {
54
+ required: true;
55
+ } ? true : O extends {
56
+ multiple: true;
57
+ } ? true : O extends {
58
+ default: infer D;
59
+ } ? null extends D ? false : undefined extends D ? false : true : false;
60
+ /**
61
+ * Final value type seen by the handler — `T` if guaranteed (required, multiple,
62
+ * or non-null default), otherwise `T | null`.
63
+ */
64
+ export type FlagReturnType<O> = IsGuaranteed<O> extends true ? InferFlagReturn<O> : InferFlagReturn<O> | null;
65
+ /** Historic alias — kept so `FlagType<O>` keeps working as a value-inference helper. */
66
+ export type FlagType<O> = InferFlagReturn<O>;
67
+ /** Schema mapping flag names to their {@link FlagDefinition}. */
68
+ export type FlagsSchema = {
69
+ [key: string]: FlagDefinition<any, any>;
70
+ };
71
+ /** Inferred runtime shape of all flags in a schema. */
72
+ export type FlagsObject<Options extends FlagsSchema> = {
73
+ [Key in keyof Options]: FlagReturnType<Options[Key]>;
74
+ };
75
+ /**
76
+ * Schema for positional arguments.
77
+ *
78
+ * Note on booleans: positional booleans don't really make sense, so the
79
+ * canonical {@link Args} builder set deliberately omits `Args.boolean`. The
80
+ * type itself is a structural alias of {@link FlagsSchema} (rather than a
81
+ * branded subtype) to keep literal-type inference flowing through the builder
82
+ * generics without surprising errors. If you put `Flags.boolean()` in
83
+ * `static args`, the runtime parser will accept it but you're outside the
84
+ * supported design.
85
+ */
86
+ export type ArgDefinition = FlagDefinition;
87
+ export type ArgsSchema = FlagsSchema;
88
+ export type InferFlags<T> = T extends {
89
+ flags: infer O extends FlagsSchema;
90
+ } ? O : FlagsSchema;
91
+ export type InferArgs<T> = T extends {
92
+ args: infer A extends ArgsSchema;
93
+ } ? A : ArgsSchema;
94
+ /** `{ flags, args }` pair for a given Command class — the second handler argument. */
95
+ export type Parsed<T> = {
96
+ flags: FlagsObject<InferFlags<T>>;
97
+ args: FlagsObject<InferArgs<T>>;
98
+ };
99
+ export {};
@@ -0,0 +1,7 @@
1
+ import { FlagOpts } from '../lib/types.js';
2
+ export declare function buildStringAsk(builderOpts: FlagOpts): Promise<any>;
3
+ export declare function buildNumberAsk(builderOpts: FlagOpts): Promise<any>;
4
+ export declare function buildOptionAsk(builderOpts: FlagOpts): Promise<any>;
5
+ export declare function buildFileAsk(builderOpts: FlagOpts): Promise<any>;
6
+ export declare function buildDirectoryAsk(builderOpts: FlagOpts): Promise<any>;
7
+ export declare function buildUrlAsk(builderOpts: FlagOpts): Promise<any>;
@@ -0,0 +1,5 @@
1
+ import { numberFlag } from '../flags/number.js';
2
+ import { optionFlag } from '../flags/option.js';
3
+ import { FlagDefinition } from '../lib/types.js';
4
+ export declare function isNumberFlag(flag: FlagDefinition): flag is ReturnType<typeof numberFlag>;
5
+ export declare function isOptionFlag(flag: FlagDefinition<any, any>): flag is ReturnType<typeof optionFlag>;
@@ -0,0 +1,10 @@
1
+ export type AskForConfirmationOptions = {
2
+ default?: boolean;
3
+ transformer?: (value: boolean) => string;
4
+ };
5
+ /**
6
+ * Yes/no confirmation prompt. Returns the user's choice, or `null` if they
7
+ * cancelled (Ctrl+C / SIGINT) — matching the cancellation contract used by
8
+ * every other prompt in the {@link UX} module.
9
+ */
10
+ export declare function askForConfirmation(message?: string, opts?: AskForConfirmationOptions): Promise<boolean | null>;
@@ -3,4 +3,8 @@ export type AskForToggleOptions = {
3
3
  active?: string;
4
4
  inactive?: string;
5
5
  };
6
- export declare function askForToggle(message: string, opts?: AskForToggleOptions): Promise<boolean>;
6
+ /**
7
+ * Two-state toggle prompt with custom labels. Returns the chosen state, or
8
+ * `null` if cancelled (Ctrl+C / SIGINT).
9
+ */
10
+ export declare function askForToggle(message: string, opts?: AskForToggleOptions): Promise<boolean | null>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Wraps an inquirer prompt so that cancellation (Ctrl+C / SIGINT, surfaced as
3
+ * `ExitPromptError`) resolves to `fallback` instead of throwing. Every other
4
+ * exception propagates so genuine failures stay visible.
5
+ */
6
+ export declare function withCancelHandling<T>(fn: () => Promise<T>, fallback: T): Promise<T>;
@@ -12,32 +12,59 @@ import { AskForSearchOptions, SearchSource } from './askForSearch.js';
12
12
  import { AskForSelectOptions } from './askForSelect.js';
13
13
  import { AskForToggleOptions } from './askForToggle.js';
14
14
  import { KeyValueOptions, ProgressBarOptions, SelectOption, TableColumn } from './types.js';
15
+ /**
16
+ * Interactive prompts and structured-output helpers exposed to commands as
17
+ * `this.ux`.
18
+ *
19
+ * **Cancellation contract:** every `askFor*` method returns `Promise<T | null>`,
20
+ * where `null` means the user cancelled the prompt (Ctrl+C / SIGINT). Callers
21
+ * should treat `null` as "user wants out" and react accordingly — there is no
22
+ * separate "cancelled" exception to catch.
23
+ */
15
24
  export declare class UX {
16
- askForConfirmation(message?: string, opts?: AskForConfirmationOptions): Promise<boolean>;
25
+ /** Yes/no confirmation. Returns `null` on cancel. */
26
+ askForConfirmation(message?: string, opts?: AskForConfirmationOptions): Promise<boolean | null>;
27
+ /** Free-text input. Returns `null` on cancel. */
17
28
  askForInput(message: string, opts?: AskForInputOptions): Promise<string | null>;
29
+ /** Masked password input. Returns `null` on cancel. */
18
30
  askForPassword(message: string, opts?: AskForPasswordOptions): Promise<string | null>;
31
+ /** Numeric input with optional validator. Returns `null` on cancel. */
19
32
  askForNumber(message: string, opts?: AskForNumberOptions): Promise<number | null>;
33
+ /** Single-choice list. Returns `null` on cancel. */
20
34
  askForSelect<V = string>(message: string, choices: Array<string | SelectOption<V>>, opts?: AskForSelectOptions<V>): Promise<V | null>;
35
+ /** Multi-choice checkbox list. Returns `null` on cancel. */
21
36
  askForCheckbox<V = string>(message: string, choices: Array<string | SelectOption<V>>, opts?: AskForCheckboxOptions<V>): Promise<V[] | null>;
37
+ /** Type-ahead search backed by a custom source. Returns `null` on cancel. */
22
38
  askForSearch<V = string>(message: string, source: SearchSource<V>, opts?: AskForSearchOptions<V>): Promise<V | null>;
39
+ /** Comma-separated list input. Returns `null` on cancel. */
23
40
  askForList(message: string, opts?: AskForListOptions): Promise<string[] | null>;
24
- askForToggle(message: string, opts?: AskForToggleOptions): Promise<boolean>;
41
+ /** Two-state toggle with custom labels. Returns `null` on cancel. */
42
+ askForToggle(message: string, opts?: AskForToggleOptions): Promise<boolean | null>;
43
+ /** Opens the user's editor (`$EDITOR`). Returns `null` on cancel. */
25
44
  askForEditor(message: string, opts?: AskForEditorOptions): Promise<string | null>;
45
+ /** Numbered list with manual entry. Returns `null` on cancel. */
26
46
  askForRawList<V = string>(message: string, choices: Array<{
27
47
  key?: string;
28
48
  name?: string;
29
49
  value: V;
30
50
  }>, opts?: AskForRawListOptions): Promise<V | null>;
51
+ /** Single-key expand prompt (Yes/No/Help-style). Returns `null` on cancel. */
31
52
  askForExpand<V = string>(message: string, choices: Array<{
32
53
  key: ExpandKey;
33
54
  name: string;
34
55
  value: V;
35
56
  }>, opts?: AskForExpandOptions): Promise<V | null>;
57
+ /** Filesystem file picker. Returns `null` on cancel. */
36
58
  askForFile(message: string, opts?: Omit<AskForFileSelectorOptions, 'type'>): Promise<string | null>;
59
+ /** Filesystem directory picker. Returns `null` on cancel. */
37
60
  askForDirectory(message: string, opts?: Omit<AskForFileSelectorOptions, 'type'>): Promise<string | null>;
61
+ /** Generic file/directory picker. Returns `null` on cancel. */
38
62
  askForFileSelector(message: string, opts?: AskForFileSelectorOptions): Promise<string | null>;
63
+ /** Renders a key/value list to the terminal. */
39
64
  keyValue(pairs: Record<string, unknown> | Array<[string, unknown]>, opts?: KeyValueOptions): void;
65
+ /** Renders rows as an aligned table with optional column metadata. */
40
66
  table<T extends Record<string, unknown>>(data: T[], columns?: TableColumn<T>[]): void;
67
+ /** Builds a progress bar bound to a known total. */
41
68
  newProgressBar(total: number, opts?: ProgressBarOptions): {
42
69
  increment: (amount?: number) => void;
43
70
  update: (value: number) => void;
@@ -45,6 +72,7 @@ export declare class UX {
45
72
  [Symbol.dispose]: () => void;
46
73
  [Symbol.asyncDispose]: () => void;
47
74
  };
75
+ /** Builds a spinner-style loader. */
48
76
  newLoader(text?: string, chars?: string[], delay?: number): {
49
77
  [Symbol.dispose]: () => void;
50
78
  [Symbol.asyncDispose]: () => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bob-core",
3
- "version": "3.0.0-beta.4",
3
+ "version": "3.0.0-beta.6",
4
4
  "description": "BOB Core",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/src/index.js",
@@ -1 +0,0 @@
1
- var e={name:`bob-core`,version:`3.0.0-beta.4`,description:`BOB Core`,type:`module`,main:`./dist/cjs/src/index.js`,module:`./dist/esm/src/index.js`,types:`./dist/esm/src/index.d.ts`,files:[`dist`],exports:{".":{import:{types:`./dist/esm/src/index.d.ts`,default:`./dist/esm/src/index.js`},require:{types:`./dist/cjs/src/index.d.ts`,default:`./dist/cjs/src/index.js`}}},scripts:{start:`node -r @swc-node/register debug/main.ts`,build:`rm -rf ./dist && vite build`,typecheck:`tsc --noEmit`,prepack:`npm run build`,test:`vitest run`,lint:`eslint .`,"lint:fix":`eslint . --fix`},author:`Léo Hubert`,license:`ISC`,devDependencies:{"@eslint/js":`^9.39.4`,"@faker-js/faker":`^10.3.0`,"@swc-node/register":`^1.11.1`,"@trivago/prettier-plugin-sort-imports":`^5.2.2`,"@types/minimist":`^1.2.5`,"@types/node":`^20.14.5`,"@types/string-similarity":`^4.0.2`,"@vitest/coverage-v8":`^4.1.0`,eslint:`^9.39.4`,"eslint-config-prettier":`^10.1.8`,"eslint-plugin-prettier":`^5.5.5`,prettier:`^3.6.2`,tsx:`^4.21.0`,typescript:`^5.9.3`,"typescript-eslint":`^8.57.0`,vite:`^8.0.0`,"vite-plugin-dts":`^4.5.4`,vitest:`^4.1.0`},dependencies:{"@inquirer/core":`^11.1.8`,"@inquirer/prompts":`^8.4.1`,chalk:`^5.6.2`,"inquirer-file-selector":`^1.0.1`,minimist:`^1.2.8`}};exports.default=e;
@@ -1,48 +0,0 @@
1
- import { CommandParser } from './CommandParser.js';
2
- import { Logger } from './Logger.js';
3
- import { ArgsSchema, ContextDefinition, FlagsSchema, Parsed } from './lib/types.js';
4
- import { UX } from './ux/index.js';
5
- export type CommandRunExample = {
6
- description: string;
7
- command: string;
8
- };
9
- export type CommandRunOption<C = ContextDefinition> = {
10
- logger: Logger;
11
- ctx: C;
12
- } & ({
13
- args: string[];
14
- } | {
15
- args: Record<string, any>;
16
- flags: Record<string, any>;
17
- });
18
- export declare abstract class Command<C extends ContextDefinition = ContextDefinition> {
19
- static $type: "BobCommand";
20
- static command: string;
21
- static description: string;
22
- static group?: string;
23
- static args: ArgsSchema;
24
- static flags: FlagsSchema;
25
- static examples: CommandRunExample[];
26
- static hidden: boolean;
27
- static aliases: string[];
28
- static disableDefaultOptions: boolean;
29
- static disablePrompting: boolean;
30
- static allowUnknownFlags: boolean;
31
- static strictMode: boolean;
32
- protected ctx: C;
33
- protected logger: Logger;
34
- protected ux: UX;
35
- protected parser: CommandParser<FlagsSchema, ArgsSchema>;
36
- protected preHandle?(): Promise<void | number>;
37
- protected abstract handle(ctx: C, parsed: Parsed<any>): Promise<number | void> | number | void;
38
- static baseFlags: FlagsSchema;
39
- protected newCommandParser(opts: {
40
- flags: FlagsSchema;
41
- args: ArgsSchema;
42
- ctx: ContextDefinition;
43
- ux: UX;
44
- cmd: typeof Command;
45
- }): CommandParser<FlagsSchema, ArgsSchema>;
46
- protected newUX(): UX;
47
- run(runOpts: CommandRunOption<C>): Promise<number | void>;
48
- }
@@ -1,110 +0,0 @@
1
- import { Command } from './Command.js';
2
- import { ArgsSchema, ContextDefinition, FlagDefinition, FlagReturnType, FlagsObject, FlagsSchema } from './lib/types.js';
3
- import { UX } from './ux/index.js';
4
- /**
5
- * Parses command-line arguments into typed flags and arguments
6
- * Handles validation, type conversion, and default values
7
- */
8
- export declare class CommandParser<Flags extends FlagsSchema, Arguments extends ArgsSchema> {
9
- protected opts: {
10
- flags: Flags;
11
- args: Arguments;
12
- ctx?: ContextDefinition;
13
- ux: UX;
14
- cmd?: typeof Command;
15
- };
16
- protected flags: FlagsSchema;
17
- protected parsedFlags: FlagsObject<Flags> | null;
18
- protected args: ArgsSchema;
19
- protected parsedArgs: FlagsObject<Arguments> | null;
20
- protected ux: UX;
21
- protected shouldPromptForMissingFlags: boolean;
22
- protected shouldValidateUnknownFlags: boolean;
23
- protected shouldRejectExtraArguments: boolean;
24
- constructor(opts: {
25
- flags: Flags;
26
- args: Arguments;
27
- ctx?: ContextDefinition;
28
- ux: UX;
29
- cmd?: typeof Command;
30
- });
31
- /**
32
- * Parses raw command-line arguments into structured flags and arguments
33
- * @param args - Raw command line arguments (typically from process.argv.slice(2))
34
- * @returns Object containing parsed flags and arguments
35
- * @throws {InvalidFlag} If an unknown flag is provided
36
- * @throws {BadCommandFlag} If a value cannot be converted to the expected type
37
- */
38
- init(args: string[]): Promise<{
39
- flags: FlagsObject<Flags>;
40
- args: FlagsObject<Arguments>;
41
- }>;
42
- /**
43
- * Validates the parsed flags and arguments
44
- * @throws {Error} If validation fails
45
- */
46
- validate(): Promise<void>;
47
- /**
48
- * Retrieves a parsed flag value by name
49
- * @param name - The flag name
50
- * @param defaultValue - Optional default value if flag is not set
51
- * @returns The typed flag value
52
- * @throws {Error} If init() has not been called yet
53
- */
54
- flag<FlagName extends keyof Flags>(name: FlagName, defaultValue?: FlagReturnType<Flags[FlagName]>): FlagReturnType<Flags[FlagName]>;
55
- setFlag<FlagName extends keyof Flags>(name: FlagName, value: FlagReturnType<Flags[FlagName]>): Promise<void>;
56
- /**
57
- * Retrieves a parsed argument value by name
58
- * @param name - The argument name
59
- * @param defaultValue - Optional default value if argument is not set
60
- * @returns The typed argument value
61
- * @throws {Error} If init() has not been called yet
62
- */
63
- argument<ArgName extends keyof Arguments>(name: ArgName, defaultValue?: FlagReturnType<Arguments[ArgName]>): FlagReturnType<Arguments[ArgName]>;
64
- setArgument<ArgName extends keyof Arguments>(name: ArgName, value: FlagReturnType<Arguments[ArgName]>): Promise<void>;
65
- /**
66
- * Checks if a value should be considered "empty" for default value purposes
67
- * @param value - The value to check
68
- * @returns true if the value is null, undefined, or an empty array
69
- */
70
- private isEmptyValue;
71
- /**
72
- * Validates that all provided flags are recognized
73
- * @throws {InvalidFlag} If an unknown flag is found
74
- */
75
- private validateUnknownFlags;
76
- /**
77
- * Processes named flags from minimist output
78
- */
79
- private handleOptions;
80
- /**
81
- * Processes positional arguments from minimist output
82
- */
83
- private handleArguments;
84
- /**
85
- * Resolves a flag value from the parsed flag values object
86
- * Handles alias resolution, defaults, and type conversion
87
- */
88
- private resolveFlagValue;
89
- /**
90
- * Parses a raw value using the definition's parse function
91
- */
92
- private parseValue;
93
- private buildOpts;
94
- private safeParse;
95
- /**
96
- * Validates a schema (flags or args) and prompts for missing required values
97
- */
98
- private validateSchema;
99
- /**
100
- * Disables prompting for missing argument values
101
- * Useful for non-interactive environments
102
- */
103
- disablePrompting(): this;
104
- allowUnknownFlags(): this;
105
- strictMode(): this;
106
- /**
107
- * Prompts the user to provide a missing value via its `ask` method
108
- */
109
- protected promptFor(name: string, definition: FlagDefinition): Promise<string | number | string[] | boolean | null>;
110
- }
@@ -1,6 +0,0 @@
1
- import { Logger } from './Logger.js';
2
- export declare class ExceptionHandler {
3
- private readonly logger;
4
- constructor(logger: Logger);
5
- handle(err: Error): number;
6
- }
@@ -1,12 +0,0 @@
1
- import { ParameterOpts } from './lib/types.js';
2
- export declare const HelpCommandFlag: import('./lib/types.js').FlagProps<boolean> & import('./lib/types.js').CustomOptions & {
3
- readonly alias: readonly ["h"];
4
- readonly description: "Displays help information about the command";
5
- readonly handler: (value: boolean, opts: ParameterOpts) => {
6
- shouldStop: false;
7
- } | {
8
- shouldStop: true;
9
- };
10
- } & {
11
- parse(input: any, opts: ParameterOpts): boolean;
12
- };
@@ -1,26 +0,0 @@
1
- export interface SimilarityResult {
2
- rating: number;
3
- target: string;
4
- }
5
- export interface BestMatchResult {
6
- bestMatch: SimilarityResult;
7
- bestMatchIndex: number;
8
- ratings: SimilarityResult[];
9
- }
10
- /**
11
- * String similarity calculator using Dice's Coefficient algorithm
12
- */
13
- export declare class StringSimilarity {
14
- /**
15
- * Generate bigrams (character pairs) from a string
16
- */
17
- private getBigrams;
18
- /**
19
- * Calculate Dice's Coefficient similarity between two strings (0-1 scale)
20
- */
21
- calculateSimilarity(str1: string, str2: string): number;
22
- /**
23
- * Find best matching string and ratings for all candidates
24
- */
25
- findBestMatch(target: string, candidates: string[]): BestMatchResult;
26
- }
@@ -1,67 +0,0 @@
1
- import { custom } from '../flags/custom.js';
2
- import { optionFlag } from '../flags/option.js';
3
- export declare const Args: {
4
- string: {
5
- (): import('../index.js').FlagProps<string> & import('../index.js').CustomOptions & {
6
- parse(input: any, opts: import('../index.js').ParameterOpts): string;
7
- };
8
- <const U extends import('../index.js').FlagProps<string> & Partial<import('../index.js').CustomOptions>>(overrides: U & Record<Exclude<keyof U, string>, never>): import('../index.js').FlagProps<string> & import('../index.js').CustomOptions & U & {
9
- parse(input: any, opts: import('../index.js').ParameterOpts): string;
10
- };
11
- };
12
- number: {
13
- (): import('../index.js').FlagProps<number> & {
14
- min?: number;
15
- max?: number;
16
- } & {
17
- parse(input: any, opts: import('../index.js').ParameterOpts): number;
18
- };
19
- <const U extends import('../index.js').FlagProps<number> & Partial<{
20
- min?: number;
21
- max?: number;
22
- }>>(overrides: U & Record<Exclude<keyof U, keyof import('../index.js').FlagProps<T> | "min" | "max">, never>): import('../index.js').FlagProps<number> & {
23
- min?: number;
24
- max?: number;
25
- } & U & {
26
- parse(input: any, opts: import('../index.js').ParameterOpts): number;
27
- };
28
- };
29
- option: typeof optionFlag;
30
- file: {
31
- (): import('../index.js').FlagProps<string> & {
32
- exists?: boolean;
33
- } & {
34
- parse(input: any, opts: import('../index.js').ParameterOpts): string;
35
- };
36
- <const U extends import('../index.js').FlagProps<string> & Partial<{
37
- exists?: boolean;
38
- }>>(overrides: U & Record<Exclude<keyof U, keyof import('../index.js').FlagProps<T> | "exists">, never>): import('../index.js').FlagProps<string> & {
39
- exists?: boolean;
40
- } & U & {
41
- parse(input: any, opts: import('../index.js').ParameterOpts): string;
42
- };
43
- };
44
- directory: {
45
- (): import('../index.js').FlagProps<string> & {
46
- exists?: boolean;
47
- } & {
48
- parse(input: any, opts: import('../index.js').ParameterOpts): string;
49
- };
50
- <const U extends import('../index.js').FlagProps<string> & Partial<{
51
- exists?: boolean;
52
- }>>(overrides: U & Record<Exclude<keyof U, keyof import('../index.js').FlagProps<T> | "exists">, never>): import('../index.js').FlagProps<string> & {
53
- exists?: boolean;
54
- } & U & {
55
- parse(input: any, opts: import('../index.js').ParameterOpts): string;
56
- };
57
- };
58
- url: {
59
- (): import('../index.js').FlagProps<URL> & import('../index.js').CustomOptions & {
60
- parse(input: any, opts: import('../index.js').ParameterOpts): URL;
61
- };
62
- <const U extends import('../index.js').FlagProps<URL> & Partial<import('../index.js').CustomOptions>>(overrides: U & Record<Exclude<keyof U, string>, never>): import('../index.js').FlagProps<URL> & import('../index.js').CustomOptions & U & {
63
- parse(input: any, opts: import('../index.js').ParameterOpts): URL;
64
- };
65
- };
66
- custom: typeof custom;
67
- };
@@ -1,5 +0,0 @@
1
- import { Logger } from '../Logger.js';
2
- export declare abstract class BobError extends Error {
3
- $type: "BobError";
4
- abstract pretty(logger: Logger): void;
5
- }
@@ -1,7 +0,0 @@
1
- import { Logger } from '../Logger.js';
2
- import { BobError } from './BobError.js';
3
- export declare class CommandNotFoundError extends BobError {
4
- readonly command: string;
5
- constructor(command: string);
6
- pretty(logger: Logger): void;
7
- }
@@ -1,7 +0,0 @@
1
- import { Logger } from '../Logger.js';
2
- import { BobError } from './BobError.js';
3
- export declare class MissingRequiredArgumentValue extends BobError {
4
- readonly argument: string;
5
- constructor(argument: string);
6
- pretty(logger: Logger): void;
7
- }
@@ -1,7 +0,0 @@
1
- import { Logger } from '../Logger.js';
2
- import { BobError } from './BobError.js';
3
- export declare class MissingRequiredFlagValue extends BobError {
4
- readonly flag: string;
5
- constructor(flag: string);
6
- pretty(logger: Logger): void;
7
- }
@@ -1,8 +0,0 @@
1
- import { Logger } from '../Logger.js';
2
- import { BobError } from './BobError.js';
3
- export declare class TooManyArguments extends BobError {
4
- readonly expected: number;
5
- readonly received: number;
6
- constructor(expected: number, received: number);
7
- pretty(logger: Logger): void;
8
- }
@@ -1,3 +0,0 @@
1
- export declare class ValidationError extends Error {
2
- constructor(message: string);
3
- }
@@ -1,9 +0,0 @@
1
- import { ParameterOpts } from '../lib/types.js';
2
- export declare const booleanFlag: {
3
- (): import('../lib/types.js').FlagProps<boolean> & import('../lib/types.js').CustomOptions & {
4
- parse(input: any, opts: ParameterOpts): boolean;
5
- };
6
- <const U extends import('../lib/types.js').FlagProps<boolean> & Partial<import('../lib/types.js').CustomOptions>>(overrides: U & Record<Exclude<keyof U, string>, never>): import('../lib/types.js').FlagProps<boolean> & import('../lib/types.js').CustomOptions & U & {
7
- parse(input: any, opts: ParameterOpts): boolean;
8
- };
9
- };
@@ -1,9 +0,0 @@
1
- import { CustomOptions, FlagProps, ParameterOpts } from '../lib/types.js';
2
- export declare function custom<T, P extends CustomOptions = CustomOptions>(defaults?: FlagProps<T> & Partial<P>): {
3
- (): FlagProps<T> & P & {
4
- parse(input: any, opts: ParameterOpts): T;
5
- };
6
- <const U extends FlagProps<T> & Partial<P>>(overrides: U & Record<Exclude<keyof U, keyof FlagProps<T> | keyof P>, never>): FlagProps<T> & P & U & {
7
- parse(input: any, opts: ParameterOpts): T;
8
- };
9
- };
@@ -1,14 +0,0 @@
1
- export declare const directoryFlag: {
2
- (): import('../index.js').FlagProps<string> & {
3
- exists?: boolean;
4
- } & {
5
- parse(input: any, opts: import('../index.js').ParameterOpts): string;
6
- };
7
- <const U extends import('../index.js').FlagProps<string> & Partial<{
8
- exists?: boolean;
9
- }>>(overrides: U & Record<Exclude<keyof U, keyof import('../index.js').FlagProps<T> | "exists">, never>): import('../index.js').FlagProps<string> & {
10
- exists?: boolean;
11
- } & U & {
12
- parse(input: any, opts: import('../index.js').ParameterOpts): string;
13
- };
14
- };
@@ -1,14 +0,0 @@
1
- export declare const fileFlag: {
2
- (): import('../index.js').FlagProps<string> & {
3
- exists?: boolean;
4
- } & {
5
- parse(input: any, opts: import('../index.js').ParameterOpts): string;
6
- };
7
- <const U extends import('../index.js').FlagProps<string> & Partial<{
8
- exists?: boolean;
9
- }>>(overrides: U & Record<Exclude<keyof U, keyof import('../index.js').FlagProps<T> | "exists">, never>): import('../index.js').FlagProps<string> & {
10
- exists?: boolean;
11
- } & U & {
12
- parse(input: any, opts: import('../index.js').ParameterOpts): string;
13
- };
14
- };
@@ -1,3 +0,0 @@
1
- import { FlagDefinition } from '../lib/types.js';
2
- export declare function formatPromptMessage(name: string, definition: FlagDefinition): string;
3
- export declare function normalizeAliases(alias: string | readonly string[] | undefined): readonly string[];