@topcli/prompts 2.2.0 → 2.3.0
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.
- package/README.md +2 -2
- package/dist/index.cjs +68 -69
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +38 -39
- package/package.json +2 -5
package/README.md
CHANGED
|
@@ -70,8 +70,8 @@ const packageName = await question('Package name', {
|
|
|
70
70
|
validators: [
|
|
71
71
|
{
|
|
72
72
|
validate: (value) => {
|
|
73
|
-
if (
|
|
74
|
-
return `Folder ${value} already exists
|
|
73
|
+
if (fs.existsSync(path.join(process.cwd(), value))) {
|
|
74
|
+
return `Folder ${value} already exists`;
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -41,35 +41,14 @@ module.exports = __toCommonJS(index_exports);
|
|
|
41
41
|
|
|
42
42
|
// src/prompts/question.ts
|
|
43
43
|
var import_node_os2 = require("os");
|
|
44
|
-
var
|
|
45
|
-
var import_wcwidth = __toESM(require("@topcli/wcwidth"), 1);
|
|
44
|
+
var import_node_util4 = require("util");
|
|
46
45
|
|
|
47
46
|
// src/prompts/abstract.ts
|
|
48
47
|
var import_node_os = require("os");
|
|
49
48
|
var import_node_readline = __toESM(require("readline"), 1);
|
|
50
49
|
var import_node_stream = require("stream");
|
|
51
50
|
var import_node_events = __toESM(require("events"), 1);
|
|
52
|
-
|
|
53
|
-
// src/utils.ts
|
|
54
|
-
var import_node_process = __toESM(require("process"), 1);
|
|
55
|
-
var kAnsiRegex = ansiRegex();
|
|
56
|
-
function ansiRegex({ onlyFirst = false } = {}) {
|
|
57
|
-
const pattern = [
|
|
58
|
-
// eslint-disable-next-line @stylistic/max-len
|
|
59
|
-
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
|
|
60
|
-
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"
|
|
61
|
-
].join("|");
|
|
62
|
-
return new RegExp(pattern, onlyFirst ? void 0 : "g");
|
|
63
|
-
}
|
|
64
|
-
function stripAnsi(string) {
|
|
65
|
-
return string.replace(kAnsiRegex, "");
|
|
66
|
-
}
|
|
67
|
-
function isUnicodeSupported() {
|
|
68
|
-
if (import_node_process.default.platform !== "win32") {
|
|
69
|
-
return import_node_process.default.env.TERM !== "linux";
|
|
70
|
-
}
|
|
71
|
-
return Boolean(import_node_process.default.env.WT_SESSION) || Boolean(import_node_process.default.env.TERMINUS_SUBLIME) || import_node_process.default.env.ConEmuTask === "{cmd::Cmder}" || import_node_process.default.env.TERM_PROGRAM === "Terminus-Sublime" || import_node_process.default.env.TERM_PROGRAM === "vscode" || import_node_process.default.env.TERM === "xterm-256color" || import_node_process.default.env.TERM === "alacritty" || import_node_process.default.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
72
|
-
}
|
|
51
|
+
var import_node_util = require("util");
|
|
73
52
|
|
|
74
53
|
// src/prompt-agent.ts
|
|
75
54
|
var kPrivateInstancier = Symbol("instancier");
|
|
@@ -193,7 +172,7 @@ var AbstractPrompt = class _AbstractPrompt extends import_node_events.default {
|
|
|
193
172
|
}
|
|
194
173
|
}
|
|
195
174
|
write(data) {
|
|
196
|
-
const formattedData =
|
|
175
|
+
const formattedData = (0, import_node_util.stripVTControlCharacters)(data).replace(import_node_os.EOL, "");
|
|
197
176
|
if (formattedData) {
|
|
198
177
|
this.history.push(formattedData);
|
|
199
178
|
}
|
|
@@ -204,7 +183,7 @@ var AbstractPrompt = class _AbstractPrompt extends import_node_events.default {
|
|
|
204
183
|
if (!lastLine) {
|
|
205
184
|
return;
|
|
206
185
|
}
|
|
207
|
-
const lastLineRows = Math.ceil(
|
|
186
|
+
const lastLineRows = Math.ceil((0, import_node_util.stripVTControlCharacters)(lastLine).length / this.stdout.columns);
|
|
208
187
|
this.stdout.moveCursor(-this.stdout.columns, -lastLineRows);
|
|
209
188
|
this.stdout.clearScreenDown();
|
|
210
189
|
}
|
|
@@ -216,8 +195,31 @@ var AbstractPrompt = class _AbstractPrompt extends import_node_events.default {
|
|
|
216
195
|
}
|
|
217
196
|
};
|
|
218
197
|
|
|
198
|
+
// src/utils.ts
|
|
199
|
+
var import_node_process = __toESM(require("process"), 1);
|
|
200
|
+
var import_node_util2 = require("util");
|
|
201
|
+
var kLenSegmenter = new Intl.Segmenter();
|
|
202
|
+
function isUnicodeSupported() {
|
|
203
|
+
if (import_node_process.default.platform !== "win32") {
|
|
204
|
+
return import_node_process.default.env.TERM !== "linux";
|
|
205
|
+
}
|
|
206
|
+
return Boolean(import_node_process.default.env.WT_SESSION) || Boolean(import_node_process.default.env.TERMINUS_SUBLIME) || import_node_process.default.env.ConEmuTask === "{cmd::Cmder}" || import_node_process.default.env.TERM_PROGRAM === "Terminus-Sublime" || import_node_process.default.env.TERM_PROGRAM === "vscode" || import_node_process.default.env.TERM === "xterm-256color" || import_node_process.default.env.TERM === "alacritty" || import_node_process.default.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
207
|
+
}
|
|
208
|
+
function stringLength(string) {
|
|
209
|
+
if (string === "") {
|
|
210
|
+
return 0;
|
|
211
|
+
}
|
|
212
|
+
let length = 0;
|
|
213
|
+
for (const _ of kLenSegmenter.segment(
|
|
214
|
+
(0, import_node_util2.stripVTControlCharacters)(string)
|
|
215
|
+
)) {
|
|
216
|
+
length++;
|
|
217
|
+
}
|
|
218
|
+
return length;
|
|
219
|
+
}
|
|
220
|
+
|
|
219
221
|
// src/constants.ts
|
|
220
|
-
var
|
|
222
|
+
var import_node_util3 = require("util");
|
|
221
223
|
var kMainSymbols = {
|
|
222
224
|
tick: "\u2714",
|
|
223
225
|
cross: "\u2716",
|
|
@@ -237,18 +239,18 @@ var kFallbackSymbols = {
|
|
|
237
239
|
inactive: "(-)"
|
|
238
240
|
};
|
|
239
241
|
var kSymbols = isUnicodeSupported() || process.env.CI ? kMainSymbols : kFallbackSymbols;
|
|
240
|
-
var kPointer = (0,
|
|
242
|
+
var kPointer = (0, import_node_util3.styleText)("gray", kSymbols.pointer);
|
|
241
243
|
var SYMBOLS = {
|
|
242
|
-
QuestionMark: (0,
|
|
243
|
-
Tick: (0,
|
|
244
|
-
Cross: (0,
|
|
244
|
+
QuestionMark: (0, import_node_util3.styleText)(["blue", "bold"], "?"),
|
|
245
|
+
Tick: (0, import_node_util3.styleText)(["green", "bold"], kSymbols.tick),
|
|
246
|
+
Cross: (0, import_node_util3.styleText)(["red", "bold"], kSymbols.cross),
|
|
245
247
|
Pointer: kPointer,
|
|
246
248
|
Previous: kSymbols.previous,
|
|
247
249
|
Next: kSymbols.next,
|
|
248
250
|
ShowCursor: "\x1B[?25h",
|
|
249
251
|
HideCursor: "\x1B[?25l",
|
|
250
|
-
Active: (0,
|
|
251
|
-
Inactive: (0,
|
|
252
|
+
Active: (0, import_node_util3.styleText)("cyan", kSymbols.active),
|
|
253
|
+
Inactive: (0, import_node_util3.styleText)("gray", kSymbols.inactive)
|
|
252
254
|
};
|
|
253
255
|
|
|
254
256
|
// src/validators.ts
|
|
@@ -315,20 +317,20 @@ var QuestionPrompt = class extends AbstractPrompt {
|
|
|
315
317
|
});
|
|
316
318
|
}
|
|
317
319
|
#getQuestionQuery() {
|
|
318
|
-
return `${(0,
|
|
320
|
+
return `${(0, import_node_util4.styleText)("bold", `${SYMBOLS.QuestionMark} ${this.message}${this.tip}`)} ${this.questionSuffixError}`;
|
|
319
321
|
}
|
|
320
322
|
#setQuestionSuffixError(error) {
|
|
321
|
-
const suffix = (0,
|
|
323
|
+
const suffix = (0, import_node_util4.styleText)("red", `[${error}] `);
|
|
322
324
|
this.questionSuffixError = suffix;
|
|
323
325
|
}
|
|
324
326
|
#writeAnswer() {
|
|
325
327
|
const prefix = this.answer ? SYMBOLS.Tick : SYMBOLS.Cross;
|
|
326
|
-
const answer = (0,
|
|
327
|
-
this.write(`${prefix} ${(0,
|
|
328
|
+
const answer = (0, import_node_util4.styleText)("yellow", this.#secure ? "CONFIDENTIAL" : this.answer ?? "");
|
|
329
|
+
this.write(`${prefix} ${(0, import_node_util4.styleText)("bold", this.message)} ${SYMBOLS.Pointer} ${answer}${import_node_os2.EOL}`);
|
|
328
330
|
}
|
|
329
331
|
#onQuestionAnswer() {
|
|
330
332
|
const questionLineCount = Math.ceil(
|
|
331
|
-
(
|
|
333
|
+
stringLength(this.#getQuestionQuery() + this.answer) / this.stdout.columns
|
|
332
334
|
);
|
|
333
335
|
this.stdout.moveCursor(-this.stdout.columns, -questionLineCount);
|
|
334
336
|
this.stdout.clearScreenDown();
|
|
@@ -376,8 +378,7 @@ var QuestionPrompt = class extends AbstractPrompt {
|
|
|
376
378
|
|
|
377
379
|
// src/prompts/confirm.ts
|
|
378
380
|
var import_node_os3 = require("os");
|
|
379
|
-
var
|
|
380
|
-
var import_wcwidth2 = __toESM(require("@topcli/wcwidth"), 1);
|
|
381
|
+
var import_node_util5 = require("util");
|
|
381
382
|
var kToggleKeys = /* @__PURE__ */ new Set([
|
|
382
383
|
"left",
|
|
383
384
|
"right",
|
|
@@ -407,8 +408,8 @@ var ConfirmPrompt = class extends AbstractPrompt {
|
|
|
407
408
|
this.selectedValue = initial;
|
|
408
409
|
}
|
|
409
410
|
#getHint() {
|
|
410
|
-
const Yes = (0,
|
|
411
|
-
const No = (0,
|
|
411
|
+
const Yes = (0, import_node_util5.styleText)(["cyan", "bold", "underline"], "Yes");
|
|
412
|
+
const No = (0, import_node_util5.styleText)(["cyan", "bold", "underline"], "No");
|
|
412
413
|
return this.selectedValue ? `${Yes}/No` : `Yes/${No}`;
|
|
413
414
|
}
|
|
414
415
|
#render() {
|
|
@@ -427,7 +428,7 @@ var ConfirmPrompt = class extends AbstractPrompt {
|
|
|
427
428
|
#onKeypress(resolve, _value, key) {
|
|
428
429
|
this.stdout.moveCursor(
|
|
429
430
|
-this.stdout.columns,
|
|
430
|
-
-Math.floor((
|
|
431
|
+
-Math.floor(stringLength(this.#getQuestionQuery()) / this.stdout.columns)
|
|
431
432
|
);
|
|
432
433
|
this.stdout.clearScreenDown();
|
|
433
434
|
if (key.name === "return") {
|
|
@@ -454,17 +455,17 @@ var ConfirmPrompt = class extends AbstractPrompt {
|
|
|
454
455
|
this.stdin.off("keypress", this.#boundKeyPressEvent);
|
|
455
456
|
}
|
|
456
457
|
#getQuestionQuery() {
|
|
457
|
-
const query = (0,
|
|
458
|
+
const query = (0, import_node_util5.styleText)("bold", `${SYMBOLS.QuestionMark} ${this.message}`);
|
|
458
459
|
return `${query} ${this.#getHint()}`;
|
|
459
460
|
}
|
|
460
461
|
#onQuestionAnswer() {
|
|
461
462
|
this.clearLastLine();
|
|
462
463
|
this.stdout.moveCursor(
|
|
463
464
|
-this.stdout.columns,
|
|
464
|
-
-Math.floor((
|
|
465
|
+
-Math.floor(stringLength(this.#getQuestionQuery()) / this.stdout.columns)
|
|
465
466
|
);
|
|
466
467
|
this.stdout.clearScreenDown();
|
|
467
|
-
this.write(`${this.selectedValue ? SYMBOLS.Tick : SYMBOLS.Cross} ${(0,
|
|
468
|
+
this.write(`${this.selectedValue ? SYMBOLS.Tick : SYMBOLS.Cross} ${(0, import_node_util5.styleText)("bold", this.message)}${import_node_os3.EOL}`);
|
|
468
469
|
}
|
|
469
470
|
async confirm() {
|
|
470
471
|
if (this.skip) {
|
|
@@ -500,8 +501,7 @@ var ConfirmPrompt = class extends AbstractPrompt {
|
|
|
500
501
|
|
|
501
502
|
// src/prompts/select.ts
|
|
502
503
|
var import_node_os4 = require("os");
|
|
503
|
-
var
|
|
504
|
-
var import_wcwidth3 = __toESM(require("@topcli/wcwidth"), 1);
|
|
504
|
+
var import_node_util6 = require("util");
|
|
505
505
|
var kRequiredChoiceProperties = ["label", "value"];
|
|
506
506
|
var SelectPrompt = class extends AbstractPrompt {
|
|
507
507
|
#boundExitEvent = () => void 0;
|
|
@@ -608,14 +608,14 @@ var SelectPrompt = class extends AbstractPrompt {
|
|
|
608
608
|
);
|
|
609
609
|
const formattedDescription = choice.description ? ` - ${choice.description}` : "";
|
|
610
610
|
const styles = isChoiceSelected ? ["white", "bold"] : ["gray"];
|
|
611
|
-
const str = `${prefix}${(0,
|
|
611
|
+
const str = `${prefix}${(0, import_node_util6.styleText)(styles, `${formattedLabel}${formattedDescription}`)}${import_node_os4.EOL}`;
|
|
612
612
|
this.write(str);
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
|
-
#showAnsweredQuestion(
|
|
616
|
-
const symbolPrefix =
|
|
617
|
-
const prefix = `${symbolPrefix} ${(0,
|
|
618
|
-
const formattedChoice = (0,
|
|
615
|
+
#showAnsweredQuestion(label) {
|
|
616
|
+
const symbolPrefix = label === "" ? SYMBOLS.Cross : SYMBOLS.Tick;
|
|
617
|
+
const prefix = `${symbolPrefix} ${(0, import_node_util6.styleText)("bold", this.message)} ${SYMBOLS.Pointer}`;
|
|
618
|
+
const formattedChoice = (0, import_node_util6.styleText)("yellow", label);
|
|
619
619
|
this.write(`${prefix} ${formattedChoice}${import_node_os4.EOL}`);
|
|
620
620
|
}
|
|
621
621
|
#onProcessExit() {
|
|
@@ -697,7 +697,7 @@ var SelectPrompt = class extends AbstractPrompt {
|
|
|
697
697
|
}
|
|
698
698
|
if (this.options.autocomplete) {
|
|
699
699
|
let linesToClear2 = Math.ceil(
|
|
700
|
-
(
|
|
700
|
+
stringLength(`${SYMBOLS.Pointer} ${this.autocompleteValue}`) / this.stdout.columns
|
|
701
701
|
);
|
|
702
702
|
while (linesToClear2 > 0) {
|
|
703
703
|
this.clearLastLine();
|
|
@@ -707,14 +707,14 @@ var SelectPrompt = class extends AbstractPrompt {
|
|
|
707
707
|
}
|
|
708
708
|
if (clearRender) {
|
|
709
709
|
const questionLineCount = Math.ceil(
|
|
710
|
-
(
|
|
710
|
+
stringLength(this.questionMessage) / this.stdout.columns
|
|
711
711
|
);
|
|
712
712
|
this.stdout.moveCursor(-this.stdout.columns, -(1 + questionLineCount));
|
|
713
713
|
this.stdout.clearScreenDown();
|
|
714
714
|
return;
|
|
715
715
|
}
|
|
716
716
|
if (error) {
|
|
717
|
-
const linesToClear = Math.ceil((
|
|
717
|
+
const linesToClear = Math.ceil(stringLength(this.questionMessage) / this.stdout.columns) + 1;
|
|
718
718
|
this.stdout.moveCursor(0, -linesToClear);
|
|
719
719
|
this.stdout.clearScreenDown();
|
|
720
720
|
this.#showQuestion(error);
|
|
@@ -731,17 +731,16 @@ var SelectPrompt = class extends AbstractPrompt {
|
|
|
731
731
|
#showQuestion(error = null) {
|
|
732
732
|
let hint = "";
|
|
733
733
|
if (error) {
|
|
734
|
-
hint = ` ${hint.length > 0 ? " " : ""}${(0,
|
|
734
|
+
hint = ` ${hint.length > 0 ? " " : ""}${(0, import_node_util6.styleText)(["red", "bold"], `[${error}]`)}`;
|
|
735
735
|
}
|
|
736
|
-
this.questionMessage = `${SYMBOLS.QuestionMark} ${(0,
|
|
736
|
+
this.questionMessage = `${SYMBOLS.QuestionMark} ${(0, import_node_util6.styleText)("bold", this.message)}${hint}`;
|
|
737
737
|
this.write(`${this.questionMessage}${import_node_os4.EOL}`);
|
|
738
738
|
}
|
|
739
739
|
};
|
|
740
740
|
|
|
741
741
|
// src/prompts/multiselect.ts
|
|
742
742
|
var import_node_os5 = require("os");
|
|
743
|
-
var
|
|
744
|
-
var import_wcwidth4 = __toESM(require("@topcli/wcwidth"), 1);
|
|
743
|
+
var import_node_util7 = require("util");
|
|
745
744
|
var kRequiredChoiceProperties2 = ["label", "value"];
|
|
746
745
|
var MultiselectPrompt = class extends AbstractPrompt {
|
|
747
746
|
#boundExitEvent = () => void 0;
|
|
@@ -867,14 +866,14 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
867
866
|
);
|
|
868
867
|
const formattedDescription = choice.description ? ` - ${choice.description}` : "";
|
|
869
868
|
const styles = isChoiceActive ? ["white", "bold"] : ["gray"];
|
|
870
|
-
const str = `${prefix} ${(0,
|
|
869
|
+
const str = `${prefix} ${(0, import_node_util7.styleText)(styles, `${formattedLabel}${formattedDescription}`)}${import_node_os5.EOL}`;
|
|
871
870
|
this.write(str);
|
|
872
871
|
}
|
|
873
872
|
}
|
|
874
873
|
#showAnsweredQuestion(choices, isAgentAnswer = false) {
|
|
875
874
|
const prefixSymbol = this.selectedIndexes.size === 0 && !isAgentAnswer ? SYMBOLS.Cross : SYMBOLS.Tick;
|
|
876
|
-
const prefix = `${prefixSymbol} ${(0,
|
|
877
|
-
const formattedChoice = (0,
|
|
875
|
+
const prefix = `${prefixSymbol} ${(0, import_node_util7.styleText)("bold", this.message)} ${SYMBOLS.Pointer}`;
|
|
876
|
+
const formattedChoice = (0, import_node_util7.styleText)("yellow", choices);
|
|
878
877
|
this.write(`${prefix}${choices ? ` ${formattedChoice}` : ""}${import_node_os5.EOL}`);
|
|
879
878
|
}
|
|
880
879
|
#selectedChoices() {
|
|
@@ -982,7 +981,7 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
982
981
|
}
|
|
983
982
|
if (this.options.autocomplete) {
|
|
984
983
|
let linesToClear2 = Math.ceil(
|
|
985
|
-
(
|
|
984
|
+
stringLength(`${SYMBOLS.Pointer} ${this.autocompleteValue}`) / this.stdout.columns
|
|
986
985
|
);
|
|
987
986
|
while (linesToClear2 > 0) {
|
|
988
987
|
this.clearLastLine();
|
|
@@ -992,14 +991,14 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
992
991
|
}
|
|
993
992
|
if (clearRender) {
|
|
994
993
|
const questionLineCount = Math.ceil(
|
|
995
|
-
(
|
|
994
|
+
stringLength(this.questionMessage) / this.stdout.columns
|
|
996
995
|
);
|
|
997
996
|
this.stdout.moveCursor(-this.stdout.columns, -(1 + questionLineCount));
|
|
998
997
|
this.stdout.clearScreenDown();
|
|
999
998
|
return;
|
|
1000
999
|
}
|
|
1001
1000
|
if (error) {
|
|
1002
|
-
const linesToClear = Math.ceil((
|
|
1001
|
+
const linesToClear = Math.ceil(stringLength(this.questionMessage) / this.stdout.columns) + 1;
|
|
1003
1002
|
this.stdout.moveCursor(0, -linesToClear);
|
|
1004
1003
|
this.stdout.clearScreenDown();
|
|
1005
1004
|
this.#showQuestion(error);
|
|
@@ -1014,15 +1013,15 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
1014
1013
|
});
|
|
1015
1014
|
}
|
|
1016
1015
|
#showQuestion(error = null) {
|
|
1017
|
-
let hint = this.#showHint ? (0,
|
|
1016
|
+
let hint = this.#showHint ? (0, import_node_util7.styleText)(
|
|
1018
1017
|
"gray",
|
|
1019
1018
|
// eslint-disable-next-line @stylistic/max-len
|
|
1020
|
-
`(Press ${(0,
|
|
1019
|
+
`(Press ${(0, import_node_util7.styleText)("bold", "<Ctrl+A>")} to toggle all, ${(0, import_node_util7.styleText)("bold", "<Left/Right>")} to toggle, ${(0, import_node_util7.styleText)("bold", "<Return>")} to submit)`
|
|
1021
1020
|
) : "";
|
|
1022
1021
|
if (error) {
|
|
1023
|
-
hint += `${hint.length > 0 ? " " : ""}${(0,
|
|
1022
|
+
hint += `${hint.length > 0 ? " " : ""}${(0, import_node_util7.styleText)(["red", "bold"], `[${error}]`)}`;
|
|
1024
1023
|
}
|
|
1025
|
-
this.questionMessage = `${SYMBOLS.QuestionMark} ${(0,
|
|
1024
|
+
this.questionMessage = `${SYMBOLS.QuestionMark} ${(0, import_node_util7.styleText)("bold", this.message)}${hint.length > 0 ? ` ${hint}` : ""}`;
|
|
1026
1025
|
this.write(`${this.questionMessage}${import_node_os5.EOL}`);
|
|
1027
1026
|
}
|
|
1028
1027
|
};
|
package/dist/index.d.cts
CHANGED
|
@@ -69,21 +69,21 @@ interface ConfirmOptions extends AbstractPromptOptions {
|
|
|
69
69
|
initial?: boolean;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
interface MultiselectOptions<T extends string
|
|
73
|
-
choices: (Choice | T)[];
|
|
72
|
+
interface MultiselectOptions<T extends string> extends AbstractPromptOptions {
|
|
73
|
+
choices: (Choice<T> | T)[];
|
|
74
74
|
maxVisible?: number;
|
|
75
|
-
preSelectedChoices?: (Choice |
|
|
76
|
-
validators?: PromptValidator[];
|
|
75
|
+
preSelectedChoices?: (Choice | T)[];
|
|
76
|
+
validators?: PromptValidator<T[]>[];
|
|
77
77
|
autocomplete?: boolean;
|
|
78
78
|
caseSensitive?: boolean;
|
|
79
79
|
showHint?: boolean;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
interface SelectOptions<T extends string
|
|
83
|
-
choices: (Choice | T)[];
|
|
82
|
+
interface SelectOptions<T extends string> extends AbstractPromptOptions {
|
|
83
|
+
choices: (Choice<T> | T)[];
|
|
84
84
|
maxVisible?: number;
|
|
85
|
-
ignoreValues?: (
|
|
86
|
-
validators?: PromptValidator[];
|
|
85
|
+
ignoreValues?: (T | number | boolean)[];
|
|
86
|
+
validators?: PromptValidator<T>[];
|
|
87
87
|
autocomplete?: boolean;
|
|
88
88
|
caseSensitive?: boolean;
|
|
89
89
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -69,21 +69,21 @@ interface ConfirmOptions extends AbstractPromptOptions {
|
|
|
69
69
|
initial?: boolean;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
interface MultiselectOptions<T extends string
|
|
73
|
-
choices: (Choice | T)[];
|
|
72
|
+
interface MultiselectOptions<T extends string> extends AbstractPromptOptions {
|
|
73
|
+
choices: (Choice<T> | T)[];
|
|
74
74
|
maxVisible?: number;
|
|
75
|
-
preSelectedChoices?: (Choice |
|
|
76
|
-
validators?: PromptValidator[];
|
|
75
|
+
preSelectedChoices?: (Choice | T)[];
|
|
76
|
+
validators?: PromptValidator<T[]>[];
|
|
77
77
|
autocomplete?: boolean;
|
|
78
78
|
caseSensitive?: boolean;
|
|
79
79
|
showHint?: boolean;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
interface SelectOptions<T extends string
|
|
83
|
-
choices: (Choice | T)[];
|
|
82
|
+
interface SelectOptions<T extends string> extends AbstractPromptOptions {
|
|
83
|
+
choices: (Choice<T> | T)[];
|
|
84
84
|
maxVisible?: number;
|
|
85
|
-
ignoreValues?: (
|
|
86
|
-
validators?: PromptValidator[];
|
|
85
|
+
ignoreValues?: (T | number | boolean)[];
|
|
86
|
+
validators?: PromptValidator<T>[];
|
|
87
87
|
autocomplete?: boolean;
|
|
88
88
|
caseSensitive?: boolean;
|
|
89
89
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,34 +1,13 @@
|
|
|
1
1
|
// src/prompts/question.ts
|
|
2
2
|
import { EOL as EOL2 } from "node:os";
|
|
3
3
|
import { styleText as styleText2 } from "node:util";
|
|
4
|
-
import wcwidth from "@topcli/wcwidth";
|
|
5
4
|
|
|
6
5
|
// src/prompts/abstract.ts
|
|
7
6
|
import { EOL } from "node:os";
|
|
8
7
|
import readline from "node:readline";
|
|
9
8
|
import { Writable } from "node:stream";
|
|
10
9
|
import EventEmitter from "node:events";
|
|
11
|
-
|
|
12
|
-
// src/utils.ts
|
|
13
|
-
import process2 from "node:process";
|
|
14
|
-
var kAnsiRegex = ansiRegex();
|
|
15
|
-
function ansiRegex({ onlyFirst = false } = {}) {
|
|
16
|
-
const pattern = [
|
|
17
|
-
// eslint-disable-next-line @stylistic/max-len
|
|
18
|
-
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
|
|
19
|
-
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"
|
|
20
|
-
].join("|");
|
|
21
|
-
return new RegExp(pattern, onlyFirst ? void 0 : "g");
|
|
22
|
-
}
|
|
23
|
-
function stripAnsi(string) {
|
|
24
|
-
return string.replace(kAnsiRegex, "");
|
|
25
|
-
}
|
|
26
|
-
function isUnicodeSupported() {
|
|
27
|
-
if (process2.platform !== "win32") {
|
|
28
|
-
return process2.env.TERM !== "linux";
|
|
29
|
-
}
|
|
30
|
-
return Boolean(process2.env.WT_SESSION) || Boolean(process2.env.TERMINUS_SUBLIME) || process2.env.ConEmuTask === "{cmd::Cmder}" || process2.env.TERM_PROGRAM === "Terminus-Sublime" || process2.env.TERM_PROGRAM === "vscode" || process2.env.TERM === "xterm-256color" || process2.env.TERM === "alacritty" || process2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
31
|
-
}
|
|
10
|
+
import { stripVTControlCharacters } from "node:util";
|
|
32
11
|
|
|
33
12
|
// src/prompt-agent.ts
|
|
34
13
|
var kPrivateInstancier = Symbol("instancier");
|
|
@@ -152,7 +131,7 @@ var AbstractPrompt = class _AbstractPrompt extends EventEmitter {
|
|
|
152
131
|
}
|
|
153
132
|
}
|
|
154
133
|
write(data) {
|
|
155
|
-
const formattedData =
|
|
134
|
+
const formattedData = stripVTControlCharacters(data).replace(EOL, "");
|
|
156
135
|
if (formattedData) {
|
|
157
136
|
this.history.push(formattedData);
|
|
158
137
|
}
|
|
@@ -163,7 +142,7 @@ var AbstractPrompt = class _AbstractPrompt extends EventEmitter {
|
|
|
163
142
|
if (!lastLine) {
|
|
164
143
|
return;
|
|
165
144
|
}
|
|
166
|
-
const lastLineRows = Math.ceil(
|
|
145
|
+
const lastLineRows = Math.ceil(stripVTControlCharacters(lastLine).length / this.stdout.columns);
|
|
167
146
|
this.stdout.moveCursor(-this.stdout.columns, -lastLineRows);
|
|
168
147
|
this.stdout.clearScreenDown();
|
|
169
148
|
}
|
|
@@ -175,6 +154,29 @@ var AbstractPrompt = class _AbstractPrompt extends EventEmitter {
|
|
|
175
154
|
}
|
|
176
155
|
};
|
|
177
156
|
|
|
157
|
+
// src/utils.ts
|
|
158
|
+
import process2 from "node:process";
|
|
159
|
+
import { stripVTControlCharacters as stripVTControlCharacters2 } from "node:util";
|
|
160
|
+
var kLenSegmenter = new Intl.Segmenter();
|
|
161
|
+
function isUnicodeSupported() {
|
|
162
|
+
if (process2.platform !== "win32") {
|
|
163
|
+
return process2.env.TERM !== "linux";
|
|
164
|
+
}
|
|
165
|
+
return Boolean(process2.env.WT_SESSION) || Boolean(process2.env.TERMINUS_SUBLIME) || process2.env.ConEmuTask === "{cmd::Cmder}" || process2.env.TERM_PROGRAM === "Terminus-Sublime" || process2.env.TERM_PROGRAM === "vscode" || process2.env.TERM === "xterm-256color" || process2.env.TERM === "alacritty" || process2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
166
|
+
}
|
|
167
|
+
function stringLength(string) {
|
|
168
|
+
if (string === "") {
|
|
169
|
+
return 0;
|
|
170
|
+
}
|
|
171
|
+
let length = 0;
|
|
172
|
+
for (const _ of kLenSegmenter.segment(
|
|
173
|
+
stripVTControlCharacters2(string)
|
|
174
|
+
)) {
|
|
175
|
+
length++;
|
|
176
|
+
}
|
|
177
|
+
return length;
|
|
178
|
+
}
|
|
179
|
+
|
|
178
180
|
// src/constants.ts
|
|
179
181
|
import { styleText } from "node:util";
|
|
180
182
|
var kMainSymbols = {
|
|
@@ -287,7 +289,7 @@ var QuestionPrompt = class extends AbstractPrompt {
|
|
|
287
289
|
}
|
|
288
290
|
#onQuestionAnswer() {
|
|
289
291
|
const questionLineCount = Math.ceil(
|
|
290
|
-
|
|
292
|
+
stringLength(this.#getQuestionQuery() + this.answer) / this.stdout.columns
|
|
291
293
|
);
|
|
292
294
|
this.stdout.moveCursor(-this.stdout.columns, -questionLineCount);
|
|
293
295
|
this.stdout.clearScreenDown();
|
|
@@ -336,7 +338,6 @@ var QuestionPrompt = class extends AbstractPrompt {
|
|
|
336
338
|
// src/prompts/confirm.ts
|
|
337
339
|
import { EOL as EOL3 } from "node:os";
|
|
338
340
|
import { styleText as styleText3 } from "node:util";
|
|
339
|
-
import wcwidth2 from "@topcli/wcwidth";
|
|
340
341
|
var kToggleKeys = /* @__PURE__ */ new Set([
|
|
341
342
|
"left",
|
|
342
343
|
"right",
|
|
@@ -386,7 +387,7 @@ var ConfirmPrompt = class extends AbstractPrompt {
|
|
|
386
387
|
#onKeypress(resolve, _value, key) {
|
|
387
388
|
this.stdout.moveCursor(
|
|
388
389
|
-this.stdout.columns,
|
|
389
|
-
-Math.floor(
|
|
390
|
+
-Math.floor(stringLength(this.#getQuestionQuery()) / this.stdout.columns)
|
|
390
391
|
);
|
|
391
392
|
this.stdout.clearScreenDown();
|
|
392
393
|
if (key.name === "return") {
|
|
@@ -420,7 +421,7 @@ var ConfirmPrompt = class extends AbstractPrompt {
|
|
|
420
421
|
this.clearLastLine();
|
|
421
422
|
this.stdout.moveCursor(
|
|
422
423
|
-this.stdout.columns,
|
|
423
|
-
-Math.floor(
|
|
424
|
+
-Math.floor(stringLength(this.#getQuestionQuery()) / this.stdout.columns)
|
|
424
425
|
);
|
|
425
426
|
this.stdout.clearScreenDown();
|
|
426
427
|
this.write(`${this.selectedValue ? SYMBOLS.Tick : SYMBOLS.Cross} ${styleText3("bold", this.message)}${EOL3}`);
|
|
@@ -460,7 +461,6 @@ var ConfirmPrompt = class extends AbstractPrompt {
|
|
|
460
461
|
// src/prompts/select.ts
|
|
461
462
|
import { EOL as EOL4 } from "node:os";
|
|
462
463
|
import { styleText as styleText4 } from "node:util";
|
|
463
|
-
import wcwidth3 from "@topcli/wcwidth";
|
|
464
464
|
var kRequiredChoiceProperties = ["label", "value"];
|
|
465
465
|
var SelectPrompt = class extends AbstractPrompt {
|
|
466
466
|
#boundExitEvent = () => void 0;
|
|
@@ -571,10 +571,10 @@ var SelectPrompt = class extends AbstractPrompt {
|
|
|
571
571
|
this.write(str);
|
|
572
572
|
}
|
|
573
573
|
}
|
|
574
|
-
#showAnsweredQuestion(
|
|
575
|
-
const symbolPrefix =
|
|
574
|
+
#showAnsweredQuestion(label) {
|
|
575
|
+
const symbolPrefix = label === "" ? SYMBOLS.Cross : SYMBOLS.Tick;
|
|
576
576
|
const prefix = `${symbolPrefix} ${styleText4("bold", this.message)} ${SYMBOLS.Pointer}`;
|
|
577
|
-
const formattedChoice = styleText4("yellow",
|
|
577
|
+
const formattedChoice = styleText4("yellow", label);
|
|
578
578
|
this.write(`${prefix} ${formattedChoice}${EOL4}`);
|
|
579
579
|
}
|
|
580
580
|
#onProcessExit() {
|
|
@@ -656,7 +656,7 @@ var SelectPrompt = class extends AbstractPrompt {
|
|
|
656
656
|
}
|
|
657
657
|
if (this.options.autocomplete) {
|
|
658
658
|
let linesToClear2 = Math.ceil(
|
|
659
|
-
|
|
659
|
+
stringLength(`${SYMBOLS.Pointer} ${this.autocompleteValue}`) / this.stdout.columns
|
|
660
660
|
);
|
|
661
661
|
while (linesToClear2 > 0) {
|
|
662
662
|
this.clearLastLine();
|
|
@@ -666,14 +666,14 @@ var SelectPrompt = class extends AbstractPrompt {
|
|
|
666
666
|
}
|
|
667
667
|
if (clearRender) {
|
|
668
668
|
const questionLineCount = Math.ceil(
|
|
669
|
-
|
|
669
|
+
stringLength(this.questionMessage) / this.stdout.columns
|
|
670
670
|
);
|
|
671
671
|
this.stdout.moveCursor(-this.stdout.columns, -(1 + questionLineCount));
|
|
672
672
|
this.stdout.clearScreenDown();
|
|
673
673
|
return;
|
|
674
674
|
}
|
|
675
675
|
if (error) {
|
|
676
|
-
const linesToClear = Math.ceil(
|
|
676
|
+
const linesToClear = Math.ceil(stringLength(this.questionMessage) / this.stdout.columns) + 1;
|
|
677
677
|
this.stdout.moveCursor(0, -linesToClear);
|
|
678
678
|
this.stdout.clearScreenDown();
|
|
679
679
|
this.#showQuestion(error);
|
|
@@ -700,7 +700,6 @@ var SelectPrompt = class extends AbstractPrompt {
|
|
|
700
700
|
// src/prompts/multiselect.ts
|
|
701
701
|
import { EOL as EOL5 } from "node:os";
|
|
702
702
|
import { styleText as styleText5 } from "node:util";
|
|
703
|
-
import wcwidth4 from "@topcli/wcwidth";
|
|
704
703
|
var kRequiredChoiceProperties2 = ["label", "value"];
|
|
705
704
|
var MultiselectPrompt = class extends AbstractPrompt {
|
|
706
705
|
#boundExitEvent = () => void 0;
|
|
@@ -941,7 +940,7 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
941
940
|
}
|
|
942
941
|
if (this.options.autocomplete) {
|
|
943
942
|
let linesToClear2 = Math.ceil(
|
|
944
|
-
|
|
943
|
+
stringLength(`${SYMBOLS.Pointer} ${this.autocompleteValue}`) / this.stdout.columns
|
|
945
944
|
);
|
|
946
945
|
while (linesToClear2 > 0) {
|
|
947
946
|
this.clearLastLine();
|
|
@@ -951,14 +950,14 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
951
950
|
}
|
|
952
951
|
if (clearRender) {
|
|
953
952
|
const questionLineCount = Math.ceil(
|
|
954
|
-
|
|
953
|
+
stringLength(this.questionMessage) / this.stdout.columns
|
|
955
954
|
);
|
|
956
955
|
this.stdout.moveCursor(-this.stdout.columns, -(1 + questionLineCount));
|
|
957
956
|
this.stdout.clearScreenDown();
|
|
958
957
|
return;
|
|
959
958
|
}
|
|
960
959
|
if (error) {
|
|
961
|
-
const linesToClear = Math.ceil(
|
|
960
|
+
const linesToClear = Math.ceil(stringLength(this.questionMessage) / this.stdout.columns) + 1;
|
|
962
961
|
this.stdout.moveCursor(0, -linesToClear);
|
|
963
962
|
this.stdout.clearScreenDown();
|
|
964
963
|
this.#showQuestion(error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topcli/prompts",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Node.js user input library for command-line interfaces.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "tsup index.ts --format cjs,esm --dts --clean",
|
|
@@ -33,16 +33,13 @@
|
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@openally/config.eslint": "^2.0.0",
|
|
35
35
|
"@openally/config.typescript": "^1.0.3",
|
|
36
|
-
"@types/node": "^
|
|
36
|
+
"@types/node": "^24.0.3",
|
|
37
37
|
"c8": "^10.1.3",
|
|
38
38
|
"glob": "^11.0.0",
|
|
39
39
|
"tsup": "^8.3.5",
|
|
40
40
|
"tsx": "^4.19.2",
|
|
41
41
|
"typescript": "^5.7.2"
|
|
42
42
|
},
|
|
43
|
-
"dependencies": {
|
|
44
|
-
"@topcli/wcwidth": "^1.0.1"
|
|
45
|
-
},
|
|
46
43
|
"engines": {
|
|
47
44
|
"node": "^20.12.0 || >=21.7.0"
|
|
48
45
|
},
|