@heinrichb/console-toolkit 1.0.10 → 1.0.13
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/README.md +320 -162
- package/dist/components/progress.d.ts +10 -0
- package/dist/components/table.d.ts +31 -0
- package/dist/core/layout.d.ts +1 -0
- package/dist/core/printer.d.ts +18 -2
- package/dist/core/style.d.ts +22 -10
- package/dist/core/types.d.ts +15 -1
- package/dist/core/utils.d.ts +7 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +280 -71
- package/dist/index.min.js +2 -2
- package/dist/presets/ascii.d.ts +3 -1
- package/dist/presets/gradients.d.ts +6 -0
- package/package.json +35 -13
package/dist/core/types.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type StandardColor = "black" | "red" | "green" | "yellow" | "blue" | "mag
|
|
|
5
5
|
/**
|
|
6
6
|
* Text style modifiers.
|
|
7
7
|
*/
|
|
8
|
-
export type StyleModifier = "bold" | "dim" | "italic" | "underline" | "
|
|
8
|
+
export type StyleModifier = "bold" | "dim" | "italic" | "underline" | "hidden" | "inverse" | "strikethrough";
|
|
9
9
|
/**
|
|
10
10
|
* A valid Hex color string (e.g., "#FF0000").
|
|
11
11
|
*/
|
|
@@ -14,6 +14,14 @@ export type HexColor = `#${string}`;
|
|
|
14
14
|
* A color can be a standard color name or a hex color string.
|
|
15
15
|
*/
|
|
16
16
|
export type Color = StandardColor | HexColor;
|
|
17
|
+
/**
|
|
18
|
+
* Represents an RGB color value.
|
|
19
|
+
*/
|
|
20
|
+
export interface RGB {
|
|
21
|
+
r: number;
|
|
22
|
+
g: number;
|
|
23
|
+
b: number;
|
|
24
|
+
}
|
|
17
25
|
/**
|
|
18
26
|
* Represents the style configuration for a text segment, line, or block.
|
|
19
27
|
*/
|
|
@@ -24,6 +32,12 @@ export interface PrintStyle {
|
|
|
24
32
|
* - An array of colors applies a gradient.
|
|
25
33
|
*/
|
|
26
34
|
color?: Color | Color[];
|
|
35
|
+
/**
|
|
36
|
+
* The background color to apply.
|
|
37
|
+
* - A single color (string) applies a solid background.
|
|
38
|
+
* - An array of colors applies a background gradient.
|
|
39
|
+
*/
|
|
40
|
+
bgColor?: Color | Color[];
|
|
27
41
|
/**
|
|
28
42
|
* A list of style modifiers (e.g., bold, italic) to apply.
|
|
29
43
|
*/
|
package/dist/core/utils.d.ts
CHANGED
|
@@ -23,3 +23,10 @@ export declare function computeMaxWidth(lines: PrintLine[]): number;
|
|
|
23
23
|
* @returns A new PrintLine with padding added if necessary.
|
|
24
24
|
*/
|
|
25
25
|
export declare function padLine(inputLine: PrintLine, targetWidth: number, padStyle?: PrintStyle): PrintLine;
|
|
26
|
+
/**
|
|
27
|
+
* Strips all ANSI escape sequences from a string, returning plain text.
|
|
28
|
+
*
|
|
29
|
+
* @param text - The string potentially containing ANSI codes.
|
|
30
|
+
* @returns The plain text with all ANSI sequences removed.
|
|
31
|
+
*/
|
|
32
|
+
export declare function stripAnsi(text: string): string;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/core/style.ts
|
|
2
2
|
var ESC = "\x1B";
|
|
3
3
|
var RESET = `${ESC}[0m`;
|
|
4
|
-
var STANDARD_COLORS = {
|
|
4
|
+
var STANDARD_COLORS = Object.assign(Object.create(null), {
|
|
5
5
|
black: "#000000",
|
|
6
6
|
red: "#EF4444",
|
|
7
7
|
green: "#10B981",
|
|
@@ -12,9 +12,8 @@ var STANDARD_COLORS = {
|
|
|
12
12
|
white: "#FFFFFF",
|
|
13
13
|
gray: "#6B7280",
|
|
14
14
|
grey: "#6B7280"
|
|
15
|
-
};
|
|
16
|
-
var MODIFIER_CODES = {
|
|
17
|
-
default: "0",
|
|
15
|
+
});
|
|
16
|
+
var MODIFIER_CODES = Object.assign(Object.create(null), {
|
|
18
17
|
bold: "1",
|
|
19
18
|
dim: "2",
|
|
20
19
|
italic: "3",
|
|
@@ -22,7 +21,7 @@ var MODIFIER_CODES = {
|
|
|
22
21
|
inverse: "7",
|
|
23
22
|
hidden: "8",
|
|
24
23
|
strikethrough: "9"
|
|
25
|
-
};
|
|
24
|
+
});
|
|
26
25
|
function colorToHex(color) {
|
|
27
26
|
if (color.startsWith("#"))
|
|
28
27
|
return color;
|
|
@@ -44,11 +43,17 @@ function hexToRgb(hex) {
|
|
|
44
43
|
function rgbToAnsi(r, g, b) {
|
|
45
44
|
return `${ESC}[38;2;${r};${g};${b}m`;
|
|
46
45
|
}
|
|
46
|
+
function rgbToBgAnsi(r, g, b) {
|
|
47
|
+
return `${ESC}[48;2;${r};${g};${b}m`;
|
|
48
|
+
}
|
|
47
49
|
function resolveColorToAnsi(color) {
|
|
48
|
-
const
|
|
49
|
-
const { r, g, b } = hexToRgb(hex);
|
|
50
|
+
const { r, g, b } = resolveColorToRgb(color);
|
|
50
51
|
return rgbToAnsi(r, g, b);
|
|
51
52
|
}
|
|
53
|
+
function resolveColorToRgb(color) {
|
|
54
|
+
const hex = colorToHex(color);
|
|
55
|
+
return hexToRgb(hex);
|
|
56
|
+
}
|
|
52
57
|
function resolveModifiersToAnsi(modifiers) {
|
|
53
58
|
if (!modifiers || modifiers.length === 0)
|
|
54
59
|
return "";
|
|
@@ -70,22 +75,38 @@ function interpolateHex(color1, color2, factor) {
|
|
|
70
75
|
const b = c1.b + f * (c2.b - c1.b);
|
|
71
76
|
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
72
77
|
}
|
|
73
|
-
function
|
|
74
|
-
|
|
78
|
+
function gradientSegment(colorCount, factor) {
|
|
79
|
+
const f = Math.max(0, Math.min(1, factor));
|
|
80
|
+
const segmentLength = 1 / (colorCount - 1);
|
|
81
|
+
const index = Math.min(Math.floor(f / segmentLength), colorCount - 2);
|
|
82
|
+
return { index, factor: (f - index * segmentLength) / segmentLength };
|
|
75
83
|
}
|
|
76
|
-
function
|
|
84
|
+
function getGradientAnsiFromRgb(colors, factor, toAnsi) {
|
|
77
85
|
if (colors.length === 0)
|
|
78
86
|
return "";
|
|
79
87
|
if (colors.length === 1)
|
|
80
|
-
return
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
return toAnsi(colors[0].r, colors[0].g, colors[0].b);
|
|
89
|
+
const seg = gradientSegment(colors.length, factor);
|
|
90
|
+
const c1 = colors[seg.index];
|
|
91
|
+
const c2 = colors[seg.index + 1];
|
|
92
|
+
const r = Math.round(c1.r + seg.factor * (c2.r - c1.r));
|
|
93
|
+
const g = Math.round(c1.g + seg.factor * (c2.g - c1.g));
|
|
94
|
+
const b = Math.round(c1.b + seg.factor * (c2.b - c1.b));
|
|
95
|
+
return toAnsi(r, g, b);
|
|
96
|
+
}
|
|
97
|
+
function getGradientColorFromRgb(colors, factor) {
|
|
98
|
+
return getGradientAnsiFromRgb(colors, factor, rgbToAnsi);
|
|
99
|
+
}
|
|
100
|
+
function getGradientBgColorFromRgb(colors, factor) {
|
|
101
|
+
return getGradientAnsiFromRgb(colors, factor, rgbToBgAnsi);
|
|
102
|
+
}
|
|
103
|
+
function interpolateGradient(colors, factor) {
|
|
104
|
+
if (colors.length === 0)
|
|
105
|
+
return "#FFFFFF";
|
|
106
|
+
if (colors.length === 1)
|
|
107
|
+
return colorToHex(colors[0]);
|
|
108
|
+
const seg = gradientSegment(colors.length, factor);
|
|
109
|
+
return interpolateHex(colorToHex(colors[seg.index]), colorToHex(colors[seg.index + 1]), seg.factor);
|
|
89
110
|
}
|
|
90
111
|
function mergeStyles(parent, child) {
|
|
91
112
|
if (!parent && !child)
|
|
@@ -94,10 +115,17 @@ function mergeStyles(parent, child) {
|
|
|
94
115
|
return child ?? {};
|
|
95
116
|
if (!child)
|
|
96
117
|
return parent;
|
|
97
|
-
const
|
|
118
|
+
const parentMods = parent.modifiers ?? [];
|
|
119
|
+
const childMods = child.modifiers ?? [];
|
|
120
|
+
const mergedModifiers = [...parentMods];
|
|
121
|
+
for (const mod of childMods) {
|
|
122
|
+
if (!mergedModifiers.includes(mod))
|
|
123
|
+
mergedModifiers.push(mod);
|
|
124
|
+
}
|
|
98
125
|
return {
|
|
99
126
|
modifiers: mergedModifiers,
|
|
100
|
-
color: child.color ?? parent.color
|
|
127
|
+
color: child.color ?? parent.color,
|
|
128
|
+
bgColor: child.bgColor ?? parent.bgColor
|
|
101
129
|
};
|
|
102
130
|
}
|
|
103
131
|
function resolveStyle(style, gradientFactor = 0) {
|
|
@@ -109,12 +137,21 @@ function resolveStyle(style, gradientFactor = 0) {
|
|
|
109
137
|
}
|
|
110
138
|
if (style.color) {
|
|
111
139
|
if (Array.isArray(style.color)) {
|
|
112
|
-
const
|
|
113
|
-
ansi +=
|
|
140
|
+
const rgbColors = style.color.map(resolveColorToRgb);
|
|
141
|
+
ansi += getGradientColorFromRgb(rgbColors, gradientFactor);
|
|
114
142
|
} else {
|
|
115
143
|
ansi += resolveColorToAnsi(style.color);
|
|
116
144
|
}
|
|
117
145
|
}
|
|
146
|
+
if (style.bgColor) {
|
|
147
|
+
if (Array.isArray(style.bgColor)) {
|
|
148
|
+
const bgRgbColors = style.bgColor.map(resolveColorToRgb);
|
|
149
|
+
ansi += getGradientBgColorFromRgb(bgRgbColors, gradientFactor);
|
|
150
|
+
} else {
|
|
151
|
+
const { r, g, b } = resolveColorToRgb(style.bgColor);
|
|
152
|
+
ansi += rgbToBgAnsi(r, g, b);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
118
155
|
return ansi;
|
|
119
156
|
}
|
|
120
157
|
// src/core/builders.ts
|
|
@@ -133,7 +170,7 @@ function getLineLength(line2) {
|
|
|
133
170
|
return line2.segments.reduce((acc, seg) => acc + seg.text.length, 0);
|
|
134
171
|
}
|
|
135
172
|
function computeMaxWidth(lines) {
|
|
136
|
-
return lines.
|
|
173
|
+
return lines.reduce((max, l) => Math.max(max, getLineLength(l)), 0);
|
|
137
174
|
}
|
|
138
175
|
function padLine(inputLine, targetWidth, padStyle) {
|
|
139
176
|
const currentLength = getLineLength(inputLine);
|
|
@@ -142,9 +179,11 @@ function padLine(inputLine, targetWidth, padStyle) {
|
|
|
142
179
|
}
|
|
143
180
|
return inputLine;
|
|
144
181
|
}
|
|
182
|
+
var ANSI_REGEX = /\x1b\[[0-9;]*m/g;
|
|
183
|
+
function stripAnsi(text) {
|
|
184
|
+
return text.replace(ANSI_REGEX, "");
|
|
185
|
+
}
|
|
145
186
|
// src/core/printer.ts
|
|
146
|
-
var ESC2 = "\x1B";
|
|
147
|
-
|
|
148
187
|
class Printer {
|
|
149
188
|
linesRendered = 0;
|
|
150
189
|
isLive;
|
|
@@ -156,7 +195,7 @@ class Printer {
|
|
|
156
195
|
getClearSequence() {
|
|
157
196
|
if (!this.isLive || this.linesRendered === 0)
|
|
158
197
|
return "";
|
|
159
|
-
return `${
|
|
198
|
+
return `${ESC}[1A${ESC}[2K\r`.repeat(this.linesRendered);
|
|
160
199
|
}
|
|
161
200
|
clear() {
|
|
162
201
|
if (this.linesRendered > 0) {
|
|
@@ -164,6 +203,14 @@ class Printer {
|
|
|
164
203
|
this.linesRendered = 0;
|
|
165
204
|
}
|
|
166
205
|
}
|
|
206
|
+
renderToString(data) {
|
|
207
|
+
if (data) {
|
|
208
|
+
this.data = data;
|
|
209
|
+
}
|
|
210
|
+
if (!this.data)
|
|
211
|
+
return "";
|
|
212
|
+
return this.renderBlock(this.data);
|
|
213
|
+
}
|
|
167
214
|
print(data) {
|
|
168
215
|
if (data) {
|
|
169
216
|
this.data = data;
|
|
@@ -171,51 +218,67 @@ class Printer {
|
|
|
171
218
|
if (!this.data) {
|
|
172
219
|
return;
|
|
173
220
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
221
|
+
const output = this.getClearSequence() + this.renderBlock(this.data);
|
|
222
|
+
process.stdout.write(output);
|
|
223
|
+
this.linesRendered = this.data.lines.length;
|
|
224
|
+
}
|
|
225
|
+
renderBlock(blockData) {
|
|
226
|
+
let output = "";
|
|
227
|
+
const lines = blockData.lines;
|
|
228
|
+
const blockStyle = blockData.style ?? {};
|
|
229
|
+
lines.forEach((ln, lineIndex) => {
|
|
230
|
+
output += this.renderLine(ln, lineIndex, lines.length, blockStyle);
|
|
179
231
|
output += `
|
|
180
232
|
`;
|
|
181
233
|
});
|
|
182
|
-
|
|
183
|
-
this.linesRendered = lines.length;
|
|
234
|
+
return output;
|
|
184
235
|
}
|
|
185
|
-
|
|
186
|
-
|
|
236
|
+
resolveBlockStyleForLine(blockStyle, lineIndex, totalLines) {
|
|
237
|
+
return {
|
|
238
|
+
modifiers: blockStyle.modifiers,
|
|
239
|
+
color: this.resolveGradientForLine(blockStyle.color, lineIndex, totalLines),
|
|
240
|
+
bgColor: this.resolveGradientForLine(blockStyle.bgColor, lineIndex, totalLines)
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
resolveGradientForLine(color, lineIndex, totalLines) {
|
|
244
|
+
if (!color)
|
|
187
245
|
return;
|
|
188
|
-
if (Array.isArray(
|
|
246
|
+
if (Array.isArray(color)) {
|
|
189
247
|
if (totalLines <= 1)
|
|
190
|
-
return
|
|
191
|
-
|
|
192
|
-
const factor = lineIndex / (totalLines - 1);
|
|
193
|
-
const f = Math.max(0, Math.min(1, factor));
|
|
194
|
-
const segmentLength = 1 / (colors.length - 1);
|
|
195
|
-
const segmentIndex = Math.min(Math.floor(f / segmentLength), colors.length - 2);
|
|
196
|
-
const segmentFactor = (f - segmentIndex * segmentLength) / segmentLength;
|
|
197
|
-
const c1 = colors[segmentIndex];
|
|
198
|
-
const c2 = colors[segmentIndex + 1];
|
|
199
|
-
return interpolateColor(c1, c2, segmentFactor);
|
|
248
|
+
return color[0];
|
|
249
|
+
return interpolateGradient(color, lineIndex / (totalLines - 1));
|
|
200
250
|
}
|
|
201
|
-
return
|
|
251
|
+
return color;
|
|
202
252
|
}
|
|
203
253
|
renderLine(line2, lineIndex, totalLines, parentBlockStyle) {
|
|
204
|
-
const
|
|
205
|
-
const baseLineStyle = {
|
|
206
|
-
modifiers: parentBlockStyle.modifiers,
|
|
207
|
-
color: blockColorForLine
|
|
208
|
-
};
|
|
254
|
+
const baseLineStyle = this.resolveBlockStyleForLine(parentBlockStyle, lineIndex, totalLines);
|
|
209
255
|
const effectiveLineStyle = mergeStyles(baseLineStyle, line2.style);
|
|
210
256
|
const totalChars = line2.segments.reduce((acc, seg) => acc + seg.text.length, 0);
|
|
211
257
|
let currentCharIndex = 0;
|
|
212
258
|
let lineOutput = "";
|
|
213
259
|
line2.segments.forEach((seg) => {
|
|
214
260
|
const effectiveSegmentStyle = mergeStyles(effectiveLineStyle, seg.style);
|
|
215
|
-
|
|
216
|
-
|
|
261
|
+
const hasFgGradient = Array.isArray(effectiveSegmentStyle.color);
|
|
262
|
+
const hasBgGradient = Array.isArray(effectiveSegmentStyle.bgColor);
|
|
263
|
+
if (hasFgGradient || hasBgGradient) {
|
|
217
264
|
const text = seg.text;
|
|
218
265
|
const isGlobalGradient = effectiveSegmentStyle.color === effectiveLineStyle.color;
|
|
266
|
+
let fgRgbColors;
|
|
267
|
+
let solidFgAnsi = "";
|
|
268
|
+
if (hasFgGradient) {
|
|
269
|
+
fgRgbColors = effectiveSegmentStyle.color.map(resolveColorToRgb);
|
|
270
|
+
} else if (effectiveSegmentStyle.color) {
|
|
271
|
+
const { r, g, b } = resolveColorToRgb(effectiveSegmentStyle.color);
|
|
272
|
+
solidFgAnsi = rgbToAnsi(r, g, b);
|
|
273
|
+
}
|
|
274
|
+
let bgRgbColors;
|
|
275
|
+
let solidBgAnsi = "";
|
|
276
|
+
if (hasBgGradient) {
|
|
277
|
+
bgRgbColors = effectiveSegmentStyle.bgColor.map(resolveColorToRgb);
|
|
278
|
+
} else if (effectiveSegmentStyle.bgColor) {
|
|
279
|
+
const { r, g, b } = resolveColorToRgb(effectiveSegmentStyle.bgColor);
|
|
280
|
+
solidBgAnsi = rgbToBgAnsi(r, g, b);
|
|
281
|
+
}
|
|
219
282
|
const modifiersAnsi = resolveModifiersToAnsi(effectiveSegmentStyle.modifiers);
|
|
220
283
|
for (let i = 0;i < text.length; i++) {
|
|
221
284
|
let factor = 0;
|
|
@@ -224,8 +287,9 @@ class Printer {
|
|
|
224
287
|
} else if (!isGlobalGradient && text.length > 1) {
|
|
225
288
|
factor = i / (text.length - 1);
|
|
226
289
|
}
|
|
227
|
-
const
|
|
228
|
-
|
|
290
|
+
const fgAnsi = fgRgbColors ? getGradientColorFromRgb(fgRgbColors, factor) : solidFgAnsi;
|
|
291
|
+
const bgAnsi = bgRgbColors ? getGradientBgColorFromRgb(bgRgbColors, factor) : solidBgAnsi;
|
|
292
|
+
lineOutput += `${modifiersAnsi}${fgAnsi}${bgAnsi}${text[i]}`;
|
|
229
293
|
}
|
|
230
294
|
lineOutput += RESET;
|
|
231
295
|
} else {
|
|
@@ -241,7 +305,7 @@ class Printer {
|
|
|
241
305
|
function mergeColumns(columns, separator = " ", defaultStyle, widths) {
|
|
242
306
|
if (columns.length === 0)
|
|
243
307
|
return [];
|
|
244
|
-
const maxLines =
|
|
308
|
+
const maxLines = columns.reduce((max, c) => Math.max(max, c.length), 0);
|
|
245
309
|
const colWidths = columns.map((col, i) => {
|
|
246
310
|
if (widths?.[i] !== undefined)
|
|
247
311
|
return widths[i];
|
|
@@ -249,14 +313,14 @@ function mergeColumns(columns, separator = " ", defaultStyle, widths) {
|
|
|
249
313
|
});
|
|
250
314
|
const output = [];
|
|
251
315
|
for (let i = 0;i < maxLines; i++) {
|
|
252
|
-
|
|
316
|
+
const segments = [];
|
|
253
317
|
for (let j = 0;j < columns.length; j++) {
|
|
254
318
|
const currentLine = columns[j][i] || line();
|
|
255
319
|
if (j < columns.length - 1) {
|
|
256
320
|
const padded = padLine(currentLine, colWidths[j], defaultStyle);
|
|
257
|
-
segments
|
|
321
|
+
segments.push(...padded.segments, segment(separator, defaultStyle));
|
|
258
322
|
} else {
|
|
259
|
-
segments
|
|
323
|
+
segments.push(...currentLine.segments);
|
|
260
324
|
}
|
|
261
325
|
}
|
|
262
326
|
output.push(line(segments));
|
|
@@ -264,8 +328,8 @@ function mergeColumns(columns, separator = " ", defaultStyle, widths) {
|
|
|
264
328
|
return output;
|
|
265
329
|
}
|
|
266
330
|
function printColumns(columns, options = {}) {
|
|
267
|
-
const { widths, separator = " ", printer = new Printer } = options;
|
|
268
|
-
const mergedLines = mergeColumns(columns, separator,
|
|
331
|
+
const { widths, separator = " ", defaultStyle, printer = new Printer } = options;
|
|
332
|
+
const mergedLines = mergeColumns(columns, separator, defaultStyle, widths);
|
|
269
333
|
printer.print(block(mergedLines));
|
|
270
334
|
}
|
|
271
335
|
// src/components/progress.ts
|
|
@@ -284,7 +348,9 @@ function createProgressBar(options) {
|
|
|
284
348
|
startChar = "[",
|
|
285
349
|
endChar = "]",
|
|
286
350
|
fillChar = "█",
|
|
351
|
+
completeChar,
|
|
287
352
|
emptyChar = "░",
|
|
353
|
+
completeStyle,
|
|
288
354
|
showPercentage = true,
|
|
289
355
|
formatPercentage
|
|
290
356
|
} = options;
|
|
@@ -295,15 +361,17 @@ function createProgressBar(options) {
|
|
|
295
361
|
const resolvedStartStyle = startStyle ?? resolvedBracketStyle;
|
|
296
362
|
const resolvedEndStyle = endStyle ?? resolvedBracketStyle;
|
|
297
363
|
const resolvedBarStyle = barStyle ?? style;
|
|
298
|
-
const
|
|
364
|
+
const isComplete = p >= 1;
|
|
365
|
+
const resolvedFillStyle = isComplete ? completeStyle ?? fillStyle ?? resolvedBarStyle : fillStyle ?? resolvedBarStyle;
|
|
299
366
|
const resolvedEmptyStyle = emptyStyle ?? resolvedBarStyle;
|
|
300
367
|
const resolvedPercentageStyle = percentageStyle ?? style;
|
|
301
368
|
const segments = [];
|
|
302
369
|
if (startChar) {
|
|
303
370
|
segments.push(segment(startChar, resolvedStartStyle));
|
|
304
371
|
}
|
|
372
|
+
const effectiveFillChar = isComplete ? completeChar ?? fillChar : fillChar;
|
|
305
373
|
if (filledWidth > 0) {
|
|
306
|
-
segments.push(segment(
|
|
374
|
+
segments.push(segment(effectiveFillChar.repeat(filledWidth), resolvedFillStyle));
|
|
307
375
|
}
|
|
308
376
|
if (emptyWidth > 0) {
|
|
309
377
|
segments.push(segment(emptyChar.repeat(emptyWidth), resolvedEmptyStyle));
|
|
@@ -342,8 +410,133 @@ class Spinner {
|
|
|
342
410
|
return this.frames[index];
|
|
343
411
|
}
|
|
344
412
|
}
|
|
413
|
+
// src/components/table.ts
|
|
414
|
+
var BORDERS = {
|
|
415
|
+
single: {
|
|
416
|
+
tl: "┌",
|
|
417
|
+
t: "─",
|
|
418
|
+
tr: "┐",
|
|
419
|
+
l: "│",
|
|
420
|
+
r: "│",
|
|
421
|
+
bl: "└",
|
|
422
|
+
b: "─",
|
|
423
|
+
br: "┘",
|
|
424
|
+
ml: "├",
|
|
425
|
+
m: "─",
|
|
426
|
+
mr: "┤",
|
|
427
|
+
tj: "┬",
|
|
428
|
+
bj: "┴",
|
|
429
|
+
mj: "┼"
|
|
430
|
+
},
|
|
431
|
+
double: {
|
|
432
|
+
tl: "╔",
|
|
433
|
+
t: "═",
|
|
434
|
+
tr: "╗",
|
|
435
|
+
l: "║",
|
|
436
|
+
r: "║",
|
|
437
|
+
bl: "╚",
|
|
438
|
+
b: "═",
|
|
439
|
+
br: "╝",
|
|
440
|
+
ml: "╠",
|
|
441
|
+
m: "═",
|
|
442
|
+
mr: "╣",
|
|
443
|
+
tj: "╦",
|
|
444
|
+
bj: "╩",
|
|
445
|
+
mj: "╬"
|
|
446
|
+
},
|
|
447
|
+
rounded: {
|
|
448
|
+
tl: "╭",
|
|
449
|
+
t: "─",
|
|
450
|
+
tr: "╮",
|
|
451
|
+
l: "│",
|
|
452
|
+
r: "│",
|
|
453
|
+
bl: "╰",
|
|
454
|
+
b: "─",
|
|
455
|
+
br: "╯",
|
|
456
|
+
ml: "├",
|
|
457
|
+
m: "─",
|
|
458
|
+
mr: "┤",
|
|
459
|
+
tj: "┬",
|
|
460
|
+
bj: "┴",
|
|
461
|
+
mj: "┼"
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
function buildBorderLine(left, fill, junction, right, colWidths, padding, borderStyle) {
|
|
465
|
+
const parts = [left];
|
|
466
|
+
for (let i = 0;i < colWidths.length; i++) {
|
|
467
|
+
parts.push(fill.repeat(colWidths[i] + padding * 2));
|
|
468
|
+
if (i < colWidths.length - 1)
|
|
469
|
+
parts.push(junction);
|
|
470
|
+
}
|
|
471
|
+
parts.push(right);
|
|
472
|
+
return line([segment(parts.join(""), borderStyle)]);
|
|
473
|
+
}
|
|
474
|
+
function buildDataRow(cells, colWidths, padding, colCount, borderChar, cellStyle, borderStyle) {
|
|
475
|
+
const segments = [];
|
|
476
|
+
segments.push(segment(borderChar, borderStyle));
|
|
477
|
+
for (let i = 0;i < colCount; i++) {
|
|
478
|
+
const cellText = cells[i] ?? "";
|
|
479
|
+
const padded = " ".repeat(padding) + cellText.padEnd(colWidths[i]) + " ".repeat(padding);
|
|
480
|
+
segments.push(segment(padded, cellStyle));
|
|
481
|
+
if (i < colCount - 1) {
|
|
482
|
+
segments.push(segment(borderChar, borderStyle));
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
segments.push(segment(borderChar, borderStyle));
|
|
486
|
+
return line(segments);
|
|
487
|
+
}
|
|
488
|
+
function createTable(options) {
|
|
489
|
+
const { headers, rows, style, headerStyle, borderStyle, border = "single", columnWidths, cellPadding = 1 } = options;
|
|
490
|
+
const colCount = rows.reduce((max, r) => Math.max(max, r.length), headers?.length ?? 0);
|
|
491
|
+
if (colCount === 0)
|
|
492
|
+
return [];
|
|
493
|
+
const colWidths = [];
|
|
494
|
+
for (let i = 0;i < colCount; i++) {
|
|
495
|
+
if (columnWidths?.[i] !== undefined) {
|
|
496
|
+
colWidths.push(columnWidths[i]);
|
|
497
|
+
} else {
|
|
498
|
+
const headerWidth = headers?.[i]?.length ?? 0;
|
|
499
|
+
const maxRowWidth = rows.reduce((max, row) => Math.max(max, row[i]?.length ?? 0), 0);
|
|
500
|
+
colWidths.push(Math.max(headerWidth, maxRowWidth));
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
if (border === "none") {
|
|
504
|
+
return buildNoBorderTable(headers, rows, colWidths, cellPadding, colCount, style, headerStyle);
|
|
505
|
+
}
|
|
506
|
+
const chars = BORDERS[border];
|
|
507
|
+
const output = [];
|
|
508
|
+
output.push(buildBorderLine(chars.tl, chars.t, chars.tj, chars.tr, colWidths, cellPadding, borderStyle));
|
|
509
|
+
if (headers) {
|
|
510
|
+
output.push(buildDataRow(headers, colWidths, cellPadding, colCount, chars.l, headerStyle ?? style, borderStyle));
|
|
511
|
+
output.push(buildBorderLine(chars.ml, chars.m, chars.mj, chars.mr, colWidths, cellPadding, borderStyle));
|
|
512
|
+
}
|
|
513
|
+
for (const row of rows) {
|
|
514
|
+
output.push(buildDataRow(row, colWidths, cellPadding, colCount, chars.l, style, borderStyle));
|
|
515
|
+
}
|
|
516
|
+
output.push(buildBorderLine(chars.bl, chars.b, chars.bj, chars.br, colWidths, cellPadding, borderStyle));
|
|
517
|
+
return output;
|
|
518
|
+
}
|
|
519
|
+
function buildNoBorderTable(headers, rows, colWidths, padding, colCount, style, headerStyle) {
|
|
520
|
+
const output = [];
|
|
521
|
+
const space = " ".repeat(padding);
|
|
522
|
+
function buildRow(cells, cellStyle) {
|
|
523
|
+
const segments = [];
|
|
524
|
+
for (let i = 0;i < colCount; i++) {
|
|
525
|
+
const cellText = cells[i] ?? "";
|
|
526
|
+
segments.push(segment(space + cellText.padEnd(colWidths[i]) + space, cellStyle));
|
|
527
|
+
}
|
|
528
|
+
return line(segments);
|
|
529
|
+
}
|
|
530
|
+
if (headers) {
|
|
531
|
+
output.push(buildRow(headers, headerStyle ?? style));
|
|
532
|
+
}
|
|
533
|
+
for (const row of rows) {
|
|
534
|
+
output.push(buildRow(row, style));
|
|
535
|
+
}
|
|
536
|
+
return output;
|
|
537
|
+
}
|
|
345
538
|
// src/presets/ascii.ts
|
|
346
|
-
function getDragon(
|
|
539
|
+
function getDragon(colors = ["#EF4444", "#F59E0B"]) {
|
|
347
540
|
const rawDragon = [
|
|
348
541
|
" ^ ^",
|
|
349
542
|
" / \\ //\\",
|
|
@@ -365,15 +558,27 @@ function getDragon(startColor = "#EF4444", endColor = "#F59E0B") {
|
|
|
365
558
|
];
|
|
366
559
|
return rawDragon.map((text, i) => {
|
|
367
560
|
const factor = rawDragon.length <= 1 ? 0 : i / (rawDragon.length - 1);
|
|
368
|
-
const
|
|
369
|
-
return line([segment(text, { color
|
|
561
|
+
const color = interpolateGradient(colors, factor);
|
|
562
|
+
return line([segment(text, { color })]);
|
|
370
563
|
});
|
|
371
564
|
}
|
|
565
|
+
// src/presets/gradients.ts
|
|
566
|
+
var GRADIENTS = {
|
|
567
|
+
rainbow: ["#EF4444", "#F59E0B", "#10B981", "#06B6D4", "#3B82F6", "#8B5CF6"],
|
|
568
|
+
ocean: ["#1E3A5F", "#0E7490", "#06B6D4", "#67E8F9"],
|
|
569
|
+
fire: ["#7F1D1D", "#EF4444", "#F59E0B", "#FDE047"],
|
|
570
|
+
sunset: ["#7C3AED", "#EC4899", "#F97316", "#FBBF24"],
|
|
571
|
+
forest: ["#064E3B", "#10B981", "#84CC16", "#BEF264"],
|
|
572
|
+
monochrome: ["#000000", "#6B7280", "#FFFFFF"]
|
|
573
|
+
};
|
|
372
574
|
export {
|
|
575
|
+
stripAnsi,
|
|
373
576
|
segment,
|
|
577
|
+
rgbToBgAnsi,
|
|
374
578
|
rgbToAnsi,
|
|
375
579
|
resolveStyle,
|
|
376
580
|
resolveModifiersToAnsi,
|
|
581
|
+
resolveColorToRgb,
|
|
377
582
|
resolveColorToAnsi,
|
|
378
583
|
printColumns,
|
|
379
584
|
padLine,
|
|
@@ -381,11 +586,13 @@ export {
|
|
|
381
586
|
mergeColumns,
|
|
382
587
|
line,
|
|
383
588
|
interpolateHex,
|
|
384
|
-
|
|
589
|
+
interpolateGradient,
|
|
385
590
|
hexToRgb,
|
|
386
591
|
getLineLength,
|
|
387
|
-
|
|
592
|
+
getGradientColorFromRgb,
|
|
593
|
+
getGradientBgColorFromRgb,
|
|
388
594
|
getDragon,
|
|
595
|
+
createTable,
|
|
389
596
|
createProgressBar,
|
|
390
597
|
computeMaxWidth,
|
|
391
598
|
colorToHex,
|
|
@@ -393,5 +600,7 @@ export {
|
|
|
393
600
|
Spinner,
|
|
394
601
|
SPINNERS,
|
|
395
602
|
RESET,
|
|
396
|
-
Printer
|
|
603
|
+
Printer,
|
|
604
|
+
GRADIENTS,
|
|
605
|
+
ESC
|
|
397
606
|
};
|