Skip to content

AdamPuzio/panda-command

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Command

@panda/command is a fully-featured library for creating commands and CLIs with minimal effort.

Panda thinks of commands as a way to collect data from a user (via passed parameters and/or prompts) and execute a task or series of tasks based upon that data.

For the full documentation, visit the @panda/command documentation website

Highlights

  • Customizable arguments, options and flags
  • Prompts that can be tied to passed parameters
  • Subcommand support
  • Data validation and formatting
  • Custom output styling and positioning
  • ESM/CommonJS/Typescript compatible
  • Automated help generation and parameter

Installation

Install Using @panda/command

If you just want to use Command, you can install it directly from @panda/command:

npm install @panda/command

Setup

Include

// ESM
import { Command } from '@panda/command'
// CommonJS
const { Command } = require('@panda/command')

Create

Commands can be created either by extending the Command class or creating a new instance of it.

Instantiate Command

The most common method is to create a new instance:

import { Command } from '@panda/command'

const cmd = new Command({
  name: 'foo:create',
  action: async (data, details) => {}
})

Extend Command

If you plan to use your command as a class that can be extended later on, extend the Command class:

import { Command } from '@panda/command'

export const FooCreateCommand extends Command {
  name = 'foo:create'

  async action (data, details) {}
}

Even as an uninstantiated class, it can be imported into other commands as a subcommand.

Run

Running a Command is as easy as calling the run() method:

import { Command } from '@panda/command'

const cmd = new Command({
  name: 'foo:create',
  action: async (data, details) => {}
}).run()

Note: The run() method should only be added to the top-level command that will directly be called.

Run Via Script

There are several methods to run a script that contains a command:

  1. Call the script directly (example: ./my-script.js)
  2. Call the script via node (example: node my-script.js)
  3. Add the script to your package.json into scripts and run npm run <script>
  4. Add the script to your package.json into bin and run npm link (or install globally) to run as an independent command

When running a script directly (without using NPM or Node), be sure to include the following in your script:

#!/usr/bin/env node

Syntax

<command> [arguments|options|flags] [subcommand] [subcommand-parameters]

A command is called by a specific name, followed by a series of parameters. These parameters can be in the form of arguments, options, or flags. Additionally, a command can have subcommands.

  • parameters
    • arguments
    • options (key=value)
    • flags
    • subcommands

Arguments, options and flags can be called in any order, but subcommands must be called after any base parameters. Any parameters called after a subcommand are considered subcommand parameters.

Usage

import { Command } from '@panda/command'

new Command({
  // required: name
  name: 'create-foo',
  // used as the command called when it's a subcommand
  command: 'foo:create',
  // used in help menu
  description: 'Create a new Foo',
  // application or command version
  version: '1.4.7',
  // argument handler
  //   if object, 'name' data key contains a single or multiple values
  //   if array, data keys are applied as positional arguments
  arguments: {
    name: 'name'
  },
  // list of options to parse
  options: [],
  // list of flags to parse
  flags: [],
  // list of subcommands
  //   if array, use the `command` property as the subcommand
  //   if object, use the key as the subcommand
  subcommands: [],
  // list of prompts to ask user
  prompts: [],
  // list of custom prompt types available to `prompts`
  promptTypes: {},
  // flag to automatically generate and display help menu on --help
  autoHelp: true,
  // flag to automatically output version on --version
  autoVersion: true,
  // flag to suppress logging output
  silent: false,
  // method to transform data before reaching action
  transform: async (data) => {
    data.type = 'based'
    return data
  },
  action: async (data, details) => {
    // perform your actions
  }
})

Properties

Property Required Type(s) Default Description
name Y string Command name
command N string Subcommand name
description N string Command description
version N string Command version
arguments N object/array Argument handler
options N array List of options
flags N array List of flags
prompts N array List of prompts
subcommands N array/object List of subcommands
promptTypes N object List of custom prompt types
autoHelp N boolean false Toggle for automated help menu
autoVersion N boolean false Toggle for automated version output
silent N boolean false Toggle for output suppression
transform N function Method to transform data
action N function Method to process data
name: string
command?: string
description?: string
version?: string
arguments?: CommandArgumentProps | CommandArgumentProps[]
options?: CommandOptionProps[]
flags?: CommandFlagProps[]
prompts?: CommandPromptProps[]
subcommands?: 
  Array<CommandProps | Command | typeof Command> 
  | {[key:string]: CommandProps | Command | typeof Command}
promptTypes?: {[key:string]: PromptConstructor}
autoHelp?: boolean
autoVersion?: boolean
silent?: boolean
transform?: (data: CommandData) => Promise<CommandData>
action?: (data: CommandData, details: CommandData) => Promise<any | void>

name

(required) The name of the command. Doubles as the subcommand if command is not set.

See Properties.name for more information

command

The callable command if set as a subcommand. Defaults to value of name.

See Properties.command for more information

description

Description of the command. Shows up in the --help menu.

See Properties.description for more information

version

Semantic version of the command. Shows up when user calls the command with the --version flag. Usually only set on primary command, but can be set on any command.

See Properties.version for more information

arguments

Handler for unnamed parameters. Can be an object or an array. Does not work with subcommands.

See Properties.arguments for more information

options

List of named parameters with values.

See Properties.options for more information

flags

List of flag parameters (named with no value).

See Properties.flags for more information

prompts

List of questions to ask the user. Can be tied to other parameters.

See Properties.prompts for more information

subcommands

List of subcommands that can be called as an argument. Does not work with arguments.

See Properties.subcommands for more information

promptTypes

List of plugins to create new types of prompts.

See Properties.promptTypes for more information

autoHelp

Toggle for automated --help flag.

See Properties.autoHelp for more information

autoVersion

Toggle for automated --version flag.

See Properties.autoVersion for more information

silent

Toggle for output functions like log(), out(), error(), heading() and spacer().

See Properties.silent for more information

transform

Method to transform data before calling action(). The data object is passed and must be returned with the final values.

See Properties.transform for more information

action

Method called to process data. Both data and details objects are passed.

See Properties.action for more information

Scripts

Build

  • dev npm run dev - Watch ./src directory and build on file change to ./dist for ESM & CommonJS (with types)
  • build npm run build - Build from ./src to ./dist for ESM & CommonJS (with types)
  • build:cjs npm run build:cjs - Build from ./src to ./dist for CommonJS (with types)
  • build:esm npm run build:esm - Build from ./src to ./dist for ESM (with types)

Lint

  • lint npm run lint - Lint check all files in ./src
  • lint:fix npm run lint:fix - Lint and fix all files in ./src
  • lint:prettier npm run lint:prettier - Check styling for all files in ./src
  • lint:prettier:fix npm run lint:prettier:fix - Fix styling for all files in ./src
  • lint:prettier:ci npm run lint:prettier:ci - Continuous integration style check

Test

  • test npm test - Run test suite and lint/style
  • test:vitest npm run test:vitest - Run test suite
  • test:watch npm run test:watch - Run test suite in watch mode

Included Libraries