bob-core 2.0.0-beta.8 → 2.0.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 (56) hide show
  1. package/README.md +338 -173
  2. package/dist/cjs/package-Blqq-jZJ.cjs +1 -0
  3. package/dist/cjs/src/Cli.d.ts +10 -11
  4. package/dist/cjs/src/Command.d.ts +13 -18
  5. package/dist/cjs/src/CommandIO.d.ts +5 -2
  6. package/dist/cjs/src/CommandParser.d.ts +13 -5
  7. package/dist/cjs/src/CommandRegistry.d.ts +13 -6
  8. package/dist/cjs/src/CommandSignatureParser.d.ts +5 -4
  9. package/dist/cjs/src/CommandWithSignature.d.ts +3 -3
  10. package/dist/cjs/src/ExceptionHandler.d.ts +1 -1
  11. package/dist/cjs/src/Logger.d.ts +1 -1
  12. package/dist/cjs/src/StringSimilarity.d.ts +26 -0
  13. package/dist/cjs/src/commands/HelpCommand.d.ts +1 -1
  14. package/dist/cjs/src/contracts/CommandOption.d.ts +3 -3
  15. package/dist/cjs/src/errors/BadCommandOption.d.ts +2 -1
  16. package/dist/cjs/src/errors/BadCommandParameter.d.ts +2 -1
  17. package/dist/cjs/src/errors/CommandNotFoundError.d.ts +2 -1
  18. package/dist/cjs/src/errors/InvalidOption.d.ts +2 -1
  19. package/dist/cjs/src/errors/MissingRequiredArgumentValue.d.ts +2 -1
  20. package/dist/cjs/src/errors/MissingRequiredOptionValue.d.ts +2 -1
  21. package/dist/cjs/src/index.d.ts +1 -0
  22. package/dist/cjs/src/index.js +17 -0
  23. package/dist/cjs/src/lib/types.d.ts +4 -2
  24. package/dist/cjs/src/options/HelpOption.d.ts +1 -1
  25. package/dist/esm/package-DbMvpGfM.js +33 -0
  26. package/dist/esm/src/Cli.d.ts +10 -11
  27. package/dist/esm/src/Command.d.ts +13 -18
  28. package/dist/esm/src/CommandIO.d.ts +5 -2
  29. package/dist/esm/src/CommandParser.d.ts +13 -5
  30. package/dist/esm/src/CommandRegistry.d.ts +13 -6
  31. package/dist/esm/src/CommandSignatureParser.d.ts +5 -4
  32. package/dist/esm/src/CommandWithSignature.d.ts +3 -3
  33. package/dist/esm/src/ExceptionHandler.d.ts +1 -1
  34. package/dist/esm/src/Logger.d.ts +1 -1
  35. package/dist/esm/src/StringSimilarity.d.ts +26 -0
  36. package/dist/esm/src/commands/HelpCommand.d.ts +1 -1
  37. package/dist/esm/src/contracts/CommandOption.d.ts +3 -3
  38. package/dist/esm/src/errors/BadCommandOption.d.ts +2 -1
  39. package/dist/esm/src/errors/BadCommandParameter.d.ts +2 -1
  40. package/dist/esm/src/errors/CommandNotFoundError.d.ts +2 -1
  41. package/dist/esm/src/errors/InvalidOption.d.ts +2 -1
  42. package/dist/esm/src/errors/MissingRequiredArgumentValue.d.ts +2 -1
  43. package/dist/esm/src/errors/MissingRequiredOptionValue.d.ts +2 -1
  44. package/dist/esm/src/index.d.ts +1 -0
  45. package/dist/esm/src/index.js +1029 -0
  46. package/dist/esm/src/lib/types.d.ts +4 -2
  47. package/dist/esm/src/options/HelpOption.d.ts +1 -1
  48. package/package.json +27 -20
  49. package/dist/cjs/index.d.ts +0 -2
  50. package/dist/cjs/index.js +0 -9
  51. package/dist/cjs/package-BaL-l6OV.cjs +0 -1
  52. package/dist/cjs/src/testFixtures.d.ts +0 -11
  53. package/dist/esm/index.d.ts +0 -2
  54. package/dist/esm/index.js +0 -971
  55. package/dist/esm/package-ODN3iB6L.js +0 -31
  56. package/dist/esm/src/testFixtures.d.ts +0 -11
