1.4.1 • Published 4 years ago

reloquent v1.4.1

Weekly downloads
7
License
MIT
Repository
github
Last release
4 years ago

reloquent

npm version Build status

Reloquent allows to ask users a question, a confirmation (y/n), or a series of questions via the read-line interface.

yarn add reloquent
npm i reloquent

Table Of Contents

API

There are 4 types of calls to the API:

  • ask a single question as a string;
  • ask a single question as an object;
  • ask multiple questions.
  • ask for a confirmation;

Their respective methods can be accessed via the import statement:

import ask, { askSingle, confirm } from 'reloquent'

Question Type

When asking a question which is not a string, the question object should have the following structure:

const q = {
  text: 'What is your name',
}
const q = {
  text: 'What is your name',
  validate(v) {
    if (!v.length) {
      throw new Error('Name required.')
    }
  },
}
const q = {
  text: 'What is your name',
  postProcess(v) {
    return `${v.toLowerCase()}`
  },
}

Default answer (shown to users in [default] brackets).

const q = {
  text: 'What is your name',
  defaultValue: 'Visitor',
}
const q = {
  text: 'What is your name',
  async getDefault() {
    await git('config', 'user.name')
  },
}
const q = {
  text: 'Please enter the password',
  password: true,
}

If both defaultValue and getDefault are provided, the result of the getDefault takes precedence:

const q = {
  defaultValue: 'I desire it much',
  getDefault() {
    return 'I desire it much so'
  },
}

getDefault will get precedence

When the password property is set to true, the answer will be hidden behind the * symbols.

import { askSingle  } from 'reloquent'

const Password = async () => {
  const res = await askSingle({
    text: 'Please enter the password',
    password: true,
  })
  return res
}
Please enter the password: ********
NameTypeDescriptionDefault
text*stringThe text to show to the user.-
defaultValuestringThe default answer to the question.-
passwordbooleanHide the inputs behind * when typing the answer.false
getDefault() => (string | !Promise<string>)The function which will get the default value, possibly asynchronously.-
validation(answer: string) => voidThe validation function which should throw on error.-
postProcess(answer: string) => (string | !Promise<string>)The transformation function for the answer.-

async askSingle(  question: (string|!Question),  timeout=: number,): string

Ask user a question via the CLI. Returns the answer to the question. If a timeout is passed, the promise will expire after the specified number of milliseconds if the answer was not given.

  • question* (string | !Question): The question to present to the user.
  • timeout number (optional): How long to wait before rejecting the promise. Waits forever by default.

Questions can be asked as a simple string.

import { askSingle } from 'reloquent'

(async () => {
  try {
    const answer = await askSingle('What brought you her', 10000)
    console.log(`You've answered: ${answer}`)
  } catch (err) {
    console.log()
    console.log(err)
    console.log('Nevermind...')
  }
})()
What brought you her: I guess Art is the cause.
You've answered: I guess Art is the cause.

Alternatively, Reloquent can ask a question which is passed as an object of the Question type, and return a string.

import { askSingle } from 'reloquent'

(async () => {
  const answer = await askSingle({
    text: 'Do you wish me to stay so long?',
    validation(a) {
      if (a.length < 5) {
        throw new Error('The answer is too short')
      }
    },
    defaultValue: 'I desire it much',
    postProcess(a) {
      return `${a}!`
    },
    async getDefault() {
      return 'I desire it much so'
    },
  })
  console.log(answer)
})()
Do you wish me to stay so long? [I desire it much]
I desire it much!

async askQuestions(  questions: !Questions,  timeout=: number,): !Object<string, string>

Ask user a series of questions via CLI and transform them into answers. Returns an object with keys as questions' texts and values as answers.

  • questions* !Questions: A set of questions.
  • timeout number (optional): How long to wait before rejecting the promise. Waits forever by default.

!Object<string, (string | !Question)> Questions: A set of questions.

import ask from 'reloquent'

const Ask = async () => {
  const questions = {
    title: {
      text: 'Title',
      validation(a) {
        if (!a) throw new Error('Please enter the title.')
      },
    },
    description: {
      text: 'Description',
      postProcess: s => s.trim(),
      defaultValue: 'A test default value',
    },
    date: {
      text: 'Date',
      async getDefault() {
        await new Promise(r => setTimeout(r, 200))
        return new Date().toLocaleString()
      },
    },
  }
  const res = await ask(questions)
  return res
}

If when provided with the following answers (leaving Date as it is), the result will be returned as an object:

Title: hello
Description: [A test default value] world
Date: [2/22/2020, 21:37:04] 

Result: {
  "title": "hello",
  "description": "world",
  "date": "2/22/2020, 21:37:04"
}

async confirm(  question: (string|!Question),  options=: !ConfirmOptions,): boolean

Ask a yes/no question. Returns true when answer was y and false otherwise.

  • question* (string | !Question): The question, such as "Add default options", or "Continue to delete?". The question mark can added automatically.
  • options !ConfirmOptions (optional): Options for the confirmation question.

ConfirmOptions: Options for the confirmation question.

NameTypeDescriptionDefault
defaultYesbooleanWhether the default value is yes.true
timeoutnumberHow long to wait before rejecting the promise. Waits forever by default.-
import { confirm } from 'reloquent'

const Confirm = async (question) => {
  const res = await confirm(question, {
    defaultYes: false,
  })
  return res
}
Do you wish to continue (y/n): [n] y

Result: true

Copyright

1.4.1

4 years ago

1.4.0

4 years ago

1.3.2

5 years ago

1.3.1

5 years ago

1.3.0

5 years ago

1.2.4

5 years ago

1.2.3

6 years ago

1.2.2

6 years ago

1.2.1

6 years ago

1.2.0

6 years ago

1.1.0

6 years ago

1.0.6

6 years ago

1.0.5

6 years ago

1.0.4

6 years ago

1.0.3

6 years ago

1.0.2

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago

0.2.0

7 years ago

0.1.2

7 years ago

0.1.1

7 years ago

0.1.0

7 years ago