lib/init/state_machine.js
'use strict'
const logQueue = require('./log-queue')
let questions
let currentQuestion
let answers
let currentOptions
let currentOptionsPointer
let currentQuestionId
let done
class StateMachine {
constructor (rli, colors) {
this.rli = rli
this.colors = colors
}
showPrompt () {
this.rli.write(this.colors.ANSWER)
this.rli.prompt()
}
onKeypress (key) {
if (!currentOptions || !key) {
return
}
if (key.name === 'tab' || key.name === 'right' || key.name === 'down') {
this.suggestOption(currentOptionsPointer + 1)
} else if (key.name === 'left' || key.name === 'up') {
this.suggestOption(currentOptionsPointer - 1)
}
if (!key.ctrl && !key.meta && key.name !== 'enter' && key.name !== 'return') {
key.name = 'escape'
}
}
suggestOption (index) {
if (!currentOptions) {
return
}
if (index === -1) {
currentOptionsPointer = currentOptions.length - 1
} else if (index === currentOptions.length) {
currentOptionsPointer = 0
} else {
currentOptionsPointer = index
}
this.rli._deleteLineLeft()
this.rli._deleteLineRight()
this.rli.write(currentOptions[currentOptionsPointer])
}
kill () {
currentOptions = null
currentQuestionId = null
this.rli.write('\n' + this.colors.RESET + '\n')
this.rli.close()
}
onLine (line) {
if (currentQuestionId) {
this.rli.write(this.colors.RESET)
line = line.trim().replace(this.colors.ANSWER, '').replace(this.colors.RESET, '')
if (currentOptions) {
currentOptionsPointer = currentOptions.indexOf(line)
if (currentOptionsPointer === -1) {
return
}
}
if (line === '') {
line = null
}
if (currentQuestion.boolean) {
line = (line === 'yes' || line === 'true' || line === 'on')
}
if (line !== null && currentQuestion.validate) {
currentQuestion.validate(line)
}
if (currentQuestion.multiple) {
answers[currentQuestionId] = answers[currentQuestionId] || []
if (line !== null) {
answers[currentQuestionId].push(line)
this.showPrompt()
if (currentOptions) {
currentOptions.splice(currentOptionsPointer, 1)
currentOptionsPointer = -1
}
} else {
this.nextQuestion()
}
} else {
answers[currentQuestionId] = line
this.nextQuestion()
}
}
}
nextQuestion () {
currentQuestion = questions.shift()
while (currentQuestion && currentQuestion.condition && !currentQuestion.condition(answers)) {
currentQuestion = questions.shift()
}
logQueue.printLogQueue()
if (currentQuestion) {
currentQuestionId = null
this.rli.write('\n' + this.colors.question(currentQuestion.question) + '\n')
this.rli.write(currentQuestion.hint + '\n')
this.showPrompt()
currentOptions = currentQuestion.options || null
currentQuestionId = currentQuestion.id
this.suggestOption(0)
} else {
this.kill()
done(answers)
}
}
process (_questions, _done) {
questions = _questions
answers = {}
done = _done
this.nextQuestion()
}
}
module.exports = StateMachine