@reliverse/relinka 1.1.10 → 1.2.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.
Files changed (224) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -42
  3. package/dist-npm/components/core/core.d.ts +2 -0
  4. package/dist-npm/components/core/core.js +2 -0
  5. package/dist-npm/{utils/constants.d.ts → components/levels/levels.d.ts} +1 -1
  6. package/dist-npm/components/{prompts/create.d.ts → modes/basic.d.ts} +3 -3
  7. package/dist-npm/components/{instance → modes}/basic.js +4 -4
  8. package/dist-npm/components/{instance → modes}/browser.d.ts +2 -2
  9. package/dist-npm/components/modes/browser.js +12 -0
  10. package/dist-npm/components/modes/shared.d.ts +5 -0
  11. package/dist-npm/components/modes/shared.js +2 -0
  12. package/dist-npm/components/{prompts → relinka}/relinka.d.ts +2 -4
  13. package/dist-npm/components/{prompts → relinka}/relinka.js +1 -7
  14. package/dist-npm/components/{instance/reporter → reporters}/basic.d.ts +1 -1
  15. package/dist-npm/components/{instance/reporter → reporters}/basic.js +2 -2
  16. package/dist-npm/components/{instance/reporter → reporters}/browser.d.ts +1 -1
  17. package/dist-npm/components/{instance/reporter → reporters}/fancy.d.ts +3 -3
  18. package/dist-npm/components/{instance/reporter → reporters}/fancy.js +5 -7
  19. package/dist-npm/main.d.ts +8 -1
  20. package/dist-npm/main.js +34 -1
  21. package/dist-npm/types/mod.d.ts +42 -0
  22. package/dist-npm/utils/color.js +4 -1
  23. package/dist-npm/utils/mod.d.ts +3 -0
  24. package/dist-npm/utils/mod.js +9 -0
  25. package/package.json +3 -2
  26. package/dist-npm/components/anykey/index.d.ts +0 -7
  27. package/dist-npm/components/anykey/index.js +0 -61
  28. package/dist-npm/components/block/block.d.ts +0 -10
  29. package/dist-npm/components/block/block.js +0 -52
  30. package/dist-npm/components/checkbox/index.d.ts +0 -3
  31. package/dist-npm/components/checkbox/index.js +0 -217
  32. package/dist-npm/components/confirm/confirm-main.d.ts +0 -3
  33. package/dist-npm/components/confirm/confirm-main.js +0 -98
  34. package/dist-npm/components/confirm/confirm-three.d.ts +0 -13
  35. package/dist-npm/components/confirm/confirm-three.js +0 -26
  36. package/dist-npm/components/confirm/index.d.ts +0 -2
  37. package/dist-npm/components/confirm/index.js +0 -41
  38. package/dist-npm/components/core/Separator.d.ts +0 -6
  39. package/dist-npm/components/core/Separator.js +0 -18
  40. package/dist-npm/components/core/create-prompt.d.ts +0 -4
  41. package/dist-npm/components/core/create-prompt.js +0 -107
  42. package/dist-npm/components/core/errors.d.ts +0 -20
  43. package/dist-npm/components/core/errors.js +0 -21
  44. package/dist-npm/components/core/hook-engine.d.ts +0 -23
  45. package/dist-npm/components/core/hook-engine.js +0 -109
  46. package/dist-npm/components/core/index.d.ts +0 -13
  47. package/dist-npm/components/core/index.js +0 -12
  48. package/dist-npm/components/core/key.d.ts +0 -10
  49. package/dist-npm/components/core/key.js +0 -16
  50. package/dist-npm/components/core/lines.d.ts +0 -14
  51. package/dist-npm/components/core/lines.js +0 -52
  52. package/dist-npm/components/core/make-theme.d.ts +0 -3
  53. package/dist-npm/components/core/make-theme.js +0 -28
  54. package/dist-npm/components/core/position.d.ts +0 -12
  55. package/dist-npm/components/core/position.js +0 -29
  56. package/dist-npm/components/core/promise-polyfill.d.ts +0 -7
  57. package/dist-npm/components/core/promise-polyfill.js +0 -13
  58. package/dist-npm/components/core/screen-manager.d.ts +0 -14
  59. package/dist-npm/components/core/screen-manager.js +0 -67
  60. package/dist-npm/components/core/theme.d.ts +0 -21
  61. package/dist-npm/components/core/theme.js +0 -24
  62. package/dist-npm/components/core/use-effect.d.ts +0 -2
  63. package/dist-npm/components/core/use-effect.js +0 -11
  64. package/dist-npm/components/core/use-keypress.d.ts +0 -3
  65. package/dist-npm/components/core/use-keypress.js +0 -21
  66. package/dist-npm/components/core/use-memo.d.ts +0 -1
  67. package/dist-npm/components/core/use-memo.js +0 -12
  68. package/dist-npm/components/core/use-pagination.d.ts +0 -11
  69. package/dist-npm/components/core/use-pagination.js +0 -34
  70. package/dist-npm/components/core/use-prefix.d.ts +0 -5
  71. package/dist-npm/components/core/use-prefix.js +0 -42
  72. package/dist-npm/components/core/use-ref.d.ts +0 -6
  73. package/dist-npm/components/core/use-ref.js +0 -4
  74. package/dist-npm/components/core/use-state.d.ts +0 -4
  75. package/dist-npm/components/core/use-state.js +0 -17
  76. package/dist-npm/components/core/useKeyPress.d.ts +0 -4
  77. package/dist-npm/components/core/useKeyPress.js +0 -16
  78. package/dist-npm/components/core/usePromptState.d.ts +0 -6
  79. package/dist-npm/components/core/usePromptState.js +0 -10
  80. package/dist-npm/components/core/utils.d.ts +0 -2
  81. package/dist-npm/components/core/utils.js +0 -11
  82. package/dist-npm/components/date/date.d.ts +0 -6
  83. package/dist-npm/components/date/date.js +0 -210
  84. package/dist-npm/components/editor/index.d.ts +0 -2
  85. package/dist-npm/components/editor/index.js +0 -78
  86. package/dist-npm/components/expand/index.d.ts +0 -3
  87. package/dist-npm/components/expand/index.js +0 -119
  88. package/dist-npm/components/figures/index.d.ts +0 -465
  89. package/dist-npm/components/figures/index.js +0 -299
  90. package/dist-npm/components/input/index.d.ts +0 -2
  91. package/dist-npm/components/input/index.js +0 -66
  92. package/dist-npm/components/input/text-main.d.ts +0 -3
  93. package/dist-npm/components/input/text-main.js +0 -103
  94. package/dist-npm/components/input/text.d.ts +0 -11
  95. package/dist-npm/components/input/text.js +0 -26
  96. package/dist-npm/components/instance/basic.d.ts +0 -8
  97. package/dist-npm/components/instance/browser.js +0 -18
  98. package/dist-npm/components/instance/shared.d.ts +0 -6
  99. package/dist-npm/components/instance/shared.js +0 -2
  100. package/dist-npm/components/mono/mono.d.ts +0 -5
  101. package/dist-npm/components/mono/mono.js +0 -64
  102. package/dist-npm/components/mono/monoTwo.d.ts +0 -30
  103. package/dist-npm/components/mono/monoTwo.js +0 -37
  104. package/dist-npm/components/multiselect/group-multiselect.d.ts +0 -23
  105. package/dist-npm/components/multiselect/group-multiselect.js +0 -58
  106. package/dist-npm/components/multiselect/multi-select-two.d.ts +0 -3
  107. package/dist-npm/components/multiselect/multi-select-two.js +0 -111
  108. package/dist-npm/components/multiselect/multi-select.d.ts +0 -21
  109. package/dist-npm/components/multiselect/multi-select.js +0 -45
  110. package/dist-npm/components/multiselect/multiselect-main.d.ts +0 -18
  111. package/dist-npm/components/multiselect/multiselect-main.js +0 -166
  112. package/dist-npm/components/multiselect/num-multi-select.d.ts +0 -3
  113. package/dist-npm/components/multiselect/num-multi-select.js +0 -111
  114. package/dist-npm/components/multiselect/num-multiselect-main.d.ts +0 -6
  115. package/dist-npm/components/multiselect/num-multiselect-main.js +0 -28
  116. package/dist-npm/components/next-steps/next-steps.d.ts +0 -2
  117. package/dist-npm/components/next-steps/next-steps.js +0 -24
  118. package/dist-npm/components/number/index.d.ts +0 -2
  119. package/dist-npm/components/number/index.js +0 -100
  120. package/dist-npm/components/number/number-main.d.ts +0 -3
  121. package/dist-npm/components/number/number-main.js +0 -95
  122. package/dist-npm/components/password/index.d.ts +0 -2
  123. package/dist-npm/components/password/index.js +0 -59
  124. package/dist-npm/components/password/password-main.d.ts +0 -3
  125. package/dist-npm/components/password/password-main.js +0 -119
  126. package/dist-npm/components/password/password-three.d.ts +0 -13
  127. package/dist-npm/components/password/password-three.js +0 -28
  128. package/dist-npm/components/progressbar/ProgressBar.d.ts +0 -22
  129. package/dist-npm/components/progressbar/ProgressBar.js +0 -53
  130. package/dist-npm/components/progressbar/helper.d.ts +0 -6
  131. package/dist-npm/components/progressbar/helper.js +0 -38
  132. package/dist-npm/components/progressbar/index.d.ts +0 -2
  133. package/dist-npm/components/progressbar/index.js +0 -1
  134. package/dist-npm/components/prompts/create.js +0 -35
  135. package/dist-npm/components/prompts/index.d.ts +0 -49
  136. package/dist-npm/components/prompts/index.js +0 -46
  137. package/dist-npm/components/prompts/prompt.d.ts +0 -36
  138. package/dist-npm/components/prompts/prompt.js +0 -232
  139. package/dist-npm/components/prompts/promptTwo.d.ts +0 -92
  140. package/dist-npm/components/prompts/promptTwo.js +0 -653
  141. package/dist-npm/components/range/range.d.ts +0 -62
  142. package/dist-npm/components/range/range.js +0 -270
  143. package/dist-npm/components/rawlist/index.d.ts +0 -3
  144. package/dist-npm/components/rawlist/index.js +0 -104
  145. package/dist-npm/components/results/results.d.ts +0 -10
  146. package/dist-npm/components/results/results.js +0 -34
  147. package/dist-npm/components/search/index.d.ts +0 -3
  148. package/dist-npm/components/search/index.js +0 -186
  149. package/dist-npm/components/select/index.d.ts +0 -3
  150. package/dist-npm/components/select/index.js +0 -176
  151. package/dist-npm/components/select/num-select-main.d.ts +0 -8
  152. package/dist-npm/components/select/num-select-main.js +0 -30
  153. package/dist-npm/components/select/num-select.d.ts +0 -5
  154. package/dist-npm/components/select/num-select.js +0 -125
  155. package/dist-npm/components/select/select-key.d.ts +0 -15
  156. package/dist-npm/components/select/select-key.js +0 -26
  157. package/dist-npm/components/select/select-main.d.ts +0 -19
  158. package/dist-npm/components/select/select-main.js +0 -151
  159. package/dist-npm/components/select/select-three.d.ts +0 -18
  160. package/dist-npm/components/select/select-three.js +0 -35
  161. package/dist-npm/components/select/select-two.d.ts +0 -2
  162. package/dist-npm/components/select/select-two.js +0 -98
  163. package/dist-npm/components/spinner/index.d.ts +0 -15
  164. package/dist-npm/components/spinner/index.js +0 -110
  165. package/dist-npm/components/st-end/end.d.ts +0 -2
  166. package/dist-npm/components/st-end/end.js +0 -35
  167. package/dist-npm/components/st-end/start.d.ts +0 -2
  168. package/dist-npm/components/st-end/start.js +0 -32
  169. package/dist-npm/components/toggle/index.d.ts +0 -13
  170. package/dist-npm/components/toggle/index.js +0 -121
  171. package/dist-npm/components/visual/animate/animate.d.ts +0 -13
  172. package/dist-npm/components/visual/animate/animate.js +0 -55
  173. package/dist-npm/components/visual/ascii-art/ascii-art.d.ts +0 -6
  174. package/dist-npm/components/visual/ascii-art/ascii-art.js +0 -12
  175. package/dist-npm/testing/index.d.ts +0 -18
  176. package/dist-npm/testing/index.js +0 -64
  177. package/dist-npm/types/general.d.ts +0 -134
  178. package/dist-npm/types/index.d.ts +0 -2
  179. package/dist-npm/types/index.js +0 -2
  180. package/dist-npm/types/keypress.d.ts +0 -52
  181. package/dist-npm/types/keypress.js +0 -37
  182. package/dist-npm/types/readline.d.ts +0 -30
  183. package/dist-npm/types/readline.js +0 -0
  184. package/dist-npm/types/relinka.d.ts +0 -30
  185. package/dist-npm/types/relinka.js +0 -0
  186. package/dist-npm/types/utils.d.ts +0 -17
  187. package/dist-npm/types/utils.js +0 -0
  188. package/dist-npm/utils/colorize.d.ts +0 -2
  189. package/dist-npm/utils/colorize.js +0 -130
  190. package/dist-npm/utils/component.d.ts +0 -101
  191. package/dist-npm/utils/component.js +0 -630
  192. package/dist-npm/utils/core.d.ts +0 -2
  193. package/dist-npm/utils/core.js +0 -2
  194. package/dist-npm/utils/decoder.d.ts +0 -14
  195. package/dist-npm/utils/decoder.js +0 -281
  196. package/dist-npm/utils/errors.d.ts +0 -1
  197. package/dist-npm/utils/errors.js +0 -15
  198. package/dist-npm/utils/keypress.d.ts +0 -7
  199. package/dist-npm/utils/keypress.js +0 -327
  200. package/dist-npm/utils/mapping.d.ts +0 -4
  201. package/dist-npm/utils/mapping.js +0 -49
  202. package/dist-npm/utils/messages.d.ts +0 -17
  203. package/dist-npm/utils/messages.js +0 -213
  204. package/dist-npm/utils/platforms.d.ts +0 -1
  205. package/dist-npm/utils/platforms.js +0 -22
  206. package/dist-npm/utils/prompt-tmp.d.ts +0 -13
  207. package/dist-npm/utils/prompt-tmp.js +0 -254
  208. package/dist-npm/utils/prompt-two.d.ts +0 -13
  209. package/dist-npm/utils/prompt-two.js +0 -254
  210. package/dist-npm/utils/readline.d.ts +0 -2
  211. package/dist-npm/utils/readline.js +0 -9
  212. package/dist-npm/utils/skeleton.d.ts +0 -7
  213. package/dist-npm/utils/skeleton.js +0 -145
  214. package/dist-npm/utils/terminal.d.ts +0 -5
  215. package/dist-npm/utils/terminal.js +0 -33
  216. package/dist-npm/utils/types.d.ts +0 -0
  217. package/dist-npm/utils/types.js +0 -0
  218. package/dist-npm/utils/utils.d.ts +0 -3
  219. package/dist-npm/utils/utils.js +0 -9
  220. package/dist-npm/utils/variants.d.ts +0 -9
  221. package/dist-npm/utils/variants.js +0 -49
  222. /package/dist-npm/{utils/constants.js → components/levels/levels.js} +0 -0
  223. /package/dist-npm/components/{instance/reporter → reporters}/browser.js +0 -0
  224. /package/dist-npm/types/{general.js → mod.js} +0 -0
