@peteanderson/ansi 0.2.4 → 0.3.1

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.
Files changed (87) hide show
  1. package/README.md +124 -28
  2. package/dist/ansi.d.ts +52 -0
  3. package/dist/ansi.js +55 -0
  4. package/dist/caret.d.ts +28 -0
  5. package/dist/caret.js +70 -0
  6. package/dist/erase.d.ts +13 -0
  7. package/dist/erase.js +30 -0
  8. package/dist/features/build.d.ts +11 -0
  9. package/dist/features/build.js +50 -0
  10. package/dist/features/detect.d.ts +4 -0
  11. package/dist/features/detect.js +33 -0
  12. package/dist/features/features.d.ts +5 -0
  13. package/dist/features/features.js +39 -0
  14. package/dist/features/index.d.ts +2 -0
  15. package/dist/features/index.js +2 -0
  16. package/dist/index.d.ts +59 -0
  17. package/dist/index.js +2 -0
  18. package/dist/pad.d.ts +12 -0
  19. package/dist/pad.js +15 -0
  20. package/dist/patterns.d.ts +3 -0
  21. package/dist/patterns.js +43 -0
  22. package/dist/scroll.d.ts +6 -0
  23. package/dist/scroll.js +14 -0
  24. package/dist/sgr/color/color.d.ts +9 -0
  25. package/dist/sgr/color/color.js +76 -0
  26. package/dist/sgr/color/index.d.ts +2 -0
  27. package/dist/sgr/color/index.js +2 -0
  28. package/dist/sgr/color/utils.d.ts +27 -0
  29. package/dist/sgr/color/utils.js +67 -0
  30. package/dist/sgr/index.d.ts +9 -0
  31. package/dist/sgr/index.js +6 -0
  32. package/dist/sgr/reset.d.ts +1 -0
  33. package/dist/sgr/reset.js +3 -0
  34. package/dist/sgr/sgr.d.ts +14 -0
  35. package/dist/sgr/sgr.js +57 -0
  36. package/dist/sgr/style.d.ts +13 -0
  37. package/dist/sgr/style.js +19 -0
  38. package/dist/sgr/utils.d.ts +2 -0
  39. package/dist/sgr/utils.js +16 -0
  40. package/dist/simplify/atom.d.ts +3 -0
  41. package/dist/simplify/atom.js +28 -0
  42. package/dist/simplify/index.d.ts +2 -0
  43. package/dist/simplify/index.js +2 -0
  44. package/dist/simplify/lookup.d.ts +5 -0
  45. package/dist/simplify/lookup.js +77 -0
  46. package/dist/simplify/simplify.d.ts +1 -0
  47. package/dist/simplify/simplify.js +25 -0
  48. package/dist/simplify/state.d.ts +10 -0
  49. package/dist/simplify/state.js +57 -0
  50. package/dist/simplify/utils.d.ts +2 -0
  51. package/dist/simplify/utils.js +31 -0
  52. package/dist/slice.d.ts +1 -0
  53. package/dist/slice.js +83 -0
  54. package/dist/strip.d.ts +15 -0
  55. package/dist/strip.js +18 -0
  56. package/package.json +13 -20
  57. package/src/ansi.js +65 -0
  58. package/src/caret.js +86 -0
  59. package/src/erase.js +34 -0
  60. package/src/features/build.js +60 -0
  61. package/src/features/detect.js +39 -0
  62. package/src/features/features.js +53 -0
  63. package/src/features/index.js +1 -0
  64. package/src/features/types.d.ts +9 -0
  65. package/src/index.js +1 -0
  66. package/src/pad.js +21 -0
  67. package/src/patterns.js +44 -0
  68. package/src/scroll.js +18 -0
  69. package/src/sgr/color/color.js +104 -0
  70. package/src/sgr/color/index.js +1 -0
  71. package/src/sgr/color/types.d.ts +28 -0
  72. package/src/sgr/color/utils.js +81 -0
  73. package/src/sgr/index.js +5 -0
  74. package/src/sgr/reset.js +3 -0
  75. package/src/sgr/sgr.js +77 -0
  76. package/src/sgr/style.js +23 -0
  77. package/src/sgr/utils.js +20 -0
  78. package/src/simplify/atom.js +34 -0
  79. package/src/simplify/index.js +1 -0
  80. package/src/simplify/lookup.js +86 -0
  81. package/src/simplify/simplify.js +33 -0
  82. package/src/simplify/state.js +73 -0
  83. package/src/simplify/types.d.ts +28 -0
  84. package/src/simplify/utils.js +41 -0
  85. package/src/slice.js +99 -0
  86. package/src/strip.js +23 -0
  87. 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 disables color when stdout is not a TTY or when standard environment variables (`NO_COLOR`, `NODE_DISABLE_COLORS`, `FORCE_COLOR`, `TERM=dumb`) indicate it should be.
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,149 @@ npm install @peteanderson/ansi
11
12
  ## Usage
