Skip to content

The v3 flag-type family in one command.

The v3 flag-type family in one command.

  • Source: examples/flag-types.ts

  • Demonstrates: flag.url(), flag.path() with directory creation, flag.date(), flag.duration(), flag.bytes(), flag.count(), flag.keyValue(), string constraints, and array .separator()/.unique().

Usage

bash
npx tsx examples/flag-types.ts --endpoint https://api.example.com --name backup
npx tsx examples/flag-types.ts --name backup --out ./artifacts --timeout 1h30m --max-size 512mb
npx tsx examples/flag-types.ts --name backup --since 2026-01-01 --region us,eu --region us
npx tsx examples/flag-types.ts --name backup --label env=prod --label team=core -vvv
npx tsx examples/flag-types.ts --help

Source

ts
#!/usr/bin/env bun
/**
 * The v3 flag-type family in one command.
 *
 * Demonstrates: `flag.url()`, `flag.path()` with directory creation,
 * `flag.date()`, `flag.duration()`, `flag.bytes()`, `flag.count()`,
 * `flag.keyValue()`, string constraints, and array `.separator()`/`.unique()`.
 *
 * Usage:
 *   npx tsx examples/flag-types.ts --endpoint https://api.example.com --name backup
 *   npx tsx examples/flag-types.ts --name backup --out ./artifacts --timeout 1h30m --max-size 512mb
 *   npx tsx examples/flag-types.ts --name backup --since 2026-01-01 --region us,eu --region us
 *   npx tsx examples/flag-types.ts --name backup --label env=prod --label team=core -vvv
 *   npx tsx examples/flag-types.ts --help
 */

import { cli, command, flag } from '@kjanat/dreamcli';

const snapshot = command('snapshot')
	.description('Create a snapshot with richly typed inputs')
	// URL — parses into a `URL`, protocol allowlist optional.
	.flag('endpoint', flag.url({ protocols: ['https'] }).describe('Upload endpoint'))
	// String constraints — checked at parse AND env/config/prompt resolution.
	.flag(
		'name',
		flag
			.string({ nonEmpty: true, pattern: /^[a-z][a-z0-9-]*$/ })
			.required()
			.describe('Snapshot name (lowercase, kebab)'),
	)
	// Path — missing directory is created (mkdir -p) at resolution time.
	.flag(
		'out',
		flag
			.path({ type: 'directory', create: true })
			.default('./snapshots')
			.describe('Output directory, created when missing'),
	)
	// Date — strict ISO-8601 into a `Date`; lenient Date.parse inputs rejected.
	.flag('since', flag.date().describe('Only include changes since this date'))
	// Duration — '90s', '1h30m', '250ms', or bare milliseconds → milliseconds.
	.flag('timeout', flag.duration().default(30_000).describe('Upload timeout'))
	// Bytes — '512mb', '1.5gb' (binary units) or bare bytes → bytes.
	.flag(
		'max-size',
		flag
			.bytes()
			.default(256 * 1024 ** 2)
			.describe('Maximum snapshot size'),
	)
	// Count — occurrence counter: -v -vv -vvv → 1, 2, 3.
	.flag('verbose', flag.count().alias('v').describe('Increase verbosity'))
	// KeyValue — repeated KEY=VALUE merges into Record<string, string>.
	.flag('label', flag.keyValue().describe('Attach metadata labels'))
	// Array — separator splits each occurrence, unique dedupes the result.
	.flag(
		'region',
		flag
			.array(flag.enum(['us', 'eu', 'ap']))
			.separator(',')
			.unique()
			.describe('Target regions'),
	)
	.action(({ flags, out }) => {
		out.status(`snapshot '${flags.name}' -> ${flags.out}`);
		out.json({
			name: flags.name,
			endpoint: flags.endpoint?.href,
			out: flags.out,
			since: flags.since?.toISOString(),
			timeoutMs: flags.timeout,
			maxSizeBytes: flags['max-size'],
			verbosity: flags.verbose,
			labels: flags.label,
			regions: flags.region,
		});
	});

void cli('snapshot').version('1.0.0').default(snapshot).run();

Released under the MIT License.