@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/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 { createInterface } from "node:readline";
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 = stripAnsi(data).replace(EOL, "");
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(stripAnsi(lastLine).length / this.stdout.columns);
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
- wcwidth(stripAnsi(this.#getQuestionQuery() + this.answer)) / this.stdout.columns
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(wcwidth2(stripAnsi(this.#getQuestionQuery())) / this.stdout.columns)
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(wcwidth2(stripAnsi(this.#getQuestionQuery())) / this.stdout.columns)
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(choice) {
575
- const symbolPrefix = choice === "" ? SYMBOLS.Cross : SYMBOLS.Tick;
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", typeof choice === "string" ? choice : choice.label);
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
- wcwidth3(`${SYMBOLS.Pointer} ${this.autocompleteValue}`) / this.stdout.columns
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
- wcwidth3(stripAnsi(this.questionMessage)) / this.stdout.columns
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(wcwidth3(this.questionMessage) / this.stdout.columns) + 1;
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
- wcwidth4(`${SYMBOLS.Pointer} ${this.autocompleteValue}`) / this.stdout.columns
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
- wcwidth4(stripAnsi(this.questionMessage)) / this.stdout.columns
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(wcwidth4(this.questionMessage) / this.stdout.columns) + 1;
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
- async function question(message, options = {}) {
989
+ function question(message, options = {}) {
991
990
  return new QuestionPrompt({ ...options, message }).question();
992
991
  }
993
- async function select(message, options) {
992
+ function select(message, options) {
994
993
  const selectPrompt = new SelectPrompt({ ...options, message });
995
994
  return selectPrompt.select();
996
995
  }
997
- async function confirm(message, options = {}) {
996
+ function confirm(message, options = {}) {
998
997
  const confirmPrompt = new ConfirmPrompt({ ...options, message });
999
998
  return confirmPrompt.confirm();
1000
999
  }
1001
- async function multiselect(message, options) {
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.1.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 --no-warnings=ExperimentalWarning --loader=esmock --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": "^1.3.0",
35
- "@openally/config.typescript": "^1.0.3",
36
- "@types/node": "^22.10.5",
37
- "c8": "^10.1.3",
38
- "esmock": "^2.6.9",
39
- "glob": "^11.0.0",
40
- "tsup": "^8.3.5",
41
- "tsx": "^4.19.2",
42
- "typescript": "^5.7.2"
43
- },
44
- "dependencies": {
45
- "@topcli/wcwidth": "^1.0.1"
46
- },
47
- "engines": {
48
- "node": "^20.12.0 || >=21.7.0"
49
- },
50
- "bugs": {
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
+ }