@heinrichb/console-toolkit 1.0.7 → 1.0.9

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.
@@ -1,53 +0,0 @@
1
- import { expect, test, describe, spyOn, afterEach, beforeEach } from "bun:test";
2
- import { Spinner, SPINNERS } from "./spinner";
3
- describe("Spinner Class", () => {
4
- let now = 1000;
5
- // Mock Date.now() to control time
6
- const dateSpy = spyOn(Date, "now").mockImplementation(() => now);
7
- beforeEach(() => {
8
- now = 1000;
9
- dateSpy.mockClear();
10
- dateSpy.mockImplementation(() => now);
11
- });
12
- afterEach(() => {
13
- dateSpy.mockClear();
14
- });
15
- test("initializes with correct defaults", () => {
16
- const spinner = new Spinner({ frames: ["a", "b"] });
17
- expect(spinner.getFrame()).toBe("a");
18
- });
19
- test("advances frames over time", () => {
20
- const spinner = new Spinner({ frames: ["a", "b", "c"], interval: 100 });
21
- // t=0 (1000)
22
- expect(spinner.getFrame()).toBe("a");
23
- // t=50 (1050) -> still frame 0
24
- now = 1050;
25
- expect(spinner.getFrame()).toBe("a");
26
- // t=100 (1100) -> frame 1
27
- now = 1100;
28
- expect(spinner.getFrame()).toBe("b");
29
- // t=200 (1200) -> frame 2
30
- now = 1200;
31
- expect(spinner.getFrame()).toBe("c");
32
- // t=300 (1300) -> frame 0 (loop)
33
- now = 1300;
34
- expect(spinner.getFrame()).toBe("a");
35
- });
36
- test("uses custom interval", () => {
37
- const spinner = new Spinner({ frames: ["a", "b"], interval: 50 });
38
- // t=0
39
- expect(spinner.getFrame()).toBe("a");
40
- // t=50 -> frame 1
41
- now = 1050;
42
- expect(spinner.getFrame()).toBe("b");
43
- });
44
- });
45
- describe("Spinner Presets", () => {
46
- test("dots preset exists and has frames", () => {
47
- expect(SPINNERS.dots).toBeDefined();
48
- expect(SPINNERS.dots.length).toBeGreaterThan(0);
49
- });
50
- test("lines preset exists", () => {
51
- expect(SPINNERS.lines).toBeDefined();
52
- });
53
- });
@@ -1,55 +0,0 @@
1
- import { computeMaxWidth, padLine } from "./utils";
2
- import { Printer } from "./printer";
3
- // -----------------
4
- // Core Layout & Printing
5
- // -----------------
6
- /**
7
- * Merges multiple columns of PrintLines into a single layout.
8
- * Ensures proper alignment by padding shorter lines.
9
- *
10
- * @param columns - Array of columns, where each column is an array of PrintLines.
11
- * @param separator - String used to separate columns.
12
- * @param defaultStyle - Style to apply to the separator and padding.
13
- * @param widths - Optional fixed widths for each column.
14
- * @returns A single array of PrintLines representing the merged output.
15
- */
16
- export function mergeMultipleColumns(columns, separator = " ", defaultStyle, widths) {
17
- if (columns.length === 0)
18
- return [];
19
- const maxLines = Math.max(...columns.map((c) => c.length));
20
- const colWidths = columns.map((col, i) => {
21
- if (widths?.[i] !== undefined)
22
- return widths[i];
23
- return computeMaxWidth(col);
24
- });
25
- const output = [];
26
- for (let i = 0; i < maxLines; i++) {
27
- let segments = [];
28
- for (let j = 0; j < columns.length; j++) {
29
- const line = columns[j][i] || { segments: [] };
30
- // If not the last column, pad it
31
- if (j < columns.length - 1) {
32
- const padded = padLine(line, colWidths[j], defaultStyle);
33
- segments = [...segments, ...padded.segments, { text: separator, style: defaultStyle }];
34
- }
35
- else {
36
- // Last column, just add segments
37
- segments = [...segments, ...line.segments];
38
- }
39
- }
40
- output.push({ segments });
41
- }
42
- return output;
43
- }
44
- /**
45
- * Prints multiple columns of styled content to the console.
46
- * A convenience wrapper around `mergeMultipleColumns` and `Printer.print`.
47
- *
48
- * @param columns - Array of columns to print.
49
- * @param options - Layout options (widths, separator, custom printer).
50
- */
51
- export function printColumns(columns, options = {}) {
52
- const { widths, separator = " ", printer = new Printer() } = options;
53
- const mergedLines = mergeMultipleColumns(columns, separator, undefined, widths);
54
- printer.print({ lines: mergedLines });
55
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,52 +0,0 @@
1
- import { expect, test, describe, spyOn, afterEach } from "bun:test";
2
- import { mergeMultipleColumns, printColumns } from "./layout";
3
- import { getLineLength } from "./utils";
4
- const lineA = { segments: [{ text: "Hello" }] };
5
- const lineB = { segments: [{ text: "World!!" }] };
6
- describe("Layout Utilities", () => {
7
- const stdoutSpy = spyOn(process.stdout, "write").mockImplementation(() => true);
8
- afterEach(() => {
9
- stdoutSpy.mockClear();
10
- });
11
- test("mergeMultipleColumns handles asymmetric column lengths", () => {
12
- // Column 1: [lineA]
13
- // Column 2: [lineB, lineB]
14
- // Separator: " | "
15
- // Default Style: undefined
16
- // Widths: [10] (first col width 10)
17
- const merged = mergeMultipleColumns([[lineA], [lineB, lineB]], " | ", undefined, [10]);
18
- expect(merged.length).toBe(2);
19
- // Second merged line:
20
- // Col 1 is empty (pad to 10) + " | " + Col 2 (lineB, length 7)
21
- // 10 + 3 + 7 = 20
22
- expect(getLineLength(merged[1])).toBe(20);
23
- });
24
- test("printColumns executes correctly", () => {
25
- printColumns([[lineA], [lineB]]);
26
- expect(stdoutSpy).toHaveBeenCalled();
27
- const output = stdoutSpy.mock.calls[0][0];
28
- expect(output).toContain("Hello");
29
- expect(output).toContain("World!!");
30
- });
31
- test("printColumns handles undefined style in segments", () => {
32
- const lineNoStyle = { segments: [{ text: "NoStyle" }] };
33
- printColumns([[lineNoStyle]]);
34
- expect(stdoutSpy).toHaveBeenCalled();
35
- const output = stdoutSpy.mock.calls[0][0];
36
- expect(output).toContain("NoStyle");
37
- });
38
- test("printColumns handles empty columns", () => {
39
- printColumns([]);
40
- // Should just print nothing or minimal output (if logic handles empty array gracefully)
41
- // mergeMultipleColumns returns []
42
- // printer.print({ lines: [] }) -> might output clear sequence or empty string
43
- expect(stdoutSpy).toHaveBeenCalled();
44
- });
45
- test("printColumns handles 3 columns", () => {
46
- printColumns([[lineA], [lineA], [lineB]]);
47
- expect(stdoutSpy).toHaveBeenCalled();
48
- const output = stdoutSpy.mock.calls[0][0];
49
- expect(output).toContain("Hello");
50
- expect(output).toContain("World!!");
51
- });
52
- });
@@ -1,129 +0,0 @@
1
- import { getGradientColor, mergeStyles, resolveStyle, RESET, interpolateColor, resolveModifiersToAnsi } from "./style";
2
- const ESC = "\x1b";
3
- /**
4
- * Handles rendering PrintBlocks to the terminal with support for interactive/live overwriting.
5
- */
6
- export class Printer {
7
- linesRendered = 0;
8
- isLive;
9
- data;
10
- constructor(options = {}) {
11
- this.isLive = options.live ?? false;
12
- this.data = options.data;
13
- }
14
- /**
15
- * Generates the clear sequence to move cursor and clear previously rendered lines.
16
- */
17
- getClearSequence() {
18
- if (!this.isLive || this.linesRendered === 0)
19
- return "";
20
- return `${ESC}[1A${ESC}[2K\r`.repeat(this.linesRendered);
21
- }
22
- /**
23
- * Clears the console using the stored line count.
24
- */
25
- clear() {
26
- if (this.linesRendered > 0) {
27
- process.stdout.write(this.getClearSequence());
28
- this.linesRendered = 0;
29
- }
30
- }
31
- /**
32
- * Renders the PrintBlock to the standard output.
33
- * If data is provided, updates the internal state.
34
- *
35
- * @param data - Optional data to update the printer with.
36
- */
37
- print(data) {
38
- if (data) {
39
- this.data = data;
40
- }
41
- if (!this.data) {
42
- return; // Nothing to print
43
- }
44
- let output = this.getClearSequence();
45
- const lines = this.data.lines;
46
- const blockStyle = this.data.style ?? {};
47
- lines.forEach((line, lineIndex) => {
48
- output += this.renderLine(line, lineIndex, lines.length, blockStyle);
49
- output += "\n";
50
- });
51
- process.stdout.write(output);
52
- this.linesRendered = lines.length;
53
- }
54
- /**
55
- * Resolves the block's vertical gradient (if any) to a solid color for the specific line.
56
- */
57
- resolveBlockColorForLine(blockStyle, lineIndex, totalLines) {
58
- if (!blockStyle.color)
59
- return undefined;
60
- if (Array.isArray(blockStyle.color)) {
61
- // Vertical Gradient
62
- if (totalLines <= 1)
63
- return blockStyle.color[0]; // Single line, use first color
64
- const colors = blockStyle.color;
65
- const factor = lineIndex / (totalLines - 1);
66
- // Interpolate manually to obtain Hex Color
67
- const f = Math.max(0, Math.min(1, factor));
68
- const segmentLength = 1 / (colors.length - 1);
69
- const segmentIndex = Math.min(Math.floor(f / segmentLength), colors.length - 2);
70
- const segmentFactor = (f - segmentIndex * segmentLength) / segmentLength;
71
- const c1 = colors[segmentIndex];
72
- const c2 = colors[segmentIndex + 1];
73
- return interpolateColor(c1, c2, segmentFactor);
74
- }
75
- return blockStyle.color;
76
- }
77
- /**
78
- * Renders a single line.
79
- */
80
- renderLine(line, lineIndex, totalLines, parentBlockStyle) {
81
- // 1. Resolve Block Gradient to Solid Color for this line
82
- const blockColorForLine = this.resolveBlockColorForLine(parentBlockStyle, lineIndex, totalLines);
83
- // 2. Create Base Line Style (Block Modifiers + Resolved Block Color)
84
- const baseLineStyle = {
85
- modifiers: parentBlockStyle.modifiers,
86
- color: blockColorForLine
87
- };
88
- // 3. Merge with Line's own style
89
- // If line.style has color, it overrides baseLineStyle.color
90
- const effectiveLineStyle = mergeStyles(baseLineStyle, line.style);
91
- // 4. Pre-calculate total chars for horizontal gradients
92
- const totalChars = line.segments.reduce((acc, seg) => acc + seg.text.length, 0);
93
- let currentCharIndex = 0;
94
- let lineOutput = "";
95
- line.segments.forEach((seg) => {
96
- const effectiveSegmentStyle = mergeStyles(effectiveLineStyle, seg.style);
97
- if (Array.isArray(effectiveSegmentStyle.color)) {
98
- // Gradient Handling (Horizontal)
99
- const colors = effectiveSegmentStyle.color;
100
- const text = seg.text;
101
- // Determine if we are using the Line's gradient (Global) or Segment's gradient (Local)
102
- // If effectiveSegmentStyle.color === effectiveLineStyle.color, it's inherited (Global)
103
- // Otherwise it's the segment's own gradient (Local)
104
- const isGlobalGradient = effectiveSegmentStyle.color === effectiveLineStyle.color;
105
- // Iterate characters to apply gradient
106
- const modifiersAnsi = resolveModifiersToAnsi(effectiveSegmentStyle.modifiers);
107
- for (let i = 0; i < text.length; i++) {
108
- let factor = 0;
109
- if (isGlobalGradient && totalChars > 1) {
110
- factor = (currentCharIndex + i) / (totalChars - 1);
111
- }
112
- else if (!isGlobalGradient && text.length > 1) {
113
- factor = i / (text.length - 1);
114
- }
115
- const colorAnsi = getGradientColor(colors, factor); // Returns ANSI Color Code
116
- lineOutput += `${modifiersAnsi}${colorAnsi}${text[i]}`;
117
- }
118
- lineOutput += RESET;
119
- }
120
- else {
121
- // Solid Color Handling
122
- const ansi = resolveStyle(effectiveSegmentStyle);
123
- lineOutput += `${ansi}${seg.text}${RESET}`;
124
- }
125
- currentCharIndex += seg.text.length;
126
- });
127
- return lineOutput;
128
- }
129
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,124 +0,0 @@
1
- import { expect, test, describe, spyOn, afterEach } from "bun:test";
2
- import { Printer } from "./printer";
3
- import { resolveColorToAnsi } from "./style";
4
- const ESC = "\x1b";
5
- describe("Printer", () => {
6
- // Mock process.stdout.write to prevent actual output during tests
7
- const stdoutSpy = spyOn(process.stdout, "write").mockImplementation(() => true);
8
- afterEach(() => {
9
- stdoutSpy.mockClear();
10
- });
11
- test("Printer.print outputs basic text with solid styles", () => {
12
- const printer = new Printer();
13
- const block = {
14
- lines: [{ segments: [{ text: "Hello", style: { color: "red" } }] }]
15
- };
16
- printer.print(block);
17
- expect(stdoutSpy).toHaveBeenCalledTimes(1);
18
- const output = stdoutSpy.mock.calls[0][0];
19
- // Check for Red ANSI + Text + Reset
20
- expect(output).toContain(`${ESC}[38;2;239;68;68mHello${ESC}[0m`);
21
- });
22
- test("Printer.print applies Block style to lines (inheritance)", () => {
23
- const printer = new Printer();
24
- const block = {
25
- style: { color: "blue", modifiers: ["bold"] },
26
- lines: [{ segments: [{ text: "Line 1" }] }, { segments: [{ text: "Line 2" }] }]
27
- };
28
- printer.print(block);
29
- const output = stdoutSpy.mock.calls[0][0];
30
- const blueAnsi = resolveColorToAnsi("blue");
31
- const boldAnsi = `${ESC}[1m`;
32
- // Both lines should be Blue + Bold
33
- // Matches: Bold + Blue + Text + Reset
34
- expect(output).toContain(`${boldAnsi}${blueAnsi}Line 1${ESC}[0m`);
35
- expect(output).toContain(`${boldAnsi}${blueAnsi}Line 2${ESC}[0m`);
36
- });
37
- test("Printer handles Block Vertical Gradient (Lines inherit solid colors)", () => {
38
- const printer = new Printer();
39
- const block = {
40
- style: { color: ["#000000", "#FFFFFF"] }, // Black to White
41
- lines: [
42
- { segments: [{ text: "Start" }] }, // Should be Black
43
- { segments: [{ text: "Middle" }] }, // Should be Gray
44
- { segments: [{ text: "End" }] } // Should be White
45
- ]
46
- };
47
- printer.print(block);
48
- const output = stdoutSpy.mock.calls[0][0];
49
- const blackAnsi = resolveColorToAnsi("#000000");
50
- const whiteAnsi = resolveColorToAnsi("#FFFFFF");
51
- const grayAnsi = resolveColorToAnsi("#808080");
52
- expect(output).toContain(`${blackAnsi}Start${ESC}[0m`);
53
- expect(output).toContain(`${grayAnsi}Middle${ESC}[0m`);
54
- expect(output).toContain(`${whiteAnsi}End${ESC}[0m`);
55
- });
56
- test("Printer handles Line Override (Horizontal Gradient)", () => {
57
- const printer = new Printer();
58
- const block = {
59
- lines: [
60
- {
61
- style: { color: ["#FF0000", "#0000FF"] }, // Red to Blue
62
- segments: [{ text: "GB" }] // Gradient applies to these 2 chars
63
- }
64
- ]
65
- };
66
- printer.print(block);
67
- const output = stdoutSpy.mock.calls[0][0];
68
- // First char 'G' should be Red (start)
69
- // Second char 'B' should be Blue (end) - wait, factor logic?
70
- // Length 2. index 0 -> factor 0. index 1 -> factor 1.
71
- const redAnsi = resolveColorToAnsi("#FF0000");
72
- const blueAnsi = resolveColorToAnsi("#0000FF");
73
- expect(output).toContain(`${redAnsi}G`);
74
- expect(output).toContain(`${blueAnsi}B`);
75
- });
76
- test("Printer handles Segment Override (Solid overrides Line Gradient)", () => {
77
- const printer = new Printer();
78
- const block = {
79
- lines: [
80
- {
81
- style: { color: ["#FF0000", "#0000FF"] }, // Line Gradient
82
- segments: [
83
- { text: "A" }, // Inherits Gradient (Red)
84
- { text: "B", style: { color: "green" } } // Override Solid (Green)
85
- ]
86
- }
87
- ]
88
- };
89
- printer.print(block);
90
- const output = stdoutSpy.mock.calls[0][0];
91
- const redAnsi = resolveColorToAnsi("#FF0000");
92
- const greenAnsi = resolveColorToAnsi("green");
93
- expect(output).toContain(`${redAnsi}A`);
94
- expect(output).toContain(`${greenAnsi}B`);
95
- });
96
- test("Printer handles live clearing", () => {
97
- const printer = new Printer({ live: true });
98
- // Print 2 lines
99
- printer.print({
100
- lines: [{ segments: [{ text: "1" }] }, { segments: [{ text: "2" }] }]
101
- });
102
- // Print again (should clear 2 lines)
103
- printer.print({
104
- lines: [{ segments: [{ text: "New" }] }]
105
- });
106
- const clearSeq = `${ESC}[1A${ESC}[2K\r`;
107
- const expectedClear = clearSeq.repeat(2);
108
- const secondCallOutput = stdoutSpy.mock.calls[1][0];
109
- expect(secondCallOutput.startsWith(expectedClear)).toBe(true);
110
- });
111
- test("Printer.clear() manually clears the output", () => {
112
- const printer = new Printer({ live: true });
113
- printer.print({
114
- lines: [{ segments: [{ text: "Line 1" }] }]
115
- });
116
- expect(stdoutSpy).toHaveBeenCalledTimes(1);
117
- printer.clear();
118
- expect(stdoutSpy).toHaveBeenCalledTimes(2);
119
- const clearSeq = `${ESC}[1A${ESC}[2K\r`;
120
- const expectedClear = clearSeq.repeat(1);
121
- const clearOutput = stdoutSpy.mock.calls[1][0];
122
- expect(clearOutput).toBe(expectedClear);
123
- });
124
- });
@@ -1,171 +0,0 @@
1
- // -----------------
2
- // Color Utilities
3
- // -----------------
4
- const ESC = "\x1b";
5
- /**
6
- * ANSI escape sequence to reset all styles.
7
- */
8
- export const RESET = `${ESC}[0m`;
9
- const STANDARD_COLORS = {
10
- black: "#000000",
11
- red: "#EF4444", // Tailwind Red-500
12
- green: "#10B981", // Tailwind Emerald-500
13
- yellow: "#F59E0B", // Tailwind Amber-500
14
- blue: "#3B82F6", // Tailwind Blue-500
15
- magenta: "#EC4899", // Tailwind Pink-500
16
- cyan: "#06B6D4", // Tailwind Cyan-500
17
- white: "#FFFFFF",
18
- gray: "#6B7280", // Tailwind Gray-500
19
- grey: "#6B7280"
20
- };
21
- const MODIFIER_CODES = {
22
- default: "0",
23
- bold: "1",
24
- dim: "2",
25
- italic: "3",
26
- underline: "4",
27
- inverse: "7",
28
- hidden: "8",
29
- strikethrough: "9"
30
- };
31
- /**
32
- * Converts any Color (hex or standard name) to a Hex string.
33
- */
34
- export function colorToHex(color) {
35
- if (color.startsWith("#"))
36
- return color;
37
- const hex = STANDARD_COLORS[color.toLowerCase()];
38
- if (!hex)
39
- return "#FFFFFF"; // Fallback
40
- return hex;
41
- }
42
- /**
43
- * Converts a hex color string to an RGB object.
44
- */
45
- export function hexToRgb(hex) {
46
- const h = hex.replace(/^#/, "");
47
- if (h.length !== 6)
48
- return { r: 255, g: 255, b: 255 }; // Fallback for invalid hex
49
- return {
50
- r: parseInt(h.substring(0, 2), 16),
51
- g: parseInt(h.substring(2, 4), 16),
52
- b: parseInt(h.substring(4, 6), 16)
53
- };
54
- }
55
- /**
56
- * Converts RGB to a 24-bit ANSI foreground color escape sequence.
57
- */
58
- export function rgbToAnsi(r, g, b) {
59
- return `${ESC}[38;2;${r};${g};${b}m`;
60
- }
61
- /**
62
- * Converts any Color to an ANSI escape sequence.
63
- */
64
- export function resolveColorToAnsi(color) {
65
- const hex = colorToHex(color);
66
- const { r, g, b } = hexToRgb(hex);
67
- return rgbToAnsi(r, g, b);
68
- }
69
- /**
70
- * Converts a list of modifiers to an ANSI escape sequence.
71
- */
72
- export function resolveModifiersToAnsi(modifiers) {
73
- if (!modifiers || modifiers.length === 0)
74
- return "";
75
- return modifiers
76
- .map((m) => {
77
- const code = MODIFIER_CODES[m];
78
- return code ? `${ESC}[${code}m` : "";
79
- })
80
- .join("");
81
- }
82
- /**
83
- * Helper to convert number to 2-digit hex.
84
- */
85
- function toHex(c) {
86
- const hex = Math.max(0, Math.min(255, Math.round(c))).toString(16);
87
- return hex.length === 1 ? "0" + hex : hex;
88
- }
89
- /**
90
- * Interpolates between two hex colors.
91
- */
92
- export function interpolateHex(color1, color2, factor) {
93
- const f = Math.max(0, Math.min(1, factor));
94
- const c1 = hexToRgb(color1);
95
- const c2 = hexToRgb(color2);
96
- const r = c1.r + f * (c2.r - c1.r);
97
- const g = c1.g + f * (c2.g - c1.g);
98
- const b = c1.b + f * (c2.b - c1.b);
99
- return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
100
- }
101
- /**
102
- * Public interpolation function that accepts any Color type.
103
- */
104
- export function interpolateColor(color1, color2, factor) {
105
- return interpolateHex(colorToHex(color1), colorToHex(color2), factor);
106
- }
107
- /**
108
- * logic to get a specific color from a multi-stop gradient array at a specific factor (0-1).
109
- */
110
- export function getGradientColor(colors, factor) {
111
- if (colors.length === 0)
112
- return "";
113
- if (colors.length === 1)
114
- return resolveColorToAnsi(colors[0]);
115
- const f = Math.max(0, Math.min(1, factor));
116
- // Map factor to segments between colors
117
- // e.g. 3 colors: [0, 0.5, 1]. factor 0.25 is in first segment (0.5 of way through)
118
- const segmentLength = 1 / (colors.length - 1);
119
- const segmentIndex = Math.min(Math.floor(f / segmentLength), colors.length - 2);
120
- const segmentFactor = (f - segmentIndex * segmentLength) / segmentLength;
121
- const c1 = colors[segmentIndex];
122
- const c2 = colors[segmentIndex + 1];
123
- const hex = interpolateColor(c1, c2, segmentFactor);
124
- return resolveColorToAnsi(hex);
125
- }
126
- // -----------------
127
- // Style Merging
128
- // -----------------
129
- /**
130
- * Merges a child style into a parent style.
131
- * - Modifiers are combined (union).
132
- * - Child color overrides parent color.
133
- */
134
- export function mergeStyles(parent, child) {
135
- if (!parent && !child)
136
- return {};
137
- if (!parent)
138
- return child ?? {};
139
- if (!child)
140
- return parent;
141
- const mergedModifiers = Array.from(new Set([...(parent.modifiers ?? []), ...(child.modifiers ?? [])]));
142
- return {
143
- modifiers: mergedModifiers,
144
- color: child.color ?? parent.color
145
- };
146
- }
147
- /**
148
- * Resolves a style object into an ANSI string.
149
- * If the color is a gradient (array), it uses the provided factor (0-1) to pick the color.
150
- * Defaults to factor 0 if not provided.
151
- */
152
- export function resolveStyle(style, gradientFactor = 0) {
153
- if (!style)
154
- return "";
155
- let ansi = "";
156
- if (style.modifiers) {
157
- ansi += resolveModifiersToAnsi(style.modifiers);
158
- }
159
- if (style.color) {
160
- if (Array.isArray(style.color)) {
161
- // Gradient
162
- const hex = getGradientColor(style.color, gradientFactor);
163
- ansi += hex;
164
- }
165
- else {
166
- // Solid
167
- ansi += resolveColorToAnsi(style.color);
168
- }
169
- }
170
- return ansi;
171
- }
@@ -1 +0,0 @@
1
- export {};