opta

1.1.0 • Public • Published

opta

We all have choices to make

NPM Version NPM Downloads test js-standard-style

Collect user input from cli flags, interactive prompts, and JS input.

Usage

$ npm i opta
const opta = require('opta')

// Create an opta instance
const opts = opta({
  options: {
    time: {
      type: 'number'
    },
    hello: {
      default: 'hello'
    },
    world: {
      default: 'world'
    }
  }
})

// .cli() returns an instance of yargs,
// configured with the options
const yargsInstance = opts.cli()

// Will set the appropriate values as
// configured on the yargs instance
yargsInstance(process.argv.slice(2))

// Set some overrides. These will take precedence,
// but also will prevent `.prompt()` from asking
// the user
opts.overrides(overrides)

// Set detauls. These will be used as
// defaults when prompting, and fill in
// values not specified in other ways
opts.defaults(defaults)

// Display prompts using inquirer, will
// populate values with input from user
const promptor = opts.prompt()
await promptor()

// Get the values after cli, overrides,
// and prompt input
const values = opts.values()

// An example of using the values
setTimeout(() => {
  console.log(`${values.hello} ${values.world}`)
}, values.time)

Composition of options

One of the primary focuses of opta is to enable easy composition of inputs across projects. If a project exports it's opta instance, another can simply combine their options parameters like this:

const opta = require('opta')

// Project One exports a key `opts` which is
// an instance of `opta`, along with it's other functionality
const projectOne = require('project-one')

// My Project which wants to expose functionality from
// Project One can simply merge `opts.options` into the
// options passed to my instance
const myOpts = opta({
  options: {
    ...projectOne.opts.options,
    myOptions: true,
    // You can also simply override the options descriptor
    // from `projectOne.opts`.  In this example we disable
    // the prompt but leave the rest alone
    projectOneOpt: {
      ...projectOne.opts.options.projectOneOpt,
      prompt: false
    }
  }
})

// Now when we call .cli(), .prompt(), and .values()
// we will get options from both the composed options
// and our projects
await myOpts.prompt()
const vals = myOpts.values()
console.log(vals) // all options from both Project and My Project

Prompt Testing

Testing user input can be difficult. This package exports a test helper which can mimic different behaviors of users interacting with prompts without dealing with the complicated work to actually handle user input. Here is an example:

const test = require('node:test');
const assert = require('node:assert')
const opta = require('opta')
const optaUtils = require('opta/utils')

test('some test', async (t) => {
  const opts = opta({
    options: {
      foo: true,
      bar: true
    },
    // Create a promptModule mock
    promptModule: optaUtils.test.promptModule({
      // Will assert that two prompts were displayed
      assertCount: 2,
      prompts: {
        foo: {
          // Set a value as if it was user input
          value: 'foo',
          
          // Assert some things about the prompt config
          // which is passed on to inquirer
          assert: (p) =>{
            assert.strictEqual(p.name, 'foo')
            assert.strictEqual(p.message, 'foo:')
            assert.strictEqual(p.type, 'input')
            assert.strictEqual(p.when, true)
          },

          // Setup a context object which is passed to the prompt
          // default if it is a function
          defaultContext: {}
        },

        // Or more simply, just set value directly
        bar: 'bar'
      }
    })
  })

  // Run the opta prompts
  await opts.prompt()()
  const values = opts.values({ baz: 'baz' })
  assert.deepStrictEqual(values, {
    foo: 'foo',
    bar: 'bar',
    baz: 'baz'
  })
})

Package Sidebar

Install

npm i opta

Weekly Downloads

85

Version

1.1.0

License

ISC

Unpacked Size

35.9 kB

Total Files

19

Last publish

Collaborators

  • wesleytodd