@topcli/prompts 2.1.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/LICENSE +13 -13
- package/README.md +274 -274
- package/dist/index.cjs +74 -75
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +44 -45
- package/package.json +50 -54
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
|
-
import
|
|
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");
|
|
@@ -125,7 +104,7 @@ var AbstractPrompt = class _AbstractPrompt extends EventEmitter {
|
|
|
125
104
|
if (this.stdout.isTTY) {
|
|
126
105
|
this.stdin.setRawMode(true);
|
|
127
106
|
}
|
|
128
|
-
this.rl = createInterface({
|
|
107
|
+
this.rl = readline.createInterface({
|
|
129
108
|
input,
|
|
130
109
|
output: new Writable({
|
|
131
110
|
write: (chunk, encoding, callback) => {
|
|
@@ -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);
|
|
@@ -987,18 +986,18 @@ var MultiselectPrompt = class extends AbstractPrompt {
|
|
|
987
986
|
};
|
|
988
987
|
|
|
989
988
|
// index.ts
|
|
990
|
-
|
|
989
|
+
function question(message, options = {}) {
|
|
991
990
|
return new QuestionPrompt({ ...options, message }).question();
|
|
992
991
|
}
|
|
993
|
-
|
|
992
|
+
function select(message, options) {
|
|
994
993
|
const selectPrompt = new SelectPrompt({ ...options, message });
|
|
995
994
|
return selectPrompt.select();
|
|
996
995
|
}
|
|
997
|
-
|
|
996
|
+
function confirm(message, options = {}) {
|
|
998
997
|
const confirmPrompt = new ConfirmPrompt({ ...options, message });
|
|
999
998
|
return confirmPrompt.confirm();
|
|
1000
999
|
}
|
|
1001
|
-
|
|
1000
|
+
function multiselect(message, options) {
|
|
1002
1001
|
const multiselectPrompt = new MultiselectPrompt({ ...options, message });
|
|
1003
1002
|
return multiselectPrompt.multiselect();
|
|
1004
1003
|
}
|
package/package.json
CHANGED
|
@@ -1,54 +1,50 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@topcli/prompts",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Node.js user input library for command-line interfaces.",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"build": "tsup index.ts --format cjs,esm --dts --clean",
|
|
7
|
-
"prepublishOnly": "npm run build",
|
|
8
|
-
"test": "glob -c \"tsx --
|
|
9
|
-
"coverage": "c8 -r html npm run test",
|
|
10
|
-
"lint": "eslint src test",
|
|
11
|
-
"lint:fix": "eslint . --fix"
|
|
12
|
-
},
|
|
13
|
-
"main": "./dist/index.js",
|
|
14
|
-
"types": "./dist/index.d.ts",
|
|
15
|
-
"exports": {
|
|
16
|
-
".": {
|
|
17
|
-
"types": "./dist/index.d.ts",
|
|
18
|
-
"require": "./dist/index.cjs",
|
|
19
|
-
"import": "./dist/index.js"
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"keywords": [
|
|
23
|
-
"node.js",
|
|
24
|
-
"cli",
|
|
25
|
-
"prompt"
|
|
26
|
-
],
|
|
27
|
-
"files": [
|
|
28
|
-
"dist"
|
|
29
|
-
],
|
|
30
|
-
"author": "PierreDemailly <pierredemailly.pro@gmail.com>",
|
|
31
|
-
"license": "ISC",
|
|
32
|
-
"type": "module",
|
|
33
|
-
"devDependencies": {
|
|
34
|
-
"@openally/config.eslint": "^
|
|
35
|
-
"@openally/config.typescript": "^1.0.3",
|
|
36
|
-
"@types/node": "^
|
|
37
|
-
"c8": "^10.1.3",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"url": "https://github.com/TopCli/prompts/issues"
|
|
52
|
-
},
|
|
53
|
-
"homepage": "https://github.com/TopCli/prompts#readme"
|
|
54
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@topcli/prompts",
|
|
3
|
+
"version": "2.3.0",
|
|
4
|
+
"description": "Node.js user input library for command-line interfaces.",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "tsup index.ts --format cjs,esm --dts --clean",
|
|
7
|
+
"prepublishOnly": "npm run build",
|
|
8
|
+
"test": "glob -c \"tsx --test\" \"./test/**/*.test.ts\"",
|
|
9
|
+
"coverage": "c8 -r html npm run test",
|
|
10
|
+
"lint": "eslint src test",
|
|
11
|
+
"lint:fix": "eslint . --fix"
|
|
12
|
+
},
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"require": "./dist/index.cjs",
|
|
19
|
+
"import": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"node.js",
|
|
24
|
+
"cli",
|
|
25
|
+
"prompt"
|
|
26
|
+
],
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"author": "PierreDemailly <pierredemailly.pro@gmail.com>",
|
|
31
|
+
"license": "ISC",
|
|
32
|
+
"type": "module",
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@openally/config.eslint": "^2.0.0",
|
|
35
|
+
"@openally/config.typescript": "^1.0.3",
|
|
36
|
+
"@types/node": "^24.0.3",
|
|
37
|
+
"c8": "^10.1.3",
|
|
38
|
+
"glob": "^11.0.0",
|
|
39
|
+
"tsup": "^8.3.5",
|
|
40
|
+
"tsx": "^4.19.2",
|
|
41
|
+
"typescript": "^5.7.2"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": "^20.12.0 || >=21.7.0"
|
|
45
|
+
},
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/TopCli/prompts/issues"
|
|
48
|
+
},
|
|
49
|
+
"homepage": "https://github.com/TopCli/prompts#readme"
|
|
50
|
+
}
|