'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