12
13
 
13
14
  ```js
14
- const {fg, bg, style, reset, stripAnsiSequences} = require('@peteanderson/ansi');
15
-
16
- console.log(fg.red('error: something went wrong'));
17
- console.log(bg.blue(fg.white('highlighted')));
18
- console.log(style.bold('important'));
19
- console.log(fg.rgb(5, 2, 0)('custom color'));
20
- console.log('some styled text' + reset);
21
- console.log(stripAnsiSequences('\x1b[31mred\x1b[0m')); // => 'red'
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
- ## API
30
+ ## Feature Detection
25
31
 
26
- All color and style functions accept a string and return a string. When color is disabled, the functions are identity — they return the input unchanged.
32
+ The module automatically detects:
27
33
 
28
- ### `fg` foreground colors
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
- `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `gray`
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
- fg.red('text')
34
- fg.rgb(r, g, b)('text') // r, g, b in 0–5 for the 6×6×6 cube, or grayscale 232–255
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
- `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white`
70
+ Functions that wrap text with color codes (or plain text if disabled):
40
71
 
41
- ```js
42
- bg.green('text')
43
- bg.rgb(r, g, b)('text')
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
- `bold` `dim` `italic` `underline` `inverse` `hidden` `strikethrough`
80
+ Functions that wrap text with style codes (disabled if color depth = 1):
49
81
 
50
- ```js
51
- style.bold('text')
52
- style.italic(style.bold('text'))
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 (`\x1b[0m`). An empty string when color is disabled.
89
+ The SGR reset sequence. Empty string if color is disabled.
90
+
91
+ ### `caret`
92
+
93
+ Available if feature is enabled:
58
94
 
59
- ### `stripAnsiSequences(text)`
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)
60
103
 
61
- Removes ANSI SGR escape sequences from a string.
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
+ ### `padStart(text, targetLength)` and `padEnd(text, targetLength)`
141
+
142
+ Pads a string to a target visible length using spaces. Accounts for ANSI sequences when calculating
143
+ length.
144
+
145
+ ### `features`
146
+
147
+ Object containing the detected feature configuration:
148
+
149
+ ```ts
150
+ {
151
+ colorDepth : 1 | 3 | 4 | 8 | 24;
152
+ style : boolean;
153
+ caret : boolean;
154
+ erase : boolean;
155
+ scroll : boolean;
156
+ }
157
+ ```
62
158
 
63
159
  ## License
64
160
 
