@mpen/ansi-colors 0.1.0
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 +133 -0
- package/dist/index.d.ts +111 -0
- package/dist/index.js +125 -0
- package/package.json +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# @mpen/ansi-colors
|
|
2
|
+
|
|
3
|
+
A lightweight, high-performance, and feature-rich terminal coloring library for Node.js, Bun, and other JS environments.
|
|
4
|
+
|
|
5
|
+
Derived from the extremely fast and optimized core of `picocolors`, this library extends it with full **Truecolor (
|
|
6
|
+
24-bit RGB)** support, **Hexadecimal** color formatting, and clean TypeScript typings.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Zero dependencies** — extremely small footprint.
|
|
11
|
+
- **Truecolor Support** — format terminal text using arbitrary 24-bit RGB and Hex colors.
|
|
12
|
+
- **High Performance** — builds on `picocolors`' highly optimized formatter architecture.
|
|
13
|
+
- **Auto-detection** — automatically detects color support (respects `FORCE_COLOR`, `NO_COLOR`, and `CI`).
|
|
14
|
+
- **Nestable & Composable** — mix and match formatting, text colors, and background colors seamlessly.
|
|
15
|
+
- **Fully Typed** — clean TypeScript declarations out of the box.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
bun add @mpen/ansi-colors
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npm install @mpen/ansi-colors
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### Basic Usage
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { createColors } from '@mpen/ansi-colors'
|
|
37
|
+
|
|
38
|
+
const c = createColors()
|
|
39
|
+
|
|
40
|
+
console.log(c.green('Success! Operation completed.'))
|
|
41
|
+
console.log(c.bold(c.red('Error: Access denied.')))
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Truecolor (RGB and Hex)
|
|
45
|
+
|
|
46
|
+
You can define custom formatters using exact 24-bit color values:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { createColors } from '@mpen/ansi-colors'
|
|
50
|
+
|
|
51
|
+
const c = createColors()
|
|
52
|
+
|
|
53
|
+
// Hex Colors
|
|
54
|
+
const purple = c.hex('#7c3aed')
|
|
55
|
+
const bgGold = c.bgHex('ffd700') // '#' prefix is optional
|
|
56
|
+
console.log(purple(bgGold(' Royal and Gold ')))
|
|
57
|
+
|
|
58
|
+
// RGB Colors
|
|
59
|
+
const orange = c.rgb(255, 128, 0)
|
|
60
|
+
const bgTeal = c.bgRgb(0, 128, 128)
|
|
61
|
+
console.log(orange(bgTeal(' Sunset Teal ')))
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Composing and Nesting
|
|
65
|
+
|
|
66
|
+
Formatters are functions that can be nested and composed inside one another:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { createColors } from '@mpen/ansi-colors'
|
|
70
|
+
|
|
71
|
+
const c = createColors()
|
|
72
|
+
|
|
73
|
+
console.log(c.bold(`Underline ${c.underline('and')} green ${c.green('text')}`))
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Disabling Colors Dynamically
|
|
77
|
+
|
|
78
|
+
By default, `createColors()` guesses support for colors automatically. You can explicitly force or disable colors by
|
|
79
|
+
passing a boolean:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { createColors } from '@mpen/ansi-colors'
|
|
83
|
+
|
|
84
|
+
// Force colors disabled (useful for raw logs)
|
|
85
|
+
const c = createColors(false)
|
|
86
|
+
|
|
87
|
+
console.log(c.red('This will print as plain uncolored text.'))
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### Color Support Auto-Detection
|
|
93
|
+
|
|
94
|
+
By default, `createColors()` automatically detects whether the terminal environment supports ANSI colors. The automatic detection evaluates:
|
|
95
|
+
|
|
96
|
+
- **`NO_COLOR`**: If this environment variable is set (regardless of its value), colors are disabled (see [no-color.org](https://no-color.org/)).
|
|
97
|
+
- **`FORCE_COLOR`**: If set, color support is forced-enabled.
|
|
98
|
+
- **`CI`**: If set (typically in continuous integration pipelines), colors are enabled.
|
|
99
|
+
- **`TERM`**: If set to `dumb`, colors are disabled.
|
|
100
|
+
- **TTY Check**: Colors are enabled if `process.stdout.isTTY` is truthy.
|
|
101
|
+
- **Windows**: On Windows environments (`win32` platform), colors are enabled.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## API Reference
|
|
106
|
+
|
|
107
|
+
### `createColors(enabled?: boolean)`
|
|
108
|
+
|
|
109
|
+
Creates a new colors instance. By default, it detects color support using environment variables.
|
|
110
|
+
|
|
111
|
+
#### Instance Properties & Formatters
|
|
112
|
+
|
|
113
|
+
| Category | Formatters |
|
|
114
|
+
| :-------------- | :------------------------------------------------------------------------------------------------------------------------------------ |
|
|
115
|
+
| **Modifiers** | `reset`, `bold`, `dim`, `italic`, `underline`, `inverse`, `hidden`, `strikethrough` |
|
|
116
|
+
| **Text Colors** | `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, `gray` / `blackBright` |
|
|
117
|
+
| **Bright Text** | `redBright`, `greenBright`, `yellowBright`, `blueBright`, `magentaBright`, `cyanBright`, `whiteBright` |
|
|
118
|
+
| **Backgrounds** | `bgBlack`, `bgRed`, `bgGreen`, `bgYellow`, `bgBlue`, `bgMagenta`, `bgCyan`, `bgWhite` |
|
|
119
|
+
| **Bright BG** | `bgBlackBright`, `bgRedBright`, `bgGreenBright`, `bgYellowBright`, `bgBlueBright`, `bgMagentaBright`, `bgCyanBright`, `bgWhiteBright` |
|
|
120
|
+
|
|
121
|
+
#### Instance Custom Factories
|
|
122
|
+
|
|
123
|
+
- **`rgb(r, g, b)`**: Returns a text color formatter for the given RGB channels (`0-255`).
|
|
124
|
+
- **`bgRgb(r, g, b)`**: Returns a background color formatter for the given RGB channels (`0-255`).
|
|
125
|
+
- **`hex(color)`**: Returns a text color formatter for the given Hex string (e.g., `#7c3aed` or `7c3aed`).
|
|
126
|
+
- **`bgHex(color)`**: Returns a background color formatter for the given Hex string.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## License
|
|
131
|
+
|
|
132
|
+
MIT © Mark Penner. Portions derived from [picocolors](https://github.com/alexeyraspopov/picocolors) (Copyright
|
|
133
|
+
© Oleksii Raspopov, Kostiantyn Denysov, Anton Verinov).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
//#region src/color.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Formats a value with ANSI escape sequences.
|
|
4
|
+
*
|
|
5
|
+
* @param input - The value to convert to a string and format.
|
|
6
|
+
* @returns The formatted string.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const red: ColorFormatter = (input) => `\x1b[31m${input}\x1b[39m`
|
|
11
|
+
* red('error')
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
type ColorFormatter = (input: unknown) => string;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a formatter for a 24-bit RGB ANSI color.
|
|
17
|
+
*
|
|
18
|
+
* @param red - The red channel as an integer from 0 to 255.
|
|
19
|
+
* @param green - The green channel as an integer from 0 to 255.
|
|
20
|
+
* @param blue - The blue channel as an integer from 0 to 255.
|
|
21
|
+
* @returns A formatter for the requested RGB color.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const colors = createColors()
|
|
26
|
+
* const orange = colors.rgb(255, 128, 0)
|
|
27
|
+
* orange('warning')
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
type RgbColorFactory = (red: number, green: number, blue: number) => ColorFormatter;
|
|
31
|
+
/**
|
|
32
|
+
* Creates a formatter for a 24-bit hexadecimal ANSI color.
|
|
33
|
+
*
|
|
34
|
+
* @param color - The color as `#rgb`, `rgb`, `#rrggbb`, or `rrggbb`.
|
|
35
|
+
* @returns A formatter for the requested hexadecimal color.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const colors = createColors()
|
|
40
|
+
* const violet = colors.hex('#7c3aed')
|
|
41
|
+
* violet('accent')
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
type HexColorFactory = (color: string) => ColorFormatter;
|
|
45
|
+
type RgbFormatterFactory = (red: number, green: number, blue: number) => ColorFormatter;
|
|
46
|
+
/**
|
|
47
|
+
* Creates a color formatter set.
|
|
48
|
+
*
|
|
49
|
+
* @param enabled - Whether the returned formatters should emit ANSI escape sequences.
|
|
50
|
+
* Defaults to detected color support for the current process.
|
|
51
|
+
* @returns A color formatter set.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* import createColors from '@mpen/ansi-colors'
|
|
56
|
+
*
|
|
57
|
+
* const pc = createColors(true)
|
|
58
|
+
* pc.bold(pc.red('error'))
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
declare function createColors(enabled?: boolean): {
|
|
62
|
+
isColorSupported: boolean;
|
|
63
|
+
reset: ColorFormatter;
|
|
64
|
+
bold: ColorFormatter;
|
|
65
|
+
dim: ColorFormatter;
|
|
66
|
+
italic: ColorFormatter;
|
|
67
|
+
underline: ColorFormatter;
|
|
68
|
+
inverse: ColorFormatter;
|
|
69
|
+
hidden: ColorFormatter;
|
|
70
|
+
strikethrough: ColorFormatter;
|
|
71
|
+
black: ColorFormatter;
|
|
72
|
+
red: ColorFormatter;
|
|
73
|
+
green: ColorFormatter;
|
|
74
|
+
yellow: ColorFormatter;
|
|
75
|
+
blue: ColorFormatter;
|
|
76
|
+
magenta: ColorFormatter;
|
|
77
|
+
cyan: ColorFormatter;
|
|
78
|
+
white: ColorFormatter;
|
|
79
|
+
gray: ColorFormatter;
|
|
80
|
+
bgBlack: ColorFormatter;
|
|
81
|
+
bgRed: ColorFormatter;
|
|
82
|
+
bgGreen: ColorFormatter;
|
|
83
|
+
bgYellow: ColorFormatter;
|
|
84
|
+
bgBlue: ColorFormatter;
|
|
85
|
+
bgMagenta: ColorFormatter;
|
|
86
|
+
bgCyan: ColorFormatter;
|
|
87
|
+
bgWhite: ColorFormatter;
|
|
88
|
+
blackBright: ColorFormatter;
|
|
89
|
+
redBright: ColorFormatter;
|
|
90
|
+
greenBright: ColorFormatter;
|
|
91
|
+
yellowBright: ColorFormatter;
|
|
92
|
+
blueBright: ColorFormatter;
|
|
93
|
+
magentaBright: ColorFormatter;
|
|
94
|
+
cyanBright: ColorFormatter;
|
|
95
|
+
whiteBright: ColorFormatter;
|
|
96
|
+
bgBlackBright: ColorFormatter;
|
|
97
|
+
bgRedBright: ColorFormatter;
|
|
98
|
+
bgGreenBright: ColorFormatter;
|
|
99
|
+
bgYellowBright: ColorFormatter;
|
|
100
|
+
bgBlueBright: ColorFormatter;
|
|
101
|
+
bgMagentaBright: ColorFormatter;
|
|
102
|
+
bgCyanBright: ColorFormatter;
|
|
103
|
+
bgWhiteBright: ColorFormatter;
|
|
104
|
+
rgb: RgbFormatterFactory;
|
|
105
|
+
bgRgb: RgbFormatterFactory;
|
|
106
|
+
hex: (color: string) => ColorFormatter;
|
|
107
|
+
bgHex: (color: string) => ColorFormatter;
|
|
108
|
+
};
|
|
109
|
+
type Colors = ReturnType<typeof createColors>;
|
|
110
|
+
//#endregion
|
|
111
|
+
export { ColorFormatter, Colors, HexColorFactory, RgbColorFactory, createColors, createColors as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
//#region src/color.ts
|
|
2
|
+
const processInfo = typeof process === "undefined" ? void 0 : process;
|
|
3
|
+
const env = processInfo?.env ?? {};
|
|
4
|
+
/**
|
|
5
|
+
* Whether ANSI colors are supported in the current process.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import createColors from '@mpen/ansi-colors'
|
|
10
|
+
*
|
|
11
|
+
* const colors = createColors()
|
|
12
|
+
* if (colors.isColorSupported) {
|
|
13
|
+
* console.log('colors are enabled')
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
const isColorSupported = !env.NO_COLOR && (Boolean(env.FORCE_COLOR) || processInfo?.platform === "win32" || Boolean(processInfo?.stdout?.isTTY) && env.TERM !== "dumb" || Boolean(env.CI));
|
|
18
|
+
const replaceClose = (string, close, replace, index) => {
|
|
19
|
+
let result = "";
|
|
20
|
+
let cursor = 0;
|
|
21
|
+
do {
|
|
22
|
+
result += string.substring(cursor, index) + replace;
|
|
23
|
+
cursor = index + close.length;
|
|
24
|
+
index = string.indexOf(close, cursor);
|
|
25
|
+
} while (index >= 0);
|
|
26
|
+
return result + string.substring(cursor);
|
|
27
|
+
};
|
|
28
|
+
const formatter = (open, close, replace = open) => (input) => {
|
|
29
|
+
const string = String(input);
|
|
30
|
+
const index = string.indexOf(close, open.length);
|
|
31
|
+
return index >= 0 ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
32
|
+
};
|
|
33
|
+
const assertRgbChannel = (channel, name) => {
|
|
34
|
+
if (!Number.isInteger(channel) || channel < 0 || channel > 255) throw new RangeError(`${name} must be an integer from 0 to 255`);
|
|
35
|
+
};
|
|
36
|
+
const rgbFormatter = (f, prefix, close) => (red, green, blue) => {
|
|
37
|
+
assertRgbChannel(red, "red");
|
|
38
|
+
assertRgbChannel(green, "green");
|
|
39
|
+
assertRgbChannel(blue, "blue");
|
|
40
|
+
return f(`\x1b[${prefix};2;${red};${green};${blue}m`, close);
|
|
41
|
+
};
|
|
42
|
+
const parseHexColor = (color) => {
|
|
43
|
+
const hex = /^#?(?<hex>[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color)?.groups?.hex;
|
|
44
|
+
if (!hex) throw new TypeError("color must be a 3- or 6-digit hex color");
|
|
45
|
+
if (hex.length === 3) return [
|
|
46
|
+
Number.parseInt(`${hex[0]}${hex[0]}`, 16),
|
|
47
|
+
Number.parseInt(`${hex[1]}${hex[1]}`, 16),
|
|
48
|
+
Number.parseInt(`${hex[2]}${hex[2]}`, 16)
|
|
49
|
+
];
|
|
50
|
+
return [
|
|
51
|
+
Number.parseInt(hex.slice(0, 2), 16),
|
|
52
|
+
Number.parseInt(hex.slice(2, 4), 16),
|
|
53
|
+
Number.parseInt(hex.slice(4, 6), 16)
|
|
54
|
+
];
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Creates a color formatter set.
|
|
58
|
+
*
|
|
59
|
+
* @param enabled - Whether the returned formatters should emit ANSI escape sequences.
|
|
60
|
+
* Defaults to detected color support for the current process.
|
|
61
|
+
* @returns A color formatter set.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import createColors from '@mpen/ansi-colors'
|
|
66
|
+
*
|
|
67
|
+
* const pc = createColors(true)
|
|
68
|
+
* pc.bold(pc.red('error'))
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
function createColors(enabled = isColorSupported) {
|
|
72
|
+
const f = enabled ? formatter : () => String;
|
|
73
|
+
const rgb = rgbFormatter(f, 38, "\x1B[39m");
|
|
74
|
+
const bgRgb = rgbFormatter(f, 48, "\x1B[49m");
|
|
75
|
+
return {
|
|
76
|
+
isColorSupported: enabled,
|
|
77
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
78
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
79
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
80
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
81
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
82
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
83
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
84
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
85
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
86
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
87
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
88
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
89
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
90
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
91
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
92
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
93
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
94
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
95
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
96
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
97
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
98
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
99
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
100
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
101
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
102
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
103
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
104
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
105
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
106
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
107
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
108
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
109
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
110
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
111
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
112
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
113
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
114
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
115
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
116
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
117
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m"),
|
|
118
|
+
rgb,
|
|
119
|
+
bgRgb,
|
|
120
|
+
hex: (color) => rgb(...parseHexColor(color)),
|
|
121
|
+
bgHex: (color) => bgRgb(...parseHexColor(color))
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
//#endregion
|
|
125
|
+
export { createColors, createColors as default };
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mpen/ansi-colors",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"exports": {
|
|
14
|
+
".": "./dist/index.js",
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/bun": "latest",
|
|
20
|
+
"tsdown": "^0.21",
|
|
21
|
+
"typescript": "^6"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "bun run --bun tsdown"
|
|
25
|
+
}
|
|
26
|
+
}
|