spyne-cli 0.6.8 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +80 -30
  3. package/index.js +131 -21
  4. package/package.json +31 -6
  5. package/src/cli/args.js +197 -0
  6. package/src/cli/render.js +198 -0
  7. package/src/core/create-app.js +256 -0
  8. package/src/core/generate-app.js +155 -0
  9. package/src/core/generate-module.js +146 -0
  10. package/src/registry.js +180 -0
  11. package/src/spyne-file-prompt.js +77 -30
  12. package/src/templates/generate-prompt-input-fields.js +1 -1
  13. package/src/ui.js +5 -1
  14. package/lib/ansi.js +0 -116
  15. package/lib/combos.js +0 -75
  16. package/lib/completer.js +0 -52
  17. package/lib/interpolate.js +0 -266
  18. package/lib/keypress.js +0 -243
  19. package/lib/placeholder.js +0 -63
  20. package/lib/prompt.js +0 -485
  21. package/lib/prompts/autocomplete.js +0 -113
  22. package/lib/prompts/basicauth.js +0 -41
  23. package/lib/prompts/confirm.js +0 -13
  24. package/lib/prompts/editable.js +0 -136
  25. package/lib/prompts/form.js +0 -196
  26. package/lib/prompts/index.js +0 -28
  27. package/lib/prompts/input.js +0 -55
  28. package/lib/prompts/invisible.js +0 -11
  29. package/lib/prompts/list.js +0 -36
  30. package/lib/prompts/multiselect.js +0 -11
  31. package/lib/prompts/numeral.js +0 -1
  32. package/lib/prompts/password.js +0 -18
  33. package/lib/prompts/quiz.js +0 -37
  34. package/lib/prompts/scale.js +0 -237
  35. package/lib/prompts/select.js +0 -139
  36. package/lib/prompts/snippet.js +0 -185
  37. package/lib/prompts/sort.js +0 -37
  38. package/lib/prompts/survey.js +0 -163
  39. package/lib/prompts/text.js +0 -1
  40. package/lib/prompts/toggle.js +0 -109
  41. package/lib/render.js +0 -33
  42. package/lib/roles.js +0 -46
  43. package/lib/state.js +0 -69
  44. package/lib/styles.js +0 -144
  45. package/lib/symbols.js +0 -66
  46. package/lib/theme.js +0 -11
  47. package/lib/timer.js +0 -38
  48. package/lib/types/array.js +0 -658
  49. package/lib/types/auth.js +0 -29
  50. package/lib/types/boolean.js +0 -88
  51. package/lib/types/index.js +0 -7
  52. package/lib/types/number.js +0 -86
  53. package/lib/types/string.js +0 -185
  54. package/lib/utils.js +0 -268
  55. package/mocha.conf.cjs +0 -16
  56. package/src/app/channels/.gitkeep +0 -0
  57. package/src/app/channels/channel-custom.js +0 -1
  58. package/src/app/components/.gitkeep +0 -0
  59. package/src/app/traits/.gitkeep +0 -0
  60. package/src/hello-world-app-source/README.md +0 -15
  61. package/src/hello-world-app-source/apache-htaccess +0 -20
  62. package/src/hello-world-app-source/karma.conf.js +0 -75
  63. package/src/hello-world-app-source/package.json +0 -50
  64. package/src/hello-world-app-source/src/app/app-view.js +0 -38
  65. package/src/hello-world-app-source/src/app/channels/.gitkeep +0 -0
  66. package/src/hello-world-app-source/src/app/components/.gitkeep +0 -0
  67. package/src/hello-world-app-source/src/app/traits/.gitkeep +0 -0
  68. package/src/hello-world-app-source/src/index.js +0 -16
  69. package/src/hello-world-app-source/src/index.tmpl.html +0 -12
  70. package/src/hello-world-app-source/src/scss/01-vendors/normalize.css +0 -349
  71. package/src/hello-world-app-source/src/scss/02-variables/mixins.scss +0 -0
  72. package/src/hello-world-app-source/src/scss/03-components/.gitkeep +0 -0
  73. package/src/hello-world-app-source/src/scss/main.scss +0 -15
  74. package/src/hello-world-app-source/src/static/data/.gitkeep +0 -0
  75. package/src/hello-world-app-source/src/static/fonts/.gitkeep +0 -0
  76. package/src/hello-world-app-source/src/static/imgs/.gitkeep +0 -0
  77. package/src/hello-world-app-source/src/tests/unit-tests/index.test.js +0 -10
  78. package/src/hello-world-app-source/webpack.config.js +0 -178
  79. package/src/spyne-app-create.js +0 -209
  80. package/src/spyne-app-creator.js +0 -119
  81. package/src/spyne-starter-app-create.js +0 -147
  82. package/tests/create-spyne-app.test.js +0 -63
  83. package/tests/generate-file-prompt.test.js +0 -45
  84. package/tests/generate-file-string.test.js +0 -66
  85. package/tests/generate-prompt-input-fields-methods.test.js +0 -177
  86. package/tests/generate-prompt-input-fields.test.js +0 -179
  87. package/tests/generate-prompt-input-object.test.js +0 -39
  88. package/tests/generate-prompt-output.test.js +0 -58
  89. package/tests/index.test.js +0 -11
  90. package/tests/mocks/answers.js +0 -33
  91. package/tests/mocks/answers.json +0 -33
  92. package/tests/mocks/enquirer-data.js +0 -411
  93. package/tests/mocks/enquirer-data.json +0 -409
  94. package/tests/utils/file-utils.test.js +0 -84