package/dist/ansi.d.ts ADDED
@@ -0,0 +1,52 @@
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
+ padEnd: typeof padEnd;
12
+ padStart: typeof padStart;
13
+ strip: typeof strip;
14
+ visibleLength: typeof visibleLength;
15
+ sanitize: typeof sanitize;
16
+ slice: typeof slice;
17
+ simplify: typeof simplify;
18
+ features: ReturnType<typeof getFeatures>;
19
+ };
20
+ declare namespace ansi {
21
+ export { Args, Ansi };
22
+ }
23
+ declare function makeAnsi(...args: Args): Ansi;
24
+ import { makeCaret } from "./caret";
25
+ import { makeErase } from "./erase";
26
+ import { makeScroll } from "./scroll";
27
+ import { makeStyle } from "./sgr/style";
28
+ import { padEnd } from "./pad";
29
+ import { padStart } from "./pad";
30
+ import { strip } from "./strip";
31
+ import { visibleLength } from "./strip";
32
+ import { sanitize } from "./strip";
33
+ import { slice } from "./slice";
34
+ import { simplify } from "./simplify/simplify";
35
+ import { getFeatures } from "./features/features";
36
+ type Args = import("./features/features").Args;
37
+ type Ansi = ReturnType<typeof makeColor> & {
38
+ caret: ReturnType<typeof makeCaret>;
39
+ erase: ReturnType<typeof makeErase>;
40
+ scroll: ReturnType<typeof makeScroll>;
41
+ reset: string;
42
+ style: ReturnType<typeof makeStyle>;
43
+ padEnd: typeof padEnd;
44
+ padStart: typeof padStart;
45
+ strip: typeof strip;
46
+ visibleLength: typeof visibleLength;
47
+ sanitize: typeof sanitize;
48
+ slice: typeof slice;
49
+ simplify: typeof simplify;
50
+ features: ReturnType<typeof getFeatures>;
51
+ };
52
+ import { makeColor } from "./sgr/color/color";
package/dist/ansi.js ADDED
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ const { makeCaret } = require("./caret");
3
+ const { makeErase } = require("./erase");
4
+ const { getFeatures } = require("./features");
5
+ const { padEnd, padStart } = require("./pad");
6
+ const { makeScroll } = require("./scroll");
7
+ const { makeColor, makeReset, makeStyle } = require("./sgr");
8
+ const { simplify } = require("./simplify");
9
+ const { slice } = require("./slice");
10
+ const { sanitize, strip, visibleLength } = require("./strip");
11
+ /**
12
+ @typedef {import("./features/features").Args} Args
13
+
14
+ @typedef {ReturnType<typeof makeColor> & {
15
+ caret : ReturnType<typeof makeCaret>;
16
+ erase : ReturnType<typeof makeErase>;
17
+ scroll : ReturnType<typeof makeScroll>;
18
+
19
+ reset : string;
20
+ style : ReturnType<typeof makeStyle>;
21
+
22
+ padEnd : typeof padEnd;
23
+ padStart : typeof padStart;
24
+
25
+ strip : typeof strip;
26
+ visibleLength : typeof visibleLength;
27
+ sanitize : typeof sanitize;
28
+ slice : typeof slice;
29
+ simplify : typeof simplify;
30
+
31
+ features : ReturnType<typeof getFeatures>;
32
+ }} Ansi
33
+ */
34
+ /** @type {(...args: Args) => Ansi}*/
35
+ function makeAnsi(...args) {
36
+ const features = getFeatures(...args);
37
+ return {
38
+ caret: makeCaret(features.caret),
39
+ erase: makeErase(features.erase),
40
+ scroll: makeScroll(features.scroll),
41
+ reset: makeReset(features.colorDepth > 1),
42
+ style: makeStyle(features.style),
43
+ ...makeColor(features.colorDepth),
44
+ padEnd,
45
+ padStart,
46
+ strip,
47
+ visibleLength,
48
+ sanitize,
49
+ slice,
50
+ simplify,
51
+ features,
52
+ };
53
+ }
54
+ const ansi = Object.assign(makeAnsi, makeAnsi());
55
+ module.exports = ansi;
@@ -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 };
@@ -0,0 +1,13 @@
1
+ export function makeErase(enabled?: boolean): {
2
+ line: {
3
+ toStart: string;
4
+ toEnd: string;
5
+ full: string;
6
+ };
7
+ screen: {
8
+ toStart: string;
9
+ toEnd: string;
10
+ full: string;
11
+ scrollback: string;
12
+ };
13
+ };
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 };
@@ -0,0 +1,2 @@
1
+ declare const _exports: typeof import("./features");
2
+ export = _exports;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ module.exports = require("./features");
@@ -0,0 +1,59 @@
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
+ padEnd: (text: string, targetLength: number, fillString?: string) => string;
51
+ padStart: (text: string, targetLength: number, fillString?: string) => string;
52
+ strip: (text: string) => string;
53
+ visibleLength: (text: string) => number;
54
+ sanitize: (text: string) => string;
55
+ slice: typeof import("./slice").slice;
56
+ simplify: typeof import("./simplify/simplify").simplify;
57
+ features: ReturnType<typeof import("./features/features").getFeatures>;
58
+ };
59
+ export = _exports;
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ module.exports = require("./ansi");
package/dist/pad.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Pad the given text at the end with the specified fill string to the target visible length without
3
+ * counting ANSI escape codes.
4
+ * @type {(text: string, targetLength: number, fillString?: string) => string}
5
+ */
6
+ export const padEnd: (text: string, targetLength: number, fillString?: string) => string;
7
+ /**
8
+ * Pad the given text at the start with the specified fill string to the target visible length
9
+ * without counting ANSI escape codes.
10
+ * @type {(text: string, targetLength: number, fillString?: string) => string}
11
+ */
12
+ export const padStart: (text: string, targetLength: number, fillString?: string) => string;