Skip to content

liquid-labs/question-and-answer

Repository files navigation

question-and-answer

coverage: 72%

Library providing command-line question and answer functionality.

This is an alpha project. The basic interface is stable, but there are some known issues and further testing required before the interface and behavior can be locked in entirely.

Installation

npm i question-and-answer

Usage

Library usage

import { Questioner } from 'question-and-answer'

const interrogationBundle = {
  "actions": [
    { "statement": "Let us know your thoughts!" },
    { 
      "prompt": "What are your 2 or 3 favorite colors?",
      "multiValue": true,
      "requireMinCount": 2,
      "requireMaxCount": 3,
      "parameter": "FAVORITE_COLOR"
    },
    {
      "prompt": "What's your favorite integer number?",
      "paramType": "integer",
      "parameter": "FAVORITE_NUMBER"
    },
    { 
      "prompt": "Which is best?",
      "options": [ "love", "honor", "justice" ],
      "parameter": "BEST_VIRTUE"
    },
    {
      "maps": [
        { "source": "FAVORITE_NUMBER > 99", "parameter": "GT100", "paramType": "boolean" },
        { "source": "FAVORITE_NUMBER * 2", "parameter": "TWOX", "paramType": "integer" }
      ]
    },
    { "review": "questions" }
  ]
}

const questioner = new Questioner({ interrogationBundle })
await questioner.question()

console.log(`Favorite color: ${questioner.get('FAVORITE_COLOR')}`)
console.log(`Best virtue: ${questioner.get('BEST_VIRTUE')}`)

CLI usage

npx qna path/to/interrogation-bundle.json

The CLI is intended mainly a way to test/demonstraite interrogation bundles.

User's Guide

Interrogation bundle format

  • The bundle defines an array of actions.
  • Each action is either a question, map, statement, or review.
  • A question asks the user a question and sets a parameter based on the answer.
  • A map maps existing parameters to a new parameter bassed on a condition-eval string.
  • A statement displays text to the user.
  • A review initiates a review of previously set questions not already reviewed.*
  • Each action has exactly one of the following fields, which defines its type:
    • "prompt": for question type actions,
    • "statement": displays the statement value,
    • "maps": defines an array of maps,
    • "review": triggers a review of either "all" or "questions".
  • Any action may define an optional "condition" string, evaluated accordig to condition-eval
  • Each parameter setting action (question or map) defines:
    • exactly one "parameter" string,
    • an optional "paramType" string of "bool", "boolean", "int", "intefer", "float", "numeric", or "string" (default)
    • an optional "noSkipDefined" parameter which, if true, will execute the action even if the named "parameter" is defined
  • Each question defines:
    • exactly one "prompt" string,
    • an optional "default" value,
    • an optional "options" array of strings,
    • an optional "multiValue" boolean,
    • an optional "elseSource"; the value is a parameter name whose value is used to set the "parameter" if the "condition" fails
    • optional requirement fields:
      • "requireSomething" dissalows empty responses,
      • "requireTruthy" requires a true boolean, non-empty string, or non-zero integer,
      • "requireExact" requires an exact match
      • "requireMatch" defines a regular expression which must match the answer (only applicable to strings),
      • "requireOneOf" defines a comma separated list of values, one of which musts match the answer,
      • "requireMinCount" defines a minimum number of answers for a multi-value question, and
      • "requireMaxCount" defines a maximum number of answers for a multi-value question.
  • each map entry defines one of:
    • an optional "source" a condition-eval statement, or
    • an optional "value" a literal value
  • a review may have a value of "questions", "maps", or "all"

Interrogation flow

  1. Each action is evaluated in order.
  2. We determine whether an action is skipped:
    • If present, the "condition" is evaluated and the action is skipped unless the "condition" evalutaess truthy.
    • Question and map actions are skipped (even if "condition" is truthy) if the "parameter" value is already defined unless "noSkipDefined" is set true for the action or the Questioner.
  3. Non-skipped actions are executed.
    • Statements are displayed.
    • Maps are calculated.
    • Questions are asked.
    • Reviews are performed.

"Asking a question" means:

  1. A default value is determined by:
    1. The current value of the "parameter", if any.
    2. The value of the "default" field.
  2. The question is displayed (either free-form or by displaying the selectable, numbered "options").
    1. If there is a default value, it is displayed in the prompt and will be used if the user just hits <ENTER> with no other input.
    2. If there are any requirements, they are evaluated against the answer and teh question is re-asked until the requirements are met.

"Performing a review" means:

  1. Determine the values to review.
    1. Any previously reviewed value is excluded.*
    2. A 'questions' review reviews only question values whereas an 'all' reviews qusetion and map values.
  2. Display the values, in order, with the option to accept (hit <ENTER>) or change the value.

To changeg a default value to literal nothing (empty string, null value), enter '-'. This "clears" the current value.

*Review note: the review does not currently skip previously reviewed items as it should. This is a known issue.

Examples