mepcli 0.5.0 → 0.6.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.
Files changed (76) hide show
  1. package/README.md +182 -6
  2. package/dist/ansi.d.ts +1 -0
  3. package/dist/ansi.js +1 -0
  4. package/dist/base.d.ts +1 -1
  5. package/dist/base.js +1 -10
  6. package/dist/core.d.ts +26 -1
  7. package/dist/core.js +72 -0
  8. package/dist/highlight.d.ts +1 -0
  9. package/dist/highlight.js +40 -0
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.js +1 -1
  12. package/dist/input.js +26 -14
  13. package/dist/prompts/autocomplete.d.ts +1 -1
  14. package/dist/prompts/autocomplete.js +2 -7
  15. package/dist/prompts/calendar.d.ts +20 -0
  16. package/dist/prompts/calendar.js +329 -0
  17. package/dist/prompts/checkbox.d.ts +1 -1
  18. package/dist/prompts/checkbox.js +38 -8
  19. package/dist/prompts/code.d.ts +17 -0
  20. package/dist/prompts/code.js +210 -0
  21. package/dist/prompts/color.d.ts +14 -0
  22. package/dist/prompts/color.js +147 -0
  23. package/dist/prompts/confirm.d.ts +1 -1
  24. package/dist/prompts/confirm.js +1 -1
  25. package/dist/prompts/cron.d.ts +13 -0
  26. package/dist/prompts/cron.js +176 -0
  27. package/dist/prompts/date.d.ts +1 -1
  28. package/dist/prompts/date.js +15 -5
  29. package/dist/prompts/editor.d.ts +14 -0
  30. package/dist/prompts/editor.js +207 -0
  31. package/dist/prompts/file.d.ts +7 -0
  32. package/dist/prompts/file.js +56 -60
  33. package/dist/prompts/form.d.ts +17 -0
  34. package/dist/prompts/form.js +225 -0
  35. package/dist/prompts/grid.d.ts +14 -0
  36. package/dist/prompts/grid.js +178 -0
  37. package/dist/prompts/keypress.d.ts +7 -0
  38. package/dist/prompts/keypress.js +57 -0
  39. package/dist/prompts/list.d.ts +1 -1
  40. package/dist/prompts/list.js +42 -22
  41. package/dist/prompts/multi-select.d.ts +1 -1
  42. package/dist/prompts/multi-select.js +39 -4
  43. package/dist/prompts/number.d.ts +1 -1
  44. package/dist/prompts/number.js +2 -2
  45. package/dist/prompts/range.d.ts +9 -0
  46. package/dist/prompts/range.js +140 -0
  47. package/dist/prompts/rating.d.ts +1 -1
  48. package/dist/prompts/rating.js +1 -1
  49. package/dist/prompts/select.d.ts +1 -1
  50. package/dist/prompts/select.js +1 -1
  51. package/dist/prompts/slider.d.ts +1 -1
  52. package/dist/prompts/slider.js +1 -1
  53. package/dist/prompts/snippet.d.ts +18 -0
  54. package/dist/prompts/snippet.js +203 -0
  55. package/dist/prompts/sort.d.ts +1 -1
  56. package/dist/prompts/sort.js +1 -4
  57. package/dist/prompts/spam.d.ts +17 -0
  58. package/dist/prompts/spam.js +62 -0
  59. package/dist/prompts/table.d.ts +1 -1
  60. package/dist/prompts/table.js +1 -1
  61. package/dist/prompts/text.d.ts +1 -0
  62. package/dist/prompts/text.js +14 -32
  63. package/dist/prompts/toggle.d.ts +1 -1
  64. package/dist/prompts/toggle.js +1 -1
  65. package/dist/prompts/transfer.d.ts +18 -0
  66. package/dist/prompts/transfer.js +203 -0
  67. package/dist/prompts/tree-select.d.ts +32 -0
  68. package/dist/prompts/tree-select.js +277 -0
  69. package/dist/prompts/tree.d.ts +20 -0
  70. package/dist/prompts/tree.js +231 -0
  71. package/dist/prompts/wait.d.ts +18 -0
  72. package/dist/prompts/wait.js +62 -0
  73. package/dist/types.d.ts +105 -0
  74. package/dist/utils.js +6 -2
  75. package/example.ts +213 -27
  76. package/package.json +14 -4
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnippetPrompt = void 0;
4
+ const ansi_1 = require("../ansi");
5
+ const base_1 = require("../base");
6
+ const theme_1 = require("../theme");
7
+ class SnippetPrompt extends base_1.Prompt {
8
+ constructor(options) {
9
+ super(options);
10
+ this.tokens = [];
11
+ this.variableTokens = []; // Indices in this.tokens
12
+ this.values = {};
13
+ this.activeVarIndex = 0; // Index in variableTokens
14
+ this.cursor = 0; // Cursor in active variable value
15
+ this.errorMsg = '';
16
+ this.lastLinesUp = 0;
17
+ this.parseTemplate();
18
+ // Initialize values
19
+ if (options.values) {
20
+ this.values = { ...options.values };
21
+ }
22
+ // Ensure all vars have entries
23
+ this.variableTokens.forEach(idx => {
24
+ const varName = this.tokens[idx].value;
25
+ if (this.values[varName] === undefined) {
26
+ this.values[varName] = '';
27
+ }
28
+ });
29
+ if (this.variableTokens.length > 0) {
30
+ const firstVar = this.tokens[this.variableTokens[0]].value;
31
+ this.cursor = this.values[firstVar].length;
32
+ }
33
+ }
34
+ parseTemplate() {
35
+ const regex = /\$\{([a-zA-Z0-9_]+)\}/g;
36
+ let lastIndex = 0;
37
+ let match;
38
+ while ((match = regex.exec(this.options.template)) !== null) {
39
+ if (match.index > lastIndex) {
40
+ this.tokens.push({ type: 'static', value: this.options.template.substring(lastIndex, match.index) });
41
+ }
42
+ this.tokens.push({ type: 'variable', value: match[1] });
43
+ this.variableTokens.push(this.tokens.length - 1);
44
+ lastIndex = regex.lastIndex;
45
+ }
46
+ if (lastIndex < this.options.template.length) {
47
+ this.tokens.push({ type: 'static', value: this.options.template.substring(lastIndex) });
48
+ }
49
+ }
50
+ render(firstRender) {
51
+ if (!firstRender && this.lastLinesUp > 0) {
52
+ this.print(`\x1b[${this.lastLinesUp}B`);
53
+ }
54
+ this.lastLinesUp = 0;
55
+ // Build the string
56
+ let output = '';
57
+ let cursorVisualIndex = 0;
58
+ let currentVisualIndex = 0;
59
+ // Prefix/Message
60
+ const prefix = `${theme_1.theme.success}? ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message || 'Fill snippet'}${ansi_1.ANSI.RESET}\n`;
61
+ output += prefix;
62
+ // cursorVisualIndex should start after prefix?
63
+ // Actually renderFrame handles newlines.
64
+ // We will construct the snippet line.
65
+ let snippetLine = '';
66
+ this.tokens.forEach((token, index) => {
67
+ if (token.type === 'static') {
68
+ snippetLine += `${theme_1.theme.muted}${token.value}${ansi_1.ANSI.RESET}`;
69
+ currentVisualIndex += token.value.length; // assuming simple ascii/static length
70
+ }
71
+ else {
72
+ const isFocused = this.variableTokens[this.activeVarIndex] === index;
73
+ const val = this.values[token.value] || '';
74
+ // Placeholder if empty?
75
+ const displayVal = val.length === 0 && isFocused ? '' : val; // maybe show placeholder?
76
+ let styledVal = displayVal;
77
+ if (isFocused) {
78
+ styledVal = `${ansi_1.ANSI.UNDERLINE}${theme_1.theme.main}${displayVal}${ansi_1.ANSI.RESET}`;
79
+ // Calculate cursor position
80
+ cursorVisualIndex = currentVisualIndex + this.cursor;
81
+ }
82
+ else {
83
+ styledVal = `${theme_1.theme.main}${displayVal}${ansi_1.ANSI.RESET}`;
84
+ }
85
+ snippetLine += styledVal;
86
+ currentVisualIndex += displayVal.length;
87
+ }
88
+ });
89
+ output += snippetLine;
90
+ if (this.errorMsg) {
91
+ output += `\n${theme_1.theme.error}>> ${this.errorMsg}${ansi_1.ANSI.RESET}`;
92
+ }
93
+ output += `\n${theme_1.theme.muted}(Tab to next variable, Enter to submit)${ansi_1.ANSI.RESET}`;
94
+ this.renderFrame(output);
95
+ // Position Cursor
96
+ this.print(ansi_1.ANSI.SHOW_CURSOR);
97
+ // We need to move to correct line and column
98
+ // Lines:
99
+ // 1. Message
100
+ // 2. Snippet (cursor here)
101
+ // 3. Error (optional)
102
+ // 4. Hint
103
+ // snippetLine is at index 1 (0-based) if Message has no newlines.
104
+ // Prefix ends with \n. So snippetLine is on 2nd line.
105
+ // Calculate which row relative to bottom the snippet line is.
106
+ // If error: 4 lines total. Snippet is line 1 (2nd). Lines up = 2.
107
+ // If no error: 3 lines total. Snippet is line 1. Lines up = 1.
108
+ let linesUp = 1;
109
+ if (this.errorMsg)
110
+ linesUp++;
111
+ if (linesUp > 0) {
112
+ this.print(`\x1b[${linesUp}A`);
113
+ this.lastLinesUp = linesUp;
114
+ }
115
+ this.print(ansi_1.ANSI.CURSOR_LEFT);
116
+ if (cursorVisualIndex > 0) {
117
+ this.print(`\x1b[${cursorVisualIndex}C`);
118
+ }
119
+ }
120
+ handleInput(char, _key) {
121
+ // Navigation: Tab / Shift+Tab
122
+ if (char === '\u001b[Z') {
123
+ // Shift Tab -> Prev
124
+ this.moveFocus(-1);
125
+ return;
126
+ }
127
+ if (char === '\t') {
128
+ this.moveFocus(1);
129
+ return;
130
+ }
131
+ // Enter
132
+ if (char === '\r' || char === '\n') {
133
+ this.submitSnippet();
134
+ return;
135
+ }
136
+ // Editing
137
+ const activeTokenIdx = this.variableTokens[this.activeVarIndex];
138
+ const varName = this.tokens[activeTokenIdx].value;
139
+ const val = this.values[varName];
140
+ if (char === '\u0008' || char === '\x7f') { // Backspace
141
+ if (this.cursor > 0) {
142
+ const pre = val.slice(0, this.cursor - 1);
143
+ const post = val.slice(this.cursor);
144
+ this.values[varName] = pre + post;
145
+ this.cursor--;
146
+ this.render(false);
147
+ }
148
+ return;
149
+ }
150
+ if (this.isLeft(char)) {
151
+ if (this.cursor > 0)
152
+ this.cursor--;
153
+ this.render(false);
154
+ return;
155
+ }
156
+ if (this.isRight(char)) {
157
+ if (this.cursor < val.length)
158
+ this.cursor++;
159
+ this.render(false);
160
+ return;
161
+ }
162
+ if (!/^[\x00-\x1F]/.test(char) && !char.startsWith('\x1b')) {
163
+ const pre = val.slice(0, this.cursor);
164
+ const post = val.slice(this.cursor);
165
+ this.values[varName] = pre + char + post;
166
+ this.cursor += char.length;
167
+ this.render(false);
168
+ }
169
+ }
170
+ handleMouse(event) {
171
+ if (event.action === 'scroll') {
172
+ if (event.scroll === 'up') {
173
+ this.moveFocus(-1);
174
+ }
175
+ else if (event.scroll === 'down') {
176
+ this.moveFocus(1);
177
+ }
178
+ }
179
+ }
180
+ moveFocus(direction) {
181
+ const nextIndex = this.activeVarIndex + direction;
182
+ if (nextIndex >= 0 && nextIndex < this.variableTokens.length) {
183
+ this.activeVarIndex = nextIndex;
184
+ const varName = this.tokens[this.variableTokens[this.activeVarIndex]].value;
185
+ this.cursor = this.values[varName].length;
186
+ this.render(false);
187
+ }
188
+ }
189
+ submitSnippet() {
190
+ // Construct final string
191
+ let result = '';
192
+ this.tokens.forEach(token => {
193
+ if (token.type === 'static') {
194
+ result += token.value;
195
+ }
196
+ else {
197
+ result += this.values[token.value] || '';
198
+ }
199
+ });
200
+ this.submit(result);
201
+ }
202
+ }
203
+ exports.SnippetPrompt = SnippetPrompt;
@@ -7,7 +7,7 @@ export declare class SortPrompt extends Prompt<string[], SortOptions> {
7
7
  private scrollTop;
8
8
  private readonly pageSize;
9
9
  constructor(options: SortOptions);
10
- protected render(firstRender: boolean): void;
10
+ protected render(_firstRender: boolean): void;
11
11
  protected handleInput(char: string): void;
12
12
  private swap;
13
13
  protected handleMouse(event: MouseEvent): void;
@@ -14,7 +14,7 @@ class SortPrompt extends base_1.Prompt {
14
14
  this.pageSize = 10;
15
15
  this.items = [...options.items];
16
16
  }
17
- render(firstRender) {
17
+ render(_firstRender) {
18
18
  // Adjust Scroll Top
19
19
  if (this.selectedIndex < this.scrollTop) {
20
20
  this.scrollTop = this.selectedIndex;
@@ -120,9 +120,6 @@ class SortPrompt extends base_1.Prompt {
120
120
  swap(i, j) {
121
121
  [this.items[i], this.items[j]] = [this.items[j], this.items[i]];
122
122
  }
123
- // Mouse support?
124
- // Drag and drop is hard with just clicks/scroll.
125
- // Maybe click to grab, scroll to move?
126
123
  handleMouse(event) {
127
124
  // Simple scroll support for navigation
128
125
  if (event.action === 'scroll') {
@@ -0,0 +1,17 @@
1
+ import { Prompt } from '../base';
2
+ import { BaseOptions } from '../types';
3
+ interface SpamOptions extends BaseOptions {
4
+ threshold: number;
5
+ spamKey?: string;
6
+ decay?: boolean;
7
+ }
8
+ export declare class SpamPrompt extends Prompt<boolean, SpamOptions> {
9
+ private count;
10
+ private width;
11
+ private decayTimer?;
12
+ constructor(options: SpamOptions);
13
+ protected cleanup(): void;
14
+ protected render(_firstRender: boolean): void;
15
+ protected handleInput(char: string): void;
16
+ }
17
+ export {};
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpamPrompt = void 0;
4
+ const ansi_1 = require("../ansi");
5
+ const base_1 = require("../base");
6
+ const theme_1 = require("../theme");
7
+ const symbols_1 = require("../symbols");
8
+ class SpamPrompt extends base_1.Prompt {
9
+ constructor(options) {
10
+ super(options);
11
+ this.count = 0;
12
+ this.width = 20; // Visual width of the bar
13
+ if (options.decay) {
14
+ this.decayTimer = setInterval(() => {
15
+ if (this.count > 0) {
16
+ this.count = Math.max(0, this.count - 1);
17
+ this.render(false);
18
+ }
19
+ }, 200); // Drop 5 presses per second
20
+ }
21
+ }
22
+ cleanup() {
23
+ if (this.decayTimer)
24
+ clearInterval(this.decayTimer);
25
+ super.cleanup();
26
+ }
27
+ render(_firstRender) {
28
+ const progress = Math.min(this.count / this.options.threshold, 1);
29
+ const filledLen = Math.round(progress * this.width);
30
+ const emptyLen = this.width - filledLen;
31
+ // Visual Bar: [#####-----]
32
+ const filled = symbols_1.symbols.line.repeat(filledLen).replace(/./g, '#'); // Or use block char
33
+ const empty = symbols_1.symbols.line.repeat(emptyLen);
34
+ const barColor = progress === 1 ? theme_1.theme.success : theme_1.theme.error;
35
+ const bar = `${theme_1.theme.muted}[${barColor}${filled}${theme_1.theme.muted}${empty}]${ansi_1.ANSI.RESET}`;
36
+ let output = `${theme_1.theme.error}${symbols_1.symbols.cross} ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET}\n`;
37
+ output += ` ${bar} ${Math.floor(progress * 100)}%`;
38
+ if (this.count >= this.options.threshold) {
39
+ output += ` ${theme_1.theme.success} READY! Press Enter${ansi_1.ANSI.RESET}`;
40
+ }
41
+ else {
42
+ output += ` ${theme_1.theme.muted}(Mash '${this.options.spamKey || 'Space'}' to fill)${ansi_1.ANSI.RESET}`;
43
+ }
44
+ this.renderFrame(output);
45
+ }
46
+ handleInput(char) {
47
+ // Confirm execution
48
+ if (this.count >= this.options.threshold && (char === '\r' || char === '\n')) {
49
+ this.submit(true);
50
+ return;
51
+ }
52
+ const trigger = this.options.spamKey || ' ';
53
+ // Check if key matches (or any key if not specified)
54
+ if (char === trigger) {
55
+ if (this.count < this.options.threshold) {
56
+ this.count++;
57
+ this.render(false);
58
+ }
59
+ }
60
+ }
61
+ }
62
+ exports.SpamPrompt = SpamPrompt;
@@ -7,7 +7,7 @@ export declare class TablePrompt<V> extends Prompt<V, TableOptions<V>> {
7
7
  private colWidths;
8
8
  constructor(options: TableOptions<V>);
9
9
  private calculateColWidths;
10
- protected render(firstRender: boolean): void;
10
+ protected render(_firstRender: boolean): void;
11
11
  private pad;
12
12
  protected handleInput(char: string): void;
13
13
  protected handleMouse(event: MouseEvent): void;
@@ -28,7 +28,7 @@ class TablePrompt extends base_1.Prompt {
28
28
  // Add padding
29
29
  this.colWidths = this.colWidths.map(w => w + 2);
30
30
  }
31
- render(firstRender) {
31
+ render(_firstRender) {
32
32
  // Scroll Logic
33
33
  if (this.selectedIndex < this.scrollTop) {
34
34
  this.scrollTop = this.selectedIndex;
@@ -5,6 +5,7 @@ export declare class TextPrompt extends Prompt<string, TextOptions> {
5
5
  private cursor;
6
6
  private hasTyped;
7
7
  private segments;
8
+ private lastLinesUp;
8
9
  constructor(options: TextOptions);
9
10
  protected render(firstRender: boolean): void;
10
11
  private getSegmentWidth;
@@ -15,14 +15,18 @@ class TextPrompt extends base_1.Prompt {
15
15
  this.cursor = 0;
16
16
  this.hasTyped = false;
17
17
  this.segments = [];
18
+ this.lastLinesUp = 0;
18
19
  this.value = options.initial || '';
19
20
  // Initialize segments from value
20
21
  this.segments = (0, utils_1.safeSplit)(this.value);
21
22
  this.cursor = this.segments.length;
22
23
  }
23
24
  render(firstRender) {
25
+ if (!firstRender && this.lastLinesUp > 0) {
26
+ this.print(`\x1b[${this.lastLinesUp}B`);
27
+ }
28
+ this.lastLinesUp = 0;
24
29
  // Calculate available width
25
- const cols = process.stdout.columns || 80;
26
30
  // 1. Prepare Prompt Label
27
31
  const icon = this.errorMsg ? `${theme_1.theme.error}${symbols_1.symbols.cross}` : `${theme_1.theme.success}?`;
28
32
  const hint = this.options.multiline ? ` ${theme_1.theme.muted}(Press Ctrl+D to submit)${ansi_1.ANSI.RESET}` : '';
@@ -43,31 +47,16 @@ class TextPrompt extends base_1.Prompt {
43
47
  cursorRelativeCol = 0;
44
48
  }
45
49
  else {
46
- const rawValue = this.options.isPassword ? '*'.repeat(this.segments.length) : this.value;
50
+ const maskChar = this.options.mask ?? (this.options.isPassword ? '*' : undefined);
47
51
  // Note: password masking replaces each grapheme with '*'
48
52
  // Split by lines (for multiline support)
49
- const lines = rawValue.split('\n');
50
53
  // Determine which line the cursor is on
51
54
  // We need to map 'cursor' (segments index) to line/col.
52
55
  // This is tricky because segments might contain '\n'.
53
56
  // safeSplit treats '\n' as a segment.
54
57
  let cursorLineIndex = 0;
55
- let cursorSegmentIndexOnLine = 0;
56
- let currentSegmentIndex = 0;
57
- for (let i = 0; i < lines.length; i++) {
58
- // How many segments in this line?
59
- // We can't just use lines[i].length because that's chars.
60
- // We need to split the line again or iterate segments.
61
- // Iterating segments is safer.
62
- // Let's assume we iterate global segments until we hit a newline segment
63
- let lineSegmentsCount = 0;
64
- // Since rawValue.split('\n') consumes the newlines, we need to account for them.
65
- // Alternative: iterate this.segments
66
- // Find where the cursor falls.
67
- }
68
58
  // Let's iterate segments to find cursor position (row, col)
69
59
  cursorLineIndex = 0;
70
- let colIndex = 0; // Visual column or char index?
71
60
  // If we want visual cursor position, we need visual width of segments.
72
61
  let visualColIndex = 0;
73
62
  for (let i = 0; i < this.cursor; i++) {
@@ -77,11 +66,11 @@ class TextPrompt extends base_1.Prompt {
77
66
  visualColIndex = 0;
78
67
  }
79
68
  else {
80
- if (this.options.isPassword) {
81
- visualColIndex += 1;
69
+ if (maskChar !== undefined) {
70
+ visualColIndex += maskChar.length;
82
71
  }
83
72
  else {
84
- visualColIndex += this.options.isPassword ? 1 : this.getSegmentWidth(seg);
73
+ visualColIndex += this.getSegmentWidth(seg);
85
74
  }
86
75
  }
87
76
  }
@@ -90,7 +79,7 @@ class TextPrompt extends base_1.Prompt {
90
79
  // Now prepare lines for display (scrolling/truncation)
91
80
  // We need to reconstruct lines from segments to apply styling/truncation logic per line.
92
81
  let currentLineSegments = [];
93
- let processedLines = []; // Array of segment arrays
82
+ const processedLines = []; // Array of segment arrays
94
83
  for (const seg of this.segments) {
95
84
  if (seg === '\n') {
96
85
  processedLines.push(currentLineSegments);
@@ -101,24 +90,16 @@ class TextPrompt extends base_1.Prompt {
101
90
  }
102
91
  }
103
92
  processedLines.push(currentLineSegments); // Last line
104
- processedLines.forEach((lineSegs, idx) => {
105
- const isCursorLine = idx === cursorLineIndex;
106
- const linePrefixLen = (idx === 0) ? prefixVisualLen : 0;
107
- const maxContentLen = Math.max(10, cols - linePrefixLen - 1);
93
+ processedLines.forEach((lineSegs) => {
108
94
  // Reconstruct line string for display calculation
109
95
  // If password, join with *?
110
96
  let visibleLine = '';
111
- if (this.options.isPassword) {
112
- visibleLine = '*'.repeat(lineSegs.length);
97
+ if (maskChar !== undefined) {
98
+ visibleLine = maskChar.repeat(lineSegs.length);
113
99
  }
114
100
  else {
115
101
  visibleLine = lineSegs.join('');
116
102
  }
117
- // If this is cursor line, we need to handle horizontal scroll based on cursorRelativeCol.
118
- // But cursorRelativeCol is global? No, we reset it on newline.
119
- // So cursorRelativeCol above was correct for the current line.
120
- if (isCursorLine) {
121
- }
122
103
  displayValueLines.push(theme_1.theme.main + visibleLine + ansi_1.ANSI.RESET);
123
104
  });
124
105
  }
@@ -145,6 +126,7 @@ class TextPrompt extends base_1.Prompt {
145
126
  if (linesUp > 0) {
146
127
  this.print(`\x1b[${linesUp}A`);
147
128
  }
129
+ this.lastLinesUp = linesUp;
148
130
  let targetCol = 0;
149
131
  if (cursorRelativeRow === 0) {
150
132
  targetCol = prefixVisualLen + cursorRelativeCol;
@@ -2,7 +2,7 @@ import { Prompt } from '../base';
2
2
  import { ToggleOptions, MouseEvent } from '../types';
3
3
  export declare class TogglePrompt extends Prompt<boolean, ToggleOptions> {
4
4
  constructor(options: ToggleOptions);
5
- protected render(firstRender: boolean): void;
5
+ protected render(_firstRender: boolean): void;
6
6
  protected handleInput(char: string): void;
7
7
  protected handleMouse(event: MouseEvent): void;
8
8
  }
@@ -10,7 +10,7 @@ class TogglePrompt extends base_1.Prompt {
10
10
  super(options);
11
11
  this.value = options.initial ?? false;
12
12
  }
13
- render(firstRender) {
13
+ render(_firstRender) {
14
14
  const activeText = this.options.activeText || 'ON';
15
15
  const inactiveText = this.options.inactiveText || 'OFF';
16
16
  let toggleDisplay = '';
@@ -0,0 +1,18 @@
1
+ import { Prompt } from '../base';
2
+ import { TransferOptions, MouseEvent } from '../types';
3
+ export declare class TransferPrompt<V> extends Prompt<[V[], V[]], TransferOptions<V>> {
4
+ private leftList;
5
+ private rightList;
6
+ private cursorLeft;
7
+ private cursorRight;
8
+ private scrollTopLeft;
9
+ private scrollTopRight;
10
+ private activeSide;
11
+ private readonly pageSize;
12
+ constructor(options: TransferOptions<V>);
13
+ private normalize;
14
+ protected truncate(str: string, width: number): string;
15
+ protected render(_firstRender: boolean): void;
16
+ protected handleInput(char: string): void;
17
+ protected handleMouse(event: MouseEvent): void;
18
+ }