mepcli 0.6.1 → 1.0.0-beta.2

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 (113) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +512 -326
  3. package/dist/ansi.d.ts +8 -0
  4. package/dist/ansi.js +8 -0
  5. package/dist/base.d.ts +21 -0
  6. package/dist/base.js +57 -0
  7. package/dist/core.d.ts +48 -1
  8. package/dist/core.js +156 -0
  9. package/dist/data/licenses.d.ts +2 -0
  10. package/dist/data/licenses.js +109 -0
  11. package/dist/highlight.js +58 -26
  12. package/dist/index.d.ts +36 -0
  13. package/dist/index.js +36 -0
  14. package/dist/input.js +0 -3
  15. package/dist/prompts/box.d.ts +21 -0
  16. package/dist/prompts/box.js +192 -0
  17. package/dist/prompts/breadcrumb.d.ts +22 -0
  18. package/dist/prompts/breadcrumb.js +302 -0
  19. package/dist/prompts/byte.d.ts +13 -0
  20. package/dist/prompts/byte.js +159 -0
  21. package/dist/prompts/calculator.d.ts +16 -0
  22. package/dist/prompts/calculator.js +213 -0
  23. package/dist/prompts/calendar.js +0 -5
  24. package/dist/prompts/code.d.ts +2 -0
  25. package/dist/prompts/code.js +104 -70
  26. package/dist/prompts/connection-string.d.ts +18 -0
  27. package/dist/prompts/connection-string.js +97 -0
  28. package/dist/prompts/curl.d.ts +39 -0
  29. package/dist/prompts/curl.js +285 -0
  30. package/dist/prompts/data-inspector.d.ts +22 -0
  31. package/dist/prompts/data-inspector.js +256 -0
  32. package/dist/prompts/dependency.d.ts +16 -0
  33. package/dist/prompts/dependency.js +265 -0
  34. package/dist/prompts/dial.d.ts +10 -0
  35. package/dist/prompts/dial.js +110 -0
  36. package/dist/prompts/diff.d.ts +10 -0
  37. package/dist/prompts/diff.js +101 -0
  38. package/dist/prompts/draw.d.ts +20 -0
  39. package/dist/prompts/draw.js +188 -0
  40. package/dist/prompts/editor.js +0 -4
  41. package/dist/prompts/emoji.d.ts +18 -0
  42. package/dist/prompts/emoji.js +228 -0
  43. package/dist/prompts/exec.d.ts +13 -0
  44. package/dist/prompts/exec.js +83 -0
  45. package/dist/prompts/fuzzy.d.ts +12 -0
  46. package/dist/prompts/fuzzy.js +136 -0
  47. package/dist/prompts/gauge.d.ts +21 -0
  48. package/dist/prompts/gauge.js +130 -0
  49. package/dist/prompts/heatmap.d.ts +13 -0
  50. package/dist/prompts/heatmap.js +141 -0
  51. package/dist/prompts/ip.d.ts +11 -0
  52. package/dist/prompts/ip.js +118 -0
  53. package/dist/prompts/kanban.d.ts +17 -0
  54. package/dist/prompts/kanban.js +228 -0
  55. package/dist/prompts/keypress.js +0 -2
  56. package/dist/prompts/license.d.ts +9 -0
  57. package/dist/prompts/license.js +105 -0
  58. package/dist/prompts/map.d.ts +15 -0
  59. package/dist/prompts/map.js +199 -0
  60. package/dist/prompts/match.d.ts +19 -0
  61. package/dist/prompts/match.js +275 -0
  62. package/dist/prompts/miller.d.ts +15 -0
  63. package/dist/prompts/miller.js +221 -0
  64. package/dist/prompts/multi-column-select.d.ts +10 -0
  65. package/dist/prompts/multi-column-select.js +166 -0
  66. package/dist/prompts/number.js +0 -2
  67. package/dist/prompts/otp.d.ts +10 -0
  68. package/dist/prompts/otp.js +91 -0
  69. package/dist/prompts/pattern.d.ts +22 -0
  70. package/dist/prompts/pattern.js +249 -0
  71. package/dist/prompts/quiz-select.d.ts +10 -0
  72. package/dist/prompts/quiz-select.js +104 -0
  73. package/dist/prompts/quiz-text.d.ts +11 -0
  74. package/dist/prompts/quiz-text.js +82 -0
  75. package/dist/prompts/regex.d.ts +13 -0
  76. package/dist/prompts/regex.js +131 -0
  77. package/dist/prompts/region.d.ts +11 -0
  78. package/dist/prompts/region.js +164 -0
  79. package/dist/prompts/schedule.d.ts +18 -0
  80. package/dist/prompts/schedule.js +221 -0
  81. package/dist/prompts/scroll.d.ts +13 -0
  82. package/dist/prompts/scroll.js +152 -0
  83. package/dist/prompts/seat.d.ts +17 -0
  84. package/dist/prompts/seat.js +165 -0
  85. package/dist/prompts/select-range.d.ts +8 -0
  86. package/dist/prompts/select-range.js +136 -0
  87. package/dist/prompts/select.d.ts +9 -9
  88. package/dist/prompts/semver.d.ts +6 -0
  89. package/dist/prompts/semver.js +32 -0
  90. package/dist/prompts/shortcut.d.ts +9 -0
  91. package/dist/prompts/shortcut.js +135 -0
  92. package/dist/prompts/slot.d.ts +16 -0
  93. package/dist/prompts/slot.js +107 -0
  94. package/dist/prompts/snippet.js +0 -3
  95. package/dist/prompts/sort-grid.d.ts +16 -0
  96. package/dist/prompts/sort-grid.js +146 -0
  97. package/dist/prompts/sort.js +0 -1
  98. package/dist/prompts/spreadsheet.d.ts +21 -0
  99. package/dist/prompts/spreadsheet.js +239 -0
  100. package/dist/prompts/text.d.ts +9 -7
  101. package/dist/prompts/text.js +52 -0
  102. package/dist/prompts/time.d.ts +12 -0
  103. package/dist/prompts/time.js +202 -0
  104. package/dist/prompts/tree-select.d.ts +0 -1
  105. package/dist/prompts/tree-select.js +1 -5
  106. package/dist/symbols.d.ts +12 -0
  107. package/dist/symbols.js +14 -2
  108. package/dist/theme.js +10 -1
  109. package/dist/types.d.ts +264 -1
  110. package/dist/utils.d.ts +53 -0
  111. package/dist/utils.js +252 -0
  112. package/package.json +51 -47
  113. package/example.ts +0 -390
