@oakoliver/gum 1.0.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.
- package/LICENSE +22 -0
- package/dist/cjs/index.cjs +2161 -0
- package/dist/esm/cli.js +2033 -0
- package/dist/esm/index.js +2104 -0
- package/dist/types/cli.d.ts +7 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/commands/choose.d.ts +7 -0
- package/dist/types/commands/choose.d.ts.map +1 -0
- package/dist/types/commands/confirm.d.ts +7 -0
- package/dist/types/commands/confirm.d.ts.map +1 -0
- package/dist/types/commands/file.d.ts +7 -0
- package/dist/types/commands/file.d.ts.map +1 -0
- package/dist/types/commands/format.d.ts +7 -0
- package/dist/types/commands/format.d.ts.map +1 -0
- package/dist/types/commands/input.d.ts +7 -0
- package/dist/types/commands/input.d.ts.map +1 -0
- package/dist/types/commands/join.d.ts +7 -0
- package/dist/types/commands/join.d.ts.map +1 -0
- package/dist/types/commands/log.d.ts +7 -0
- package/dist/types/commands/log.d.ts.map +1 -0
- package/dist/types/commands/pager.d.ts +7 -0
- package/dist/types/commands/pager.d.ts.map +1 -0
- package/dist/types/commands/spin.d.ts +7 -0
- package/dist/types/commands/spin.d.ts.map +1 -0
- package/dist/types/commands/style.d.ts +7 -0
- package/dist/types/commands/style.d.ts.map +1 -0
- package/dist/types/commands/table.d.ts +7 -0
- package/dist/types/commands/table.d.ts.map +1 -0
- package/dist/types/commands/write.d.ts +7 -0
- package/dist/types/commands/write.d.ts.map +1 -0
- package/dist/types/fuzzy.d.ts +36 -0
- package/dist/types/fuzzy.d.ts.map +1 -0
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/internal/decode.d.ts +11 -0
- package/dist/types/internal/decode.d.ts.map +1 -0
- package/dist/types/internal/exit.d.ts +9 -0
- package/dist/types/internal/exit.d.ts.map +1 -0
- package/dist/types/internal/files.d.ts +9 -0
- package/dist/types/internal/files.d.ts.map +1 -0
- package/dist/types/internal/index.d.ts +7 -0
- package/dist/types/internal/index.d.ts.map +1 -0
- package/dist/types/internal/stdin.d.ts +21 -0
- package/dist/types/internal/stdin.d.ts.map +1 -0
- package/dist/types/internal/timeout.d.ts +18 -0
- package/dist/types/internal/timeout.d.ts.map +1 -0
- package/dist/types/internal/tty.d.ts +13 -0
- package/dist/types/internal/tty.d.ts.map +1 -0
- package/dist/types/parser.d.ts +36 -0
- package/dist/types/parser.d.ts.map +1 -0
- package/dist/types/style.d.ts +37 -0
- package/dist/types/style.d.ts.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,2161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
exactMatches: () => exactMatches,
|
|
34
|
+
extractStyleOptions: () => extractStyleOptions,
|
|
35
|
+
flagBool: () => flagBool,
|
|
36
|
+
flagInt: () => flagInt,
|
|
37
|
+
flagStr: () => flagStr,
|
|
38
|
+
flagWithEnv: () => flagWithEnv,
|
|
39
|
+
fuzzyFind: () => fuzzyFind,
|
|
40
|
+
fuzzyFindNoSort: () => fuzzyFindNoSort,
|
|
41
|
+
isStdinEmpty: () => isStdinEmpty,
|
|
42
|
+
listFiles: () => listFiles,
|
|
43
|
+
matchAll: () => matchAll,
|
|
44
|
+
matchedRanges: () => matchedRanges,
|
|
45
|
+
parseArgs: () => parseArgs,
|
|
46
|
+
parsePadding: () => parsePadding,
|
|
47
|
+
readStdin: () => readStdin,
|
|
48
|
+
runChoose: () => run,
|
|
49
|
+
runConfirm: () => run2,
|
|
50
|
+
runFile: () => run3,
|
|
51
|
+
runFormat: () => run4,
|
|
52
|
+
runInput: () => run5,
|
|
53
|
+
runJoin: () => run6,
|
|
54
|
+
runLog: () => run7,
|
|
55
|
+
runPager: () => run8,
|
|
56
|
+
runSpin: () => run9,
|
|
57
|
+
runStyle: () => run10,
|
|
58
|
+
runTable: () => run11,
|
|
59
|
+
runWrite: () => run12,
|
|
60
|
+
stripAnsi: () => stripAnsi,
|
|
61
|
+
toLipgloss: () => toLipgloss
|
|
62
|
+
});
|
|
63
|
+
module.exports = __toCommonJS(index_exports);
|
|
64
|
+
|
|
65
|
+
// src/fuzzy.ts
|
|
66
|
+
function fuzzyFind(pattern, choices) {
|
|
67
|
+
if (!pattern) return matchAll(choices);
|
|
68
|
+
const matches = [];
|
|
69
|
+
const lowerPattern = pattern.toLowerCase();
|
|
70
|
+
for (let i = 0; i < choices.length; i++) {
|
|
71
|
+
const choice = choices[i];
|
|
72
|
+
const result = fuzzyMatch(lowerPattern, choice);
|
|
73
|
+
if (result) {
|
|
74
|
+
matches.push({
|
|
75
|
+
str: choice,
|
|
76
|
+
index: i,
|
|
77
|
+
matchedIndexes: result.indexes,
|
|
78
|
+
score: result.score
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
matches.sort((a, b) => b.score - a.score);
|
|
83
|
+
return matches;
|
|
84
|
+
}
|
|
85
|
+
function fuzzyFindNoSort(pattern, choices) {
|
|
86
|
+
if (!pattern) return matchAll(choices);
|
|
87
|
+
const matches = [];
|
|
88
|
+
const lowerPattern = pattern.toLowerCase();
|
|
89
|
+
for (let i = 0; i < choices.length; i++) {
|
|
90
|
+
const choice = choices[i];
|
|
91
|
+
const result = fuzzyMatch(lowerPattern, choice);
|
|
92
|
+
if (result) {
|
|
93
|
+
matches.push({
|
|
94
|
+
str: choice,
|
|
95
|
+
index: i,
|
|
96
|
+
matchedIndexes: result.indexes,
|
|
97
|
+
score: result.score
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return matches;
|
|
102
|
+
}
|
|
103
|
+
function matchAll(choices) {
|
|
104
|
+
return choices.map((str, index) => ({
|
|
105
|
+
str,
|
|
106
|
+
index,
|
|
107
|
+
matchedIndexes: [],
|
|
108
|
+
score: 0
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
function exactMatches(search, choices) {
|
|
112
|
+
if (!search) return matchAll(choices);
|
|
113
|
+
const lowerSearch = search.toLowerCase();
|
|
114
|
+
const matches = [];
|
|
115
|
+
for (let i = 0; i < choices.length; i++) {
|
|
116
|
+
const choice = choices[i];
|
|
117
|
+
const lowerChoice = choice.toLowerCase();
|
|
118
|
+
const index = lowerChoice.indexOf(lowerSearch);
|
|
119
|
+
if (index >= 0) {
|
|
120
|
+
const matchedIndexes = [];
|
|
121
|
+
for (let s = 0; s < lowerSearch.length; s++) {
|
|
122
|
+
matchedIndexes.push(index + s);
|
|
123
|
+
}
|
|
124
|
+
matches.push({
|
|
125
|
+
str: choice,
|
|
126
|
+
index: i,
|
|
127
|
+
matchedIndexes,
|
|
128
|
+
score: 0
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return matches;
|
|
133
|
+
}
|
|
134
|
+
function fuzzyMatch(lowerPattern, str) {
|
|
135
|
+
const lowerStr = str.toLowerCase();
|
|
136
|
+
const indexes = [];
|
|
137
|
+
let score = 0;
|
|
138
|
+
let patternIdx = 0;
|
|
139
|
+
let prevMatchIdx = -1;
|
|
140
|
+
for (let i = 0; i < lowerStr.length && patternIdx < lowerPattern.length; i++) {
|
|
141
|
+
if (lowerStr[i] === lowerPattern[patternIdx]) {
|
|
142
|
+
indexes.push(i);
|
|
143
|
+
if (prevMatchIdx !== -1 && i === prevMatchIdx + 1) {
|
|
144
|
+
score += 4;
|
|
145
|
+
}
|
|
146
|
+
if (i === 0 || str[i - 1] === " " || str[i - 1] === "/" || str[i - 1] === "." || str[i - 1] === "-" || str[i - 1] === "_") {
|
|
147
|
+
score += 2;
|
|
148
|
+
}
|
|
149
|
+
if (str[i] === lowerPattern[patternIdx]) {
|
|
150
|
+
score += 1;
|
|
151
|
+
}
|
|
152
|
+
prevMatchIdx = i;
|
|
153
|
+
patternIdx++;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (patternIdx !== lowerPattern.length) return null;
|
|
157
|
+
return { indexes, score };
|
|
158
|
+
}
|
|
159
|
+
function matchedRanges(indexes) {
|
|
160
|
+
if (indexes.length === 0) return [];
|
|
161
|
+
let current = [indexes[0], indexes[0]];
|
|
162
|
+
if (indexes.length === 1) return [current];
|
|
163
|
+
const out = [];
|
|
164
|
+
for (let i = 1; i < indexes.length; i++) {
|
|
165
|
+
if (indexes[i] === current[1] + 1) {
|
|
166
|
+
current[1] = indexes[i];
|
|
167
|
+
} else {
|
|
168
|
+
out.push(current);
|
|
169
|
+
current = [indexes[i], indexes[i]];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
out.push(current);
|
|
173
|
+
return out;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/style.ts
|
|
177
|
+
var import_lipgloss = require("@oakoliver/lipgloss");
|
|
178
|
+
|
|
179
|
+
// src/internal/decode.ts
|
|
180
|
+
var alignMap = {
|
|
181
|
+
center: 0.5,
|
|
182
|
+
left: 0,
|
|
183
|
+
top: 0,
|
|
184
|
+
bottom: 1,
|
|
185
|
+
right: 1,
|
|
186
|
+
middle: 0.5
|
|
187
|
+
};
|
|
188
|
+
var borderMap = {
|
|
189
|
+
double: "double",
|
|
190
|
+
hidden: "hidden",
|
|
191
|
+
none: "none",
|
|
192
|
+
normal: "normal",
|
|
193
|
+
rounded: "rounded",
|
|
194
|
+
thick: "thick"
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// src/style.ts
|
|
198
|
+
function parsePadding(s) {
|
|
199
|
+
if (!s) return [0, 0, 0, 0];
|
|
200
|
+
const tokens = s.trim().split(/\s+/);
|
|
201
|
+
if (tokens.length > 4) return [0, 0, 0, 0];
|
|
202
|
+
const ints = [];
|
|
203
|
+
for (const token of tokens) {
|
|
204
|
+
const n = parseInt(token, 10);
|
|
205
|
+
if (isNaN(n)) return [0, 0, 0, 0];
|
|
206
|
+
ints.push(n);
|
|
207
|
+
}
|
|
208
|
+
if (ints.length === 1) return [ints[0], ints[0], ints[0], ints[0]];
|
|
209
|
+
if (ints.length === 2) return [ints[0], ints[1], ints[0], ints[1]];
|
|
210
|
+
if (ints.length === 4) return [ints[0], ints[1], ints[2], ints[3]];
|
|
211
|
+
return [0, 0, 0, 0];
|
|
212
|
+
}
|
|
213
|
+
function toLipgloss(opts) {
|
|
214
|
+
let s = (0, import_lipgloss.newStyle)();
|
|
215
|
+
if (opts.foreground) s = s.foreground(opts.foreground);
|
|
216
|
+
if (opts.background) s = s.background(opts.background);
|
|
217
|
+
if (opts.borderForeground) s = s.borderForeground(opts.borderForeground);
|
|
218
|
+
if (opts.borderBackground) s = s.borderBackground(opts.borderBackground);
|
|
219
|
+
if (opts.align && alignMap[opts.align] !== void 0) {
|
|
220
|
+
s = s.align(alignMap[opts.align]);
|
|
221
|
+
}
|
|
222
|
+
if (opts.border && borderMap[opts.border]) {
|
|
223
|
+
s = s.border(opts.border);
|
|
224
|
+
}
|
|
225
|
+
if (opts.height !== void 0 && opts.height > 0) s = s.height(opts.height);
|
|
226
|
+
if (opts.width !== void 0 && opts.width > 0) s = s.width(opts.width);
|
|
227
|
+
if (opts.margin) {
|
|
228
|
+
const [t, r, b, l] = parsePadding(opts.margin);
|
|
229
|
+
s = s.marginTop(t).marginRight(r).marginBottom(b).marginLeft(l);
|
|
230
|
+
}
|
|
231
|
+
if (opts.padding) {
|
|
232
|
+
const [t, r, b, l] = parsePadding(opts.padding);
|
|
233
|
+
s = s.paddingTop(t).paddingRight(r).paddingBottom(b).paddingLeft(l);
|
|
234
|
+
}
|
|
235
|
+
if (opts.bold) s = s.bold(true);
|
|
236
|
+
if (opts.faint) s = s.faint(true);
|
|
237
|
+
if (opts.italic) s = s.italic(true);
|
|
238
|
+
if (opts.strikethrough) s = s.strikethrough(true);
|
|
239
|
+
if (opts.underline) s = s.underline(true);
|
|
240
|
+
return s;
|
|
241
|
+
}
|
|
242
|
+
function extractStyleOptions(flags, prefix) {
|
|
243
|
+
const get = (key) => flags[`${prefix}.${key}`] ?? flags[`${prefix}-${key}`];
|
|
244
|
+
return {
|
|
245
|
+
foreground: get("foreground"),
|
|
246
|
+
background: get("background"),
|
|
247
|
+
border: get("border"),
|
|
248
|
+
borderBackground: get("border-background") ?? get("borderBackground"),
|
|
249
|
+
borderForeground: get("border-foreground") ?? get("borderForeground"),
|
|
250
|
+
align: get("align"),
|
|
251
|
+
height: get("height") !== void 0 ? parseInt(get("height"), 10) : void 0,
|
|
252
|
+
width: get("width") !== void 0 ? parseInt(get("width"), 10) : void 0,
|
|
253
|
+
margin: get("margin"),
|
|
254
|
+
padding: get("padding"),
|
|
255
|
+
bold: get("bold") === true || get("bold") === "true",
|
|
256
|
+
faint: get("faint") === true || get("faint") === "true",
|
|
257
|
+
italic: get("italic") === true || get("italic") === "true",
|
|
258
|
+
strikethrough: get("strikethrough") === true || get("strikethrough") === "true",
|
|
259
|
+
underline: get("underline") === true || get("underline") === "true"
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// src/parser.ts
|
|
264
|
+
var BOOL_FLAGS = /* @__PURE__ */ new Set([
|
|
265
|
+
"no-limit",
|
|
266
|
+
"no-show-help",
|
|
267
|
+
"no-strip-ansi",
|
|
268
|
+
"ordered",
|
|
269
|
+
"reverse",
|
|
270
|
+
"no-strict",
|
|
271
|
+
"strict",
|
|
272
|
+
"select-if-one",
|
|
273
|
+
"sort",
|
|
274
|
+
"no-sort",
|
|
275
|
+
"affirmative",
|
|
276
|
+
"negative",
|
|
277
|
+
"default",
|
|
278
|
+
"bold",
|
|
279
|
+
"faint",
|
|
280
|
+
"italic",
|
|
281
|
+
"strikethrough",
|
|
282
|
+
"underline",
|
|
283
|
+
"horizontal",
|
|
284
|
+
"vertical",
|
|
285
|
+
"show-line-numbers",
|
|
286
|
+
"soft-wrap",
|
|
287
|
+
"show-help",
|
|
288
|
+
"strip-ansi",
|
|
289
|
+
"cursor.bold",
|
|
290
|
+
"cursor.faint",
|
|
291
|
+
"cursor.italic",
|
|
292
|
+
"cursor.strikethrough",
|
|
293
|
+
"cursor.underline",
|
|
294
|
+
"header.bold",
|
|
295
|
+
"header.faint",
|
|
296
|
+
"header.italic",
|
|
297
|
+
"header.strikethrough",
|
|
298
|
+
"header.underline",
|
|
299
|
+
"selected.bold",
|
|
300
|
+
"selected.faint",
|
|
301
|
+
"selected.italic",
|
|
302
|
+
"selected.strikethrough",
|
|
303
|
+
"selected.underline",
|
|
304
|
+
"unselected.bold",
|
|
305
|
+
"unselected.faint",
|
|
306
|
+
"unselected.italic",
|
|
307
|
+
"unselected.strikethrough",
|
|
308
|
+
"unselected.underline",
|
|
309
|
+
"text.bold",
|
|
310
|
+
"text.faint",
|
|
311
|
+
"text.italic",
|
|
312
|
+
"text.strikethrough",
|
|
313
|
+
"text.underline",
|
|
314
|
+
"match.bold",
|
|
315
|
+
"match.faint",
|
|
316
|
+
"match.italic",
|
|
317
|
+
"match.strikethrough",
|
|
318
|
+
"match.underline",
|
|
319
|
+
"indicator.bold",
|
|
320
|
+
"indicator.faint",
|
|
321
|
+
"indicator.italic",
|
|
322
|
+
"indicator.strikethrough",
|
|
323
|
+
"indicator.underline",
|
|
324
|
+
"prompt.bold",
|
|
325
|
+
"prompt.faint",
|
|
326
|
+
"prompt.italic",
|
|
327
|
+
"prompt.strikethrough",
|
|
328
|
+
"prompt.underline",
|
|
329
|
+
"item.bold",
|
|
330
|
+
"item.faint",
|
|
331
|
+
"item.italic",
|
|
332
|
+
"item.strikethrough",
|
|
333
|
+
"item.underline",
|
|
334
|
+
"fuzzy",
|
|
335
|
+
"exact"
|
|
336
|
+
]);
|
|
337
|
+
function parseArgs(argv) {
|
|
338
|
+
if (argv.length === 0) {
|
|
339
|
+
return { command: "", flags: {}, args: [] };
|
|
340
|
+
}
|
|
341
|
+
const command = argv[0];
|
|
342
|
+
if (command === "--help" || command === "-h") {
|
|
343
|
+
return { command: "help", flags: {}, args: [] };
|
|
344
|
+
}
|
|
345
|
+
if (command === "--version" || command === "-v") {
|
|
346
|
+
return { command: "version", flags: {}, args: [] };
|
|
347
|
+
}
|
|
348
|
+
const flags = {};
|
|
349
|
+
const args = [];
|
|
350
|
+
let i = 1;
|
|
351
|
+
let pastFlags = false;
|
|
352
|
+
while (i < argv.length) {
|
|
353
|
+
const arg = argv[i];
|
|
354
|
+
if (pastFlags) {
|
|
355
|
+
args.push(arg);
|
|
356
|
+
i++;
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (arg === "--") {
|
|
360
|
+
pastFlags = true;
|
|
361
|
+
i++;
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (arg.startsWith("--")) {
|
|
365
|
+
const eqIndex = arg.indexOf("=");
|
|
366
|
+
if (eqIndex !== -1) {
|
|
367
|
+
const key = arg.substring(2, eqIndex);
|
|
368
|
+
const value = arg.substring(eqIndex + 1);
|
|
369
|
+
flags[key] = value;
|
|
370
|
+
i++;
|
|
371
|
+
} else {
|
|
372
|
+
const key = arg.substring(2);
|
|
373
|
+
if (key.startsWith("no-") && !BOOL_FLAGS.has(key)) {
|
|
374
|
+
const positiveKey = key.substring(3);
|
|
375
|
+
flags[positiveKey] = false;
|
|
376
|
+
i++;
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
if (isBoolFlag(key)) {
|
|
380
|
+
flags[key] = true;
|
|
381
|
+
i++;
|
|
382
|
+
} else if (i + 1 < argv.length && !argv[i + 1].startsWith("--")) {
|
|
383
|
+
flags[key] = argv[i + 1];
|
|
384
|
+
i += 2;
|
|
385
|
+
} else {
|
|
386
|
+
flags[key] = true;
|
|
387
|
+
i++;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
} else {
|
|
391
|
+
args.push(arg);
|
|
392
|
+
i++;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return { command, flags, args };
|
|
396
|
+
}
|
|
397
|
+
function isBoolFlag(key) {
|
|
398
|
+
if (BOOL_FLAGS.has(key)) return true;
|
|
399
|
+
const parts = key.split(".");
|
|
400
|
+
if (parts.length === 2) {
|
|
401
|
+
const suffix = parts[1];
|
|
402
|
+
if (["bold", "faint", "italic", "strikethrough", "underline"].includes(suffix)) {
|
|
403
|
+
return true;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
408
|
+
function flagStr(flags, key, defaultValue) {
|
|
409
|
+
const v = flags[key];
|
|
410
|
+
if (v === void 0) return defaultValue;
|
|
411
|
+
if (typeof v === "boolean") return String(v);
|
|
412
|
+
return v;
|
|
413
|
+
}
|
|
414
|
+
function flagInt(flags, key, defaultValue) {
|
|
415
|
+
const v = flags[key];
|
|
416
|
+
if (v === void 0) return defaultValue;
|
|
417
|
+
const n = parseInt(String(v), 10);
|
|
418
|
+
return isNaN(n) ? defaultValue : n;
|
|
419
|
+
}
|
|
420
|
+
function flagBool(flags, key, defaultValue = false) {
|
|
421
|
+
const v = flags[key];
|
|
422
|
+
if (v === void 0) return defaultValue;
|
|
423
|
+
if (typeof v === "boolean") return v;
|
|
424
|
+
return v === "true" || v === "1" || v === "yes";
|
|
425
|
+
}
|
|
426
|
+
function flagWithEnv(flags, key, envKey, defaultValue) {
|
|
427
|
+
const v = flags[key];
|
|
428
|
+
if (v !== void 0) return typeof v === "boolean" ? String(v) : v;
|
|
429
|
+
const envVal = process.env[envKey];
|
|
430
|
+
if (envVal !== void 0) return envVal;
|
|
431
|
+
return defaultValue;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// src/commands/choose.ts
|
|
435
|
+
var import_bubbletea = require("@oakoliver/bubbletea");
|
|
436
|
+
var import_bubbles = require("@oakoliver/bubbles");
|
|
437
|
+
|
|
438
|
+
// src/internal/stdin.ts
|
|
439
|
+
var fs = __toESM(require("node:fs"), 1);
|
|
440
|
+
function stripAnsi(s) {
|
|
441
|
+
return s.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "");
|
|
442
|
+
}
|
|
443
|
+
function isStdinEmpty() {
|
|
444
|
+
try {
|
|
445
|
+
const stat = fs.fstatSync(0);
|
|
446
|
+
if (stat.isFIFO()) return false;
|
|
447
|
+
if (stat.size > 0) return false;
|
|
448
|
+
return true;
|
|
449
|
+
} catch {
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
function readStdin(opts = {}) {
|
|
454
|
+
if (isStdinEmpty()) {
|
|
455
|
+
throw new Error("stdin is empty");
|
|
456
|
+
}
|
|
457
|
+
const chunks = [];
|
|
458
|
+
const buf = Buffer.alloc(1024);
|
|
459
|
+
let bytesRead;
|
|
460
|
+
try {
|
|
461
|
+
while (true) {
|
|
462
|
+
bytesRead = fs.readSync(0, buf, 0, buf.length, null);
|
|
463
|
+
if (bytesRead === 0) break;
|
|
464
|
+
chunks.push(Buffer.from(buf.subarray(0, bytesRead)));
|
|
465
|
+
if (opts.singleLine) {
|
|
466
|
+
const combined = Buffer.concat(chunks).toString("utf-8");
|
|
467
|
+
const nlIndex = combined.indexOf("\n");
|
|
468
|
+
if (nlIndex !== -1) {
|
|
469
|
+
const line = combined.substring(0, nlIndex).trim();
|
|
470
|
+
return opts.stripAnsi ? stripAnsi(line) : line;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
} catch {
|
|
475
|
+
}
|
|
476
|
+
let result = Buffer.concat(chunks).toString("utf-8").trim();
|
|
477
|
+
if (opts.singleLine) {
|
|
478
|
+
const nlIndex = result.indexOf("\n");
|
|
479
|
+
if (nlIndex !== -1) {
|
|
480
|
+
result = result.substring(0, nlIndex).trim();
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
if (opts.stripAnsi) {
|
|
484
|
+
result = stripAnsi(result);
|
|
485
|
+
}
|
|
486
|
+
return result;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// src/internal/tty.ts
|
|
490
|
+
var tty = __toESM(require("node:tty"), 1);
|
|
491
|
+
var _isTTY;
|
|
492
|
+
function isTTY() {
|
|
493
|
+
if (_isTTY === void 0) {
|
|
494
|
+
_isTTY = tty.isatty(1);
|
|
495
|
+
}
|
|
496
|
+
return _isTTY;
|
|
497
|
+
}
|
|
498
|
+
function println(s) {
|
|
499
|
+
if (isTTY()) {
|
|
500
|
+
console.log(s);
|
|
501
|
+
} else {
|
|
502
|
+
console.log(stripAnsi(s));
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// src/internal/exit.ts
|
|
507
|
+
var STATUS_ABORTED = 130;
|
|
508
|
+
|
|
509
|
+
// src/commands/choose.ts
|
|
510
|
+
function createModel(parsed) {
|
|
511
|
+
const flags = parsed.flags;
|
|
512
|
+
let items = [];
|
|
513
|
+
if (parsed.args.length > 0) {
|
|
514
|
+
items = parsed.args;
|
|
515
|
+
} else if (!isStdinEmpty()) {
|
|
516
|
+
const stdinContent = readStdin();
|
|
517
|
+
items = stdinContent.split("\n").filter((line) => line.length > 0);
|
|
518
|
+
}
|
|
519
|
+
if (items.length === 0) {
|
|
520
|
+
console.error("Error: no items provided");
|
|
521
|
+
process.exit(1);
|
|
522
|
+
}
|
|
523
|
+
const limit = flagInt(flags, "limit", 1);
|
|
524
|
+
const noLimit = flagBool(flags, "no-limit", false);
|
|
525
|
+
const height = flagInt(flags, "height", 10);
|
|
526
|
+
const header = flagStr(flags, "header", "");
|
|
527
|
+
const cursorPrefix = flagStr(flags, "cursor", "> ");
|
|
528
|
+
const selectedPrefix = flagStr(flags, "selected.prefix", "[\u2713] ");
|
|
529
|
+
const unselectedPrefix = flagStr(flags, "unselected.prefix", "[ ] ");
|
|
530
|
+
const selectIfOne = flagBool(flags, "select-if-one", false);
|
|
531
|
+
const ordered = flagBool(flags, "ordered", false);
|
|
532
|
+
const selectedItems = flagStr(flags, "selected", "").split(",").filter(Boolean);
|
|
533
|
+
const cursorStyle = toLipgloss(extractStyleOptions(flags, "cursor"));
|
|
534
|
+
const itemStyle = toLipgloss(extractStyleOptions(flags, "item"));
|
|
535
|
+
const selectedItemStyle = toLipgloss(extractStyleOptions(flags, "selected"));
|
|
536
|
+
const headerStyle = toLipgloss(extractStyleOptions(flags, "header"));
|
|
537
|
+
const choiceItems = items.map((text) => ({
|
|
538
|
+
text,
|
|
539
|
+
selected: selectedItems.includes(text),
|
|
540
|
+
order: 0
|
|
541
|
+
}));
|
|
542
|
+
const numSelected = choiceItems.filter((i) => i.selected).length;
|
|
543
|
+
const paginator = (0, import_bubbles.newPaginator)();
|
|
544
|
+
paginator.type = import_bubbles.PaginatorType.Dots;
|
|
545
|
+
paginator.perPage = height;
|
|
546
|
+
paginator.setTotalPages(choiceItems.length);
|
|
547
|
+
if (selectIfOne && choiceItems.length === 1) {
|
|
548
|
+
choiceItems[0].selected = true;
|
|
549
|
+
}
|
|
550
|
+
const isMulti = noLimit || limit > 1;
|
|
551
|
+
return {
|
|
552
|
+
items: choiceItems,
|
|
553
|
+
cursor: 0,
|
|
554
|
+
paginator,
|
|
555
|
+
limit: noLimit ? 0 : limit,
|
|
556
|
+
noLimit,
|
|
557
|
+
numSelected,
|
|
558
|
+
aborted: false,
|
|
559
|
+
quitting: false,
|
|
560
|
+
header,
|
|
561
|
+
cursorPrefix,
|
|
562
|
+
selectedPrefix: isMulti ? selectedPrefix : cursorPrefix,
|
|
563
|
+
unselectedPrefix: isMulti ? unselectedPrefix : " ",
|
|
564
|
+
cursorStyle,
|
|
565
|
+
itemStyle,
|
|
566
|
+
selectedItemStyle,
|
|
567
|
+
headerStyle,
|
|
568
|
+
height,
|
|
569
|
+
selectIfOne,
|
|
570
|
+
init() {
|
|
571
|
+
return null;
|
|
572
|
+
},
|
|
573
|
+
update(msg) {
|
|
574
|
+
if (msg instanceof import_bubbletea.WindowSizeMsg) {
|
|
575
|
+
this.paginator.perPage = msg.height - 1;
|
|
576
|
+
if (this.header) this.paginator.perPage--;
|
|
577
|
+
this.paginator.setTotalPages(this.items.length);
|
|
578
|
+
return [this, null];
|
|
579
|
+
}
|
|
580
|
+
if (msg instanceof import_bubbletea.KeyPressMsg) {
|
|
581
|
+
if (msg.mod & import_bubbletea.KeyMod.Ctrl && msg.text === "c") {
|
|
582
|
+
this.aborted = true;
|
|
583
|
+
this.quitting = true;
|
|
584
|
+
return [this, () => (0, import_bubbletea.Quit)()];
|
|
585
|
+
}
|
|
586
|
+
if (msg.code === import_bubbletea.KeyCode.Escape) {
|
|
587
|
+
this.aborted = true;
|
|
588
|
+
this.quitting = true;
|
|
589
|
+
return [this, () => (0, import_bubbletea.Quit)()];
|
|
590
|
+
}
|
|
591
|
+
if (msg.code === import_bubbletea.KeyCode.Enter) {
|
|
592
|
+
this.quitting = true;
|
|
593
|
+
if (!this.noLimit && this.limit === 1 && this.numSelected === 0) {
|
|
594
|
+
this.items[this.cursor].selected = true;
|
|
595
|
+
}
|
|
596
|
+
return [this, () => (0, import_bubbletea.Quit)()];
|
|
597
|
+
}
|
|
598
|
+
if (msg.code === import_bubbletea.KeyCode.Down || msg.text === "j" || msg.mod & import_bubbletea.KeyMod.Ctrl && msg.text === "n") {
|
|
599
|
+
this.cursor = Math.min(this.cursor + 1, this.items.length - 1);
|
|
600
|
+
const [start, end] = this.paginator.getSliceBounds(this.items.length);
|
|
601
|
+
if (this.cursor >= end) this.paginator.nextPage();
|
|
602
|
+
return [this, null];
|
|
603
|
+
}
|
|
604
|
+
if (msg.code === import_bubbletea.KeyCode.Up || msg.text === "k" || msg.mod & import_bubbletea.KeyMod.Ctrl && msg.text === "p") {
|
|
605
|
+
this.cursor = Math.max(this.cursor - 1, 0);
|
|
606
|
+
const [start] = this.paginator.getSliceBounds(this.items.length);
|
|
607
|
+
if (this.cursor < start) this.paginator.prevPage();
|
|
608
|
+
return [this, null];
|
|
609
|
+
}
|
|
610
|
+
if (msg.code === import_bubbletea.KeyCode.Home || msg.text === "g") {
|
|
611
|
+
this.cursor = 0;
|
|
612
|
+
this.paginator.page = 0;
|
|
613
|
+
return [this, null];
|
|
614
|
+
}
|
|
615
|
+
if (msg.code === import_bubbletea.KeyCode.End || msg.text === "G") {
|
|
616
|
+
this.cursor = this.items.length - 1;
|
|
617
|
+
this.paginator.page = this.paginator.totalPages - 1;
|
|
618
|
+
return [this, null];
|
|
619
|
+
}
|
|
620
|
+
if (msg.code === import_bubbletea.KeyCode.Right || msg.text === "l") {
|
|
621
|
+
this.paginator.nextPage();
|
|
622
|
+
const [start] = this.paginator.getSliceBounds(this.items.length);
|
|
623
|
+
this.cursor = start;
|
|
624
|
+
return [this, null];
|
|
625
|
+
}
|
|
626
|
+
if (msg.code === import_bubbletea.KeyCode.Left || msg.text === "h") {
|
|
627
|
+
this.paginator.prevPage();
|
|
628
|
+
const [start] = this.paginator.getSliceBounds(this.items.length);
|
|
629
|
+
this.cursor = start;
|
|
630
|
+
return [this, null];
|
|
631
|
+
}
|
|
632
|
+
if ((this.noLimit || this.limit > 1) && (msg.code === import_bubbletea.KeyCode.Space || msg.code === import_bubbletea.KeyCode.Tab || msg.text === "x")) {
|
|
633
|
+
const item = this.items[this.cursor];
|
|
634
|
+
if (item.selected) {
|
|
635
|
+
item.selected = false;
|
|
636
|
+
this.numSelected--;
|
|
637
|
+
} else if (this.noLimit || this.numSelected < this.limit) {
|
|
638
|
+
item.selected = true;
|
|
639
|
+
this.numSelected++;
|
|
640
|
+
item.order = this.numSelected;
|
|
641
|
+
}
|
|
642
|
+
return [this, null];
|
|
643
|
+
}
|
|
644
|
+
if ((this.noLimit || this.limit > 1) && msg.mod & import_bubbletea.KeyMod.Ctrl && msg.text === "a") {
|
|
645
|
+
const allSelected = this.items.every((i) => i.selected);
|
|
646
|
+
for (const item of this.items) {
|
|
647
|
+
item.selected = !allSelected;
|
|
648
|
+
}
|
|
649
|
+
this.numSelected = allSelected ? 0 : this.items.length;
|
|
650
|
+
return [this, null];
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
return [this, null];
|
|
654
|
+
},
|
|
655
|
+
view() {
|
|
656
|
+
if (this.quitting) return "";
|
|
657
|
+
const [start, end] = this.paginator.getSliceBounds(this.items.length);
|
|
658
|
+
const visible = this.items.slice(start, end);
|
|
659
|
+
let out = "";
|
|
660
|
+
if (this.header) {
|
|
661
|
+
out += this.headerStyle.render(this.header) + "\n";
|
|
662
|
+
}
|
|
663
|
+
const isMulti2 = this.noLimit || this.limit > 1;
|
|
664
|
+
for (let i = 0; i < visible.length; i++) {
|
|
665
|
+
const idx = start + i;
|
|
666
|
+
const item = visible[i];
|
|
667
|
+
const isCursor = idx === this.cursor;
|
|
668
|
+
let prefix;
|
|
669
|
+
let style;
|
|
670
|
+
if (isCursor) {
|
|
671
|
+
prefix = isMulti2 ? item.selected ? this.selectedPrefix : this.unselectedPrefix : this.cursorPrefix;
|
|
672
|
+
style = this.cursorStyle;
|
|
673
|
+
} else if (item.selected) {
|
|
674
|
+
prefix = this.selectedPrefix;
|
|
675
|
+
style = this.selectedItemStyle;
|
|
676
|
+
} else {
|
|
677
|
+
prefix = isMulti2 ? this.unselectedPrefix : " ";
|
|
678
|
+
style = this.itemStyle;
|
|
679
|
+
}
|
|
680
|
+
out += style.render(prefix + item.text);
|
|
681
|
+
if (i < visible.length - 1) out += "\n";
|
|
682
|
+
}
|
|
683
|
+
if (this.paginator.totalPages > 1) {
|
|
684
|
+
out += "\n" + this.paginator.view();
|
|
685
|
+
}
|
|
686
|
+
return out;
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
async function run(parsed) {
|
|
691
|
+
const model = createModel(parsed);
|
|
692
|
+
if (model.selectIfOne && model.items.length === 1) {
|
|
693
|
+
println(model.items[0].text);
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
const p = new import_bubbletea.Program(model);
|
|
697
|
+
const final = await p.run();
|
|
698
|
+
if (final.aborted) {
|
|
699
|
+
process.exit(STATUS_ABORTED);
|
|
700
|
+
}
|
|
701
|
+
const selected = final.items.filter((i) => i.selected);
|
|
702
|
+
if (selected.length === 0) return;
|
|
703
|
+
for (const item of selected) {
|
|
704
|
+
println(item.text);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// src/commands/confirm.ts
|
|
709
|
+
var import_bubbletea2 = require("@oakoliver/bubbletea");
|
|
710
|
+
|
|
711
|
+
// src/internal/timeout.ts
|
|
712
|
+
function parseDuration(s) {
|
|
713
|
+
if (!s || s === "0" || s === "0s" || s === "0ms") return 0;
|
|
714
|
+
const match = s.match(/^(\d+(?:\.\d+)?)(ms|s|m|h)?$/);
|
|
715
|
+
if (!match) return 0;
|
|
716
|
+
const value = parseFloat(match[1]);
|
|
717
|
+
const unit = match[2] || "ms";
|
|
718
|
+
switch (unit) {
|
|
719
|
+
case "ms":
|
|
720
|
+
return value;
|
|
721
|
+
case "s":
|
|
722
|
+
return value * 1e3;
|
|
723
|
+
case "m":
|
|
724
|
+
return value * 60 * 1e3;
|
|
725
|
+
case "h":
|
|
726
|
+
return value * 60 * 60 * 1e3;
|
|
727
|
+
default:
|
|
728
|
+
return 0;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// src/commands/confirm.ts
|
|
733
|
+
function createModel2(parsed) {
|
|
734
|
+
const flags = parsed.flags;
|
|
735
|
+
const prompt = parsed.args.length > 0 ? parsed.args.join(" ") : flagStr(flags, "prompt", "Are you sure?");
|
|
736
|
+
const affirmative = flagStr(flags, "affirmative", "Yes");
|
|
737
|
+
const negative = flagStr(flags, "negative", "No");
|
|
738
|
+
const defaultValue = flagBool(flags, "default", true);
|
|
739
|
+
const selectedStyle = toLipgloss(extractStyleOptions(flags, "selected"));
|
|
740
|
+
const unselectedStyle = toLipgloss(extractStyleOptions(flags, "unselected"));
|
|
741
|
+
const promptStyle = toLipgloss(extractStyleOptions(flags, "prompt"));
|
|
742
|
+
return {
|
|
743
|
+
affirmative,
|
|
744
|
+
negative,
|
|
745
|
+
confirmation: defaultValue,
|
|
746
|
+
defaultValue,
|
|
747
|
+
quitting: false,
|
|
748
|
+
aborted: false,
|
|
749
|
+
hasTimeout: false,
|
|
750
|
+
prompt,
|
|
751
|
+
selectedStyle: selectedStyle.padding(0, 3),
|
|
752
|
+
unselectedStyle: unselectedStyle.padding(0, 3),
|
|
753
|
+
promptStyle,
|
|
754
|
+
init() {
|
|
755
|
+
return null;
|
|
756
|
+
},
|
|
757
|
+
update(msg) {
|
|
758
|
+
if (msg instanceof import_bubbletea2.KeyPressMsg) {
|
|
759
|
+
if (msg.mod & import_bubbletea2.KeyMod.Ctrl && msg.text === "c") {
|
|
760
|
+
this.aborted = true;
|
|
761
|
+
this.quitting = true;
|
|
762
|
+
return [this, () => (0, import_bubbletea2.Quit)()];
|
|
763
|
+
}
|
|
764
|
+
if (msg.code === import_bubbletea2.KeyCode.Escape) {
|
|
765
|
+
this.aborted = true;
|
|
766
|
+
this.quitting = true;
|
|
767
|
+
return [this, () => (0, import_bubbletea2.Quit)()];
|
|
768
|
+
}
|
|
769
|
+
if (msg.code === import_bubbletea2.KeyCode.Enter) {
|
|
770
|
+
this.quitting = true;
|
|
771
|
+
return [this, () => (0, import_bubbletea2.Quit)()];
|
|
772
|
+
}
|
|
773
|
+
if (msg.code === import_bubbletea2.KeyCode.Left || msg.code === import_bubbletea2.KeyCode.Right || msg.text === "h" || msg.text === "l" || msg.code === import_bubbletea2.KeyCode.Tab) {
|
|
774
|
+
this.confirmation = !this.confirmation;
|
|
775
|
+
return [this, null];
|
|
776
|
+
}
|
|
777
|
+
if (msg.text === "y" || msg.text === "Y") {
|
|
778
|
+
this.confirmation = true;
|
|
779
|
+
this.quitting = true;
|
|
780
|
+
return [this, () => (0, import_bubbletea2.Quit)()];
|
|
781
|
+
}
|
|
782
|
+
if (msg.text === "n" || msg.text === "N") {
|
|
783
|
+
this.confirmation = false;
|
|
784
|
+
this.quitting = true;
|
|
785
|
+
return [this, () => (0, import_bubbletea2.Quit)()];
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
return [this, null];
|
|
789
|
+
},
|
|
790
|
+
view() {
|
|
791
|
+
if (this.quitting) return "";
|
|
792
|
+
let out = "";
|
|
793
|
+
out += this.promptStyle.render(this.prompt) + "\n\n";
|
|
794
|
+
if (this.confirmation) {
|
|
795
|
+
out += this.selectedStyle.render(this.affirmative) + " ";
|
|
796
|
+
out += this.unselectedStyle.render(this.negative);
|
|
797
|
+
} else {
|
|
798
|
+
out += this.unselectedStyle.render(this.affirmative) + " ";
|
|
799
|
+
out += this.selectedStyle.render(this.negative);
|
|
800
|
+
}
|
|
801
|
+
return out;
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
async function run2(parsed) {
|
|
806
|
+
const model = createModel2(parsed);
|
|
807
|
+
const timeoutStr = flagStr(parsed.flags, "timeout", "0");
|
|
808
|
+
const timeoutMs = parseDuration(timeoutStr);
|
|
809
|
+
const p = new import_bubbletea2.Program(model);
|
|
810
|
+
const final = await p.run();
|
|
811
|
+
if (final.aborted) {
|
|
812
|
+
process.exit(STATUS_ABORTED);
|
|
813
|
+
}
|
|
814
|
+
process.exit(final.confirmation ? 0 : 1);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// src/commands/file.ts
|
|
818
|
+
var import_bubbletea3 = require("@oakoliver/bubbletea");
|
|
819
|
+
var import_bubbles2 = require("@oakoliver/bubbles");
|
|
820
|
+
var import_lipgloss2 = require("@oakoliver/lipgloss");
|
|
821
|
+
var import_node_path = require("node:path");
|
|
822
|
+
function helpView() {
|
|
823
|
+
return " \u2193\u2191 navigate \u2022 esc close \u2022 enter select";
|
|
824
|
+
}
|
|
825
|
+
function createModel3(parsed) {
|
|
826
|
+
const flags = parsed.flags;
|
|
827
|
+
const startPath = (0, import_node_path.resolve)(parsed.args[0] ?? flagStr(flags, "path", "."));
|
|
828
|
+
const cursor = flagStr(flags, "cursor", ">");
|
|
829
|
+
const showHidden = flagBool(flags, "all", false);
|
|
830
|
+
const showPermissions = flagBool(flags, "permissions", true);
|
|
831
|
+
const showSize = flagBool(flags, "size", true);
|
|
832
|
+
const fileAllowed = flagBool(flags, "file", true);
|
|
833
|
+
const dirAllowed = flagBool(flags, "directory", false);
|
|
834
|
+
const showHelp = flagBool(flags, "show-help", true);
|
|
835
|
+
const header = flagStr(flags, "header", "");
|
|
836
|
+
const height = flagInt(flags, "height", 10);
|
|
837
|
+
const paddingStr = flagStr(flags, "padding", "0 0");
|
|
838
|
+
const padding = parsePadding(paddingStr);
|
|
839
|
+
if (!fileAllowed && !dirAllowed) {
|
|
840
|
+
console.error("Error: at least one of --file or --directory must be enabled");
|
|
841
|
+
process.exit(1);
|
|
842
|
+
}
|
|
843
|
+
const fp = (0, import_bubbles2.newFilePicker)();
|
|
844
|
+
fp.currentDirectory = startPath;
|
|
845
|
+
fp.cursor = cursor;
|
|
846
|
+
fp.showHidden = showHidden;
|
|
847
|
+
fp.showPermissions = showPermissions;
|
|
848
|
+
fp.showSize = showSize;
|
|
849
|
+
fp.fileAllowed = fileAllowed;
|
|
850
|
+
fp.dirAllowed = dirAllowed;
|
|
851
|
+
if (height > 0) {
|
|
852
|
+
fp.autoHeight = false;
|
|
853
|
+
fp.setHeight(height);
|
|
854
|
+
} else {
|
|
855
|
+
fp.autoHeight = true;
|
|
856
|
+
}
|
|
857
|
+
const cursorOpts = extractStyleOptions(flags, "cursor");
|
|
858
|
+
if (!cursorOpts.foreground) cursorOpts.foreground = "212";
|
|
859
|
+
fp.styles.cursor = toLipgloss(cursorOpts);
|
|
860
|
+
const symlinkOpts = extractStyleOptions(flags, "symlink");
|
|
861
|
+
if (!symlinkOpts.foreground) symlinkOpts.foreground = "36";
|
|
862
|
+
fp.styles.symlink = toLipgloss(symlinkOpts);
|
|
863
|
+
const directoryOpts = extractStyleOptions(flags, "directory");
|
|
864
|
+
if (!directoryOpts.foreground) directoryOpts.foreground = "99";
|
|
865
|
+
fp.styles.directory = toLipgloss(directoryOpts);
|
|
866
|
+
const fileOpts = extractStyleOptions(flags, "file");
|
|
867
|
+
fp.styles.file = toLipgloss(fileOpts);
|
|
868
|
+
const permOpts = extractStyleOptions(flags, "permissions");
|
|
869
|
+
if (!permOpts.foreground) permOpts.foreground = "244";
|
|
870
|
+
fp.styles.permission = toLipgloss(permOpts);
|
|
871
|
+
const selectedOpts = extractStyleOptions(flags, "selected");
|
|
872
|
+
if (!selectedOpts.foreground) selectedOpts.foreground = "212";
|
|
873
|
+
if (!selectedOpts.bold) selectedOpts.bold = true;
|
|
874
|
+
fp.styles.selected = toLipgloss(selectedOpts);
|
|
875
|
+
const fileSizeOpts = extractStyleOptions(flags, "file-size");
|
|
876
|
+
if (!fileSizeOpts.foreground) fileSizeOpts.foreground = "240";
|
|
877
|
+
fp.styles.fileSize = toLipgloss(fileSizeOpts);
|
|
878
|
+
const headerStyle = toLipgloss((() => {
|
|
879
|
+
const opts = extractStyleOptions(flags, "header");
|
|
880
|
+
if (!opts.foreground) opts.foreground = "99";
|
|
881
|
+
return opts;
|
|
882
|
+
})());
|
|
883
|
+
return {
|
|
884
|
+
filepicker: fp,
|
|
885
|
+
header,
|
|
886
|
+
headerStyle,
|
|
887
|
+
selectedPath: "",
|
|
888
|
+
quitting: false,
|
|
889
|
+
showHelp,
|
|
890
|
+
padding,
|
|
891
|
+
init() {
|
|
892
|
+
return this.filepicker.init();
|
|
893
|
+
},
|
|
894
|
+
update(msg) {
|
|
895
|
+
if (msg instanceof import_bubbletea3.WindowSizeMsg) {
|
|
896
|
+
const usable = msg.height - this.padding[0] - this.padding[2];
|
|
897
|
+
this.filepicker.setHeight(Math.max(usable, 1));
|
|
898
|
+
return [this, null];
|
|
899
|
+
}
|
|
900
|
+
if (msg instanceof import_bubbletea3.KeyPressMsg) {
|
|
901
|
+
if (msg.mod & import_bubbletea3.KeyMod.Ctrl && msg.text === "c") {
|
|
902
|
+
this.quitting = true;
|
|
903
|
+
return [this, () => (0, import_bubbletea3.Quit)()];
|
|
904
|
+
}
|
|
905
|
+
if (msg.code === import_bubbletea3.KeyCode.Escape || msg.text === "q") {
|
|
906
|
+
this.quitting = true;
|
|
907
|
+
return [this, () => (0, import_bubbletea3.Quit)()];
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
const [updatedFp, cmd] = this.filepicker.update(msg);
|
|
911
|
+
this.filepicker = updatedFp;
|
|
912
|
+
const result = this.filepicker.didSelectFile(msg);
|
|
913
|
+
const didSelect = Array.isArray(result) ? result[0] : result?.selected;
|
|
914
|
+
const selectedPath = Array.isArray(result) ? result[1] : result?.path;
|
|
915
|
+
if (didSelect && selectedPath) {
|
|
916
|
+
this.selectedPath = selectedPath;
|
|
917
|
+
this.quitting = true;
|
|
918
|
+
return [this, () => (0, import_bubbletea3.Quit)()];
|
|
919
|
+
}
|
|
920
|
+
return [this, cmd];
|
|
921
|
+
},
|
|
922
|
+
view() {
|
|
923
|
+
if (this.quitting) return "";
|
|
924
|
+
const parts = [];
|
|
925
|
+
if (this.header) {
|
|
926
|
+
parts.push(this.headerStyle.render(this.header));
|
|
927
|
+
}
|
|
928
|
+
parts.push(this.filepicker.view());
|
|
929
|
+
if (this.showHelp) {
|
|
930
|
+
parts.push(helpView());
|
|
931
|
+
}
|
|
932
|
+
let content = (0, import_lipgloss2.joinVertical)(import_lipgloss2.Left, ...parts);
|
|
933
|
+
const [pt, pr, pb, pl] = this.padding;
|
|
934
|
+
if (pt || pr || pb || pl) {
|
|
935
|
+
const padStyle = (0, import_lipgloss2.newStyle)().paddingTop(pt).paddingRight(pr).paddingBottom(pb).paddingLeft(pl);
|
|
936
|
+
content = padStyle.render(content);
|
|
937
|
+
}
|
|
938
|
+
return content;
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
async function run3(parsed) {
|
|
943
|
+
const model = createModel3(parsed);
|
|
944
|
+
const p = new import_bubbletea3.Program(model);
|
|
945
|
+
const final = await p.run();
|
|
946
|
+
if (final.quitting && !final.selectedPath) {
|
|
947
|
+
process.exit(STATUS_ABORTED);
|
|
948
|
+
}
|
|
949
|
+
if (final.selectedPath) {
|
|
950
|
+
console.log(final.selectedPath);
|
|
951
|
+
} else {
|
|
952
|
+
console.error("Error: no file selected");
|
|
953
|
+
process.exit(1);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
// src/commands/format.ts
|
|
958
|
+
var import_glamour = require("@oakoliver/glamour");
|
|
959
|
+
function detectFormatType(flags) {
|
|
960
|
+
if (flagBool(flags, "type", false)) {
|
|
961
|
+
const t = flagStr(flags, "type", "markdown");
|
|
962
|
+
if (["markdown", "code", "emoji", "template"].includes(t)) {
|
|
963
|
+
return t;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
if (flags["code"] === true) return "code";
|
|
967
|
+
if (flags["emoji"] === true) return "emoji";
|
|
968
|
+
if (flags["template"] === true) return "template";
|
|
969
|
+
if (flags["markdown"] === true) return "markdown";
|
|
970
|
+
return "markdown";
|
|
971
|
+
}
|
|
972
|
+
function formatCode(text, language) {
|
|
973
|
+
const wrapped = "```" + language + "\n" + text + "\n```";
|
|
974
|
+
return (0, import_glamour.render)(wrapped, "dark");
|
|
975
|
+
}
|
|
976
|
+
function formatEmoji(text) {
|
|
977
|
+
return text.replace(/:([a-z0-9_+-]+):/g, (match, name) => {
|
|
978
|
+
const emoji = EMOJI_MAP[name];
|
|
979
|
+
return emoji || match;
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
function formatTemplate(text, _flags) {
|
|
983
|
+
return text.replace(/\{\{\s*\.Env\.(\w+)\s*\}\}/g, (_match, key) => {
|
|
984
|
+
return process.env[key] || "";
|
|
985
|
+
});
|
|
986
|
+
}
|
|
987
|
+
var EMOJI_MAP = {
|
|
988
|
+
"smile": "\u{1F604}",
|
|
989
|
+
"laughing": "\u{1F606}",
|
|
990
|
+
"blush": "\u{1F60A}",
|
|
991
|
+
"smiley": "\u{1F603}",
|
|
992
|
+
"relaxed": "\u263A\uFE0F",
|
|
993
|
+
"heart_eyes": "\u{1F60D}",
|
|
994
|
+
"kissing_heart": "\u{1F618}",
|
|
995
|
+
"wink": "\u{1F609}",
|
|
996
|
+
"stuck_out_tongue_winking_eye": "\u{1F61C}",
|
|
997
|
+
"sunglasses": "\u{1F60E}",
|
|
998
|
+
"thumbsup": "\u{1F44D}",
|
|
999
|
+
"thumbsdown": "\u{1F44E}",
|
|
1000
|
+
"clap": "\u{1F44F}",
|
|
1001
|
+
"wave": "\u{1F44B}",
|
|
1002
|
+
"fire": "\u{1F525}",
|
|
1003
|
+
"heart": "\u2764\uFE0F",
|
|
1004
|
+
"star": "\u2B50",
|
|
1005
|
+
"sparkles": "\u2728",
|
|
1006
|
+
"check": "\u2705",
|
|
1007
|
+
"x": "\u274C",
|
|
1008
|
+
"warning": "\u26A0\uFE0F",
|
|
1009
|
+
"bulb": "\u{1F4A1}",
|
|
1010
|
+
"rocket": "\u{1F680}",
|
|
1011
|
+
"tada": "\u{1F389}",
|
|
1012
|
+
"party_popper": "\u{1F389}",
|
|
1013
|
+
"coffee": "\u2615",
|
|
1014
|
+
"beer": "\u{1F37A}",
|
|
1015
|
+
"pizza": "\u{1F355}",
|
|
1016
|
+
"bug": "\u{1F41B}",
|
|
1017
|
+
"wrench": "\u{1F527}",
|
|
1018
|
+
"hammer": "\u{1F528}",
|
|
1019
|
+
"gear": "\u2699\uFE0F",
|
|
1020
|
+
"lock": "\u{1F512}",
|
|
1021
|
+
"key": "\u{1F511}",
|
|
1022
|
+
"link": "\u{1F517}",
|
|
1023
|
+
"package": "\u{1F4E6}",
|
|
1024
|
+
"memo": "\u{1F4DD}",
|
|
1025
|
+
"book": "\u{1F4D6}",
|
|
1026
|
+
"pencil": "\u270F\uFE0F",
|
|
1027
|
+
"scissors": "\u2702\uFE0F",
|
|
1028
|
+
"computer": "\u{1F4BB}",
|
|
1029
|
+
"phone": "\u{1F4F1}",
|
|
1030
|
+
"email": "\u{1F4E7}",
|
|
1031
|
+
"globe": "\u{1F30D}",
|
|
1032
|
+
"sun": "\u2600\uFE0F",
|
|
1033
|
+
"moon": "\u{1F319}",
|
|
1034
|
+
"cloud": "\u2601\uFE0F",
|
|
1035
|
+
"rainbow": "\u{1F308}",
|
|
1036
|
+
"zap": "\u26A1",
|
|
1037
|
+
"boom": "\u{1F4A5}",
|
|
1038
|
+
"collision": "\u{1F4A5}",
|
|
1039
|
+
"eyes": "\u{1F440}",
|
|
1040
|
+
"brain": "\u{1F9E0}",
|
|
1041
|
+
"muscle": "\u{1F4AA}",
|
|
1042
|
+
"green_circle": "\u{1F7E2}",
|
|
1043
|
+
"red_circle": "\u{1F534}",
|
|
1044
|
+
"blue_circle": "\u{1F535}",
|
|
1045
|
+
"white_check_mark": "\u2705",
|
|
1046
|
+
"heavy_check_mark": "\u2714\uFE0F",
|
|
1047
|
+
"arrow_right": "\u27A1\uFE0F",
|
|
1048
|
+
"arrow_left": "\u2B05\uFE0F",
|
|
1049
|
+
"arrow_up": "\u2B06\uFE0F",
|
|
1050
|
+
"arrow_down": "\u2B07\uFE0F",
|
|
1051
|
+
"plus": "\u2795",
|
|
1052
|
+
"minus": "\u2796"
|
|
1053
|
+
};
|
|
1054
|
+
async function run4(parsed) {
|
|
1055
|
+
const flags = parsed.flags;
|
|
1056
|
+
const formatType = detectFormatType(flags);
|
|
1057
|
+
const language = flagStr(flags, "language", "") || flagStr(flags, "lang", "");
|
|
1058
|
+
const theme = flagStr(flags, "theme", "dark");
|
|
1059
|
+
let text;
|
|
1060
|
+
if (parsed.args.length > 0) {
|
|
1061
|
+
text = parsed.args.join("\n");
|
|
1062
|
+
} else if (!isStdinEmpty()) {
|
|
1063
|
+
text = readStdin();
|
|
1064
|
+
} else {
|
|
1065
|
+
text = "";
|
|
1066
|
+
}
|
|
1067
|
+
if (!text) return;
|
|
1068
|
+
let output;
|
|
1069
|
+
switch (formatType) {
|
|
1070
|
+
case "code":
|
|
1071
|
+
output = formatCode(text, language);
|
|
1072
|
+
break;
|
|
1073
|
+
case "emoji":
|
|
1074
|
+
output = formatEmoji(text);
|
|
1075
|
+
break;
|
|
1076
|
+
case "template":
|
|
1077
|
+
output = formatTemplate(text, flags);
|
|
1078
|
+
break;
|
|
1079
|
+
case "markdown":
|
|
1080
|
+
default:
|
|
1081
|
+
output = (0, import_glamour.render)(text, theme);
|
|
1082
|
+
break;
|
|
1083
|
+
}
|
|
1084
|
+
process.stdout.write(output);
|
|
1085
|
+
if (!output.endsWith("\n")) {
|
|
1086
|
+
process.stdout.write("\n");
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
// src/commands/input.ts
|
|
1091
|
+
var import_bubbletea4 = require("@oakoliver/bubbletea");
|
|
1092
|
+
var import_bubbles3 = require("@oakoliver/bubbles");
|
|
1093
|
+
function createModel4(parsed) {
|
|
1094
|
+
const flags = parsed.flags;
|
|
1095
|
+
const ti = (0, import_bubbles3.newTextInput)();
|
|
1096
|
+
ti.placeholder = flagWithEnv(flags, "placeholder", "GUM_INPUT_PLACEHOLDER", "Type something...");
|
|
1097
|
+
ti.prompt = flagWithEnv(flags, "prompt", "GUM_INPUT_PROMPT", "> ");
|
|
1098
|
+
const value = flagStr(flags, "value", "");
|
|
1099
|
+
if (value) ti.setValue(value);
|
|
1100
|
+
const charLimit = flagInt(flags, "char-limit", 400);
|
|
1101
|
+
ti.charLimit = charLimit;
|
|
1102
|
+
const echoModeStr = flagStr(flags, "echo-mode", "normal");
|
|
1103
|
+
switch (echoModeStr) {
|
|
1104
|
+
case "password":
|
|
1105
|
+
ti.echoMode = import_bubbles3.EchoMode.EchoPassword;
|
|
1106
|
+
break;
|
|
1107
|
+
case "none":
|
|
1108
|
+
ti.echoMode = import_bubbles3.EchoMode.EchoNone;
|
|
1109
|
+
break;
|
|
1110
|
+
default:
|
|
1111
|
+
ti.echoMode = import_bubbles3.EchoMode.EchoNormal;
|
|
1112
|
+
break;
|
|
1113
|
+
}
|
|
1114
|
+
const password = flagBool(flags, "password", false);
|
|
1115
|
+
if (password) ti.echoMode = import_bubbles3.EchoMode.EchoPassword;
|
|
1116
|
+
const widthFlag = flagInt(flags, "width", 0);
|
|
1117
|
+
const autoWidth = widthFlag === 0;
|
|
1118
|
+
if (!autoWidth) {
|
|
1119
|
+
ti.setWidth(widthFlag);
|
|
1120
|
+
}
|
|
1121
|
+
const header = flagStr(flags, "header", "");
|
|
1122
|
+
const headerStyle = toLipgloss(extractStyleOptions(flags, "header"));
|
|
1123
|
+
const promptStyleOpts = extractStyleOptions(flags, "prompt");
|
|
1124
|
+
const promptStyle = toLipgloss(promptStyleOpts);
|
|
1125
|
+
const styles = ti.styles();
|
|
1126
|
+
styles.focused.prompt = promptStyle;
|
|
1127
|
+
ti.setStyles(styles);
|
|
1128
|
+
const cursorStyleOpts = extractStyleOptions(flags, "cursor");
|
|
1129
|
+
const cursorStyle = toLipgloss(cursorStyleOpts);
|
|
1130
|
+
const curStyles = ti.styles();
|
|
1131
|
+
const cursorFg = flagStr(flags, "cursor.foreground", "");
|
|
1132
|
+
if (cursorFg) {
|
|
1133
|
+
curStyles.cursor.color = cursorFg;
|
|
1134
|
+
}
|
|
1135
|
+
ti.setStyles(curStyles);
|
|
1136
|
+
ti.focus();
|
|
1137
|
+
return {
|
|
1138
|
+
textInput: ti,
|
|
1139
|
+
aborted: false,
|
|
1140
|
+
quitting: false,
|
|
1141
|
+
header,
|
|
1142
|
+
headerStyle,
|
|
1143
|
+
autoWidth,
|
|
1144
|
+
width: widthFlag || 80,
|
|
1145
|
+
init() {
|
|
1146
|
+
return null;
|
|
1147
|
+
},
|
|
1148
|
+
update(msg) {
|
|
1149
|
+
if (msg instanceof import_bubbletea4.WindowSizeMsg) {
|
|
1150
|
+
this.width = msg.width;
|
|
1151
|
+
if (this.autoWidth) {
|
|
1152
|
+
this.textInput.setWidth(msg.width - 1);
|
|
1153
|
+
}
|
|
1154
|
+
return [this, null];
|
|
1155
|
+
}
|
|
1156
|
+
if (msg instanceof import_bubbletea4.KeyPressMsg) {
|
|
1157
|
+
if (msg.code === import_bubbletea4.KeyCode.Escape || msg.mod & import_bubbletea4.KeyMod.Ctrl && msg.text === "c") {
|
|
1158
|
+
this.aborted = true;
|
|
1159
|
+
this.quitting = true;
|
|
1160
|
+
return [this, () => (0, import_bubbletea4.Quit)()];
|
|
1161
|
+
}
|
|
1162
|
+
if (msg.code === import_bubbletea4.KeyCode.Escape) {
|
|
1163
|
+
this.quitting = true;
|
|
1164
|
+
return [this, () => (0, import_bubbletea4.Quit)()];
|
|
1165
|
+
}
|
|
1166
|
+
if (msg.code === import_bubbletea4.KeyCode.Enter) {
|
|
1167
|
+
this.quitting = true;
|
|
1168
|
+
return [this, () => (0, import_bubbletea4.Quit)()];
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
const [updatedTi, cmd] = this.textInput.update(msg);
|
|
1172
|
+
this.textInput = updatedTi;
|
|
1173
|
+
return [this, cmd];
|
|
1174
|
+
},
|
|
1175
|
+
view() {
|
|
1176
|
+
if (this.quitting) return "";
|
|
1177
|
+
let out = "";
|
|
1178
|
+
if (this.header) {
|
|
1179
|
+
out += this.headerStyle.render(this.header) + "\n";
|
|
1180
|
+
}
|
|
1181
|
+
out += this.textInput.view();
|
|
1182
|
+
return out;
|
|
1183
|
+
}
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
async function run5(parsed) {
|
|
1187
|
+
const model = createModel4(parsed);
|
|
1188
|
+
const p = new import_bubbletea4.Program(model);
|
|
1189
|
+
const final = await p.run();
|
|
1190
|
+
if (final.aborted) {
|
|
1191
|
+
process.exit(STATUS_ABORTED);
|
|
1192
|
+
}
|
|
1193
|
+
process.stdout.write(final.textInput.value() + "\n");
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
// src/commands/join.ts
|
|
1197
|
+
var import_lipgloss3 = require("@oakoliver/lipgloss");
|
|
1198
|
+
function parseAlign(s) {
|
|
1199
|
+
switch (s.toLowerCase()) {
|
|
1200
|
+
case "center":
|
|
1201
|
+
return import_lipgloss3.Center;
|
|
1202
|
+
case "right":
|
|
1203
|
+
case "bottom":
|
|
1204
|
+
return import_lipgloss3.Right;
|
|
1205
|
+
case "left":
|
|
1206
|
+
case "top":
|
|
1207
|
+
default:
|
|
1208
|
+
return import_lipgloss3.Left;
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
async function run6(parsed) {
|
|
1212
|
+
const flags = parsed.flags;
|
|
1213
|
+
const horizontal = flagBool(flags, "horizontal", false);
|
|
1214
|
+
const align = flagStr(flags, "align", "left");
|
|
1215
|
+
const texts = parsed.args;
|
|
1216
|
+
if (texts.length === 0) {
|
|
1217
|
+
process.stdout.write("");
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
const pos = parseAlign(align);
|
|
1221
|
+
let result;
|
|
1222
|
+
if (horizontal) {
|
|
1223
|
+
result = (0, import_lipgloss3.joinHorizontal)(pos, ...texts);
|
|
1224
|
+
} else {
|
|
1225
|
+
result = (0, import_lipgloss3.joinVertical)(pos, ...texts);
|
|
1226
|
+
}
|
|
1227
|
+
process.stdout.write(result + "\n");
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
// src/commands/log.ts
|
|
1231
|
+
var import_lipgloss4 = require("@oakoliver/lipgloss");
|
|
1232
|
+
var fs2 = __toESM(require("node:fs"), 1);
|
|
1233
|
+
var LOG_LEVEL_COLORS = {
|
|
1234
|
+
debug: "#6c757d",
|
|
1235
|
+
info: "#0d6efd",
|
|
1236
|
+
warn: "#ffc107",
|
|
1237
|
+
error: "#dc3545",
|
|
1238
|
+
fatal: "#dc3545",
|
|
1239
|
+
none: ""
|
|
1240
|
+
};
|
|
1241
|
+
function formatTimestamp(format) {
|
|
1242
|
+
const now = /* @__PURE__ */ new Date();
|
|
1243
|
+
if (format === "TimeOnly" || format === "timeonly") {
|
|
1244
|
+
return now.toLocaleTimeString();
|
|
1245
|
+
}
|
|
1246
|
+
if (format === "DateTime" || format === "datetime") {
|
|
1247
|
+
return now.toLocaleString();
|
|
1248
|
+
}
|
|
1249
|
+
if (format === "DateOnly" || format === "dateonly") {
|
|
1250
|
+
return now.toLocaleDateString();
|
|
1251
|
+
}
|
|
1252
|
+
if (format === "Kitchen" || format === "kitchen") {
|
|
1253
|
+
return now.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit", hour12: true });
|
|
1254
|
+
}
|
|
1255
|
+
if (format === "RFC3339" || format === "rfc3339") {
|
|
1256
|
+
return now.toISOString();
|
|
1257
|
+
}
|
|
1258
|
+
const h = now.getHours().toString().padStart(2, "0");
|
|
1259
|
+
const m = now.getMinutes().toString().padStart(2, "0");
|
|
1260
|
+
const s = now.getSeconds().toString().padStart(2, "0");
|
|
1261
|
+
return `${h}:${m}:${s}`;
|
|
1262
|
+
}
|
|
1263
|
+
function formatText(level, message, kvPairs, prefix, timeFormat, levelStyle, keyStyle, valueStyle, separatorStyle, prefixStyle, timeStyle, messageStyle) {
|
|
1264
|
+
const parts = [];
|
|
1265
|
+
if (timeFormat) {
|
|
1266
|
+
parts.push(timeStyle.render(formatTimestamp(timeFormat)));
|
|
1267
|
+
}
|
|
1268
|
+
const levelStr = level.toUpperCase().padEnd(5);
|
|
1269
|
+
parts.push(levelStyle.render(levelStr));
|
|
1270
|
+
if (prefix) {
|
|
1271
|
+
parts.push(prefixStyle.render(prefix));
|
|
1272
|
+
}
|
|
1273
|
+
parts.push(messageStyle.render(message));
|
|
1274
|
+
for (const [key, value] of Object.entries(kvPairs)) {
|
|
1275
|
+
parts.push(
|
|
1276
|
+
keyStyle.render(key) + separatorStyle.render("=") + valueStyle.render(value)
|
|
1277
|
+
);
|
|
1278
|
+
}
|
|
1279
|
+
return parts.join(" ");
|
|
1280
|
+
}
|
|
1281
|
+
function formatJSON(level, message, kvPairs, prefix, timeFormat) {
|
|
1282
|
+
const obj = {};
|
|
1283
|
+
if (timeFormat) obj["time"] = formatTimestamp(timeFormat);
|
|
1284
|
+
obj["level"] = level.toUpperCase();
|
|
1285
|
+
if (prefix) obj["prefix"] = prefix;
|
|
1286
|
+
obj["msg"] = message;
|
|
1287
|
+
Object.assign(obj, kvPairs);
|
|
1288
|
+
return JSON.stringify(obj);
|
|
1289
|
+
}
|
|
1290
|
+
function formatLogfmt(level, message, kvPairs, prefix, timeFormat) {
|
|
1291
|
+
const parts = [];
|
|
1292
|
+
if (timeFormat) parts.push(`time=${formatTimestamp(timeFormat)}`);
|
|
1293
|
+
parts.push(`level=${level.toUpperCase()}`);
|
|
1294
|
+
if (prefix) parts.push(`prefix=${prefix}`);
|
|
1295
|
+
parts.push(`msg="${message}"`);
|
|
1296
|
+
for (const [key, value] of Object.entries(kvPairs)) {
|
|
1297
|
+
if (value.includes(" ")) {
|
|
1298
|
+
parts.push(`${key}="${value}"`);
|
|
1299
|
+
} else {
|
|
1300
|
+
parts.push(`${key}=${value}`);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
return parts.join(" ");
|
|
1304
|
+
}
|
|
1305
|
+
async function run7(parsed) {
|
|
1306
|
+
const flags = parsed.flags;
|
|
1307
|
+
const level = flagStr(flags, "level", "info");
|
|
1308
|
+
const formatter = flagStr(flags, "formatter", "text") || flagStr(flags, "format", "text");
|
|
1309
|
+
const prefix = flagStr(flags, "prefix", "");
|
|
1310
|
+
const timeFormat = flagStr(flags, "time", "");
|
|
1311
|
+
const structured = flagBool(flags, "structured", false);
|
|
1312
|
+
const message = parsed.args.length > 0 ? parsed.args[0] : "";
|
|
1313
|
+
const kvPairs = {};
|
|
1314
|
+
for (let i = 1; i < parsed.args.length; i++) {
|
|
1315
|
+
const arg = parsed.args[i];
|
|
1316
|
+
const eqIdx = arg.indexOf("=");
|
|
1317
|
+
if (eqIdx !== -1) {
|
|
1318
|
+
kvPairs[arg.substring(0, eqIdx)] = arg.substring(eqIdx + 1);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
const levelColor = LOG_LEVEL_COLORS[level] || "";
|
|
1322
|
+
const levelStyle = levelColor ? (0, import_lipgloss4.newStyle)().foreground(levelColor).bold(true) : (0, import_lipgloss4.newStyle)();
|
|
1323
|
+
const keyStyle = toLipgloss(extractStyleOptions(flags, "key"));
|
|
1324
|
+
const valueStyle = toLipgloss(extractStyleOptions(flags, "value"));
|
|
1325
|
+
const separatorStyle = toLipgloss(extractStyleOptions(flags, "separator"));
|
|
1326
|
+
const prefixStyle = toLipgloss(extractStyleOptions(flags, "prefix"));
|
|
1327
|
+
const timeStyle = toLipgloss(extractStyleOptions(flags, "time"));
|
|
1328
|
+
const messageStyle = toLipgloss(extractStyleOptions(flags, "message"));
|
|
1329
|
+
let output;
|
|
1330
|
+
switch (formatter) {
|
|
1331
|
+
case "json":
|
|
1332
|
+
output = formatJSON(level, message, kvPairs, prefix, timeFormat);
|
|
1333
|
+
break;
|
|
1334
|
+
case "logfmt":
|
|
1335
|
+
output = formatLogfmt(level, message, kvPairs, prefix, timeFormat);
|
|
1336
|
+
break;
|
|
1337
|
+
default:
|
|
1338
|
+
output = formatText(
|
|
1339
|
+
level,
|
|
1340
|
+
message,
|
|
1341
|
+
kvPairs,
|
|
1342
|
+
prefix,
|
|
1343
|
+
timeFormat,
|
|
1344
|
+
levelStyle,
|
|
1345
|
+
keyStyle,
|
|
1346
|
+
valueStyle,
|
|
1347
|
+
separatorStyle,
|
|
1348
|
+
prefixStyle,
|
|
1349
|
+
timeStyle,
|
|
1350
|
+
messageStyle
|
|
1351
|
+
);
|
|
1352
|
+
break;
|
|
1353
|
+
}
|
|
1354
|
+
const file = flagStr(flags, "file", "");
|
|
1355
|
+
if (file) {
|
|
1356
|
+
fs2.appendFileSync(file, output + "\n");
|
|
1357
|
+
}
|
|
1358
|
+
process.stderr.write(output + "\n");
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
// src/commands/pager.ts
|
|
1362
|
+
var import_bubbletea5 = require("@oakoliver/bubbletea");
|
|
1363
|
+
var import_bubbles4 = require("@oakoliver/bubbles");
|
|
1364
|
+
var import_lipgloss5 = require("@oakoliver/lipgloss");
|
|
1365
|
+
var HELP_VIEW = " \u2191/\u2193 navigate \u2022 / search \u2022 n next \u2022 N prev \u2022 q quit";
|
|
1366
|
+
function lipglossPadding(style) {
|
|
1367
|
+
const rendered = style.render(" ");
|
|
1368
|
+
const idx = rendered.indexOf(" ");
|
|
1369
|
+
return [idx, rendered.length - 1 - idx];
|
|
1370
|
+
}
|
|
1371
|
+
function softWrapText(str, maxWidth, wrap) {
|
|
1372
|
+
if (!wrap || maxWidth <= 0) return [str];
|
|
1373
|
+
const lines = [];
|
|
1374
|
+
let remaining = str;
|
|
1375
|
+
while ((0, import_lipgloss5.stringWidth)(remaining) > maxWidth) {
|
|
1376
|
+
let cut = 0;
|
|
1377
|
+
let w = 0;
|
|
1378
|
+
for (let i = 0; i < remaining.length; i++) {
|
|
1379
|
+
const ch = remaining[i];
|
|
1380
|
+
if (ch === "\x1B") {
|
|
1381
|
+
const end = remaining.indexOf("m", i);
|
|
1382
|
+
if (end !== -1) {
|
|
1383
|
+
i = end;
|
|
1384
|
+
continue;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
w++;
|
|
1388
|
+
cut = i + 1;
|
|
1389
|
+
if (w >= maxWidth) break;
|
|
1390
|
+
}
|
|
1391
|
+
if (cut === 0) break;
|
|
1392
|
+
lines.push(remaining.substring(0, cut));
|
|
1393
|
+
remaining = remaining.substring(cut);
|
|
1394
|
+
}
|
|
1395
|
+
if (remaining.length > 0) lines.push(remaining);
|
|
1396
|
+
return lines;
|
|
1397
|
+
}
|
|
1398
|
+
function processText(model) {
|
|
1399
|
+
const lines = model.origContent.split("\n");
|
|
1400
|
+
const [padL, padR] = lipglossPadding(model.viewportStyle);
|
|
1401
|
+
const lineNumWidth = model.showLineNumbers ? ` ${lines.length} \u2502 `.length : 0;
|
|
1402
|
+
model.maxWidth = model.viewport.width() - padL - padR - lineNumWidth;
|
|
1403
|
+
const processed = [];
|
|
1404
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1405
|
+
let line = lines[i];
|
|
1406
|
+
const prefix = model.showLineNumbers ? model.lineNumberStyle.render(`${String(i + 1).padStart(4)} \u2502 `) : "";
|
|
1407
|
+
if (model.softWrap && model.maxWidth > 0) {
|
|
1408
|
+
const wrapped = softWrapText(line, model.maxWidth, true);
|
|
1409
|
+
for (let j = 0; j < wrapped.length; j++) {
|
|
1410
|
+
processed.push(j === 0 ? prefix + wrapped[j] : " ".repeat(lineNumWidth) + wrapped[j]);
|
|
1411
|
+
}
|
|
1412
|
+
} else {
|
|
1413
|
+
processed.push(prefix + line);
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
if (model.showLineNumbers) {
|
|
1417
|
+
const visible = model.viewport.height();
|
|
1418
|
+
while (processed.length < visible) {
|
|
1419
|
+
processed.push(model.lineNumberStyle.render(" ~ \u2502 "));
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
model.content = processed.join("\n");
|
|
1423
|
+
model.viewport.setContent(model.content);
|
|
1424
|
+
}
|
|
1425
|
+
function searchBegin(search) {
|
|
1426
|
+
search.active = true;
|
|
1427
|
+
search.input = (0, import_bubbles4.newTextInput)();
|
|
1428
|
+
search.input.placeholder = "search...";
|
|
1429
|
+
search.input.prompt = "/ ";
|
|
1430
|
+
search.input.focus();
|
|
1431
|
+
}
|
|
1432
|
+
function searchExecute(model) {
|
|
1433
|
+
const value = model.search.input.value();
|
|
1434
|
+
if (!value) return;
|
|
1435
|
+
let pattern;
|
|
1436
|
+
try {
|
|
1437
|
+
pattern = new RegExp(value, "gi");
|
|
1438
|
+
} catch {
|
|
1439
|
+
return;
|
|
1440
|
+
}
|
|
1441
|
+
const highlighted = model.content.replace(pattern, (m) => model.matchStyle.render(m));
|
|
1442
|
+
model.content = highlighted;
|
|
1443
|
+
model.viewport.setContent(model.content);
|
|
1444
|
+
const styledSample = model.matchStyle.render(value);
|
|
1445
|
+
try {
|
|
1446
|
+
model.search.query = new RegExp(escapeRegex(styledSample), "gi");
|
|
1447
|
+
} catch {
|
|
1448
|
+
model.search.query = null;
|
|
1449
|
+
}
|
|
1450
|
+
model.search.matchIndex = -1;
|
|
1451
|
+
}
|
|
1452
|
+
function searchDone(search) {
|
|
1453
|
+
search.active = false;
|
|
1454
|
+
search.query = null;
|
|
1455
|
+
search.matchIndex = -1;
|
|
1456
|
+
search.matchString = "";
|
|
1457
|
+
search.matchHighlightStr = "";
|
|
1458
|
+
}
|
|
1459
|
+
function searchNextMatch(model) {
|
|
1460
|
+
if (!model.search.query) return;
|
|
1461
|
+
const matches = [...model.content.matchAll(model.search.query)];
|
|
1462
|
+
if (matches.length === 0) return;
|
|
1463
|
+
if (model.search.matchHighlightStr && model.search.matchString) {
|
|
1464
|
+
model.content = model.content.replace(model.search.matchHighlightStr, model.search.matchString);
|
|
1465
|
+
}
|
|
1466
|
+
model.search.matchIndex = (model.search.matchIndex + 1) % matches.length;
|
|
1467
|
+
const match = matches[model.search.matchIndex];
|
|
1468
|
+
model.search.matchString = match[0];
|
|
1469
|
+
model.search.matchHighlightStr = model.matchHighlightStyle.render(
|
|
1470
|
+
model.search.input.value()
|
|
1471
|
+
);
|
|
1472
|
+
model.content = model.content.substring(0, match.index) + model.search.matchHighlightStr + model.content.substring(match.index + match[0].length);
|
|
1473
|
+
model.viewport.setContent(model.content);
|
|
1474
|
+
const beforeMatch = model.content.substring(0, match.index);
|
|
1475
|
+
const line = beforeMatch.split("\n").length - 1;
|
|
1476
|
+
model.viewport.setYOffset(Math.max(0, line - Math.floor(model.viewport.height() / 2)));
|
|
1477
|
+
}
|
|
1478
|
+
function searchPrevMatch(model) {
|
|
1479
|
+
if (!model.search.query) return;
|
|
1480
|
+
const matches = [...model.content.matchAll(model.search.query)];
|
|
1481
|
+
if (matches.length === 0) return;
|
|
1482
|
+
if (model.search.matchHighlightStr && model.search.matchString) {
|
|
1483
|
+
model.content = model.content.replace(model.search.matchHighlightStr, model.search.matchString);
|
|
1484
|
+
}
|
|
1485
|
+
model.search.matchIndex = model.search.matchIndex <= 0 ? matches.length - 1 : model.search.matchIndex - 1;
|
|
1486
|
+
const match = matches[model.search.matchIndex];
|
|
1487
|
+
model.search.matchString = match[0];
|
|
1488
|
+
model.search.matchHighlightStr = model.matchHighlightStyle.render(
|
|
1489
|
+
model.search.input.value()
|
|
1490
|
+
);
|
|
1491
|
+
model.content = model.content.substring(0, match.index) + model.search.matchHighlightStr + model.content.substring(match.index + match[0].length);
|
|
1492
|
+
model.viewport.setContent(model.content);
|
|
1493
|
+
const beforeMatch = model.content.substring(0, match.index);
|
|
1494
|
+
const line = beforeMatch.split("\n").length - 1;
|
|
1495
|
+
model.viewport.setYOffset(Math.max(0, line - Math.floor(model.viewport.height() / 2)));
|
|
1496
|
+
}
|
|
1497
|
+
function escapeRegex(s) {
|
|
1498
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1499
|
+
}
|
|
1500
|
+
function createModel5(parsed) {
|
|
1501
|
+
const flags = parsed.flags;
|
|
1502
|
+
let content = "";
|
|
1503
|
+
if (parsed.args.length > 0) {
|
|
1504
|
+
content = parsed.args[0];
|
|
1505
|
+
} else if (!isStdinEmpty()) {
|
|
1506
|
+
content = readStdin();
|
|
1507
|
+
content = content.replace(/.\x08/g, "");
|
|
1508
|
+
}
|
|
1509
|
+
const showLineNumbers = flagBool(flags, "show-line-numbers", true);
|
|
1510
|
+
const softWrap = flagBool(flags, "soft-wrap", true);
|
|
1511
|
+
const lineNumberStyle = toLipgloss(extractStyleOptions(flags, "line-number"));
|
|
1512
|
+
const lineNumberFg = flagStr(flags, "line-number.foreground", "237");
|
|
1513
|
+
const lnStyle = lineNumberFg === "237" && !flags["line-number.foreground"] ? (0, import_lipgloss5.newStyle)().foreground("237") : lineNumberStyle;
|
|
1514
|
+
const matchOpts = extractStyleOptions(flags, "match");
|
|
1515
|
+
const matchStyle = matchOpts.foreground || matchOpts.bold ? toLipgloss(matchOpts) : (0, import_lipgloss5.newStyle)().foreground("212").bold(true);
|
|
1516
|
+
const mhOpts = extractStyleOptions(flags, "match-highlight");
|
|
1517
|
+
const matchHighlightStyle = mhOpts.foreground || mhOpts.background || mhOpts.bold ? toLipgloss(mhOpts) : (0, import_lipgloss5.newStyle)().foreground("235").background("225").bold(true);
|
|
1518
|
+
const borderFg = flagStr(flags, "border-foreground", "212");
|
|
1519
|
+
const vpStyle = (0, import_lipgloss5.newStyle)().border((0, import_lipgloss5.roundedBorder)()).borderForeground(borderFg).paddingRight(1).paddingLeft(1);
|
|
1520
|
+
const viewport = (0, import_bubbles4.newViewport)();
|
|
1521
|
+
viewport.softWrap = softWrap;
|
|
1522
|
+
viewport.style = vpStyle;
|
|
1523
|
+
const search = {
|
|
1524
|
+
active: false,
|
|
1525
|
+
input: (0, import_bubbles4.newTextInput)(),
|
|
1526
|
+
query: null,
|
|
1527
|
+
matchIndex: -1,
|
|
1528
|
+
matchString: "",
|
|
1529
|
+
matchHighlightStr: ""
|
|
1530
|
+
};
|
|
1531
|
+
return {
|
|
1532
|
+
viewport,
|
|
1533
|
+
content,
|
|
1534
|
+
origContent: content,
|
|
1535
|
+
showLineNumbers,
|
|
1536
|
+
lineNumberStyle: lnStyle,
|
|
1537
|
+
softWrap,
|
|
1538
|
+
search,
|
|
1539
|
+
matchStyle,
|
|
1540
|
+
matchHighlightStyle,
|
|
1541
|
+
maxWidth: 0,
|
|
1542
|
+
aborted: false,
|
|
1543
|
+
quitting: false,
|
|
1544
|
+
viewportStyle: vpStyle,
|
|
1545
|
+
init() {
|
|
1546
|
+
return null;
|
|
1547
|
+
},
|
|
1548
|
+
update(msg) {
|
|
1549
|
+
if (msg instanceof import_bubbletea5.WindowSizeMsg) {
|
|
1550
|
+
this.viewport.setWidth(msg.width);
|
|
1551
|
+
this.viewport.setHeight(msg.height - 2);
|
|
1552
|
+
processText(this);
|
|
1553
|
+
return [this, null];
|
|
1554
|
+
}
|
|
1555
|
+
if (msg instanceof import_bubbletea5.KeyPressMsg) {
|
|
1556
|
+
if (this.search.active) {
|
|
1557
|
+
if (msg.code === import_bubbletea5.KeyCode.Enter) {
|
|
1558
|
+
if (this.search.input.value()) {
|
|
1559
|
+
searchExecute(this);
|
|
1560
|
+
this.search.active = false;
|
|
1561
|
+
} else {
|
|
1562
|
+
searchDone(this.search);
|
|
1563
|
+
this.content = this.origContent;
|
|
1564
|
+
processText(this);
|
|
1565
|
+
}
|
|
1566
|
+
return [this, null];
|
|
1567
|
+
}
|
|
1568
|
+
if (msg.code === import_bubbletea5.KeyCode.Escape || msg.mod & import_bubbletea5.KeyMod.Ctrl && msg.text === "c" || msg.mod & import_bubbletea5.KeyMod.Ctrl && msg.text === "d") {
|
|
1569
|
+
searchDone(this.search);
|
|
1570
|
+
this.content = this.origContent;
|
|
1571
|
+
processText(this);
|
|
1572
|
+
return [this, null];
|
|
1573
|
+
}
|
|
1574
|
+
const [updatedInput] = this.search.input.update(msg);
|
|
1575
|
+
this.search.input = updatedInput;
|
|
1576
|
+
return [this, null];
|
|
1577
|
+
}
|
|
1578
|
+
if (msg.text === "g" || msg.code === import_bubbletea5.KeyCode.Home) {
|
|
1579
|
+
this.viewport.gotoTop();
|
|
1580
|
+
return [this, null];
|
|
1581
|
+
}
|
|
1582
|
+
if (msg.text === "G" || msg.code === import_bubbletea5.KeyCode.End) {
|
|
1583
|
+
this.viewport.gotoBottom();
|
|
1584
|
+
return [this, null];
|
|
1585
|
+
}
|
|
1586
|
+
if (msg.text === "/") {
|
|
1587
|
+
searchBegin(this.search);
|
|
1588
|
+
return [this, null];
|
|
1589
|
+
}
|
|
1590
|
+
if (msg.text === "n") {
|
|
1591
|
+
searchNextMatch(this);
|
|
1592
|
+
return [this, null];
|
|
1593
|
+
}
|
|
1594
|
+
if (msg.text === "p" || msg.text === "N") {
|
|
1595
|
+
searchPrevMatch(this);
|
|
1596
|
+
return [this, null];
|
|
1597
|
+
}
|
|
1598
|
+
if (msg.text === "q" || msg.code === import_bubbletea5.KeyCode.Escape) {
|
|
1599
|
+
this.quitting = true;
|
|
1600
|
+
return [this, () => (0, import_bubbletea5.Quit)()];
|
|
1601
|
+
}
|
|
1602
|
+
if (msg.mod & import_bubbletea5.KeyMod.Ctrl && msg.text === "c") {
|
|
1603
|
+
this.aborted = true;
|
|
1604
|
+
this.quitting = true;
|
|
1605
|
+
return [this, () => (0, import_bubbletea5.Quit)()];
|
|
1606
|
+
}
|
|
1607
|
+
const [updatedVp, vpCmd] = this.viewport.update(msg);
|
|
1608
|
+
this.viewport = updatedVp;
|
|
1609
|
+
return [this, vpCmd];
|
|
1610
|
+
}
|
|
1611
|
+
return [this, null];
|
|
1612
|
+
},
|
|
1613
|
+
view() {
|
|
1614
|
+
if (this.quitting) return "";
|
|
1615
|
+
if (this.search.active) {
|
|
1616
|
+
return this.viewport.view() + "\n " + this.search.input.view();
|
|
1617
|
+
}
|
|
1618
|
+
return this.viewport.view() + "\n" + HELP_VIEW;
|
|
1619
|
+
}
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
async function run8(parsed) {
|
|
1623
|
+
const model = createModel5(parsed);
|
|
1624
|
+
const p = new import_bubbletea5.Program(model, (0, import_bubbletea5.WithAltScreen)());
|
|
1625
|
+
const final = await p.run();
|
|
1626
|
+
if (final.aborted) {
|
|
1627
|
+
process.exit(STATUS_ABORTED);
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
// src/commands/spin.ts
|
|
1632
|
+
var import_bubbletea6 = require("@oakoliver/bubbletea");
|
|
1633
|
+
var import_bubbles5 = require("@oakoliver/bubbles");
|
|
1634
|
+
var import_node_child_process = require("node:child_process");
|
|
1635
|
+
var spinnerMap = {
|
|
1636
|
+
line: import_bubbles5.Line,
|
|
1637
|
+
dot: import_bubbles5.Dot,
|
|
1638
|
+
minidot: import_bubbles5.MiniDot,
|
|
1639
|
+
jump: import_bubbles5.Jump,
|
|
1640
|
+
pulse: import_bubbles5.Pulse,
|
|
1641
|
+
points: import_bubbles5.Points,
|
|
1642
|
+
globe: import_bubbles5.Globe,
|
|
1643
|
+
moon: import_bubbles5.Moon,
|
|
1644
|
+
monkey: import_bubbles5.Monkey,
|
|
1645
|
+
meter: import_bubbles5.Meter,
|
|
1646
|
+
hamburger: import_bubbles5.Hamburger
|
|
1647
|
+
};
|
|
1648
|
+
var FinishCommandMsg = class {
|
|
1649
|
+
constructor(output, exitCode) {
|
|
1650
|
+
this.output = output;
|
|
1651
|
+
this.exitCode = exitCode;
|
|
1652
|
+
}
|
|
1653
|
+
_tag = "FinishCommandMsg";
|
|
1654
|
+
};
|
|
1655
|
+
function runCommand(command) {
|
|
1656
|
+
return () => new Promise((resolve2) => {
|
|
1657
|
+
const child = (0, import_node_child_process.spawn)(command[0], command.slice(1), {
|
|
1658
|
+
shell: true,
|
|
1659
|
+
stdio: ["inherit", "pipe", "pipe"]
|
|
1660
|
+
});
|
|
1661
|
+
let stdout = "";
|
|
1662
|
+
let stderr = "";
|
|
1663
|
+
child.stdout?.on("data", (data) => {
|
|
1664
|
+
stdout += data.toString();
|
|
1665
|
+
});
|
|
1666
|
+
child.stderr?.on("data", (data) => {
|
|
1667
|
+
stderr += data.toString();
|
|
1668
|
+
});
|
|
1669
|
+
child.on("close", (code) => {
|
|
1670
|
+
resolve2(new FinishCommandMsg(stdout || stderr, code ?? 1));
|
|
1671
|
+
});
|
|
1672
|
+
child.on("error", (err) => {
|
|
1673
|
+
resolve2(new FinishCommandMsg(err.message, 1));
|
|
1674
|
+
});
|
|
1675
|
+
});
|
|
1676
|
+
}
|
|
1677
|
+
function createModel6(parsed) {
|
|
1678
|
+
const flags = parsed.flags;
|
|
1679
|
+
const spinnerName = flagStr(flags, "spinner", "dot");
|
|
1680
|
+
const spinnerType = spinnerMap[spinnerName] || import_bubbles5.Dot;
|
|
1681
|
+
const spinner = (0, import_bubbles5.newSpinner)();
|
|
1682
|
+
spinner.spinner = spinnerType;
|
|
1683
|
+
const title = flagStr(flags, "title", "Loading...");
|
|
1684
|
+
const showOutput = flagBool(flags, "show-output", false);
|
|
1685
|
+
const align = flagStr(flags, "align", "left");
|
|
1686
|
+
const titleStyle = toLipgloss(extractStyleOptions(flags, "title"));
|
|
1687
|
+
const spinnerStyle = toLipgloss(extractStyleOptions(flags, "spinner"));
|
|
1688
|
+
spinner.style = spinnerStyle;
|
|
1689
|
+
const command = parsed.args;
|
|
1690
|
+
return {
|
|
1691
|
+
spinner,
|
|
1692
|
+
title,
|
|
1693
|
+
titleStyle,
|
|
1694
|
+
spinnerStyle,
|
|
1695
|
+
command,
|
|
1696
|
+
aborted: false,
|
|
1697
|
+
quitting: false,
|
|
1698
|
+
output: "",
|
|
1699
|
+
exitCode: 0,
|
|
1700
|
+
showOutput,
|
|
1701
|
+
align,
|
|
1702
|
+
init() {
|
|
1703
|
+
const cmds = [];
|
|
1704
|
+
cmds.push(() => this.spinner.tickMsg());
|
|
1705
|
+
if (this.command.length > 0) {
|
|
1706
|
+
cmds.push(runCommand(this.command));
|
|
1707
|
+
}
|
|
1708
|
+
return (0, import_bubbletea6.Batch)(...cmds);
|
|
1709
|
+
},
|
|
1710
|
+
update(msg) {
|
|
1711
|
+
if (msg instanceof FinishCommandMsg) {
|
|
1712
|
+
this.output = msg.output;
|
|
1713
|
+
this.exitCode = msg.exitCode;
|
|
1714
|
+
this.quitting = true;
|
|
1715
|
+
return [this, () => (0, import_bubbletea6.Quit)()];
|
|
1716
|
+
}
|
|
1717
|
+
if (msg instanceof import_bubbletea6.KeyPressMsg) {
|
|
1718
|
+
if (msg.mod & import_bubbletea6.KeyMod.Ctrl && msg.text === "c") {
|
|
1719
|
+
this.aborted = true;
|
|
1720
|
+
this.quitting = true;
|
|
1721
|
+
return [this, () => (0, import_bubbletea6.Quit)()];
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
const [updatedSpinner, cmd] = this.spinner.update(msg);
|
|
1725
|
+
this.spinner = updatedSpinner;
|
|
1726
|
+
return [this, cmd];
|
|
1727
|
+
},
|
|
1728
|
+
view() {
|
|
1729
|
+
if (this.quitting) return "";
|
|
1730
|
+
let line;
|
|
1731
|
+
const spinView = this.spinner.view();
|
|
1732
|
+
const titleView = this.titleStyle.render(this.title);
|
|
1733
|
+
if (this.align === "right") {
|
|
1734
|
+
line = titleView + " " + spinView;
|
|
1735
|
+
} else {
|
|
1736
|
+
line = spinView + " " + titleView;
|
|
1737
|
+
}
|
|
1738
|
+
let out = line;
|
|
1739
|
+
if (this.showOutput && this.output) {
|
|
1740
|
+
out += "\n" + this.output;
|
|
1741
|
+
}
|
|
1742
|
+
return out;
|
|
1743
|
+
}
|
|
1744
|
+
};
|
|
1745
|
+
}
|
|
1746
|
+
async function run9(parsed) {
|
|
1747
|
+
const model = createModel6(parsed);
|
|
1748
|
+
if (model.command.length === 0) {
|
|
1749
|
+
console.error("Error: no command provided. Usage: gum spin -- <command>");
|
|
1750
|
+
process.exit(1);
|
|
1751
|
+
}
|
|
1752
|
+
const p = new import_bubbletea6.Program(model);
|
|
1753
|
+
const final = await p.run();
|
|
1754
|
+
if (final.aborted) {
|
|
1755
|
+
process.exit(STATUS_ABORTED);
|
|
1756
|
+
}
|
|
1757
|
+
if (final.output) {
|
|
1758
|
+
process.stdout.write(final.output);
|
|
1759
|
+
if (!final.output.endsWith("\n")) {
|
|
1760
|
+
process.stdout.write("\n");
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
process.exit(final.exitCode);
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
// src/commands/style.ts
|
|
1767
|
+
async function run10(parsed) {
|
|
1768
|
+
const flags = parsed.flags;
|
|
1769
|
+
const opts = {
|
|
1770
|
+
foreground: flagStr(flags, "foreground", "") || void 0,
|
|
1771
|
+
background: flagStr(flags, "background", "") || void 0,
|
|
1772
|
+
border: flagStr(flags, "border", "") || void 0,
|
|
1773
|
+
borderForeground: flagStr(flags, "border-foreground", "") || flagStr(flags, "border.foreground", "") || void 0,
|
|
1774
|
+
borderBackground: flagStr(flags, "border-background", "") || flagStr(flags, "border.background", "") || void 0,
|
|
1775
|
+
align: flagStr(flags, "align", "") || void 0,
|
|
1776
|
+
height: flags["height"] !== void 0 ? parseInt(String(flags["height"]), 10) : void 0,
|
|
1777
|
+
width: flags["width"] !== void 0 ? parseInt(String(flags["width"]), 10) : void 0,
|
|
1778
|
+
margin: flagStr(flags, "margin", "") || void 0,
|
|
1779
|
+
padding: flagStr(flags, "padding", "") || void 0,
|
|
1780
|
+
bold: flags["bold"] === true || flags["bold"] === "true",
|
|
1781
|
+
faint: flags["faint"] === true || flags["faint"] === "true",
|
|
1782
|
+
italic: flags["italic"] === true || flags["italic"] === "true",
|
|
1783
|
+
strikethrough: flags["strikethrough"] === true || flags["strikethrough"] === "true",
|
|
1784
|
+
underline: flags["underline"] === true || flags["underline"] === "true"
|
|
1785
|
+
};
|
|
1786
|
+
const style = toLipgloss(opts);
|
|
1787
|
+
let text;
|
|
1788
|
+
if (parsed.args.length > 0) {
|
|
1789
|
+
text = parsed.args.join(" ");
|
|
1790
|
+
} else if (!isStdinEmpty()) {
|
|
1791
|
+
text = readStdin();
|
|
1792
|
+
} else {
|
|
1793
|
+
text = "";
|
|
1794
|
+
}
|
|
1795
|
+
const result = style.render(text);
|
|
1796
|
+
println(result);
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
// src/commands/table.ts
|
|
1800
|
+
var import_bubbletea7 = require("@oakoliver/bubbletea");
|
|
1801
|
+
var import_bubbles6 = require("@oakoliver/bubbles");
|
|
1802
|
+
var import_lipgloss6 = require("@oakoliver/lipgloss");
|
|
1803
|
+
var fs3 = __toESM(require("node:fs"), 1);
|
|
1804
|
+
function parseCSV(input, separator) {
|
|
1805
|
+
const rows = [];
|
|
1806
|
+
let i = 0;
|
|
1807
|
+
const len = input.length;
|
|
1808
|
+
while (i < len) {
|
|
1809
|
+
const row = [];
|
|
1810
|
+
while (i < len) {
|
|
1811
|
+
if (input[i] === '"') {
|
|
1812
|
+
i++;
|
|
1813
|
+
let field = "";
|
|
1814
|
+
while (i < len) {
|
|
1815
|
+
if (input[i] === '"') {
|
|
1816
|
+
if (i + 1 < len && input[i + 1] === '"') {
|
|
1817
|
+
field += '"';
|
|
1818
|
+
i += 2;
|
|
1819
|
+
} else {
|
|
1820
|
+
i++;
|
|
1821
|
+
break;
|
|
1822
|
+
}
|
|
1823
|
+
} else {
|
|
1824
|
+
field += input[i];
|
|
1825
|
+
i++;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
row.push(field);
|
|
1829
|
+
} else {
|
|
1830
|
+
let field = "";
|
|
1831
|
+
while (i < len && input[i] !== separator && input[i] !== "\n" && input[i] !== "\r") {
|
|
1832
|
+
field += input[i];
|
|
1833
|
+
i++;
|
|
1834
|
+
}
|
|
1835
|
+
row.push(field);
|
|
1836
|
+
}
|
|
1837
|
+
if (i < len && input[i] === separator) {
|
|
1838
|
+
i++;
|
|
1839
|
+
} else {
|
|
1840
|
+
break;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
if (i < len && input[i] === "\r") i++;
|
|
1844
|
+
if (i < len && input[i] === "\n") i++;
|
|
1845
|
+
if (row.length === 1 && row[0] === "" && i >= len) break;
|
|
1846
|
+
rows.push(row);
|
|
1847
|
+
}
|
|
1848
|
+
return rows;
|
|
1849
|
+
}
|
|
1850
|
+
function writeCSV(row, separator) {
|
|
1851
|
+
return row.map((field) => {
|
|
1852
|
+
if (field.includes(separator) || field.includes('"') || field.includes("\n")) {
|
|
1853
|
+
return '"' + field.replace(/"/g, '""') + '"';
|
|
1854
|
+
}
|
|
1855
|
+
return field;
|
|
1856
|
+
}).join(separator);
|
|
1857
|
+
}
|
|
1858
|
+
function createModel7(table, showHelp) {
|
|
1859
|
+
return {
|
|
1860
|
+
table,
|
|
1861
|
+
aborted: false,
|
|
1862
|
+
quitting: false,
|
|
1863
|
+
showHelp,
|
|
1864
|
+
init() {
|
|
1865
|
+
this.table.focus();
|
|
1866
|
+
return null;
|
|
1867
|
+
},
|
|
1868
|
+
update(msg) {
|
|
1869
|
+
if (msg instanceof import_bubbletea7.WindowSizeMsg) {
|
|
1870
|
+
this.table.setWidth(msg.width);
|
|
1871
|
+
this.table.setHeight(msg.height - 2);
|
|
1872
|
+
this.table.updateViewport();
|
|
1873
|
+
return [this, null];
|
|
1874
|
+
}
|
|
1875
|
+
if (msg instanceof import_bubbletea7.KeyPressMsg) {
|
|
1876
|
+
if (msg.mod & import_bubbletea7.KeyMod.Ctrl && msg.text === "c") {
|
|
1877
|
+
this.aborted = true;
|
|
1878
|
+
this.quitting = true;
|
|
1879
|
+
return [this, () => (0, import_bubbletea7.Quit)()];
|
|
1880
|
+
}
|
|
1881
|
+
if (msg.code === import_bubbletea7.KeyCode.Escape || msg.text === "q" || msg.mod & import_bubbletea7.KeyMod.Ctrl && msg.text === "q") {
|
|
1882
|
+
this.aborted = true;
|
|
1883
|
+
this.quitting = true;
|
|
1884
|
+
return [this, () => (0, import_bubbletea7.Quit)()];
|
|
1885
|
+
}
|
|
1886
|
+
if (msg.code === import_bubbletea7.KeyCode.Enter) {
|
|
1887
|
+
this.quitting = true;
|
|
1888
|
+
return [this, () => (0, import_bubbletea7.Quit)()];
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
const [updated, cmd] = this.table.update(msg);
|
|
1892
|
+
this.table = updated;
|
|
1893
|
+
return [this, cmd];
|
|
1894
|
+
},
|
|
1895
|
+
view() {
|
|
1896
|
+
if (this.quitting) return "";
|
|
1897
|
+
let out = this.table.view();
|
|
1898
|
+
const total = this.table.rows().length;
|
|
1899
|
+
const current = this.table.cursor() + 1;
|
|
1900
|
+
const counter = ` ${current}/${total}`;
|
|
1901
|
+
if (this.showHelp) {
|
|
1902
|
+
out += "\n" + (0, import_lipgloss6.newStyle)().faint(true).render(
|
|
1903
|
+
"\u2191/\u2193: navigate \u2022 enter: select \u2022 q/esc: quit"
|
|
1904
|
+
) + counter;
|
|
1905
|
+
} else {
|
|
1906
|
+
out += "\n" + counter;
|
|
1907
|
+
}
|
|
1908
|
+
return out;
|
|
1909
|
+
}
|
|
1910
|
+
};
|
|
1911
|
+
}
|
|
1912
|
+
async function run11(parsed) {
|
|
1913
|
+
const flags = parsed.flags;
|
|
1914
|
+
const separator = flagStr(flags, "separator", ",");
|
|
1915
|
+
const colFlag = flagStr(flags, "columns", "");
|
|
1916
|
+
const widthsFlag = flagStr(flags, "widths", "");
|
|
1917
|
+
const height = flagInt(flags, "height", 0);
|
|
1918
|
+
const printMode = flagBool(flags, "print", false);
|
|
1919
|
+
const filePath = flagStr(flags, "file", "");
|
|
1920
|
+
const showHelp = flagBool(flags, "show-help", true);
|
|
1921
|
+
const returnColumn = flagInt(flags, "return-column", 0);
|
|
1922
|
+
let input = "";
|
|
1923
|
+
if (filePath) {
|
|
1924
|
+
input = fs3.readFileSync(filePath, "utf-8");
|
|
1925
|
+
} else if (!isStdinEmpty()) {
|
|
1926
|
+
input = readStdin();
|
|
1927
|
+
} else {
|
|
1928
|
+
console.error("Error: no input provided (pipe data or use --file)");
|
|
1929
|
+
process.exit(1);
|
|
1930
|
+
}
|
|
1931
|
+
const allRows = parseCSV(input, separator);
|
|
1932
|
+
if (allRows.length === 0) {
|
|
1933
|
+
console.error("Error: no data");
|
|
1934
|
+
process.exit(1);
|
|
1935
|
+
}
|
|
1936
|
+
let headers;
|
|
1937
|
+
let dataRows;
|
|
1938
|
+
if (colFlag) {
|
|
1939
|
+
headers = colFlag.split(",");
|
|
1940
|
+
dataRows = allRows;
|
|
1941
|
+
} else {
|
|
1942
|
+
headers = allRows[0];
|
|
1943
|
+
dataRows = allRows.slice(1);
|
|
1944
|
+
}
|
|
1945
|
+
const explicitWidths = widthsFlag ? widthsFlag.split(",").map((w) => parseInt(w, 10)) : [];
|
|
1946
|
+
const columns = headers.map((title, i) => {
|
|
1947
|
+
if (explicitWidths[i] && explicitWidths[i] > 0) {
|
|
1948
|
+
return { title, width: explicitWidths[i] };
|
|
1949
|
+
}
|
|
1950
|
+
let maxW = (0, import_lipgloss6.stringWidth)(title);
|
|
1951
|
+
for (const row of dataRows) {
|
|
1952
|
+
if (row[i] !== void 0) {
|
|
1953
|
+
maxW = Math.max(maxW, (0, import_lipgloss6.stringWidth)(row[i]));
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
return { title, width: maxW + 2 };
|
|
1957
|
+
});
|
|
1958
|
+
const cellOpts = extractStyleOptions(flags, "cell");
|
|
1959
|
+
const headerOpts = extractStyleOptions(flags, "header");
|
|
1960
|
+
const selectedOpts = extractStyleOptions(flags, "selected");
|
|
1961
|
+
if (!selectedOpts.foreground) selectedOpts.foreground = "212";
|
|
1962
|
+
const baseStyles = (0, import_bubbles6.tableDefaultStyles)();
|
|
1963
|
+
const styles = {
|
|
1964
|
+
cell: toLipgloss(cellOpts).inherit(baseStyles.cell),
|
|
1965
|
+
header: toLipgloss(headerOpts).inherit(baseStyles.header),
|
|
1966
|
+
selected: toLipgloss(selectedOpts).inherit(baseStyles.selected)
|
|
1967
|
+
};
|
|
1968
|
+
const tableHeight = height > 0 ? height : Math.min(dataRows.length, 20);
|
|
1969
|
+
const table = (0, import_bubbles6.newTable)(
|
|
1970
|
+
(0, import_bubbles6.withColumns)(columns),
|
|
1971
|
+
(0, import_bubbles6.withRows)(dataRows),
|
|
1972
|
+
(0, import_bubbles6.withTableFocused)(true),
|
|
1973
|
+
(0, import_bubbles6.withTableStyles)(styles),
|
|
1974
|
+
(0, import_bubbles6.withTableHeight)(tableHeight)
|
|
1975
|
+
);
|
|
1976
|
+
if (printMode) {
|
|
1977
|
+
println(table.view());
|
|
1978
|
+
return;
|
|
1979
|
+
}
|
|
1980
|
+
const model = createModel7(table, showHelp);
|
|
1981
|
+
const p = new import_bubbletea7.Program(model);
|
|
1982
|
+
const final = await p.run();
|
|
1983
|
+
if (final.aborted) {
|
|
1984
|
+
process.exit(STATUS_ABORTED);
|
|
1985
|
+
}
|
|
1986
|
+
const selected = final.table.selectedRow();
|
|
1987
|
+
if (!selected || selected.length === 0) return;
|
|
1988
|
+
if (returnColumn > 0 && returnColumn <= selected.length) {
|
|
1989
|
+
println(selected[returnColumn - 1]);
|
|
1990
|
+
} else {
|
|
1991
|
+
println(writeCSV(selected, separator));
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
// src/commands/write.ts
|
|
1996
|
+
var import_bubbletea8 = require("@oakoliver/bubbletea");
|
|
1997
|
+
var import_bubbles7 = require("@oakoliver/bubbles");
|
|
1998
|
+
function createModel8(parsed) {
|
|
1999
|
+
const flags = parsed.flags;
|
|
2000
|
+
const ta = (0, import_bubbles7.newTextarea)();
|
|
2001
|
+
ta.placeholder = flagWithEnv(flags, "placeholder", "GUM_WRITE_PLACEHOLDER", "Write something...");
|
|
2002
|
+
ta.prompt = flagStr(flags, "prompt", "\u2503 ");
|
|
2003
|
+
const value = flagStr(flags, "value", "");
|
|
2004
|
+
if (value) ta.setValue(value);
|
|
2005
|
+
const charLimit = flagInt(flags, "char-limit", 400);
|
|
2006
|
+
ta.charLimit = charLimit > 0 ? charLimit : 0;
|
|
2007
|
+
const showLineNumbers = flagBool(flags, "show-line-numbers", false);
|
|
2008
|
+
ta.showLineNumbers = showLineNumbers;
|
|
2009
|
+
const widthFlag = flagInt(flags, "width", 0);
|
|
2010
|
+
const heightFlag = flagInt(flags, "height", 10);
|
|
2011
|
+
const autoWidth = widthFlag === 0;
|
|
2012
|
+
const autoHeight = heightFlag === 0;
|
|
2013
|
+
if (!autoWidth) {
|
|
2014
|
+
ta.setWidth(widthFlag);
|
|
2015
|
+
}
|
|
2016
|
+
if (!autoHeight) {
|
|
2017
|
+
ta.setHeight(heightFlag);
|
|
2018
|
+
}
|
|
2019
|
+
const header = flagStr(flags, "header", "");
|
|
2020
|
+
const headerStyle = toLipgloss(extractStyleOptions(flags, "header"));
|
|
2021
|
+
const cursorFg = flagStr(flags, "cursor.foreground", "");
|
|
2022
|
+
if (cursorFg) {
|
|
2023
|
+
const styles = ta.getStyles();
|
|
2024
|
+
styles.cursor.color = cursorFg;
|
|
2025
|
+
ta.setStyles(styles);
|
|
2026
|
+
}
|
|
2027
|
+
const baseStyleOpts = extractStyleOptions(flags, "base");
|
|
2028
|
+
if (Object.values(baseStyleOpts).some((v) => v !== void 0 && v !== false && v !== "")) {
|
|
2029
|
+
const styles = ta.getStyles();
|
|
2030
|
+
const baseStyle = toLipgloss(baseStyleOpts);
|
|
2031
|
+
styles.focused.base = baseStyle;
|
|
2032
|
+
ta.setStyles(styles);
|
|
2033
|
+
}
|
|
2034
|
+
ta.focus();
|
|
2035
|
+
return {
|
|
2036
|
+
textarea: ta,
|
|
2037
|
+
aborted: false,
|
|
2038
|
+
quitting: false,
|
|
2039
|
+
header,
|
|
2040
|
+
headerStyle,
|
|
2041
|
+
autoWidth,
|
|
2042
|
+
autoHeight,
|
|
2043
|
+
width: widthFlag || 80,
|
|
2044
|
+
init() {
|
|
2045
|
+
return null;
|
|
2046
|
+
},
|
|
2047
|
+
update(msg) {
|
|
2048
|
+
if (msg instanceof import_bubbletea8.WindowSizeMsg) {
|
|
2049
|
+
this.width = msg.width;
|
|
2050
|
+
if (this.autoWidth) {
|
|
2051
|
+
this.textarea.setWidth(msg.width);
|
|
2052
|
+
}
|
|
2053
|
+
if (this.autoHeight) {
|
|
2054
|
+
this.textarea.setHeight(msg.height - 2);
|
|
2055
|
+
}
|
|
2056
|
+
return [this, null];
|
|
2057
|
+
}
|
|
2058
|
+
if (msg instanceof import_bubbletea8.KeyPressMsg) {
|
|
2059
|
+
if (msg.mod & import_bubbletea8.KeyMod.Ctrl && msg.text === "c") {
|
|
2060
|
+
this.aborted = true;
|
|
2061
|
+
this.quitting = true;
|
|
2062
|
+
return [this, () => (0, import_bubbletea8.Quit)()];
|
|
2063
|
+
}
|
|
2064
|
+
if (msg.code === import_bubbletea8.KeyCode.Escape) {
|
|
2065
|
+
this.quitting = true;
|
|
2066
|
+
return [this, () => (0, import_bubbletea8.Quit)()];
|
|
2067
|
+
}
|
|
2068
|
+
if (msg.mod & import_bubbletea8.KeyMod.Ctrl && msg.text === "d") {
|
|
2069
|
+
this.quitting = true;
|
|
2070
|
+
return [this, () => (0, import_bubbletea8.Quit)()];
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
const [updatedTa, cmd] = this.textarea.update(msg);
|
|
2074
|
+
this.textarea = updatedTa;
|
|
2075
|
+
return [this, cmd];
|
|
2076
|
+
},
|
|
2077
|
+
view() {
|
|
2078
|
+
if (this.quitting) return "";
|
|
2079
|
+
let out = "";
|
|
2080
|
+
if (this.header) {
|
|
2081
|
+
out += this.headerStyle.render(this.header) + "\n";
|
|
2082
|
+
}
|
|
2083
|
+
out += this.textarea.view();
|
|
2084
|
+
return out;
|
|
2085
|
+
}
|
|
2086
|
+
};
|
|
2087
|
+
}
|
|
2088
|
+
async function run12(parsed) {
|
|
2089
|
+
const model = createModel8(parsed);
|
|
2090
|
+
const p = new import_bubbletea8.Program(model);
|
|
2091
|
+
const final = await p.run();
|
|
2092
|
+
if (final.aborted) {
|
|
2093
|
+
process.exit(STATUS_ABORTED);
|
|
2094
|
+
}
|
|
2095
|
+
process.stdout.write(final.textarea.value() + "\n");
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2098
|
+
// src/internal/files.ts
|
|
2099
|
+
var fs4 = __toESM(require("node:fs"), 1);
|
|
2100
|
+
var path = __toESM(require("node:path"), 1);
|
|
2101
|
+
var defaultIgnorePatterns = ["node_modules", ".git", "."];
|
|
2102
|
+
function shouldIgnore(filePath) {
|
|
2103
|
+
for (const prefix of defaultIgnorePatterns) {
|
|
2104
|
+
if (filePath.startsWith(prefix)) return true;
|
|
2105
|
+
}
|
|
2106
|
+
return false;
|
|
2107
|
+
}
|
|
2108
|
+
function listFiles(dir = ".") {
|
|
2109
|
+
const files = [];
|
|
2110
|
+
function walk(currentDir) {
|
|
2111
|
+
let entries;
|
|
2112
|
+
try {
|
|
2113
|
+
entries = fs4.readdirSync(currentDir, { withFileTypes: true });
|
|
2114
|
+
} catch {
|
|
2115
|
+
return;
|
|
2116
|
+
}
|
|
2117
|
+
for (const entry of entries) {
|
|
2118
|
+
const relativePath = path.join(currentDir, entry.name);
|
|
2119
|
+
if (shouldIgnore(relativePath) || shouldIgnore(entry.name)) continue;
|
|
2120
|
+
if (entry.isDirectory()) {
|
|
2121
|
+
walk(relativePath);
|
|
2122
|
+
} else if (entry.isFile()) {
|
|
2123
|
+
files.push(relativePath);
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
walk(dir);
|
|
2128
|
+
return files;
|
|
2129
|
+
}
|
|
2130
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2131
|
+
0 && (module.exports = {
|
|
2132
|
+
exactMatches,
|
|
2133
|
+
extractStyleOptions,
|
|
2134
|
+
flagBool,
|
|
2135
|
+
flagInt,
|
|
2136
|
+
flagStr,
|
|
2137
|
+
flagWithEnv,
|
|
2138
|
+
fuzzyFind,
|
|
2139
|
+
fuzzyFindNoSort,
|
|
2140
|
+
isStdinEmpty,
|
|
2141
|
+
listFiles,
|
|
2142
|
+
matchAll,
|
|
2143
|
+
matchedRanges,
|
|
2144
|
+
parseArgs,
|
|
2145
|
+
parsePadding,
|
|
2146
|
+
readStdin,
|
|
2147
|
+
runChoose,
|
|
2148
|
+
runConfirm,
|
|
2149
|
+
runFile,
|
|
2150
|
+
runFormat,
|
|
2151
|
+
runInput,
|
|
2152
|
+
runJoin,
|
|
2153
|
+
runLog,
|
|
2154
|
+
runPager,
|
|
2155
|
+
runSpin,
|
|
2156
|
+
runStyle,
|
|
2157
|
+
runTable,
|
|
2158
|
+
runWrite,
|
|
2159
|
+
stripAnsi,
|
|
2160
|
+
toLipgloss
|
|
2161
|
+
});
|