package/lib/completer.js DELETED
@@ -1,52 +0,0 @@
1
- 'use strict';
2
-
3
- const unique = arr => arr.filter((v, i) => arr.lastIndexOf(v) === i);
4
- const compact = arr => unique(arr).filter(Boolean);
5
-
6
- module.exports = (action, data = {}, value = '') => {
7
- let { past = [], present = '' } = data;
8
- let rest, prev;
9
-
10
- switch (action) {
11
- case 'prev':
12
- case 'undo':
13
- rest = past.slice(0, past.length - 1);
14
- prev = past[past.length - 1] || '';
15
- return {
16
- past: compact([value, ...rest]),
17
- present: prev
18
- };
19
-
20
- case 'next':
21
- case 'redo':
22
- rest = past.slice(1);
23
- prev = past[0] || '';
24
- return {
25
- past: compact([...rest, value]),
26
- present: prev
27
- };
28
-
29
- case 'save':
30
- return {
31
- past: compact([...past, value]),
32
- present: ''
33
- };
34
-
35
- case 'remove':
36
- prev = compact(past.filter(v => v !== value));
37
- present = '';
38
-
39
- if (prev.length) {
40
- present = prev.pop();
41
- }
42
-
43
- return {
44
- past: prev,
45
- present
46
- };
47
-
48
- default: {
49
- throw new Error(`Invalid action: "${action}"`);
50
- }
51
- }
52
- };
@@ -1,266 +0,0 @@
1
- 'use strict';
2
-
3
- const colors = require('ansi-colors');
4
- const clean = (str = '') => {
5
- return typeof str === 'string' ? str.replace(/^['"]|['"]$/g, '') : '';
6
- };
7
-
8
- /**
9
- * This file contains the interpolation and rendering logic for
10
- * the Snippet prompt.
11
- */
12
-
13
- class Item {
14
- constructor(token) {
15
- this.name = token.key;
16
- this.field = token.field || {};
17
- this.value = clean(token.initial || this.field.initial || '');
18
- this.message = token.message || this.name;
19
- this.cursor = 0;
20
- this.input = '';
21
- this.lines = [];
22
- }
23
- }
24
-
25
- const tokenize = async(options = {}, defaults = {}, fn = token => token) => {
26
- let unique = new Set();
27
- let fields = options.fields || [];
28
- let input = options.template;
29
- let tabstops = [];
30
- let items = [];
31
- let keys = [];
32
- let line = 1;
33
-
34
- if (typeof input === 'function') {
35
- input = await input();
36
- }
37
-
38
- let i = -1;
39
- let next = () => input[++i];
40
- let peek = () => input[i + 1];
41
- let push = token => {
42
- token.line = line;
43
- tabstops.push(token);
44
- };
45
-
46
- push({ type: 'bos', value: '' });
47
-
48
- while (i < input.length - 1) {
49
- let value = next();
50
-
51
- if (/^[^\S\n ]$/.test(value)) {
52
- push({ type: 'text', value });
53
- continue;
54
- }
55
-
56
- if (value === '\n') {
57
- push({ type: 'newline', value });
58
- line++;
59
- continue;
60
- }
61
-
62
- if (value === '\\') {
63
- value += next();
64
- push({ type: 'text', value });
65
- continue;
66
- }
67
-
68
- if ((value === '$' || value === '#' || value === '{') && peek() === '{') {
69
- let n = next();
70
- value += n;
71
-
72
- let token = { type: 'template', open: value, inner: '', close: '', value };
73
- let ch;
74
-
75
- while ((ch = next())) {
76
- if (ch === '}') {
77
- if (peek() === '}') ch += next();
78
- token.value += ch;
79
- token.close = ch;
80
- break;
81
- }
82
-
83
- if (ch === ':') {
84
- token.initial = '';
85
- token.key = token.inner;
86
- } else if (token.initial !== void 0) {
87
- token.initial += ch;
88
- }
89
-
90
- token.value += ch;
91
- token.inner += ch;
92
- }
93
-
94
- token.template = token.open + (token.initial || token.inner) + token.close;
95
- token.key = token.key || token.inner;
96
-
97
- if (defaults.hasOwnProperty(token.key)) {
98
- token.initial = defaults[token.key];
99
- }
100
-
101
- token = fn(token);
102
- push(token);
103
-
104
- keys.push(token.key);
105
- unique.add(token.key);
106
-
107
- let item = items.find(item => item.name === token.key);
108
- token.field = fields.find(ch => ch.name === token.key);
109
-
110
- if (!item) {
111
- item = new Item(token);
112
- items.push(item);
113
- }
114
-
115
- item.lines.push(token.line - 1);
116
- continue;
117
- }
118
-
119
- let last = tabstops[tabstops.length - 1];
120
- if (last.type === 'text' && last.line === line) {
121
- last.value += value;
122
- } else {
123
- push({ type: 'text', value });
124
- }
125
- }
126
-
127
- push({ type: 'eos', value: '' });
128
- return { input, tabstops, unique, keys, items };
129
- };
130
-
131
- module.exports = async prompt => {
132
- let options = prompt.options;
133
- let required = new Set(options.required === true ? [] : (options.required || []));
134
- let defaults = { ...options.values, ...options.initial };
135
- let { tabstops, items, keys } = await tokenize(options, defaults);
136
-
137
- let result = createFn('result', prompt, options);
138
- let format = createFn('format', prompt, options);
139
- let isValid = createFn('validate', prompt, options, true);
140
- let isVal = prompt.isValue.bind(prompt);
141
-
142
- return async(state = {}, submitted = false) => {
143
- let index = 0;
144
-
145
- state.required = required;
146
- state.items = items;
147
- state.keys = keys;
148
- state.output = '';
149
-
150
- let validate = async(value, state, item, index) => {
151
- let error = await isValid(value, state, item, index);
152
- if (error === false) {
153
- return 'Invalid field ' + item.name;
154
- }
155
- return error;
156
- };
157
-
158
- for (let token of tabstops) {
159
- let value = token.value;
160
- let key = token.key;
161
-
162
- if (token.type !== 'template') {
163
- if (value) state.output += value;
164
- continue;
165
- }
166
-
167
- if (token.type === 'template') {
168
- let item = items.find(ch => ch.name === key);
169
-
170
- if (options.required === true) {
171
- state.required.add(item.name);
172
- }
173
-
174
- let val = [item.input, state.values[item.value], item.value, value].find(isVal);
175
- let field = item.field || {};
176
- let message = field.message || token.inner;
177
-
178
- if (submitted) {
179
- let error = await validate(state.values[key], state, item, index);
180
- if ((error && typeof error === 'string') || error === false) {
181
- state.invalid.set(key, error);
182
- continue;
183
- }
184
-
185
- state.invalid.delete(key);
186
- let res = await result(state.values[key], state, item, index);
187
- state.output += colors.unstyle(res);
188
- continue;
189
- }
190
-
191
- item.placeholder = false;
192
-
193
- let before = value;
194
- value = await format(value, state, item, index);
195
-
196
- if (val !== value) {
197
- state.values[key] = val;
198
- value = prompt.styles.typing(val);
199
- state.missing.delete(message);
200
-
201
- } else {
202
- state.values[key] = void 0;
203
- val = `<${message}>`;
204
- value = prompt.styles.primary(val);
205
- item.placeholder = true;
206
-
207
- if (state.required.has(key)) {
208
- state.missing.add(message);
209
- }
210
- }
211
-
212
- if (state.missing.has(message) && state.validating) {
213
- value = prompt.styles.warning(val);
214
- }
215
-
216
- if (state.invalid.has(key) && state.validating) {
217
- value = prompt.styles.danger(val);
218
- }
219
-
220
- if (index === state.index) {
221
- if (before !== value) {
222
- value = prompt.styles.underline(value);
223
- } else {
224
- value = prompt.styles.heading(colors.unstyle(value));
225
- }
226
- }
227
-
228
- index++;
229
- }
230
-
231
- if (value) {
232
- state.output += value;
233
- }
234
- }
235
-
236
- let lines = state.output.split('\n').map(l => ' ' + l);
237
- let len = items.length;
238
- let done = 0;
239
-
240
- for (let item of items) {
241
- if (state.invalid.has(item.name)) {
242
- item.lines.forEach(i => {
243
- if (lines[i][0] !== ' ') return;
244
- lines[i] = state.styles.danger(state.symbols.bullet) + lines[i].slice(1);
245
- });
246
- }
247
-
248
- if (prompt.isValue(state.values[item.name])) {
249
- done++;
250
- }
251
- }
252
-
253
- state.completed = ((done / len) * 100).toFixed(0);
254
- state.output = lines.join('\n');
255
- return state.output;
256
- };
257
- };
258
-
259
- function createFn(prop, prompt, options, fallback) {
260
- return (value, state, item, index) => {
261
- if (typeof item.field[prop] === 'function') {
262
- return item.field[prop].call(prompt, value, state, item, index);
263
- }
264
- return [fallback, value].find(v => prompt.isValue(v));
265
- };
266
- }
package/lib/keypress.js DELETED
@@ -1,243 +0,0 @@
1
- 'use strict';
2
-
3
- const readline = require('readline');
4
- const combos = require('./combos');
5
-
6
- /* eslint-disable no-control-regex */
7
- const metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/;
8
- const fnKeyRe = /^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/;
9
- const keyName = {
10
- /* xterm/gnome ESC O letter */
11
- 'OP': 'f1',
12
- 'OQ': 'f2',
13
- 'OR': 'f3',
14
- 'OS': 'f4',
15
- /* xterm/rxvt ESC [ number ~ */
16
- '[11~': 'f1',
17
- '[12~': 'f2',
18
- '[13~': 'f3',
19
- '[14~': 'f4',
20
- /* from Cygwin and used in libuv */
21
- '[[A': 'f1',
22
- '[[B': 'f2',
23
- '[[C': 'f3',
24
- '[[D': 'f4',
25
- '[[E': 'f5',
26
- /* common */
27
- '[15~': 'f5',
28
- '[17~': 'f6',
29
- '[18~': 'f7',
30
- '[19~': 'f8',
31
- '[20~': 'f9',
32
- '[21~': 'f10',
33
- '[23~': 'f11',
34
- '[24~': 'f12',
35
- /* xterm ESC [ letter */
36
- '[A': 'up',
37
- '[B': 'down',
38
- '[C': 'right',
39
- '[D': 'left',
40
- '[E': 'clear',
41
- '[F': 'end',
42
- '[H': 'home',
43
- /* xterm/gnome ESC O letter */
44
- 'OA': 'up',
45
- 'OB': 'down',
46
- 'OC': 'right',
47
- 'OD': 'left',
48
- 'OE': 'clear',
49
- 'OF': 'end',
50
- 'OH': 'home',
51
- /* xterm/rxvt ESC [ number ~ */
52
- '[1~': 'home',
53
- '[2~': 'insert',
54
- '[3~': 'delete',
55
- '[4~': 'end',
56
- '[5~': 'pageup',
57
- '[6~': 'pagedown',
58
- /* putty */
59
- '[[5~': 'pageup',
60
- '[[6~': 'pagedown',
61
- /* rxvt */
62
- '[7~': 'home',
63
- '[8~': 'end',
64
- /* rxvt keys with modifiers */
65
- '[a': 'up',
66
- '[b': 'down',
67
- '[c': 'right',
68
- '[d': 'left',
69
- '[e': 'clear',
70
-
71
- '[2$': 'insert',
72
- '[3$': 'delete',
73
- '[5$': 'pageup',
74
- '[6$': 'pagedown',
75
- '[7$': 'home',
76
- '[8$': 'end',
77
-
78
- 'Oa': 'up',
79
- 'Ob': 'down',
80
- 'Oc': 'right',
81
- 'Od': 'left',
82
- 'Oe': 'clear',
83
-
84
- '[2^': 'insert',
85
- '[3^': 'delete',
86
- '[5^': 'pageup',
87
- '[6^': 'pagedown',
88
- '[7^': 'home',
89
- '[8^': 'end',
90
- /* misc. */
91
- '[Z': 'tab',
92
- }
93
-
94
- function isShiftKey(code) {
95
- return ['[a', '[b', '[c', '[d', '[e', '[2$', '[3$', '[5$', '[6$', '[7$', '[8$', '[Z'].includes(code)
96
- }
97
-
98
- function isCtrlKey(code) {
99
- return [ 'Oa', 'Ob', 'Oc', 'Od', 'Oe', '[2^', '[3^', '[5^', '[6^', '[7^', '[8^'].includes(code)
100
- }
101
-
102
- const keypress = (s = '', event = {}) => {
103
- let parts;
104
- let key = {
105
- name: event.name,
106
- ctrl: false,
107
- meta: false,
108
- shift: false,
109
- option: false,
110
- sequence: s,
111
- raw: s,
112
- ...event
113
- };
114
-
115
- if (Buffer.isBuffer(s)) {
116
- if (s[0] > 127 && s[1] === void 0) {
117
- s[0] -= 128;
118
- s = '\x1b' + String(s);
119
- } else {
120
- s = String(s);
121
- }
122
- } else if (s !== void 0 && typeof s !== 'string') {
123
- s = String(s);
124
- } else if (!s) {
125
- s = key.sequence || '';
126
- }
127
-
128
- key.sequence = key.sequence || s || key.name;
129
-
130
- if (s === '\r') {
131
- // carriage return
132
- key.raw = void 0;
133
- key.name = 'return';
134
- } else if (s === '\n') {
135
- // enter, should have been called linefeed
136
- key.name = 'enter';
137
- } else if (s === '\t') {
138
- // tab
139
- key.name = 'tab';
140
- } else if (s === '\b' || s === '\x7f' || s === '\x1b\x7f' || s === '\x1b\b') {
141
- // backspace or ctrl+h
142
- key.name = 'backspace';
143
- key.meta = s.charAt(0) === '\x1b';
144
- } else if (s === '\x1b' || s === '\x1b\x1b') {
145
- // escape key
146
- key.name = 'escape';
147
- key.meta = s.length === 2;
148
- } else if (s === ' ' || s === '\x1b ') {
149
- key.name = 'space';
150
- key.meta = s.length === 2;
151
- } else if (s <= '\x1a') {
152
- // ctrl+letter
153
- key.name = String.fromCharCode(s.charCodeAt(0) + 'a'.charCodeAt(0) - 1);
154
- key.ctrl = true;
155
- } else if (s.length === 1 && s >= '0' && s <= '9') {
156
- // number
157
- key.name = 'number';
158
- } else if (s.length === 1 && s >= 'a' && s <= 'z') {
159
- // lowercase letter
160
- key.name = s;
161
- } else if (s.length === 1 && s >= 'A' && s <= 'Z') {
162
- // shift+letter
163
- key.name = s.toLowerCase();
164
- key.shift = true;
165
- } else if ((parts = metaKeyCodeRe.exec(s))) {
166
- // meta+character key
167
- key.meta = true;
168
- key.shift = /^[A-Z]$/.test(parts[1]);
169
- } else if ((parts = fnKeyRe.exec(s))) {
170
- let segs = [...s];
171
-
172
- if (segs[0] === '\u001b' && segs[1] === '\u001b') {
173
- key.option = true;
174
- }
175
-
176
- // ansi escape sequence
177
- // reassemble the key code leaving out leading \x1b's,
178
- // the modifier key bitflag and any meaningless "1;" sequence
179
- let code = [parts[1], parts[2], parts[4], parts[6]].filter(Boolean).join('');
180
- let modifier = (parts[3] || parts[5] || 1) - 1;
181
-
182
- // Parse the key modifier
183
- key.ctrl = !!(modifier & 4);
184
- key.meta = !!(modifier & 10);
185
- key.shift = !!(modifier & 1);
186
- key.code = code;
187
-
188
- key.name = keyName[code];
189
- key.shift = isShiftKey(code) || key.shift;
190
- key.ctrl = isCtrlKey(code) || key.ctrl;
191
- }
192
- return key;
193
- };
194
-
195
- keypress.listen = (options = {}, onKeypress) => {
196
- let { stdin } = options;
197
-
198
- if (!stdin || (stdin !== process.stdin && !stdin.isTTY)) {
199
- throw new Error('Invalid stream passed');
200
- }
201
-
202
- let rl = readline.createInterface({ terminal: true, input: stdin });
203
- readline.emitKeypressEvents(stdin, rl);
204
-
205
- let on = (buf, key) => onKeypress(buf, keypress(buf, key), rl);
206
- let isRaw = stdin.isRaw;
207
-
208
- if (stdin.isTTY) stdin.setRawMode(true);
209
- stdin.on('keypress', on);
210
- rl.resume();
211
-
212
- let off = () => {
213
- if (stdin.isTTY) stdin.setRawMode(isRaw);
214
- stdin.removeListener('keypress', on);
215
- rl.pause();
216
- rl.close();
217
- };
218
-
219
- return off;
220
- };
221
-
222
- keypress.action = (buf, key, customActions) => {
223
- let obj = { ...combos, ...customActions };
224
- if (key.ctrl) {
225
- key.action = obj.ctrl[key.name];
226
- return key;
227
- }
228
-
229
- if (key.option && obj.option) {
230
- key.action = obj.option[key.name];
231
- return key;
232
- }
233
-
234
- if (key.shift) {
235
- key.action = obj.shift[key.name];
236
- return key;
237
- }
238
-
239
- key.action = obj.keys[key.name];
240
- return key;
241
- };
242
-
243
- module.exports = keypress;
@@ -1,63 +0,0 @@
1
- 'use strict';
2
-
3
- const utils = require('./utils');
4
-
5
- /**
6
- * Render a placeholder value with cursor and styling based on the
7
- * position of the cursor.
8
- *
9
- * @param {Object} `prompt` Prompt instance.
10
- * @param {String} `input` Input string.
11
- * @param {String} `initial` The initial user-provided value.
12
- * @param {Number} `pos` Current cursor position.
13
- * @param {Boolean} `showCursor` Render a simulated cursor using the inverse primary style.
14
- * @return {String} Returns the styled placeholder string.
15
- * @api public
16
- */
17
-
18
- module.exports = (prompt, options = {}) => {
19
- prompt.cursorHide();
20
-
21
- let { input = '', initial = '', pos, showCursor = true, color } = options;
22
- let style = color || prompt.styles.placeholder;
23
- let inverse = utils.inverse(prompt.styles.primary);
24
- let blinker = str => inverse(prompt.styles.black(str));
25
- let output = input;
26
- let char = ' ';
27
- let reverse = blinker(char);
28
-
29
- if (prompt.blink && prompt.blink.off === true) {
30
- blinker = str => str;
31
- reverse = '';
32
- }
33
-
34
- if (showCursor && pos === 0 && initial === '' && input === '') {
35
- return blinker(char);
36
- }
37
-
38
- if (showCursor && pos === 0 && (input === initial || input === '')) {
39
- return blinker(initial[0]) + style(initial.slice(1));
40
- }
41
-
42
- initial = utils.isPrimitive(initial) ? `${initial}` : '';
43
- input = utils.isPrimitive(input) ? `${input}` : '';
44
-
45
- let placeholder = initial && initial.startsWith(input) && initial !== input;
46
- let cursor = placeholder ? blinker(initial[input.length]) : reverse;
47
-
48
- if (pos !== input.length && showCursor === true) {
49
- output = input.slice(0, pos) + blinker(input[pos]) + input.slice(pos + 1);
50
- cursor = '';
51
- }
52
-
53
- if (showCursor === false) {
54
- cursor = '';
55
- }
56
-
57
- if (placeholder) {
58
- let raw = prompt.styles.unstyle(output + cursor);
59
- return output + cursor + style(initial.slice(raw.length));
60
- }
61
-
62
- return output + cursor;
63
- };