@boneskull/bargs 3.2.0 → 3.4.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 (70) hide show
  1. package/README.md +125 -52
  2. package/dist/bargs.cjs +139 -21
  3. package/dist/bargs.cjs.map +1 -1
  4. package/dist/bargs.d.cts +51 -5
  5. package/dist/bargs.d.cts.map +1 -1
  6. package/dist/bargs.d.ts +51 -5
  7. package/dist/bargs.d.ts.map +1 -1
  8. package/dist/bargs.js +136 -20
  9. package/dist/bargs.js.map +1 -1
  10. package/dist/help.cjs +31 -2
  11. package/dist/help.cjs.map +1 -1
  12. package/dist/help.d.cts +4 -0
  13. package/dist/help.d.cts.map +1 -1
  14. package/dist/help.d.ts +4 -0
  15. package/dist/help.d.ts.map +1 -1
  16. package/dist/help.js +31 -2
  17. package/dist/help.js.map +1 -1
  18. package/dist/index.cjs +3 -3
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +4 -5
  21. package/dist/index.d.cts.map +1 -1
  22. package/dist/index.d.ts +4 -5
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +2 -3
  25. package/dist/index.js.map +1 -1
  26. package/dist/opt.cjs +38 -0
  27. package/dist/opt.cjs.map +1 -1
  28. package/dist/opt.d.cts +63 -0
  29. package/dist/opt.d.cts.map +1 -1
  30. package/dist/opt.d.ts +63 -0
  31. package/dist/opt.d.ts.map +1 -1
  32. package/dist/opt.js +38 -0
  33. package/dist/opt.js.map +1 -1
  34. package/dist/osc.cjs +12 -0
  35. package/dist/osc.cjs.map +1 -1
  36. package/dist/osc.d.cts +6 -0
  37. package/dist/osc.d.cts.map +1 -1
  38. package/dist/osc.d.ts +6 -0
  39. package/dist/osc.d.ts.map +1 -1
  40. package/dist/osc.js +12 -0
  41. package/dist/osc.js.map +1 -1
  42. package/dist/parser.cjs +48 -1
  43. package/dist/parser.cjs.map +1 -1
  44. package/dist/parser.d.cts +2 -0
  45. package/dist/parser.d.cts.map +1 -1
  46. package/dist/parser.d.ts +2 -0
  47. package/dist/parser.d.ts.map +1 -1
  48. package/dist/parser.js +48 -1
  49. package/dist/parser.js.map +1 -1
  50. package/dist/theme.cjs +8 -0
  51. package/dist/theme.cjs.map +1 -1
  52. package/dist/theme.d.cts +6 -0
  53. package/dist/theme.d.cts.map +1 -1
  54. package/dist/theme.d.ts +6 -0
  55. package/dist/theme.d.ts.map +1 -1
  56. package/dist/theme.js +8 -0
  57. package/dist/theme.js.map +1 -1
  58. package/dist/types.d.cts +50 -1
  59. package/dist/types.d.cts.map +1 -1
  60. package/dist/types.d.ts +50 -1
  61. package/dist/types.d.ts.map +1 -1
  62. package/dist/version.cjs +16 -0
  63. package/dist/version.cjs.map +1 -1
  64. package/dist/version.d.cts +4 -0
  65. package/dist/version.d.cts.map +1 -1
  66. package/dist/version.d.ts +4 -0
  67. package/dist/version.d.ts.map +1 -1
  68. package/dist/version.js +16 -0
  69. package/dist/version.js.map +1 -1
  70. package/package.json +3 -1
