[6a3a178] | 1 | 'use strict'
|
---|
| 2 |
|
---|
| 3 | const logQueue = require('./log-queue')
|
---|
| 4 |
|
---|
| 5 | let questions
|
---|
| 6 | let currentQuestion
|
---|
| 7 | let answers
|
---|
| 8 | let currentOptions
|
---|
| 9 | let currentOptionsPointer
|
---|
| 10 | let currentQuestionId
|
---|
| 11 | let done
|
---|
| 12 |
|
---|
| 13 | class StateMachine {
|
---|
| 14 | constructor (rli, colors) {
|
---|
| 15 | this.rli = rli
|
---|
| 16 | this.colors = colors
|
---|
| 17 | }
|
---|
| 18 |
|
---|
| 19 | showPrompt () {
|
---|
| 20 | this.rli.write(this.colors.ANSWER)
|
---|
| 21 | this.rli.prompt()
|
---|
| 22 | }
|
---|
| 23 |
|
---|
| 24 | onKeypress (key) {
|
---|
| 25 | if (!currentOptions || !key) {
|
---|
| 26 | return
|
---|
| 27 | }
|
---|
| 28 |
|
---|
| 29 | if (key.name === 'tab' || key.name === 'right' || key.name === 'down') {
|
---|
| 30 | this.suggestOption(currentOptionsPointer + 1)
|
---|
| 31 | } else if (key.name === 'left' || key.name === 'up') {
|
---|
| 32 | this.suggestOption(currentOptionsPointer - 1)
|
---|
| 33 | }
|
---|
| 34 |
|
---|
| 35 | if (!key.ctrl && !key.meta && key.name !== 'enter' && key.name !== 'return') {
|
---|
| 36 | key.name = 'escape'
|
---|
| 37 | }
|
---|
| 38 | }
|
---|
| 39 |
|
---|
| 40 | suggestOption (index) {
|
---|
| 41 | if (!currentOptions) {
|
---|
| 42 | return
|
---|
| 43 | }
|
---|
| 44 |
|
---|
| 45 | if (index === -1) {
|
---|
| 46 | currentOptionsPointer = currentOptions.length - 1
|
---|
| 47 | } else if (index === currentOptions.length) {
|
---|
| 48 | currentOptionsPointer = 0
|
---|
| 49 | } else {
|
---|
| 50 | currentOptionsPointer = index
|
---|
| 51 | }
|
---|
| 52 |
|
---|
| 53 | this.rli._deleteLineLeft()
|
---|
| 54 | this.rli._deleteLineRight()
|
---|
| 55 | this.rli.write(currentOptions[currentOptionsPointer])
|
---|
| 56 | }
|
---|
| 57 |
|
---|
| 58 | kill () {
|
---|
| 59 | currentOptions = null
|
---|
| 60 | currentQuestionId = null
|
---|
| 61 | this.rli.write('\n' + this.colors.RESET + '\n')
|
---|
| 62 | this.rli.close()
|
---|
| 63 | }
|
---|
| 64 |
|
---|
| 65 | onLine (line) {
|
---|
| 66 | if (currentQuestionId) {
|
---|
| 67 | this.rli.write(this.colors.RESET)
|
---|
| 68 | line = line.trim().replace(this.colors.ANSWER, '').replace(this.colors.RESET, '')
|
---|
| 69 |
|
---|
| 70 | if (currentOptions) {
|
---|
| 71 | currentOptionsPointer = currentOptions.indexOf(line)
|
---|
| 72 | if (currentOptionsPointer === -1) {
|
---|
| 73 | return
|
---|
| 74 | }
|
---|
| 75 | }
|
---|
| 76 |
|
---|
| 77 | if (line === '') {
|
---|
| 78 | line = null
|
---|
| 79 | }
|
---|
| 80 |
|
---|
| 81 | if (currentQuestion.boolean) {
|
---|
| 82 | line = (line === 'yes' || line === 'true' || line === 'on')
|
---|
| 83 | }
|
---|
| 84 |
|
---|
| 85 | if (line !== null && currentQuestion.validate) {
|
---|
| 86 | currentQuestion.validate(line)
|
---|
| 87 | }
|
---|
| 88 |
|
---|
| 89 | if (currentQuestion.multiple) {
|
---|
| 90 | answers[currentQuestionId] = answers[currentQuestionId] || []
|
---|
| 91 | if (line !== null) {
|
---|
| 92 | answers[currentQuestionId].push(line)
|
---|
| 93 | this.showPrompt()
|
---|
| 94 |
|
---|
| 95 | if (currentOptions) {
|
---|
| 96 | currentOptions.splice(currentOptionsPointer, 1)
|
---|
| 97 | currentOptionsPointer = -1
|
---|
| 98 | }
|
---|
| 99 | } else {
|
---|
| 100 | this.nextQuestion()
|
---|
| 101 | }
|
---|
| 102 | } else {
|
---|
| 103 | answers[currentQuestionId] = line
|
---|
| 104 | this.nextQuestion()
|
---|
| 105 | }
|
---|
| 106 | }
|
---|
| 107 | }
|
---|
| 108 |
|
---|
| 109 | nextQuestion () {
|
---|
| 110 | currentQuestion = questions.shift()
|
---|
| 111 |
|
---|
| 112 | while (currentQuestion && currentQuestion.condition && !currentQuestion.condition(answers)) {
|
---|
| 113 | currentQuestion = questions.shift()
|
---|
| 114 | }
|
---|
| 115 |
|
---|
| 116 | logQueue.printLogQueue()
|
---|
| 117 |
|
---|
| 118 | if (currentQuestion) {
|
---|
| 119 | currentQuestionId = null
|
---|
| 120 |
|
---|
| 121 | this.rli.write('\n' + this.colors.question(currentQuestion.question) + '\n')
|
---|
| 122 | this.rli.write(currentQuestion.hint + '\n')
|
---|
| 123 | this.showPrompt()
|
---|
| 124 |
|
---|
| 125 | currentOptions = currentQuestion.options || null
|
---|
| 126 | currentQuestionId = currentQuestion.id
|
---|
| 127 | this.suggestOption(0)
|
---|
| 128 | } else {
|
---|
| 129 | this.kill()
|
---|
| 130 | done(answers)
|
---|
| 131 | }
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | process (_questions, _done) {
|
---|
| 135 | questions = _questions
|
---|
| 136 | answers = {}
|
---|
| 137 | done = _done
|
---|
| 138 |
|
---|
| 139 | this.nextQuestion()
|
---|
| 140 | }
|
---|
| 141 | }
|
---|
| 142 |
|
---|
| 143 | module.exports = StateMachine
|
---|