package/README.md CHANGED
@@ -1,275 +1,440 @@
1
- # BOB Core - Bash Operation Buddy Core
1
+ <div align="center">
2
2
 
3
- ## Introduction
3
+ ```
4
+ ____ ____ ____
5
+ | __ ) / __ \| __ )
6
+ | _ \| | | | _ \
7
+ | |_) | | | | |_) |
8
+ |____/ \____/|____/
9
+ ```
10
+
11
+ # BOB Core
12
+
13
+ **Your Bash Operation Buddy** 💪
14
+
15
+ *Build powerful TypeScript CLIs with type-safe commands and beautiful interactive prompts*
16
+
17
+ [![npm version](https://img.shields.io/npm/v/bob-core.svg)](https://www.npmjs.com/package/bob-core)
18
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
19
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue)](https://www.typescriptlang.org/)
4
20
 
5
- BOB (Bash Operation Buddy) Core is a library that provides a set of functions to create your own CLI in TypeScript easily.
21
+ [Features](#features) [Installation](#installation) [Quick Start](#quick-start) [Documentation](#documentation) [Examples](#examples)
6
22
 
7
- ## Usage
23
+ </div>
24
+
25
+ ---
26
+
27
+ ## Features
28
+
29
+ ✨ **Type-Safe Commands** - Full TypeScript support with type inference for arguments and options
30
+ 🎯 **Declarative API** - Define commands with simple schemas or string signatures
31
+ 💬 **Interactive Prompts** - Built-in support for confirmations, selections, inputs, and more
32
+ 🎨 **Beautiful Help** - Automatically generated, well-formatted help documentation
33
+ 🔍 **Smart Suggestions** - Fuzzy matching suggests similar commands when you make typos
34
+ 📦 **Zero Config** - Works out of the box with sensible defaults
35
+ 🚀 **Dual Module Support** - Both CommonJS and ESM supported
36
+ ⚡️ **Fast & Lightweight** - Minimal dependencies, maximum performance
37
+
38
+ ---
39
+
40
+ ## Installation
8
41
 
9
42
  ```bash
10
43
  npm install bob-core
11
44
  ```
12
45
 
13
- Initialize the CLI:
46
+ ```bash
47
+ yarn add bob-core
48
+ ```
49
+
50
+ ```bash
51
+ pnpm add bob-core
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Quick Start
57
+
58
+ ### Create your CLI
14
59
 
15
60
  ```typescript
16
- import { CLI } from 'bob-core';
61
+ // cli.ts
62
+ import { Cli } from 'bob-core';
17
63
 
18
- const cli = new CLI();
64
+ const cli = new Cli({
65
+ name: 'my-cli',
66
+ version: '1.0.0'
67
+ });
19
68
 
20
69
  await cli.withCommands('./commands');
21
70
 
22
- cli.run('commandName', 'arg1', 'arg2', 'arg3');
71
+ const exitCode = await cli.runCommand(process.argv[2], ...process.argv.slice(3));
72
+ process.exit(exitCode);
23
73
  ```
24
74
 
25
- Create a command in the `commands` folder:
75
+ ### Create a Command
26
76
 
27
- ```typescript
28
- import { LegacyCommand } from 'bob-core';
29
-
30
- export default class MyCommand extends LegacyCommand {
31
- public name = 'my-command {arg1} {--option1}';
32
- public description = 'This is my command';
33
-
34
- /**
35
- * Define the arguments and options help
36
- *
37
- * Optional
38
- */
39
- helpDefinition = {
40
- arg1: 'This is the first argument',
41
- '--option1': 'This is the first option'
42
- }
77
+ **Modern Schema-Based (Recommended):**
43
78
 
44
- /**
45
- * Provide examples of how to use the command
46
- *
47
- * Optional
48
- */
49
- commandsExamples = [
50
- {
51
- command: 'my-command value1 --option1',
52
- description: 'This is an example'
53
- }
54
- ]
55
-
56
- public async handle() {
57
- console.log('Hello World');
58
- console.log('Arguments:', this.argument('arg1'));
59
- console.log('Options:', this.option('option1'));
79
+ ```typescript
80
+ // commands/greet.ts
81
+ import { Command } from 'bob-core';
82
+
83
+ export default new Command('greet', {
84
+ description: 'Greet a user',
85
+ arguments: {
86
+ name: 'string'
87
+ },
88
+ options: {
89
+ enthusiastic: {
90
+ type: 'boolean',
91
+ alias: ['e'],
92
+ default: false,
93
+ description: 'Add enthusiasm!'
94
+ }
60
95
  }
61
- }
96
+ }).handler((ctx, { arguments: args, options }) => {
97
+ const greeting = `Hello, ${args.name}${options.enthusiastic ? '!' : '.'}`;
98
+ console.log(greeting);
99
+ });
62
100
  ```
63
101
 
64
- ## Cli Help
102
+ **Modern Class-Based:**
65
103
 
66
- The CLI provides a help command that displays all available commands and their descriptions.
104
+ ```typescript
105
+ // commands/greet.ts
106
+ import { Command, CommandHandlerOptions, OptionsSchema } from 'bob-core';
107
+
108
+ const GreetOptions = {
109
+ enthusiastic: {
110
+ type: 'boolean',
111
+ alias: ['e'],
112
+ default: false,
113
+ description: 'Add enthusiasm!'
114
+ }
115
+ } satisfies OptionsSchema;
116
+ type GreetOptions = typeof GreetOptions;
117
+
118
+ const GreetArguments = {
119
+ name: 'string'
120
+ } satisfies OptionsSchema;
121
+ type GreetArguments = typeof GreetArguments;
122
+
123
+ export default class GreetCommand extends Command<any, GreetOptions, GreetArguments> {
124
+ constructor() {
125
+ super('greet', {
126
+ description: 'Greet a user',
127
+ options: GreetOptions,
128
+ arguments: GreetArguments
129
+ });
130
+ }
67
131
 
68
- ```bash
69
- node cli.js help
132
+ handle(ctx: any, opts: CommandHandlerOptions<GreetOptions, GreetArguments>) {
133
+ const greeting = `Hello, ${opts.arguments.name}${opts.options.enthusiastic ? '!' : '.'}`;
134
+ console.log(greeting);
135
+ }
136
+ }
70
137
  ```
71
138
 
72
- ## Commands
73
-
74
- ```bash
75
- Bob CLI x.x.x 💪
139
+ **Signature-Based:**
76
140
 
77
- Usage:
78
- command [options] [arguments]
141
+ ```typescript
142
+ // commands/greet.ts
143
+ import { CommandWithSignature } from 'bob-core';
79
144
 
80
- Available commands:
145
+ export default class GreetCommand extends CommandWithSignature {
146
+ signature = 'greet {name} {--enthusiastic|-e}';
147
+ description = 'Greet a user';
81
148
 
82
- help Show help
83
- test test description
84
- sub:
85
- sub sub command description
86
- sub:sub sub:sub command description
149
+ protected async handle() {
150
+ const name = this.argument<string>('name');
151
+ const enthusiastic = this.option<boolean>('enthusiastic');
87
152
 
153
+ const greeting = `Hello, ${name}${enthusiastic ? '!' : '.'}`;
154
+ console.log(greeting);
155
+ }
156
+ }
88
157
  ```
89
158
 
90
- ## LegacyCommand help
91
-
92
- You can also display the help of a specific command.
159
+ ### Run It
93
160
 
94
161
  ```bash
95
- node cli.js test -h
96
- ```
162
+ $ node cli.js greet John
163
+ Hello, John.
97
164
 
98
- ```bash
165
+ $ node cli.js greet Jane --enthusiastic
166
+ Hello, Jane!
167
+
168
+ $ node cli.js help greet
99
169
  Description:
100
- test description
170
+ Greet a user
101
171
 
102
172
  Usage:
103
- test <user> [options]
173
+ greet <name> [options]
104
174
 
105
175
  Arguments:
106
- user user description
107
- test test description [default: null]
108
- test2 [default: []] (variadic)
176
+ name (string)
109
177
 
110
178
  Options:
111
- --option, -o, -b option description (boolean) [default: false]
112
- --flag flag description (string) [default: null]
113
- --arr arr description (array) [default: null]
114
- --flag2 flag2 description (string) [default: 2]
115
- --help, -h Display help for the given command. When no command is given display help for the list command (boolean)
179
+ --enthusiastic, -e Add enthusiasm! (boolean) [default: false]
180
+ --help, -h Display help for the given command
181
+ ```
116
182
 
117
- Examples:
118
- Example description 1
183
+ ---
119
184
 
120
- node cli.js test yayo --option
185
+ ## Interactive Prompts
121
186
 
122
- Example description 2
187
+ Build beautiful interactive CLIs with built-in prompts:
123
188
 
124
- node cli.js test anothervalue --flag=2
125
- ```
189
+ ```typescript
190
+ import { Command, CommandHandlerOptions, OptionsSchema } from 'bob-core';
191
+
192
+ export default class SetupCommand extends Command<any, OptionsSchema, OptionsSchema> {
193
+ constructor() {
194
+ super('setup', {
195
+ description: 'Interactive project setup'
196
+ });
197
+ }
126
198
 
127
- Depending on the command, the help will display the command signature, description, arguments, options and examples.
199
+ async handle(ctx: any, opts: CommandHandlerOptions<OptionsSchema, OptionsSchema>) {
200
+ // Text input
201
+ const name = await this.io.askForInput('Project name:');
202
+
203
+ // Confirmation
204
+ const useTypeScript = await this.io.askForConfirmation('Use TypeScript?', true);
205
+
206
+ // Selection
207
+ const framework = await this.io.askForSelect('Framework:', [
208
+ { title: 'React', value: 'react' },
209
+ { title: 'Vue', value: 'vue' },
210
+ { title: 'Svelte', value: 'svelte' }
211
+ ]);
212
+
213
+ // Multi-select
214
+ const features = await this.io.askForSelect(
215
+ 'Features:',
216
+ ['ESLint', 'Prettier', 'Testing'],
217
+ { type: 'multiselect' }
218
+ );
219
+
220
+ // Spinner/loader
221
+ using loader = this.io.newLoader('Creating project...');
222
+ await createProject({ name, framework, features });
223
+ loader.stop();
224
+
225
+ this.io.info('✅ Project created!');
226
+ }
227
+ }
228
+ ```
128
229
 
230
+ ---
129
231
 
130
- ## Commands signature
232
+ ## Context Injection
131
233
 
132
- The command signature is a string that defines the command name, arguments and options.
234
+ Pass shared dependencies and configuration to your commands:
133
235
 
134
- Example:
135
236
  ```typescript
136
- signature = 'my-command {arg1} {arg2} {arg3} {--option1} {--option2}';
137
- ```
237
+ interface AppContext {
238
+ config: Config;
239
+ database: Database;
240
+ logger: Logger;
241
+ }
138
242
 
139
- ### Arguments
243
+ const context: AppContext = {
244
+ config: loadConfig(),
245
+ database: new Database(),
246
+ logger: new Logger()
247
+ };
248
+
249
+ const cli = new Cli<AppContext>({
250
+ ctx: context,
251
+ name: 'my-app',
252
+ version: '1.0.0'
253
+ });
254
+
255
+ // Access context in commands
256
+ export default new Command<AppContext>('users:list', {
257
+ description: 'List users'
258
+ }).handler(async (ctx) => {
259
+ const users = await ctx.database.getUsers();
260
+ users.forEach(user => console.log(user.name));
261
+ });
262
+ ```
140
263
 
141
- All user supplied arguments and options are wrapped in curly braces.
142
- In the following example, the command defines three **required** arguments `arg1`, `arg2` and `arg3`.
264
+ ---
143
265
 
144
- ```typescript
145
- signature = 'my-command {arg1} {arg2} {arg3}';
146
- ```
266
+ ## Documentation
147
267
 
148
- You may want to make an argument optional by adding a `?` after the argument name or by providing a default value with `=`.
268
+ 📚 **[Getting Started](./docs/getting-started.md)** - Installation and first CLI
269
+ 🔨 **[Creating Commands](./docs/creating-commands.md)** - Schema-based and signature-based approaches
270
+ ⚙️ **[Arguments & Options](./docs/arguments-and-options.md)** - Type-safe parameters
271
+ 💬 **[Interactive Prompts](./docs/interactive-prompts.md)** - Build interactive CLIs
272
+ 🚀 **[Advanced Topics](./docs/advanced.md)** - Context, resolvers, error handling
273
+ ❓ **[Help System](./docs/help-system.md)** - Customize help output
274
+ 📖 **[API Reference](./docs/api-reference.md)** - Complete API documentation
275
+ 💡 **[Examples](./docs/examples.md)** - Real-world examples
149
276
 
150
- ```typescript
151
- signature = 'my-command {arg1} {arg2?} {arg3=defaultValue}';
277
+ ---
152
278
 
153
- handle() {
154
- this.argument('arg1'); // 'value' or throw an error if not provided
155
- this.argument('arg2'); // 'value' or null if not provided
156
- this.argument('arg3'); // 'value' or 'defaultValue' if not provided
157
- }
158
- ```
279
+ ## Examples
159
280
 
160
- You can also define a variadic argument by adding `*` after the argument name.
161
- Variadic arguments are stored in an array.
281
+ ### Type-Safe Arguments
162
282
 
163
283
  ```typescript
164
- signature = 'my-command {arg1} {arg2*}';
165
-
166
- handle() {
167
- this.argument('arg1'); // 'value1'
168
- this.argument('arg2'); // ['value2', 'value3']
284
+ export default new Command('deploy', {
285
+ arguments: {
286
+ environment: 'string', // Required
287
+ region: { // Optional with default
288
+ type: 'string',
289
+ default: 'us-east-1',
290
+ required: false
169
291
  }
292
+ }
293
+ }).handler((ctx, { arguments: args }) => {
294
+ // args.environment is string
295
+ // args.region is string | null
296
+ });
170
297
  ```
171
298
 
172
- Variadic arguments can also be optional.
299
+ ### Variadic Arguments
173
300
 
174
301
  ```typescript
175
- signature = 'my-command {arg1} {arg2*?}';
302
+ export default new Command('delete', {
303
+ arguments: {
304
+ files: ['string'] // Array of strings
305
+ }
306
+ }).handler((ctx, { arguments: args }) => {
307
+ // args.files is string[]
308
+ args.files.forEach(file => deleteFile(file));
309
+ });
176
310
  ```
177
311
 
178
- ### Options
179
-
180
- Options are defined by `{--optionName}`.
312
+ ### Options with Aliases
181
313
 
182
314
  ```typescript
183
- signature = 'my-command {--option1} {--option2} {--option3}';
184
- ```
315
+ export default new Command('serve', {
316
+ options: {
317
+ port: {
318
+ type: 'number',
319
+ alias: ['p'],
320
+ default: 3000
321
+ },
322
+ verbose: {
323
+ type: 'boolean',
324
+ alias: ['v', 'V'],
325
+ default: false
326
+ }
327
+ }
328
+ });
185
329
 
186
- By default options are boolean with a default value of `false`.
187
- You can also change the option type to string by adding `=` to the option definition.
188
- You can also provide a default value by adding `=value`.
330
+ // Usage: serve --port=8080 -v
331
+ // Usage: serve -p 8080 --verbose
332
+ ```
189
333
 
190
- If the value is 'true' or 'false', the option will be converted to a boolean.
334
+ ### Pre-Handlers for Validation
191
335
 
192
336
  ```typescript
193
- signature = 'my-command {--option1} {--option2=true} {--option3=} {--option4=defaultValue} {--option5=}';
194
-
195
- handle() {
196
- this.option('option1'); // by default `false` and can be set to `true` by the user
197
- this.option('option2'); // by default `true` and can be set to `false` by the user
198
- this.option('option3'); // by default `null` and can be set to "value" by the user
199
- this.option('option4'); // by default "defaultValue" and can be set to "value" by the user
337
+ export default new Command('deploy')
338
+ .preHandler(async (ctx) => {
339
+ if (!ctx.isAuthenticated) {
340
+ console.error('Not authenticated');
341
+ return 1; // Stop execution
200
342
  }
343
+ })
344
+ .handler(async (ctx) => {
345
+ // Only runs if authenticated
346
+ });
201
347
  ```
202
348
 
203
- You can also define a variadic option by adding `*` as option value. (e.g. `{--option2=*}`)
204
- Variadic options are stored in an array.
349
+ ### Command Groups
205
350
 
206
351
  ```typescript
207
- signature = 'my-command {--option1} {--option2=*}';
208
-
209
- handle() {
210
- this.option('option1'); // 'value1'
211
- this.option('option2'); // ['value2', 'value3'] // or [] if not provided
212
- }
352
+ // commands/db/migrate.ts
353
+ export default new Command('db:migrate', {
354
+ description: 'Run migrations',
355
+ group: 'Database'
356
+ });
357
+
358
+ // commands/db/seed.ts
359
+ export default new Command('db:seed', {
360
+ description: 'Seed database',
361
+ group: 'Database'
362
+ });
363
+
364
+ // Displayed as:
365
+ // Database:
366
+ // db:migrate Run migrations
367
+ // db:seed Seed database
213
368
  ```
214
369
 
215
- ## Commands I/O
370
+ ---
216
371
 
217
- ### Arguments
372
+ ## Why BOB Core?
218
373
 
219
- ```typescript
220
- this.argument('arg1');
221
- ```
374
+ BOB Core makes CLI development in TypeScript a breeze:
222
375
 
223
- You can also provide a default value if the argument is optional.
376
+ - **No Boilerplate** - Define commands declaratively, not imperatively
377
+ - **Type Safety** - Catch errors at compile time, not runtime
378
+ - **Great DX** - Intelligent auto-complete, clear error messages
379
+ - **User Friendly** - Beautiful help, smart suggestions, interactive prompts
380
+ - **Flexible** - Multiple command styles, extend anything
381
+ - **Well Tested** - Comprehensive test suite with Vitest
224
382
 
225
- ```typescript
226
- this.argument('arg1', 'defaultValue');
227
- ```
383
+ ---
228
384
 
229
- If you always need a boolean value, you can use the `argumentBoolean` method.
385
+ ## Supported Types
230
386
 
231
- ```typescript
232
- this.argumentBoolean('arg1');
233
- ```
387
+ | Type | Description | Example |
388
+ |------|-------------|---------|
389
+ | `'string'` | Text value | `'hello'` |
390
+ | `'number'` | Numeric value | `42` |
391
+ | `'boolean'` | True/false | `true` |
392
+ | `['string']` | String array | `['a', 'b']` |
393
+ | `['number']` | Number array | `[1, 2, 3]` |
234
394
 
235
- If you always need a number value, you can use the `argumentNumber` method.
395
+ **Note:** The `secret` flag is not a type but a property of OptionDefinition.
236
396
 
237
- ```typescript
238
- this.argumentNumber('arg1');
239
- ```
397
+ ### Secret/Masked Input
240
398
 
241
- If you always need a array value, you can use the `argumentArray` method.
399
+ For sensitive input like passwords, use the `secret: true` flag in the option definition:
242
400
 
243
401
  ```typescript
244
- this.argumentArray('arg1');
402
+ options: {
403
+ password: {
404
+ type: 'string', // Type is still 'string'
405
+ secret: true, // Flag to mask input in interactive prompts
406
+ required: true,
407
+ description: 'User password'
408
+ }
409
+ }
245
410
  ```
246
411
 
247
- ### Options
412
+ The `secret` flag masks the input when prompting interactively, making it perfect for passwords and API keys.
248
413
 
249
- ```typescript
250
- this.option('option1');
251
- ```
414
+ ---
252
415
 
253
- You can also provide a default value if the option is optional.
416
+ ## Contributing
254
417
 
255
- ```typescript
256
- this.option('option1', 'defaultValue');
257
- ```
418
+ Contributions are welcome! Please feel free to submit a Pull Request.
258
419
 
259
- If you always need a boolean value, you can use the `optionBoolean` method.
420
+ 1. Fork the repository
421
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
422
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
423
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
424
+ 5. Open a Pull Request
260
425
 
261
- ```typescript
262
- this.optionBoolean('option1');
263
- ```
426
+ ---
264
427
 
265
- If you always need a number value, you can use the `optionNumber` method.
428
+ ## License
266
429
 
267
- ```typescript
268
- this.optionNumber('option1');
269
- ```
430
+ [ISC](LICENSE) © Léo Hubert
270
431
 
271
- If you always need a array value, you can use the `optionArray` method.
432
+ ---
272
433
 
273
- ```typescript
274
- this.optionArray('option1');
275
- ```
434
+ <div align="center">
435
+
436
+ **[⬆ back to top](#bob-core)**
437
+
438
+ Made with ❤️ by developers, for developers
439
+
440
+ </div>
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="bob-core",t="2.0.0",s="BOB Core",i="module",n="./dist/cjs/src/index.js",r="./dist/esm/src/index.js",c="./dist/esm/src/index.d.ts",o=["dist"],d={".":{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"}}},p={start:"node -r @swc-node/register debug/main.ts",build:"rimraf ./dist && vite build",typecheck:"tsc --noEmit",prepack:"npm run build",test:"vitest run",lint:"eslint .","lint:fix":"eslint . --fix"},l="Léo Hubert",m="ISC",a={"@eslint/js":"^9.37.0","@faker-js/faker":"^10.0.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/prompts":"^2.4.9","@types/string-similarity":"^4.0.2","@vitest/coverage-v8":"^3.2.4",eslint:"^9.37.0","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4",prettier:"^3.6.2",rimraf:"^6.0.1",tsx:"^4.20.6",typescript:"^5.9.3","typescript-eslint":"^8.46.0",vite:"^7.2.7","vite-plugin-dts":"^4.5.4",vitest:"^3.2.4"},u={chalk:"^4.1.2",minimist:"^1.2.8",prompts:"^2.4.2"},y={name:e,version:t,description:s,type:i,main:n,module:r,types:c,files:o,exports:d,scripts:p,author:l,license:m,devDependencies:a,dependencies:u};exports.author=l;exports.default=y;exports.dependencies=u;exports.description=s;exports.devDependencies=a;exports.exports=d;exports.files=o;exports.license=m;exports.main=n;exports.module=r;exports.name=e;exports.scripts=p;exports.type=i;exports.types=c;exports.version=t;
@@ -1,23 +1,22 @@
1
- import { CommandRegistry, CommandResolver, FileImporter } from './CommandRegistry.js';
2
- import { default as HelpCommand, HelpCommandOptions } from './commands/HelpCommand.js';
3
- import { ExceptionHandler } from './ExceptionHandler.js';
4
1
  import { Command } from './Command.js';
2
+ import { CommandRegistry, CommandRegistryOptions, CommandResolver, FileImporter } from './CommandRegistry.js';
3
+ import { ExceptionHandler } from './ExceptionHandler.js';
5
4
  import { Logger } from './Logger.js';
6
- export type CliOptions<C = any> = {
5
+ import { default as HelpCommand, HelpCommandOptions } from './commands/HelpCommand.js';
6
+ import { ContextDefinition, OptionsSchema } from './lib/types.js';
7
+ export type CliOptions<C extends ContextDefinition = ContextDefinition> = {
7
8
  ctx?: C;
8
9
  name?: string;
9
10
  version?: string;
10
11
  logger?: Logger;
11
12
  };
12
- export declare class Cli<C = any> {
13
+ export declare class Cli<C extends ContextDefinition = ContextDefinition> {
13
14
  private readonly ctx?;
14
15
  private readonly logger;
15
16
  readonly commandRegistry: CommandRegistry;
16
17
  private readonly exceptionHandler;
17
18
  private readonly helpCommand;
18
- protected newCommandRegistry(opts: {
19
- logger: Logger;
20
- }): CommandRegistry;
19
+ protected newCommandRegistry(opts: CommandRegistryOptions): CommandRegistry;
21
20
  protected newHelpCommand(opts: HelpCommandOptions): HelpCommand;
22
21
  protected newExceptionHandler(opts: {
23
22
  logger: Logger;
@@ -25,10 +24,10 @@ export declare class Cli<C = any> {
25
24
  constructor(opts?: CliOptions<C>);
26
25
  withCommandResolver(resolver: CommandResolver): this;
27
26
  withFileImporter(importer: FileImporter): this;
28
- withCommands(...commands: Array<Command<C, any, any> | {
27
+ withCommands(...commands: Array<Command<C, OptionsSchema, OptionsSchema> | {
29
28
  new (): Command<C>;
30
29
  } | string>): Promise<void>;
31
- runCommand(command: string | Command | undefined, ...args: any[]): Promise<number>;
30
+ runCommand(command: string | Command | undefined, ...args: string[]): Promise<number>;
32
31
  runHelpCommand(): Promise<number>;
33
- protected registerCommand(command: Command<C>): void;
32
+ protected registerCommand(command: Command<C, OptionsSchema, OptionsSchema>): void;
34
33
  }