| 1 | "use strict";
|
|---|
| 2 |
|
|---|
| 3 | function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|---|
| 4 |
|
|---|
| 5 | function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|---|
| 6 |
|
|---|
| 7 | const color = require('kleur');
|
|---|
| 8 |
|
|---|
| 9 | const Prompt = require('./prompt');
|
|---|
| 10 |
|
|---|
| 11 | const _require = require('sisteransi'),
|
|---|
| 12 | erase = _require.erase,
|
|---|
| 13 | cursor = _require.cursor;
|
|---|
| 14 |
|
|---|
| 15 | const _require2 = require('../util'),
|
|---|
| 16 | style = _require2.style,
|
|---|
| 17 | clear = _require2.clear,
|
|---|
| 18 | lines = _require2.lines,
|
|---|
| 19 | figures = _require2.figures;
|
|---|
| 20 | /**
|
|---|
| 21 | * TextPrompt Base Element
|
|---|
| 22 | * @param {Object} opts Options
|
|---|
| 23 | * @param {String} opts.message Message
|
|---|
| 24 | * @param {String} [opts.style='default'] Render style
|
|---|
| 25 | * @param {String} [opts.initial] Default value
|
|---|
| 26 | * @param {Function} [opts.validate] Validate function
|
|---|
| 27 | * @param {Stream} [opts.stdin] The Readable stream to listen to
|
|---|
| 28 | * @param {Stream} [opts.stdout] The Writable stream to write readline data to
|
|---|
| 29 | * @param {String} [opts.error] The invalid error label
|
|---|
| 30 | */
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 | class TextPrompt extends Prompt {
|
|---|
| 34 | constructor(opts = {}) {
|
|---|
| 35 | super(opts);
|
|---|
| 36 | this.transform = style.render(opts.style);
|
|---|
| 37 | this.scale = this.transform.scale;
|
|---|
| 38 | this.msg = opts.message;
|
|---|
| 39 | this.initial = opts.initial || ``;
|
|---|
| 40 |
|
|---|
| 41 | this.validator = opts.validate || (() => true);
|
|---|
| 42 |
|
|---|
| 43 | this.value = ``;
|
|---|
| 44 | this.errorMsg = opts.error || `Please Enter A Valid Value`;
|
|---|
| 45 | this.cursor = Number(!!this.initial);
|
|---|
| 46 | this.cursorOffset = 0;
|
|---|
| 47 | this.clear = clear(``, this.out.columns);
|
|---|
| 48 | this.render();
|
|---|
| 49 | }
|
|---|
| 50 |
|
|---|
| 51 | set value(v) {
|
|---|
| 52 | if (!v && this.initial) {
|
|---|
| 53 | this.placeholder = true;
|
|---|
| 54 | this.rendered = color.gray(this.transform.render(this.initial));
|
|---|
| 55 | } else {
|
|---|
| 56 | this.placeholder = false;
|
|---|
| 57 | this.rendered = this.transform.render(v);
|
|---|
| 58 | }
|
|---|
| 59 |
|
|---|
| 60 | this._value = v;
|
|---|
| 61 | this.fire();
|
|---|
| 62 | }
|
|---|
| 63 |
|
|---|
| 64 | get value() {
|
|---|
| 65 | return this._value;
|
|---|
| 66 | }
|
|---|
| 67 |
|
|---|
| 68 | reset() {
|
|---|
| 69 | this.value = ``;
|
|---|
| 70 | this.cursor = Number(!!this.initial);
|
|---|
| 71 | this.cursorOffset = 0;
|
|---|
| 72 | this.fire();
|
|---|
| 73 | this.render();
|
|---|
| 74 | }
|
|---|
| 75 |
|
|---|
| 76 | exit() {
|
|---|
| 77 | this.abort();
|
|---|
| 78 | }
|
|---|
| 79 |
|
|---|
| 80 | abort() {
|
|---|
| 81 | this.value = this.value || this.initial;
|
|---|
| 82 | this.done = this.aborted = true;
|
|---|
| 83 | this.error = false;
|
|---|
| 84 | this.red = false;
|
|---|
| 85 | this.fire();
|
|---|
| 86 | this.render();
|
|---|
| 87 | this.out.write('\n');
|
|---|
| 88 | this.close();
|
|---|
| 89 | }
|
|---|
| 90 |
|
|---|
| 91 | validate() {
|
|---|
| 92 | var _this = this;
|
|---|
| 93 |
|
|---|
| 94 | return _asyncToGenerator(function* () {
|
|---|
| 95 | let valid = yield _this.validator(_this.value);
|
|---|
| 96 |
|
|---|
| 97 | if (typeof valid === `string`) {
|
|---|
| 98 | _this.errorMsg = valid;
|
|---|
| 99 | valid = false;
|
|---|
| 100 | }
|
|---|
| 101 |
|
|---|
| 102 | _this.error = !valid;
|
|---|
| 103 | })();
|
|---|
| 104 | }
|
|---|
| 105 |
|
|---|
| 106 | submit() {
|
|---|
| 107 | var _this2 = this;
|
|---|
| 108 |
|
|---|
| 109 | return _asyncToGenerator(function* () {
|
|---|
| 110 | _this2.value = _this2.value || _this2.initial;
|
|---|
| 111 | _this2.cursorOffset = 0;
|
|---|
| 112 | _this2.cursor = _this2.rendered.length;
|
|---|
| 113 | yield _this2.validate();
|
|---|
| 114 |
|
|---|
| 115 | if (_this2.error) {
|
|---|
| 116 | _this2.red = true;
|
|---|
| 117 |
|
|---|
| 118 | _this2.fire();
|
|---|
| 119 |
|
|---|
| 120 | _this2.render();
|
|---|
| 121 |
|
|---|
| 122 | return;
|
|---|
| 123 | }
|
|---|
| 124 |
|
|---|
| 125 | _this2.done = true;
|
|---|
| 126 | _this2.aborted = false;
|
|---|
| 127 |
|
|---|
| 128 | _this2.fire();
|
|---|
| 129 |
|
|---|
| 130 | _this2.render();
|
|---|
| 131 |
|
|---|
| 132 | _this2.out.write('\n');
|
|---|
| 133 |
|
|---|
| 134 | _this2.close();
|
|---|
| 135 | })();
|
|---|
| 136 | }
|
|---|
| 137 |
|
|---|
| 138 | next() {
|
|---|
| 139 | if (!this.placeholder) return this.bell();
|
|---|
| 140 | this.value = this.initial;
|
|---|
| 141 | this.cursor = this.rendered.length;
|
|---|
| 142 | this.fire();
|
|---|
| 143 | this.render();
|
|---|
| 144 | }
|
|---|
| 145 |
|
|---|
| 146 | moveCursor(n) {
|
|---|
| 147 | if (this.placeholder) return;
|
|---|
| 148 | this.cursor = this.cursor + n;
|
|---|
| 149 | this.cursorOffset += n;
|
|---|
| 150 | }
|
|---|
| 151 |
|
|---|
| 152 | _(c, key) {
|
|---|
| 153 | let s1 = this.value.slice(0, this.cursor);
|
|---|
| 154 | let s2 = this.value.slice(this.cursor);
|
|---|
| 155 | this.value = `${s1}${c}${s2}`;
|
|---|
| 156 | this.red = false;
|
|---|
| 157 | this.cursor = this.placeholder ? 0 : s1.length + 1;
|
|---|
| 158 | this.render();
|
|---|
| 159 | }
|
|---|
| 160 |
|
|---|
| 161 | delete() {
|
|---|
| 162 | if (this.isCursorAtStart()) return this.bell();
|
|---|
| 163 | let s1 = this.value.slice(0, this.cursor - 1);
|
|---|
| 164 | let s2 = this.value.slice(this.cursor);
|
|---|
| 165 | this.value = `${s1}${s2}`;
|
|---|
| 166 | this.red = false;
|
|---|
| 167 |
|
|---|
| 168 | if (this.isCursorAtStart()) {
|
|---|
| 169 | this.cursorOffset = 0;
|
|---|
| 170 | } else {
|
|---|
| 171 | this.cursorOffset++;
|
|---|
| 172 | this.moveCursor(-1);
|
|---|
| 173 | }
|
|---|
| 174 |
|
|---|
| 175 | this.render();
|
|---|
| 176 | }
|
|---|
| 177 |
|
|---|
| 178 | deleteForward() {
|
|---|
| 179 | if (this.cursor * this.scale >= this.rendered.length || this.placeholder) return this.bell();
|
|---|
| 180 | let s1 = this.value.slice(0, this.cursor);
|
|---|
| 181 | let s2 = this.value.slice(this.cursor + 1);
|
|---|
| 182 | this.value = `${s1}${s2}`;
|
|---|
| 183 | this.red = false;
|
|---|
| 184 |
|
|---|
| 185 | if (this.isCursorAtEnd()) {
|
|---|
| 186 | this.cursorOffset = 0;
|
|---|
| 187 | } else {
|
|---|
| 188 | this.cursorOffset++;
|
|---|
| 189 | }
|
|---|
| 190 |
|
|---|
| 191 | this.render();
|
|---|
| 192 | }
|
|---|
| 193 |
|
|---|
| 194 | first() {
|
|---|
| 195 | this.cursor = 0;
|
|---|
| 196 | this.render();
|
|---|
| 197 | }
|
|---|
| 198 |
|
|---|
| 199 | last() {
|
|---|
| 200 | this.cursor = this.value.length;
|
|---|
| 201 | this.render();
|
|---|
| 202 | }
|
|---|
| 203 |
|
|---|
| 204 | left() {
|
|---|
| 205 | if (this.cursor <= 0 || this.placeholder) return this.bell();
|
|---|
| 206 | this.moveCursor(-1);
|
|---|
| 207 | this.render();
|
|---|
| 208 | }
|
|---|
| 209 |
|
|---|
| 210 | right() {
|
|---|
| 211 | if (this.cursor * this.scale >= this.rendered.length || this.placeholder) return this.bell();
|
|---|
| 212 | this.moveCursor(1);
|
|---|
| 213 | this.render();
|
|---|
| 214 | }
|
|---|
| 215 |
|
|---|
| 216 | isCursorAtStart() {
|
|---|
| 217 | return this.cursor === 0 || this.placeholder && this.cursor === 1;
|
|---|
| 218 | }
|
|---|
| 219 |
|
|---|
| 220 | isCursorAtEnd() {
|
|---|
| 221 | return this.cursor === this.rendered.length || this.placeholder && this.cursor === this.rendered.length + 1;
|
|---|
| 222 | }
|
|---|
| 223 |
|
|---|
| 224 | render() {
|
|---|
| 225 | if (this.closed) return;
|
|---|
| 226 |
|
|---|
| 227 | if (!this.firstRender) {
|
|---|
| 228 | if (this.outputError) this.out.write(cursor.down(lines(this.outputError, this.out.columns) - 1) + clear(this.outputError, this.out.columns));
|
|---|
| 229 | this.out.write(clear(this.outputText, this.out.columns));
|
|---|
| 230 | }
|
|---|
| 231 |
|
|---|
| 232 | super.render();
|
|---|
| 233 | this.outputError = '';
|
|---|
| 234 | this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), this.red ? color.red(this.rendered) : this.rendered].join(` `);
|
|---|
| 235 |
|
|---|
| 236 | if (this.error) {
|
|---|
| 237 | this.outputError += this.errorMsg.split(`\n`).reduce((a, l, i) => a + `\n${i ? ' ' : figures.pointerSmall} ${color.red().italic(l)}`, ``);
|
|---|
| 238 | }
|
|---|
| 239 |
|
|---|
| 240 | this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore + cursor.move(this.cursorOffset, 0));
|
|---|
| 241 | }
|
|---|
| 242 |
|
|---|
| 243 | }
|
|---|
| 244 |
|
|---|
| 245 | module.exports = TextPrompt; |
|---|