Interface: ArgSchema
An argument schema definition for command-line argument parsing.
This schema is similar to the schema of Node.js util.parseArgs
but with extended features:
- Additional
required
anddescription
properties - Extended
type
support: 'string', 'boolean', 'number', 'enum', 'positional', 'custom' - Simplified
default
property (single type, not union types)
Examples
Basic string argument:
ts
const schema: ArgSchema = {
type: 'string',
description: 'Server hostname',
default: 'localhost'
}
Required number argument with alias:
ts
const schema: ArgSchema = {
type: 'number',
short: 'p',
description: 'Port number to listen on',
required: true
}
Enum argument with choices:
ts
const schema: ArgSchema = {
type: 'enum',
choices: ['info', 'warn', 'error'],
description: 'Logging level',
default: 'info'
}
Properties
Property | Type | Description |
---|---|---|
choices? | string [] | readonly string [] | Array of allowed string values for enum-type arguments. Required when type: 'enum' . The argument value must be one of these choices, otherwise an ArgResolveError with type 'type' will be thrown. Supports both mutable arrays and readonly arrays for type safety. Example Enum choices: { logLevel: { type: 'enum', choices: ['debug', 'info', 'warn', 'error'] as const, default: 'info', description: 'Logging verbosity level' }, format: { type: 'enum', choices: ['json', 'yaml', 'toml'], description: 'Output format' } } |
conflicts? | string | string [] | Names of other options that conflict with this option. When this option is used together with any of the conflicting options, an ArgResolveError with type 'conflict' will be thrown. Conflicts only need to be defined on one side - if option A defines a conflict with option B, the conflict is automatically detected when both are used, regardless of whether B also defines a conflict with A. Supports both single option name or array of option names. Option names must match the property keys in the schema object exactly (no automatic conversion between camelCase and kebab-case). Examples Single conflict (bidirectional definition): { summer: { type: 'boolean', conflicts: 'autumn' // Cannot use --summer with --autumn }, autumn: { type: 'boolean', conflicts: 'summer' // Can define on both sides for clarity } } Single conflict (one-way definition): { summer: { type: 'boolean', conflicts: 'autumn' // Only defined on summer side }, autumn: { type: 'boolean' // No conflicts defined, but still cannot use with --summer } } // Usage: --summer --autumn will throw error // Error: "Optional argument '--summer' conflicts with '--autumn'" Multiple conflicts: { port: { type: 'number', conflicts: ['socket', 'pipe'], // Cannot use with --socket or --pipe description: 'TCP port number' }, socket: { type: 'string', conflicts: ['port', 'pipe'], // Cannot use with --port or --pipe description: 'Unix socket path' }, pipe: { type: 'string', conflicts: ['port', 'socket'], // Cannot use with --port or --socket description: 'Named pipe path' } } // These three options are mutually exclusive With kebab-case conversion: { summerSeason: { type: 'boolean', toKebab: true, // Accessible as --summer-season conflicts: 'autumnSeason' // Must use property key, not CLI name }, autumnSeason: { type: 'boolean', toKebab: true // Accessible as --autumn-season } } // Error: "Optional argument '--summer-season' conflicts with '--autumn-season'" |
default? | string | number | boolean | Default value used when the argument is not provided. The type must match the argument's type property: - string type: string default - boolean type: boolean default - number type: number default - enum type: must be one of the choices values - positional /custom type: any appropriate default Example Default values by type: { host: { type: 'string', default: 'localhost' // string default }, verbose: { type: 'boolean', default: false // boolean default }, port: { type: 'number', default: 8080 // number default }, level: { type: 'enum', choices: ['low', 'high'], default: 'low' // must be in choices } } |
description? | string | Human-readable description of the argument's purpose. Used for help text generation and documentation. Should be concise but descriptive enough to understand the argument's role. Example Descriptive help text: { config: { type: 'string', description: 'Path to configuration file' }, timeout: { type: 'number', description: 'Request timeout in milliseconds' } } |
multiple? | true | Allows the argument to accept multiple values. When true , the resolved value becomes an array. For options: can be specified multiple times (--tag foo --tag bar) For positional: collects remaining positional arguments Note: Only true is allowed (not false ) to make intent explicit. Example Multiple values: { tags: { type: 'string', multiple: true, // --tags foo --tags bar → ['foo', 'bar'] description: 'Tags to apply' }, files: { type: 'positional', multiple: true // Collects all remaining positional args } } |
negatable? | boolean | Enables negation for boolean arguments using --no- prefix. When true , allows users to explicitly set the boolean to false using --no-option-name . When false or omitted, only positive form is available. Only applicable to type: 'boolean' arguments. Example Negatable boolean: { color: { type: 'boolean', negatable: true, default: true, description: 'Enable colorized output' } // Usage: --color (true), --no-color (false) } |
parse? | (value ) => any | Custom parsing function for type: 'custom' arguments. Required when type: 'custom' . Receives the raw string value and must return the parsed result. Should throw an Error (or subclass) if parsing fails. The function's return type becomes the resolved argument type. Throws Error or subclass when value is invalid Example Custom parsing functions: { config: { type: 'custom', parse: (value: string) => { try { return JSON.parse(value) // Parse JSON config } catch { throw new Error('Invalid JSON configuration') } }, description: 'JSON configuration object' }, date: { type: 'custom', parse: (value: string) => { const date = new Date(value) if (isNaN(date.getTime())) { throw new Error('Invalid date format') } return date } } } |
required? | true | Marks the argument as required. When true , the argument must be provided by the user. If missing, an ArgResolveError with type 'required' will be thrown. Note: Only true is allowed (not false ) to make intent explicit. Example Required arguments: { input: { type: 'string', required: true, // Must be provided: --input file.txt description: 'Input file path' }, source: { type: 'positional', required: true // First positional argument must exist } } |
short? | string | Single character alias for the long option name. As example, allows users to use -x instead of --extended-option . Only valid for non-positional argument types. Example Short alias usage: { verbose: { type: 'boolean', short: 'v' // Enables both --verbose and -v }, port: { type: 'number', short: 'p' // Enables both --port 3000 and -p 3000 } } |
toKebab? | true | Converts the argument name from camelCase to kebab-case for CLI usage. When true , a property like maxCount becomes available as --max-count . This allows CAC user-friendly property names while maintaining CLI conventions. Can be overridden globally with resolveArgs({ toKebab: true }) . Note: Only true is allowed (not false ) to make intent explicit. Example Kebab-case conversion: { maxRetries: { type: 'number', toKebab: true, // Accessible as --max-retries description: 'Maximum retry attempts' }, enableLogging: { type: 'boolean', toKebab: true // Accessible as --enable-logging } } |
type | "string" | "number" | "boolean" | "positional" | "enum" | "custom" | Type of the argument value. - 'string' : Text value (default if not specified) - 'boolean' : true /false flag (can be negatable with --no- prefix) - 'number' : Numeric value (parsed as integer or float) - 'enum' : One of predefined string values (requires choices property) - 'positional' : Non-option argument by position - 'custom' : Custom parsing with user-defined parse function Example Different argument types: { name: { type: 'string' }, // --name value verbose: { type: 'boolean' }, // --verbose or --no-verbose port: { type: 'number' }, // --port 3000 level: { type: 'enum', choices: ['debug', 'info'] }, file: { type: 'positional' }, // first positional arg config: { type: 'custom', parse: JSON.parse } } |