@@ -48,8 +48,6 @@ class NumberPrompt extends base_1.Prompt {
48
48
  if (char === '\r' || char === '\n') {
49
49
  const num = parseFloat(this.stringValue);
50
50
  if (this.stringValue.trim() === '' || isNaN(num)) {
51
- // Check if empty is allowed?
52
- // If not required? Assuming required for number prompt usually
53
51
  this.errorMsg = 'Please enter a valid number.';
54
52
  this.render(false);
55
53
  return;
@@ -0,0 +1,10 @@
1
+ import { Prompt } from '../base';
2
+ import { OTPOptions } from '../types';
3
+ export declare class OTPPrompt extends Prompt<string, OTPOptions> {
4
+ private slots;
5
+ private cursor;
6
+ private readonly length;
7
+ constructor(options: OTPOptions);
8
+ protected render(_firstRender: boolean): void;
9
+ protected handleInput(char: string): void;
10
+ }
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OTPPrompt = void 0;
4
+ const ansi_1 = require("../ansi");
5
+ const base_1 = require("../base");
6
+ const theme_1 = require("../theme");
7
+ class OTPPrompt extends base_1.Prompt {
8
+ constructor(options) {
9
+ super(options);
10
+ this.cursor = 0;
11
+ this.length = options.length || 6;
12
+ this.slots = new Array(this.length).fill('');
13
+ }
14
+ render(_firstRender) {
15
+ const mask = this.options.mask || '_';
16
+ let output = `${theme_1.theme.success}?${ansi_1.ANSI.RESET} ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET}\n`;
17
+ output += ' '; // Indent
18
+ for (let i = 0; i < this.length; i++) {
19
+ const val = this.slots[i];
20
+ let charToDisplay = mask;
21
+ if (val) {
22
+ charToDisplay = this.options.secure ? '*' : val;
23
+ }
24
+ else {
25
+ // Use placeholder char if available at this index
26
+ if (this.options.placeholder && i < this.options.placeholder.length) {
27
+ charToDisplay = this.options.placeholder[i];
28
+ }
29
+ }
30
+ if (i === this.cursor) {
31
+ output += `${ansi_1.ANSI.REVERSE}${charToDisplay}${ansi_1.ANSI.RESET} `;
32
+ }
33
+ else {
34
+ if (!val) {
35
+ output += `${theme_1.theme.muted}${charToDisplay}${ansi_1.ANSI.RESET} `;
36
+ }
37
+ else {
38
+ output += `${theme_1.theme.main}${charToDisplay}${ansi_1.ANSI.RESET} `;
39
+ }
40
+ }
41
+ }
42
+ this.renderFrame(output);
43
+ }
44
+ handleInput(char) {
45
+ // Digits
46
+ if (/^\d$/.test(char)) {
47
+ this.slots[this.cursor] = char;
48
+ // If we are at the last slot
49
+ if (this.cursor === this.length - 1) {
50
+ // Only submit if all slots are filled
51
+ if (this.slots.every(s => s !== '')) {
52
+ this.render(false); // Update view first
53
+ this.submit(this.slots.join(''));
54
+ return;
55
+ }
56
+ }
57
+ this.cursor++;
58
+ this.render(false);
59
+ return;
60
+ }
61
+ // Backspace
62
+ if (char === '\u0008' || char === '\x7f') {
63
+ if (this.slots[this.cursor] !== '') {
64
+ this.slots[this.cursor] = '';
65
+ }
66
+ else if (this.cursor > 0) {
67
+ this.cursor--;
68
+ this.slots[this.cursor] = '';
69
+ }
70
+ this.render(false);
71
+ return;
72
+ }
73
+ // Left Arrow
74
+ if (this.isLeft(char)) {
75
+ if (this.cursor > 0) {
76
+ this.cursor--;
77
+ this.render(false);
78
+ }
79
+ return;
80
+ }
81
+ // Right Arrow
82
+ if (this.isRight(char)) {
83
+ if (this.cursor < this.length - 1) {
84
+ this.cursor++;
85
+ this.render(false);
86
+ }
87
+ return;
88
+ }
89
+ }
90
+ }
91
+ exports.OTPPrompt = OTPPrompt;
@@ -0,0 +1,22 @@
1
+ import { Prompt } from '../base';
2
+ import { PatternOptions, MouseEvent } from '../types';
3
+ export declare class PatternPrompt extends Prompt<number[], PatternOptions> {
4
+ private path;
5
+ private cursor;
6
+ private isDragging;
7
+ private errorMsg;
8
+ private rows;
9
+ private cols;
10
+ private nodeChar;
11
+ private nodeSpacingX;
12
+ private nodeSpacingY;
13
+ private lastMouse;
14
+ constructor(options: PatternOptions);
15
+ private getIndex;
16
+ private getPoint;
17
+ protected render(firstRender: boolean): void;
18
+ private drawLine;
19
+ protected handleInput(char: string, _key: Buffer): void;
20
+ private addToPath;
21
+ protected handleMouse(event: MouseEvent): void;
22
+ }
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PatternPrompt = void 0;
4
+ const ansi_1 = require("../ansi");
5
+ const base_1 = require("../base");
6
+ const theme_1 = require("../theme");
7
+ class PatternPrompt extends base_1.Prompt {
8
+ constructor(options) {
9
+ super(options);
10
+ this.path = [];
11
+ this.cursor = { r: 0, c: 0 };
12
+ this.isDragging = false;
13
+ this.errorMsg = '';
14
+ // Layout
15
+ this.nodeSpacingX = 4;
16
+ this.nodeSpacingY = 2;
17
+ this.lastMouse = null;
18
+ this.rows = options.rows || 3;
19
+ this.cols = options.cols || 3;
20
+ this.nodeChar = options.nodeChar || '●';
21
+ }
22
+ getIndex(r, c) {
23
+ return r * this.cols + c;
24
+ }
25
+ getPoint(index) {
26
+ return {
27
+ r: Math.floor(index / this.cols),
28
+ c: index % this.cols
29
+ };
30
+ }
31
+ render(firstRender) {
32
+ let output = '';
33
+ // Title
34
+ const icon = this.errorMsg ? `${theme_1.theme.error}✖` : `${theme_1.theme.success}?`;
35
+ output += `${icon} ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET}\n`;
36
+ // Instructions
37
+ if (firstRender) {
38
+ output += `${ansi_1.ANSI.DIM}(Draw pattern with mouse or use Arrows + Space)${ansi_1.ANSI.RESET}\n`;
39
+ }
40
+ // Render Grid
41
+ // Initialize buffer with spaces
42
+ // Adjust height/width slightly to ensure we cover full lines
43
+ const bufferHeight = this.rows * this.nodeSpacingY + 1;
44
+ const bufferWidth = this.cols * this.nodeSpacingX + 1;
45
+ const buffer = Array(bufferHeight).fill(null).map(() => Array(bufferWidth).fill(' '));
46
+ // Draw connections
47
+ for (let i = 0; i < this.path.length - 1; i++) {
48
+ this.drawLine(buffer, this.path[i], this.path[i + 1]);
49
+ }
50
+ // Draw nodes
51
+ for (let r = 0; r < this.rows; r++) {
52
+ for (let c = 0; c < this.cols; c++) {
53
+ const index = this.getIndex(r, c);
54
+ const isSelected = this.path.includes(index);
55
+ // Calculate buffer position
56
+ const by = r * this.nodeSpacingY;
57
+ const bx = c * this.nodeSpacingX;
58
+ // Mark node in buffer (will be stylized later)
59
+ buffer[by][bx] = isSelected ? '●' : '○';
60
+ }
61
+ }
62
+ // Build string from buffer
63
+ // Limit loop to actual grid dimensions to avoid trailing empty lines
64
+ const displayHeight = (this.rows - 1) * this.nodeSpacingY + 1;
65
+ const displayWidth = (this.cols - 1) * this.nodeSpacingX + 1;
66
+ for (let y = 0; y < displayHeight; y++) {
67
+ output += ' '; // Indent
68
+ for (let x = 0; x < displayWidth; x++) {
69
+ const char = buffer[y][x];
70
+ // Determine coloring context
71
+ const isNodeRow = y % this.nodeSpacingY === 0;
72
+ const isNodeCol = x % this.nodeSpacingX === 0;
73
+ if (isNodeRow && isNodeCol) {
74
+ const r = y / this.nodeSpacingY;
75
+ const c = x / this.nodeSpacingX;
76
+ const idx = this.getIndex(r, c);
77
+ const isSelected = this.path.includes(idx);
78
+ const isLast = this.path.length > 0 && this.path[this.path.length - 1] === idx;
79
+ const isCursor = this.cursor.r === r && this.cursor.c === c;
80
+ let styledChar = this.nodeChar;
81
+ if (isSelected)
82
+ styledChar = theme_1.theme.main + this.nodeChar + ansi_1.ANSI.RESET;
83
+ if (isLast)
84
+ styledChar = theme_1.theme.success + this.nodeChar + ansi_1.ANSI.RESET;
85
+ if (isCursor) {
86
+ styledChar = ansi_1.ANSI.REVERSE + styledChar + ansi_1.ANSI.RESET;
87
+ }
88
+ else if (!isSelected) {
89
+ styledChar = theme_1.theme.muted + '○' + ansi_1.ANSI.RESET;
90
+ }
91
+ output += styledChar;
92
+ }
93
+ else {
94
+ // It's a line or space
95
+ if (char !== ' ' && char !== '○' && char !== '●') {
96
+ output += theme_1.theme.main + char + ansi_1.ANSI.RESET;
97
+ }
98
+ else {
99
+ output += ' ';
100
+ }
101
+ }
102
+ }
103
+ output += '\n';
104
+ }
105
+ if (this.errorMsg) {
106
+ output += `\n${theme_1.theme.error}>> ${this.errorMsg}${ansi_1.ANSI.RESET}`;
107
+ }
108
+ this.renderFrame(output);
109
+ }
110
+ drawLine(buffer, fromIdx, toIdx) {
111
+ const p1 = this.getPoint(fromIdx);
112
+ const p2 = this.getPoint(toIdx);
113
+ const y1 = p1.r * this.nodeSpacingY;
114
+ const x1 = p1.c * this.nodeSpacingX;
115
+ const y2 = p2.r * this.nodeSpacingY;
116
+ const x2 = p2.c * this.nodeSpacingX;
117
+ const dy = y2 - y1;
118
+ const dx = x2 - x1;
119
+ const steps = Math.max(Math.abs(dx), Math.abs(dy));
120
+ if (steps === 0)
121
+ return;
122
+ const yInc = dy / steps;
123
+ const xInc = dx / steps;
124
+ let y = y1;
125
+ let x = x1;
126
+ for (let i = 0; i <= steps; i++) {
127
+ const ry = Math.round(y);
128
+ const rx = Math.round(x);
129
+ // Check bounds
130
+ if (ry >= 0 && ry < buffer.length && rx >= 0 && rx < buffer[0].length) {
131
+ const isNode = (ry % this.nodeSpacingY === 0) && (rx % this.nodeSpacingX === 0);
132
+ if (!isNode) {
133
+ // Determine char based on slope
134
+ // Flat horizontal
135
+ if (dy === 0)
136
+ buffer[ry][rx] = '─';
137
+ // Flat vertical
138
+ else if (dx === 0)
139
+ buffer[ry][rx] = '│';
140
+ // Diagonal
141
+ else if ((dx > 0 && dy > 0) || (dx < 0 && dy < 0))
142
+ buffer[ry][rx] = '╲';
143
+ else
144
+ buffer[ry][rx] = '╱';
145
+ }
146
+ }
147
+ y += yInc;
148
+ x += xInc;
149
+ }
150
+ }
151
+ handleInput(char, _key) {
152
+ // Navigation
153
+ if (this.isUp(char)) {
154
+ this.cursor.r = Math.max(0, this.cursor.r - 1);
155
+ this.render(false);
156
+ return;
157
+ }
158
+ if (this.isDown(char)) {
159
+ this.cursor.r = Math.min(this.rows - 1, this.cursor.r + 1);
160
+ this.render(false);
161
+ return;
162
+ }
163
+ if (this.isLeft(char)) {
164
+ this.cursor.c = Math.max(0, this.cursor.c - 1);
165
+ this.render(false);
166
+ return;
167
+ }
168
+ if (this.isRight(char)) {
169
+ this.cursor.c = Math.min(this.cols - 1, this.cursor.c + 1);
170
+ this.render(false);
171
+ return;
172
+ }
173
+ // Selection (Space)
174
+ if (char === ' ') {
175
+ const index = this.getIndex(this.cursor.r, this.cursor.c);
176
+ this.addToPath(index);
177
+ this.render(false);
178
+ return;
179
+ }
180
+ // Submit (Enter)
181
+ if (char === '\r' || char === '\n') {
182
+ if (this.path.length < 2) {
183
+ this.errorMsg = 'Pattern too short';
184
+ this.render(false);
185
+ return;
186
+ }
187
+ this.submit(this.path);
188
+ return;
189
+ }
190
+ // Backspace / Reset
191
+ if (char === '\x7f' || char === '\b') {
192
+ this.path.pop();
193
+ this.render(false);
194
+ return;
195
+ }
196
+ }
197
+ addToPath(index) {
198
+ if (this.path.includes(index)) {
199
+ return;
200
+ }
201
+ this.path.push(index);
202
+ }
203
+ handleMouse(event) {
204
+ if (event.action === 'release') {
205
+ this.isDragging = false;
206
+ this.lastMouse = null;
207
+ if (this.path.length >= 2) {
208
+ this.submit(this.path);
209
+ }
210
+ return;
211
+ }
212
+ if (this.lastMouse) {
213
+ const dx = event.x - this.lastMouse.x;
214
+ const dy = event.y - this.lastMouse.y;
215
+ // Sensitivity threshold
216
+ if (dx !== 0 || dy !== 0) {
217
+ if (Math.abs(dx) > Math.abs(dy)) {
218
+ if (dx > 0)
219
+ this.cursor.c = Math.min(this.cols - 1, this.cursor.c + 1);
220
+ else if (dx < 0)
221
+ this.cursor.c = Math.max(0, this.cursor.c - 1);
222
+ }
223
+ else {
224
+ if (dy > 0)
225
+ this.cursor.r = Math.min(this.rows - 1, this.cursor.r + 1);
226
+ else if (dy < 0)
227
+ this.cursor.r = Math.max(0, this.cursor.r - 1);
228
+ }
229
+ if (this.isDragging) {
230
+ const idx = this.getIndex(this.cursor.r, this.cursor.c);
231
+ this.addToPath(idx);
232
+ }
233
+ this.render(false);
234
+ }
235
+ }
236
+ else {
237
+ // Mouse Down
238
+ if (event.action === 'press' && event.button === 0) {
239
+ this.isDragging = true;
240
+ this.path = []; // Reset
241
+ const idx = this.getIndex(this.cursor.r, this.cursor.c);
242
+ this.addToPath(idx);
243
+ this.render(false);
244
+ }
245
+ }
246
+ this.lastMouse = { x: event.x, y: event.y };
247
+ }
248
+ }
249
+ exports.PatternPrompt = PatternPrompt;
@@ -0,0 +1,10 @@
1
+ import { QuizSelectOptions } from '../types';
2
+ import { SelectPrompt } from './select';
3
+ export declare class QuizSelectPrompt<V> extends SelectPrompt<V, QuizSelectOptions<V>> {
4
+ private status;
5
+ private isCorrect;
6
+ private userSelectionIndex;
7
+ constructor(options: QuizSelectOptions<V>);
8
+ protected handleInput(char: string): void;
9
+ protected render(firstRender: boolean): void;
10
+ }
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QuizSelectPrompt = void 0;
4
+ const ansi_1 = require("../ansi");
5
+ const theme_1 = require("../theme");
6
+ const symbols_1 = require("../symbols");
7
+ const select_1 = require("./select");
8
+ class QuizSelectPrompt extends select_1.SelectPrompt {
9
+ constructor(options) {
10
+ super(options);
11
+ this.status = 'pending';
12
+ this.isCorrect = false;
13
+ this.userSelectionIndex = -1;
14
+ }
15
+ handleInput(char) {
16
+ if (this.status === 'revealed') {
17
+ // Wait for Enter to submit
18
+ if (char === '\r' || char === '\n') {
19
+ const choices = this.getFilteredChoices();
20
+ // Ensure index is valid, though it should be captured
21
+ const value = choices[this.userSelectionIndex]
22
+ ? choices[this.userSelectionIndex].value
23
+ : null;
24
+ this.submit(value);
25
+ }
26
+ return;
27
+ }
28
+ if (this.status === 'pending') {
29
+ // Intercept Enter
30
+ if (char === '\r' || char === '\n') {
31
+ const choices = this.getFilteredChoices();
32
+ if (choices.length === 0)
33
+ return;
34
+ if (this.isSeparator(choices[this.selectedIndex]))
35
+ return;
36
+ this.userSelectionIndex = this.selectedIndex;
37
+ const selectedChoice = choices[this.userSelectionIndex];
38
+ // Check correctness
39
+ this.isCorrect = selectedChoice.value === this.options.correctValue;
40
+ this.status = 'revealed';
41
+ this.render(false);
42
+ return;
43
+ }
44
+ // Delegate navigation to super
45
+ super.handleInput(char);
46
+ }
47
+ }
48
+ render(firstRender) {
49
+ if (this.status === 'pending') {
50
+ super.render(firstRender);
51
+ return;
52
+ }
53
+ // Revealed State
54
+ let output = '';
55
+ const choices = this.getFilteredChoices();
56
+ // Header
57
+ const icon = this.isCorrect ? `${theme_1.theme.success}${symbols_1.symbols.tick}` : `${theme_1.theme.error}${symbols_1.symbols.cross}`;
58
+ output += `${icon} ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET}\n`;
59
+ const visibleChoices = choices.slice(this.scrollTop, this.scrollTop + this.pageSize);
60
+ visibleChoices.forEach((choice, index) => {
61
+ if (index > 0)
62
+ output += '\n';
63
+ if (this.isSeparator(choice)) {
64
+ output += ` ${ansi_1.ANSI.DIM}${choice.text || symbols_1.symbols.line.repeat(8)}${ansi_1.ANSI.RESET}`;
65
+ }
66
+ else {
67
+ // Determine absolute index to match with user selection
68
+ const actualIndex = this.scrollTop + index;
69
+ const isSelected = actualIndex === this.userSelectionIndex;
70
+ const isCorrectAnswer = choice.value === this.options.correctValue;
71
+ let prefix = ' ';
72
+ let style = ansi_1.ANSI.RESET;
73
+ if (isSelected) {
74
+ if (this.isCorrect) {
75
+ prefix = `${theme_1.theme.success}${symbols_1.symbols.pointer} `;
76
+ style = theme_1.theme.success;
77
+ }
78
+ else {
79
+ prefix = `${theme_1.theme.error}${symbols_1.symbols.cross} `;
80
+ style = theme_1.theme.error;
81
+ }
82
+ }
83
+ else if (isCorrectAnswer) {
84
+ prefix = `${theme_1.theme.success}${symbols_1.symbols.pointer} `;
85
+ style = theme_1.theme.success;
86
+ }
87
+ output += `${prefix}${style}${choice.title}${ansi_1.ANSI.RESET}`;
88
+ if (isSelected && !this.isCorrect) {
89
+ output += ` ${theme_1.theme.error}(Your Answer)${ansi_1.ANSI.RESET}`;
90
+ }
91
+ if (isCorrectAnswer && !isSelected) {
92
+ output += ` ${theme_1.theme.success}(Correct)${ansi_1.ANSI.RESET}`;
93
+ }
94
+ }
95
+ });
96
+ // Explanation
97
+ if (this.options.explanation) {
98
+ output += `\n\n${ansi_1.ANSI.BOLD}Explanation:${ansi_1.ANSI.RESET}\n${theme_1.theme.muted}${this.options.explanation}${ansi_1.ANSI.RESET}`;
99
+ }
100
+ output += `\n\n${ansi_1.ANSI.DIM}(Press Enter to continue)${ansi_1.ANSI.RESET}`;
101
+ this.renderFrame(output);
102
+ }
103
+ }
104
+ exports.QuizSelectPrompt = QuizSelectPrompt;
@@ -0,0 +1,11 @@
1
+ import { QuizTextOptions } from '../types';
2
+ import { TextPrompt } from './text';
3
+ export declare class QuizTextPrompt extends TextPrompt<QuizTextOptions> {
4
+ private status;
5
+ private isCorrect;
6
+ constructor(options: QuizTextOptions);
7
+ protected handleInput(char: string): void;
8
+ protected submit(value: string): void;
9
+ private checkCorrectness;
10
+ protected render(firstRender: boolean): void;
11
+ }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QuizTextPrompt = void 0;
4
+ const ansi_1 = require("../ansi");
5
+ const theme_1 = require("../theme");
6
+ const symbols_1 = require("../symbols");
7
+ const text_1 = require("./text");
8
+ class QuizTextPrompt extends text_1.TextPrompt {
9
+ constructor(options) {
10
+ super(options);
11
+ this.status = 'pending';
12
+ this.isCorrect = false;
13
+ }
14
+ handleInput(char) {
15
+ if (this.status === 'revealed') {
16
+ if (char === '\r' || char === '\n') {
17
+ this.submit(this.value);
18
+ }
19
+ return;
20
+ }
21
+ super.handleInput(char);
22
+ }
23
+ submit(value) {
24
+ if (this.status === 'pending') {
25
+ // We caught the submission from TextPrompt logic.
26
+ // Now verify correctness.
27
+ this.checkCorrectness(value).then(correct => {
28
+ this.isCorrect = correct;
29
+ this.status = 'revealed';
30
+ this.render(false);
31
+ });
32
+ }
33
+ else {
34
+ // If revealed (or anything else), we proceed to final submission.
35
+ // This calls Prompt.submit
36
+ super.submit(value);
37
+ }
38
+ }
39
+ async checkCorrectness(value) {
40
+ try {
41
+ if (this.options.verify) {
42
+ return await this.options.verify(value);
43
+ }
44
+ if (this.options.correctAnswer) {
45
+ return value.trim().toLowerCase() === this.options.correctAnswer.trim().toLowerCase();
46
+ }
47
+ return false;
48
+ }
49
+ catch (_e) {
50
+ return false;
51
+ }
52
+ }
53
+ render(firstRender) {
54
+ if (this.status === 'pending') {
55
+ super.render(firstRender);
56
+ return;
57
+ }
58
+ // Revealed State
59
+ let output = '';
60
+ const icon = this.isCorrect ? `${theme_1.theme.success}${symbols_1.symbols.tick}` : `${theme_1.theme.error}${symbols_1.symbols.cross}`;
61
+ output += `${icon} ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET}\n`;
62
+ const userValue = this.segments.join('');
63
+ // Display user input
64
+ if (this.isCorrect) {
65
+ output += ` ${theme_1.theme.success}${userValue}${ansi_1.ANSI.RESET} ${theme_1.theme.success}(Correct)${ansi_1.ANSI.RESET}`;
66
+ }
67
+ else {
68
+ output += ` ${theme_1.theme.error}${userValue}${ansi_1.ANSI.RESET} ${theme_1.theme.error}(Wrong)${ansi_1.ANSI.RESET}`;
69
+ }
70
+ // Show correct answer if wrong
71
+ if (!this.isCorrect && this.options.correctAnswer) {
72
+ output += `\n ${theme_1.theme.success}Correct Answer: ${this.options.correctAnswer}${ansi_1.ANSI.RESET}`;
73
+ }
74
+ // Explanation
75
+ if (this.options.explanation) {
76
+ output += `\n\n${ansi_1.ANSI.BOLD}Explanation:${ansi_1.ANSI.RESET}\n${theme_1.theme.muted}${this.options.explanation}${ansi_1.ANSI.RESET}`;
77
+ }
78
+ output += `\n\n${ansi_1.ANSI.DIM}(Press Enter to continue)${ansi_1.ANSI.RESET}`;
79
+ this.renderFrame(output);
80
+ }
81
+ }
82
+ exports.QuizTextPrompt = QuizTextPrompt;
@@ -0,0 +1,13 @@
1
+ import { Prompt } from '../base';
2
+ import { RegexOptions } from '../types';
3
+ export declare class RegexPrompt extends Prompt<RegExp, RegexOptions> {
4
+ private input;
5
+ private cursor;
6
+ private segments;
7
+ private error;
8
+ private regex;
9
+ constructor(options: RegexOptions);
10
+ private validateRegex;
11
+ protected render(_firstRender: boolean): void;
12
+ protected handleInput(char: string, _key: Buffer): void;
13
+ }