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.
- package/LICENSE +21 -21
- package/README.md +512 -326
- package/dist/ansi.d.ts +8 -0
- package/dist/ansi.js +8 -0
- package/dist/base.d.ts +21 -0
- package/dist/base.js +57 -0
- package/dist/core.d.ts +48 -1
- package/dist/core.js +156 -0
- package/dist/data/licenses.d.ts +2 -0
- package/dist/data/licenses.js +109 -0
- package/dist/highlight.js +58 -26
- package/dist/index.d.ts +36 -0
- package/dist/index.js +36 -0
- package/dist/input.js +0 -3
- package/dist/prompts/box.d.ts +21 -0
- package/dist/prompts/box.js +192 -0
- package/dist/prompts/breadcrumb.d.ts +22 -0
- package/dist/prompts/breadcrumb.js +302 -0
- package/dist/prompts/byte.d.ts +13 -0
- package/dist/prompts/byte.js +159 -0
- package/dist/prompts/calculator.d.ts +16 -0
- package/dist/prompts/calculator.js +213 -0
- package/dist/prompts/calendar.js +0 -5
- package/dist/prompts/code.d.ts +2 -0
- package/dist/prompts/code.js +104 -70
- package/dist/prompts/connection-string.d.ts +18 -0
- package/dist/prompts/connection-string.js +97 -0
- package/dist/prompts/curl.d.ts +39 -0
- package/dist/prompts/curl.js +285 -0
- package/dist/prompts/data-inspector.d.ts +22 -0
- package/dist/prompts/data-inspector.js +256 -0
- package/dist/prompts/dependency.d.ts +16 -0
- package/dist/prompts/dependency.js +265 -0
- package/dist/prompts/dial.d.ts +10 -0
- package/dist/prompts/dial.js +110 -0
- package/dist/prompts/diff.d.ts +10 -0
- package/dist/prompts/diff.js +101 -0
- package/dist/prompts/draw.d.ts +20 -0
- package/dist/prompts/draw.js +188 -0
- package/dist/prompts/editor.js +0 -4
- package/dist/prompts/emoji.d.ts +18 -0
- package/dist/prompts/emoji.js +228 -0
- package/dist/prompts/exec.d.ts +13 -0
- package/dist/prompts/exec.js +83 -0
- package/dist/prompts/fuzzy.d.ts +12 -0
- package/dist/prompts/fuzzy.js +136 -0
- package/dist/prompts/gauge.d.ts +21 -0
- package/dist/prompts/gauge.js +130 -0
- package/dist/prompts/heatmap.d.ts +13 -0
- package/dist/prompts/heatmap.js +141 -0
- package/dist/prompts/ip.d.ts +11 -0
- package/dist/prompts/ip.js +118 -0
- package/dist/prompts/kanban.d.ts +17 -0
- package/dist/prompts/kanban.js +228 -0
- package/dist/prompts/keypress.js +0 -2
- package/dist/prompts/license.d.ts +9 -0
- package/dist/prompts/license.js +105 -0
- package/dist/prompts/map.d.ts +15 -0
- package/dist/prompts/map.js +199 -0
- package/dist/prompts/match.d.ts +19 -0
- package/dist/prompts/match.js +275 -0
- package/dist/prompts/miller.d.ts +15 -0
- package/dist/prompts/miller.js +221 -0
- package/dist/prompts/multi-column-select.d.ts +10 -0
- package/dist/prompts/multi-column-select.js +166 -0
- package/dist/prompts/number.js +0 -2
- package/dist/prompts/otp.d.ts +10 -0
- package/dist/prompts/otp.js +91 -0
- package/dist/prompts/pattern.d.ts +22 -0
- package/dist/prompts/pattern.js +249 -0
- package/dist/prompts/quiz-select.d.ts +10 -0
- package/dist/prompts/quiz-select.js +104 -0
- package/dist/prompts/quiz-text.d.ts +11 -0
- package/dist/prompts/quiz-text.js +82 -0
- package/dist/prompts/regex.d.ts +13 -0
- package/dist/prompts/regex.js +131 -0
- package/dist/prompts/region.d.ts +11 -0
- package/dist/prompts/region.js +164 -0
- package/dist/prompts/schedule.d.ts +18 -0
- package/dist/prompts/schedule.js +221 -0
- package/dist/prompts/scroll.d.ts +13 -0
- package/dist/prompts/scroll.js +152 -0
- package/dist/prompts/seat.d.ts +17 -0
- package/dist/prompts/seat.js +165 -0
- package/dist/prompts/select-range.d.ts +8 -0
- package/dist/prompts/select-range.js +136 -0
- package/dist/prompts/select.d.ts +9 -9
- package/dist/prompts/semver.d.ts +6 -0
- package/dist/prompts/semver.js +32 -0
- package/dist/prompts/shortcut.d.ts +9 -0
- package/dist/prompts/shortcut.js +135 -0
- package/dist/prompts/slot.d.ts +16 -0
- package/dist/prompts/slot.js +107 -0
- package/dist/prompts/snippet.js +0 -3
- package/dist/prompts/sort-grid.d.ts +16 -0
- package/dist/prompts/sort-grid.js +146 -0
- package/dist/prompts/sort.js +0 -1
- package/dist/prompts/spreadsheet.d.ts +21 -0
- package/dist/prompts/spreadsheet.js +239 -0
- package/dist/prompts/text.d.ts +9 -7
- package/dist/prompts/text.js +52 -0
- package/dist/prompts/time.d.ts +12 -0
- package/dist/prompts/time.js +202 -0
- package/dist/prompts/tree-select.d.ts +0 -1
- package/dist/prompts/tree-select.js +1 -5
- package/dist/symbols.d.ts +12 -0
- package/dist/symbols.js +14 -2
- package/dist/theme.js +10 -1
- package/dist/types.d.ts +264 -1
- package/dist/utils.d.ts +53 -0
- package/dist/utils.js +252 -0
- package/package.json +51 -47
- package/example.ts +0 -390
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KanbanPrompt = void 0;
|
|
4
|
+
const base_1 = require("../base");
|
|
5
|
+
const ansi_1 = require("../ansi");
|
|
6
|
+
const utils_1 = require("../utils");
|
|
7
|
+
class KanbanPrompt extends base_1.Prompt {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
super(options);
|
|
10
|
+
this.activeCol = 0;
|
|
11
|
+
this.activeRow = 0;
|
|
12
|
+
this.grabbed = false;
|
|
13
|
+
// Deep copy columns to avoid mutating original options during drag/drop
|
|
14
|
+
this.columns = JSON.parse(JSON.stringify(options.columns));
|
|
15
|
+
this.scrollStates = new Array(this.columns.length).fill(0);
|
|
16
|
+
}
|
|
17
|
+
render(_firstRender) {
|
|
18
|
+
const { columns } = this.stdout; // terminal width
|
|
19
|
+
const colCount = this.columns.length;
|
|
20
|
+
const colWidth = Math.floor(columns / colCount);
|
|
21
|
+
let output = '';
|
|
22
|
+
// Render Title
|
|
23
|
+
output += `${ansi_1.ANSI.FG_CYAN}${ansi_1.ANSI.BOLD}? ${this.options.message}${ansi_1.ANSI.RESET}\n`;
|
|
24
|
+
if (this.grabbed) {
|
|
25
|
+
output += `${ansi_1.ANSI.FG_YELLOW}(Grabbed) Move with arrows, Space to Drop${ansi_1.ANSI.RESET}\n`;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
output += `${ansi_1.ANSI.FG_GRAY}(Normal) Space to Grab, Arrows to Navigate, Enter to Submit${ansi_1.ANSI.RESET}\n`;
|
|
29
|
+
}
|
|
30
|
+
// Render Headers
|
|
31
|
+
const headers = this.columns.map((col, i) => {
|
|
32
|
+
const isSelected = i === this.activeCol;
|
|
33
|
+
const title = this.truncate(col.title, colWidth - 4);
|
|
34
|
+
const style = isSelected ? `${ansi_1.ANSI.FG_BLUE}${ansi_1.ANSI.BOLD}` : ansi_1.ANSI.BOLD;
|
|
35
|
+
return this.padCenter(title, colWidth, style);
|
|
36
|
+
});
|
|
37
|
+
output += headers.join('') + '\n';
|
|
38
|
+
// Render Separator
|
|
39
|
+
output += ansi_1.ANSI.FG_GRAY + '─'.repeat(columns) + ansi_1.ANSI.RESET + '\n';
|
|
40
|
+
// Render Rows
|
|
41
|
+
const viewportHeight = 10;
|
|
42
|
+
for (let r = 0; r < viewportHeight; r++) {
|
|
43
|
+
const rowLine = this.columns.map((col, cIndex) => {
|
|
44
|
+
const scrollTop = this.scrollStates[cIndex];
|
|
45
|
+
const itemIndex = r + scrollTop;
|
|
46
|
+
const item = col.items[itemIndex];
|
|
47
|
+
let content = '';
|
|
48
|
+
if (item) {
|
|
49
|
+
const isCursor = cIndex === this.activeCol && itemIndex === this.activeRow;
|
|
50
|
+
let prefix = ' ';
|
|
51
|
+
const suffix = ' ';
|
|
52
|
+
let style = '';
|
|
53
|
+
if (isCursor) {
|
|
54
|
+
if (this.grabbed) {
|
|
55
|
+
style = ansi_1.ANSI.BG_YELLOW + ansi_1.ANSI.FG_BLACK;
|
|
56
|
+
prefix = '>';
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
style = ansi_1.ANSI.FG_CYAN + ansi_1.ANSI.BOLD;
|
|
60
|
+
prefix = '>';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const title = this.truncate(item.title, colWidth - 4);
|
|
64
|
+
content = `${prefix} ${title}${suffix}`;
|
|
65
|
+
content = content.padEnd(colWidth);
|
|
66
|
+
const plain = `${prefix} ${title}${suffix}`.padEnd(colWidth);
|
|
67
|
+
if (style) {
|
|
68
|
+
content = style + plain + ansi_1.ANSI.RESET;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
content = plain;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
// Empty slot
|
|
76
|
+
content = ' '.repeat(colWidth);
|
|
77
|
+
}
|
|
78
|
+
return content;
|
|
79
|
+
}).join('');
|
|
80
|
+
output += rowLine + '\n';
|
|
81
|
+
}
|
|
82
|
+
this.renderFrame(output);
|
|
83
|
+
}
|
|
84
|
+
padCenter(str, width, style = '') {
|
|
85
|
+
const visibleLen = (0, utils_1.stringWidth)(str);
|
|
86
|
+
if (visibleLen >= width)
|
|
87
|
+
return style + str + ansi_1.ANSI.RESET;
|
|
88
|
+
const left = Math.floor((width - visibleLen) / 2);
|
|
89
|
+
const right = width - visibleLen - left;
|
|
90
|
+
return ' '.repeat(left) + style + str + ansi_1.ANSI.RESET + ' '.repeat(right);
|
|
91
|
+
}
|
|
92
|
+
handleMouse(event) {
|
|
93
|
+
if (event.action === 'scroll') {
|
|
94
|
+
if (this.grabbed) {
|
|
95
|
+
// Grabbed: Scroll moves Left/Right
|
|
96
|
+
if (event.scroll === 'up') {
|
|
97
|
+
// Up/Left
|
|
98
|
+
if (this.activeCol > 0) {
|
|
99
|
+
this.moveItemHorizontal(-1);
|
|
100
|
+
this.activeCol--;
|
|
101
|
+
this.clampRow();
|
|
102
|
+
this.ensureVisible();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else if (event.scroll === 'down') {
|
|
106
|
+
// Down/Right
|
|
107
|
+
if (this.activeCol < this.columns.length - 1) {
|
|
108
|
+
this.moveItemHorizontal(1);
|
|
109
|
+
this.activeCol++;
|
|
110
|
+
this.clampRow();
|
|
111
|
+
this.ensureVisible();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// Normal: Scroll moves Up/Down
|
|
117
|
+
if (event.scroll === 'up') {
|
|
118
|
+
if (this.activeRow > 0) {
|
|
119
|
+
this.activeRow--;
|
|
120
|
+
this.ensureVisible();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else if (event.scroll === 'down') {
|
|
124
|
+
const colLen = this.columns[this.activeCol].items.length;
|
|
125
|
+
if (this.activeRow < colLen - 1) {
|
|
126
|
+
this.activeRow++;
|
|
127
|
+
this.ensureVisible();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
this.render(false);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
handleInput(char, _key) {
|
|
135
|
+
if (char === '\r' || char === '\n') { // Enter
|
|
136
|
+
const result = {};
|
|
137
|
+
this.columns.forEach(c => {
|
|
138
|
+
result[c.id] = c.items;
|
|
139
|
+
});
|
|
140
|
+
this.submit(result);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (char === ' ') { // Space
|
|
144
|
+
this.grabbed = !this.grabbed;
|
|
145
|
+
this.render(false);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (this.isLeft(char)) {
|
|
149
|
+
if (this.activeCol > 0) {
|
|
150
|
+
if (this.grabbed) {
|
|
151
|
+
this.moveItemHorizontal(-1);
|
|
152
|
+
}
|
|
153
|
+
this.activeCol--;
|
|
154
|
+
this.clampRow();
|
|
155
|
+
this.ensureVisible();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
else if (this.isRight(char)) {
|
|
159
|
+
if (this.activeCol < this.columns.length - 1) {
|
|
160
|
+
if (this.grabbed) {
|
|
161
|
+
this.moveItemHorizontal(1);
|
|
162
|
+
}
|
|
163
|
+
this.activeCol++;
|
|
164
|
+
this.clampRow();
|
|
165
|
+
this.ensureVisible();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else if (this.isUp(char)) {
|
|
169
|
+
if (this.activeRow > 0) {
|
|
170
|
+
if (this.grabbed) {
|
|
171
|
+
// Swap with prev
|
|
172
|
+
const col = this.columns[this.activeCol];
|
|
173
|
+
const temp = col.items[this.activeRow];
|
|
174
|
+
col.items[this.activeRow] = col.items[this.activeRow - 1];
|
|
175
|
+
col.items[this.activeRow - 1] = temp;
|
|
176
|
+
}
|
|
177
|
+
this.activeRow--;
|
|
178
|
+
this.ensureVisible();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else if (this.isDown(char)) {
|
|
182
|
+
const colLen = this.columns[this.activeCol].items.length;
|
|
183
|
+
if (this.activeRow < colLen - 1) {
|
|
184
|
+
if (this.grabbed) {
|
|
185
|
+
// Swap with next
|
|
186
|
+
const col = this.columns[this.activeCol];
|
|
187
|
+
const temp = col.items[this.activeRow];
|
|
188
|
+
col.items[this.activeRow] = col.items[this.activeRow + 1];
|
|
189
|
+
col.items[this.activeRow + 1] = temp;
|
|
190
|
+
}
|
|
191
|
+
this.activeRow++;
|
|
192
|
+
this.ensureVisible();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
this.render(false);
|
|
196
|
+
}
|
|
197
|
+
moveItemHorizontal(direction) {
|
|
198
|
+
const sourceCol = this.columns[this.activeCol];
|
|
199
|
+
const targetCol = this.columns[this.activeCol + direction];
|
|
200
|
+
const item = sourceCol.items.splice(this.activeRow, 1)[0];
|
|
201
|
+
let targetIndex = this.activeRow;
|
|
202
|
+
if (targetIndex > targetCol.items.length) {
|
|
203
|
+
targetIndex = targetCol.items.length;
|
|
204
|
+
}
|
|
205
|
+
targetCol.items.splice(targetIndex, 0, item);
|
|
206
|
+
this.activeRow = targetIndex;
|
|
207
|
+
}
|
|
208
|
+
clampRow() {
|
|
209
|
+
const len = this.columns[this.activeCol].items.length;
|
|
210
|
+
if (len === 0) {
|
|
211
|
+
this.activeRow = 0;
|
|
212
|
+
}
|
|
213
|
+
else if (this.activeRow >= len) {
|
|
214
|
+
this.activeRow = len - 1;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
ensureVisible() {
|
|
218
|
+
const scrollTop = this.scrollStates[this.activeCol];
|
|
219
|
+
const viewportHeight = 10;
|
|
220
|
+
if (this.activeRow < scrollTop) {
|
|
221
|
+
this.scrollStates[this.activeCol] = this.activeRow;
|
|
222
|
+
}
|
|
223
|
+
else if (this.activeRow >= scrollTop + viewportHeight) {
|
|
224
|
+
this.scrollStates[this.activeCol] = this.activeRow - viewportHeight + 1;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
exports.KanbanPrompt = KanbanPrompt;
|
package/dist/prompts/keypress.js
CHANGED
|
@@ -18,8 +18,6 @@ class KeypressPrompt extends base_1.Prompt {
|
|
|
18
18
|
return 'space';
|
|
19
19
|
return k;
|
|
20
20
|
}).join('/');
|
|
21
|
-
// Only show hint if it's short enough to be helpful, or always?
|
|
22
|
-
// Let's always show it if provided, or maybe just dimmed.
|
|
23
21
|
output += ` ${theme_1.theme.muted}(${hint})${ansi_1.ANSI.RESET}`;
|
|
24
22
|
}
|
|
25
23
|
else {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SelectPrompt } from './select';
|
|
2
|
+
import { LicenseOptions } from '../types';
|
|
3
|
+
export declare class LicensePrompt extends SelectPrompt<string> {
|
|
4
|
+
private licenses;
|
|
5
|
+
constructor(options: LicenseOptions);
|
|
6
|
+
protected render(_firstRender: boolean): void;
|
|
7
|
+
private renderList;
|
|
8
|
+
private renderDetails;
|
|
9
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LicensePrompt = void 0;
|
|
4
|
+
const ansi_1 = require("../ansi");
|
|
5
|
+
const select_1 = require("./select");
|
|
6
|
+
const theme_1 = require("../theme");
|
|
7
|
+
const symbols_1 = require("../symbols");
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
const licenses_1 = require("../data/licenses");
|
|
10
|
+
class LicensePrompt extends select_1.SelectPrompt {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
// Map licenses to choices expected by SelectPrompt
|
|
13
|
+
const choices = licenses_1.POPULAR_LICENSES.map(l => ({
|
|
14
|
+
title: l.id,
|
|
15
|
+
value: l.id,
|
|
16
|
+
description: l.name
|
|
17
|
+
}));
|
|
18
|
+
super({
|
|
19
|
+
...options,
|
|
20
|
+
choices
|
|
21
|
+
});
|
|
22
|
+
this.licenses = licenses_1.POPULAR_LICENSES;
|
|
23
|
+
// Set initial selection if provided
|
|
24
|
+
if (options.defaultLicense) {
|
|
25
|
+
const idx = this.licenses.findIndex(l => l.id === options.defaultLicense);
|
|
26
|
+
if (idx !== -1) {
|
|
27
|
+
this.selectedIndex = idx;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
render(_firstRender) {
|
|
32
|
+
const width = this.stdout.columns || 80;
|
|
33
|
+
const gap = 2;
|
|
34
|
+
const ratio = 0.3;
|
|
35
|
+
// Calculate dimensions
|
|
36
|
+
// Left column: 30% or min 20 chars
|
|
37
|
+
// Right column: rest
|
|
38
|
+
const leftWidth = Math.floor((width - gap) * ratio);
|
|
39
|
+
const rightWidth = width - leftWidth - gap;
|
|
40
|
+
const leftContent = this.renderList();
|
|
41
|
+
const rightContent = this.renderDetails(rightWidth);
|
|
42
|
+
const content = utils_1.Layout.split(leftContent, rightContent, width, { ratio, gap });
|
|
43
|
+
// Header
|
|
44
|
+
const header = `${theme_1.theme.success}? ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET} ${theme_1.theme.muted}(Use arrows to navigate, Enter to select)${ansi_1.ANSI.RESET}`;
|
|
45
|
+
// Combine
|
|
46
|
+
this.renderFrame(`${header}\n${content}`);
|
|
47
|
+
}
|
|
48
|
+
renderList() {
|
|
49
|
+
const selectedIndex = this.selectedIndex;
|
|
50
|
+
const scrollTop = this.scrollTop;
|
|
51
|
+
const pageSize = this.pageSize;
|
|
52
|
+
const choices = this.options.choices; // from super
|
|
53
|
+
let output = '';
|
|
54
|
+
const visibleChoices = choices.slice(scrollTop, scrollTop + pageSize);
|
|
55
|
+
visibleChoices.forEach((choice, index) => {
|
|
56
|
+
const actualIndex = scrollTop + index;
|
|
57
|
+
const isSelected = actualIndex === selectedIndex;
|
|
58
|
+
const cursor = isSelected ? `${theme_1.theme.main}${symbols_1.symbols.pointer}` : ' ';
|
|
59
|
+
// Handle Separator type safety
|
|
60
|
+
if ('separator' in choice) {
|
|
61
|
+
output += `${theme_1.theme.muted}${choice.text || '---'}${ansi_1.ANSI.RESET}\n`;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const title = isSelected ? `${theme_1.theme.main}${choice.title}${ansi_1.ANSI.RESET}` : choice.title;
|
|
65
|
+
output += `${cursor} ${title}\n`;
|
|
66
|
+
});
|
|
67
|
+
// Fill remaining lines to maintain height
|
|
68
|
+
const filledLines = visibleChoices.length;
|
|
69
|
+
if (filledLines < pageSize) {
|
|
70
|
+
output += '\n'.repeat(pageSize - filledLines);
|
|
71
|
+
}
|
|
72
|
+
return output;
|
|
73
|
+
}
|
|
74
|
+
renderDetails(maxWidth) {
|
|
75
|
+
const selectedIndex = this.selectedIndex;
|
|
76
|
+
const license = this.licenses[selectedIndex];
|
|
77
|
+
if (!license)
|
|
78
|
+
return '';
|
|
79
|
+
let output = '';
|
|
80
|
+
output += `${ansi_1.ANSI.BOLD}${license.name}${ansi_1.ANSI.RESET}\n`;
|
|
81
|
+
const wrappedDesc = utils_1.Layout.wrap(license.description, maxWidth);
|
|
82
|
+
const coloredDesc = wrappedDesc.split('\n').map(line => `${theme_1.theme.muted}${line}${ansi_1.ANSI.RESET}`).join('\n');
|
|
83
|
+
output += `${coloredDesc}\n\n`;
|
|
84
|
+
// Permissions
|
|
85
|
+
if (license.permissions.length > 0) {
|
|
86
|
+
output += `${ansi_1.ANSI.FG_GREEN}Permissions:${ansi_1.ANSI.RESET}\n`;
|
|
87
|
+
license.permissions.forEach(p => output += ` ${theme_1.theme.success}${symbols_1.symbols.checked} ${p}${ansi_1.ANSI.RESET}\n`);
|
|
88
|
+
output += '\n';
|
|
89
|
+
}
|
|
90
|
+
// Conditions
|
|
91
|
+
if (license.conditions.length > 0) {
|
|
92
|
+
output += `${ansi_1.ANSI.FG_BLUE}Conditions:${ansi_1.ANSI.RESET}\n`;
|
|
93
|
+
// symbols.info doesn't exist, use 'i' or similar
|
|
94
|
+
license.conditions.forEach(c => output += ` ${ansi_1.ANSI.FG_BLUE}ℹ ${c}${ansi_1.ANSI.RESET}\n`);
|
|
95
|
+
output += '\n';
|
|
96
|
+
}
|
|
97
|
+
// Limitations
|
|
98
|
+
if (license.limitations.length > 0) {
|
|
99
|
+
output += `${ansi_1.ANSI.FG_RED}Limitations:${ansi_1.ANSI.RESET}\n`;
|
|
100
|
+
license.limitations.forEach(l => output += ` ${theme_1.theme.error}${symbols_1.symbols.cross} ${l}${ansi_1.ANSI.RESET}\n`);
|
|
101
|
+
}
|
|
102
|
+
return output;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.LicensePrompt = LicensePrompt;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Prompt } from '../base';
|
|
2
|
+
import { MapOptions, MouseEvent } from '../types';
|
|
3
|
+
export declare class MapPrompt extends Prompt<Record<string, string>, MapOptions> {
|
|
4
|
+
private items;
|
|
5
|
+
private rowIndex;
|
|
6
|
+
private colIndex;
|
|
7
|
+
private scrollTop;
|
|
8
|
+
private readonly pageSize;
|
|
9
|
+
private errorMsg;
|
|
10
|
+
constructor(options: MapOptions);
|
|
11
|
+
protected render(_firstRender: boolean): void;
|
|
12
|
+
private pad;
|
|
13
|
+
protected handleInput(char: string): void;
|
|
14
|
+
protected handleMouse(event: MouseEvent): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MapPrompt = 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
|
+
const utils_1 = require("../utils");
|
|
9
|
+
class MapPrompt extends base_1.Prompt {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
super(options);
|
|
12
|
+
this.items = [];
|
|
13
|
+
this.rowIndex = 0;
|
|
14
|
+
this.colIndex = 0; // 0: Key, 1: Value
|
|
15
|
+
this.scrollTop = 0;
|
|
16
|
+
this.pageSize = 7;
|
|
17
|
+
this.errorMsg = '';
|
|
18
|
+
if (options.initial) {
|
|
19
|
+
this.items = Object.entries(options.initial).map(([key, value]) => ({ key, value }));
|
|
20
|
+
}
|
|
21
|
+
if (this.items.length === 0) {
|
|
22
|
+
this.items.push({ key: '', value: '' });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
render(_firstRender) {
|
|
26
|
+
let output = '';
|
|
27
|
+
// Title
|
|
28
|
+
const icon = this.errorMsg ? `${theme_1.theme.error}${symbols_1.symbols.cross}` : `${theme_1.theme.success}?`;
|
|
29
|
+
output += `${icon} ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET}\n`;
|
|
30
|
+
// Layout Calculation
|
|
31
|
+
const maxKeyWidth = Math.max(5, // Minimum width
|
|
32
|
+
...this.items.map(item => (0, utils_1.stringWidth)(item.key))) + 2; // Padding
|
|
33
|
+
// Scrolling Logic
|
|
34
|
+
if (this.rowIndex < this.scrollTop) {
|
|
35
|
+
this.scrollTop = this.rowIndex;
|
|
36
|
+
}
|
|
37
|
+
else if (this.rowIndex >= this.scrollTop + this.pageSize) {
|
|
38
|
+
this.scrollTop = this.rowIndex - this.pageSize + 1;
|
|
39
|
+
}
|
|
40
|
+
// Clamping
|
|
41
|
+
const maxScroll = Math.max(0, this.items.length - this.pageSize);
|
|
42
|
+
this.scrollTop = Math.min(this.scrollTop, maxScroll);
|
|
43
|
+
// Header
|
|
44
|
+
const keyHeader = this.pad('Key', maxKeyWidth);
|
|
45
|
+
output += ` ${ansi_1.ANSI.BOLD}${keyHeader}Value${ansi_1.ANSI.RESET}\n`;
|
|
46
|
+
// Rows
|
|
47
|
+
const visibleItems = this.items.slice(this.scrollTop, this.scrollTop + this.pageSize);
|
|
48
|
+
visibleItems.forEach((item, index) => {
|
|
49
|
+
const actualIndex = this.scrollTop + index;
|
|
50
|
+
if (index > 0)
|
|
51
|
+
output += '\n';
|
|
52
|
+
const isRowActive = actualIndex === this.rowIndex;
|
|
53
|
+
const pointer = isRowActive ? `${theme_1.theme.main}${symbols_1.symbols.pointer}${ansi_1.ANSI.RESET} ` : ' ';
|
|
54
|
+
// Render Key
|
|
55
|
+
let keyStr = item.key;
|
|
56
|
+
if (isRowActive && this.colIndex === 0) {
|
|
57
|
+
keyStr = `${theme_1.theme.main}${ansi_1.ANSI.UNDERLINE}${keyStr}${ansi_1.ANSI.RESET}`;
|
|
58
|
+
}
|
|
59
|
+
// Adjust padding manually because ANSI codes mess up simple padEnd
|
|
60
|
+
const keyVisualWidth = (0, utils_1.stringWidth)(item.key);
|
|
61
|
+
const padding = ' '.repeat(Math.max(0, maxKeyWidth - keyVisualWidth));
|
|
62
|
+
// Render Value
|
|
63
|
+
let valStr = item.value;
|
|
64
|
+
if (isRowActive && this.colIndex === 1) {
|
|
65
|
+
valStr = `${theme_1.theme.main}${ansi_1.ANSI.UNDERLINE}${valStr || ' '}${ansi_1.ANSI.RESET}`;
|
|
66
|
+
}
|
|
67
|
+
output += `${pointer}${keyStr}${padding}${valStr}`;
|
|
68
|
+
});
|
|
69
|
+
// Instructions
|
|
70
|
+
output += `\n${ansi_1.ANSI.DIM}(Ctrl+N: Add, Ctrl+D: Del)${ansi_1.ANSI.RESET}`;
|
|
71
|
+
if (this.errorMsg) {
|
|
72
|
+
output += `\n${theme_1.theme.error}>> ${this.errorMsg}${ansi_1.ANSI.RESET}`;
|
|
73
|
+
}
|
|
74
|
+
this.renderFrame(output);
|
|
75
|
+
}
|
|
76
|
+
pad(str, width) {
|
|
77
|
+
const len = (0, utils_1.stringWidth)(str);
|
|
78
|
+
if (len >= width)
|
|
79
|
+
return str;
|
|
80
|
+
return str + ' '.repeat(width - len);
|
|
81
|
+
}
|
|
82
|
+
handleInput(char) {
|
|
83
|
+
this.errorMsg = '';
|
|
84
|
+
// Navigation
|
|
85
|
+
if (this.isUp(char)) {
|
|
86
|
+
if (this.rowIndex > 0)
|
|
87
|
+
this.rowIndex--;
|
|
88
|
+
this.render(false);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (this.isDown(char)) {
|
|
92
|
+
if (this.rowIndex < this.items.length - 1) {
|
|
93
|
+
this.rowIndex++;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// Down at last row adds new row
|
|
97
|
+
this.items.push({ key: '', value: '' });
|
|
98
|
+
this.rowIndex++;
|
|
99
|
+
this.colIndex = 0; // Optional: Reset to Key col when creating new row
|
|
100
|
+
}
|
|
101
|
+
this.render(false);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (char === '\t' || this.isRight(char) || this.isLeft(char)) {
|
|
105
|
+
// Toggle column
|
|
106
|
+
this.colIndex = this.colIndex === 0 ? 1 : 0;
|
|
107
|
+
this.render(false);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// CRUD
|
|
111
|
+
// Ctrl+N (Standard ASCII for Ctrl+N is \x0e)
|
|
112
|
+
if (char === '\x0e') {
|
|
113
|
+
this.items.push({ key: '', value: '' });
|
|
114
|
+
this.rowIndex = this.items.length - 1;
|
|
115
|
+
this.colIndex = 0;
|
|
116
|
+
this.render(false);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// Ctrl+D (Standard ASCII for Ctrl+D is \x04)
|
|
120
|
+
if (char === '\x04') {
|
|
121
|
+
if (this.items.length > 1) {
|
|
122
|
+
this.items.splice(this.rowIndex, 1);
|
|
123
|
+
if (this.rowIndex >= this.items.length) {
|
|
124
|
+
this.rowIndex = this.items.length - 1;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
// Clear the last remaining item instead of deleting it
|
|
129
|
+
this.items[0] = { key: '', value: '' };
|
|
130
|
+
}
|
|
131
|
+
this.render(false);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// Submit
|
|
135
|
+
if (char === '\r' || char === '\n') {
|
|
136
|
+
// Validate duplicates
|
|
137
|
+
const keys = this.items.map(i => i.key);
|
|
138
|
+
const duplicates = keys.filter((item, index) => keys.indexOf(item) !== index && item !== '');
|
|
139
|
+
if (duplicates.length > 0) {
|
|
140
|
+
this.errorMsg = `Duplicate keys found: ${duplicates.join(', ')}`;
|
|
141
|
+
this.render(false);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (keys.some(k => k === '')) {
|
|
145
|
+
this.errorMsg = 'Keys cannot be empty';
|
|
146
|
+
this.render(false);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const result = {};
|
|
150
|
+
this.items.forEach(item => {
|
|
151
|
+
result[item.key] = item.value;
|
|
152
|
+
});
|
|
153
|
+
this.submit(result);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// Backspace
|
|
157
|
+
if (char === '\u0008' || char === '\x7f') {
|
|
158
|
+
const item = this.items[this.rowIndex];
|
|
159
|
+
if (this.colIndex === 0) {
|
|
160
|
+
if (item.key.length > 0)
|
|
161
|
+
item.key = item.key.slice(0, -1);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
if (item.value.length > 0)
|
|
165
|
+
item.value = item.value.slice(0, -1);
|
|
166
|
+
}
|
|
167
|
+
this.render(false);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Typing
|
|
171
|
+
if (!/^[\x00-\x1F]/.test(char)) {
|
|
172
|
+
const item = this.items[this.rowIndex];
|
|
173
|
+
if (this.colIndex === 0) {
|
|
174
|
+
item.key += char;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
item.value += char;
|
|
178
|
+
}
|
|
179
|
+
this.render(false);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
handleMouse(event) {
|
|
183
|
+
if (event.action === 'scroll') {
|
|
184
|
+
if (event.scroll === 'up') {
|
|
185
|
+
if (this.rowIndex > 0) {
|
|
186
|
+
this.rowIndex--;
|
|
187
|
+
this.render(false);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else if (event.scroll === 'down') {
|
|
191
|
+
if (this.rowIndex < this.items.length - 1) {
|
|
192
|
+
this.rowIndex++;
|
|
193
|
+
this.render(false);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
exports.MapPrompt = MapPrompt;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Prompt } from '../base';
|
|
2
|
+
import { MatchOptions, MouseEvent } from '../types';
|
|
3
|
+
export declare class MatchPrompt extends Prompt<Record<string, any[]>, MatchOptions> {
|
|
4
|
+
private source;
|
|
5
|
+
private target;
|
|
6
|
+
private links;
|
|
7
|
+
private cursorSource;
|
|
8
|
+
private cursorTarget;
|
|
9
|
+
private scrollTopSource;
|
|
10
|
+
private scrollTopTarget;
|
|
11
|
+
private activeSide;
|
|
12
|
+
private pickedSourceIndex;
|
|
13
|
+
private readonly pageSize;
|
|
14
|
+
constructor(options: MatchOptions);
|
|
15
|
+
private normalize;
|
|
16
|
+
protected render(_firstRender: boolean): void;
|
|
17
|
+
protected handleInput(char: string): void;
|
|
18
|
+
protected handleMouse(event: MouseEvent): void;
|
|
19
|
+
}
|