@topcli/prompts 1.9.0 → 1.10.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.
- package/README.md +51 -24
- package/dist/index.cjs +239 -172
- package/dist/index.d.cts +22 -16
- package/dist/index.d.ts +22 -16
- package/dist/index.js +239 -172
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import wcwidth from "@topcli/wcwidth";
|
|
|
7
7
|
import { EOL } from "os";
|
|
8
8
|
import { createInterface } from "readline";
|
|
9
9
|
import { Writable } from "stream";
|
|
10
|
+
import EventEmitter from "events";
|
|
10
11
|
|
|
11
12
|
// src/utils.ts
|
|
12
13
|
import process2 from "process";
|
|
@@ -72,25 +73,49 @@ var PromptAgent = class _PromptAgent {
|
|
|
72
73
|
}
|
|
73
74
|
};
|
|
74
75
|
|
|
76
|
+
// src/errors/abort.ts
|
|
77
|
+
var AbortError = class extends Error {
|
|
78
|
+
constructor(message) {
|
|
79
|
+
super(message);
|
|
80
|
+
this.name = "AbortError";
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
75
84
|
// src/prompts/abstract.ts
|
|
76
|
-
var AbstractPrompt = class _AbstractPrompt {
|
|
85
|
+
var AbstractPrompt = class _AbstractPrompt extends EventEmitter {
|
|
77
86
|
stdin;
|
|
78
87
|
stdout;
|
|
79
88
|
message;
|
|
89
|
+
signal;
|
|
80
90
|
history;
|
|
81
91
|
agent;
|
|
82
92
|
mute;
|
|
83
93
|
rl;
|
|
84
|
-
|
|
94
|
+
#signalHandler;
|
|
95
|
+
constructor(options) {
|
|
96
|
+
super();
|
|
85
97
|
if (this.constructor === _AbstractPrompt) {
|
|
86
98
|
throw new Error("AbstractPrompt can't be instantiated.");
|
|
87
99
|
}
|
|
100
|
+
const {
|
|
101
|
+
stdin: input = process.stdin,
|
|
102
|
+
stdout: output = process.stdout,
|
|
103
|
+
message,
|
|
104
|
+
signal
|
|
105
|
+
} = options;
|
|
88
106
|
if (typeof message !== "string") {
|
|
89
107
|
throw new TypeError(`message must be string, ${typeof message} given.`);
|
|
90
108
|
}
|
|
109
|
+
if (!output.isTTY) {
|
|
110
|
+
Object.assign(output, {
|
|
111
|
+
moveCursor: () => void 0,
|
|
112
|
+
clearScreenDown: () => void 0
|
|
113
|
+
});
|
|
114
|
+
}
|
|
91
115
|
this.stdin = input;
|
|
92
116
|
this.stdout = output;
|
|
93
117
|
this.message = message;
|
|
118
|
+
this.signal = signal;
|
|
94
119
|
this.history = [];
|
|
95
120
|
this.agent = PromptAgent.agent();
|
|
96
121
|
this.mute = false;
|
|
@@ -101,7 +126,7 @@ var AbstractPrompt = class _AbstractPrompt {
|
|
|
101
126
|
input,
|
|
102
127
|
output: new Writable({
|
|
103
128
|
write: (chunk, encoding, callback) => {
|
|
104
|
-
if (!this.mute) {
|
|
129
|
+
if (!this.mute && chunk) {
|
|
105
130
|
this.stdout.write(chunk, encoding);
|
|
106
131
|
}
|
|
107
132
|
callback();
|
|
@@ -109,6 +134,16 @@ var AbstractPrompt = class _AbstractPrompt {
|
|
|
109
134
|
}),
|
|
110
135
|
terminal: true
|
|
111
136
|
});
|
|
137
|
+
if (this.signal) {
|
|
138
|
+
this.#signalHandler = () => {
|
|
139
|
+
this.rl.close();
|
|
140
|
+
for (let i = 0; i < this.history.length; i++) {
|
|
141
|
+
this.clearLastLine();
|
|
142
|
+
}
|
|
143
|
+
this.emit("error", new AbortError("Prompt aborted"));
|
|
144
|
+
};
|
|
145
|
+
this.signal.addEventListener("abort", this.#signalHandler, { once: true });
|
|
146
|
+
}
|
|
112
147
|
}
|
|
113
148
|
write(data) {
|
|
114
149
|
const formattedData = stripAnsi(data).replace(EOL, "");
|
|
@@ -128,6 +163,9 @@ var AbstractPrompt = class _AbstractPrompt {
|
|
|
128
163
|
}
|
|
129
164
|
destroy() {
|
|
130
165
|
this.rl.close();
|
|
166
|
+
if (this.signal) {
|
|
167
|
+
this.signal.removeEventListener("abort", this.#signalHandler);
|
|
168
|
+
}
|
|
131
169
|
}
|
|
132
170
|
};
|
|
133
171
|
|
|
@@ -175,15 +213,14 @@ var QuestionPrompt = class extends AbstractPrompt {
|
|
|
175
213
|
answerBuffer;
|
|
176
214
|
#validators;
|
|
177
215
|
#secure;
|
|
178
|
-
constructor(
|
|
216
|
+
constructor(options) {
|
|
179
217
|
const {
|
|
180
|
-
stdin = process.stdin,
|
|
181
|
-
stdout = process.stdout,
|
|
182
218
|
defaultValue,
|
|
183
219
|
validators = [],
|
|
184
|
-
secure = false
|
|
220
|
+
secure = false,
|
|
221
|
+
...baseOptions
|
|
185
222
|
} = options;
|
|
186
|
-
super(
|
|
223
|
+
super({ ...baseOptions });
|
|
187
224
|
if (defaultValue && typeof defaultValue !== "string") {
|
|
188
225
|
throw new TypeError("defaultValue must be a string");
|
|
189
226
|
}
|
|
@@ -196,6 +233,7 @@ var QuestionPrompt = class extends AbstractPrompt {
|
|
|
196
233
|
#question() {
|
|
197
234
|
return new Promise((resolve) => {
|
|
198
235
|
const questionQuery = this.#getQuestionQuery();
|
|
236
|
+
this.history.push(questionQuery);
|
|
199
237
|
this.rl.question(questionQuery, (answer) => {
|
|
200
238
|
this.history.push(questionQuery + answer);
|
|
201
239
|
this.mute = false;
|
|
@@ -233,24 +271,30 @@ var QuestionPrompt = class extends AbstractPrompt {
|
|
|
233
271
|
this.answerBuffer = void 0;
|
|
234
272
|
this.#writeAnswer();
|
|
235
273
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
this
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
this.
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
this.answer
|
|
274
|
+
question() {
|
|
275
|
+
return new Promise(async (resolve, reject) => {
|
|
276
|
+
this.answer = this.agent.nextAnswers.shift();
|
|
277
|
+
if (this.answer !== void 0) {
|
|
278
|
+
this.#writeAnswer();
|
|
279
|
+
this.destroy();
|
|
280
|
+
resolve(this.answer);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
this.once("error", (error) => {
|
|
284
|
+
reject(error);
|
|
285
|
+
});
|
|
286
|
+
this.answer = await this.#question();
|
|
287
|
+
if (this.answer === "" && this.defaultValue) {
|
|
288
|
+
this.answer = this.defaultValue;
|
|
289
|
+
}
|
|
250
290
|
this.#onQuestionAnswer();
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
291
|
+
while (this.answerBuffer !== void 0) {
|
|
292
|
+
this.answer = await this.answerBuffer;
|
|
293
|
+
this.#onQuestionAnswer();
|
|
294
|
+
}
|
|
295
|
+
this.destroy();
|
|
296
|
+
resolve(this.answer);
|
|
297
|
+
});
|
|
254
298
|
}
|
|
255
299
|
};
|
|
256
300
|
|
|
@@ -277,13 +321,12 @@ var ConfirmPrompt = class extends AbstractPrompt {
|
|
|
277
321
|
fastAnswer;
|
|
278
322
|
#boundKeyPressEvent;
|
|
279
323
|
#boundExitEvent;
|
|
280
|
-
constructor(
|
|
324
|
+
constructor(options) {
|
|
281
325
|
const {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
initial = false
|
|
326
|
+
initial = false,
|
|
327
|
+
...baseOptions
|
|
285
328
|
} = options;
|
|
286
|
-
super(
|
|
329
|
+
super({ ...baseOptions });
|
|
287
330
|
this.initial = initial;
|
|
288
331
|
this.selectedValue = initial;
|
|
289
332
|
}
|
|
@@ -347,25 +390,31 @@ var ConfirmPrompt = class extends AbstractPrompt {
|
|
|
347
390
|
this.stdout.clearScreenDown();
|
|
348
391
|
this.write(`${this.selectedValue ? SYMBOLS.Tick : SYMBOLS.Cross} ${kleur3.bold(this.message)}${EOL3}`);
|
|
349
392
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
393
|
+
confirm() {
|
|
394
|
+
return new Promise(async (resolve, reject) => {
|
|
395
|
+
const answer = this.agent.nextAnswers.shift();
|
|
396
|
+
if (answer !== void 0) {
|
|
397
|
+
this.selectedValue = answer;
|
|
398
|
+
this.#onQuestionAnswer();
|
|
399
|
+
this.destroy();
|
|
400
|
+
resolve(answer);
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
this.once("error", (error) => {
|
|
404
|
+
reject(error);
|
|
405
|
+
});
|
|
406
|
+
this.write(SYMBOLS.HideCursor);
|
|
407
|
+
try {
|
|
408
|
+
await this.#question();
|
|
409
|
+
this.#onQuestionAnswer();
|
|
410
|
+
resolve(this.selectedValue);
|
|
411
|
+
} finally {
|
|
412
|
+
this.write(SYMBOLS.ShowCursor);
|
|
413
|
+
this.#onProcessExit();
|
|
414
|
+
process.off("exit", this.#boundExitEvent);
|
|
415
|
+
this.destroy();
|
|
416
|
+
}
|
|
417
|
+
});
|
|
369
418
|
}
|
|
370
419
|
};
|
|
371
420
|
|
|
@@ -377,6 +426,7 @@ var kRequiredChoiceProperties = ["label", "value"];
|
|
|
377
426
|
var SelectPrompt = class extends AbstractPrompt {
|
|
378
427
|
#boundExitEvent = () => void 0;
|
|
379
428
|
#boundKeyPressEvent = () => void 0;
|
|
429
|
+
#validators;
|
|
380
430
|
activeIndex = 0;
|
|
381
431
|
questionMessage;
|
|
382
432
|
autocompleteValue = "";
|
|
@@ -414,22 +464,19 @@ var SelectPrompt = class extends AbstractPrompt {
|
|
|
414
464
|
return choice.label.length;
|
|
415
465
|
}));
|
|
416
466
|
}
|
|
417
|
-
constructor(
|
|
467
|
+
constructor(options) {
|
|
418
468
|
const {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
} = options
|
|
423
|
-
super(
|
|
424
|
-
if (!options) {
|
|
425
|
-
this.destroy();
|
|
426
|
-
throw new TypeError("Missing required options");
|
|
427
|
-
}
|
|
469
|
+
choices,
|
|
470
|
+
validators = [],
|
|
471
|
+
...baseOptions
|
|
472
|
+
} = options;
|
|
473
|
+
super({ ...baseOptions });
|
|
428
474
|
this.options = options;
|
|
429
475
|
if (!choices?.length) {
|
|
430
476
|
this.destroy();
|
|
431
477
|
throw new TypeError("Missing required param: choices");
|
|
432
478
|
}
|
|
479
|
+
this.#validators = validators;
|
|
433
480
|
for (const choice of choices) {
|
|
434
481
|
if (typeof choice === "string") {
|
|
435
482
|
continue;
|
|
@@ -509,6 +556,13 @@ var SelectPrompt = class extends AbstractPrompt {
|
|
|
509
556
|
const choice = this.filteredChoices[this.activeIndex] || "";
|
|
510
557
|
const label = typeof choice === "string" ? choice : choice.label;
|
|
511
558
|
const value = typeof choice === "string" ? choice : choice.value;
|
|
559
|
+
for (const validator of this.#validators) {
|
|
560
|
+
if (!validator.validate(value)) {
|
|
561
|
+
const error = validator.error(value);
|
|
562
|
+
render({ error });
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
512
566
|
render({ clearRender: true });
|
|
513
567
|
if (!this.options.ignoreValues?.includes(value)) {
|
|
514
568
|
this.#showAnsweredQuestion(label);
|
|
@@ -530,56 +584,71 @@ var SelectPrompt = class extends AbstractPrompt {
|
|
|
530
584
|
render();
|
|
531
585
|
}
|
|
532
586
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
}
|
|
553
|
-
if (
|
|
554
|
-
let
|
|
555
|
-
|
|
556
|
-
);
|
|
557
|
-
while (linesToClear2 > 0) {
|
|
587
|
+
select() {
|
|
588
|
+
return new Promise((resolve, reject) => {
|
|
589
|
+
const answer = this.agent.nextAnswers.shift();
|
|
590
|
+
if (answer !== void 0) {
|
|
591
|
+
this.#showAnsweredQuestion(answer);
|
|
592
|
+
this.destroy();
|
|
593
|
+
resolve(answer);
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
this.once("error", (error) => {
|
|
597
|
+
reject(error);
|
|
598
|
+
});
|
|
599
|
+
this.write(SYMBOLS.HideCursor);
|
|
600
|
+
this.#showQuestion();
|
|
601
|
+
const render = (options = {}) => {
|
|
602
|
+
const {
|
|
603
|
+
initialRender = false,
|
|
604
|
+
clearRender = false,
|
|
605
|
+
error = null
|
|
606
|
+
} = options;
|
|
607
|
+
if (!initialRender) {
|
|
608
|
+
let linesToClear = this.lastRender.endIndex - this.lastRender.startIndex;
|
|
609
|
+
while (linesToClear > 0) {
|
|
558
610
|
this.clearLastLine();
|
|
559
|
-
|
|
611
|
+
linesToClear--;
|
|
612
|
+
}
|
|
613
|
+
if (this.options.autocomplete) {
|
|
614
|
+
let linesToClear2 = Math.ceil(
|
|
615
|
+
wcwidth3(`${SYMBOLS.Pointer} ${this.autocompleteValue}`) / this.stdout.columns
|
|
616
|
+
);
|
|
617
|
+
while (linesToClear2 > 0) {
|
|
618
|
+
this.clearLastLine();
|
|
619
|
+
linesToClear2--;
|
|
620
|
+
}
|
|
560
621
|
}
|
|
561
622
|
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
623
|
+
if (clearRender) {
|
|
624
|
+
const questionLineCount = Math.ceil(
|
|
625
|
+
wcwidth3(stripAnsi(this.questionMessage)) / this.stdout.columns
|
|
626
|
+
);
|
|
627
|
+
this.stdout.moveCursor(-this.stdout.columns, -(1 + questionLineCount));
|
|
628
|
+
this.stdout.clearScreenDown();
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
if (error) {
|
|
632
|
+
const linesToClear = Math.ceil(wcwidth3(this.questionMessage) / this.stdout.columns) + 1;
|
|
633
|
+
this.stdout.moveCursor(0, -linesToClear);
|
|
634
|
+
this.stdout.clearScreenDown();
|
|
635
|
+
this.#showQuestion(error);
|
|
636
|
+
}
|
|
637
|
+
this.#showChoices();
|
|
638
|
+
};
|
|
639
|
+
render({ initialRender: true });
|
|
575
640
|
this.#boundKeyPressEvent = this.#onKeypress.bind(this, resolve, render);
|
|
576
641
|
this.stdin.on("keypress", this.#boundKeyPressEvent);
|
|
577
642
|
this.#boundExitEvent = this.#onProcessExit.bind(this);
|
|
578
643
|
process.once("exit", this.#boundExitEvent);
|
|
579
644
|
});
|
|
580
645
|
}
|
|
581
|
-
#showQuestion() {
|
|
582
|
-
|
|
646
|
+
#showQuestion(error = null) {
|
|
647
|
+
let hint = "";
|
|
648
|
+
if (error) {
|
|
649
|
+
hint = ` ${hint.length > 0 ? " " : ""}${kleur4.red().bold(`[${error}]`)}`;
|
|
650
|
+
}
|
|
651
|
+
this.questionMessage = `${SYMBOLS.QuestionMark} ${kleur4.bold(this.message)}${hint}`;
|
|
583
652
|
this.write(`${this.questionMessage}${EOL4}`);
|
|
584
653
|
}
|
|
585
654
|
};
|
|
@@ -595,7 +664,7 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
595
664
|
#validators;
|
|
596
665
|
#showHint;
|
|
597
666
|
activeIndex = 0;
|
|
598
|
-
selectedIndexes =
|
|
667
|
+
selectedIndexes = /* @__PURE__ */ new Set();
|
|
599
668
|
questionMessage;
|
|
600
669
|
autocompleteValue = "";
|
|
601
670
|
options;
|
|
@@ -632,20 +701,15 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
632
701
|
return choice.label.length;
|
|
633
702
|
}));
|
|
634
703
|
}
|
|
635
|
-
constructor(
|
|
704
|
+
constructor(options) {
|
|
636
705
|
const {
|
|
637
|
-
stdin = process.stdin,
|
|
638
|
-
stdout = process.stdout,
|
|
639
706
|
choices,
|
|
640
707
|
preSelectedChoices,
|
|
641
708
|
validators = [],
|
|
642
|
-
showHint = true
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
this.destroy();
|
|
647
|
-
throw new TypeError("Missing required options");
|
|
648
|
-
}
|
|
709
|
+
showHint = true,
|
|
710
|
+
...baseOptions
|
|
711
|
+
} = options;
|
|
712
|
+
super({ ...baseOptions });
|
|
649
713
|
this.options = options;
|
|
650
714
|
if (!choices?.length) {
|
|
651
715
|
this.destroy();
|
|
@@ -678,7 +742,7 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
678
742
|
this.destroy();
|
|
679
743
|
throw new Error(`Invalid pre-selected choice: ${typeof choice === "string" ? choice : choice.value}`);
|
|
680
744
|
}
|
|
681
|
-
this.selectedIndexes.
|
|
745
|
+
this.selectedIndexes.add(choiceIndex);
|
|
682
746
|
}
|
|
683
747
|
}
|
|
684
748
|
#getFormattedChoice(choiceIndex) {
|
|
@@ -706,7 +770,7 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
706
770
|
for (let choiceIndex = startIndex; choiceIndex < endIndex; choiceIndex++) {
|
|
707
771
|
const choice = this.#getFormattedChoice(choiceIndex);
|
|
708
772
|
const isChoiceActive = choiceIndex === this.activeIndex;
|
|
709
|
-
const isChoiceSelected = this.selectedIndexes.
|
|
773
|
+
const isChoiceSelected = this.selectedIndexes.has(choiceIndex);
|
|
710
774
|
const showPreviousChoicesArrow = startIndex > 0 && choiceIndex === startIndex;
|
|
711
775
|
const showNextChoicesArrow = endIndex < this.filteredChoices.length && choiceIndex === endIndex - 1;
|
|
712
776
|
let prefixArrow = " ";
|
|
@@ -726,7 +790,7 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
726
790
|
}
|
|
727
791
|
}
|
|
728
792
|
#showAnsweredQuestion(choices, isAgentAnswer = false) {
|
|
729
|
-
const prefixSymbol = this.selectedIndexes.
|
|
793
|
+
const prefixSymbol = this.selectedIndexes.size === 0 && !isAgentAnswer ? SYMBOLS.Cross : SYMBOLS.Tick;
|
|
730
794
|
const prefix = `${prefixSymbol} ${kleur5.bold(this.message)} ${SYMBOLS.Pointer}`;
|
|
731
795
|
const formattedChoice = kleur5.yellow(choices);
|
|
732
796
|
this.write(`${prefix}${choices ? ` ${formattedChoice}` : ""}${EOL5}`);
|
|
@@ -746,20 +810,20 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
746
810
|
this.activeIndex = this.activeIndex === this.filteredChoices.length - 1 ? 0 : this.activeIndex + 1;
|
|
747
811
|
render();
|
|
748
812
|
} else if (key.ctrl && key.name === "a") {
|
|
749
|
-
this.selectedIndexes = this.selectedIndexes.
|
|
813
|
+
this.selectedIndexes = this.selectedIndexes.size === this.filteredChoices.length ? /* @__PURE__ */ new Set() : new Set(this.filteredChoices.map((_, index) => index));
|
|
750
814
|
render();
|
|
751
815
|
} else if (key.name === "right") {
|
|
752
|
-
this.selectedIndexes.
|
|
816
|
+
this.selectedIndexes.add(this.activeIndex);
|
|
753
817
|
render();
|
|
754
818
|
} else if (key.name === "left") {
|
|
755
|
-
this.selectedIndexes = this.selectedIndexes.filter((index) => index !== this.activeIndex);
|
|
819
|
+
this.selectedIndexes = new Set([...this.selectedIndexes].filter((index) => index !== this.activeIndex));
|
|
756
820
|
render();
|
|
757
821
|
} else if (key.name === "return") {
|
|
758
|
-
const labels = this.selectedIndexes.map((index) => {
|
|
822
|
+
const labels = [...this.selectedIndexes].map((index) => {
|
|
759
823
|
const choice = this.filteredChoices[index];
|
|
760
824
|
return typeof choice === "string" ? choice : choice.label;
|
|
761
825
|
});
|
|
762
|
-
const values = this.selectedIndexes.map((index) => {
|
|
826
|
+
const values = [...this.selectedIndexes].map((index) => {
|
|
763
827
|
const choice = this.filteredChoices[index];
|
|
764
828
|
return typeof choice === "string" ? choice : choice.value;
|
|
765
829
|
});
|
|
@@ -779,7 +843,7 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
779
843
|
resolve(values);
|
|
780
844
|
} else {
|
|
781
845
|
if (!key.ctrl && this.options.autocomplete) {
|
|
782
|
-
this.selectedIndexes
|
|
846
|
+
this.selectedIndexes.clear();
|
|
783
847
|
this.activeIndex = 0;
|
|
784
848
|
if (key.name === "backspace" && this.autocompleteValue.length > 0) {
|
|
785
849
|
this.autocompleteValue = this.autocompleteValue.slice(0, -1);
|
|
@@ -790,56 +854,60 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
790
854
|
render();
|
|
791
855
|
}
|
|
792
856
|
}
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
wcwidth4(`${SYMBOLS.Pointer} ${this.autocompleteValue}`) / this.stdout.columns
|
|
818
|
-
);
|
|
819
|
-
while (linesToClear2 > 0) {
|
|
857
|
+
multiselect() {
|
|
858
|
+
return new Promise((resolve, reject) => {
|
|
859
|
+
const answer = this.agent.nextAnswers.shift();
|
|
860
|
+
if (answer !== void 0) {
|
|
861
|
+
const formatedAnser = Array.isArray(answer) ? answer.join(", ") : answer;
|
|
862
|
+
this.#showAnsweredQuestion(formatedAnser, true);
|
|
863
|
+
this.destroy();
|
|
864
|
+
resolve(Array.isArray(answer) ? answer : [answer]);
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
this.once("error", (error) => {
|
|
868
|
+
reject(error);
|
|
869
|
+
});
|
|
870
|
+
this.write(SYMBOLS.HideCursor);
|
|
871
|
+
this.#showQuestion();
|
|
872
|
+
const render = (options = {}) => {
|
|
873
|
+
const {
|
|
874
|
+
initialRender = false,
|
|
875
|
+
clearRender = false,
|
|
876
|
+
error = null
|
|
877
|
+
} = options;
|
|
878
|
+
if (!initialRender) {
|
|
879
|
+
let linesToClear = this.lastRender.endIndex - this.lastRender.startIndex;
|
|
880
|
+
while (linesToClear > 0) {
|
|
820
881
|
this.clearLastLine();
|
|
821
|
-
|
|
882
|
+
linesToClear--;
|
|
883
|
+
}
|
|
884
|
+
if (this.options.autocomplete) {
|
|
885
|
+
let linesToClear2 = Math.ceil(
|
|
886
|
+
wcwidth4(`${SYMBOLS.Pointer} ${this.autocompleteValue}`) / this.stdout.columns
|
|
887
|
+
);
|
|
888
|
+
while (linesToClear2 > 0) {
|
|
889
|
+
this.clearLastLine();
|
|
890
|
+
linesToClear2--;
|
|
891
|
+
}
|
|
822
892
|
}
|
|
823
893
|
}
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
render({ initialRender: true });
|
|
842
|
-
return new Promise((resolve) => {
|
|
894
|
+
if (clearRender) {
|
|
895
|
+
const questionLineCount = Math.ceil(
|
|
896
|
+
wcwidth4(stripAnsi(this.questionMessage)) / this.stdout.columns
|
|
897
|
+
);
|
|
898
|
+
this.stdout.moveCursor(-this.stdout.columns, -(1 + questionLineCount));
|
|
899
|
+
this.stdout.clearScreenDown();
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
if (error) {
|
|
903
|
+
const linesToClear = Math.ceil(wcwidth4(this.questionMessage) / this.stdout.columns) + 1;
|
|
904
|
+
this.stdout.moveCursor(0, -linesToClear);
|
|
905
|
+
this.stdout.clearScreenDown();
|
|
906
|
+
this.#showQuestion(error);
|
|
907
|
+
}
|
|
908
|
+
this.#showChoices();
|
|
909
|
+
};
|
|
910
|
+
render({ initialRender: true });
|
|
843
911
|
this.#boundKeyPressEvent = this.#onKeypress.bind(this, resolve, render);
|
|
844
912
|
this.stdin.on("keypress", this.#boundKeyPressEvent);
|
|
845
913
|
this.#boundExitEvent = this.#onProcessExit.bind(this);
|
|
@@ -869,19 +937,18 @@ function required() {
|
|
|
869
937
|
|
|
870
938
|
// index.ts
|
|
871
939
|
async function question(message, options = {}) {
|
|
872
|
-
|
|
873
|
-
return questionPrompt.question();
|
|
940
|
+
return new QuestionPrompt({ ...options, message }).question();
|
|
874
941
|
}
|
|
875
942
|
async function select(message, options) {
|
|
876
|
-
const selectPrompt = new SelectPrompt(
|
|
943
|
+
const selectPrompt = new SelectPrompt({ ...options, message });
|
|
877
944
|
return selectPrompt.select();
|
|
878
945
|
}
|
|
879
946
|
async function confirm(message, options) {
|
|
880
|
-
const confirmPrompt = new ConfirmPrompt(
|
|
947
|
+
const confirmPrompt = new ConfirmPrompt({ ...options, message });
|
|
881
948
|
return confirmPrompt.confirm();
|
|
882
949
|
}
|
|
883
950
|
async function multiselect(message, options) {
|
|
884
|
-
const multiselectPrompt = new MultiselectPrompt(
|
|
951
|
+
const multiselectPrompt = new MultiselectPrompt({ ...options, message });
|
|
885
952
|
return multiselectPrompt.multiselect();
|
|
886
953
|
}
|
|
887
954
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topcli/prompts",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
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",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@nodesecure/eslint-config": "^1.9.0",
|
|
35
35
|
"@types/node": "^20.11.6",
|
|
36
36
|
"c8": "^9.1.0",
|
|
37
|
-
"eslint": "^
|
|
37
|
+
"eslint": "^9.2.0",
|
|
38
38
|
"esmock": "^2.6.3",
|
|
39
39
|
"glob": "^10.3.10",
|
|
40
40
|
"tsup": "^8.0.1",
|