Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .config/typedoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ export default {
favicon: '../site/media/favicon.svg',
// @ts-expect-error from extras plugin
footerLastModified: true,
kindSortOrder: [
'Reference',
'Project',
'Module',
'Namespace',
'Function',
'TypeAlias',
],
lightHighlightTheme: 'vitesse-light',
markdownLinkExternal: true,
name: 'BARGS',
Expand Down
57 changes: 25 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ A CLI with an optional command and a couple options:
```typescript
import { bargs, opt, pos } from '@boneskull/bargs';

await bargs
.create('greet', { version: '1.0.0' })
await bargs('greet', { version: '1.0.0' })
.globals(
opt.options({
name: opt.string({ default: 'world' }),
Expand Down Expand Up @@ -112,11 +111,10 @@ const parser = pos.positionals(pos.variadic('string', { name: 'text' }))(
}),
);

const { values, positionals } = await bargs
.create('echo', {
description: 'Echo text to stdout',
version: '1.0.0',
})
const { values, positionals } = await bargs('echo', {
description: 'Echo text to stdout',
version: '1.0.0',
})
.globals(parser)
.parseAsync();

Expand All @@ -132,11 +130,10 @@ For a CLI with multiple subcommands:
```typescript
import { bargs, merge, opt, pos } from '@boneskull/bargs';

await bargs
.create('tasks', {
description: 'A task manager',
version: '1.0.0',
})
await bargs('tasks', {
description: 'A task manager',
version: '1.0.0',
})
.globals(
opt.options({
verbose: opt.boolean({ aliases: ['v'], default: false }),
Expand Down Expand Up @@ -189,8 +186,7 @@ Commands can be nested to arbitrary depth by passing a `CliBuilder` as the secon
import { bargs, opt, pos } from '@boneskull/bargs';

// Define subcommands as a separate builder
const remoteCommands = bargs
.create('remote')
const remoteCommands = bargs('remote')
.command(
'add',
pos.positionals(
Expand All @@ -208,8 +204,7 @@ const remoteCommands = bargs
.defaultCommand('add');

// Nest under parent CLI
await bargs
.create('git')
await bargs('git')
.globals(opt.options({ verbose: opt.boolean({ aliases: ['v'] }) }))
.command('remote', remoteCommands, 'Manage remotes') // ← CliBuilder
.command('commit', commitParser, commitHandler) // ← Regular command
Expand All @@ -227,7 +222,7 @@ Parent globals automatically flow to nested command handlers. You can nest as de

## API

### bargs.create(name, options?)
### bargs(name, options?)

Create a CLI builder.

Expand All @@ -243,7 +238,7 @@ Create a CLI builder.
Set global options and transforms that apply to all commands.

```typescript
bargs.create('my-cli').globals(opt.options({ verbose: opt.boolean() }));
bargs('my-cli').globals(opt.options({ verbose: opt.boolean() }));
// ...
```

Expand All @@ -268,9 +263,9 @@ Register a command. The handler receives merged global + command types.
Register a nested command group. The `cliBuilder` is another `CliBuilder` whose commands become subcommands. Parent globals are passed down to nested handlers.

```typescript
const subCommands = bargs.create('sub').command('foo', ...).command('bar', ...);
const subCommands = bargs('sub').command('foo', ...).command('bar', ...);

bargs.create('main')
bargs('main')
.command('nested', subCommands, 'Nested commands') // nested group
.parseAsync();

Expand Down Expand Up @@ -304,11 +299,11 @@ Parse arguments and execute handlers.

```typescript
// Async (supports async transforms/handlers)
const result = await bargs.create('my-cli').globals(...).parseAsync();
const result = await bargs('my-cli').globals(...).parseAsync();
console.log(result.values, result.positionals, result.command);

// Sync (no async transforms/handlers)
const result = bargs.create('my-cli').globals(...).parse();
const result = bargs('my-cli').globals(...).parse();
```

## Option Helpers
Expand Down Expand Up @@ -469,8 +464,7 @@ const globals = map(
}),
);

await bargs
.create('my-cli')
await bargs('my-cli')
.globals(globals)
.command(
'info',
Expand Down Expand Up @@ -513,8 +507,7 @@ If you prefer camelCase property names instead of kebab-case, use the `camelCase
```typescript
import { bargs, map, opt, camelCaseValues } from '@boneskull/bargs';

const { values } = await bargs
.create('my-cli')
const { values } = await bargs('my-cli')
.globals(
map(
opt.options({
Expand Down Expand Up @@ -542,12 +535,12 @@ By default, **bargs** displays your package's homepage and repository URLs (from

```typescript
// Custom epilog
bargs.create('my-cli', {
bargs('my-cli', {
epilog: 'For more info, visit https://example.com',
});

// Disable epilog entirely
bargs.create('my-cli', { epilog: false });
bargs('my-cli', { epilog: false });
```

## Theming
Expand All @@ -556,18 +549,18 @@ Customize help output colors with built-in themes or your own:

```typescript
// Use a built-in theme: 'default', 'mono', 'ocean', 'warm'
bargs.create('my-cli', { theme: 'ocean' });
bargs('my-cli', { theme: 'ocean' });

// Disable colors entirely
bargs.create('my-cli', { theme: 'mono' });
bargs('my-cli', { theme: 'mono' });
```

The `ansi` export provides common ANSI escape codes for styled terminal output:

```typescript
import { ansi } from '@boneskull/bargs';

bargs.create('my-cli', {
bargs('my-cli', {
theme: {
command: ansi.bold,
flag: ansi.brightCyan,
Expand Down Expand Up @@ -613,7 +606,7 @@ import {
} from '@boneskull/bargs';

try {
await bargs.create('my-cli').parseAsync();
await bargs('my-cli').parseAsync();
} catch (error) {
if (error instanceof ValidationError) {
// Config validation failed (e.g., invalid schema)
Expand Down
9 changes: 4 additions & 5 deletions examples/greeter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,10 @@ const greetPositionals = pos.positionals(

// Build and run the CLI
// Using the (Parser, handler) form for full type inference of merged globals
await bargs
.create('greeter', {
description: 'A friendly greeter CLI',
version: '1.0.0',
})
await bargs('greeter', {
description: 'A friendly greeter CLI',
version: '1.0.0',
})
.globals(globalOptions)
// The (Parser, handler, description) form gives us merged global + command types!
.command(
Expand Down
15 changes: 6 additions & 9 deletions examples/nested-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ const config: Map<string, string> = new Map([
// ═══════════════════════════════════════════════════════════════════════════════

// "remote" command group with subcommands: add, remove, list
const remoteCommands = bargs
.create('remote')
const remoteCommands = bargs('remote')
.command(
'add',
pos.positionals(
Expand Down Expand Up @@ -96,8 +95,7 @@ const remoteCommands = bargs
.defaultCommand('list');

// "config" command group with subcommands: get, set
const configCommands = bargs
.create('config')
const configCommands = bargs('config')
.command(
'get',
pos.positionals(pos.string({ name: 'key', required: true })),
Expand Down Expand Up @@ -137,11 +135,10 @@ const globals = opt.options({
verbose: opt.boolean({ aliases: ['v'], default: false }),
});

await bargs
.create('git-like', {
description: 'A git-like CLI demonstrating nested commands',
version: '1.0.0',
})
await bargs('git-like', {
description: 'A git-like CLI demonstrating nested commands',
version: '1.0.0',
})
.globals(globals)
// Register nested command groups
.command('remote', remoteCommands, 'Manage remotes')
Expand Down
9 changes: 4 additions & 5 deletions examples/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,10 @@ const doneParser = pos.positionals(pos.string({ name: 'id', required: true }));
// Using (Parser, handler, description) form for full type inference!
// ═══════════════════════════════════════════════════════════════════════════════

await bargs
.create('tasks', {
description: 'A simple task manager',
version: '1.0.0',
})
await bargs('tasks', {
description: 'A simple task manager',
version: '1.0.0',
})
.globals(globalOptions)
// The handler receives merged global + command types
.command(
Expand Down
9 changes: 4 additions & 5 deletions examples/transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,10 @@ const infoParser = opt.options({});
// Using (Parser, handler, description) form for full type inference!
// ═══════════════════════════════════════════════════════════════════════════════

await bargs
.create('transforms-demo', {
description: 'Demonstrates transforms with commands',
version: '1.0.0',
})
await bargs('transforms-demo', {
description: 'Demonstrates transforms with commands',
version: '1.0.0',
})
.globals(globals)
// The handler receives merged global + command types
.command(
Expand Down
19 changes: 8 additions & 11 deletions src/bargs.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/**
* Core bargs API using parser combinator pattern.
*
* Provides `bargs.create()` for building CLIs with a fluent API, plus
* combinator functions like `pipe()`, `map()`, and `handle()`.
* Provides `bargs()` for building CLIs with a fluent API, plus combinator
* functions like `pipe()`, `map()`, and `handle()`.
*
* @packageDocumentation
*/
Expand Down Expand Up @@ -362,8 +362,7 @@ const kebabToCamel = (s: string): string =>
* ```typescript
* import { bargs, opt, map, camelCaseValues } from '@boneskull/bargs';
*
* const { values } = await bargs
* .create('my-cli')
* const { values } = await bargs('my-cli')
* .globals(
* map(opt.options({ 'output-dir': opt.string() }), camelCaseValues),
* )
Expand Down Expand Up @@ -396,8 +395,7 @@ export const camelCaseValues = <V, P extends readonly unknown[]>(
* @example
*
* ```typescript
* const cli = await bargs
* .create('my-app', { version: '1.0.0' })
* const cli = await bargs('my-app', { version: '1.0.0' })
* .globals(
* map(opt.options({ verbose: opt.boolean() }), ({ values }) => ({
* values: { ...values, ts: Date.now() },
Expand All @@ -414,7 +412,7 @@ export const camelCaseValues = <V, P extends readonly unknown[]>(
*
* @function
*/
const create = (
export const bargs = (
name: string,
options: CreateOptions = {},
): CliBuilder<Record<string, never>, readonly []> => {
Expand Down Expand Up @@ -1110,8 +1108,7 @@ const runWithCommands = (
};

/**
* Main bargs namespace.
* @ignore
* @deprecated
*/
export const bargs = {
create,
};
bargs.create = bargs;
3 changes: 1 addition & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
* ```typescript
* import { bargs, opt, pos } from '@boneskull/bargs';
*
* await bargs
* .create('my-app', { version: '1.0.0' })
* await bargs('my-app', { version: '1.0.0' })
* .globals(opt.options({ verbose: opt.boolean({ aliases: ['v'] }) }))
* .command(
* 'greet',
Expand Down
2 changes: 2 additions & 0 deletions src/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { stripVTControlCharacters } from 'node:util';

/**
* Strip all ANSI escape codes from a string.
*
* @function
*/
export const stripAnsi = stripVTControlCharacters;

Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ export interface CountOption extends OptionBase {
}

/**
* Options for bargs.create().
* Options for bargs().
*/
export interface CreateOptions {
/** Description shown in help */
Expand Down
Loading