package/README.md CHANGED
@@ -27,8 +27,7 @@ A CLI with an optional command and a couple options:
27
27
  ```typescript
28
28
  import { bargs, opt, pos } from '@boneskull/bargs';
29
29
 
30
- await bargs
31
- .create('greet', { version: '1.0.0' })
30
+ await bargs('greet', { version: '1.0.0' })
32
31
  .globals(
33
32
  opt.options({
34
33
  name: opt.string({ default: 'world' }),
@@ -112,11 +111,10 @@ const parser = pos.positionals(pos.variadic('string', { name: 'text' }))(
112
111
  }),
113
112
  );
114
113
 
115
- const { values, positionals } = await bargs
116
- .create('echo', {
117
- description: 'Echo text to stdout',
118
- version: '1.0.0',
119
- })
114
+ const { values, positionals } = await bargs('echo', {
115
+ description: 'Echo text to stdout',
116
+ version: '1.0.0',
117
+ })
120
118
  .globals(parser)
121
119
  .parseAsync();
122
120
 
@@ -132,11 +130,10 @@ For a CLI with multiple subcommands:
132
130
  ```typescript
133
131
  import { bargs, merge, opt, pos } from '@boneskull/bargs';
134
132
 
135
- await bargs
136
- .create('tasks', {
137
- description: 'A task manager',
138
- version: '1.0.0',
139
- })
133
+ await bargs('tasks', {
134
+ description: 'A task manager',
135
+ version: '1.0.0',
136
+ })
140
137
  .globals(
141
138
  opt.options({
142
139
  verbose: opt.boolean({ aliases: ['v'], default: false }),
@@ -183,36 +180,36 @@ All tasks
183
180
 
184
181
  ### Nested Commands (Subcommands)
185
182
 
186
- Commands can be nested to arbitrary depth by passing a `CliBuilder` as the second argument to `.command()`:
183
+ Commands can be nested to arbitrary depth. Use the **factory pattern** for full type inference of parent globals:
187
184
 
188
185
  ```typescript
189
186
  import { bargs, opt, pos } from '@boneskull/bargs';
190
187
 
191
- // Define subcommands as a separate builder
192
- const remoteCommands = bargs
193
- .create('remote')
188
+ await bargs('git')
189
+ .globals(opt.options({ verbose: opt.boolean({ aliases: ['v'] }) }))
190
+ // Factory pattern: receives a builder with parent globals already typed
194
191
  .command(
195
- 'add',
196
- pos.positionals(
197
- pos.string({ name: 'name', required: true }),
198
- pos.string({ name: 'url', required: true }),
199
- ),
200
- ({ positionals, values }) => {
201
- const [name, url] = positionals;
202
- // Parent globals (verbose) are available here!
203
- if (values.verbose) console.log(`Adding ${name}: ${url}`);
204
- },
205
- 'Add a remote',
192
+ 'remote',
193
+ (remote) =>
194
+ remote
195
+ .command(
196
+ 'add',
197
+ pos.positionals(
198
+ pos.string({ name: 'name', required: true }),
199
+ pos.string({ name: 'url', required: true }),
200
+ ),
201
+ ({ positionals, values }) => {
202
+ const [name, url] = positionals;
203
+ // values.verbose is fully typed! (from parent globals)
204
+ if (values.verbose) console.log(`Adding ${name}: ${url}`);
205
+ },
206
+ 'Add a remote',
207
+ )
208
+ .command('remove' /* ... */)
209
+ .defaultCommand('add'),
210
+ 'Manage remotes',
206
211
  )
207
- .command('remove' /* ... */)
208
- .defaultCommand('add');
209
-
210
- // Nest under parent CLI
211
- await bargs
212
- .create('git')
213
- .globals(opt.options({ verbose: opt.boolean({ aliases: ['v'] }) }))
214
- .command('remote', remoteCommands, 'Manage remotes') // ← CliBuilder
215
- .command('commit', commitParser, commitHandler) // ← Regular command
212
+ .command('commit', commitParser, commitHandler) // Regular command
216
213
  .parseAsync();
217
214
  ```
218
215
 
@@ -223,11 +220,13 @@ Adding origin: https://github.com/...
223
220
  $ git remote remove origin
224
221
  ```
225
222
 
226
- Parent globals automatically flow to nested command handlers. You can nest as deep as you like—just nest `CliBuilder`s inside `CliBuilder`s. See `examples/nested-commands.ts` for a full example.
223
+ The factory function receives a `CliBuilder` that already has parent globals typed, so all nested command handlers get full type inference for merged `global + command` options.
224
+
225
+ You can also pass a pre-built `CliBuilder` directly (see [.command(name, cliBuilder)](#commandname-clibuilder-description)), but handlers won't have parent globals typed at compile time. See `examples/nested-commands.ts` for a full example.
227
226
 
228
227
  ## API
229
228
 
230
- ### bargs.create(name, options?)
229
+ ### bargs(name, options?)
231
230
 
232
231
  Create a CLI builder.
233
232
 
@@ -243,7 +242,7 @@ Create a CLI builder.
243
242
  Set global options and transforms that apply to all commands.
244
243
 
245
244
  ```typescript
246
- bargs.create('my-cli').globals(opt.options({ verbose: opt.boolean() }));
245
+ bargs('my-cli').globals(opt.options({ verbose: opt.boolean() }));
247
246
  // ...
248
247
  ```
249
248
 
@@ -265,12 +264,12 @@ Register a command. The handler receives merged global + command types.
265
264
 
266
265
  ### .command(name, cliBuilder, description?)
267
266
 
268
- Register a nested command group. The `cliBuilder` is another `CliBuilder` whose commands become subcommands. Parent globals are passed down to nested handlers.
267
+ Register a nested command group. The `cliBuilder` is another `CliBuilder` whose commands become subcommands. Parent globals are passed down to nested handlers at runtime, but **handlers won't have parent globals typed** at compile time.
269
268
 
270
269
  ```typescript
271
- const subCommands = bargs.create('sub').command('foo', ...).command('bar', ...);
270
+ const subCommands = bargs('sub').command('foo', ...).command('bar', ...);
272
271
 
273
- bargs.create('main')
272
+ bargs('main')
274
273
  .command('nested', subCommands, 'Nested commands') // nested group
275
274
  .parseAsync();
276
275
 
@@ -278,6 +277,26 @@ bargs.create('main')
278
277
  // $ main nested bar
279
278
  ```
280
279
 
280
+ ### .command(name, factory, description?)
281
+
282
+ Register a nested command group using a factory function. **This is the recommended form** because the factory receives a builder that already has parent globals typed, giving full type inference in nested handlers.
283
+
284
+ ```typescript
285
+ bargs('main')
286
+ .globals(opt.options({ verbose: opt.boolean() }))
287
+ .command(
288
+ 'nested',
289
+ (nested) =>
290
+ nested
291
+ .command('foo', fooParser, ({ values }) => {
292
+ // values.verbose is typed correctly!
293
+ })
294
+ .command('bar', barParser, barHandler),
295
+ 'Nested commands',
296
+ )
297
+ .parseAsync();
298
+ ```
299
+
281
300
  ### .defaultCommand(name)
282
301
 
283
302
  > Or `.defaultCommand(parser, handler)`
@@ -304,11 +323,11 @@ Parse arguments and execute handlers.
304
323
 
305
324
  ```typescript
306
325
  // Async (supports async transforms/handlers)
307
- const result = await bargs.create('my-cli').globals(...).parseAsync();
326
+ const result = await bargs('my-cli').globals(...).parseAsync();
308
327
  console.log(result.values, result.positionals, result.command);
309
328
 
310
329
  // Sync (no async transforms/handlers)
311
- const result = bargs.create('my-cli').globals(...).parse();
330
+ const result = bargs('my-cli').globals(...).parse();
312
331
  ```
313
332
 
314
333
  ## Option Helpers
@@ -336,6 +355,32 @@ opt.count(); // -vvv → 3
336
355
  | `hidden` | `boolean` | Hide from `--help` output |
337
356
  | `required` | `boolean` | Mark as required (makes the option non-nullable) |
338
357
 
358
+ ### Boolean Negation (`--no-<flag>`)
359
+
360
+ All boolean options automatically support a negated form `--no-<flag>` to explicitly set the option to `false`:
361
+
362
+ ```shell
363
+ $ my-cli --verbose # verbose: true
364
+ $ my-cli --no-verbose # verbose: false
365
+ $ my-cli # verbose: undefined (or default)
366
+ ```
367
+
368
+ If both `--flag` and `--no-flag` are specified, bargs throws an error:
369
+
370
+ ```shell
371
+ $ my-cli --verbose --no-verbose
372
+ Error: Conflicting options: --verbose and --no-verbose cannot both be specified
373
+ ```
374
+
375
+ In help output, booleans with `default: true` display as `--no-<flag>` (since that's how users would turn them off):
376
+
377
+ ```typescript
378
+ opt.options({
379
+ colors: opt.boolean({ default: true, description: 'Use colors' }),
380
+ });
381
+ // Help output shows: --no-colors Use colors [boolean] default: true
382
+ ```
383
+
339
384
  ### `opt.options(schema)`
340
385
 
341
386
  Create a parser from an options schema:
@@ -443,8 +488,7 @@ const globals = map(
443
488
  }),
444
489
  );
445
490
 
446
- await bargs
447
- .create('my-cli')
491
+ await bargs('my-cli')
448
492
  .globals(globals)
449
493
  .command(
450
494
  'info',
@@ -480,18 +524,47 @@ const globals = map(
480
524
  );
481
525
  ```
482
526
 
527
+ ### CamelCase Option Keys
528
+
529
+ If you prefer camelCase property names instead of kebab-case, use the `camelCaseValues` transform:
530
+
531
+ ```typescript
532
+ import { bargs, map, opt, camelCaseValues } from '@boneskull/bargs';
533
+
534
+ const { values } = await bargs('my-cli')
535
+ .globals(
536
+ map(
537
+ opt.options({
538
+ 'output-dir': opt.string({ default: '/tmp' }),
539
+ 'dry-run': opt.boolean(),
540
+ }),
541
+ camelCaseValues,
542
+ ),
543
+ )
544
+ .parseAsync(['--output-dir', './dist', '--dry-run']);
545
+
546
+ console.log(values.outputDir); // './dist'
547
+ console.log(values.dryRun); // true
548
+ ```
549
+
550
+ The `camelCaseValues` transform:
551
+
552
+ - Converts all kebab-case keys to camelCase (`output-dir` → `outputDir`)
553
+ - Preserves keys that are already camelCase or have no hyphens
554
+ - Is fully type-safe—TypeScript knows the transformed key names
555
+
483
556
  ## Epilog
484
557
 
485
558
  By default, **bargs** displays your package's homepage and repository URLs (from `package.json`) at the end of help output. URLs become clickable hyperlinks in supported terminals.
486
559
 
487
560
  ```typescript
488
561
  // Custom epilog
489
- bargs.create('my-cli', {
562
+ bargs('my-cli', {
490
563
  epilog: 'For more info, visit https://example.com',
491
564
  });
492
565
 
493
566
  // Disable epilog entirely
494
- bargs.create('my-cli', { epilog: false });
567
+ bargs('my-cli', { epilog: false });
495
568
  ```
496
569
 
497
570
  ## Theming
@@ -500,10 +573,10 @@ Customize help output colors with built-in themes or your own:
500
573
 
501
574
  ```typescript
502
575
  // Use a built-in theme: 'default', 'mono', 'ocean', 'warm'
503
- bargs.create('my-cli', { theme: 'ocean' });
576
+ bargs('my-cli', { theme: 'ocean' });
504
577
 
505
578
  // Disable colors entirely
506
- bargs.create('my-cli', { theme: 'mono' });
579
+ bargs('my-cli', { theme: 'mono' });
507
580
  ```
508
581
 
509
582
  The `ansi` export provides common ANSI escape codes for styled terminal output:
@@ -511,7 +584,7 @@ The `ansi` export provides common ANSI escape codes for styled terminal output:
511
584
  ```typescript
512
585
  import { ansi } from '@boneskull/bargs';
513
586
 
514
- bargs.create('my-cli', {
587
+ bargs('my-cli', {
515
588
  theme: {
516
589
  command: ansi.bold,
517
590
  flag: ansi.brightCyan,
@@ -557,7 +630,7 @@ import {
557
630
  } from '@boneskull/bargs';
558
631
 
559
632
  try {
560
- await bargs.create('my-cli').parseAsync();
633
+ await bargs('my-cli').parseAsync();
561
634
  } catch (error) {
562
635
  if (error instanceof ValidationError) {
563
636
  // Config validation failed (e.g., invalid schema)
package/dist/bargs.cjs CHANGED
@@ -2,13 +2,13 @@
2
2
  /**
3
3
  * Core bargs API using parser combinator pattern.
4
4
  *
5
- * Provides `bargs.create()` for building CLIs with a fluent API, plus
6
- * combinator functions like `pipe()`, `map()`, and `handle()`.
5
+ * Provides `bargs()` for building CLIs with a fluent API, plus combinator
6
+ * functions like `pipe()`, `map()`, and `handle()`.
7
7
  *
8
8
  * @packageDocumentation
9
9
  */
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.bargs = void 0;
11
+ exports.bargs = exports.camelCaseValues = void 0;
12
12
  exports.handle = handle;
13
13
  exports.map = map;
14
14
  exports.merge = merge;
@@ -53,27 +53,47 @@ function handle(parserOrFn, maybeFn) {
53
53
  };
54
54
  }
55
55
  function map(parserOrFn, maybeFn) {
56
+ // Helper to compose transforms (chains existing + new)
57
+ /**
58
+ * @function
59
+ */
60
+ const composeTransform = (parser, fn) => {
61
+ const existing = parser.__transform;
62
+ if (!existing) {
63
+ return fn;
64
+ }
65
+ // Chain: existing transform first, then new transform
66
+ return (r) => {
67
+ const r1 = existing(r);
68
+ if (r1 instanceof Promise) {
69
+ return r1.then(fn);
70
+ }
71
+ return fn(r1);
72
+ };
73
+ };
56
74
  // Direct form: map(parser, fn) returns Parser
57
75
  // Check for Parser first since CallableParser is also a function
58
76
  if (isParser(parserOrFn)) {
59
77
  const parser = parserOrFn;
60
78
  const fn = maybeFn;
79
+ const composedTransform = composeTransform(parser, fn);
61
80
  return {
62
81
  ...parser,
63
82
  __brand: 'Parser',
64
83
  __positionals: [],
65
- __transform: fn,
84
+ __transform: composedTransform,
66
85
  __values: {},
67
86
  };
68
87
  }
69
88
  // Curried form: map(fn) returns (parser) => Parser
70
89
  const fn = parserOrFn;
71
90
  return (parser) => {
91
+ const composedTransform = composeTransform(parser, fn);
72
92
  return {
73
93
  ...parser,
74
94
  __brand: 'Parser',
75
95
  __positionals: [],
76
- __transform: fn,
96
+ __transform: composedTransform,
77
97
  __values: {},
78
98
  };
79
99
  };
@@ -130,6 +150,43 @@ function merge(...parsers) {
130
150
  return result;
131
151
  }
132
152
  // ═══════════════════════════════════════════════════════════════════════════════
153
+ // CAMEL CASE HELPER
154
+ // ═══════════════════════════════════════════════════════════════════════════════
155
+ /**
156
+ * Convert kebab-case string to camelCase.
157
+ *
158
+ * @function
159
+ */
160
+ const kebabToCamel = (s) => s.replace(/-([a-zA-Z])/g, (_, c) => c.toUpperCase());
161
+ /**
162
+ * Transform for use with `map()` that converts kebab-case option keys to
163
+ * camelCase.
164
+ *
165
+ * @example
166
+ *
167
+ * ```typescript
168
+ * import { bargs, opt, map, camelCaseValues } from '@boneskull/bargs';
169
+ *
170
+ * const { values } = await bargs('my-cli')
171
+ * .globals(
172
+ * map(opt.options({ 'output-dir': opt.string() }), camelCaseValues),
173
+ * )
174
+ * .parseAsync();
175
+ *
176
+ * console.log(values.outputDir); // camelCased!
177
+ * ```
178
+ *
179
+ * @function
180
+ */
181
+ const camelCaseValues = (result) => ({
182
+ ...result,
183
+ values: Object.fromEntries(Object.entries(result.values).map(([k, v]) => [
184
+ kebabToCamel(k),
185
+ v,
186
+ ])),
187
+ });
188
+ exports.camelCaseValues = camelCaseValues;
189
+ // ═══════════════════════════════════════════════════════════════════════════════
133
190
  // CLI BUILDER
134
191
  // ═══════════════════════════════════════════════════════════════════════════════
135
192
  /**
@@ -138,8 +195,7 @@ function merge(...parsers) {
138
195
  * @example
139
196
  *
140
197
  * ```typescript
141
- * const cli = await bargs
142
- * .create('my-app', { version: '1.0.0' })
198
+ * const cli = await bargs('my-app', { version: '1.0.0' })
143
199
  * .globals(
144
200
  * map(opt.options({ verbose: opt.boolean() }), ({ values }) => ({
145
201
  * values: { ...values, ts: Date.now() },
@@ -153,8 +209,10 @@ function merge(...parsers) {
153
209
  * )
154
210
  * .parseAsync();
155
211
  * ```
212
+ *
213
+ * @function
156
214
  */
157
- const create = (name, options = {}) => {
215
+ const bargs = (name, options = {}) => {
158
216
  const theme = options.theme ? (0, theme_js_1.getTheme)(options.theme) : theme_js_1.defaultTheme;
159
217
  return createCliBuilder({
160
218
  commands: new Map(),
@@ -163,8 +221,11 @@ const create = (name, options = {}) => {
163
221
  theme,
164
222
  });
165
223
  };
224
+ exports.bargs = bargs;
166
225
  /**
167
226
  * Check if something is a Command (has __brand: 'Command').
227
+ *
228
+ * @function
168
229
  */
169
230
  const isCommand = (x) => {
170
231
  if (x === null || x === undefined) {
@@ -175,6 +236,8 @@ const isCommand = (x) => {
175
236
  };
176
237
  /**
177
238
  * Create a CLI builder.
239
+ *
240
+ * @function
178
241
  */
179
242
  const createCliBuilder = (state) => {
180
243
  const builder = {
@@ -183,11 +246,39 @@ const createCliBuilder = (state) => {
183
246
  const stateWithGlobals = { ...state, parentGlobals };
184
247
  return parseCore(stateWithGlobals, args, allowAsync);
185
248
  },
186
- // Overloaded command(): accepts (name, Command, desc?), (name, Parser, handler, desc?), or (name, CliBuilder, desc?)
187
- command(name, cmdOrParserOrBuilder, handlerOrDesc, maybeDesc) {
249
+ // Overloaded command(): accepts (name, factory, desc?), (name, CliBuilder, desc?),
250
+ // (name, Command, desc?), or (name, Parser, handler, desc?)
251
+ command(name, cmdOrParserOrBuilderOrFactory, handlerOrDesc, maybeDesc) {
252
+ // Form 4: command(name, factory, description?) - factory for nested commands with parent globals
253
+ // Check this FIRST before isCliBuilder/isParser since those check for __brand which a plain function won't have
254
+ if (typeof cmdOrParserOrBuilderOrFactory === 'function' &&
255
+ !isParser(cmdOrParserOrBuilderOrFactory) &&
256
+ !isCommand(cmdOrParserOrBuilderOrFactory) &&
257
+ !isCliBuilder(cmdOrParserOrBuilderOrFactory)) {
258
+ const factory = cmdOrParserOrBuilderOrFactory;
259
+ const description = handlerOrDesc;
260
+ // Create a child builder with parent global TYPES (for type inference)
261
+ // but NOT the globalParser (parent globals are passed via parentGlobals at runtime,
262
+ // not re-parsed from args)
263
+ const childBuilder = createCliBuilder({
264
+ commands: new Map(),
265
+ globalParser: undefined, // Parent globals come via parentGlobals, not re-parsing
266
+ name,
267
+ options: state.options,
268
+ theme: state.theme,
269
+ });
270
+ // Call factory to let user add commands
271
+ const nestedBuilder = factory(childBuilder);
272
+ state.commands.set(name, {
273
+ builder: nestedBuilder,
274
+ description,
275
+ type: 'nested',
276
+ });
277
+ return this;
278
+ }
188
279
  // Form 3: command(name, CliBuilder, description?) - nested commands
189
- if (isCliBuilder(cmdOrParserOrBuilder)) {
190
- const builder = cmdOrParserOrBuilder;
280
+ if (isCliBuilder(cmdOrParserOrBuilderOrFactory)) {
281
+ const builder = cmdOrParserOrBuilderOrFactory;
191
282
  const description = handlerOrDesc;
192
283
  state.commands.set(name, {
193
284
  builder: builder,
@@ -198,14 +289,14 @@ const createCliBuilder = (state) => {
198
289
  }
199
290
  let cmd;
200
291
  let description;
201
- if (isCommand(cmdOrParserOrBuilder)) {
292
+ if (isCommand(cmdOrParserOrBuilderOrFactory)) {
202
293
  // Form 1: command(name, Command, description?)
203
- cmd = cmdOrParserOrBuilder;
294
+ cmd = cmdOrParserOrBuilderOrFactory;
204
295
  description = handlerOrDesc;
205
296
  }
206
- else if (isParser(cmdOrParserOrBuilder)) {
297
+ else if (isParser(cmdOrParserOrBuilderOrFactory)) {
207
298
  // Form 2: command(name, Parser, handler, description?)
208
- const parser = cmdOrParserOrBuilder;
299
+ const parser = cmdOrParserOrBuilderOrFactory;
209
300
  const handler = handlerOrDesc;
210
301
  description = maybeDesc;
211
302
  // Create Command from Parser + handler
@@ -223,7 +314,7 @@ const createCliBuilder = (state) => {
223
314
  cmd = newCmd;
224
315
  }
225
316
  else {
226
- throw new Error('command() requires a Command, Parser, or CliBuilder as second argument');
317
+ throw new Error('command() requires a Command, Parser, CliBuilder, or factory function as second argument');
227
318
  }
228
319
  state.commands.set(name, { cmd, description, type: 'command' });
229
320
  return this;
@@ -298,6 +389,8 @@ const createCliBuilder = (state) => {
298
389
  };
299
390
  /**
300
391
  * Core parse logic shared between parse() and parseAsync().
392
+ *
393
+ * @function
301
394
  */
302
395
  const parseCore = (state, args, allowAsync) => {
303
396
  const { commands, options, theme } = state;
@@ -330,6 +423,8 @@ const parseCore = (state, args, allowAsync) => {
330
423
  };
331
424
  /**
332
425
  * Generate command-specific help.
426
+ *
427
+ * @function
333
428
  */
334
429
  const generateCommandHelpNew = (state, commandName, theme) => {
335
430
  const commandEntry = state.commands.get(commandName);
@@ -356,6 +451,8 @@ const generateCommandHelpNew = (state, commandName, theme) => {
356
451
  };
357
452
  /**
358
453
  * Generate help for the new CLI structure.
454
+ *
455
+ * @function
359
456
  */
360
457
  const generateHelpNew = (state, theme) => {
361
458
  // TODO: Implement proper help generation for new structure
@@ -375,6 +472,8 @@ const generateHelpNew = (state, theme) => {
375
472
  /**
376
473
  * Check if something is a Parser (has __brand: 'Parser'). Parsers can be either
377
474
  * objects or functions (CallableParser).
475
+ *
476
+ * @function
378
477
  */
379
478
  const isParser = (x) => {
380
479
  if (x === null || x === undefined) {
@@ -387,6 +486,8 @@ const isParser = (x) => {
387
486
  /**
388
487
  * Check if something is a CliBuilder (has command, globals, parse, parseAsync
389
488
  * methods).
489
+ *
490
+ * @function
390
491
  */
391
492
  const isCliBuilder = (x) => {
392
493
  if (x === null || x === undefined || typeof x !== 'object') {
@@ -400,6 +501,8 @@ const isCliBuilder = (x) => {
400
501
  };
401
502
  /**
402
503
  * Run a simple CLI (no commands).
504
+ *
505
+ * @function
403
506
  */
404
507
  const runSimple = (state, args, allowAsync) => {
405
508
  const { globalParser } = state;
@@ -436,6 +539,8 @@ const runSimple = (state, args, allowAsync) => {
436
539
  // ═══════════════════════════════════════════════════════════════════════════════
437
540
  /**
438
541
  * Delegate parsing to a nested CliBuilder, passing down parent globals.
542
+ *
543
+ * @function
439
544
  */
440
545
  const delegateToNestedBuilder = (builder, remainingArgs, parentGlobals, allowAsync) => {
441
546
  // Access the internal parse function that accepts parent globals
@@ -444,6 +549,8 @@ const delegateToNestedBuilder = (builder, remainingArgs, parentGlobals, allowAsy
444
549
  };
445
550
  /**
446
551
  * Run a CLI with commands.
552
+ *
553
+ * @function
447
554
  */
448
555
  const runWithCommands = (state, args, allowAsync) => {
449
556
  const { commands, defaultCommandName, globalParser } = state;
@@ -532,6 +639,9 @@ const runWithCommands = (state, args, allowAsync) => {
532
639
  values: { ...parentValues, ...parsed.values },
533
640
  };
534
641
  // Helper to check for async and throw if not allowed
642
+ /**
643
+ * @function
644
+ */
535
645
  const checkAsync = (value, context) => {
536
646
  if (value instanceof Promise && !allowAsync) {
537
647
  throw new errors_js_1.BargsError(`Async ${context} detected. Use parseAsync() instead of parse().`);
@@ -541,6 +651,9 @@ const runWithCommands = (state, args, allowAsync) => {
541
651
  const globalTransform = globalParser?.__transform;
542
652
  const commandTransform = cmd?.__transform;
543
653
  // Apply transforms and run handler
654
+ /**
655
+ * @function
656
+ */
544
657
  const applyTransformsAndHandle = () => {
545
658
  // Apply global transforms first
546
659
  if (globalTransform) {
@@ -556,6 +669,9 @@ const runWithCommands = (state, args, allowAsync) => {
556
669
  }
557
670
  return continueWithCommandTransform();
558
671
  };
672
+ /**
673
+ * @function
674
+ */
559
675
  const continueWithCommandTransform = () => {
560
676
  // Apply command transforms
561
677
  if (commandTransform) {
@@ -571,6 +687,9 @@ const runWithCommands = (state, args, allowAsync) => {
571
687
  }
572
688
  return runHandler();
573
689
  };
690
+ /**
691
+ * @function
692
+ */
574
693
  const runHandler = () => {
575
694
  const handlerResult = cmd.handler(result);
576
695
  checkAsync(handlerResult, 'handler');
@@ -582,9 +701,8 @@ const runWithCommands = (state, args, allowAsync) => {
582
701
  return applyTransformsAndHandle();
583
702
  };
584
703
  /**
585
- * Main bargs namespace.
704
+ * @ignore
705
+ * @deprecated
586
706
  */
587
- exports.bargs = {
588
- create,
589
- };
707
+ exports.bargs.create = exports.bargs;
590
708
  //# sourceMappingURL=bargs.js.map