0.67.0 โ€ข Published 8 months ago

@stacksjs/cli v0.67.0

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

Stacks CLI

The simple way to build beautiful CLIs.

โ˜˜๏ธ Features

  • ๐ŸŽจ Easily create beautiful CLI apps
  • โšก๏ธ Lightweight, user-friendly, interactive prompts
  • ๐Ÿšฆ Elegant terminal spinners
  • โ›‘๏ธ Helper methods to run commands

๐Ÿค– Usage

bun install -d @stacksjs/cli

Now, you can use it in your project:

// command.ts
// you may create create a relatively complex CLI UI/UX via the following:
import { ExitCode, command, italic, prompts, spawn, spinner } from '@stacksjs/cli'

const stacks = command('stacks')

stacks
  .command('example', 'A dummy command') // bun buddy example
  .option('-i, --install', 'The install option', { default: true })
  .action(async (options) => {
    if (options.install)
      await install()

    const answer = await prompts.select({
      type: 'select',
      message: 'Are you trying to run this command?',
      choices: [
        { title: 'Run the command', value: 'run' },
        { title: 'Do not run the command', value: 'do-not-run' },
      ],
    })

    if (answer === 'run')
      install()
    else if (answer === 'do-not-run')
      log.info('Not running the command')
    else process.exit(ExitCode.InvalidArgument)
  })

async function install() {
  try {
    const spin = spinner('Running...').start()
    setTimeout(() => {
      spin.text = italic('This may take a few moments...')
    }, 5000)
    await spawn('bun install')
    spin.stop()
  }
  catch (error) {
    log.error(error)
  }
}

command.help() // automatically expose a -h and --help flag
command.version(version) // automatically expose a -v and --version flag
command.parse() // parse the command

You may now run the command via:

bun command.ts

CLI Apps

Setup

The intro and outro functions will print a message to begin or end a prompt session, respectively.

import { intro, outro } from '@stacksjs/cli';

intro(`create-my-app`);
// Do stuff
outro(`You're all set!`);

Cancellation

The isCancel function is a guard that detects when a user cancels a question with CTRL + C. You should handle this situation for each prompt, optionally providing a nice cancellation message with the cancel utility.

import { isCancel, cancel, text } from '@stacksjs/cli';

const value = await text(/* TODO */);

if (isCancel(value)) {
  cancel('Operation cancelled.');
  process.exit(0);
}

Components

Text

The text component accepts a single line of text.

import { text } from '@stacksjs/cli';

const meaning = await text({
  message: 'What is the meaning of life?',
  placeholder: 'Not sure',
  initialValue: '42',
  validate(value) {
    if (value.length === 0) return `Value is required!`;
  },
});

Confirm

The confirm component accepts a yes or no answer. The result is a boolean value of true or false.

import { confirm } from '@stacksjs/cli';

const shouldContinue = await confirm({
  message: 'Do you want to continue?',
});

Select

The select component allows a user to choose one value from a list of options. The result is the value prop of a given option.

import { select } from '@stacksjs/cli';

const projectType = await select({
  message: 'Pick a project type.',
  options: [
    { value: 'ts', label: 'TypeScript' },
    { value: 'js', label: 'JavaScript' },
    { value: 'coffee', label: 'CoffeeScript', hint: 'oh no' },
  ],
});

Multi-Select

The multiselect component allows a user to choose many values from a list of options. The result is an array with all selected value props.

import { multiselect } from '@stacksjs/cli';

const additionalTools = await multiselect({
  message: 'Select additional tools.',
  options: [
    { value: 'eslint', label: 'ESLint', hint: 'recommended' },
    { value: 'prettier', label: 'Prettier' },
    { value: 'gh-action', label: 'GitHub Action' },
  ],
  required: false,
});

Spinner

The spinner component surfaces a pending action, such as a long-running download or dependency installation.

import { spinner } from '@stacksjs/cli';

const s = spinner();
s.start('Installing via npm');
// Do installation here
s.stop('Installed via npm');

Utilities

Grouping

Grouping prompts together is a great way to keep your code organized. This accepts a JSON object with a name that can be used to reference the group later. The second argument is an optional but has a onCancel callback that will be called if the user cancels one of the prompts in the group.

import * as p from '@stacksjs/cli';

const group = await p.group(
  {
    name: () => p.text({ message: 'What is your name?' }),
    age: () => p.text({ message: 'What is your age?' }),
    color: ({ results }) =>
      p.multiselect({
        message: `What is your favorite color ${results.name}?`,
        options: [
          { value: 'red', label: 'Red' },
          { value: 'green', label: 'Green' },
          { value: 'blue', label: 'Blue' },
        ],
      }),
  },
  {
    // On Cancel callback that wraps the group
    // So if the user cancels one of the prompts in the group this function will be called
    onCancel: ({ results }) => {
      p.cancel('Operation cancelled.');
      process.exit(0);
    },
  }
);

console.log(group.name, group.age, group.color);

Tasks

Execute multiple tasks in spinners.

await p.tasks([
  {
    title: 'Installing via npm',
    task: async (message) => {
      // Do installation here
      return 'Installed via npm';
    },
  },
]);

To view a more detailed example, check out Buddy.

You may also use any of the following CLI utilities:

import {
  ansi256Bg,
  bgBlack,
  bgBlue,
  bgCyan,
  bgGray,
  bgGreen,
  bgLightBlue,
  bgLightCyan,
  bgLightGray,
  bgLightGreen,
  bgLightMagenta,
  bgLightRed,
  bgLightYellow,
  bgMagenta,
  bgRed,
  bgWhite,
  bgYellow,
  black,
  blue,
  bold,
  cyan,
  dim,
  gray,
  green,
  hidden,
  inverse,
  italic,
  lightBlue,
  lightCyan,
  lightGray,
  lightGreen,
  lightMagenta,
  lightRed,
  lightYellow,
  link,
  magenta,
  red,
  reset,
  strikethrough,
  underline,
  white,
  yellow
} from '@stacksjs/cli'

