API
Every export of zodline — defineOptions, defineCommand, defineConfig, processConfig, ZodlineError and the types.
Everything is exported from the package root.
import {
defineCommand,
defineConfig,
defineOptions,
processConfig,
ZodlineError,
} from 'zodline';
import type {
CommandDefinition,
DefineConfig,
OptionsDefinition,
ProcessResult,
} from 'zodline';
defineOptions
function defineOptions<T extends z.ZodObject>(
schema: T,
aliases?: Record<string, string>,
): OptionsDefinition<T>;
Pairs an options schema with an alias map. Returns { schema, aliases } unchanged — the function exists to
capture T so the schema type flows into defineCommand.
schemaz.ZodObject
One key per option, in camelCase.
z.ZodObjectaliases?Record<string, string>
Maps a short flag to a schema key, e.g. { n: "name" }.
Record<string, string>const options = defineOptions(
z.object({
name: z.string().describe('Name to greet'),
loud: z.boolean().default(false).describe('Use uppercase'),
}),
{ n: 'name', l: 'loud' },
);
defineCommand
function defineCommand<TOptions, TArgs>(config: {
description?: string;
options?: TOptions;
args?: TArgs;
action: (options, args) => void | Promise<void>;
}): CommandDefinition<…>;
Describes one command. Returns its input; the generics make options and args inside action inferred
rather than any.
description?string
Shown in the help screens.
stringoptions?OptionsDefinition
The result of defineOptions().
OptionsDefinitionargs?z.ZodType
Schema applied to the positional argument array.
z.ZodTypeaction(options, args) => void | Promise<void>
Never invoked by processConfig — you call it.
(options, args) => void | Promise<void>defineConfig
function defineConfig<TCommands>(config: DefineConfig<TCommands>): DefineConfig<TCommands>;
Collects commands and CLI metadata.
meta?{ name?: string; version?: string; description?: string }
Identity used by the help screens and --version.
{ name?: string; version?: string; description?: string }commandsRecord<string, CommandDefinition>
Keys are the names users type.
Record<string, CommandDefinition>defaultCommand?CommandDefinition
Runs when no command name is given. Never receives positional arguments.
CommandDefinitionprocessConfig
function processConfig<TCommands>(
config: DefineConfig<TCommands>,
args: string[],
): ProcessResult;
Parses and validates args, then returns the matched command with its typed options and args. Does not
call the action.
Pass process.argv.slice(2) — the array must not include the node binary or the script path.
const result = processConfig(config, process.argv.slice(2));
await result.command.action(result.options, result.args);
Control flow
Parse flags
Resolve the command
The first positional argument names the command. With none, --version and --help are handled (both
exit 0), then defaultCommand, then a ZodlineError.
Per-command help
--help after a command name prints its options and exits 0.Validate
Options run through the options pipeline; positional arguments run through the args schema.
Throws
| Condition | Error |
|---|---|
No command and no defaultCommand |
ZodlineError: No command specified. |
| Unknown command | ZodlineError: Unknown command: <name> |
| Unknown option | ZodlineError: Unknown option: --<name> |
| Options schema failure | ZodError |
| Args schema failure | Error: Argument validation failed: … |
ZodlineError
class ZodlineError extends Error {
name: 'ZodlineError';
}
Thrown for parse-level problems: no command, unknown command, unknown option. Schema failures are Zod’s errors, not this one.
if (error instanceof ZodlineError) {
console.error(error.message);
process.exit(2);
}
Types
OptionsDefinition
interface OptionsDefinition<T extends z.ZodObject = z.ZodObject> {
schema: T;
aliases?: Record<string, string> | undefined;
}
CommandDefinition
interface CommandDefinition<TOptions extends z.ZodObject, TArgs extends z.ZodType | undefined> {
description?: string;
options?: OptionsDefinition<TOptions>;
args?: TArgs;
action: (
options: TOptions extends z.ZodObject ? z.infer<TOptions> : {},
args: TArgs extends z.ZodType ? z.infer<TArgs> : undefined,
) => void | Promise<void>;
}
DefineConfig
interface DefineConfig<TCommands extends Record<string, CommandDefinition>> {
meta?: {
name?: string;
version?: string;
description?: string;
};
commands: TCommands;
defaultCommand?: CommandDefinition;
}
ProcessResult
interface ProcessResult<TCommand extends CommandDefinition> {
command: TCommand;
options: z.infer<TCommand['options']['schema']>;
args: z.infer<TCommand['args']>;
}
options resolves to {} for a command without options; args resolves to undefined for a command
without an args schema.