@@ -1,37 +0,0 @@
1
- import { text, confirm, select, multiselect } from "../prompts/promptTwo.js";
2
- export async function prompt(message, opts = {}) {
3
- if (!opts.type || opts.type === "text") {
4
- return await text({
5
- message,
6
- defaultValue: opts.default,
7
- placeholder: opts.placeholder,
8
- initialValue: opts.initial
9
- });
10
- }
11
- if (opts.type === "confirm") {
12
- return await confirm({
13
- message,
14
- initialValue: opts.initial
15
- });
16
- }
17
- if (opts.type === "select") {
18
- return await select({
19
- message,
20
- options: opts.options.map(
21
- (o) => typeof o === "string" ? { value: o, label: o } : o
22
- ),
23
- initialValue: opts.initial
24
- });
25
- }
26
- if (opts.type === "multiselect") {
27
- return await multiselect({
28
- message,
29
- options: opts.options.map(
30
- (o) => typeof o === "string" ? { value: o, label: o } : o
31
- ),
32
- required: opts.required,
33
- initialValues: opts.initial
34
- });
35
- }
36
- throw new Error(`Unknown prompt type: ${opts.type}`);
37
- }
@@ -1,23 +0,0 @@
1
- import type { PromptOptions } from "../prompts/prompt.js";
2
- import Prompt from "../prompts/prompt.js";
3
- type GroupMultiSelectOptions<T extends {
4
- value: any;
5
- }> = {
6
- options: Record<string, T[]>;
7
- initialValues?: T["value"][];
8
- required?: boolean;
9
- cursorAt?: T["value"];
10
- } & PromptOptions<GroupMultiSelectPrompt<T>>;
11
- export default class GroupMultiSelectPrompt<T extends {
12
- value: any;
13
- }> extends Prompt {
14
- options: (T & {
15
- group: string | boolean;
16
- })[];
17
- cursor: number;
18
- getGroupItems(group: string): T[];
19
- isGroupSelected(group: string): boolean;
20
- private toggleValue;
21
- constructor(opts: GroupMultiSelectOptions<T>);
22
- }
23
- export {};
@@ -1,58 +0,0 @@
1
- import Prompt from "../prompts/prompt.js";
2
- export default class GroupMultiSelectPrompt extends Prompt {
3
- options;
4
- cursor = 0;
5
- getGroupItems(group) {
6
- return this.options.filter((o) => o.group === group);
7
- }
8
- isGroupSelected(group) {
9
- const items = this.getGroupItems(group);
10
- return items.every((i) => this.value.includes(i.value));
11
- }
12
- toggleValue() {
13
- const item = this.options[this.cursor];
14
- if (item.group === true) {
15
- const group = item.value;
16
- const groupedItems = this.getGroupItems(group);
17
- if (this.isGroupSelected(group)) {
18
- this.value = this.value.filter(
19
- (v) => groupedItems.findIndex((i) => i.value === v) === -1
20
- );
21
- } else {
22
- this.value = [...this.value, ...groupedItems.map((i) => i.value)];
23
- }
24
- this.value = Array.from(new Set(this.value));
25
- } else {
26
- const selected = this.value.includes(item.value);
27
- this.value = selected ? this.value.filter((v) => v !== item.value) : [...this.value, item.value];
28
- }
29
- }
30
- constructor(opts) {
31
- super(opts, false);
32
- const { options } = opts;
33
- this.options = Object.entries(options).flatMap(([key, option]) => [
34
- { value: key, group: true, label: key },
35
- ...option.map((opt) => ({ ...opt, group: key }))
36
- ]);
37
- this.value = [...opts.initialValues ?? []];
38
- this.cursor = Math.max(
39
- this.options.findIndex(({ value }) => value === opts.cursorAt),
40
- 0
41
- );
42
- this.on("cursor", (key) => {
43
- switch (key) {
44
- case "left":
45
- case "up":
46
- this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
47
- break;
48
- case "down":
49
- case "right":
50
- this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
51
- break;
52
- case "space":
53
- this.toggleValue();
54
- break;
55
- }
56
- });
57
- }
58
- }
@@ -1,3 +0,0 @@
1
- import type { Static, TSchema } from "@sinclair/typebox";
2
- import type { PromptOptions } from "../../types/general.js";
3
- export declare function multiselectPrompt<T extends TSchema>(options: PromptOptions<T>): Promise<Static<T>>;
@@ -1,111 +0,0 @@
1
- import { Value } from "@sinclair/typebox/value";
2
- import { stdin as input, stdout as output } from "node:process";
3
- import readline from "node:readline/promises";
4
- import { colorize } from "../../utils/colorize.js";
5
- import { bar, fmt, msg } from "../../utils/messages.js";
6
- import {
7
- countLines,
8
- deleteLastLine,
9
- deleteLastLines
10
- } from "../../utils/terminal.js";
11
- export async function multiselectPrompt(options) {
12
- const {
13
- title,
14
- choices,
15
- schema,
16
- defaultValue,
17
- titleColor = "cyanBright",
18
- titleTypography = "bold",
19
- titleVariant,
20
- hint,
21
- content,
22
- contentColor = "dim",
23
- contentTypography,
24
- contentVariant,
25
- borderColor = "viceGradient",
26
- variantOptions
27
- } = options;
28
- if (!choices || choices.length === 0) {
29
- throw new Error("Choices are required for multiselect prompt.");
30
- }
31
- const rl = readline.createInterface({ input, output });
32
- const formattedBar = bar({ borderColor });
33
- let linesToDelete = 0;
34
- let errorMessage = "";
35
- try {
36
- while (true) {
37
- if (linesToDelete > 0) {
38
- deleteLastLines(linesToDelete);
39
- }
40
- const question = fmt({
41
- type: errorMessage !== "" ? "M_ERROR" : "M_GENERAL",
42
- title: `${title}${defaultValue ? ` [Default: ${Array.isArray(defaultValue) ? defaultValue.join(", ") : defaultValue}]` : ""}`,
43
- titleColor,
44
- titleTypography,
45
- titleVariant,
46
- content,
47
- contentColor,
48
- contentTypography,
49
- contentVariant,
50
- borderColor,
51
- hint,
52
- variantOptions,
53
- errorMessage,
54
- addNewLineBefore: false,
55
- addNewLineAfter: false
56
- });
57
- const choicesText = choices.map(
58
- (choice, index) => `${formattedBar} ${index + 1}) ${choice.title}${choice.description ? ` - ${choice.description}` : ""}`
59
- ).join("\n");
60
- const fullPrompt = `${question}
61
- ${choicesText}
62
- ${formattedBar} ${colorize(`Enter your choices (comma-separated numbers between 1-${choices.length})`, contentColor)}:
63
- ${formattedBar} `;
64
- const formattedPrompt = fmt({
65
- type: "M_NULL",
66
- title: fullPrompt
67
- });
68
- const questionLines = countLines(formattedPrompt);
69
- linesToDelete = questionLines + 1;
70
- const answer = (await rl.question(formattedPrompt)).trim();
71
- if (!answer && defaultValue !== void 0) {
72
- deleteLastLine();
73
- msg({
74
- type: "M_MIDDLE",
75
- title: ` ${Array.isArray(defaultValue) ? defaultValue.join(", ") : defaultValue}`,
76
- titleColor: "none"
77
- });
78
- msg({ type: "M_NEWLINE" });
79
- return defaultValue;
80
- }
81
- const selections = answer.split(",").map((s) => s.trim());
82
- const invalidSelections = selections.filter((s) => {
83
- const num = Number(s);
84
- return isNaN(num) || num < 1 || num > choices.length;
85
- });
86
- if (invalidSelections.length > 0) {
87
- errorMessage = `Invalid selections: ${invalidSelections.join(
88
- ", "
89
- )}. Please enter numbers between 1 and ${choices.length}.`;
90
- continue;
91
- }
92
- const selectedValues = selections.map((s) => choices[Number(s) - 1]?.id);
93
- let isValid = true;
94
- errorMessage = "";
95
- if (schema) {
96
- isValid = Value.Check(schema, selectedValues);
97
- if (!isValid) {
98
- const errors = [...Value.Errors(schema, selectedValues)];
99
- errorMessage = errors.length > 0 ? errors[0]?.message ?? "Invalid input." : "Invalid input.";
100
- }
101
- }
102
- if (isValid) {
103
- msg({ type: "M_NEWLINE" });
104
- rl.close();
105
- return selectedValues;
106
- }
107
- }
108
- } finally {
109
- rl.close();
110
- }
111
- }
@@ -1,21 +0,0 @@
1
- import type { PromptOptions } from "../../components/prompts/prompt.js";
2
- import Prompt from "../../components/prompts/prompt.js";
3
- type MultiSelectOptions<T extends {
4
- value: any;
5
- }> = {
6
- options: T[];
7
- initialValues?: T["value"][];
8
- required?: boolean;
9
- cursorAt?: T["value"];
10
- } & PromptOptions<MultiSelectPrompt<T>>;
11
- export default class MultiSelectPrompt<T extends {
12
- value: any;
13
- }> extends Prompt {
14
- options: T[];
15
- cursor: number;
16
- private get _value();
17
- private toggleAll;
18
- private toggleValue;
19
- constructor(opts: MultiSelectOptions<T>);
20
- }
21
- export {};
@@ -1,45 +0,0 @@
1
- import Prompt from "../../components/prompts/prompt.js";
2
- export default class MultiSelectPrompt extends Prompt {
3
- options;
4
- cursor = 0;
5
- get _value() {
6
- return this.options[this.cursor].value;
7
- }
8
- toggleAll() {
9
- const allSelected = this.value.length === this.options.length;
10
- this.value = allSelected ? [] : this.options.map((v) => v.value);
11
- }
12
- toggleValue() {
13
- const selected = this.value.includes(this._value);
14
- this.value = selected ? this.value.filter((value) => value !== this._value) : [...this.value, this._value];
15
- }
16
- constructor(opts) {
17
- super(opts, false);
18
- this.options = opts.options;
19
- this.value = [...opts.initialValues ?? []];
20
- this.cursor = Math.max(
21
- this.options.findIndex(({ value }) => value === opts.cursorAt),
22
- 0
23
- );
24
- this.on("key", (char) => {
25
- if (char === "a") {
26
- this.toggleAll();
27
- }
28
- });
29
- this.on("cursor", (key) => {
30
- switch (key) {
31
- case "left":
32
- case "up":
33
- this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
34
- break;
35
- case "down":
36
- case "right":
37
- this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
38
- break;
39
- case "space":
40
- this.toggleValue();
41
- break;
42
- }
43
- });
44
- }
45
- }
@@ -1,18 +0,0 @@
1
- import type { ColorName, Variant, TypographyName } from "../../types/general.js";
2
- export declare function multiselectPrompt<T extends string>(params: {
3
- title: string;
4
- options: {
5
- value: T;
6
- hint?: string;
7
- }[];
8
- required?: boolean;
9
- initial?: T[];
10
- borderColor?: ColorName;
11
- titleColor?: ColorName;
12
- titleTypography?: TypographyName;
13
- titleVariant?: Variant;
14
- border?: boolean;
15
- endTitle?: string;
16
- endTitleColor?: ColorName;
17
- maxItems?: number;
18
- }): Promise<T[]>;
@@ -1,166 +0,0 @@
1
- import { stdin as input, stdout as output } from "node:process";
2
- import readline from "node:readline";
3
- import { cyanBright, dim, greenBright, redBright } from "picocolors";
4
- import { colorize } from "../../main.js";
5
- import { bar, symbols, msg } from "../../utils/messages.js";
6
- import { deleteLastLine } from "../../utils/terminal.js";
7
- export async function multiselectPrompt(params) {
8
- const {
9
- title,
10
- options,
11
- required = false,
12
- initial = [],
13
- borderColor = "viceGradient",
14
- titleColor = "cyanBright",
15
- titleTypography = "bold",
16
- titleVariant,
17
- border = true,
18
- endTitle = "\u{1F44B}",
19
- endTitleColor = "passionGradient",
20
- maxItems
21
- } = params;
22
- let pointer = 0;
23
- const selectedOptions = new Set(
24
- initial.map((opt) => options.findIndex((o) => o.value === opt)).filter((i) => i >= 0)
25
- );
26
- const rl = readline.createInterface({ input, output });
27
- readline.emitKeypressEvents(input, rl);
28
- if (typeof input.setRawMode === "function") {
29
- input.setRawMode(true);
30
- }
31
- const formattedBar = bar({ borderColor });
32
- let linesRendered = 0;
33
- const instructions = `Use <\u2191/\u2193> or <k/j> to navigate, <Space> to select/deselect, <Enter> to confirm, <Ctrl+C> to exit`;
34
- let errorMessage = "";
35
- function renderOptions() {
36
- if (linesRendered > 0) {
37
- process.stdout.write(`\x1B[${linesRendered}A`);
38
- }
39
- let outputStr = `${greenBright(symbols.step_active)} ${colorize(title, titleColor, titleTypography)}
40
- `;
41
- if (errorMessage) {
42
- outputStr += redBright(`${symbols.step_error} ${errorMessage}
43
- `);
44
- } else {
45
- outputStr += `${formattedBar} ${dim(instructions)}
46
- `;
47
- }
48
- const terminalHeight = process.stdout.rows || 24;
49
- const availableHeight = terminalHeight - 4;
50
- const computedMaxItems = Math.min(
51
- maxItems ?? Infinity,
52
- availableHeight > 0 ? availableHeight : Infinity,
53
- options.length
54
- );
55
- const minItems = 3;
56
- const displayItems = Math.max(computedMaxItems, minItems);
57
- let startIdx = 0;
58
- let endIdx = options.length - 1;
59
- if (options.length > displayItems) {
60
- const half = Math.floor(displayItems / 2);
61
- startIdx = pointer - half;
62
- endIdx = pointer + (displayItems - half - 1);
63
- if (startIdx < 0) {
64
- startIdx = 0;
65
- endIdx = displayItems - 1;
66
- } else if (endIdx >= options.length) {
67
- endIdx = options.length - 1;
68
- startIdx = options.length - displayItems;
69
- }
70
- }
71
- const shouldRenderTopEllipsis = startIdx > 0;
72
- const shouldRenderBottomEllipsis = endIdx < options.length - 1;
73
- if (shouldRenderTopEllipsis) {
74
- outputStr += `${formattedBar} ${dim("...")}
75
- `;
76
- }
77
- for (let index = startIdx; index <= endIdx; index++) {
78
- const option = options[index];
79
- const isSelected = selectedOptions.has(index);
80
- const isHighlighted = index === pointer;
81
- const checkbox = isSelected ? "[x]" : "[ ]";
82
- const prefix = isHighlighted ? "> " : " ";
83
- const optionLabel = isHighlighted ? cyanBright(option.value) : option.value;
84
- const hint = option.hint ? ` (${option.hint})` : "";
85
- outputStr += `${formattedBar} ${prefix}${checkbox} ${optionLabel}${dim(hint)}
86
- `;
87
- }
88
- if (shouldRenderBottomEllipsis) {
89
- outputStr += `${formattedBar} ${dim("...")}
90
- `;
91
- }
92
- process.stdout.write(outputStr);
93
- linesRendered = 1 + // Symbol + Title
94
- 1 + // Instructions or error message
95
- (shouldRenderTopEllipsis ? 1 : 0) + // Top ellipsis
96
- (endIdx - startIdx + 1) + // Displayed options
97
- (shouldRenderBottomEllipsis ? 1 : 0);
98
- }
99
- renderOptions();
100
- return new Promise((resolve) => {
101
- function onKeyPress(str, key) {
102
- if (key.name === "up" || key.name === "k") {
103
- pointer = (pointer - 1 + options.length) % options.length;
104
- errorMessage = "";
105
- renderOptions();
106
- } else if (key.name === "down" || key.name === "j") {
107
- pointer = (pointer + 1) % options.length;
108
- errorMessage = "";
109
- renderOptions();
110
- } else if (key.name === "space") {
111
- if (selectedOptions.has(pointer)) {
112
- selectedOptions.delete(pointer);
113
- } else {
114
- selectedOptions.add(pointer);
115
- }
116
- errorMessage = "";
117
- renderOptions();
118
- } else if (key.name === "return") {
119
- if (!required || selectedOptions.size > 0) {
120
- const selectedValues = Array.from(selectedOptions).map(
121
- (index) => options[index].value
122
- );
123
- cleanup();
124
- resolve(selectedValues);
125
- deleteLastLine();
126
- deleteLastLine();
127
- msg({
128
- type: "M_MIDDLE"
129
- });
130
- } else {
131
- deleteLastLine();
132
- errorMessage = "You must select at least one option.\x1B[K";
133
- renderOptions();
134
- }
135
- } else if (key.name === "c" && key.ctrl) {
136
- msg({
137
- type: "M_NEWLINE"
138
- });
139
- msg({
140
- type: "M_END",
141
- title: endTitle,
142
- titleColor: endTitleColor,
143
- titleTypography,
144
- titleVariant,
145
- border,
146
- borderColor
147
- });
148
- cleanup(true);
149
- }
150
- }
151
- function cleanup(isCtrlC = false) {
152
- if (typeof input.setRawMode === "function") {
153
- input.setRawMode(false);
154
- }
155
- rl.close();
156
- input.removeListener("keypress", onKeyPress);
157
- process.stdout.write(`\x1B[${linesRendered}B`);
158
- if (isCtrlC) {
159
- process.exit();
160
- } else {
161
- console.log();
162
- }
163
- }
164
- input.on("keypress", onKeyPress);
165
- });
166
- }
@@ -1,3 +0,0 @@
1
- import type { Static, TSchema } from "@sinclair/typebox";
2
- import type { PromptOptions } from "../../types/general.js";
3
- export declare function numMultiSelectPrompt<T extends TSchema>(options: PromptOptions<T>): Promise<Static<T>>;
@@ -1,111 +0,0 @@
1
- import { Value } from "@sinclair/typebox/value";
2
- import { stdin as input, stdout as output } from "node:process";
3
- import readline from "node:readline/promises";
4
- import { colorize } from "../../utils/colorize.js";
5
- import { bar, fmt, msg } from "../../utils/messages.js";
6
- import {
7
- countLines,
8
- deleteLastLine,
9
- deleteLastLines
10
- } from "../../utils/terminal.js";
11
- export async function numMultiSelectPrompt(options) {
12
- const {
13
- title,
14
- choices,
15
- schema,
16
- defaultValue,
17
- titleColor = "cyanBright",
18
- titleTypography = "bold",
19
- titleVariant,
20
- hint,
21
- content,
22
- contentColor = "dim",
23
- contentTypography,
24
- contentVariant,
25
- borderColor = "viceGradient",
26
- variantOptions
27
- } = options;
28
- if (!choices || choices.length === 0) {
29
- throw new Error("Choices are required for multiselect prompt.");
30
- }
31
- const rl = readline.createInterface({ input, output });
32
- const formattedBar = bar({ borderColor });
33
- let linesToDelete = 0;
34
- let errorMessage = "";
35
- try {
36
- while (true) {
37
- if (linesToDelete > 0) {
38
- deleteLastLines(linesToDelete);
39
- }
40
- const question = fmt({
41
- type: errorMessage !== "" ? "M_ERROR" : "M_GENERAL",
42
- title: `${title}${defaultValue ? ` [Default: ${Array.isArray(defaultValue) ? defaultValue.join(", ") : defaultValue}]` : ""}`,
43
- titleColor,
44
- titleTypography,
45
- titleVariant,
46
- content,
47
- contentColor,
48
- contentTypography,
49
- contentVariant,
50
- borderColor,
51
- hint,
52
- variantOptions,
53
- errorMessage,
54
- addNewLineBefore: false,
55
- addNewLineAfter: false
56
- });
57
- const choicesText = choices.map(
58
- (choice, index) => `${formattedBar} ${index + 1}) ${choice.title}${choice.description ? ` - ${choice.description}` : ""}`
59
- ).join("\n");
60
- const fullPrompt = `${question}
61
- ${choicesText}
62
- ${formattedBar} ${colorize(`Enter your choices (comma-separated numbers between 1-${choices.length})`, contentColor)}:
63
- ${formattedBar} `;
64
- const formattedPrompt = fmt({
65
- type: "M_NULL",
66
- title: fullPrompt
67
- });
68
- const questionLines = countLines(formattedPrompt);
69
- linesToDelete = questionLines + 1;
70
- const answer = (await rl.question(formattedPrompt)).trim();
71
- if (!answer && defaultValue !== void 0) {
72
- deleteLastLine();
73
- msg({
74
- type: "M_MIDDLE",
75
- title: ` ${Array.isArray(defaultValue) ? defaultValue.join(", ") : defaultValue}`,
76
- titleColor: "none"
77
- });
78
- msg({ type: "M_NEWLINE" });
79
- return defaultValue;
80
- }
81
- const selections = answer.split(",").map((s) => s.trim());
82
- const invalidSelections = selections.filter((s) => {
83
- const num = Number(s);
84
- return isNaN(num) || num < 1 || num > choices.length;
85
- });
86
- if (invalidSelections.length > 0) {
87
- errorMessage = `Invalid selections: ${invalidSelections.join(
88
- ", "
89
- )}. Please enter numbers between 1 and ${choices.length}.`;
90
- continue;
91
- }
92
- const selectedValues = selections.map((s) => choices[Number(s) - 1]?.id);
93
- let isValid = true;
94
- errorMessage = "";
95
- if (schema) {
96
- isValid = Value.Check(schema, selectedValues);
97
- if (!isValid) {
98
- const errors = [...Value.Errors(schema, selectedValues)];
99
- errorMessage = errors.length > 0 ? errors[0]?.message ?? "Invalid input." : "Invalid input.";
100
- }
101
- }
102
- if (isValid) {
103
- msg({ type: "M_NEWLINE" });
104
- rl.close();
105
- return selectedValues;
106
- }
107
- }
108
- } finally {
109
- rl.close();
110
- }
111
- }
@@ -1,6 +0,0 @@
1
- export declare function multiselectPrompt<T extends string>(params: {
2
- message: string;
3
- options: T[];
4
- required?: boolean;
5
- initial?: T[];
6
- }): Promise<T[]>;
@@ -1,28 +0,0 @@
1
- import { stdin as input, stdout as output } from "process";
2
- import readline from "readline/promises";
3
- export async function multiselectPrompt(params) {
4
- const { message, options, required = false, initial = [] } = params;
5
- const rl = readline.createInterface({ input, output });
6
- while (true) {
7
- console.log(`
8
- ${message}`);
9
- options.forEach((option, index) => {
10
- const isSelected = initial.includes(option) ? "[x]" : "[ ]";
11
- console.log(`${index + 1}. ${isSelected} ${option}`);
12
- });
13
- const promptMessage = initial.length > 0 ? `Please select options by number (separated by commas, default ${initial.map((opt) => options.indexOf(opt) + 1).join(", ")}): ` : "Please select options by number (separated by commas): ";
14
- const response = await rl.question(promptMessage);
15
- let indices;
16
- if (response.trim() === "" && initial.length > 0) {
17
- indices = initial.map((opt) => options.indexOf(opt));
18
- } else {
19
- indices = response.split(",").map((num) => parseInt(num.trim(), 10) - 1).filter((index) => index >= 0 && index < options.length);
20
- }
21
- if (indices.length > 0 || !required && indices.length === 0) {
22
- rl.close();
23
- return indices.map((index) => options[index]);
24
- } else {
25
- console.log("Invalid selection. Please try again.");
26
- }
27
- }
28
- }
@@ -1,2 +0,0 @@
1
- import type { PromptOptions } from "../../types/general.js";
2
- export declare function nextStepsPrompt(options: PromptOptions): Promise<void>;
@@ -1,24 +0,0 @@
1
- import { msg } from "../../utils/messages.js";
2
- export async function nextStepsPrompt(options) {
3
- const {
4
- title,
5
- titleColor = "cyanBright",
6
- titleVariant,
7
- titleTypography = "bold",
8
- content,
9
- contentColor,
10
- contentVariant,
11
- contentTypography
12
- } = options;
13
- msg({
14
- type: "M_INFO",
15
- title,
16
- titleColor,
17
- titleVariant,
18
- titleTypography,
19
- content,
20
- contentColor,
21
- contentVariant,
22
- contentTypography
23
- });
24
- }
@@ -1,2 +0,0 @@
1
- declare const _default: any;
2
- export default _default;