log.info(`hello ${bold(italic('world'))}`)

To view the full documentation, please visit https://stacksjs.org/cli.

๐Ÿงช Testing

bun test

๐Ÿ“ˆ Changelog

Please see our releases page for more information on what has changed recently.

๐Ÿšœ Contributing

Please review the Contributing Guide for details.

๐Ÿ Community

For help, discussion about best practices, or any other conversation that would benefit from being searchable:

Discussions on GitHub

For casual chit-chat with others using this package:

Join the Stacks Discord Server

๐Ÿ™๐Ÿผ Credits

Many thanks to the following core technologies & people who have contributed to this package:

๐Ÿ“„ License

The MIT License (MIT). Please see LICENSE for more information.

Made with ๐Ÿ’™

0.67.0

8 months ago

0.65.0

8 months ago

0.62.0

11 months ago

0.63.0

10 months ago

0.63.1

10 months ago

0.61.23

1 year ago

0.61.24

1 year ago

0.61.21

1 year ago

0.61.20

1 year ago

0.64.6

10 months ago

0.64.3

10 months ago

0.64.2

10 months ago

0.64.5

10 months ago

0.64.4

10 months ago

0.64.1

10 months ago

0.64.0

10 months ago

0.61.12

1 year ago

0.61.13

1 year ago

0.61.9

1 year ago

0.61.10

1 year ago

0.61.11

1 year ago

0.61.6

1 year ago

0.61.5

1 year ago

0.61.8

1 year ago

0.61.7

1 year ago

0.61.18

1 year ago

0.61.19

1 year ago

0.61.16

1 year ago

0.61.17

1 year ago

0.61.14

1 year ago

0.61.15

1 year ago

0.61.2

1 year ago

0.61.1

1 year ago

0.61.4

1 year ago

0.61.3

1 year ago

0.61.0

1 year ago

0.59.11

1 year ago

0.59.8

1 year ago

0.59.9

1 year ago

0.59.7

1 year ago

0.59.10

1 year ago

0.59.2

1 year ago

0.59.3

1 year ago

0.59.1

1 year ago

0.59.6

1 year ago

0.59.4

1 year ago

0.59.5

1 year ago

0.58.73

1 year ago

0.58.72

1 year ago

0.58.70

1 year ago

0.58.71

1 year ago

0.58.69

1 year ago

0.58.65

1 year ago

0.58.66

1 year ago

0.58.67

1 year ago

0.58.68

1 year ago

0.58.61

1 year ago

0.58.62

1 year ago

0.58.63

1 year ago

0.58.64

1 year ago

0.58.59

1 year ago

0.58.58

1 year ago

0.58.57

1 year ago

0.58.56

1 year ago

0.58.55

1 year ago

0.58.52

1 year ago

0.58.53

1 year ago

0.58.50

1 year ago

0.58.51

1 year ago

0.58.49

1 year ago

0.58.47

1 year ago

0.58.48

1 year ago

0.58.43

1 year ago

0.58.44

1 year ago

0.58.45

1 year ago

0.58.46

1 year ago

0.58.27

1 year ago

0.58.28

1 year ago

0.58.19

1 year ago

0.58.20

1 year ago

0.58.21

1 year ago

0.58.22

1 year ago

0.58.24

1 year ago

0.57.4

2 years ago

0.57.2

2 years ago

0.57.3

2 years ago

0.56.24

2 years ago

0.56.23

2 years ago

0.56.28

2 years ago

0.56.27

2 years ago

0.56.29

2 years ago

0.56.35

2 years ago

0.56.34

2 years ago

0.56.31

2 years ago

0.56.30

2 years ago

0.56.33

2 years ago

0.56.32

2 years ago

0.56.3

2 years ago

0.52.10

2 years ago

0.53.1

2 years ago

0.52.9

2 years ago

0.52.7

2 years ago

0.52.8

2 years ago

0.52.5

2 years ago

0.52.6

2 years ago

0.52.3

2 years ago

0.52.4

2 years ago

0.52.1

2 years ago

0.52.2

2 years ago

0.52.0

2 years ago

0.51.0

2 years ago

0.50.0

2 years ago

0.44.10

2 years ago

0.49.1

2 years ago

0.48.2

2 years ago

0.46.4

2 years ago

0.44.11

2 years ago

0.44.6

2 years ago

0.49.2

2 years ago

0.48.3

2 years ago

0.47.4

2 years ago

0.44.12

2 years ago

0.44.7

2 years ago

0.47.1

2 years ago

0.46.2

2 years ago

0.49.0

2 years ago

0.48.1

2 years ago

0.47.2

2 years ago

0.46.3

2 years ago

0.46.0

2 years ago

0.45.1

2 years ago

0.47.0

2 years ago

0.46.1

2 years ago

0.45.2

2 years ago

0.45.0

2 years ago

0.49.3

2 years ago

0.44.8

2 years ago

0.44.9

2 years ago

0.43.1

3 years ago

0.43.0

3 years ago

0.42.2

3 years ago

0.42.1

3 years ago

0.41.1

3 years ago

0.41.0

3 years ago

0.40.0

3 years ago

0.39.1

3 years ago

0.39.0

3 years ago

0.38.4

3 years ago

0.38.3

3 years ago

0.38.2

3 years ago

0.38.1

3 years ago