@peteanderson/ansi 0.2.4 → 0.3.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 +119 -28
- package/dist/ansi.d.ts +46 -0
- package/dist/ansi.js +49 -0
- package/dist/caret.d.ts +28 -0
- package/dist/caret.js +70 -0
- package/dist/erase.d.ts +13 -0
- package/dist/erase.js +30 -0
- package/dist/features/build.d.ts +11 -0
- package/dist/features/build.js +50 -0
- package/dist/features/detect.d.ts +4 -0
- package/dist/features/detect.js +33 -0
- package/dist/features/features.d.ts +5 -0
- package/dist/features/features.js +39 -0
- package/dist/features/index.d.ts +2 -0
- package/dist/features/index.js +2 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.js +2 -0
- package/dist/patterns.d.ts +3 -0
- package/dist/patterns.js +43 -0
- package/dist/scroll.d.ts +6 -0
- package/dist/scroll.js +14 -0
- package/dist/sgr/color/color.d.ts +9 -0
- package/dist/sgr/color/color.js +76 -0
- package/dist/sgr/color/index.d.ts +2 -0
- package/dist/sgr/color/index.js +2 -0
- package/dist/sgr/color/utils.d.ts +27 -0
- package/dist/sgr/color/utils.js +67 -0
- package/dist/sgr/index.d.ts +9 -0
- package/dist/sgr/index.js +6 -0
- package/dist/sgr/reset.d.ts +1 -0
- package/dist/sgr/reset.js +3 -0
- package/dist/sgr/sgr.d.ts +14 -0
- package/dist/sgr/sgr.js +57 -0
- package/dist/sgr/style.d.ts +13 -0
- package/dist/sgr/style.js +19 -0
- package/dist/sgr/utils.d.ts +2 -0
- package/dist/sgr/utils.js +16 -0
- package/dist/simplify/atom.d.ts +3 -0
- package/dist/simplify/atom.js +28 -0
- package/dist/simplify/index.d.ts +2 -0
- package/dist/simplify/index.js +2 -0
- package/dist/simplify/lookup.d.ts +5 -0
- package/dist/simplify/lookup.js +77 -0
- package/dist/simplify/simplify.d.ts +1 -0
- package/dist/simplify/simplify.js +25 -0
- package/dist/simplify/state.d.ts +10 -0
- package/dist/simplify/state.js +57 -0
- package/dist/simplify/utils.d.ts +2 -0
- package/dist/simplify/utils.js +31 -0
- package/dist/slice.d.ts +1 -0
- package/dist/slice.js +83 -0
- package/dist/strip.d.ts +15 -0
- package/dist/strip.js +18 -0
- package/package.json +13 -20
- package/src/ansi.js +58 -0
- package/src/caret.js +86 -0
- package/src/erase.js +34 -0
- package/src/features/build.js +60 -0
- package/src/features/detect.js +39 -0
- package/src/features/features.js +53 -0
- package/src/features/index.js +1 -0
- package/src/features/types.d.ts +9 -0
- package/src/index.js +1 -0
- package/src/patterns.js +44 -0
- package/src/scroll.js +18 -0
- package/src/sgr/color/color.js +104 -0
- package/src/sgr/color/index.js +1 -0
- package/src/sgr/color/types.d.ts +28 -0
- package/src/sgr/color/utils.js +81 -0
- package/src/sgr/index.js +5 -0
- package/src/sgr/reset.js +3 -0
- package/src/sgr/sgr.js +77 -0
- package/src/sgr/style.js +23 -0
- package/src/sgr/utils.js +20 -0
- package/src/simplify/atom.js +34 -0
- package/src/simplify/index.js +1 -0
- package/src/simplify/lookup.js +86 -0
- package/src/simplify/simplify.js +33 -0
- package/src/simplify/state.js +73 -0
- package/src/simplify/types.d.ts +28 -0
- package/src/simplify/utils.js +41 -0
- package/src/slice.js +99 -0
- package/src/strip.js +23 -0
- package/ansi.js +0 -28
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# @peteanderson/ansi
|
|
2
2
|
|
|
3
|
-
ANSI escape sequence helpers for Node.js terminal output. Automatically
|
|
3
|
+
ANSI escape sequence helpers for Node.js terminal output. Automatically detects terminal
|
|
4
|
+
capabilities and adapts output accordingly.
|
|
4
5
|
|
|
5
6
|
## Installation
|
|
6
7
|
|
|
@@ -11,54 +12,144 @@ npm install @peteanderson/ansi
|
|
|
11
12
|
## Usage
|
|
12
13
|
|
|
13
14
|
```js
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
console.log(fg.red(
|
|
17
|
-
console.log(bg.blue(fg.white(
|
|
18
|
-
console.log(style.bold(
|
|
19
|
-
console.log(fg.rgb(5, 2, 0)(
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
const ansi = require("@peteanderson/ansi");
|
|
16
|
+
|
|
17
|
+
console.log(ansi.fg.red("error: something went wrong"));
|
|
18
|
+
console.log(ansi.bg.blue.combine(ansi.fg.white)("highlighted"));
|
|
19
|
+
console.log(ansi.style.bold("important"));
|
|
20
|
+
console.log(ansi.fg.rgb(5, 2, 0)("custom color"));
|
|
21
|
+
|
|
22
|
+
// Disable colors for a specific stream
|
|
23
|
+
const ansiNoColor = ansi(1); // force 1-bit (no color)
|
|
24
|
+
console.log(ansiNoColor.fg.red("this won't be colored"));
|
|
25
|
+
|
|
26
|
+
// Override specific features
|
|
27
|
+
const customAnsi = ansi({colorDepth: 8, caret: false});
|
|
22
28
|
```
|
|
23
29
|
|
|
24
|
-
##
|
|
30
|
+
## Feature Detection
|
|
25
31
|
|
|
26
|
-
|
|
32
|
+
The module automatically detects:
|
|
27
33
|
|
|
28
|
-
|
|
34
|
+
- **Color depth**: 1 (none), 4 (16 colors), 8 (256 colors), 24 (true color)
|
|
35
|
+
- **Style support**: enabled if color depth > 1
|
|
36
|
+
- **Other features**: caret, erase, scroll — enabled if output is a TTY and `TERM` is not `dumb`
|
|
37
|
+
|
|
38
|
+
When disabled, features output empty strings. Color outputs plain text. This can be overridden:
|
|
29
39
|
|
|
30
|
-
|
|
40
|
+
- Pass a boolean to force color on/off
|
|
41
|
+
- Pass a number to set specific color depth (1, 3, 4, 8, or 24)
|
|
42
|
+
- Pass a stream to use for detection
|
|
43
|
+
- Pass a partial features object to override individual features
|
|
44
|
+
|
|
45
|
+
## API
|
|
46
|
+
|
|
47
|
+
### Default Export
|
|
48
|
+
|
|
49
|
+
The module exports a callable function with detection-based properties:
|
|
31
50
|
|
|
32
51
|
```js
|
|
33
|
-
|
|
34
|
-
|
|
52
|
+
const ansi = require("@peteanderson/ansi");
|
|
53
|
+
const customAnsi = ansi(options); // returns configured instance
|
|
35
54
|
```
|
|
36
55
|
|
|
56
|
+
### `fg` — foreground colors
|
|
57
|
+
|
|
58
|
+
Functions that wrap text with color codes (or plain text if disabled):
|
|
59
|
+
|
|
60
|
+
- Basic colors: `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `default`
|
|
61
|
+
- Bright colors: `brightBlack` `brightRed` `brightGreen` `brightYellow` `brightBlue` `brightMagenta`
|
|
62
|
+
`brightCyan` `brightWhite`
|
|
63
|
+
- `fg.rgb(r, g, b)(text)` - 24-bit RGB color, downscaled for lower color depths
|
|
64
|
+
- `fg.x256(code)(text)` or `fg.x256(r, g, b)(text)` - 256-color palette, downscaled as needed
|
|
65
|
+
|
|
66
|
+
All return functions with `open` and `close` properties for raw sequences.
|
|
67
|
+
|
|
37
68
|
### `bg` — background colors
|
|
38
69
|
|
|
39
|
-
|
|
70
|
+
Functions that wrap text with color codes (or plain text if disabled):
|
|
40
71
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
72
|
+
- Basic colors: `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `default`
|
|
73
|
+
- Bright colors: `brightBlack` `brightRed` `brightGreen` `brightYellow` `brightBlue` `brightMagenta`
|
|
74
|
+
`brightCyan` `brightWhite`
|
|
75
|
+
- `bg.rgb(r, g, b)(text)` - 24-bit RGB color, downscaled for lower color depths
|
|
76
|
+
- `bg.x256(code)(text)` or `bg.x256(r, g, b)(text)` - 256-color palette, downscaled as needed
|
|
45
77
|
|
|
46
78
|
### `style`
|
|
47
79
|
|
|
48
|
-
|
|
80
|
+
Functions that wrap text with style codes (disabled if color depth = 1):
|
|
49
81
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
82
|
+
`bold` `dim` `italic` `underline` `inverse` `hidden` `strikethrough` `doubleUnderline` `framed`
|
|
83
|
+
`encircled` `overline`
|
|
84
|
+
|
|
85
|
+
All return functions with `open` and `close` properties for raw sequences.
|
|
54
86
|
|
|
55
87
|
### `reset`
|
|
56
88
|
|
|
57
|
-
The SGR reset sequence
|
|
89
|
+
The SGR reset sequence. Empty string if color is disabled.
|
|
90
|
+
|
|
91
|
+
### `caret`
|
|
58
92
|
|
|
59
|
-
|
|
93
|
+
Available if feature is enabled:
|
|
60
94
|
|
|
61
|
-
|
|
95
|
+
- `caret.show` / `caret.hide` - show or hide the cursor
|
|
96
|
+
- `caret.position.get` - get the current cursor position (terminal sends position to stdin)
|
|
97
|
+
- `caret.position.set(row, col)` - set cursor position (1-based indexing)
|
|
98
|
+
- `caret.shape.block` / `caret.shape.underline` / `caret.shape.bar` - change cursor shape
|
|
99
|
+
- `caret.up(n)` / `caret.down(n)` / `caret.forward(n)` / `caret.backward(n)` - move cursor
|
|
100
|
+
- `caret.nextLine(n)` / `caret.prevLine(n)` - move cursor to next/previous line
|
|
101
|
+
- `caret.x(col)` - move cursor to column (1-based)
|
|
102
|
+
- `caret.save` / `caret.restore` - save/restore cursor position (VT100)
|
|
103
|
+
|
|
104
|
+
### `erase`
|
|
105
|
+
|
|
106
|
+
Available if feature is enabled:
|
|
107
|
+
|
|
108
|
+
- `erase.line.toStart` / `erase.line.toEnd` / `erase.line.full` - erase line
|
|
109
|
+
- `erase.screen.toStart` / `erase.screen.toEnd` / `erase.screen.full` - erase screen
|
|
110
|
+
- `erase.screen.scrollback` - erase screen and scrollback buffer
|
|
111
|
+
|
|
112
|
+
### `scroll`
|
|
113
|
+
|
|
114
|
+
Available if feature is enabled:
|
|
115
|
+
|
|
116
|
+
- `scroll.up(lines)` - scroll up (default 1 line)
|
|
117
|
+
- `scroll.down(lines)` - scroll down (default 1 line)
|
|
118
|
+
|
|
119
|
+
### `strip(text)`
|
|
120
|
+
|
|
121
|
+
Removes all ANSI CSI sequences from a string (always available).
|
|
122
|
+
|
|
123
|
+
### `slice(text, start, end)`
|
|
124
|
+
|
|
125
|
+
Slices a string by visible characters, ignoring ANSI sequences (always available).
|
|
126
|
+
|
|
127
|
+
### `sanitize(text)`
|
|
128
|
+
|
|
129
|
+
Removes "unsafe" CSI sequences, leaving only color and style codes (always available).
|
|
130
|
+
|
|
131
|
+
### `simplify(text)`
|
|
132
|
+
|
|
133
|
+
Simplifies ANSI SGR sequences by combining adjacent sequences and removing redundant codes (always
|
|
134
|
+
available).
|
|
135
|
+
|
|
136
|
+
### `visibleLength(text)`
|
|
137
|
+
|
|
138
|
+
Returns the visible length of a string with all ANSI sequences removed (always available).
|
|
139
|
+
|
|
140
|
+
### `features`
|
|
141
|
+
|
|
142
|
+
Object containing the detected feature configuration:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
{
|
|
146
|
+
colorDepth : 1 | 3 | 4 | 8 | 24;
|
|
147
|
+
style : boolean;
|
|
148
|
+
caret : boolean;
|
|
149
|
+
erase : boolean;
|
|
150
|
+
scroll : boolean;
|
|
151
|
+
}
|
|
152
|
+
```
|
|
62
153
|
|
|
63
154
|
## License
|
|
64
155
|
|
package/dist/ansi.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export = ansi;
|
|
2
|
+
declare const ansi: typeof makeAnsi & {
|
|
3
|
+
fg: Channel;
|
|
4
|
+
bg: Channel;
|
|
5
|
+
} & {
|
|
6
|
+
caret: ReturnType<typeof makeCaret>;
|
|
7
|
+
erase: ReturnType<typeof makeErase>;
|
|
8
|
+
scroll: ReturnType<typeof makeScroll>;
|
|
9
|
+
reset: string;
|
|
10
|
+
style: ReturnType<typeof makeStyle>;
|
|
11
|
+
strip: typeof strip;
|
|
12
|
+
visibleLength: typeof visibleLength;
|
|
13
|
+
sanitize: typeof sanitize;
|
|
14
|
+
slice: typeof slice;
|
|
15
|
+
simplify: typeof simplify;
|
|
16
|
+
features: ReturnType<typeof getFeatures>;
|
|
17
|
+
};
|
|
18
|
+
declare namespace ansi {
|
|
19
|
+
export { Args, Ansi };
|
|
20
|
+
}
|
|
21
|
+
declare function makeAnsi(...args: Args): Ansi;
|
|
22
|
+
import { makeCaret } from "./caret";
|
|
23
|
+
import { makeErase } from "./erase";
|
|
24
|
+
import { makeScroll } from "./scroll";
|
|
25
|
+
import { makeStyle } from "./sgr/style";
|
|
26
|
+
import { strip } from "./strip";
|
|
27
|
+
import { visibleLength } from "./strip";
|
|
28
|
+
import { sanitize } from "./strip";
|
|
29
|
+
import { slice } from "./slice";
|
|
30
|
+
import { simplify } from "./simplify/simplify";
|
|
31
|
+
import { getFeatures } from "./features/features";
|
|
32
|
+
type Args = import("./features/features").Args;
|
|
33
|
+
type Ansi = ReturnType<typeof makeColor> & {
|
|
34
|
+
caret: ReturnType<typeof makeCaret>;
|
|
35
|
+
erase: ReturnType<typeof makeErase>;
|
|
36
|
+
scroll: ReturnType<typeof makeScroll>;
|
|
37
|
+
reset: string;
|
|
38
|
+
style: ReturnType<typeof makeStyle>;
|
|
39
|
+
strip: typeof strip;
|
|
40
|
+
visibleLength: typeof visibleLength;
|
|
41
|
+
sanitize: typeof sanitize;
|
|
42
|
+
slice: typeof slice;
|
|
43
|
+
simplify: typeof simplify;
|
|
44
|
+
features: ReturnType<typeof getFeatures>;
|
|
45
|
+
};
|
|
46
|
+
import { makeColor } from "./sgr/color/color";
|
package/dist/ansi.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { makeCaret } = require("./caret");
|
|
3
|
+
const { makeErase } = require("./erase");
|
|
4
|
+
const { getFeatures } = require("./features");
|
|
5
|
+
const { makeScroll } = require("./scroll");
|
|
6
|
+
const { makeColor, makeReset, makeStyle } = require("./sgr");
|
|
7
|
+
const { simplify } = require("./simplify");
|
|
8
|
+
const { slice } = require("./slice");
|
|
9
|
+
const { sanitize, strip, visibleLength } = require("./strip");
|
|
10
|
+
/**
|
|
11
|
+
@typedef {import("./features/features").Args} Args
|
|
12
|
+
|
|
13
|
+
@typedef {ReturnType<typeof makeColor> & {
|
|
14
|
+
caret : ReturnType<typeof makeCaret>;
|
|
15
|
+
erase : ReturnType<typeof makeErase>;
|
|
16
|
+
scroll : ReturnType<typeof makeScroll>;
|
|
17
|
+
|
|
18
|
+
reset : string;
|
|
19
|
+
style : ReturnType<typeof makeStyle>;
|
|
20
|
+
|
|
21
|
+
strip : typeof strip;
|
|
22
|
+
visibleLength : typeof visibleLength;
|
|
23
|
+
sanitize : typeof sanitize;
|
|
24
|
+
slice : typeof slice;
|
|
25
|
+
simplify : typeof simplify;
|
|
26
|
+
|
|
27
|
+
features : ReturnType<typeof getFeatures>;
|
|
28
|
+
}} Ansi
|
|
29
|
+
*/
|
|
30
|
+
/** @type {(...args: Args) => Ansi}*/
|
|
31
|
+
function makeAnsi(...args) {
|
|
32
|
+
const features = getFeatures(...args);
|
|
33
|
+
return {
|
|
34
|
+
caret: makeCaret(features.caret),
|
|
35
|
+
erase: makeErase(features.erase),
|
|
36
|
+
scroll: makeScroll(features.scroll),
|
|
37
|
+
reset: makeReset(features.colorDepth > 1),
|
|
38
|
+
style: makeStyle(features.style),
|
|
39
|
+
...makeColor(features.colorDepth),
|
|
40
|
+
strip,
|
|
41
|
+
visibleLength,
|
|
42
|
+
sanitize,
|
|
43
|
+
slice,
|
|
44
|
+
simplify,
|
|
45
|
+
features,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const ansi = Object.assign(makeAnsi, makeAnsi());
|
|
49
|
+
module.exports = ansi;
|
package/dist/caret.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function makeCaret(enabled?: boolean): {
|
|
2
|
+
up: (count?: number) => string;
|
|
3
|
+
down: (count?: number) => string;
|
|
4
|
+
forward: (count?: number) => string;
|
|
5
|
+
backward: (count?: number) => string;
|
|
6
|
+
nextLine: (count?: number) => string;
|
|
7
|
+
prevLine: (count?: number) => string;
|
|
8
|
+
/** @type {(x: number) => string} */
|
|
9
|
+
x: (x: number) => string;
|
|
10
|
+
save: string;
|
|
11
|
+
restore: string;
|
|
12
|
+
hide: string;
|
|
13
|
+
show: string;
|
|
14
|
+
position: {
|
|
15
|
+
get: string;
|
|
16
|
+
/** @type {(x: number, y: number) => string} */
|
|
17
|
+
set: (x: number, y: number) => string;
|
|
18
|
+
};
|
|
19
|
+
shape: {
|
|
20
|
+
steadyBlock: string;
|
|
21
|
+
steadyBar: string;
|
|
22
|
+
steadyUnderline: string;
|
|
23
|
+
blinkingBlock: string;
|
|
24
|
+
blinkingBar: string;
|
|
25
|
+
blinkingUnderline: string;
|
|
26
|
+
default: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
package/dist/caret.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** @type {(code: string) => (count?: number) => string} */
|
|
3
|
+
const move = code => count => `\x1b[${count === undefined ? "" : count ? count : "?"}${code}`;
|
|
4
|
+
/** @type {(count?: number) => string} */
|
|
5
|
+
const noop = () => "";
|
|
6
|
+
const caret = {
|
|
7
|
+
up: move("A"),
|
|
8
|
+
down: move("B"),
|
|
9
|
+
forward: move("C"),
|
|
10
|
+
backward: move("D"),
|
|
11
|
+
nextLine: move("E"),
|
|
12
|
+
prevLine: move("F"),
|
|
13
|
+
/** @type {(x: number) => string} */
|
|
14
|
+
x: x => `\x1b[${x}G`,
|
|
15
|
+
// These are the old VT100 codes, but they're widely supported by old and new terminals. The
|
|
16
|
+
// newer VT220 codes are standardized by ECMA and ISO, and are also widely supported, but might
|
|
17
|
+
// not work in some older terminals. The VT220 codes are:
|
|
18
|
+
//
|
|
19
|
+
// ```
|
|
20
|
+
// save : "\x1b[s",
|
|
21
|
+
// restore : "\x1b[u",
|
|
22
|
+
// ```
|
|
23
|
+
save: "\x1b7",
|
|
24
|
+
restore: "\x1b8",
|
|
25
|
+
hide: "\x1b[?25l",
|
|
26
|
+
show: "\x1b[?25h",
|
|
27
|
+
position: {
|
|
28
|
+
get: "\x1b[6n",
|
|
29
|
+
/** @type {(x: number, y: number) => string} */
|
|
30
|
+
set: (x, y) => `\x1b[${y};${x}H`,
|
|
31
|
+
},
|
|
32
|
+
shape: {
|
|
33
|
+
steadyBlock: "\x1b[2 q",
|
|
34
|
+
steadyBar: "\x1b[6 q",
|
|
35
|
+
steadyUnderline: "\x1b[4 q",
|
|
36
|
+
blinkingBlock: "\x1b[1 q",
|
|
37
|
+
blinkingBar: "\x1b[5 q",
|
|
38
|
+
blinkingUnderline: "\x1b[3 q",
|
|
39
|
+
default: "\x1b[0 q",
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
/** @type {typeof caret} */
|
|
43
|
+
const disabled = {
|
|
44
|
+
up: noop,
|
|
45
|
+
down: noop,
|
|
46
|
+
forward: noop,
|
|
47
|
+
backward: noop,
|
|
48
|
+
nextLine: noop,
|
|
49
|
+
prevLine: noop,
|
|
50
|
+
x: noop,
|
|
51
|
+
save: "",
|
|
52
|
+
restore: "",
|
|
53
|
+
hide: "",
|
|
54
|
+
show: "",
|
|
55
|
+
position: {
|
|
56
|
+
get: "",
|
|
57
|
+
set: noop,
|
|
58
|
+
},
|
|
59
|
+
shape: {
|
|
60
|
+
steadyBlock: "",
|
|
61
|
+
steadyBar: "",
|
|
62
|
+
steadyUnderline: "",
|
|
63
|
+
blinkingBlock: "",
|
|
64
|
+
blinkingBar: "",
|
|
65
|
+
blinkingUnderline: "",
|
|
66
|
+
default: "",
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
const makeCaret = (enabled = true) => enabled ? caret : disabled;
|
|
70
|
+
module.exports = { makeCaret };
|
package/dist/erase.d.ts
ADDED
package/dist/erase.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const erase = {
|
|
3
|
+
line: {
|
|
4
|
+
toStart: "\x1b[1K",
|
|
5
|
+
toEnd: "\x1b[0K",
|
|
6
|
+
full: "\x1b[2K",
|
|
7
|
+
},
|
|
8
|
+
screen: {
|
|
9
|
+
toStart: "\x1b[1J",
|
|
10
|
+
toEnd: "\x1b[0J",
|
|
11
|
+
full: "\x1b[2J",
|
|
12
|
+
scrollback: "\x1b[3J",
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
/** @type {typeof erase} */
|
|
16
|
+
const disabled = {
|
|
17
|
+
line: {
|
|
18
|
+
toStart: "",
|
|
19
|
+
toEnd: "",
|
|
20
|
+
full: "",
|
|
21
|
+
},
|
|
22
|
+
screen: {
|
|
23
|
+
toStart: "",
|
|
24
|
+
toEnd: "",
|
|
25
|
+
full: "",
|
|
26
|
+
scrollback: "",
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
const makeErase = (enabled = true) => enabled ? erase : disabled;
|
|
30
|
+
module.exports = { makeErase };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type ColorDepth = import("./types").ColorDepth;
|
|
2
|
+
export type Features = import("./types").Features;
|
|
3
|
+
export function build(isTTY: boolean, colorDepth: ColorDepth, style?: boolean, caret?: boolean, erase?: boolean, scroll?: boolean): Features;
|
|
4
|
+
/** @type {(isTTY: boolean, enabled: boolean) => Features} */
|
|
5
|
+
export const boolean: (isTTY: boolean, enabled: boolean) => Features;
|
|
6
|
+
/** @type {(isTTY: boolean, colorDepth: ColorDepth) => Features} */
|
|
7
|
+
export const number: (isTTY: boolean, colorDepth: ColorDepth) => Features;
|
|
8
|
+
/** @type {(stream: NodeJS.WriteStream) => Features} */
|
|
9
|
+
export const tty: (stream: NodeJS.WriteStream) => Features;
|
|
10
|
+
/** @type {() => Features} */
|
|
11
|
+
export const pipe: () => Features;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { getColorDepth, detectFeatureSupport } = require("./detect");
|
|
3
|
+
/** @typedef {import("./types").ColorDepth} ColorDepth */
|
|
4
|
+
/** @typedef {import("./types").Features} Features */
|
|
5
|
+
/** @type {(colorDepth: number) => ColorDepth} */
|
|
6
|
+
function normalizeColorDepth(colorDepth) {
|
|
7
|
+
colorDepth = Math.floor(colorDepth);
|
|
8
|
+
if (colorDepth >= 24)
|
|
9
|
+
return 24;
|
|
10
|
+
if (colorDepth >= 8)
|
|
11
|
+
return 8;
|
|
12
|
+
if (colorDepth >= 4)
|
|
13
|
+
return 4;
|
|
14
|
+
if (colorDepth === 3)
|
|
15
|
+
return 3;
|
|
16
|
+
return 1;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
@type {
|
|
20
|
+
(
|
|
21
|
+
isTTY : boolean,
|
|
22
|
+
colorDepth : ColorDepth,
|
|
23
|
+
style? : boolean,
|
|
24
|
+
caret? : boolean,
|
|
25
|
+
erase? : boolean,
|
|
26
|
+
scroll? : boolean,
|
|
27
|
+
) => Features
|
|
28
|
+
}
|
|
29
|
+
*/
|
|
30
|
+
function build(isTTY, colorDepth, style, caret, erase, scroll) {
|
|
31
|
+
if (style !== undefined && caret !== undefined && erase !== undefined && scroll !== undefined)
|
|
32
|
+
return { colorDepth: normalizeColorDepth(colorDepth), style, caret, erase, scroll };
|
|
33
|
+
const support = detectFeatureSupport(isTTY, colorDepth);
|
|
34
|
+
return {
|
|
35
|
+
colorDepth: normalizeColorDepth(colorDepth),
|
|
36
|
+
style: style ?? support.style,
|
|
37
|
+
caret: caret ?? support.caret,
|
|
38
|
+
erase: erase ?? support.erase,
|
|
39
|
+
scroll: scroll ?? support.scroll,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** @type {(isTTY: boolean, enabled: boolean) => Features} */
|
|
43
|
+
const boolean = (isTTY, enabled) => build(isTTY, enabled ? 4 : 1);
|
|
44
|
+
/** @type {(isTTY: boolean, colorDepth: ColorDepth) => Features} */
|
|
45
|
+
const number = (isTTY, colorDepth) => build(isTTY, colorDepth);
|
|
46
|
+
/** @type {(stream: NodeJS.WriteStream) => Features} */
|
|
47
|
+
const tty = stream => build(true, getColorDepth(stream));
|
|
48
|
+
/** @type {() => Features} */
|
|
49
|
+
const pipe = () => build(false, getColorDepth());
|
|
50
|
+
module.exports = { build, boolean, number, tty, pipe };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type ColorDepth = import("./types").ColorDepth;
|
|
2
|
+
export type Features = import("./types").Features;
|
|
3
|
+
export function detectFeatureSupport(isTTY: boolean, colorDepth: ColorDepth): Omit<Features, "colorDepth">;
|
|
4
|
+
export function getColorDepth(stream?: NodeJS.WriteStream): ColorDepth;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** @typedef {import("./types").ColorDepth} ColorDepth */
|
|
3
|
+
/** @typedef {import("./types").Features} Features */
|
|
4
|
+
/** @type {(stream?: NodeJS.WriteStream) => ColorDepth} */
|
|
5
|
+
function getColorDepth(stream) {
|
|
6
|
+
if (stream?.isTTY)
|
|
7
|
+
return /** @type {ColorDepth} */ (stream.getColorDepth());
|
|
8
|
+
if (process.env.NO_COLOR || process.env.NODE_DISABLE_COLORS)
|
|
9
|
+
return 1;
|
|
10
|
+
switch (process.env.FORCE_COLOR) {
|
|
11
|
+
case "":
|
|
12
|
+
case "true":
|
|
13
|
+
case "1":
|
|
14
|
+
return 4;
|
|
15
|
+
case "2":
|
|
16
|
+
return 8;
|
|
17
|
+
case "3":
|
|
18
|
+
return 24;
|
|
19
|
+
default:
|
|
20
|
+
return 1;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** @type {(isTTY: boolean, colorDepth: ColorDepth) => Omit<Features, "colorDepth">} */
|
|
24
|
+
function detectFeatureSupport(isTTY, colorDepth) {
|
|
25
|
+
const enabled = process.env.TERM !== "dumb" && isTTY;
|
|
26
|
+
return {
|
|
27
|
+
style: colorDepth > 1,
|
|
28
|
+
caret: enabled,
|
|
29
|
+
erase: enabled,
|
|
30
|
+
scroll: enabled,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
module.exports = { detectFeatureSupport, getColorDepth };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type ColorDepth = import("./types").ColorDepth;
|
|
2
|
+
export type Features = import("./types").Features;
|
|
3
|
+
export type Args = [enabled: boolean, stream?: NodeJS.WriteStream] | [colorDepth: ColorDepth, stream?: NodeJS.WriteStream] | [features: Partial<Features>, stream?: NodeJS.WriteStream] | [socket: Socket] | [stream?: NodeJS.WriteStream];
|
|
4
|
+
export function getFeatures(...args: Args): Features;
|
|
5
|
+
import { Socket } from "node:net";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { Socket } = require("node:net");
|
|
3
|
+
const { WriteStream } = require("node:tty");
|
|
4
|
+
const { build, boolean, number, tty, pipe } = require("./build");
|
|
5
|
+
const { getColorDepth } = require("./detect");
|
|
6
|
+
/**
|
|
7
|
+
@typedef {import("./types").ColorDepth} ColorDepth
|
|
8
|
+
@typedef {import("./types").Features} Features
|
|
9
|
+
|
|
10
|
+
@typedef {
|
|
11
|
+
| [enabled : boolean, stream?: NodeJS.WriteStream]
|
|
12
|
+
| [colorDepth : ColorDepth, stream?: NodeJS.WriteStream]
|
|
13
|
+
| [features : Partial<Features>, stream?: NodeJS.WriteStream]
|
|
14
|
+
| [socket : Socket]
|
|
15
|
+
| [stream? : NodeJS.WriteStream]
|
|
16
|
+
} Args
|
|
17
|
+
*/
|
|
18
|
+
/** @type {(...args: Args) => Features} */
|
|
19
|
+
function getFeatures(...args) {
|
|
20
|
+
let [features, stream] = args;
|
|
21
|
+
if (typeof features === "boolean")
|
|
22
|
+
return boolean((stream ?? process.stdout).isTTY, features);
|
|
23
|
+
if (typeof features === "number")
|
|
24
|
+
return number((stream ?? process.stdout).isTTY, features);
|
|
25
|
+
if (!features || typeof features !== "object")
|
|
26
|
+
features = (stream ?? process.stdout);
|
|
27
|
+
if (features instanceof WriteStream)
|
|
28
|
+
return tty(features);
|
|
29
|
+
if (features instanceof Socket)
|
|
30
|
+
return pipe();
|
|
31
|
+
const { colorDepth, style, caret, erase, scroll } = features;
|
|
32
|
+
stream ??= process.stdout;
|
|
33
|
+
if (colorDepth)
|
|
34
|
+
build(stream.isTTY, colorDepth, style, caret, erase, scroll);
|
|
35
|
+
if (stream.isTTY)
|
|
36
|
+
return build(true, getColorDepth(stream), style, caret, erase, scroll);
|
|
37
|
+
return build(false, getColorDepth(), style, caret, erase, scroll);
|
|
38
|
+
}
|
|
39
|
+
module.exports = { getFeatures };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
declare const _exports: ((...args: Args) => Ansi) & {
|
|
2
|
+
fg: Channel;
|
|
3
|
+
bg: Channel;
|
|
4
|
+
} & {
|
|
5
|
+
caret: ReturnType<(enabled?: boolean) => {
|
|
6
|
+
up: (count?: number) => string;
|
|
7
|
+
down: (count?: number) => string;
|
|
8
|
+
forward: (count?: number) => string;
|
|
9
|
+
backward: (count?: number) => string;
|
|
10
|
+
nextLine: (count?: number) => string;
|
|
11
|
+
prevLine: (count?: number) => string;
|
|
12
|
+
x: (x: number) => string;
|
|
13
|
+
save: string;
|
|
14
|
+
restore: string;
|
|
15
|
+
hide: string;
|
|
16
|
+
show: string;
|
|
17
|
+
position: {
|
|
18
|
+
get: string;
|
|
19
|
+
set: (x: number, y: number) => string;
|
|
20
|
+
};
|
|
21
|
+
shape: {
|
|
22
|
+
steadyBlock: string;
|
|
23
|
+
steadyBar: string;
|
|
24
|
+
steadyUnderline: string;
|
|
25
|
+
blinkingBlock: string;
|
|
26
|
+
blinkingBar: string;
|
|
27
|
+
blinkingUnderline: string;
|
|
28
|
+
default: string;
|
|
29
|
+
};
|
|
30
|
+
}>;
|
|
31
|
+
erase: ReturnType<(enabled?: boolean) => {
|
|
32
|
+
line: {
|
|
33
|
+
toStart: string;
|
|
34
|
+
toEnd: string;
|
|
35
|
+
full: string;
|
|
36
|
+
};
|
|
37
|
+
screen: {
|
|
38
|
+
toStart: string;
|
|
39
|
+
toEnd: string;
|
|
40
|
+
full: string;
|
|
41
|
+
scrollback: string;
|
|
42
|
+
};
|
|
43
|
+
}>;
|
|
44
|
+
scroll: ReturnType<(enabled?: boolean) => {
|
|
45
|
+
up: (lines?: number) => string;
|
|
46
|
+
down: (lines?: number) => string;
|
|
47
|
+
}>;
|
|
48
|
+
reset: string;
|
|
49
|
+
style: ReturnType<typeof import("./sgr/style").makeStyle>;
|
|
50
|
+
strip: (text: string) => string;
|
|
51
|
+
visibleLength: (text: string) => number;
|
|
52
|
+
sanitize: (text: string) => string;
|
|
53
|
+
slice: typeof import("./slice").slice;
|
|
54
|
+
simplify: typeof import("./simplify/simplify").simplify;
|
|
55
|
+
features: ReturnType<typeof import("./features/features").getFeatures>;
|
|
56
|
+
};
|
|
57
|
+
export = _exports;
|
package/dist/index.js
ADDED