### Define and Run a Command - TypeScript Source: https://github.com/schniz/cmd-ts/blob/main/docs/parsers/command.md Example of defining a command with arguments and running it. This demonstrates how to use the `command` combinator with parsers for different argument types and a handler function. ```typescript import { command, string, number } from "../src"; const greet = command({ name: "greet", version: "1.0.0", args: { name: string({}) }, handler: ({ name }) => { console.log(`Hello, ${name}!`); } }); const add = command({ name: "add", version: "1.0.0", args: { a: number({}), b: number({}) }, handler: ({ a, b }) => { console.log(`${a} + ${b} = ${a + b}`); } }); const app = greet.subcommands({ add }); app.run(); ``` -------------------------------- ### Install cmd-ts with npm Source: https://github.com/schniz/cmd-ts/blob/main/docs/getting_started.md Use this command to install the cmd-ts package if you are using npm. ```bash npm install --save cmd-ts ``` -------------------------------- ### Install cmd-ts with Yarn Source: https://github.com/schniz/cmd-ts/blob/main/docs/getting_started.md Use this command to install the cmd-ts package if you are using Yarn. ```bash yarn add cmd-ts ``` -------------------------------- ### Basic File Argument Parsing with cmd-ts Source: https://github.com/schniz/cmd-ts/blob/main/docs/custom_types.md This example shows how to parse a file path as a string argument using cmd-ts. It reads the file content and pipes it to standard output. ```typescript import { command, run, positional, string } from 'cmd-ts'; const app = command({ /// name: ..., args: { file: positional({ type: string, displayName: 'file' }), }, handler: ({ file }) => { // read the file to the screen fs.createReadStream(file).pipe(stdout); }, }); // parse arguments run(app, process.argv.slice(2)); ``` -------------------------------- ### Parsing a File Path as a String with cmd-ts Source: https://github.com/schniz/cmd-ts/blob/main/README.md Shows a simple case of parsing a file path as a string using a positional argument. This example is a precursor to custom type decoding. ```typescript // my-app.ts import { command, run, positional, string } from 'cmd-ts'; const app = command({ /// name: ..., args: { file: positional({ type: string, displayName: 'file' }), }, handler: ({ file }) => { // read the file to the screen fs.createReadStream(file).pipe(stdout); }, }); // parse arguments run(app, process.argv.slice(2)); ``` -------------------------------- ### Define a CLI command with cmd-ts Source: https://context7.com/schniz/cmd-ts/llms.txt Use the `command` function to define a runnable CLI command. Specify arguments, version, description, and a handler function. Examples demonstrate basic usage. ```typescript import { command, run, string, number, positional, option, flag, boolean } from 'cmd-ts'; const greet = command({ name: 'greet', version: '1.0.0', description: 'Greet someone by name', args: { name: positional({ type: string, displayName: 'name' }), times: option({ long: 'times', short: 't', type: number, description: 'How many times to greet', defaultValue: () => 1, defaultValueIsSerializable: true, }), shout: flag({ long: 'shout', short: 's', description: 'UPPERCASE output' }), }, examples: [ { description: 'Greet Alice', command: 'greet Alice --times 3' }, { description: 'Shout at Bob', command: 'greet Bob --shout' }, ], handler: ({ name, times, shout }) => { const msg = `Hello, ${name}!`; for (let i = 0; i < times; i++) { console.log(shout ? msg.toUpperCase() : msg); } }, }); // node greet.js Alice --times 2 // → Hello, Alice! // → Hello, Alice! run(greet, process.argv.slice(2)); ``` -------------------------------- ### Using Custom ReadStream Type with cmd-ts Source: https://github.com/schniz/cmd-ts/blob/main/docs/custom_types.md This example demonstrates how to use the custom `ReadStream` type within a cmd-ts command. The handler function now directly receives a `Stream` object, simplifying file processing logic. ```typescript import { command, run, positional } from 'cmd-ts'; const app = command({ // name: ..., args: { stream: positional({ type: ReadStream, displayName: 'file' }), }, handler: ({ stream }) => stream.pipe(process.stdout), }); // parse arguments run(app, process.argv.slice(2)); ``` -------------------------------- ### Using binary helper to run a command Source: https://github.com/schniz/cmd-ts/blob/main/docs/parsers/binary.md This snippet demonstrates how to use the `binary` helper to wrap a command and run it with `process.argv`. It automatically handles the omission of the first two arguments passed to a standard Node.js executable. ```typescript import { binary, command, run } from 'cmd-ts'; const myCommand = command({ /* ... */ }); const binaryCommand = binary(myCommand); run(binaryCommand, process.argv); ``` -------------------------------- ### Implement a Fully Custom Help Formatter Source: https://context7.com/schniz/cmd-ts/llms.txt Implement a fully custom help formatter by providing an object that adheres to the HelpFormatter interface, defining methods for formatting commands and subcommands. This offers maximum flexibility for unique output requirements. ```typescript setDefaultHelpFormatter({ formatCommand(data, _ctx) { return `${data.name} ${data.version ?? ''}\n${data.description ?? ''}\n`; }, formatSubcommands(data, _ctx) { return `${data.name}: ${data.commands.map(c => c.name).join(' | ')}\n`; }, }); ``` -------------------------------- ### Basic cmd-ts Application Source: https://github.com/schniz/cmd-ts/blob/main/docs/getting_started.md Create a simple command-line application that accepts a single string positional argument and logs it to the console. Ensure you have the necessary imports from 'cmd-ts'. ```typescript import { command, run, string, positional } from 'cmd-ts'; const app = command({ name: 'my-first-app', args: { someArg: positional({ type: string, displayName: 'some arg' }), }, handler: ({ someArg }) => { console.log({ someArg }); }, }); run(app, process.argv.slice(2)); ``` -------------------------------- ### Run CLI with Custom Help Formatter and Reset Source: https://context7.com/schniz/cmd-ts/llms.txt After setting a custom help formatter, run your CLI application using the run function. Use resetHelpFormatter to revert to the built-in formatter, which is useful for testing or when custom formatting is no longer needed. ```typescript const deploy = command({ name: 'deploy', description: 'Deploy the application', args: { env: option({ long: 'env', type: string }) }, handler: ({ env }) => console.log(`Deploying to ${env}`) }); const cli = subcommands({ name: 'mycli', version: '1.0.0', cmds: { deploy } }); // --help now uses your custom formatter run(cli, process.argv.slice(2)); // Reset to built-in formatter (useful in tests) resetHelpFormatter(); ``` -------------------------------- ### File Source: https://github.com/schniz/cmd-ts/blob/main/docs/batteries_file_system.md Resolves into an existing file. Fails if the provided path is not a file. ```APIDOC ## File ### Description Resolves into an existing file. Fails if the provided path is not a file. ### Usage ```typescript import { File } from 'cmd-ts/batteries/fs'; ``` ``` -------------------------------- ### Basic Command Line Argument Parsing with cmd-ts Source: https://github.com/schniz/cmd-ts/blob/main/README.md Demonstrates basic usage of cmd-ts for parsing string and number arguments, including positional and optional arguments. Imports required functions and defines a command with a handler. ```typescript import { command, run, string, number, positional, option, } from 'cmd-ts'; const cmd = command({ name: 'my-command', description: 'print something to the screen', version: '1.0.0', args: { number: positional({ type: number, displayName: 'num' }), message: option({ long: 'greeting', type: string, }), }, handler: (args) => { args.message; // string args.number; // number console.log(args); }, }); run(cmd, process.argv.slice(2)); ``` -------------------------------- ### run / runSafely / dryRun / parse — execute a command Source: https://context7.com/schniz/cmd-ts/llms.txt Provides four utilities for executing commands with different side-effect profiles: `run` exits on error, `runSafely` returns a `Result`, `dryRun` returns an error message string, and `parse` resolves the parsed arguments without invoking the handler. ```APIDOC ## run / runSafely / dryRun / parse — execute a command Four runner utilities with different side-effect profiles. `run` executes the command and calls `process.exit` on errors. `runSafely` returns a `Result` instead of exiting. `dryRun` returns a `Result` where the error is the formatted error message as a string. `parse` resolves the parsed argument object without invoking the handler. ```ts import { command, run, runSafely, dryRun, parse, string, positional } from 'cmd-ts'; const cmd = command({ name: 'hello', args: { who: positional({ type: string, displayName: 'who' }) }, handler: ({ who }) => `Hello, ${who}!`, }); // 1. run: exits the process on error run(cmd, ['World']); // → handler receives { who: 'World' } // 2. runSafely: returns Result, no process.exit const result = await runSafely(cmd, ['World']); if (result._tag === 'Right') console.log(result.value); // 'Hello, World!' // 3. dryRun: returns error message as a string, not an Exit object const dry = await dryRun(cmd, []); if (dry._tag === 'Left') console.error(dry.error); // formatted error string // 4. parse: returns parsed args without running the handler const parsed = await parse(cmd, ['Alice']); // parsed is a ParsingResult<{ who: string }> ``` ``` -------------------------------- ### Directory Source: https://github.com/schniz/cmd-ts/blob/main/docs/batteries_file_system.md Resolves into a path of an existing directory. If an existing file was given, it uses its parent directory. ```APIDOC ## Directory ### Description Resolves into a path of an existing directory. If an existing file was given, it'll use its `dirname`. ### Usage ```typescript import { Directory } from 'cmd-ts/batteries/fs'; ``` ``` -------------------------------- ### Import File Type Source: https://github.com/schniz/cmd-ts/blob/main/docs/batteries_file_system.md Use File to ensure a provided path points to an existing file. It will fail if the path is not a file. ```typescript import { File } from 'cmd-ts/batteries/fs'; ``` -------------------------------- ### Filesystem Batteries: ExistingPath, Directory, File Source: https://context7.com/schniz/cmd-ts/llms.txt Utilize pre-built filesystem types for path validation at parse time. `File` and `Directory` ensure the path exists and is of the correct type, while `ExistingPath` checks only for existence. ```typescript import { command, run, positional, option } from 'cmd-ts'; import { ExistingPath, Directory, File } from 'cmd-ts/batteries/fs'; const cmd = command({ name: 'read-file', args: { src: positional({ type: File, displayName: 'src', description: 'Source file' }), outDir: option({ long: 'out-dir', type: Directory, description: 'Output directory' }), anyPath: option({ long: 'config', type: ExistingPath, description: 'Any existing path' }), }, handler: ({ src, outDir, anyPath }) => { console.log('File: ', src); // absolute path to file console.log('Directory: ', outDir); // absolute path to directory console.log('Any path: ', anyPath); // any existing fs entry }, }); // node cmd.js ./package.json --out-dir ./dist --config ./tsconfig.json run(cmd, process.argv.slice(2)); ``` -------------------------------- ### Wrap Commands for `process.argv` with `binary` Source: https://context7.com/schniz/cmd-ts/llms.txt Use `binary` to wrap a command, ensuring that `process.argv` is correctly processed. It strips the Node binary and script paths, and injects the command name into the parsed path for accurate help and error messages. ```typescript import { binary, command, subcommands, run, string, option } from 'cmd-ts'; const deploy = command({ name: 'deploy', args: { env: option({ long: 'env', type: string }) }, handler: ({ env }) => console.log(`Deploying to ${env}`), }); const cli = binary(subcommands({ name: 'mycli', cmds: { deploy } })); // node ./mycli.js deploy --env production run(cli, process.argv); // Note: pass process.argv, NOT process.argv.slice(2) ``` -------------------------------- ### Globally Replace Help Formatter with Vercel Style Source: https://context7.com/schniz/cmd-ts/llms.txt Use the pre-configured Vercel formatter by calling setDefaultHelpFormatter with vercelFormatter. This option is suitable when the default Vercel styling meets your needs. ```typescript import { command, run, subcommands, option, string, setDefaultHelpFormatter, resetHelpFormatter } from 'cmd-ts'; import { createVercelFormatter, vercelFormatter } from 'cmd-ts/batteries/vercelFormatter'; // Option A: use the pre-configured Vercel formatter defaultSetHelpFormatter(vercelFormatter); ``` -------------------------------- ### Import Directory Type Source: https://github.com/schniz/cmd-ts/blob/main/docs/batteries_file_system.md Use Directory to resolve a path to an existing directory. If a file path is given, its parent directory is used. ```typescript import { Directory } from 'cmd-ts/batteries/fs'; ``` -------------------------------- ### subcommands — compose multiple commands Source: https://context7.com/schniz/cmd-ts/llms.txt Groups multiple `command` or nested `subcommands` instances under one router. Automatically displays help when called with no arguments and includes suggestions for mistyped subcommand names. ```APIDOC ## subcommands — compose multiple commands Groups multiple `command` (or nested `subcommands`) instances under one router. Calling with no arguments automatically displays help. Includes "did you mean?" suggestions for mistyped subcommand names. ```ts import { subcommands, command, run, string, number, option, positional } from 'cmd-ts'; const add = command({ name: 'add', args: { a: positional({ type: number }), b: positional({ type: number }) }, handler: ({ a, b }) => console.log(a + b), }); const echo = command({ name: 'echo', args: { text: option({ long: 'text', type: string }) }, handler: ({ text }) => console.log(text), }); const cli = subcommands({ name: 'mycli', version: '2.0.0', description: 'My awesome CLI', cmds: { add, echo }, examples: [ { description: 'Add two numbers', command: 'mycli add 3 4' }, { description: 'Echo text', command: 'mycli echo --text hello' }, ], }); // node cli.js add 3 4 → 7 // node cli.js → shows help run(cli, process.argv.slice(2)); ``` ``` -------------------------------- ### command — define a CLI command Source: https://context7.com/schniz/cmd-ts/llms.txt Creates a runnable command from a map of argument parsers and a typed handler function. Arguments are automatically inferred as properties of the handler's parameters. ```APIDOC ## command — define a CLI command Creates a runnable command from a map of argument parsers and a typed handler function. Every key in `args` becomes a typed property in the handler's parameter, inferred automatically. ```ts import { command, run, string, number, positional, option, flag, boolean } from 'cmd-ts'; const greet = command({ name: 'greet', version: '1.0.0', description: 'Greet someone by name', args: { name: positional({ type: string, displayName: 'name' }), times: option({ long: 'times', short: 't', type: number, description: 'How many times to greet', defaultValue: () => 1, defaultValueIsSerializable: true, }), shout: flag({ long: 'shout', short: 's', description: 'UPPERCASE output' }), }, examples: [ { description: 'Greet Alice', command: 'greet Alice --times 3' }, { description: 'Shout at Bob', command: 'greet Bob --shout' }, ], handler: ({ name, times, shout }) => { const msg = `Hello, ${name}!`; for (let i = 0; i < times; i++) { console.log(shout ? msg.toUpperCase() : msg); } }, }); // node greet.js Alice --times 2 // → Hello, Alice! // → Hello, Alice! run(greet, process.argv.slice(2)); ``` ``` -------------------------------- ### Customize Vercel Help Formatter Source: https://context7.com/schniz/cmd-ts/llms.txt Customize the Vercel formatter by using createVercelFormatter and passing configuration options like cliName and logo. This allows for branding and personalization of the help output. ```typescript setDefaultHelpFormatter(createVercelFormatter({ cliName: 'My Awesome CLI', logo: '⚡', })); ``` -------------------------------- ### ExistingPath Source: https://github.com/schniz/cmd-ts/blob/main/docs/batteries_file_system.md Resolves into a path that exists. Fails if the path does not exist. Relative paths are expanded using the current working directory. ```APIDOC ## ExistingPath ### Description Resolves into a path that exists. Fails if the path does not exist. If a relative path is provided (`../file`), it will expand by using the current working directory. ### Usage ```typescript import { ExistingPath } from 'cmd-ts/batteries/fs'; ``` ``` -------------------------------- ### Import ExistingPath Type Source: https://github.com/schniz/cmd-ts/blob/main/docs/batteries_file_system.md Use ExistingPath to ensure a provided path exists. It resolves relative paths using the current working directory. ```typescript import { ExistingPath } from 'cmd-ts/batteries/fs'; ``` -------------------------------- ### Define and Run Nested Subcommands Source: https://github.com/schniz/cmd-ts/blob/main/docs/parsers/subcommands.md Use `subcommands` to create a parent command that can execute other commands or nested subcommand structures. Import `command`, `subcommands`, and `run` from `cmd-ts`. Define individual commands, group them using `subcommands`, and then run the top-level subcommand structure with `run`. ```typescript import { command, subcommands, run } from 'cmd-ts'; const cmd1 = command({ name: 'cmd1', args: {}, handler: () => console.log('Running cmd1') }); const cmd2 = command({ name: 'cmd2', args: {}, handler: () => console.log('Running cmd2') }); const subcmd1 = subcommands({ name: 'my subcmd1', cmds: { cmd1, cmd2 }, }); const nestingSubcommands = subcommands({ name: 'nesting subcommands', cmds: { subcmd1 }, }); run(nestingSubcommands, process.argv.slice(2)); ``` -------------------------------- ### Import Url Type from cmd-ts/batteries/url Source: https://github.com/schniz/cmd-ts/blob/main/docs/batteries_url.md Imports the Url type for general URL parsing. Fails if the URL lacks a host or protocol. ```typescript import { Url } from 'cmd-ts/batteries/url'; ``` -------------------------------- ### Compose multiple commands with subcommands Source: https://context7.com/schniz/cmd-ts/llms.txt Use `subcommands` to group multiple `command` instances under a single router. This allows for nested command structures and provides help messages and suggestions for mistyped subcommands. ```typescript import { subcommands, command, run, string, number, option, positional } from 'cmd-ts'; const add = command({ name: 'add', args: { a: positional({ type: number }), b: positional({ type: number }) }, handler: ({ a, b }) => console.log(a + b), }); const echo = command({ name: 'echo', args: { text: option({ long: 'text', type: string }) }, handler: ({ text }) => console.log(text), }); const cli = subcommands({ name: 'mycli', version: '2.0.0', description: 'My awesome CLI', cmds: { add, echo }, examples: [ { description: 'Add two numbers', command: 'mycli add 3 4' }, { description: 'Echo text', command: 'mycli echo --text hello' }, ], }); // node cli.js add 3 4 → 7 // node cli.js → shows help run(cli, process.argv.slice(2)); ``` -------------------------------- ### Url Type Source: https://github.com/schniz/cmd-ts/blob/main/docs/batteries_url.md The `Url` type from `cmd-ts/batteries/url` resolves into a `URL` class. It requires a `host` and `protocol` to be present, otherwise it fails. ```APIDOC ## Url Type ### Description Resolves into a `URL` class. Fails if there is no `host` or `protocol`. ### Usage ```typescript import { Url } from 'cmd-ts/batteries/url'; ``` ``` -------------------------------- ### Execute commands with different runner utilities Source: https://context7.com/schniz/cmd-ts/llms.txt cmd-ts offers four runner utilities: `run` (exits on error), `runSafely` (returns a Result), `dryRun` (returns error message as string), and `parse` (returns parsed arguments without handler invocation). ```typescript import { command, run, runSafely, dryRun, parse, string, positional } from 'cmd-ts'; const cmd = command({ name: 'hello', args: { who: positional({ type: string, displayName: 'who' }) }, handler: ({ who }) => `Hello, ${who}!`, }); // 1. run: exits the process on error run(cmd, ['World']); // → handler receives { who: 'World' } // 2. runSafely: returns Result, no process.exit const result = await runSafely(cmd, ['World']); if (result._tag === 'Right') console.log(result.value); // 'Hello, World!' // 3. dryRun: returns error message as a string, not an Exit object const dry = await dryRun(cmd, []); if (dry._tag === 'Left') console.error(dry.error); // formatted error string // 4. parse: returns parsed args without running the handler const parsed = await parse(cmd, ['Alice']); // parsed is a ParsingResult<{ who: string }> ``` -------------------------------- ### Define Multiple String Options with Dynamic Defaults Source: https://github.com/schniz/cmd-ts/blob/main/docs/parsers/options.md Parses multiple string options and provides a dynamic default value using `onMissing` if no options are provided. This is useful for scenarios like specifying multiple files to include in a build process, with an auto-discovery fallback. ```typescript import { command, multioption } from 'cmd-ts'; import type { Type } from 'cmd-ts'; const stringArray: Type = { async from(strings) { return strings; }, displayName: 'string', }; const includes = multioption({ type: stringArray, long: 'include', short: 'i', description: 'Files to include', onMissing: async () => { // Auto-discover files when none specified const files = await glob('src/**/*.ts'); return files; }, }); const cmd = command({ name: 'build', args: { includes }, handler: ({ includes }) => { console.log(`Processing files: ${includes.join(', ')}`); }, }); ``` -------------------------------- ### Custom ConfigFile Type with onMissing Source: https://github.com/schniz/cmd-ts/blob/main/docs/custom_types.md Defines a custom `ConfigFile` type that dynamically resolves configuration. It attempts to load a config file from standard locations if not provided, otherwise returns a default configuration object. This type is useful for encapsulating configuration loading logic. ```typescript const ConfigFile: Type = { async from(str) { if (!fs.existsSync(str)) { throw new Error(`Config file not found: ${str}`); } return JSON.parse(fs.readFileSync(str, 'utf8')); }, displayName: 'config-file', async onMissing() { // Look for config in standard locations when not provided const candidates = [ './config.json', path.join(os.homedir(), '.myapp', 'config.json'), '/etc/myapp/config.json' ]; for (const candidate of candidates) { if (fs.existsSync(candidate)) { console.log(`Using config from: ${candidate}`); return JSON.parse(fs.readFileSync(candidate, 'utf8')); } } // Return default config if none found return { debug: false, verbose: false }; }, }; ``` -------------------------------- ### Import HttpUrl Type from cmd-ts/batteries/url Source: https://github.com/schniz/cmd-ts/blob/main/docs/batteries_url.md Imports the HttpUrl type for parsing HTTP or HTTPS URLs. Fails if the protocol is not http or https. ```typescript import { HttpUrl } from 'cmd-ts/batteries/url'; ``` -------------------------------- ### Dynamic Defaults for Flags with `onMissing` Source: https://github.com/schniz/cmd-ts/blob/main/docs/parsers/flags.md Illustrates using the `onMissing` callback to provide dynamic default values for flags when they are not provided. This can involve checking environment variables or asynchronously loading configuration. ```typescript import { command, flag } from 'cmd-ts'; const verboseFlag = flag({ long: 'verbose', short: 'v', description: 'Enable verbose output', onMissing: () => { // Check environment variable as fallback return process.env.NODE_ENV === 'development'; }, }); const debugFlag = flag({ long: 'debug', short: 'd', description: 'Enable debug mode', onMissing: async () => { // Async example: check config file or make API call const config = await loadConfig(); return config.debug || false; }, }); const cmd = command({ name: 'my app', args: { verbose: verboseFlag, debug: debugFlag, }, handler: ({ verbose, debug }) => { console.log(`Verbose: ${verbose}, Debug: ${debug}`); }, }); ``` -------------------------------- ### Dynamic Defaults for Optional Options Source: https://github.com/schniz/cmd-ts/blob/main/docs/parsers/options.md Demonstrates using the `onMissing` callback to dynamically generate a default value for an optional option, such as prompting the user for input. This is useful when an option is not provided and a fallback value needs to be determined at runtime. ```typescript import { command, option, string } from './src'; import { createInterface } from 'readline/promises'; const name = option({ type: string, long: 'name', short: 'n', description: 'Your name for the greeting', onMissing: async () => { const rl = createInterface({ input: process.stdin, output: process.stdout, }); try { const answer = await rl.question("What's your name? "); return answer.trim() || 'Anonymous'; } finally { rl.close(); } }, }); const cmd = command({ name: 'greeting', args: { name }, handler: ({ name }) => { console.log(`Hello, ${name}!`); }, }); ``` -------------------------------- ### Repeatable Named Options Source: https://context7.com/schniz/cmd-ts/llms.txt Accepts the same named option multiple times, decoding from `string[]`. Use with the `array` type helper. ```typescript import { command, run, multioption, array, string } from 'cmd-ts'; const cmd = command({ name: 'install', args: { packages: multioption({ long: 'package', short: 'p', type: array(string), description: 'Package(s) to install', defaultValue: () => [], }), }, handler: ({ packages }) => { if (packages.length === 0) { console.log('Nothing to install'); return; } console.log('Installing:', packages.join(', ')); }, }); // node install.js -p react -p typescript --package vite // → Installing: react, typescript, vite run(cmd, process.argv.slice(2)); ``` -------------------------------- ### HttpUrl Type Source: https://github.com/schniz/cmd-ts/blob/main/docs/batteries_url.md The `HttpUrl` type from `cmd-ts/batteries/url` resolves into a `URL` class. It specifically fails if the protocol is not `http` or `https`. ```APIDOC ## HttpUrl Type ### Description Resolves into a `URL` class. Fails if the protocol is not `http` or `https`. ### Usage ```typescript import { HttpUrl } from 'cmd-ts/batteries/url'; ``` ``` -------------------------------- ### Named Options with Environment Fallback Source: https://context7.com/schniz/cmd-ts/llms.txt Reads named options like `--long value` or `-s value`. Supports environment variable fallback and interactive prompts for missing required options. ```typescript import { command, run, option, string, number } from 'cmd-ts'; const cmd = command({ name: 'server', args: { host: option({ long: 'host', short: 'h', type: string, env: 'SERVER_HOST', defaultValue: () => 'localhost', defaultValueIsSerializable: true, description: 'Hostname to bind', }), port: option({ long: 'port', short: 'p', type: number, env: 'PORT', description: 'Port to listen on', onMissing: async () => { // Could interactively prompt user here throw new Error('--port is required'); }, }), }, handler: ({ host, port }) => console.log(`Listening on ${host}:${port}`), }); // PORT=8080 node server.js → Listening on localhost:8080 // node server.js --port 3000 → Listening on localhost:3000 // node server.js -h 0.0.0.0 -p 80 → Listening on 0.0.0.0:80 run(cmd, process.argv.slice(2)); ``` -------------------------------- ### Defining a Custom Type for File Streams with cmd-ts Source: https://github.com/schniz/cmd-ts/blob/main/README.md Illustrates how to define a custom type `ReadStream` that decodes a string into a file read stream, including custom error handling for non-existent files. ```typescript // ReadStream.ts import { Type } from 'cmd-ts'; import fs from 'fs'; // Type reads as "A type from `string` to `Stream`" const ReadStream: Type = { async from(str) { if (!fs.existsSync(str)) { // Here is our error handling! throw new Error('File not found'); } return fs.createReadStream(str); }, }; ``` -------------------------------- ### Create Custom Type Decoders with `Type` and `extendType` Source: https://context7.com/schniz/cmd-ts/llms.txt Define custom argument types by implementing the `Type` interface. Use `extendType` to compose existing types with custom validation logic, such as checking for file existence and type. ```typescript import { Type, extendType, string, command, run, positional } from 'cmd-ts'; import fs from 'fs'; // Custom type: string → resolved absolute path that must exist const ExistingFile: Type = extendType(string, { displayName: 'file', description: 'An existing file path', async from(str) { const resolved = require('path').resolve(str); if (!fs.existsSync(resolved)) throw new Error(`File not found: ${resolved}`); const stat = fs.statSync(resolved); if (!stat.isFile()) throw new Error(`Not a file: ${resolved}`); return resolved; }, }); const cmd = command({ name: 'wc', args: { file: positional({ type: ExistingFile, displayName: 'file' }) }, handler: ({ file }) => { const content = fs.readFileSync(file, 'utf8'); console.log(`Lines: ${content.split('\n').length}, File: ${file}`); }, }); // node wc.js ./README.md → Lines: 127, File: /absolute/path/README.md // node wc.js ./nope.txt → error: File not found: /absolute/path/nope.txt run(cmd, process.argv.slice(2)); ``` -------------------------------- ### Using Custom File Stream Type in cmd-ts Command Source: https://github.com/schniz/cmd-ts/blob/main/README.md Demonstrates using the custom `ReadStream` type as a positional argument in a cmd-ts command, allowing direct handling of file streams. ```typescript // my-app.ts import { command, run, positional } from 'cmd-ts'; const app = command({ // name: ..., args: { stream: positional({ type: ReadStream, displayName: 'file' }), }, handler: ({ stream }) => stream.pipe(process.stdout), }); // parse arguments run(app, process.argv.slice(2)); ``` -------------------------------- ### Capture Remaining Raw Tokens with `rest` Source: https://context7.com/schniz/cmd-ts/llms.txt The `rest` parser captures all unconsumed arguments, including flags and options, as a raw `string[]`. This is useful for creating wrapper CLIs that forward arguments verbatim to another process. ```typescript import { command, run, rest, flag } from 'cmd-ts'; const cmd = command({ name: 'docker-run', args: { interactive: flag({ long: 'interactive', short: 'i' }), dockerArgs: rest({ displayName: 'docker-args', description: 'Arguments forwarded to docker run' }), }, handler: ({ interactive, dockerArgs }) => { const prefix = interactive ? ['--interactive'] : []; console.log('docker run', [...prefix, ...dockerArgs].join(' ')); }, }); // node docker-run.js -i nginx --port 80:80 // → docker run --interactive nginx --port 80:80 run(cmd, process.argv.slice(2)); ``` -------------------------------- ### Capture Remaining Positional Arguments with `restPositionals` Source: https://context7.com/schniz/cmd-ts/llms.txt Use `restPositionals` as the last item in `args` to capture all subsequent positional arguments. Each captured argument is decoded using the specified `Type`. This behaves similarly to the JavaScript `...rest` syntax. ```typescript import { command, run, restPositionals, number, option, string } from 'cmd-ts'; const cmd = command({ name: 'sum', args: { label: option({ long: 'label', type: string, defaultValue: () => 'Total', defaultValueIsSerializable: true }), numbers: restPositionals({ type: number, displayName: 'num', description: 'Numbers to sum' }), }, handler: ({ label, numbers }) => { const total = numbers.reduce((acc, n) => acc + n, 0); console.log(`${label}: ${total}`); }, }); // node sum.js 1 2 3 4 5 → Total: 15 // node sum.js --label Sum 10 20 → Sum: 30 run(cmd, process.argv.slice(2)); ``` -------------------------------- ### Positional Arguments Source: https://context7.com/schniz/cmd-ts/llms.txt Reads one or more non-flag arguments from the command line. Use `number` or `string` types as needed. Default values can be provided. ```typescript import { command, run, positional, number, string } from 'cmd-ts'; const cmd = command({ name: 'calc', args: { x: positional({ type: number, displayName: 'x', description: 'First operand' }), y: positional({ type: number, displayName: 'y', description: 'Second operand' }), label: positional({ type: string, displayName: 'label', defaultValue: () => 'result', defaultValueIsSerializable: true, }), }, handler: ({ x, y, label }) => console.log(`${label}: ${x + y}`), }); // node calc.js 3 5 → result: 8 // node calc.js 3 5 sum → sum: 8 // node calc.js → error: No value provided for x run(cmd, process.argv.slice(2)); ``` -------------------------------- ### Union Type: Try Multiple Types in Order Source: https://context7.com/schniz/cmd-ts/llms.txt Use `union` to attempt parsing an argument with multiple types sequentially. It returns the first successful parse or a combined error message if all types fail. Custom error aggregation is possible. ```typescript import { command, run, option, union, number, string } from 'cmd-ts'; const NumberOrString = union([number, string]); const cmd = command({ name: 'process', args: { value: option({ long: 'value', type: union([number, string], { combineErrors: (errs) => `Not a number or string: ${errs.join('; ')}`, }), description: 'A number or a string value', }), }, handler: ({ value }) => { if (typeof value === 'number') console.log(`Got number: ${value * 2}`); else console.log(`Got string: ${value.toUpperCase()}`); }, }); // node process.js --value 42 → Got number: 84 // node process.js --value hello → Got string: HELLO run(cmd, process.argv.slice(2)); ``` -------------------------------- ### Define a Boolean Flag with `flag` Parser Source: https://github.com/schniz/cmd-ts/blob/main/docs/parsers/flags.md This snippet demonstrates how to define a required boolean flag using the `flag` parser. It specifies the type, long form key, and short form key. ```typescript import { command, boolean, flag } from 'cmd-ts'; const myFlag = flag({ type: boolean, long: 'my-flag', short: 'f', }); const cmd = command({ name: 'my flag', args: { myFlag }, }); ``` -------------------------------- ### Fetch All Remaining Positional Arguments Source: https://github.com/schniz/cmd-ts/blob/main/docs/parsers/positionals.md Use the `restPositionals` parser to fetch all remaining positional arguments. This parser consumes all subsequent positional arguments, so no further positional parsers can be used after it. It requires a type for decoding each argument. ```typescript import { restPositionals } from "cmd-ts/batteries/argsinfer" restPositionals({ displayName: "files", type: string, description: "The files to process" }) ``` -------------------------------- ### Fetch a Single Positional Argument Source: https://github.com/schniz/cmd-ts/blob/main/docs/parsers/positionals.md Use the `positional` parser to fetch a single positional argument. This parser requires a display name and a type for decoding. It will fail if the user input cannot be decoded. ```typescript import { positional } from "cmd-ts/batteries/argsinfer" positional({ displayName: "name", type: string, description: "The name to greet" }) ``` -------------------------------- ### URL Batteries: Url, HttpUrl Source: https://context7.com/schniz/cmd-ts/llms.txt Decode strings into validated `URL` objects. `HttpUrl` specifically enforces HTTP or HTTPS protocols, rejecting others at parse time. `Url` accepts any valid URL format. ```typescript import { command, run, option } from 'cmd-ts'; import { Url, HttpUrl } from 'cmd-ts/batteries/url'; const cmd = command({ name: 'fetch', args: { endpoint: option({ long: 'url', type: HttpUrl, description: 'HTTP/HTTPS endpoint URL' }), origin: option({ long: 'origin', type: Url, description: 'Any valid URL' }), }, handler: ({ endpoint, origin }) => { console.log('Endpoint host:', endpoint.hostname); console.log('Origin: ', origin.href); }, }); // node fetch.js --url https://api.example.com/v1 --origin ws://socket.io // node fetch.js --url ftp://bad.url → error: Only allowed http and https URLs run(cmd, process.argv.slice(2)); ``` -------------------------------- ### Defining a Custom ReadStream Type in cmd-ts Source: https://github.com/schniz/cmd-ts/blob/main/docs/custom_types.md This snippet defines a custom `Type` for cmd-ts. It handles converting a string file path into a readable stream, including error handling for non-existent files. ```typescript import { Type } from 'cmd-ts'; import fs from 'fs'; // Type reads as "A type from `string` to `Stream`" const ReadStream: Type = { async from(str) { if (!fs.existsSync(str)) { // Here is our error handling! throw new Error('File not found'); } return fs.createReadStream(str); }, }; ``` -------------------------------- ### Define a Single Number Option Source: https://github.com/schniz/cmd-ts/blob/main/docs/parsers/options.md Defines a required number option with a long and short form key. This is useful for options that expect a numerical value. ```typescript import { command, number, option } from 'cmd-ts'; const myNumber = option({ type: number, long: 'my-number', short: 'n', }); const cmd = command({ name: 'my number', args: { myNumber }, }); ``` -------------------------------- ### Repeatable Boolean Flags (Verbosity) Source: https://context7.com/schniz/cmd-ts/llms.txt Accepts a boolean flag multiple times, useful for counting verbosity levels. The type decodes from `boolean[]` and is processed to count occurrences. ```typescript import { command, run, multiflag } from 'cmd-ts'; const cmd = command({ name: 'ping', args: { verbose: multiflag({ long: 'verbose', short: 'v', type: { from: (bools: boolean[]) => Promise.resolve(bools.filter(Boolean).length), displayName: 'verbosity', description: 'Increase verbosity (repeat for more)', }, }), }, handler: ({ verbose }) => console.log(`Verbosity level: ${verbose}`), }); // node ping.js -v -v -v → Verbosity level: 3 // node ping.js → Verbosity level: 0 run(cmd, process.argv.slice(2)); ``` -------------------------------- ### Create Enum-like Types with `oneOf` Source: https://context7.com/schniz/cmd-ts/llms.txt Use `oneOf` to create a type that accepts only a specific set of literal string values, effectively creating an enum or union-of-literals type for arguments. This is useful for options like log levels or environments. ```typescript import { command, run, option, oneOf } from 'cmd-ts'; const LogLevel = oneOf(['debug', 'info', 'warn', 'error'] as const); const cmd = command({ name: 'logger', args: { level: option({ long: 'level', type: LogLevel, env: 'LOG_LEVEL', description: 'Log level to use', defaultValue: () => 'info' as const, defaultValueIsSerializable: true, }), }, handler: ({ level }) => console.log(`Log level set to: ${level}`), }); // node logger.js --level debug → Log level set to: debug // node logger.js --level verbose → error: Invalid value 'verbose'. Expected one of: 'debug', 'info', 'warn', 'error' run(cmd, process.argv.slice(2)); ``` -------------------------------- ### Type Modifiers: Optional and Array Source: https://context7.com/schniz/cmd-ts/llms.txt Use `optional(t)` to make a type accept `undefined` when no value is provided. Use `array(t)` to parse multiple values for an option, typically with `multioption`. ```typescript import { command, run, option, positional, multioption, optional, array, number, string } from 'cmd-ts'; const cmd = command({ name: 'example', args: { maybePort: option({ long: 'port', type: optional(number), description: 'Optional port' }), tags: multioption({ long: 'tag', type: array(string), description: 'Tags (repeat)' }), }, handler: ({ maybePort, tags }) => { console.log('port:', maybePort ?? 'not set'); console.log('tags:', tags); }, }); // node example.js --tag a --tag b // → port: not set // → tags: [ 'a', 'b' ] run(cmd, process.argv.slice(2)); ``` -------------------------------- ### Boolean Flags Source: https://context7.com/schniz/cmd-ts/llms.txt Reads boolean flags, defaulting to `false` if absent and `true` if present. Supports short forms and environment variables. ```typescript import { command, run, flag, option, string } from 'cmd-ts'; const cmd = command({ name: 'deploy', args: { verbose: flag({ long: 'verbose', short: 'v', description: 'Verbose output' }), dryRun: flag({ long: 'dry-run', short: 'd', description: 'Do not apply changes' }), env: option({ long: 'env', type: string, env: 'DEPLOY_ENV', defaultValue: () => 'production', defaultValueIsSerializable: true }), }, handler: ({ verbose, dryRun, env }) => { if (verbose) console.log(`[verbose] deploying to ${env}`); if (dryRun) console.log('Dry-run mode — no changes applied'); else console.log(`Deployed to ${env}`); }, }); // node deploy.js -vd --env staging // → [verbose] deploying to staging // → Dry-run mode — no changes applied run(cmd, process.argv.slice(2)); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.