npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@poppinss/prompts

v3.1.3

Published

Wrapper over enquirer with better support for testing

Downloads

138,707

Readme

@poppinss/prompts

Wrapper over enquirer with better support for testing

gh-workflow-image typescript-image npm-image license-image

Why this package exists?

There are many CLI prompts libraries in the Node ecosystem. However, they all fall short when it comes to writing tests that involve prompts.

Let's say you are writing tests for a command that triggers CLI prompts. Unfortunately, the CLI process will stall since it is waiting for manual input.

This package makes testing prompts easier by allowing you to trap them during testing.

It is worth noting we only export the following prompts from the enquirer package, and also, the API is somewhat different.

  • input
  • list
  • password
  • confirm
  • toggle
  • select
  • multiselect
  • autocomplete

Usage

Install the package from the npm registry as follows.

npm i @poppinss/prompts

# Yarn lovers
yarn add @poppinss/prompts

Next, create an instance of the prompt class. If you want, you can re-use the single instance throughout the entire process lifecycle.

import { Prompt } from '@poppinss/prompts'

const prompt = new Prompt()

const modelName = await prompt.ask('Specify the model name')

const drivers = await prompt.multiple(
  'Select database drivers',
  [
    {
      name: 'sqlite',
      message: 'SQLite3',
    },
    {
      name: 'mysql',
      message: 'MYSQL',
    },
  ],
  {
    validate(choices) {
      return choices.length > 0
    }
  }
)

Available prompts

Following is the list of available prompts

ask

Prompt the user to type text. The ask method uses the enquirer input prompt.

The method accepts the prompt message as the first param and the options object as the second param.

await prompt.ask('Specify the model name')
// Validate input
await prompt.ask('Specify the model name', {
  validate(value) {
    return value.length > 0
  }
})
// Default value
await prompt.ask('Specify the model name', {
  default: 'User'
})

secure

Prompt the user to type text. The output on the terminal gets masked with a star *. The secure method uses the enquirer password prompt.

The method accepts the prompt message as the first param and the options object as the second param.

await prompt.secure('Enter account password')
await prompt.secure('Enter account password', {
  validate(value) {
    return value.length < 6
      ? 'Password must be 6 characters long'
      : true
  }
})

list

The list method uses the enquirer list prompt. It allows you to accept a comma-separated list of values.

const tags = await prompt.list('Enter tags to assign')
// Default list of tags
const tags = await prompt.list('Enter tags to assign', {
  default: ['node.js', 'javascript']
})

confirm

The confirm method uses enquirer confirm prompt. It presents the user with a Y/N option and returns a boolean value.

const shouldDeleteFiles = await prompt.confirm('Want to delete all files?')

if (shouldDeleteFiles) {
  // take action
}

toggle

The toggle prompt is similar to the confirm prompt but allows you to specify custom display values for true and false.

const shouldDeleteFiles = await prompt.confirm('Want to delete all files?', ['Yup', 'Nope'])

if (shouldDeleteFiles) {
  // take action
}

choice

The choice method uses the enquirer select prompt. It allows you to display a list of choices for selection.

await prompt.choice('Select package manager', [
  'npm',
  'yarn',
  'pnpm'
])

The selection options can also be an object with the name and the message properties.

  • The value of the name property is returned as the prompt result.
  • The message property is displayed in the terminal.
await prompt.choice('Select database driver', [
  {
    name: 'sqlite',
    message: 'SQLite'
  },
  {
    name: 'mysql',
    message: 'MySQL'
  },
  {
    name: 'pg',
    message: 'PostgreSQL'
  }
])

multiple

The multiple method uses the enquirer multiselect prompt. It allows you to display a list of choices for multiple selections.

await prompt.multiple('Select database driver', [
  {
    name: 'sqlite',
    message: 'SQLite'
  },
  {
    name: 'mysql',
    message: 'MySQL'
  },
  {
    name: 'pg',
    message: 'PostgreSQL'
  }
])

autocomplete

The autocomplete prompt is a combination of the select and the multiselect prompt, but with the ability to fuzzy search the choices.

const cities = []

await prompt.autocomplete('Select your city', cities)

Prompt Options

Following is the list of options accepted by the prompts.

Testing traps

The biggest reason for using this package is for the testing traps API. Testing traps allow you to handle prompts programmatically.

In the following example, we trap the prompt by its display message and answer it using the replyWith method.

import { Prompt } from '@poppinss/prompts'
const prompt = new Prompt()

test('test some example command', () => {
  prompt.trap('Specify the model name').replyWith('User')

  // run command that triggers the prompt
})

The prompt.trap method matches the exact prompt message. You can also assign a unique name to your prompts and use that for trapping the prompt. For example:

await prompt.ask('Specify the model name', {
  name: 'modelName'
})

// Trap with prompt name
prompt.trap('modelName')

Assertions

You can define assertions on the prompt to test the validate method behavior. For example: Assert that the validate method disallows empty strings.

prompt
  .trap('modelName')
  .assertFails('')

// Assert the validation method to print a specific error message
prompt
  .trap('modelName')
  .assertFails('', 'Enter model name')

The assertFails method accepts the input to be tested against the validate method. The second argument is an optional message you expect the validate method to print.

Similarly, you can use the assertPasses method to test whether the validate method allows for acceptable values.

prompt
  .trap('modelName')
  .assertPasses('User')
  .assertPasses('app_user')
  .assertPasses('models/User')
  .replyWith('User')

Traps API

Following is the list of available methods on a trapped prompt.

replyWith

Set the return value for the prompt.

prompt.trap('modelName').replyWith('User')

accept

Accept the toggle and the confirm prompts with a true value.

prompt.trap('Want to delete all files?').accept()

reject

Reject the toggle and the confirm prompts with a false value.

prompt.trap('Want to delete all files?').reject()

chooseOption

Choose an option by its index for a select prompt.

prompt
  .trap('Select package manager')
  .chooseOption(0)

If you do not choose any option explicitly, then the first option will be selected by default.

chooseOptions

Choose multiple options by their indexes for a multiselect prompt.

prompt
  .trap('Select database manager')
  .chooseOptions([1, 2])

Handling prompts cancellation error

Enquirer throws an error when a prompt is cancelled using Ctrl + C. You can capture the exception by wrapping the prompt display code inside a try/catch block and check for E_PROMPT_CANCELLED error.

import { Prompt, errors } from '@poppinss/prompts'

const prompt = new Prompt()

try {
  const modelName = await prompt.ask('Specify the model name')
} catch (error) {
  if (error instanceof errors.E_PROMPT_CANCELLED) {
    console.log('Prompt cancelled')
  }
}