Fixed #1 - Fixed the whatsnew-** script for loading release notes into builds

Added test to ensure that release notes are parsed properly
Updated to latest dependencies to fix security vulnerability
Updated GH Actions Workflow to run test before updating tag
Updated README.md to reflect proper whatsnew documentation.
This commit is contained in:
Drew Heavner
2020-01-30 11:14:51 -05:00
parent b6496ac4e3
commit bdde081050
2660 changed files with 251487 additions and 213182 deletions

View File

@@ -9,13 +9,15 @@ const color = require('kleur');
const Prompt = require('./prompt');
const _require = require('sisteransi'),
erase = _require.erase,
cursor = _require.cursor;
const _require2 = require('../util'),
style = _require2.style,
clear = _require2.clear,
figures = _require2.figures,
strip = _require2.strip;
wrap = _require2.wrap,
entriesToDisplay = _require2.entriesToDisplay;
const getVal = (arr, i) => arr[i] && (arr[i].value || arr[i].title || arr[i]);
@@ -50,9 +52,11 @@ class AutocompletePrompt extends Prompt {
this.choices = opts.choices;
this.initial = typeof opts.initial === 'number' ? opts.initial : getIndex(opts.choices, opts.initial);
this.select = this.initial || opts.cursor || 0;
this.fallback = opts.fallback || (opts.initial !== undefined ? `${figures.pointerSmall} ${getTitle(this.choices, this.initial)}` : `${figures.pointerSmall} ${opts.noMatches || 'no matches found'}`);
this.suggestions = [[]];
this.page = 0;
this.i18n = {
noMatches: opts.noMatches || 'no matches found'
};
this.fallback = opts.fallback || this.initial;
this.suggestions = [];
this.input = '';
this.limit = opts.limit || 10;
this.cursor = 0;
@@ -65,15 +69,23 @@ class AutocompletePrompt extends Prompt {
this.render();
}
set fallback(fb) {
this._fb = Number.isSafeInteger(parseInt(fb)) ? parseInt(fb) : fb;
}
get fallback() {
let choice;
if (typeof this._fb === 'number') choice = this.choices[this._fb];else if (typeof this._fb === 'string') choice = {
title: this._fb
};
return choice || this._fb || {
title: this.i18n.noMatches
};
}
moveSelect(i) {
this.select = i;
if (this.suggestions[this.page].length > 0) {
this.value = getVal(this.suggestions[this.page], i);
} else {
this.value = this.initial !== undefined ? getVal(this.choices, this.initial) : null;
}
if (this.suggestions.length > 0) this.value = getVal(this.suggestions, i);else this.value = this.fallback.value;
this.fire();
}
@@ -87,25 +99,10 @@ class AutocompletePrompt extends Prompt {
if (_this.completing !== p) return;
_this.suggestions = suggestions.map((s, i, arr) => ({
title: getTitle(arr, i),
value: getVal(arr, i)
})).reduce((arr, sug) => {
if (arr[arr.length - 1].length < _this.limit) arr[arr.length - 1].push(sug);else arr.push([sug]);
return arr;
}, [[]]);
_this.isFallback = false;
value: getVal(arr, i),
description: s.description
}));
_this.completing = false;
if (!_this.suggestions[_this.page]) _this.page = 0;
if (!_this.suggestions.length && _this.fallback) {
const index = getIndex(_this.choices, _this.fallback);
_this.suggestions = [[]];
if (index !== undefined) _this.suggestions[0].push({
title: getTitle(_this.choices, index),
value: getVal(_this.choices, index)
});
_this.isFallback = true;
}
const l = Math.max(suggestions.length - 1, 0);
_this.moveSelect(Math.min(l, _this.select));
@@ -141,7 +138,6 @@ class AutocompletePrompt extends Prompt {
}
_(c, key) {
// TODO on ctrl+# go to page #
let s1 = this.input.slice(0, this.cursor);
let s2 = this.input.slice(this.cursor);
this.input = `${s1}${c}${s2}`;
@@ -175,7 +171,7 @@ class AutocompletePrompt extends Prompt {
}
last() {
this.moveSelect(this.suggestions[this.page].length - 1);
this.moveSelect(this.suggestions.length - 1);
this.render();
}
@@ -186,14 +182,13 @@ class AutocompletePrompt extends Prompt {
}
down() {
if (this.select >= this.suggestions[this.page].length - 1) return this.bell();
if (this.select >= this.suggestions.length - 1) return this.bell();
this.moveSelect(this.select + 1);
this.render();
}
next() {
if (this.select === this.suggestions[this.page].length - 1) {
this.page = (this.page + 1) % this.suggestions.length;
if (this.select === this.suggestions.length - 1) {
this.moveSelect(0);
} else this.moveSelect(this.select + 1);
@@ -201,16 +196,12 @@ class AutocompletePrompt extends Prompt {
}
nextPage() {
if (this.page >= this.suggestions.length - 1) return this.bell();
this.page++;
this.moveSelect(0);
this.moveSelect(Math.min(this.select + this.limit, this.suggestions.length - 1));
this.render();
}
prevPage() {
if (this.page <= 0) return this.bell();
this.page--;
this.moveSelect(0);
this.moveSelect(Math.max(this.select - this.limit, 0));
this.render();
}
@@ -226,49 +217,43 @@ class AutocompletePrompt extends Prompt {
this.render();
}
render() {
if (this.closed) return;
super.render();
if (this.lineCount) this.out.write(cursor.down(this.lineCount));
let prompt = color.bold(`${style.symbol(this.done, this.aborted)} ${this.msg} `) + `${style.delimiter(this.completing)} `;
let length = strip(prompt).length;
renderOption(v, hovered, isStart, isEnd) {
let desc;
let prefix = isStart ? figures.arrowUp : isEnd ? figures.arrowDown : ' ';
let title = hovered ? color.cyan().underline(v.title) : v.title;
prefix = (hovered ? color.cyan(figures.pointer) + ' ' : ' ') + prefix;
if (this.done && this.suggestions[this.page][this.select]) {
prompt += `${this.suggestions[this.page][this.select].title}`;
} else {
this.rendered = `${this.transform.render(this.input)}`;
length += this.rendered.length;
prompt += this.rendered;
}
if (v.description) {
desc = ` - ${v.description}`;
if (!this.done) {
this.lineCount = this.suggestions[this.page].length;
let suggestions = this.suggestions[this.page].reduce((acc, item, i) => acc + `\n${i === this.select ? color.cyan(item.title) : item.title}`, '');
if (suggestions && !this.isFallback) {
prompt += suggestions;
if (this.suggestions.length > 1) {
this.lineCount++;
prompt += color.blue(`\nPage ${this.page + 1}/${this.suggestions.length}`);
}
} else {
const fallbackIndex = getIndex(this.choices, this.fallback);
const fallbackTitle = fallbackIndex !== undefined ? getTitle(this.choices, fallbackIndex) : this.fallback;
prompt += `\n${color.gray(fallbackTitle)}`;
this.lineCount++;
if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) {
desc = '\n' + wrap(v.description, {
margin: 3,
width: this.out.columns
});
}
}
this.out.write(this.clear + prompt);
this.clear = clear(prompt);
return prefix + ' ' + title + color.gray(desc || '');
}
if (this.lineCount && !this.done) {
let pos = cursor.up(this.lineCount);
pos += cursor.left + cursor.to(length);
pos += cursor.move(-this.rendered.length + this.cursor * this.scale);
this.out.write(pos);
render() {
if (this.closed) return;
if (this.firstRender) this.out.write(cursor.hide);else this.out.write(clear(this.outputText));
super.render();
let _entriesToDisplay = entriesToDisplay(this.select, this.choices.length, this.limit),
startIndex = _entriesToDisplay.startIndex,
endIndex = _entriesToDisplay.endIndex;
this.outputText = [color.bold(style.symbol(this.done, this.aborted)), color.bold(this.msg), style.delimiter(this.completing), this.done && this.suggestions[this.select] ? this.suggestions[this.select].title : this.rendered = this.transform.render(this.input)].join(' ');
if (!this.done) {
const suggestions = this.suggestions.slice(startIndex, endIndex).map((item, i) => this.renderOption(item, this.select === i + startIndex, i === 0 && startIndex > 0, i + startIndex === endIndex - 1 && endIndex < this.choices.length)).join('\n');
this.outputText += `\n` + (suggestions || color.gray(this.fallback.title));
}
this.out.write(erase.line + cursor.to(0) + this.outputText);
}
}

View File

@@ -137,13 +137,21 @@ class AutocompleteMultiselectPrompt extends MultiselectPrompt {
}
renderInstructions() {
return `
if (this.instructions === undefined || this.instructions) {
if (typeof this.instructions === 'string') {
return this.instructions;
}
return `
Instructions:
${figures.arrowUp}/${figures.arrowDown}: Highlight option
${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection
[a,b,c]/delete: Filter choices
enter/return: Complete answer
`;
`;
}
return '';
}
renderCurrentInput() {
@@ -159,8 +167,7 @@ Filtered results for: ${this.inputValue ? this.inputValue : color.gray('Enter so
renderDoneOrInstructions() {
if (this.done) {
const selected = this.value.filter(e => e.selected).map(v => v.title).join(', ');
return selected;
return this.value.filter(e => e.selected).map(v => v.title).join(', ');
}
const output = [color.gray(this.hint), this.renderInstructions(), this.renderCurrentInput()];

View File

@@ -5,7 +5,8 @@ const color = require('kleur');
const Prompt = require('./prompt');
const _require = require('../util'),
style = _require.style;
style = _require.style,
clear = _require.clear;
const _require2 = require('sisteransi'),
erase = _require2.erase,
@@ -77,9 +78,10 @@ class ConfirmPrompt extends Prompt {
render() {
if (this.closed) return;
if (this.firstRender) this.out.write(cursor.hide);
if (this.firstRender) this.out.write(cursor.hide);else this.out.write(clear(this.outputText));
super.render();
this.out.write(erase.line + cursor.to(0) + [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), this.done ? this.value ? this.yesMsg : this.noMsg : color.gray(this.initialValue ? this.yesOption : this.noOption)].join(' '));
this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), this.done ? this.value ? this.yesMsg : this.noMsg : color.gray(this.initialValue ? this.yesOption : this.noOption)].join(' ');
this.out.write(erase.line + cursor.to(0) + this.outputText);
}
}

View File

@@ -11,8 +11,7 @@ const Prompt = require('./prompt');
const _require = require('../util'),
style = _require.style,
clear = _require.clear,
figures = _require.figures,
strip = _require.strip;
figures = _require.figures;
const _require2 = require('sisteransi'),
erase = _require2.erase,
@@ -231,28 +230,16 @@ class DatePrompt extends Prompt {
render() {
if (this.closed) return;
if (this.firstRender) this.out.write(cursor.hide);else this.out.write(erase.lines(1));
super.render();
let clear = erase.line + (this.lines ? erase.down(this.lines) : '') + cursor.to(0);
this.lines = 0;
let error = '';
if (this.firstRender) this.out.write(cursor.hide);else this.out.write(clear(this.outputText));
super.render(); // Print prompt
this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.parts.reduce((arr, p, idx) => arr.concat(idx === this.cursor && !this.done ? color.cyan().underline(p.toString()) : p), []).join('')].join(' '); // Print error
if (this.error) {
let lines = this.errorMsg.split('\n');
error = lines.reduce((a, l, i) => a + `\n${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
this.lines = lines.length;
} // Print prompt
let prompt = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.parts.reduce((arr, p, idx) => arr.concat(idx === this.cursor && !this.done ? color.cyan().underline(p.toString()) : p), []).join('')].join(' ');
let position = '';
if (this.lines) {
position += cursor.up(this.lines);
position += cursor.left + cursor.to(strip(prompt).length);
this.outputText += this.errorMsg.split('\n').reduce((a, l, i) => a + `\n${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
}
this.out.write(clear + prompt + error + position);
this.out.write(erase.line + cursor.to(0) + this.outputText);
}
}

View File

@@ -10,7 +10,9 @@ const Prompt = require('./prompt');
const _require2 = require('../util'),
clear = _require2.clear,
figures = _require2.figures,
style = _require2.style;
style = _require2.style,
wrap = _require2.wrap,
entriesToDisplay = _require2.entriesToDisplay;
/**
* MultiselectPrompt Base Element
* @param {Object} opts Options
@@ -20,6 +22,7 @@ const _require2 = require('../util'),
* @param {String} [opts.warn] Hint shown for disabled choices
* @param {Number} [opts.max] Max choices
* @param {Number} [opts.cursor=0] Cursor start position
* @param {Number} [opts.optionsPerPage=10] Max options to display at once
* @param {Stream} [opts.stdin] The Readable stream to listen to
* @param {Stream} [opts.stdout] The Writable stream to write readline data to
*/
@@ -36,6 +39,8 @@ class MultiselectPrompt extends Prompt {
this.minSelected = opts.min;
this.showMinError = false;
this.maxChoices = opts.max;
this.instructions = opts.instructions;
this.optionsPerPage = opts.optionsPerPage || 10;
this.value = opts.choices.map((ch, idx) => {
if (typeof ch === 'string') ch = {
title: ch,
@@ -43,7 +48,8 @@ class MultiselectPrompt extends Prompt {
};
return {
title: ch && (ch.title || ch.value || ch),
value: ch && (ch.value || idx),
description: ch && ch.description,
value: ch && (ch.value === undefined ? idx : ch.value),
selected: ch && ch.selected,
disabled: ch && ch.disabled
};
@@ -150,57 +156,88 @@ class MultiselectPrompt extends Prompt {
}
}
toggleAll() {
if (this.maxChoices !== undefined || this.value[this.cursor].disabled) {
return this.bell();
}
const newSelected = !this.value[this.cursor].selected;
this.value.filter(v => !v.disabled).forEach(v => v.selected = newSelected);
this.render();
}
_(c, key) {
if (c === ' ') {
this.handleSpaceToggle();
} else if (c === 'a') {
this.toggleAll();
} else {
return this.bell();
}
}
renderInstructions() {
return `
Instructions:
${figures.arrowUp}/${figures.arrowDown}: Highlight option
${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection
enter/return: Complete answer
`;
if (this.instructions === undefined || this.instructions) {
if (typeof this.instructions === 'string') {
return this.instructions;
}
return '\nInstructions:\n' + ` ${figures.arrowUp}/${figures.arrowDown}: Highlight option\n` + ` ${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection\n` + (this.maxChoices === undefined ? ` a: Toggle all\n` : '') + ` enter/return: Complete answer`;
}
return '';
}
renderOption(cursor, v, i) {
let title;
if (v.disabled) title = cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);else title = cursor === i ? color.cyan().underline(v.title) : v.title;
return (v.selected ? color.green(figures.radioOn) : figures.radioOff) + ' ' + title;
renderOption(cursor, v, i, arrowIndicator) {
const prefix = (v.selected ? color.green(figures.radioOn) : figures.radioOff) + ' ' + arrowIndicator + ' ';
let title, desc;
if (v.disabled) {
title = cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);
} else {
title = cursor === i ? color.cyan().underline(v.title) : v.title;
if (cursor === i && v.description) {
desc = ` - ${v.description}`;
if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) {
desc = '\n' + wrap(v.description, {
margin: prefix.length,
width: this.out.columns
});
}
}
}
return prefix + title + color.gray(desc || '');
} // shared with autocompleteMultiselect
paginateOptions(options) {
const c = this.cursor;
let styledOptions = options.map((v, i) => this.renderOption(c, v, i));
const numOfOptionsToRender = 10; // if needed, can add an option to change this.
let scopedOptions = styledOptions;
let hint = '';
if (styledOptions.length === 0) {
if (options.length === 0) {
return color.red('No matches for this query.');
} else if (styledOptions.length > numOfOptionsToRender) {
let startIndex = c - numOfOptionsToRender / 2;
let endIndex = c + numOfOptionsToRender / 2;
if (startIndex < 0) {
startIndex = 0;
endIndex = numOfOptionsToRender;
} else if (endIndex > options.length) {
endIndex = options.length;
startIndex = endIndex - numOfOptionsToRender;
}
scopedOptions = styledOptions.slice(startIndex, endIndex);
hint = color.dim('(Move up and down to reveal more choices)');
}
return '\n' + scopedOptions.join('\n') + '\n' + hint;
let _entriesToDisplay = entriesToDisplay(this.cursor, options.length, this.optionsPerPage),
startIndex = _entriesToDisplay.startIndex,
endIndex = _entriesToDisplay.endIndex;
let prefix,
styledOptions = [];
for (let i = startIndex; i < endIndex; i++) {
if (i === startIndex && startIndex > 0) {
prefix = figures.arrowUp;
} else if (i === endIndex - 1 && endIndex < options.length) {
prefix = figures.arrowDown;
} else {
prefix = ' ';
}
styledOptions.push(this.renderOption(this.cursor, options[i], i, prefix));
}
return '\n' + styledOptions.join('\n');
} // shared with autocomleteMultiselect
@@ -214,8 +251,7 @@ Instructions:
renderDoneOrInstructions() {
if (this.done) {
const selected = this.value.filter(e => e.selected).map(v => v.title).join(', ');
return selected;
return this.value.filter(e => e.selected).map(v => v.title).join(', ');
}
const output = [color.gray(this.hint), this.renderInstructions()];

View File

@@ -14,9 +14,9 @@ const _require = require('sisteransi'),
const _require2 = require('../util'),
style = _require2.style,
clear = _require2.clear,
figures = _require2.figures,
strip = _require2.strip;
clear = _require2.clear,
lines = _require2.lines;
const isNumber = /[0-9]/;
@@ -159,6 +159,11 @@ class NumberPrompt extends Prompt {
up() {
this.typed = ``;
if (this.value === '') {
this.value = this.min - this.inc;
}
if (this.value >= this.max) return this.bell();
this.value += this.inc;
this.color = `cyan`;
@@ -168,6 +173,11 @@ class NumberPrompt extends Prompt {
down() {
this.typed = ``;
if (this.value === '') {
this.value = this.min + this.inc;
}
if (this.value <= this.min) return this.bell();
this.value -= this.inc;
this.color = `cyan`;
@@ -179,6 +189,11 @@ class NumberPrompt extends Prompt {
let val = this.value.toString();
if (val.length === 0) return this.bell();
this.value = this.parse(val = val.slice(0, -1)) || ``;
if (this.value !== '' && this.value < this.min) {
this.value = this.min;
}
this.color = `cyan`;
this.fire();
this.render();
@@ -208,27 +223,22 @@ class NumberPrompt extends Prompt {
render() {
if (this.closed) return;
if (!this.firstRender) {
if (this.outputError) this.out.write(cursor.down(lines(this.outputError) - 1) + clear(this.outputError));
this.out.write(clear(this.outputText));
}
super.render();
let clear = erase.line + (this.lines ? erase.down(this.lines) : ``) + cursor.to(0);
this.lines = 0;
let error = ``;
this.outputError = ''; // Print prompt
this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), !this.done || !this.done && !this.placeholder ? color[this.color]().underline(this.rendered) : this.rendered].join(` `); // Print error
if (this.error) {
let lines = this.errorMsg.split(`\n`);
error += lines.reduce((a, l, i) => a + `\n${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
this.lines = lines.length;
this.outputError += this.errorMsg.split(`\n`).reduce((a, l, i) => a + `\n${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
}
let underline = !this.done || !this.done && !this.placeholder;
let prompt = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), underline ? color[this.color]().underline(this.rendered) : this.rendered].join(` `);
let position = ``;
if (this.lines) {
position += cursor.up(this.lines);
position += cursor.left + cursor.to(strip(prompt).length);
}
this.out.write(clear + prompt + error + position);
this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore);
}
}

View File

@@ -23,17 +23,18 @@ class Prompt extends EventEmitter {
constructor(opts = {}) {
super();
this.firstRender = true;
this.in = opts.in || process.stdin;
this.out = opts.out || process.stdout;
this.in = opts.stdin || process.stdin;
this.out = opts.stdout || process.stdout;
this.onRender = (opts.onRender || (() => void 0)).bind(this);
const rl = readline.createInterface(this.in);
readline.emitKeypressEvents(this.in, rl);
if (this.in.isTTY) this.in.setRawMode(true);
const isSelect = ['SelectPrompt', 'MultiselectPrompt'].indexOf(this.constructor.name) > -1;
const keypress = (str, key) => {
let a = action(key);
let a = action(key, isSelect);
if (a === false) {
this._ && this._(str, key);

View File

@@ -7,10 +7,11 @@ const Prompt = require('./prompt');
const _require = require('../util'),
style = _require.style,
clear = _require.clear,
figures = _require.figures;
figures = _require.figures,
wrap = _require.wrap,
entriesToDisplay = _require.entriesToDisplay;
const _require2 = require('sisteransi'),
erase = _require2.erase,
cursor = _require2.cursor;
/**
* SelectPrompt Base Element
@@ -21,6 +22,7 @@ const _require2 = require('sisteransi'),
* @param {Number} [opts.initial] Index of default value
* @param {Stream} [opts.stdin] The Readable stream to listen to
* @param {Stream} [opts.stdout] The Writable stream to write readline data to
* @param {Number} [opts.optionsPerPage=10] Max options to display at once
*/
@@ -38,11 +40,13 @@ class SelectPrompt extends Prompt {
};
return {
title: ch && (ch.title || ch.value || ch),
value: ch && (ch.value || idx),
value: ch && (ch.value === undefined ? idx : ch.value),
description: ch && ch.description,
selected: ch && ch.selected,
disabled: ch && ch.disabled
};
});
this.optionsPerPage = opts.optionsPerPage || 10;
this.value = (this.choices[this.cursor] || {}).value;
this.clear = clear('');
this.render();
@@ -116,26 +120,57 @@ class SelectPrompt extends Prompt {
render() {
if (this.closed) return;
if (this.firstRender) this.out.write(cursor.hide);else this.out.write(erase.lines(this.choices.length + 1));
super.render(); // Print prompt
if (this.firstRender) this.out.write(cursor.hide);else this.out.write(clear(this.outputText));
super.render();
this.out.write([style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.done ? this.selection.title : this.selection.disabled ? color.yellow(this.warn) : color.gray(this.hint)].join(' ')); // Print choices
let _entriesToDisplay = entriesToDisplay(this.cursor, this.choices.length, this.optionsPerPage),
startIndex = _entriesToDisplay.startIndex,
endIndex = _entriesToDisplay.endIndex; // Print prompt
this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.done ? this.selection.title : this.selection.disabled ? color.yellow(this.warn) : color.gray(this.hint)].join(' '); // Print choices
if (!this.done) {
this.out.write('\n' + this.choices.map((v, i) => {
let title, prefix;
this.outputText += '\n';
for (let i = startIndex; i < endIndex; i++) {
let title,
prefix,
desc = '',
v = this.choices[i]; // Determine whether to display "more choices" indicators
if (i === startIndex && startIndex > 0) {
prefix = figures.arrowUp;
} else if (i === endIndex - 1 && endIndex < this.choices.length) {
prefix = figures.arrowDown;
} else {
prefix = ' ';
}
if (v.disabled) {
title = this.cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);
prefix = this.cursor === i ? color.bold().gray(figures.pointer) + ' ' : ' ';
prefix = (this.cursor === i ? color.bold().gray(figures.pointer) + ' ' : ' ') + prefix;
} else {
title = this.cursor === i ? color.cyan().underline(v.title) : v.title;
prefix = this.cursor === i ? color.cyan(figures.pointer) + ' ' : ' ';
prefix = (this.cursor === i ? color.cyan(figures.pointer) + ' ' : ' ') + prefix;
if (v.description && this.cursor === i) {
desc = ` - ${v.description}`;
if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) {
desc = '\n' + wrap(v.description, {
margin: 3,
width: this.out.columns
});
}
}
}
return `${prefix} ${title}`;
}).join('\n'));
this.outputText += `${prefix} ${title}${color.gray(desc)}\n`;
}
}
this.out.write(this.outputText);
}
}

View File

@@ -9,12 +9,13 @@ const color = require('kleur');
const Prompt = require('./prompt');
const _require = require('sisteransi'),
erase = _require.erase,
cursor = _require.cursor;
const _require2 = require('../util'),
style = _require2.style,
clear = _require2.clear,
strip = _require2.strip,
lines = _require2.lines,
figures = _require2.figures;
/**
* TextPrompt Base Element
@@ -191,28 +192,21 @@ class TextPrompt extends Prompt {
render() {
if (this.closed) return;
if (!this.firstRender) {
if (this.outputError) this.out.write(cursor.down(lines(this.outputError) - 1) + clear(this.outputError));
this.out.write(clear(this.outputText));
}
super.render();
let erase = (this.lines ? cursor.down(this.lines) : ``) + this.clear;
this.lines = 0;
let prompt = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), this.red ? color.red(this.rendered) : this.rendered].join(` `);
let error = ``;
this.outputError = '';
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(` `);
if (this.error) {
let lines = this.errorMsg.split(`\n`);
error += lines.reduce((a, l, i) => a += `\n${i ? ' ' : figures.pointerSmall} ${color.red().italic(l)}`, ``);
this.lines = lines.length;
this.outputError += this.errorMsg.split(`\n`).reduce((a, l, i) => a + `\n${i ? ' ' : figures.pointerSmall} ${color.red().italic(l)}`, ``);
}
let position = ``;
if (this.lines) {
position += cursor.up(this.lines);
position += cursor.left + cursor.to(strip(prompt).length);
}
position += cursor.move(this.placeholder ? -this.initial.length * this.scale : -this.rendered.length + this.cursor * this.scale);
this.out.write(erase + prompt + error + position);
this.clear = clear(prompt + error);
this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore);
}
}

View File

@@ -109,9 +109,10 @@ class TogglePrompt extends Prompt {
render() {
if (this.closed) return;
if (this.firstRender) this.out.write(cursor.hide);
if (this.firstRender) this.out.write(cursor.hide);else this.out.write(clear(this.outputText));
super.render();
this.out.write(erase.lines(this.first ? 1 : this.msg.split(/\n/g).length) + cursor.to(0) + [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), this.value ? this.inactive : color.cyan().underline(this.inactive), color.gray('/'), this.value ? color.cyan().underline(this.active) : this.active].join(' '));
this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), this.value ? this.inactive : color.cyan().underline(this.inactive), color.gray('/'), this.value ? color.cyan().underline(this.active) : this.active].join(' ');
this.out.write(erase.line + cursor.to(0) + this.outputText);
}
}

23
node_modules/prompts/dist/index.js generated vendored
View File

@@ -1,6 +1,8 @@
'use strict';
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -10,7 +12,7 @@ function _asyncToGenerator(fn) { return function () { var self = this, args = ar
const prompts = require('./prompts');
const passOn = ['suggest', 'format', 'onState', 'validate', 'onRender'];
const passOn = ['suggest', 'format', 'onState', 'validate', 'onRender', 'type'];
const noop = () => {};
/**
@@ -34,7 +36,7 @@ function _prompt() {
const answers = {};
const override = prompt._override || {};
questions = [].concat(questions);
let answer, question, quit, name, type;
let answer, question, quit, name, type, lastPrompt;
const getFormattedAnswer =
/*#__PURE__*/
@@ -63,13 +65,22 @@ function _prompt() {
name = _question.name;
type = _question.type;
// if property is a function, invoke it unless it's a special function
// evaluate type first and skip if type is a falsy value
if (typeof type === 'function') {
type = yield type(answer, _objectSpread({}, answers), question);
question['type'] = type;
}
if (!type) continue; // if property is a function, invoke it unless it's a special function
for (let key in question) {
if (passOn.includes(key)) continue;
let value = question[key];
question[key] = typeof value === 'function' ? yield value(answer, _objectSpread({}, answers), question) : value;
question[key] = typeof value === 'function' ? yield value(answer, _objectSpread({}, answers), lastPrompt) : value;
}
lastPrompt = question;
if (typeof question.message !== 'string') {
throw new Error('prompt message is required');
} // update vars in case they changed
@@ -78,8 +89,6 @@ function _prompt() {
var _question2 = question;
name = _question2.name;
type = _question2.type;
// skip if type is a falsy value
if (!type) continue;
if (prompts[type] === void 0) {
throw new Error(`prompt type (${type}) is not defined`);

View File

@@ -1,6 +1,8 @@
'use strict';
module.exports = key => {
module.exports = (key, isSelect) => {
if (key.meta) return;
if (key.ctrl) {
if (key.name === 'a') return 'first';
if (key.name === 'c') return 'abort';
@@ -9,6 +11,11 @@ module.exports = key => {
if (key.name === 'g') return 'reset';
}
if (isSelect) {
if (key.name === 'j') return 'down';
if (key.name === 'k') return 'up';
}
if (key.name === 'return') return 'submit';
if (key.name === 'enter') return 'submit'; // ctrl + J

21
node_modules/prompts/dist/util/entriesToDisplay.js generated vendored Normal file
View File

@@ -0,0 +1,21 @@
'use strict';
/**
* Determine what entries should be displayed on the screen, based on the
* currently selected index and the maximum visible. Used in list-based
* prompts like `select` and `multiselect`.
*
* @param {number} cursor the currently selected entry
* @param {number} total the total entries available to display
* @param {number} [maxVisible] the number of entries that can be displayed
*/
module.exports = (cursor, total, maxVisible) => {
maxVisible = maxVisible || total;
let startIndex = Math.min(total - maxVisible, cursor - Math.floor(maxVisible / 2));
if (startIndex < 0) startIndex = 0;
let endIndex = Math.min(startIndex + maxVisible, total);
return {
startIndex,
endIndex
};
};

View File

@@ -5,5 +5,8 @@ module.exports = {
clear: require('./clear'),
style: require('./style'),
strip: require('./strip'),
figures: require('./figures')
figures: require('./figures'),
lines: require('./lines'),
wrap: require('./wrap'),
entriesToDisplay: require('./entriesToDisplay')
};

9
node_modules/prompts/dist/util/lines.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
'use strict';
const strip = require('./strip');
module.exports = function (msg, perLine = process.stdout.columns) {
let lines = String(strip(msg) || '').split(/\r?\n/);
if (!perLine) return lines.length;
return lines.map(l => Math.ceil(l.length / perLine)).reduce((a, b) => a + b);
};

16
node_modules/prompts/dist/util/wrap.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
'use strict';
/**
* @param {string} msg The message to wrap
* @param {object} [opts]
* @param {number|string} [opts.margin] Left margin
* @param {number} [opts.width] Maximum characters per line including the margin
*/
module.exports = (msg, opts = {}) => {
const tab = Number.isSafeInteger(parseInt(opts.margin)) ? new Array(parseInt(opts.margin)).fill(' ').join('') : opts.margin || '';
const width = opts.width || process.stdout.columns;
return (msg || '').split(/\r?\n/g).map(line => line.split(/\s+/g).reduce((arr, w) => {
if (w.length + tab.length >= width || arr[arr.length - 1].length + w.length + 1 < width) arr[arr.length - 1] += ` ${w}`;else arr.push(`${tab}${w}`);
return arr;
}, [tab]).join('\n')).join('\n');
};