@cjser/chalk 5.6.2-cjser.2 → 6.0.0-cjser.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/source/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- // TODO: Make it this when TS suports that.
1
+ // TODO: Make it this when TS supports that.
2
2
  // import {ModifierName, ForegroundColor, BackgroundColor, ColorName} from '#ansi-styles';
3
3
  // import {ColorInfo, ColorSupportLevel} from '#supports-color';
4
4
  import {
@@ -20,8 +20,12 @@ export interface Options {
20
20
  - `1` - Basic 16 colors support.
21
21
  - `2` - ANSI 256 colors support.
22
22
  - `3` - Truecolor 16 million colors support.
23
+
24
+ Omit this option, or pass `undefined`, to have the level detected instead.
25
+
26
+ @throws If the value is neither `undefined` nor an integer from 0 to 3.
23
27
  */
24
- readonly level?: ColorSupportLevel;
28
+ readonly level?: ColorSupportLevel | undefined;
25
29
  }
26
30
 
27
31
  /**
@@ -42,6 +46,8 @@ export interface ChalkInstance {
42
46
  - `1` - Basic 16 colors support.
43
47
  - `2` - ANSI 256 colors support.
44
48
  - `3` - Truecolor 16 million colors support.
49
+
50
+ @throws If the assigned value is not an integer from 0 to 3.
45
51
  */
46
52
  level: ColorSupportLevel;
47
53
 
@@ -74,6 +80,8 @@ export interface ChalkInstance {
74
80
  /**
75
81
  Use an [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set text color.
76
82
 
83
+ The value is downsampled to the 16-color palette on terminals that only support basic colors (level 1), so `chalk.ansi256(196)` becomes 91 (ANSI escape for bright red).
84
+
77
85
  @example
78
86
  ```
79
87
  import chalk from '@cjser/chalk';
@@ -110,7 +118,9 @@ export interface ChalkInstance {
110
118
  bgHex: (color: string) => this;
111
119
 
112
120
  /**
113
- Use a [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set background color.
121
+ Use an [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set background color.
122
+
123
+ The value is downsampled to the 16-color palette on terminals that only support basic colors (level 1), so `chalk.bgAnsi256(196)` becomes 101 (ANSI escape for bright red background).
114
124
 
115
125
  @example
116
126
  ```
@@ -121,6 +131,52 @@ export interface ChalkInstance {
121
131
  */
122
132
  bgAnsi256: (index: number) => this;
123
133
 
134
+ /**
135
+ Use RGB values to set underline color.
136
+
137
+ The underline color is only visible when an underline style is also applied.
138
+
139
+ @example
140
+ ```
141
+ import chalk from '@cjser/chalk';
142
+
143
+ chalk.underlineRgb(222, 173, 237).underlineCurly('Hello, world!');
144
+ ```
145
+ */
146
+ underlineRgb: (red: number, green: number, blue: number) => this;
147
+
148
+ /**
149
+ Use HEX value to set underline color.
150
+
151
+ The underline color is only visible when an underline style is also applied.
152
+
153
+ @param color - Hexadecimal value representing the desired color.
154
+
155
+ @example
156
+ ```
157
+ import chalk from '@cjser/chalk';
158
+
159
+ chalk.underlineHex('#DEADED').underlineCurly('Hello, world!');
160
+ ```
161
+ */
162
+ underlineHex: (color: string) => this;
163
+
164
+ /**
165
+ Use an [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set underline color.
166
+
167
+ The underline color is only visible when an underline style is also applied.
168
+
169
+ The value is downsampled to the first 16 palette entries on terminals that only support basic colors (level 1), so `chalk.underlineAnsi256(196)` becomes 9 (the palette index for bright red).
170
+
171
+ @example
172
+ ```
173
+ import chalk from '@cjser/chalk';
174
+
175
+ chalk.underlineAnsi256(201).underlineCurly('Hello, world!');
176
+ ```
177
+ */
178
+ underlineAnsi256: (index: number) => this;
179
+
124
180
  /**
125
181
  Modifier: Reset the current style.
126
182
  */
@@ -146,6 +202,26 @@ export interface ChalkInstance {
146
202
  */
147
203
  readonly underline: this;
148
204
 
205
+ /**
206
+ Modifier: Put a double horizontal line below the text. *(Not widely supported)*
207
+ */
208
+ readonly underlineDouble: this;
209
+
210
+ /**
211
+ Modifier: Put a curly horizontal line below the text. *(Not widely supported)*
212
+ */
213
+ readonly underlineCurly: this;
214
+
215
+ /**
216
+ Modifier: Put a dotted horizontal line below the text. *(Not widely supported)*
217
+ */
218
+ readonly underlineDotted: this;
219
+
220
+ /**
221
+ Modifier: Put a dashed horizontal line below the text. *(Not widely supported)*
222
+ */
223
+ readonly underlineDashed: this;
224
+
149
225
  /**
150
226
  Modifier: Put a horizontal line above the text. *(Not widely supported)*
151
227
  */
@@ -182,12 +258,12 @@ export interface ChalkInstance {
182
258
  readonly cyan: this;
183
259
  readonly white: this;
184
260
 
185
- /*
261
+ /**
186
262
  Alias for `blackBright`.
187
263
  */
188
264
  readonly gray: this;
189
265
 
190
- /*
266
+ /**
191
267
  Alias for `blackBright`.
192
268
  */
193
269
  readonly grey: this;
@@ -210,12 +286,12 @@ export interface ChalkInstance {
210
286
  readonly bgCyan: this;
211
287
  readonly bgWhite: this;
212
288
 
213
- /*
289
+ /**
214
290
  Alias for `bgBlackBright`.
215
291
  */
216
292
  readonly bgGray: this;
217
293
 
218
- /*
294
+ /**
219
295
  Alias for `bgBlackBright`.
220
296
  */
221
297
  readonly bgGrey: this;
@@ -228,6 +304,34 @@ export interface ChalkInstance {
228
304
  readonly bgMagentaBright: this;
229
305
  readonly bgCyanBright: this;
230
306
  readonly bgWhiteBright: this;
307
+
308
+ readonly underlineBlack: this;
309
+ readonly underlineRed: this;
310
+ readonly underlineGreen: this;
311
+ readonly underlineYellow: this;
312
+ readonly underlineBlue: this;
313
+ readonly underlineMagenta: this;
314
+ readonly underlineCyan: this;
315
+ readonly underlineWhite: this;
316
+
317
+ /**
318
+ Alias for `underlineBlackBright`.
319
+ */
320
+ readonly underlineGray: this;
321
+
322
+ /**
323
+ Alias for `underlineBlackBright`.
324
+ */
325
+ readonly underlineGrey: this;
326
+
327
+ readonly underlineBlackBright: this;
328
+ readonly underlineRedBright: this;
329
+ readonly underlineGreenBright: this;
330
+ readonly underlineYellowBright: this;
331
+ readonly underlineBlueBright: this;
332
+ readonly underlineMagentaBright: this;
333
+ readonly underlineCyanBright: this;
334
+ readonly underlineWhiteBright: this;
231
335
  }
232
336
 
233
337
  /**
@@ -247,8 +351,16 @@ export const chalkStderr: typeof chalk;
247
351
  export const supportsColorStderr: typeof supportsColor;
248
352
 
249
353
  export {
250
- ModifierName, ForegroundColorName, BackgroundColorName, ColorName,
251
- modifierNames, foregroundColorNames, backgroundColorNames, colorNames,
354
+ ModifierName,
355
+ ForegroundColorName,
356
+ BackgroundColorName,
357
+ UnderlineColorName,
358
+ ColorName,
359
+ modifierNames,
360
+ foregroundColorNames,
361
+ backgroundColorNames,
362
+ underlineColorNames,
363
+ colorNames,
252
364
  // } from '#ansi-styles';
253
365
  } from './vendor/ansi-styles/index.js';
254
366
 
@@ -299,27 +411,27 @@ export type Color = ColorName;
299
411
 
300
412
  Basic modifier names.
301
413
  */
302
- export const modifiers: readonly Modifiers[];
414
+ export const modifiers: readonly ModifierName[];
303
415
 
304
416
  /**
305
417
  @deprecated Use `foregroundColorNames` instead.
306
418
 
307
419
  Basic foreground color names.
308
420
  */
309
- export const foregroundColors: readonly ForegroundColor[];
421
+ export const foregroundColors: readonly ForegroundColorName[];
310
422
 
311
423
  /**
312
424
  @deprecated Use `backgroundColorNames` instead.
313
425
 
314
426
  Basic background color names.
315
427
  */
316
- export const backgroundColors: readonly BackgroundColor[];
428
+ export const backgroundColors: readonly BackgroundColorName[];
317
429
 
318
430
  /**
319
431
  @deprecated Use `colorNames` instead.
320
432
 
321
433
  Basic color names. The combination of foreground and background color names.
322
434
  */
323
- export const colors: readonly Color[];
435
+ export const colors: readonly ColorName[];
324
436
 
325
437
  export default chalk;
package/source/index.js CHANGED
@@ -1,34 +1,45 @@
1
- import ansiStyles from '#ansi-styles';
2
- import supportsColor from '#supports-color';
3
- import { // eslint-disable-line import/order
1
+ import {
4
2
  stringReplaceAll,
5
3
  stringEncaseCRLFWithFirstIndex,
6
4
  } from './utilities.js';
5
+ import ansiStyles from '#ansi-styles';
6
+ import supportsColor from '#supports-color';
7
7
 
8
8
  const {stdout: stdoutColor, stderr: stderrColor} = supportsColor;
9
9
 
10
10
  const GENERATOR = Symbol('GENERATOR');
11
11
  const STYLER = Symbol('STYLER');
12
12
  const IS_EMPTY = Symbol('IS_EMPTY');
13
-
14
- // `supportsColor.level` → `ansiStyles.color[name]` mapping
15
- const levelMapping = [
16
- 'ansi',
17
- 'ansi',
18
- 'ansi256',
19
- 'ansi16m',
20
- ];
13
+ const LEVEL = Symbol('LEVEL');
21
14
 
22
15
  const styles = Object.create(null);
23
16
 
17
+ const assertValidLevel = level => {
18
+ if (!Number.isSafeInteger(level) || level < 0 || level > 3) {
19
+ throw new Error('The `level` should be an integer from 0 to 3');
20
+ }
21
+ };
22
+
23
+ // The level is stored under a symbol so the hot path can read it as a plain property, while `level` itself is an accessor that rejects values the rest of the code could not handle.
24
+ const levelDescriptor = {
25
+ enumerable: true,
26
+ get() {
27
+ return this[LEVEL];
28
+ },
29
+ set(level) {
30
+ assertValidLevel(level);
31
+ this[LEVEL] = level;
32
+ },
33
+ };
34
+
24
35
  const applyOptions = (object, options = {}) => {
25
- if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
26
- throw new Error('The `level` option should be an integer from 0 to 3');
36
+ if (options.level !== undefined) {
37
+ assertValidLevel(options.level);
27
38
  }
28
39
 
29
- // Detect level if not set manually
40
+ // Detect level if not set manually. Written under the symbol rather than through `level`, as the prototype carrying that accessor is not installed until after this runs.
30
41
  const colorLevel = stdoutColor ? stdoutColor.level : 0;
31
- object.level = options.level === undefined ? colorLevel : options.level;
42
+ object[LEVEL] = options.level === undefined ? colorLevel : options.level;
32
43
  };
33
44
 
34
45
  export class Chalk {
@@ -51,6 +62,7 @@ function createChalk(options) {
51
62
  return chalkFactory(options);
52
63
  }
53
64
 
65
+ // eslint-disable-next-line unicorn/no-top-level-side-effects -- The prototype chain must be set up at module load.
54
66
  Object.setPrototypeOf(createChalk.prototype, Function.prototype);
55
67
 
56
68
  for (const [styleName, style] of Object.entries(ansiStyles)) {
@@ -71,63 +83,71 @@ styles.visible = {
71
83
  },
72
84
  };
73
85
 
74
- const getModelAnsi = (model, level, type, ...arguments_) => {
75
- if (model === 'rgb') {
76
- if (level === 'ansi16m') {
77
- return ansiStyles[type].ansi16m(...arguments_);
78
- }
79
-
80
- if (level === 'ansi256') {
81
- return ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_));
82
- }
86
+ // Resolve a color model to one converter per `level`, so that a call only has to look up the converter for the current level instead of re-deciding the model and level every time.
87
+ const createModelConverters = (model, type) => {
88
+ const style = ansiStyles[type];
83
89
 
84
- return ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_));
90
+ if (model === 'rgb') {
91
+ const ansi = (red, green, blue) => style.ansi(ansiStyles.rgbToAnsi(red, green, blue));
92
+ const ansi256 = (red, green, blue) => style.ansi256(ansiStyles.rgbToAnsi256(red, green, blue));
93
+ return [ansi, ansi, ansi256, style.ansi16m];
85
94
  }
86
95
 
87
96
  if (model === 'hex') {
88
- return getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_));
97
+ const ansi = hex => style.ansi(ansiStyles.hexToAnsi(hex));
98
+ const ansi256 = hex => style.ansi256(ansiStyles.hexToAnsi256(hex));
99
+ return [ansi, ansi, ansi256, hex => style.ansi16m(...ansiStyles.hexToRgb(hex))];
89
100
  }
90
101
 
91
- return ansiStyles[type][model](...arguments_);
102
+ // `ansi256` is already the native form, so only the 16-color levels need converting.
103
+ const ansi = code => style.ansi(ansiStyles.ansi256ToAnsi(code));
104
+ return [ansi, ansi, style.ansi256, style.ansi256];
92
105
  };
93
106
 
94
107
  const usedModels = ['rgb', 'hex', 'ansi256'];
95
108
 
96
109
  for (const model of usedModels) {
97
- styles[model] = {
98
- get() {
99
- const {level} = this;
100
- return function (...arguments_) {
101
- const styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]);
102
- return createBuilder(this, styler, this[IS_EMPTY]);
103
- };
104
- },
105
- };
106
-
107
- const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
108
- styles[bgModel] = {
109
- get() {
110
- const {level} = this;
111
- return function (...arguments_) {
112
- const styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]);
113
- return createBuilder(this, styler, this[IS_EMPTY]);
114
- };
115
- },
116
- };
110
+ const capitalizedModel = model[0].toUpperCase() + model.slice(1);
111
+
112
+ for (const [styleName, type] of [
113
+ [model, 'color'],
114
+ ['bg' + capitalizedModel, 'bgColor'],
115
+ ['underline' + capitalizedModel, 'underlineColor'],
116
+ ]) {
117
+ const {close} = ansiStyles[type];
118
+ const converters = createModelConverters(model, type);
119
+
120
+ styles[styleName] = {
121
+ get() {
122
+ // The level is read on call rather than captured here so the function can be cached on the instance instead of being reallocated on every property access.
123
+ // `rgb` is the widest model, so naming the three parameters avoids a rest array.
124
+ const styleFunction = function (first, second, third) {
125
+ const open = converters[this.level](first, second, third);
126
+ return createBuilder(this, createStyler(open, close, this[STYLER]), this[IS_EMPTY]);
127
+ };
128
+
129
+ Object.defineProperty(this, styleName, {value: styleFunction});
130
+ return styleFunction;
131
+ },
132
+ };
133
+ }
117
134
  }
