### Install Dependencies Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/quick-start.mdx After generating the application, navigate to the directory and install the declared dependencies. Use --ignore-scripts if auto-complete is enabled. ```bash npm install --ignore-scripts ``` -------------------------------- ### Install Dependencies with Bun Source: https://github.com/bloomberg/stricli/blob/main/examples/bun/README.md Use this command to install all project dependencies managed by Bun. Ensure Bun is installed on your system. ```bash bun install ``` -------------------------------- ### Start Local Development Server Source: https://github.com/bloomberg/stricli/blob/main/docs/README.md Starts a local development server. Changes are reflected live without a server restart. ```bash $ nx start ``` -------------------------------- ### Configure Version Information and Update Warnings Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/configuration/version-information.mdx This example demonstrates how to configure Stricli to display the current version and to check for and warn about update availability. It includes static current version, a function to get the latest version, and an upgrade command. ```typescript import { Stricli } from "stricli"; const stricli = new Stricli({ versionInfo: { currentVersion: "1.0.0", getLatestVersion: async (currentVersion) => { // Replace with actual logic to fetch the latest version const response = await fetch("https://api.example.com/latest-version"); const data = await response.json(); return data.version; }, upgradeCommand: "npm install -g my-cli-package@latest", }, }); stricli.run(); ``` -------------------------------- ### Help Text Output Example Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/command-routing/route-maps.mdx This demonstrates how the 'brief' and 'fullDescription' fields are rendered in the application's help text. ```shell run --help // output-start USAGE run subcommand1|subcommand2 run --help This is the full description of the routes. It should include all of the necessary details about the subcommands within. It will only be displayed to the user in the help text for this route. // output-end ``` -------------------------------- ### Application Setup Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/infer-empty-flag.txt This sets up the Stricli application with the defined command spec. ```typescript import { buildApplication } from "@stricli/core"; import root from "./spec.ts"; export default buildApplication(root, { name: "run" }); ``` -------------------------------- ### Install Dependencies with npm Source: https://github.com/bloomberg/stricli/blob/main/examples/node/README.md Use this command to install project dependencies. ```bash npm install ``` -------------------------------- ### Install Stricli Core Package Source: https://github.com/bloomberg/stricli/blob/main/README.md Install the core Stricli framework as a production dependency using npm. ```bash npm i --save-prod @stricli/core ``` -------------------------------- ### Manage Shell Autocomplete Installation Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/shell-autocomplete.mdx Use this command to install or uninstall shell auto-completion for a target command. Currently, only bash is supported. ```bash USAGE @stricli/auto-complete install [--shell bash] targetCmd autcCmd @stricli/auto-complete uninstall [--shell bash] targetCmd @stricli/auto-complete --help @stricli/auto-complete --version Manage auto-complete command installations for shells FLAGS -h --help Print this help information and exit -v --version Print version information and exit COMMANDS install Installs target command with autocompletion for a given shell type uninstall Uninstalls target command for a given shell type ``` -------------------------------- ### Run Single Command App Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/quick-start.mdx Execute the single-command Stricli application with provided arguments and flags. This example demonstrates running the app with a name and a count. ```bash dist/cli.js World --count 3 ``` ```text Hello World! Hello World! Hello World! ``` -------------------------------- ### Define Command for Version Check Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/configuration/examples/version-warning.txt Define a command using `buildCommand` that can be used to check the version. This example sets up a basic command with documentation. ```typescript import { buildCommand } from "@stricli/core"; export default buildCommand({ loader: () => import("./impl"), parameters: { flags: {}, }, docs: { brief: "Example for live playground to print version warning", }, }); ``` -------------------------------- ### Run stricli CLI with Deno Source: https://github.com/bloomberg/stricli/blob/main/examples/deno/README.md Execute the stricli CLI application using Deno. Ensure you have Deno v2 installed and grant necessary permissions for environment variable access. ```bash deno run --allow-env src/bin/cli.ts ``` -------------------------------- ### Command Implementation Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/command-routing/examples/help-text-documentation.txt The implementation of a Stricli command receives parsed flags as an argument. This example logs the received flags. ```typescript export default async function(flags: { alpha?: boolean, bravo?: boolean, charlie?: boolean, delta?: string }) { console.log(flags); } ``` -------------------------------- ### Test Command Implementation Exception Handling Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/testing.mdx Tests should catch exceptions thrown by implementation functions. This example demonstrates how to assert that a specific error is thrown when dividing by zero. ```typescript import func from "./impl"; describe("divide command", () => { it("dividing by zero throws an error", async () => { const context = buildContextForTest(); await func.call(context, {}, 1, 0).then( () => { throw new Error("Expected ({}, 1, 0) to throw an error"); }, // highlight-start (exc) => { expect(exc instanceof Error); expect(exc.message).includes("Cannot divide by zero"); }, // highlight-end ); }); }); ``` -------------------------------- ### Define a Stricli Command with Help Text Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/command-routing/examples/help-text-documentation.txt Use `buildCommand` to define a command, including its brief and full descriptions for help text, and custom usage examples. Define parameters like boolean flags and parsed string flags. ```typescript import { buildCommand } from "@stricli/core"; export default buildCommand({ docs: { brief: "This is a brief description of the command", fullDescription: [ "This is the full description of the command.", "It should include all of the necessary details about the behavior.", "It will only be displayed to the user in the help text for this command.", ].join("\n"), customUsage: [ "--a --b", "--c", { input: "--d", brief: "Brief description of this use case" }, ], }, loader: () => import("./impl"), parameters: { flags: { alpha: { kind: "boolean", brief: "Flag that should be passed with bravo", optional: true }, bravo: { kind: "boolean", brief: "Flag that should be passed with alpha", optional: true }, charlie: { kind: "boolean", brief: "Flag that should be passed by itself", optional: true }, delta: { kind: "parsed", parse: String, brief: "Flag that should be passed by itself", optional: true }, }, }, }); ``` -------------------------------- ### Implementation for Bounded Array Argument Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/bounded-array-argument.txt The implementation function receives the array of parsed arguments. This example logs the received IDs. ```typescript export default async function(_: {}, ...ids: number[]) { console.log(`Grouping users with IDs: ${ids.join(", ")}`); } ``` -------------------------------- ### Variadic Default Flag Example Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/flags.mdx Specify an array of default values for variadic flags. Each default value is validated or parsed before being applied. ```typescript import { createCli } from "@bloomberg/stricli"; const cli = createCli({ flags: { items: { type: "string", variadic: true, default: ["a", "b"], }, }, }); const result = cli.parse([]); console.log(result.flags.items); // ["a", "b"] ``` -------------------------------- ### Counter Flag Example Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/flags.mdx Use the `counter` flag type for flags that should increment by 1 for each appearance in the arguments. This is specifically for integer counts. ```typescript import { createCli } from "@bloomberg/stricli"; const cli = createCli({ flags: { count: { type: "counter", }, }, }); const result = cli.parse(["--count", "--count"]); console.log(result.flags.count); // 2 ``` -------------------------------- ### Define Positional Arguments with Placeholders Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/placeholder-argument.txt Define positional arguments for a command, specifying their brief description, parsing function, and a placeholder name. This example shows how to define 'src' and 'dest' as string arguments. ```typescript import { buildCommand } from "@stricli/core"; export default buildCommand({ loader: () => import("./impl"), parameters: { positional: { kind: "tuple", parameters: [ { brief: "Source file", parse: String, placeholder: "src", }, { brief: "Destination path", parse: String, placeholder: "dest", }, ], }, }, docs: { brief: "Example for live playground with positional arguments labeled by placeholders", }, }); ``` -------------------------------- ### Positional Arguments with Tuples Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/positional.mdx When function arguments are individually specified, Stricli infers their types. This example demonstrates defining positional arguments as a tuple. ```typescript import { command } from "@stricli/stricli"; command( "my-command ", (flags, first: string, second: number, third: boolean) => { console.log(first, second, third); } ); ``` -------------------------------- ### Default Flag Example Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/flags.mdx Provide a default string value for any flag using the `default` property. For parsed types, this string is parsed; for enums, it's type-checked. ```typescript import { createCli } from "@bloomberg/stricli"; const cli = createCli({ flags: { level: { type: "number", default: "10", }, }, }); const result = cli.parse([]); console.log(result.flags.level); // 10 ``` -------------------------------- ### Variadic Flag Example Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/flags.mdx Configure a flag as variadic when its type is an array. Multiple instances of the flag are collected into a single array. You can also specify a separator string to split inputs. ```typescript import { createCli } from "@bloomberg/stricli"; const cli = createCli({ flags: { tags: { type: "string", variadic: ",", }, }, }); const result = cli.parse(["--tags", "a,b,c"]); console.log(result.flags.tags); // ["a", "b", "c"] ``` -------------------------------- ### Optional Flag Example Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/flags.mdx Mark a flag as optional by setting `optional: true` in its configuration. This is enforced by TypeScript and allows the flag's value to be undefined. ```typescript import { createCli } from "@bloomberg/stricli"; const cli = createCli({ flags: { name: { type: "string", optional: true, }, }, }); const result = cli.parse([]); console.log(result.flags.name); // undefined ``` -------------------------------- ### Enum Flag Example Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/flags.mdx Shows how to define an 'enum' flag type in Stricli, restricting flag values to a predefined set of string literals. This is useful for type safety and auto-completion. ```typescript import { createCli } from "@stricli/cli"; type Color = "red" | "green" | "blue"; const cli = createCli({ name: "my-cli", version: "1.0.0", parameters: { color: { type: "enum", description: "Choose a color", options: ["red", "green", "blue"], }, }, }); cli.run(); ``` -------------------------------- ### Parsed Flag Example Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/flags.mdx Demonstrates how to use a 'parsed' flag type in Stricli, requiring a custom parsing function to convert string input to a specific type. ```typescript import { createCli } from "@stricli/cli"; const cli = createCli({ name: "my-cli", version: "1.0.0", parameters: { allowEdits: { type: "parsed", description: "Allow edits to the file", // Example: parse string to boolean parser: (value) => value === "true" || value === "1", }, }, }); cli.run(); ``` -------------------------------- ### Implementing Variadic Flag Logic Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/variadic-flag.txt The implementation receives the variadic flag values as an array. You can then process this array as needed, for example, by joining the elements into a string for logging. ```typescript type Flags = { id: number[]; }; export default async function({ id }: Flags) { console.log(`Selected following IDs: ${id.join(", ")}`); } ``` -------------------------------- ### Command Specification with Counter Flag (TypeScript) Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/counter-flag.txt Configures a command using Stricli's buildCommand, specifying a 'verbose' counter flag and its alias 'v'. It also includes custom usage examples for the flag. ```typescript import { buildCommand } from "@stricli/core"; interface Flags { verbose: number; } export default buildCommand({ loader: () => import("./impl"), parameters: { flags: { verbose: { kind: "counter", brief: "Controls how verbose logging should be", }, }, aliases: { v: "verbose" }, }, docs: { brief: "Example for live playground with counter flag", customUsage: [ "--verbose", "-v", "-vv", "-vv -v", ], }, }); ``` -------------------------------- ### Hidden Flag Example Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/flags.mdx Mark flags as hidden using `hidden: true` to exclude them from default help text and auto-complete. These are typically for advanced or debug features. Use `--helpAll` to see all flags. ```typescript import { createCli } from "@bloomberg/stricli"; const cli = createCli({ flags: { debug: { type: "boolean", hidden: true, }, }, }); const result = cli.parse([]); console.log(result.flags.debug); // false ``` -------------------------------- ### Build Stricli Packages with Nx Source: https://github.com/bloomberg/stricli/blob/main/README.md Initialize the repository with npm ci and then use Nx to build all Stricli packages concurrently. ```bash npm ci npx nx@latest run-many -t build ``` -------------------------------- ### Build Website for Deployment Source: https://github.com/bloomberg/stricli/blob/main/docs/README.md Generates static website content into the 'build' directory, ready for hosting. ```bash $ nx build ``` -------------------------------- ### Build Application with Command Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/array-argument.txt Build the application by providing the root command specification and application name. This sets up the entry point for the command-line interface. ```typescript import { buildApplication } from "@stricli/core"; import root from "./spec.ts"; export default buildApplication(root, { name: "run" }); ``` -------------------------------- ### Test Multi-Command App Output Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/quick-start.mdx Verify the generated multi-command application by running the compiled bin script with the --help flag. This shows the available commands and flags. ```bash dist/cli.js --help ``` ```text USAGE my-app subdir my-app nested foo|bar ... my-app --help my-app --version Stricli command line application FLAGS -h --help Print this help information and exit -v --version Print version information and exit COMMANDS subdir Command in subdirectory nested Nested commands ``` ```bash dist/cli.js nested --help ``` ```text USAGE my-app nested foo my-app nested bar my-app nested --help Nested commands FLAGS -h --help Print this help information and exit COMMANDS foo Nested foo command bar Nested bar command ``` -------------------------------- ### Test Single Command App Output Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/quick-start.mdx Verify the generated single-command application by running the compiled bin script with the --help flag. This displays the application's usage and available options. ```bash dist/cli.js --help ``` ```text USAGE my-app --count value arg1 my-app --help my-app --version Stricli command line application FLAGS --count Number of times to say hello -h --help Print this help information and exit -v --version Print version information and exit ARGUMENTS arg1 Your name ``` -------------------------------- ### Command Documentation Options Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/command-routing/commands.mdx Illustrates how to provide documentation for a command, including a mandatory `brief` description and optional `fullDescription` or `customUsage`. The `customUsage` property can be used for advanced input validation scenarios. ```text import { buildCommand } from "@stricli/core"; const command = buildCommand({ brief: "A brief description of the command.", fullDescription: `A more detailed description that can span multiple lines. It provides more context to the user.`, customUsage: { input: "", brief: "Description for the custom usage pattern." }, func: (flags) => { console.log("Command executed!"); } }); export default command; ``` -------------------------------- ### Configure Version Info in Application Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/configuration/examples/version-warning.txt Set up `versionInfo` in your application's configuration to provide current and latest version details. This is useful for implementing version checking and upgrade prompts. ```typescript import { buildApplication } from "@stricli/core"; import root from "./spec.ts"; export default buildApplication(root, { name: "run", // Only modify properties in this configuration object versionInfo: { getCurrentVersion: async () => new Date(+new Date() - 86400000).toISOString().split("T")[0], getLatestVersion: async () => new Date().toISOString().split("T")[0], // upgradeCommand: "Check tomorrow? 😁", }, }); ``` -------------------------------- ### Run Application with Bun Source: https://github.com/bloomberg/stricli/blob/main/examples/bun/README.md Execute the main application script using Bun. This command assumes the script is located at './src/bin/cli.ts'. ```bash bun run ./src/bin/cli.ts ``` -------------------------------- ### Build Stricli Application Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/boolean-flag.txt Build your Stricli application by combining the command specification with the core application builder. This sets up the entry point for your CLI tool. ```typescript import { buildApplication } from "@stricli/core"; import root from "./spec.ts"; export default buildApplication(root, { name: "run" }); ``` -------------------------------- ### Implementation File Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/default-tuple-argument.txt This is the implementation file for the command defined in `spec.ts`. It logs the output path. ```typescript export default async function(_: {}, outputPath: string) { console.log(`Printing file to ${outputPath}`); } ``` -------------------------------- ### Define Route Map with Documentation Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/command-routing/route-maps.mdx Use 'brief' for short help text and 'fullDescription' for detailed help text. 'hideRoute' can be used to exclude specific routes from documentation. ```typescript buildRouteMap({ docs: { brief: "This is a brief description of the routes", fullDescription: [ "This is the full description of the routes.", "It should include all of the necessary details about the subcommands within.", "It will only be displayed to the user in the help text for this route.", ].join("\n"), hideRoute: { secret: true, }, }, ... }); ``` -------------------------------- ### Generate New Stricli App Source: https://github.com/bloomberg/stricli/blob/main/packages/create-app/README.md Run this command to create a new Stricli application using the latest version of the package. ```bash npx @stricli/create-app@latest ``` -------------------------------- ### TypeScript Union Type Example Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/out-of-scope.mdx This TypeScript code defines a union type for flags, which Stricli does not directly support. Manual validation using libraries like Zod is recommended for such cases. ```typescript export default function(flags: { alpha: number } | { beta: number; bravo: number }) { ... ``` -------------------------------- ### Generate New Stricli App Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/quick-start.mdx Use npx to create a new Stricli application. This command initializes a new directory with the necessary boilerplate. ```bash npx @stricli/create-app@latest my-app ``` -------------------------------- ### Generate Single Command App Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/quick-start.mdx Optionally generate a single command application by using the --template single flag during creation. ```bash npx @stricli/create-app@latest --template single ``` -------------------------------- ### Run the CLI with tsx Source: https://github.com/bloomberg/stricli/blob/main/examples/node/README.md Execute the stricli-node CLI application using tsx. ```bash tsx src/bin/cli.ts ``` -------------------------------- ### Infer Empty Flag Example Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/flags.mdx Use `inferEmpty: true` for parsed flag types to infer an empty string `""` when a flag is present without a value. This helps distinguish between `--flag` and `--flag value`. ```typescript import { createCli } from "@bloomberg/stricli"; const cli = createCli({ flags: { message: { type: "string", inferEmpty: true, }, }, }); const result = cli.parse(["--message"]); console.log(result.flags.message); // "" ``` -------------------------------- ### Build Stricli Application Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/default-flag.txt This TypeScript file builds the Stricli application by combining the command specification with the application name. ```typescript /// !app.ts import { buildApplication } from "@stricli/core"; import root from "./spec.ts"; export default buildApplication(root, { name: "run" }); ``` -------------------------------- ### Direct Command Implementation with Func Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/command-routing/commands.mdx Defines a command by directly providing the implementation function using the `func` property. This is an alternative to `loader` when lazy loading is not desired, allowing for co-location of command specification and implementation. ```typescript /// commands.ts const command = buildCommand({ // highlight-next-line func(flags: {}) { console.log("This is the inline function"); }, ... }); ``` -------------------------------- ### Define Implementation Logic Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/default-flag.txt This TypeScript file defines the function that will be executed when the command is run. It accepts flags as an argument and logs the selected line ending. ```typescript /// impl.ts type Flags = { lineEnding: "lf" | "crlf"; }; export default async function({ lineEnding }: Flags) { console.log(`Switched line ending to ${lineEnding}`); } ``` -------------------------------- ### Configure Command with Default Flag Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/default-flag.txt This TypeScript file configures the command using `buildCommand`. It specifies the implementation loader, defines the 'lineEnding' flag as an enum with a default value of 'lf', and provides documentation. ```typescript /// spec.ts import { buildCommand } from "@stricli/core"; export default buildCommand({ loader: () => import("./impl"), parameters: { flags: { lineEnding: { kind: "enum", values: ["lf", "crlf"], brief: "Line ending characters", default: "lf", }, }, }, docs: { brief: "Example for live playground with flag configured with default value", }, }); ``` -------------------------------- ### Test Echo Command with Run Function Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/testing.mdx Tests the 'echo' command by running the application with string inputs and asserting the output. Ensure inputs are formatted as they would be from process.argv. ```typescript import { run } from "@stricli/core"; import { app } from "./app"; describe("echo command", () => { it("prints 'hello' to stdout", async () => { const context = buildContextForTest(); // highlight-next-line await run(app, ["echo", "hello"], context); expect(context.stdout).includes("hello"); }); it("prints 'hello world' to stdout", async () => { const context = buildContextForTest(); // highlight-next-line await run(app, ["echo", "hello", "world"], context); expect(context.stdout).includes("hello world"); }); }); ``` -------------------------------- ### Define Primary and Alternative Routes Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/command-routing/route-maps.mdx Use `buildRouteMap` to define top-level routes. Route names are subject to the scanner case style configuration. ```typescript const primaryCommand = ... const altCommand = ... buildRouteMap({ routes: { primary: primaryCommand, alt: altCommand, }, ... }); ``` -------------------------------- ### Implementation of Positional Argument Logic Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/placeholder-argument.txt This is the implementation file for the command defined in `spec.ts`. It exports an async function that takes parsed arguments and logs the source and destination paths. ```typescript export default async function(_: {}, src: string, dest: string) { console.log(`Copying file from ${src} to ${dest}`); } ``` -------------------------------- ### Empty Implementation for Version Check Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/configuration/examples/version-warning.txt An empty implementation function that logs a message indicating to run with the --version flag instead. This serves as a placeholder for the command's logic. ```typescript export default async function({}: Flags) { console.log("Empty implementation, run with --version instead"); } ``` -------------------------------- ### Logging with CommandContext Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/isolated-context.mdx Demonstrates how to use the CommandContext to write messages to stdout. This context is automatically bound to `this` within command implementations. ```typescript import { CommandContext } from "@stricli/core"; export default function(this: CommandContext) { this.process.stdout.write("Hello, world!\n"); } ``` -------------------------------- ### Building a Command with Stricli Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/examples/command-context-logging.txt Defines a Stricli command using `buildCommand`. It specifies the loader for the implementation and any parameters. This is a standard way to structure commands in Stricli. ```typescript import { buildCommand, type CommandContext } from "@stricli/core"; export default buildCommand({ loader: () => import("./impl"), parameters: {}, docs: { brief: "Example for live playground with homogenous positional parameters", }, }); ``` -------------------------------- ### Test Echo Command by Importing Implementation Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/testing.mdx Tests the 'echo' command's implementation directly by calling the exported function. Inputs are passed as arguments, allowing for direct testing of the function's logic. ```typescript import func from "./impl"; describe("echo command", () => { it("prints 'hello' to stdout", async () => { const context = buildContextForTest(); // highlight-next-line await func.call(context, {}, "hello"); expect(context.stdout).includes("hello"); }); it("prints 'hello world' to stdout", async () => { const context = buildContextForTest(); // highlight-next-line await func.call(context, {}, "hello", "world"); expect(context.stdout).includes("hello world"); }); }); ``` -------------------------------- ### Define Command with Default Tuple Argument Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/default-tuple-argument.txt This snippet shows how to define a command with a positional parameter that accepts a tuple and has a default value. The `parse: String` indicates that each element of the tuple will be parsed as a string, and `default: "output.txt"` sets the default value for the entire tuple. ```typescript import { buildCommand } from "@stricli/core"; export default buildCommand({ loader: () => import("./impl"), parameters: { positional: { kind: "tuple", parameters: [ { brief: "File for intended output", parse: String, default: "output.txt" }, ], }, }, docs: { brief: "Example for live playground with positional parameter configured with default value", }, }); ``` -------------------------------- ### Implement Command Logic with Enum Flag Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/enum-flag.txt Implement the command's logic to accept and use the enum flag. The 'level' parameter will be one of the predefined enum values. ```typescript type Flags = { level: "info" | "warn" | "error"; }; export default async function({ level }: Flags) { console.log(`Set logging level to ${level}`); } ``` -------------------------------- ### Implement Optional Flag Logic Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/optional-flag.txt This TypeScript code defines the implementation for a command that accepts an optional 'limit' flag. It logs the limit if provided, otherwise indicates that no limit is set. ```typescript type Flags = { limit?: number; }; export default async function({ limit }: Flags) { console.log(limit ? `Set limit to ${limit}` : "No limit"); } ``` -------------------------------- ### Implementation of Parsed Flag Handler Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/parsed-flag.txt This is the implementation file that the command loader points to. It defines the function that will be executed with the parsed flag values. ```typescript type Flags = { item: string; price: number; }; export default async function({ item, price }: Flags) { console.log(`${item}s cost $${price.toFixed(2)}`); } ``` -------------------------------- ### Implement Array Argument Logic Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/array-argument.txt Implement the command logic to process an array of string arguments. The `paths` parameter will receive all provided string values as an array. ```typescript export default async function(_: {}, ...paths: string[]) { console.log(`Deleting files at ${paths.join(", ")}`); } ``` -------------------------------- ### Configure Scanner Case Style Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/configuration/input-scanning.mdx Adjust the `caseStyle` property to control how route, command, and flag names are matched. Use `allow-kebab-for-camel` to accept kebab-case versions of camelCase names. ```typescript import { StricliConfig } from "@stricli/config"; const config: StricliConfig = { scanner: { caseStyle: "allow-kebab-for-camel", }, }; ``` -------------------------------- ### Implementation of Optional Tuple Argument Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/optional-tuple-argument.txt This is the implementation logic for the command defined in `spec.ts`. It handles the optional last name parameter. ```typescript export default async function(_: {}, firstName: string, lastName?: string) { if (lastName) { console.log(`Hello ${firstName} ${lastName}!`); } else { console.log(`Hello ${firstName}!`); } } ``` -------------------------------- ### Test Add Command Error Handling with Run Function Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/testing.mdx Tests error handling for the 'add' command when an invalid input is provided. Asserts that the expected error message is captured in stderr. ```typescript import { run } from "@stricli/core"; import { app } from "./app"; describe("add command", () => { it("fails if one input isn't a valid number", async () => { const context = buildContextForTest(); await run(app, ["add", "1", "two"], context); // highlight-next-line expect(context.stderr).includes("Cannot convert two to a number"); }); }); ``` -------------------------------- ### Customizing CommandContext with User Data Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/isolated-context.mdx Defines a custom context extending CommandContext to include user information. This allows passing custom data, like user details, into command implementations via dependency injection. ```typescript interface User { readonly id: number; readonly name: string; } interface CustomContext extends CommandContext { readonly user?: User; } ``` ```typescript export default function(this: CustomContext) { if (this.user) { this.process.stdout.write(`Logged in as ${this.user.name}`); } else { this.process.stdout.write(`Not logged in`); } } ``` ```typescript const user = ... // load user await run(app, process.argv.slice(2), { process, user }); ``` -------------------------------- ### Enable Argument Escape Sequence Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/configuration/input-scanning.mdx Set `allowArgumentEscapeSequence` to `true` to allow the `--` sequence to treat all subsequent inputs as positional arguments, bypassing flag parsing. ```sh run --foo -- --bar // output-next-line { foo: true }, ["--bar"] ``` -------------------------------- ### Implement Tuple Argument Logic Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/tuple-argument.txt The implementation function receives the parsed tuple arguments. Ensure the function signature matches the expected parameters. ```typescript export default async function(_: {}, from: string, to: string) { console.log(`Moving file from ${from} to ${to}`); } ``` -------------------------------- ### Nest Route Maps for Sub-commands Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/command-routing/route-maps.mdx Define nested route maps to create sub-commands. The usage text will list sub-route names as options. ```typescript const itemActionsRouteMap = buildRouteMap({ routes: { create: createItemCommand, rename: renameItemCommand, delete: deleteItemCommand, }, ... }); const root = buildRouteMap({ routes: { login: loginCommand, item: itemActionsRouteMap, }, ... }); ``` -------------------------------- ### Infer Empty Flag Implementation Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/infer-empty-flag.txt The implementation simply logs the flags object. The inferEmpty behavior is handled by the Stricli framework. ```typescript type Flags = { value?: string }; export default async function(flags: Flags) { console.log(flags); } ``` -------------------------------- ### Logging to CommandContext in TypeScript Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/examples/command-context-logging.txt Use `this.process.stdout.write` and `this.process.stderr.write` to log messages within the CommandContext. This is useful for providing feedback during command execution or for testing purposes. ```typescript import type { CommandContext } from "@stricli/core"; export default async function(this: CommandContext) { this.process.stdout.write(`This string is written to the CommandContext.\n`); this.process.stdout.write(`If \`process\` is passed, it will write to stdout.\n`); this.process.stderr.write(`...or stderr.\n`); this.process.stdout.write(`But you can also stub the context in testing,\n`); this.process.stdout.write(`for easy dependency injection!\n`); } ``` -------------------------------- ### Implement Boolean Flag Logic Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/boolean-flag.txt Implement the logic for a boolean flag in your application's implementation file. The flag's value (true or false) is passed directly to your function. ```typescript type Flags = { quiet: boolean; }; export default async function({ quiet }: Flags) { console.log(quiet ? "LOUD LOGGING" : "quiet logging"); } ``` -------------------------------- ### Lazy Command Implementation with Loader Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/command-routing/commands.mdx Defines a command using a `loader` function for asynchronous module import. This is useful for code splitting and delaying implementation loading until runtime. The `loader` can return the default export or a named export from the imported module. ```typescript /// impl.ts export default function(flags: {}) { console.log("This is the primary function"); } export function alt(flags: {}) { console.log("This is the alternative function"); } ``` ```typescript /// commands.ts const primaryCommand = buildCommand({ // highlight-next-line loader: async () => import("./impl"), ... }); const altCommand = buildCommand({ loader: async () => { // highlight-start const { alt } = await import("./impl"); return alt; // highlight-end }, ... }); ``` -------------------------------- ### Configure Case Style for Flag Parsing Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/configuration/examples/flag-case-style.txt Configure Stricli to allow kebab-case flags when camelCase is the default. This setting enables users to use kebab-case versions of flags, improving compatibility with various command-line conventions. ```typescript import { buildApplication } from "@stricli/core"; import root from "./spec.ts"; export default buildApplication(root, { name: "run", // Only modify properties in this configuration object scanner: { caseStyle: "allow-kebab-for-camel", }, }); ``` -------------------------------- ### Define Optional Tuple Argument Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/optional-tuple-argument.txt This snippet defines a command with a tuple of positional parameters where the last parameter is optional. It uses `kind: "tuple"` and `optional: true` to achieve this. ```typescript import { buildCommand } from "@stricli/core"; export default buildCommand({ loader: () => import("./impl"), parameters: { positional: { kind: "tuple", parameters: [ { brief: "First name", parse: String, }, { brief: "Last name", parse: String, optional: true, }, ], }, }, docs: { brief: "Example for live playground with optional positional parameter", }, }); ``` -------------------------------- ### Add Aliases to Routes Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/command-routing/route-maps.mdx Use the `aliases` property to expose a command under multiple names without duplicating the route definition. ```typescript buildRouteMap({ routes: { open: openCommand, close: closeCommand, }, aliases: { reopen: "open", }, ... }); ``` -------------------------------- ### Positional Arguments with Placeholders Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/positional.mdx Placeholders provide a semantic name for positional arguments, used in auto-generated usage lines and help text. This helps in clarifying the purpose of each argument without confusion with named flags. ```typescript import { command } from "@stricli/stricli"; command( "my-command ", (flags, first: string, second: number) => {}, { placeholders: { first: "input-file", second: "output-path" } } ); ``` -------------------------------- ### Define Variadic Flag with Default Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/variadic-default-flag.txt Defines a 'format' flag that can accept multiple enum values and has a default of 'json' and 'yaml'. ```typescript type Flags = { format?: ("json" | "xml" | "yaml")[]; }; export default async function({ format }: Flags) { console.log(`Output formats: ${format?.join(", ") ?? "none"}`); } ``` ```typescript import { buildCommand } from "@stricli/core"; export default buildCommand({ loader: () => import("./impl"), parameters: { flags: { format: { kind: "enum", values: ["json", "xml", "yaml"], brief: "Output format(s)", optional: true, variadic: true, default: ["json", "yaml"], }, }, aliases: { f: "format", }, }, docs: { brief: "Example for live playground with variadic flag and default values", customUsage: [ "", "--format xml", "--format json --format yaml", "-f xml -f json", ], }, }); ``` -------------------------------- ### Counter Flag Implementation (TypeScript) Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/counter-flag.txt Defines the implementation logic for a command that accepts a counter flag for verbosity. The 'verbose' flag is a number that increments with each occurrence. ```typescript type Flags = { verbose: number; }; export default async function({ verbose }: Flags) { console.log(`Logging with verbosity level ${verbose}`); } ``` -------------------------------- ### Define Optional Flag in Stricli Spec Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/optional-flag.txt This TypeScript code defines the command specification using Stricli's `buildCommand`. It configures an optional numeric flag named 'limit' with a description and specifies its parsing behavior. ```typescript import { buildCommand, numberParser } from "@stricli/core"; interface Flags { limit?: number; } export default buildCommand({ loader: () => import("./impl"), parameters: { flags: { limit: { kind: "parsed", parse: numberParser, brief: "Upper limit on number of items", optional: true, }, }, }, docs: { brief: "Example for live playground with optional flag", customUsage: [ "", "--limit 1000", ], }, }); ``` -------------------------------- ### Set Default Command for Route Maps Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/command-routing/route-maps.mdx Configure a `defaultCommand` within a route map to handle inputs that don't match specific routes. This command must be registered as a route within the same map. ```typescript buildRouteMap({ routes: { foo: fooCommand, bar: buildRouteMap({ routes: { old: oldBarCommand, new: newBarCommand, }, defaultCommand: "old", }), }, }); ``` -------------------------------- ### Defining a Variadic Flag Source: https://github.com/bloomberg/stricli/blob/main/docs/docs/features/argument-parsing/examples/variadic-flag.txt In the spec file, define a flag as 'variadic: true' to allow it to accept multiple values. Use a parser like 'numberParser' to ensure the values are of the correct type. Aliases can also be configured for convenience. ```typescript import { buildCommand, numberParser } from "@stricli/core"; export default buildCommand({ loader: () => import("./impl"), parameters: { flags: { id: { kind: "parsed", parse: numberParser, brief: "Set of IDs", variadic: true, }, }, aliases: { i: "id", }, }, docs: { brief: "Example for live playground with variadic flag", customUsage: [ "--id 10", "--id 10 --id 20 --id 30", "--id 5 -i 10 -i 15", ], }, }); ```