### Adding Positional Arguments to a Gunshi CLI
Source: https://gunshi.dev/guide/essentials/getting-started
This example extends the basic Gunshi CLI to accept a positional argument, such as a user's name. It demonstrates how to access these arguments via the `ctx.positionals` array within the `cli` function's context.
```js
import { cli } from 'gunshi'
await cli(process.argv.slice(2), ctx => {
// Access positional arguments
const name = ctx.positionals[0] || 'World'
console.log(`Hello, ${name}!`)
})
```
--------------------------------
### Executing Gunshi CLI with Positional Arguments
Source: https://gunshi.dev/guide/essentials/getting-started
This command demonstrates how to run the Gunshi CLI application and pass a positional argument (e.g., 'Alice') to it. The argument will be processed by the CLI application to customize its output.
```sh
node index.js Alice
```
--------------------------------
### Generating Built-in Help for Gunshi CLI
Source: https://gunshi.dev/guide/essentials/getting-started
This command shows how to trigger Gunshi's automatic help generation feature. Running the CLI with `--help` displays a comprehensive message including command descriptions, available options, and their descriptions, simplifying user interaction.
```sh
node index.js --help
```
--------------------------------
### Creating a Basic Gunshi CLI: Hello World
Source: https://gunshi.dev/guide/essentials/getting-started
This snippet demonstrates how to create a minimal 'Hello World' command-line application using Gunshi's `cli` function. It shows the basic structure of a Gunshi CLI, taking command-line arguments and executing a simple function.
```js
import { cli } from 'gunshi'
// Run a simple command
await cli(process.argv.slice(2), () => {
console.log('Hello, World!')
})
```
--------------------------------
### Install Gunshi Package in JavaScript Environments
Source: https://gunshi.dev/guide/introduction/setup
This section provides commands to install the Gunshi package using various JavaScript package managers and runtimes, including npm, pnpm, yarn, bun, and Deno's JSR. Select the command appropriate for your project's setup.
```sh
npm install --save gunshi
```
```sh
pnpm add gunshi
```
```sh
yarn add gunshi
```
```deno
# For Deno projects, you can add Gunshi from JSR:
deno add jsr:@kazupon/gunshi
```
```sh
bun add gunshi
```
--------------------------------
### Executing Gunshi CLI with Long and Short Options
Source: https://gunshi.dev/guide/essentials/getting-started
This command demonstrates how to run the Gunshi CLI application, passing both long-form (`--name`, `--uppercase`) and short-form (`-n`, `-u`) command-line options. It illustrates how to activate specific functionalities based on provided flags.
```sh
node index.js --name Alice --uppercase
# or with short options
node index.js -n Alice -u
```
--------------------------------
### Running a Basic Gunshi CLI Application
Source: https://gunshi.dev/guide/essentials/getting-started
This snippet provides the command to execute a Gunshi CLI application written in JavaScript/TypeScript using Node.js. It shows how to invoke the `index.js` file from the command line.
```sh
node index.js
```
--------------------------------
### CLI Usage Examples for Data Processor (Shell)
Source: https://gunshi.dev/guide/advanced/documentation-generation
Provides practical command-line examples for using the `data-processor` utility. It shows how to convert a CSV file to JSON and how to process a file to print its output to standard output.
```sh
data-processor --input data.csv --format json --output data.json
```
```sh
data-processor --input data.csv
```
--------------------------------
### JavaScript Example: Intlify Translation Adapter for Gunshi CLI
Source: https://gunshi.dev/guide/advanced/translation-adapter
This JavaScript code defines an `IntlifyTranslation` class that serves as a custom translation adapter for the Gunshi CLI framework. It illustrates how to initialize an Intlify core context, manage locale-specific messages, and implement translation logic. The snippet further includes a Gunshi command (`greeter`) that leverages this adapter to fetch localized resources and translate messages based on command-line arguments, showcasing a complete internationalization setup. This example requires the `@intlify/core` package.
```javascript
import { cli } from 'gunshi'
import {
createCoreContext,
getLocaleMessage,
NOT_REOSLVED,
setLocaleMessage,
translate as intlifyTranslate
} from '@intlify/core' // need to install `npm install --save @intlify/core@next`
// Create an Intlify translation adapter factory
function createIntlifyAdapterFactory(options) {
return new IntlifyTranslation(options)
}
class IntlifyTranslation {
#options
#context
constructor(options) {
this.#options = options
const { locale, fallbackLocale } = options
const messages = {
[locale]: {}
}
if (locale !== fallbackLocale) {
messages[fallbackLocale] = {}
}
// Create the Intlify core context
this.#context = createCoreContext({
locale,
fallbackLocale,
messages
})
}
getResource(locale) {
return getLocaleMessage(this.#context, locale)
}
setResource(locale, resource) {
setLocaleMessage(this.#context, locale, resource)
}
getMessage(locale, key) {
const resource = this.getResource(locale)
if (resource) {
return resource[key]
}
return
}
translate(locale, key, values = {}) {
// Check if the message exists in the specified locale or fallback locale
const message =
this.getMessage(locale, key) || this.getMessage(this.#options.fallbackLocale, key)
if (message === undefined) {
return
}
// Use Intlify's translate function
const result = intlifyTranslate(this.#context, key, values)
return typeof result === 'number' && result === NOT_REOSLVED ? undefined : result
}
}
// Define your command
const command = {
name: 'greeter',
args: {
name: {
type: 'string',
short: 'n'
}
},
// Define a resource fetcher with Intlify syntax
resource: async ctx => {
if (ctx.locale.toString() === 'ja-JP') {
return {
description: '挨拶アプリケーション',
name: '挨拶する相手の名前',
greeting: 'こんにちは、{name}さん!'
}
}
return {
description: 'Greeting application',
name: 'Name to greet',
greeting: 'Hello, {name}!'
}
},
run: ctx => {
const { name = 'World' } = ctx.values
// Use the translation function with Intlify
const message = ctx.translate('greeting', { name })
console.log(message)
}
}
// Run the command with the Intlify translation adapter
await cli(process.argv.slice(2), command, {
name: 'intlify-example',
version: '1.0.0',
locale: new Intl.Locale(process.env.MY_LOCALE || 'en-US'),
translationAdapterFactory: createIntlifyAdapterFactory
})
```
--------------------------------
### View Installed Man Page
Source: https://gunshi.dev/guide/advanced/documentation-generation
This simple shell command demonstrates how users can view a man page after it has been successfully installed on their system. The `man` command is used followed by the name of the tool.
```sh
man my-tool
```
--------------------------------
### Implementing Command Options in Gunshi CLI
Source: https://gunshi.dev/guide/essentials/getting-started
This snippet shows how to define and use command-line options (like `--name` and `--uppercase`) within a Gunshi CLI. It uses a declarative command object to specify argument types, short forms, descriptions, and how to access option values via `ctx.values`.
```js
import { cli } from 'gunshi'
const command = {
name: 'greeter',
description: 'A simple greeting CLI',
args: {
name: {
type: 'string',
short: 'n',
description: 'Name to greet'
},
uppercase: {
type: 'boolean',
short: 'u',
description: 'Convert greeting to uppercase'
}
},
run: ctx => {
const { name = 'World', uppercase } = ctx.values
let greeting = `Hello, ${name}!`
if (uppercase) {
greeting = greeting.toUpperCase()
}
console.log(greeting)
}
}
await cli(process.argv.slice(2), command)
```
--------------------------------
### Install Man Page System-Wide
Source: https://gunshi.dev/guide/advanced/documentation-generation
These shell commands provide instructions for installing a generated man page system-wide, typically for packaged applications. This requires superuser privileges to copy the file to the global man pages directory and update the system's man database.
```sh
sudo cp my-tool.1 /usr/local/share/man/man1/
sudo mandb
```
--------------------------------
### Install Man Page Locally for Development
Source: https://gunshi.dev/guide/advanced/documentation-generation
These shell commands demonstrate how to install a generated man page into a user's local man pages directory for development or personal use. It involves copying the man page file and updating the `mandb` database to make it discoverable.
```sh
cp my-tool.1 ~/.local/share/man/man1/
mandb
```
--------------------------------
### Generate CLI Usage for Rich Documentation (JavaScript)
Source: https://gunshi.dev/guide/advanced/documentation-generation
Demonstrates how to generate the core usage text for a CLI command using `gunshi/generator` and then integrate this text into a larger, custom Markdown documentation file, including sections for installation and examples.
```js
import { generate } from 'gunshi/generator'
import { promises as fs } from 'node:fs'
// Generate rich documentation
async function main() {
const command = {
name: 'data-processor',
description: 'Process data files',
args: {
input: {
type: 'string',
short: 'i',
required: true,
description: 'Input file path'
},
format: {
type: 'string',
short: 'f',
description: 'Output format (json, csv, xml)'
},
output: {
type: 'string',
short: 'o',
description: 'Output file path'
}
},
run: ctx => {
// Command implementation
}
}
// Generate the usage information
const usageText = await generate(null, command, {
name: 'data-processor',
version: '1.0.0',
description: 'A data processing utility'
})
// Create rich documentation
const documentation = `\n# Data Processor CLI\n\nA command-line utility for processing data files in various formats.\n\n## Installation\n\n```sh\nnpm install -g data-processor\n```\n\n## Usage\n\n```sh\n${usageText}\n```\n\n## Examples\n\n### Convert a CSV file to JSON\n\n```sh\ndata-processor --input data.csv --format json --output data.json\n```\n\n### Process a file and print to stdout\n\n```sh\ndata-processor --input data.csv\n```\n`
}
```
--------------------------------
### Gunshi Localization Resource Key Naming Conventions Example
Source: https://gunshi.dev/guide/essentials/internationalization
This TypeScript example demonstrates the recommended naming conventions for localization resource keys within a Gunshi command's resource function. It shows how to define descriptions for commands, examples, arguments (using arg: prefix), and custom messages.
```ts
import { define } from 'gunshi'
const command = define({
name: 'my-command',
args: {
target: { type: 'string' },
verbose: { type: 'boolean' }
},
resource: async ctx => {
// Example for 'en-US' locale
return {
description: 'This is my command.', // No prefix
examples: '$ my-command --target file.txt', // No prefix
'arg:target': 'The target file to process.', // 'arg:' prefix
'arg:verbose': 'Enable verbose output.', // 'arg:' prefix
'arg:no-verbose': 'Disable verbose logging specifically.', // Optional custom translation for the negatable option
processing_message: 'Processing target...' // No prefix
}
},
run: ctx => {
/* ... */
}
})
```
--------------------------------
### Configure npm Package for Man Page Installation
Source: https://gunshi.dev/guide/advanced/documentation-generation
This JSON snippet shows how to configure an `npm` `package.json` file to include man pages. By adding the `man` field with an array of paths to the man page files, `npm` will automatically install them when the package is installed globally.
```json
{
"man": ["./man/my-tool.1"]
}
```
--------------------------------
### Complete i18n Example for a gunshi.js CLI Command
Source: https://gunshi.dev/guide/essentials/internationalization
This comprehensive example illustrates setting up a `gunshi.js` CLI command with full internationalization support. It includes defining arguments, a `resource` fetcher for translations, command examples, and the `run` function which uses `ctx.translate` to display locale-specific messages.
```javascript
import { cli } from 'gunshi'
import enUS from './locales/en-US.json' with { type: 'json' }
const command = {
name: 'greeter',
args: {
name: {
type: 'string',
short: 'n'
},
formal: {
type: 'boolean',
short: 'f'
}
},
// Define a resource fetcher for translations
resource: async ctx => {
// Check the locale and return appropriate translations
if (ctx.locale.toString() === 'ja-JP') {
const resource = await import('./locales/ja-JP.json', { with: { type: 'json' } })
return resource.default
}
// Default to English
return enUS
},
// Define examples
examples:
'# Basic greeting\n$ node index.js --name John\n\n# Formal greeting in Japanese\n$ MY_LOCALE=ja-JP node index.js --name 田中 --formal',
// Command execution function
run: ctx => {
const { name = 'World', formal } = ctx.values
const locale = ctx.locale.toString()
console.log(`Current locale: ${locale}`)
// Choose between formal and informal greeting
const greeting = formal ? ctx.translate('formal_greeting') : ctx.translate('informal_greeting')
// Display the greeting
console.log(`${greeting}, ${name}!`)
// Show translation information
console.log('\nTranslation Information:')
console.log(`Command Description: ${ctx.translate('description')}`)
console.log(`Name Argument: ${ctx.translate('arg:name')}`)
console.log(`Formal Argument: ${ctx.translate('arg:formal')}`)
}
}
// Run the command with i18n support
await cli(process.argv.slice(2), command, {
name: 'i18n-example',
version: '1.0.0',
description: 'Example of internationalization support',
// Set the locale via an environment variable
locale: new Intl.Locale(process.env.MY_LOCALE || 'en-US')
})
```
--------------------------------
### API Reference: Command Interface
Source: https://gunshi.dev/api/default/interfaces/Command
Comprehensive API documentation for the Command interface, detailing its generic type parameter 'A' and all available properties such as 'args', 'description', 'examples', 'name', 'resource', 'run', and 'toKebab', along with their types and descriptions.
```APIDOC
Interface: Command
Description: Command interface.
Type Parameters:
A: extends Args (Default: Args)
Properties:
args?: A
Description: Command arguments. Each argument can include a description property to describe the argument in usage.
description?: string
Description: Command description. It's used to describe the command in usage and it's recommended to specify.
examples?: string | CommandExamplesFetcher
Description: Command examples. examples of how to use the command.
name?: string
Description: Command name. It's used to find command line arguments to execute from sub commands, and it's recommended to specify.
resource?: CommandResourceFetcher
Description: Command resource fetcher.
run?: CommandRunner
Description: Command runner. it's the command to be executed
toKebab?: boolean
Description: Whether to convert the camel-case style argument name to kebab-case. If you will set to `true`, All Command.args names will be converted to kebab-case.
```
--------------------------------
### Implement Complete Gunshi Declarative Command
Source: https://gunshi.dev/guide/essentials/declarative-configuration
Provides a comprehensive example of a Gunshi command using declarative configuration. It demonstrates various argument types (string, positional, number, boolean, negatable), defines command examples, and implements the execution logic to access context values, process a file, repeat greetings, and handle rest arguments.
```js
import { cli } from 'gunshi'
// Define a command with declarative configuration
const command = {
// Command metadata
name: 'greet',
description: 'A greeting command with declarative configuration',
// Command arguments with descriptions
args: {
name: {
type: 'string',
short: 'n',
description: 'Name to greet'
},
// Add a positional argument using 'file' as the key
file: {
type: 'positional',
description: 'Input file to process'
},
greeting: {
type: 'string',
short: 'g',
default: 'Hello',
description: 'Greeting to use (default: "Hello")'
},
times: {
type: 'number',
short: 't',
default: 1,
description: 'Number of times to repeat the greeting (default: 1)'
},
verbose: {
type: 'boolean',
short: 'V',
description: 'Enable verbose output',
negatable: true // Add this to enable --no-verbose
},
banner: {
// Added another boolean option for grouping example
type: 'boolean',
short: 'b',
description: 'Show banner'
}
},
// Command examples
examples: `# Examples\n$ node index.js --name World\n\n$ node index.js -n World -g "Hey there" -t 3\n\n# Boolean short options can be grouped: -V -b is the same as -Vb\n$ node index.js -Vb -n World\n\n# Using the negatable option\n$ node index.js --no-verbose -n World\n\n# Using rest arguments after \`--\` (arguments after \`--\` are not parsed by gunshi)\n$ node index.js -n User -- --foo --bar buz\n`,
// Command execution function
run: ctx => {
// If 'verbose' is defined with negatable: true:
// - true if -V or --verbose is passed
// - false if --no-verbose is passed
// - undefined if neither is passed (or default value if set)
// Access positional argument 'file' via ctx.values.file
const { name = 'World', greeting, times, verbose, banner, file } = ctx.values
if (banner) {
// Added check for banner
console.log('*** GREETING ***')
}
if (verbose) {
console.log('Running in verbose mode...')
console.log('Context values:', ctx.values)
console.log('Input file (from positional via ctx.values.file):', file)
console.log('Raw positional array (ctx.positionals):', ctx.positionals) // Still available
}
// Process the input file (example placeholder)
console.log(`\nProcessing file: ${file}...`)
// Repeat the greeting the specified number of times
for (let i = 0; i < times; i++) {
console.log(`${greeting}, ${name}!`)
}
// Print rest arguments if they exist
if (ctx.rest.length > 0) {
console.log('\nRest arguments received:')
for (const [index, arg] of ctx.rest.entries()) {
console.log(` ${index + 1}: ${arg}`)
}
}
}
}
// Run the command with the declarative configuration
await cli(process.argv.slice(2), command, {
name: 'declarative-example',
version: '1.0.0',
description: 'Example of declarative command configuration'
})
```
--------------------------------
### Define CLI Command with Arguments and Examples in Gunshi (JavaScript)
Source: https://gunshi.dev/guide/essentials/auto-usage-generation
This JavaScript snippet demonstrates how to define a Gunshi CLI command, including its name, description, arguments with types and descriptions, and example usage strings. It then initializes the CLI with this command, making it ready for execution and automatic help generation.
```js
import { cli } from 'gunshi'
const command = {
name: 'file-manager',
description: 'A file management utility',
// Define arguments with descriptions
args: {
path: {
type: 'string',
short: 'p',
description: 'File or directory path to operate on'
},
recursive: {
type: 'boolean',
short: 'r',
description: 'Operate recursively on directories'
},
operation: {
type: 'string',
short: 'o',
required: true,
description: 'Operation to perform: list, copy, move, or delete'
}
},
// Example commands
examples: `# List files in current directory
$ app --operation list
# Copy files recursively
$ app --operation copy --path ./source --recursive
# Delete files
$ app --operation delete --path ./temp`,
run: ctx => {
// Command implementation
}
}
await cli(process.argv.slice(2), command, {
name: 'app',
version: '1.0.0'
})
```
--------------------------------
### Illustrate Basic CLI Sub-command Structure
Source: https://gunshi.dev/guide/essentials/composable
This snippet demonstrates the fundamental command-line syntax for applications that utilize sub-commands. It shows how a main CLI command is followed by a specific sub-command and its associated options, providing a clear example of typical usage.
```Shell
cli [command options]
cli create --name my-resource
```
--------------------------------
### Example: Parsing Command Line Arguments with parseArgs (JavaScript)
Source: https://gunshi.dev/api/default/functions/parseArgs
Demonstrates how to use the `parseArgs` function from the `args-tokens` library to parse command line arguments in Node.js, Bun, or Deno environments. The example shows parsing various argument formats like `--foo bar`, `-x`, and `--bar=baz` and logging the resulting tokens.
```js
import { parseArgs } from 'args-tokens' // for Node.js and Bun
// import { parseArgs } from 'jsr:@kazupon/args-tokens' // for Deno
const tokens = parseArgs(['--foo', 'bar', '-x', '--bar=baz'])
// do something with using tokens
// ...
console.log('tokens:', tokens)
```
--------------------------------
### Generated CLI Help Output with Examples (Shell)
Source: https://gunshi.dev/guide/essentials/auto-usage-generation
This shell output shows the automatically generated help message for a Gunshi CLI command. It includes the usage syntax, defined options with their short flags, types, and descriptions, and the custom examples provided in the command definition, enhancing user understanding.
```sh
app (app v1.0.0)
USAGE:
app
OPTIONS:
-p, --path File or directory path to operate on
-r, --recursive Operate recursively on directories
--no-recursive Negatable of -r, --recursive
-o, --operation Operation to perform: list, copy, move, or delete
-h, --help Display this help message
-v, --version Display this version
EXAMPLES:
# List files in current directory
$ app --operation list
# Copy files recursively
$ app --operation copy --path ./source --recursive
# Delete files
$ app --operation delete --path ./temp
```
--------------------------------
### Define Basic Gunshi Command Structure
Source: https://gunshi.dev/guide/essentials/declarative-configuration
Illustrates the fundamental declarative structure for a Gunshi command, including metadata (name, description), argument definitions, examples, and the core run function for execution logic.
```js
const command = {
// Command metadata
name: 'command-name',
description: 'Command description',
// Command arguments
args: {
// Argument definitions
},
// Command examples
examples: 'Example usage',
// Command execution function
run: ctx => {
// Command implementation
}
}
```
--------------------------------
### Understanding Unix Man Page Structure
Source: https://gunshi.dev/guide/advanced/documentation-generation
This section introduces the traditional structure and common sections of Unix man pages, which are used for documenting command-line tools on Unix-like operating systems. It outlines the standard headings like NAME, SYNOPSIS, DESCRIPTION, and EXAMPLES.
```APIDOC
NAME: The name of the command and a brief description
SYNOPSIS: The command syntax
DESCRIPTION: A detailed description of the command
OPTIONS: A list of available options
EXAMPLES: Example usage
SEE ALSO: Related commands or documentation
AUTHOR: Information about the author
```
--------------------------------
### English Locale File for CLI i18n Example
Source: https://gunshi.dev/guide/essentials/internationalization
This JSON file provides the English translations for the `gunshi.js` CLI internationalization example. It defines key-value pairs for descriptions, argument names, and different greeting phrases, which are accessed by the CLI application based on the active locale.
```json
{
"description": "Greeting application",
"arg:name": "Name to greet",
"arg:formal": "Use formal greeting",
"informal_greeting": "Hello",
"formal_greeting": "Good day"
}
```
--------------------------------
### TypeScript Property: CommandResource.examples
Source: https://gunshi.dev/api/default/type-aliases/CommandResource
Defines the examples usage for the command resource, which can be a string or a `CommandExamplesFetcher` function.
```TypeScript
examples: string | CommandExamplesFetcher;
```
--------------------------------
### Generated Main CLI Help Output with Sub-commands (Shell)
Source: https://gunshi.dev/guide/essentials/auto-usage-generation
This shell output displays the help message for a Gunshi CLI that includes sub-commands. It lists the available commands and provides clear instructions on how to get more specific help for each sub-command, guiding users through the CLI's functionality.
```sh
app (app v1.0.0)
USAGE:
app [manage]
app
COMMANDS:
create Create a new resource
list List all resources
manage Manage resources
For more info, run any command with the `--help` flag:
app create --help
app list --help
app manage --help
OPTIONS:
-h, --help Display this help message
-v, --version Display this version
```
--------------------------------
### Define Command Metadata in TypeScript
Source: https://gunshi.dev/guide/advanced/advanced-lazy-loading
Example of a `meta.ts` file defining the name, description, and arguments for a Gunshi sub-command. This metadata is imported directly and bundled with the main CLI, allowing help information to be displayed without loading the full command implementation.
```ts
// packages/command-a/src/meta.ts
export default {
name: 'command-a',
description: 'Performs action A',
args: {
input: {
type: 'string',
short: 'i',
description: 'Input file'
},
output: {
type: 'string',
short: 'o',
description: 'Output file'
}
}
}
```
--------------------------------
### Japanese Locale File for CLI i18n Example
Source: https://gunshi.dev/guide/essentials/internationalization
This JSON file contains the Japanese translations corresponding to the English locale file for the `gunshi.js` CLI internationalization example. It demonstrates how to provide localized strings for the same keys, enabling the application to switch languages seamlessly.
```json
{
"description": "挨拶アプリケーション",
"arg:name": "挨拶する相手の名前",
"arg:formal": "丁寧な挨拶を使用する",
"informal_greeting": "こんにちは",
"formal_greeting": "はじめまして"
}
```
--------------------------------
### Implementing Lazy Loading with `lazy` Helper in Gunshi
Source: https://gunshi.dev/guide/essentials/lazy-async
This example demonstrates how to use Gunshi's `lazy` helper to define a command whose execution logic is loaded on demand. It separates the command's metadata (`helloDefinition`) from its asynchronous loader function (`helloLoader`), which returns the `CommandRunner`. The `lazy` function combines these, allowing Gunshi to display help messages without executing the loader, thereby optimizing initial bundle size and loading heavy dependencies only when the command is actually run.
```js
import { cli, lazy } from 'gunshi'
// Define the metadata for the command separately
const helloDefinition = {
name: 'hello', // This name is used as the key in subCommands Map
description: 'A command whose runner is loaded lazily',
args: {
name: {
type: 'string',
description: 'Name to greet',
default: 'world'
}
},
example: 'my-app hello --name=Gunshi'
// No 'run' function needed here in the definition
}
// Define the loader function that returns the CommandRunner
const helloLoader = async () => {
console.log('Loading hello command runner...')
// Simulate loading time or dynamic import
await new Promise(resolve => setTimeout(resolve, 500))
// Dynamically import the actual run function (CommandRunner)
// const { run } = await import('./commands/hello.js')
// return run
// For simplicity, we define the runner inline here
const run = ctx => {
console.log(`Hello, ${ctx.values.name}!`)
}
return run // Return only the runner function
}
// Create the LazyCommand using the lazy helper
const lazyHello = lazy(helloLoader, helloDefinition)
// Create a Map of sub-commands using the LazyCommand
const subCommands = new Map()
// Use the name from the definition as the key
subCommands.set(lazyHello.commandName, lazyHello)
// Define the main command
const mainCommand = {
// name is optional for the main command if 'name' is provided in config below
description: 'Example of lazy loading with the `lazy` helper',
run: () => {
// This runs if no sub-command is provided
console.log('Use the hello sub-command: my-app hello')
}
}
// Run the CLI
// Gunshi automatically resolves the LazyCommand and loads the runner when needed
await cli(process.argv.slice(2), mainCommand, {
name: 'my-app',
version: '1.0.0',
subCommands
})
```
--------------------------------
### Example English Locale JSON File for Gunshi CLI
Source: https://gunshi.dev/guide/essentials/internationalization
This JSON file provides the English (en-US) translations for the Gunshi CLI 'greeter' application. It defines key-value pairs for the command description, argument descriptions, and various greeting phrases used in the application.
```json
{
"description": "Greeting application",
"arg:name": "Name to greet",
"arg:formal": "Use formal greeting",
"informal_greeting": "Hello",
"formal_greeting": "Good day"
}
```
--------------------------------
### JavaScript Example: Custom CLI Renderers with Chalk
Source: https://gunshi.dev/guide/advanced/custom-usage-generation
This JavaScript code demonstrates how to create custom header and usage renderers for a CLI application using the 'chalk' library to add colors. It defines functions that take a context object (ctx) and return formatted strings, then applies these renderers when initializing the CLI.
```js
import { cli } from 'gunshi'
import chalk from 'chalk'
// Custom header renderer with colors
const coloredHeaderRenderer = ctx => {
const lines = []
lines.push(chalk.blue('╔═════════════════════════════════════════╗'))
lines.push(chalk.blue(`║ ${chalk.bold(ctx.env.name.toUpperCase())} ║`))
lines.push(chalk.blue('╚═════════════════════════════════════════╝'))
if (ctx.env.description) {
lines.push(chalk.white(ctx.env.description))
}
if (ctx.env.version) {
lines.push(chalk.gray(`Version: ${ctx.env.version}`))
}
lines.push('')
return Promise.resolve(lines.join('\n'))
}
// Custom usage renderer with colors
const coloredUsageRenderer = ctx => {
const lines = []
lines.push(chalk.yellow.bold('📋 COMMAND USAGE'))
lines.push(chalk.yellow('═══════════════'))
lines.push('')
lines.push(chalk.white.bold('BASIC USAGE:'))
lines.push(chalk.white(` $ ${ctx.env.name} [options]`))
lines.push('')
if (ctx.args && Object.keys(ctx.args).length > 0) {
lines.push(chalk.white.bold('OPTIONS:'))
for (const [key, option] of Object.entries(ctx.args)) {
const shortFlag = option.short ? chalk.green(`-${option.short}, `) : ' '
const longFlag = chalk.green(`--${key}`)
const type = chalk.blue(`[${option.type}]`)
const required = option.required ? chalk.red(' (required)') : ''
lines.push(
` ${shortFlag}${longFlag.padEnd(15)} ${type.padEnd(10)} ${ctx.translate(key)}${required}`
)
}
lines.push('')
}
return Promise.resolve(lines.join('\n'))
}
// Run the CLI with colored renderers
await cli(process.argv.slice(2), command, {
name: 'task-manager',
version: '1.0.0',
description: 'A task management utility',
renderHeader: coloredHeaderRenderer,
renderUsage: coloredUsageRenderer
})
```
--------------------------------
### Generated Sub-command Specific Help Output (Shell)
Source: https://gunshi.dev/guide/essentials/auto-usage-generation
This shell output shows the detailed help message for a specific sub-command (`create`), demonstrating Gunshi's ability to generate granular documentation. It includes the sub-command's description, usage syntax, options, and examples, providing comprehensive guidance for that particular command.
```sh
app (app v1.0.0)
Create a new resource
USAGE:
app create
OPTIONS:
-n, --name Name of the resource
-h, --help Display this help message
-v, --version Display this version
EXAMPLES:
$ app create --name my-resource
```
--------------------------------
### Define and Run Composable Sub-commands in JavaScript with Gunshi
Source: https://gunshi.dev/guide/essentials/composable
This example illustrates how to define and register multiple sub-commands, 'create' and 'list', within a Gunshi CLI application using JavaScript. It details the structure for defining command names, descriptions, arguments, and their execution logic, then shows how to integrate these into the main CLI for modular command management.
```JavaScript
import { cli } from 'gunshi'
// Define sub-commands
const createCommand = {
name: 'create',
description: 'Create a new resource',
args: {
name: { type: 'string', short: 'n' }
},
run: ctx => {
console.log(`Creating resource: ${ctx.values.name}`)
}
}
const listCommand = {
name: 'list',
description: 'List all resources',
run: () => {
console.log('Listing all resources...')
}
}
// Create a Map of sub-commands
const subCommands = new Map()
subCommands.set('create', createCommand)
subCommands.set('list', listCommand)
// Define the main command
const mainCommand = {
name: 'manage',
description: 'Manage resources',
run: () => {
console.log('Use one of the sub-commands: create, list')
}
}
// Run the CLI with composable sub-commands
await cli(process.argv.slice(2), mainCommand, {
name: 'my-app',
version: '1.0.0',
subCommands
})
```
--------------------------------
### Implement Gunshi Command Runner in TypeScript
Source: https://gunshi.dev/guide/advanced/advanced-lazy-loading
Example of a command's `index.ts` file, demonstrating the `run` function that serves as the command's implementation. It imports the `CommandContext` type from 'gunshi' and utilizes the arguments defined in the associated metadata file.
```ts
// packages/command-a/src/index.ts
import type { CommandContext } from 'gunshi'
import meta from './meta'
export const run = async (ctx: CommandContext) => {
const { input, output } = ctx.values
console.log(`Processing ${input} to ${output}`)
// Command implementation...
}
```
--------------------------------
### TypeScript Type Alias: CommandExamplesFetcher
Source: https://gunshi.dev/api/default/type-aliases/CommandExamplesFetcher
Defines the `CommandExamplesFetcher` type alias, which is a function that accepts a command context and returns an `Awaitable`. It is used to fetch command examples asynchronously.
```ts
type CommandExamplesFetcher = (ctx) => Awaitable;
```
```APIDOC
Type Alias: CommandExamplesFetcher
Type Parameters:
A: extends Args (Default: Args)
Parameters:
ctx: Readonly> - A command context
Returns:
Awaitable - A fetched command examples.
```
--------------------------------
### Implement On-Demand Sub-Command Loading for Gunshi CLI
Source: https://gunshi.dev/guide/advanced/advanced-lazy-loading
This example illustrates an advanced technique for CLIs with many sub-commands, enabling on-demand loading of both metadata and implementation. It uses a factory function to create lazy commands, where full metadata is dynamically imported only when needed, further optimizing initial load times.
```typescript
// packages/cli/src/commands.ts
import { lazy } from 'gunshi/definition'
import { load } from './loader'
// Function to create a lazy command
function createLazyCommand(name: string) {
return lazy(
async () => {
// Dynamically import metadata and implementation
const meta = await import(`${name}/meta`).then(m => m.default || m)
return await load(name)
},
{ name } // Minimal metadata, rest will be loaded on demand
)
}
// Create commands map with factory function
export const commands = new Map([
['command-a', createLazyCommand('command-a')],
['command-b', createLazyCommand('command-b')]
// Add more commands as needed
])
```
--------------------------------
### Customize CLI Help Header with Gunshi JavaScript
Source: https://gunshi.dev/guide/advanced/custom-usage-generation
This snippet shows how to create a custom `renderHeader` function for Gunshi CLI applications. It defines a custom header with branding, description, and version information. The example demonstrates applying this renderer when initializing the CLI.
```js
import { cli } from 'gunshi'
// Define a custom header renderer
const customHeaderRenderer = ctx => {
const lines = []
// Add a fancy header
lines.push('╔═════════════════════════════════════════╗')
lines.push(`║ ${ctx.env.name.toUpperCase().padStart(20).padEnd(39)} ║`)
lines.push('╚═════════════════════════════════════════╝')
// Add description and version
if (ctx.env.description) {
lines.push(ctx.env.description)
}
if (ctx.env.version) {
lines.push(`Version: ${ctx.env.version}`)
}
lines.push('')
// Return the header as a string
return lines.join('\n')
}
// Define your command
const command = {
name: 'app',
description: 'My application',
args: {
name: {
type: 'string',
short: 'n',
description: 'Name to use'
}
},
run: ctx => {
// Command implementation
}
}
// Run the command with the custom header renderer
await cli(process.argv.slice(2), command, {
name: 'my-app',
version: '1.0.0',
description: 'A CLI application with custom usage generation',
renderHeader: customHeaderRenderer
})
```
```sh
╔═════════════════════════════════════════╗
║ MY-APP ║
╚═════════════════════════════════════════╝
A CLI application with custom usage generation
Version: 1.0.0
USAGE:
my-app
OPTIONS:
-n, --name Name to use
-h, --help Display this help message
-v, --version Display this version
```
--------------------------------
### Complete CLI Application with Custom Renderers in JavaScript
Source: https://gunshi.dev/guide/advanced/custom-usage-generation
This comprehensive JavaScript snippet illustrates the creation of a CLI application using the 'gunshi' library. It defines custom functions for rendering the CLI header, detailed usage instructions, and validation errors, providing a highly customized user experience. The example includes a 'task-manager' command with various arguments and demonstrates how to integrate these custom renderers into the CLI execution.
```javascript
import { cli } from 'gunshi'
// Custom header renderer
const customHeaderRenderer = ctx => {
const lines = []
lines.push('╔═════════════════════════════════════════╗')
lines.push('║ TASK MANAGER ║')
lines.push('╚═════════════════════════════════════════╝')
if (ctx.env.description) {
lines.push(ctx.env.description)
}
if (ctx.env.version) {
lines.push(`Version: ${ctx.env.version}`)
}
lines.push('')
return Promise.resolve(lines.join('\n'))
}
// Custom usage renderer
const customUsageRenderer = ctx => {
const lines = []
// Add a custom title
lines.push('📋 COMMAND USAGE')
lines.push('═══════════════')
lines.push('')
// Add basic usage
lines.push('BASIC USAGE:')
lines.push(` $ ${ctx.env.name} [options]`)
lines.push('')
// Add options section with custom formatting
if (ctx.args && Object.keys(ctx.args).length > 0) {
lines.push('OPTIONS:')
for (const [key, option] of Object.entries(ctx.args)) {
const shortFlag = option.short ? `-${option.short}, ` : ' '
const longFlag = `--${key}`
const type = `[${option.type}]`
// Format the option with custom styling
const formattedOption = ` ${shortFlag}${longFlag.padEnd(15)} ${type.padEnd(10)} ${ctx.translate(key)}`
lines.push(formattedOption)
}
lines.push('')
}
// Add examples section with custom formatting
if (ctx.examples) {
lines.push('EXAMPLES:')
const examples = ctx.examples.split('\n')
for (const example of examples) {
// Add extra indentation to examples
lines.push(` ${example}`)
}
lines.push('')
}
// Add footer
lines.push('NOTE: This is a demo application with custom usage formatting.')
lines.push('For more information, visit: https://github.com/kazupon/gunshi')
return Promise.resolve(lines.join('\n'))
}
// Custom validation errors renderer
const customValidationErrorsRenderer = (ctx, error) => {
const lines = []
lines.push('❌ ERROR:')
lines.push('═════════')
for (const err of error.errors) {
lines.push(` • ${err.message}`)
}
lines.push('')
lines.push('Please correct the above errors and try again.')
lines.push(`Run '${ctx.env.name} --help' for usage information.`)
return Promise.resolve(lines.join('\n'))
}
// Define a command
const command = {
name: 'task-manager',
description: 'A task management utility with custom usage generation',
args: {
add: {
type: 'string',
short: 'a',
description: 'Add a new task'
},
list: {
type: 'boolean',
short: 'l',
description: 'List all tasks'
},
complete: {
type: 'string',
short: 'c',
description: 'Mark a task as complete'
},
priority: {
type: 'string',
short: 'p',
description: 'Set task priority (low, medium, high)'
},
due: {
type: 'string',
short: 'd',
description: 'Set due date in YYYY-MM-DD format'
}
},
examples: `# Add a new task\n$ task-manager --add "Complete the project"\n\n# Add a task with priority and due date\n$ task-manager --add "Important meeting" --priority high --due 2023-12-31\n\n# List all tasks\n$ task-manager --list\n\n# Mark a task as complete\n$ task-manager --complete "Complete the project"`,
run: ctx => {
const { add, list, complete, priority, due } = ctx.values
if (add) {
console.log(`Adding task: "${add}"`)
if (priority) console.log(`Priority: ${priority}`)
if (due) console.log(`Due date: ${due}`)
} else if (list) {
console.log('Listing all tasks...')
} else if (complete) {
console.log(`Marking task as complete: "${complete}"`)
} else {
console.log('No action specified. Run with --help to see usage information.')
}
}
}
// Run the command with custom usage generation
await cli(process.argv.slice(2), command, {
name: 'task-manager',
version: '1.0.0',
description: 'A task management utility with custom usage generation',
// Custom renderers
renderHeader: customHeaderRenderer,
renderUsage: customUsageRenderer,
renderValidationErrors: customValidationErrorsRenderer
})
```
--------------------------------
### Run Gunshi CLI with Different Locales
Source: https://gunshi.dev/guide/essentials/internationalization
This shell script shows how to execute the Gunshi CLI example with different locales. It demonstrates running the command with the default English locale and then with the `ja-JP` locale by setting the `MY_LOCALE` environment variable, showcasing the localized output.
```sh
# English (default)
node index.js --name John
# i18n-example (i18n-example v1.0.0)
#
# Hello, John!
#
# Translation Information:
# Current locale: en-US
# Command Description: Greeting application
# Japanese
MY_LOCALE=ja-JP node index.js --name 田中 --formal
# i18n-example (i18n-example v1.0.0)
#
# こんにちは, 田中!
#
# Translation Information:
# Current locale: ja-JP
# Command Description: 挨拶アプリケーション
```