118
135
 
119
- const proto = Object.defineProperties(() => {}, {
120
- ...styles,
121
- level: {
122
- enumerable: true,
123
- get() {
124
- return this[GENERATOR].level;
125
- },
126
- set(level) {
127
- this[GENERATOR].level = level;
136
+ const proto = Object.defineProperties(
137
+ () => {},
138
+ {
139
+ ...styles,
140
+ level: {
141
+ enumerable: true,
142
+ get() {
143
+ return this[GENERATOR].level;
144
+ },
145
+ set(level) {
146
+ this[GENERATOR].level = level;
147
+ },
128
148
  },
129
149
  },
130
- });
150
+ );
131
151
 
132
152
  const createStyler = (open, close, parent) => {
133
153
  let openAll;
@@ -151,14 +171,25 @@ const createStyler = (open, close, parent) => {
151
171
 
152
172
  const createBuilder = (self, _styler, _isEmpty) => {
153
173
  // Single argument is hot path, implicit coercion is faster than anything
154
- // eslint-disable-next-line no-implicit-coercion
155
- const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));
174
+ const builder = (...arguments_) => {
175
+ if (arguments_.length === 1) {
176
+ // eslint-disable-next-line no-implicit-coercion
177
+ return applyStyle(builder, '' + arguments_[0]);
178
+ }
179
+
180
+ if (arguments_.length === 2) {
181
+ return applyStyle(builder, arguments_[0] + ' ' + arguments_[1]);
182
+ }
183
+
184
+ return applyStyle(builder, arguments_.join(' '));
185
+ };
156
186
 
157
187
  // We alter the prototype because we must return a function, but there is
158
188
  // no way to create a function with a different prototype
159
189
  Object.setPrototypeOf(builder, proto);
160
190
 
161
- builder[GENERATOR] = self;
191
+ // Point every builder at the root generator instead of its immediate parent, so reading the level costs one property load rather than walking a `level` getter per link of the chain.
192
+ builder[GENERATOR] = self[GENERATOR] ?? self;
162
193
  builder[STYLER] = _styler;
163
194
  builder[IS_EMPTY] = _isEmpty;
164
195
 
@@ -166,7 +197,9 @@ const createBuilder = (self, _styler, _isEmpty) => {
166
197
  };
167
198
 
168
199
  const applyStyle = (self, string) => {
169
- if (self.level <= 0 || !string) {
200
+ // Read the level directly off the generator to skip the `level` getter dispatch on this hot path
201
+ if (self[GENERATOR][LEVEL] <= 0 || !string) {
202
+ // eslint-disable-next-line unicorn/no-computed-property-existence-check -- Reads the boolean value, not a property existence check.
170
203
  return self[IS_EMPTY] ? '' : string;
171
204
  }
172
205
 
@@ -177,7 +210,7 @@ const applyStyle = (self, string) => {
177
210
  }
178
211
 
179
212
  const {openAll, closeAll} = styler;
180
- if (string.includes('\u001B')) {
213
+ if (string.includes('\u{1B}')) {
181
214
  while (styler !== undefined) {
182
215
  // Replace any instances already present with a re-opening code
183
216
  // otherwise only the part of the string until said closing code
@@ -199,7 +232,9 @@ const applyStyle = (self, string) => {
199
232
  return openAll + string + closeAll;
200
233
  };
201
234
 
202
- Object.defineProperties(createChalk.prototype, styles);
235
+ // `level` lives on the prototype rather than on each instance, so it costs nothing to construct an instance and matches how builders already expose it. It is inherited rather than own, so it does not show up in `Object.keys()`, same as for a builder.
236
+ // eslint-disable-next-line unicorn/no-top-level-side-effects -- The style getters must be installed at module load.
237
+ Object.defineProperties(createChalk.prototype, {...styles, level: levelDescriptor});
203
238
 
204
239
  const chalk = createChalk();
205
240
  export const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0});
@@ -208,6 +243,7 @@ export {
208
243
  modifierNames,
209
244
  foregroundColorNames,
210
245
  backgroundColorNames,
246
+ underlineColorNames,
211
247
  colorNames,
212
248
 
213
249
  // TODO: Remove these aliases in the next major version
@@ -1,5 +1,5 @@
1
- // TODO: When targeting Node.js 16, use `String.prototype.replaceAll`.
2
- export function stringReplaceAll(string, substring, replacer) {
1
+ // Note: Each match is kept and `postfix` is inserted after it. `String#replaceAll(substring, substring + postfix)` does the same, but it has to scan the replacement for `$` patterns and it is several times slower on the no-match path that most calls take.
2
+ export function stringReplaceAll(string, substring, postfix) {
3
3
  let index = string.indexOf(substring);
4
4
  if (index === -1) {
5
5
  return string;
@@ -9,7 +9,7 @@ export function stringReplaceAll(string, substring, replacer) {
9
9
  let endIndex = 0;
10
10
  let returnValue = '';
11
11
  do {
12
- returnValue += string.slice(endIndex, index) + substring + replacer;
12
+ returnValue += string.slice(endIndex, index) + substring + postfix;
13
13
  endIndex = index + substringLength;
14
14
  index = string.indexOf(substring, endIndex);
15
15
  } while (index !== -1);
@@ -22,8 +22,8 @@ export function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
22
22
  let endIndex = 0;
23
23
  let returnValue = '';
24
24
  do {
25
- const gotCR = string[index - 1] === '\r';
26
- returnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\r\n' : '\n') + postfix;
25
+ const isGotCR = string[index - 1] === '\r';
26
+ returnValue += string.slice(endIndex, (isGotCR ? index - 1 : index)) + prefix + (isGotCR ? '\r\n' : '\n') + postfix;
27
27
  endIndex = index + 1;
28
28
  index = string.indexOf('\n', endIndex);
29
29
  } while (index !== -1);
@@ -1,4 +1,4 @@
1
- export interface CSPair { // eslint-disable-line @typescript-eslint/naming-convention
1
+ export type CSPair = { // eslint-disable-line @typescript-eslint/naming-convention
2
2
  /**
3
3
  The ANSI terminal control sequence for starting this style.
4
4
  */
@@ -8,9 +8,9 @@ export interface CSPair { // eslint-disable-line @typescript-eslint/naming-conve
8
8
  The ANSI terminal control sequence for ending this style.
9
9
  */
10
10
  readonly close: string;
11
- }
11
+ };
12
12
 
13
- export interface ColorBase {
13
+ export type ColorBase = {
14
14
  /**
15
15
  The ANSI terminal control sequence for ending this color.
16
16
  */
@@ -21,9 +21,9 @@ export interface ColorBase {
21
21
  ansi256(code: number): string;
22
22
 
23
23
  ansi16m(red: number, green: number, blue: number): string;
24
- }
24
+ };
25
25
 
26
- export interface Modifier {
26
+ export type Modifier = {
27
27
  /**
28
28
  Resets the current color chain.
29
29
  */
@@ -45,12 +45,32 @@ export interface Modifier {
45
45
  readonly italic: CSPair;
46
46
 
47
47
  /**
48
- Make text underline. (Not widely supported)
48
+ Put a horizontal line below the text. (Not widely supported)
49
49
  */
50
50
  readonly underline: CSPair;
51
51
 
52
52
  /**
53
- Make text overline.
53
+ Put a double horizontal line below the text. (Not widely supported)
54
+ */
55
+ readonly underlineDouble: CSPair;
56
+
57
+ /**
58
+ Put a curly horizontal line below the text. (Not widely supported)
59
+ */
60
+ readonly underlineCurly: CSPair;
61
+
62
+ /**
63
+ Put a dotted horizontal line below the text. (Not widely supported)
64
+ */
65
+ readonly underlineDotted: CSPair;
66
+
67
+ /**
68
+ Put a dashed horizontal line below the text. (Not widely supported)
69
+ */
70
+ readonly underlineDashed: CSPair;
71
+
72
+ /**
73
+ Put a horizontal line above the text.
54
74
 
55
75
  Supported on VTE-based terminals, the GNOME terminal, mintty, and Git Bash.
56
76
  */
@@ -70,9 +90,9 @@ export interface Modifier {
70
90
  Puts a horizontal line through the center of the text. (Not widely supported)
71
91
  */
72
92
  readonly strikethrough: CSPair;
73
- }
93
+ };
74
94
 
75
- export interface ForegroundColor {
95
+ export type ForegroundColor = {
76
96
  readonly black: CSPair;
77
97
  readonly red: CSPair;
78
98
  readonly green: CSPair;
@@ -100,9 +120,9 @@ export interface ForegroundColor {
100
120
  readonly cyanBright: CSPair;
101
121
  readonly magentaBright: CSPair;
102
122
  readonly whiteBright: CSPair;
103
- }
123
+ };
104
124
 
105
- export interface BackgroundColor {
125
+ export type BackgroundColor = {
106
126
  readonly bgBlack: CSPair;
107
127
  readonly bgRed: CSPair;
108
128
  readonly bgGreen: CSPair;
@@ -130,9 +150,39 @@ export interface BackgroundColor {
130
150
  readonly bgCyanBright: CSPair;
131
151
  readonly bgMagentaBright: CSPair;
132
152
  readonly bgWhiteBright: CSPair;
133
- }
153
+ };
154
+
155
+ export type UnderlineColor = {
156
+ readonly underlineBlack: CSPair;
157
+ readonly underlineRed: CSPair;
158
+ readonly underlineGreen: CSPair;
159
+ readonly underlineYellow: CSPair;
160
+ readonly underlineBlue: CSPair;
161
+ readonly underlineCyan: CSPair;
162
+ readonly underlineMagenta: CSPair;
163
+ readonly underlineWhite: CSPair;
164
+
165
+ /**
166
+ Alias for `underlineBlackBright`.
167
+ */
168
+ readonly underlineGray: CSPair;
134
169
 
135
- export interface ConvertColor {
170
+ /**
171
+ Alias for `underlineBlackBright`.
172
+ */
173
+ readonly underlineGrey: CSPair;
174
+
175
+ readonly underlineBlackBright: CSPair;
176
+ readonly underlineRedBright: CSPair;
177
+ readonly underlineGreenBright: CSPair;
178
+ readonly underlineYellowBright: CSPair;
179
+ readonly underlineBlueBright: CSPair;
180
+ readonly underlineCyanBright: CSPair;
181
+ readonly underlineMagentaBright: CSPair;
182
+ readonly underlineWhiteBright: CSPair;
183
+ };
184
+
185
+ export type ConvertColor = {
136
186
  /**
137
187
  Convert from the RGB color space to the ANSI 256 color space.
138
188
 
@@ -178,7 +228,7 @@ export interface ConvertColor {
178
228
  @param hex - A hexadecimal string containing RGB data.
179
229
  */
180
230
  hexToAnsi(hex: string): number;
181
- }
231
+ };
182
232
 
183
233
  /**
184
234
  Basic modifier names.
@@ -199,6 +249,13 @@ Basic background color names.
199
249
  */
200
250
  export type BackgroundColorName = keyof BackgroundColor;
201
251
 
252
+ /**
253
+ Basic underline color names.
254
+
255
+ [More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
256
+ */
257
+ export type UnderlineColorName = keyof UnderlineColor;
258
+
202
259
  /**
203
260
  Basic color names. The combination of foreground and background color names.
204
261
 
@@ -221,7 +278,12 @@ Basic background color names.
221
278
  */
222
279
  export const backgroundColorNames: readonly BackgroundColorName[];
223
280
 
224
- /*
281
+ /**
282
+ Basic underline color names.
283
+ */
284
+ export const underlineColorNames: readonly UnderlineColorName[];
285
+
286
+ /**
225
287
  Basic color names. The combination of foreground and background color names.
226
288
  */
227
289
  export const colorNames: readonly ColorName[];
@@ -230,7 +292,8 @@ declare const ansiStyles: {
230
292
  readonly modifier: Modifier;
231
293
  readonly color: ColorBase & ForegroundColor;
232
294
  readonly bgColor: ColorBase & BackgroundColor;
295
+ readonly underlineColor: ColorBase & UnderlineColor;
233
296
  readonly codes: ReadonlyMap<number, number>;
234
- } & ForegroundColor & BackgroundColor & Modifier & ConvertColor;
297
+ } & ForegroundColor & BackgroundColor & UnderlineColor & Modifier & ConvertColor;
235
298
 
236
299
  export default ansiStyles;