@peteanderson/ansi 0.2.3 → 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.
Files changed (51) hide show
  1. package/README.md +70 -19
  2. package/dist/ansi.d.ts +41 -8
  3. package/dist/ansi.js +44 -18
  4. package/dist/caret.d.ts +28 -25
  5. package/dist/caret.js +31 -1
  6. package/dist/erase.d.ts +13 -14
  7. package/dist/erase.js +16 -1
  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 +12 -62
  17. package/dist/scroll.d.ts +6 -2
  18. package/dist/scroll.js +7 -1
  19. package/dist/sgr/color/color.d.ts +9 -0
  20. package/dist/sgr/color/color.js +76 -0
  21. package/dist/sgr/color/index.d.ts +2 -0
  22. package/dist/sgr/color/index.js +2 -0
  23. package/dist/sgr/color/utils.d.ts +27 -0
  24. package/dist/sgr/color/utils.js +67 -0
  25. package/dist/sgr/index.d.ts +5 -55
  26. package/dist/sgr/reset.d.ts +1 -1
  27. package/dist/sgr/reset.js +2 -2
  28. package/dist/sgr/sgr.d.ts +3 -3
  29. package/dist/sgr/sgr.js +18 -8
  30. package/dist/sgr/style.d.ts +13 -13
  31. package/dist/sgr/style.js +18 -15
  32. package/package.json +1 -1
  33. package/src/ansi.js +54 -24
  34. package/src/caret.js +40 -3
  35. package/src/erase.js +18 -1
  36. package/src/features/build.js +60 -0
  37. package/src/features/detect.js +39 -0
  38. package/src/features/features.js +53 -0
  39. package/src/features/index.js +1 -0
  40. package/src/features/types.d.ts +9 -0
  41. package/src/scroll.js +9 -1
  42. package/src/sgr/color/color.js +104 -0
  43. package/src/sgr/color/index.js +1 -0
  44. package/src/sgr/color/types.d.ts +28 -0
  45. package/src/sgr/color/utils.js +81 -0
  46. package/src/sgr/reset.js +2 -2
  47. package/src/sgr/sgr.js +25 -14
  48. package/src/sgr/style.js +19 -15
  49. package/dist/sgr/color.d.ts +0 -62
  50. package/dist/sgr/color.js +0 -111
  51. package/src/sgr/color.js +0 -130
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # @peteanderson/ansi
2
2
 
3
- ANSI escape sequence helpers for Node.js terminal output.
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
 
@@ -17,47 +18,80 @@ console.log(ansi.fg.red("error: something went wrong"));
17
18
  console.log(ansi.bg.blue.combine(ansi.fg.white)("highlighted"));
18
19
  console.log(ansi.style.bold("important"));
19
20
  console.log(ansi.fg.rgb(5, 2, 0)("custom color"));
20
- console.log(ansi.strip("styled text")); // remove all ANSI codes
21
- console.log(ansi.visibleLength(styledText)); // get display width
22
- console.log(ansi.slice("styled text", 0, 5)); // slice by visible length
23
- console.log(ansi.simplify(styledText)); // combine adjacent SGR sequences
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});
24
28
  ```
25
29
 
30
+ ## Feature Detection
31
+
32
+ The module automatically detects:
33
+
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:
39
+
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
+
26
45
  ## API
27
46
 
47
+ ### Default Export
48
+
49
+ The module exports a callable function with detection-based properties:
50
+
51
+ ```js
52
+ const ansi = require("@peteanderson/ansi");
53
+ const customAnsi = ansi(options); // returns configured instance
54
+ ```
55
+
28
56
  ### `fg` — foreground colors
29
57
 
30
- Functions that wrap text with color codes:
58
+ Functions that wrap text with color codes (or plain text if disabled):
31
59
 
32
60
  - Basic colors: `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `default`
33
61
  - Bright colors: `brightBlack` `brightRed` `brightGreen` `brightYellow` `brightBlue` `brightMagenta`
34
62
  `brightCyan` `brightWhite`
35
- - `fg.rgb(r, g, b)(text)` - 24-bit RGB color (r, g, b in 0–5 or grayscale 232–255)
36
- - `fg.x256(code)(text)` or `fg.x256(r, g, b)(text)` - 256-color palette
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
37
65
 
38
66
  All return functions with `open` and `close` properties for raw sequences.
39
67
 
40
68
  ### `bg` — background colors
41
69
 
42
- Functions that wrap text with color codes:
70
+ Functions that wrap text with color codes (or plain text if disabled):
43
71
 
44
72
  - Basic colors: `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `default`
45
73
  - Bright colors: `brightBlack` `brightRed` `brightGreen` `brightYellow` `brightBlue` `brightMagenta`
46
74
  `brightCyan` `brightWhite`
47
- - `bg.rgb(r, g, b)(text)` - 24-bit RGB color
48
- - `bg.x256(code)(text)` or `bg.x256(r, g, b)(text)` - 256-color palette
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
49
77
 
50
78
  ### `style`
51
79
 
52
- Functions that wrap text with style codes:
80
+ Functions that wrap text with style codes (disabled if color depth = 1):
53
81
 
54
82
  `bold` `dim` `italic` `underline` `inverse` `hidden` `strikethrough` `doubleUnderline` `framed`
55
83
  `encircled` `overline`
56
84
 
57
85
  All return functions with `open` and `close` properties for raw sequences.
58
86
 
87
+ ### `reset`
88
+
89
+ The SGR reset sequence. Empty string if color is disabled.
90
+
59
91
  ### `caret`
60
92
 
93
+ Available if feature is enabled:
94
+
61
95
  - `caret.show` / `caret.hide` - show or hide the cursor
62
96
  - `caret.position.get` - get the current cursor position (terminal sends position to stdin)
63
97
  - `caret.position.set(row, col)` - set cursor position (1-based indexing)
@@ -69,36 +103,53 @@ All return functions with `open` and `close` properties for raw sequences.
69
103
 
70
104
  ### `erase`
71
105
 
106
+ Available if feature is enabled:
107
+
72
108
  - `erase.line.toStart` / `erase.line.toEnd` / `erase.line.full` - erase line
73
109
  - `erase.screen.toStart` / `erase.screen.toEnd` / `erase.screen.full` - erase screen
74
110
  - `erase.screen.scrollback` - erase screen and scrollback buffer
75
111
 
76
112
  ### `scroll`
77
113
 
114
+ Available if feature is enabled:
115
+
78
116
  - `scroll.up(lines)` - scroll up (default 1 line)
79
117
  - `scroll.down(lines)` - scroll down (default 1 line)
80
118
 
81
119
  ### `strip(text)`
82
120
 
83
- Removes all ANSI CSI sequences from a string.
121
+ Removes all ANSI CSI sequences from a string (always available).
84
122
 
85
123
  ### `slice(text, start, end)`
86
124
 
87
- Slices a string by visible characters, ignoring ANSI sequences. Works like `String.prototype.slice`
88
- but counts only visible characters. Properly maintains terminal state at slice boundaries.
125
+ Slices a string by visible characters, ignoring ANSI sequences (always available).
89
126
 
90
127
  ### `sanitize(text)`
91
128
 
92
- Removes "unsafe" CSI sequences (non-SGR), leaving only color and style codes.
129
+ Removes "unsafe" CSI sequences, leaving only color and style codes (always available).
93
130
 
94
131
  ### `simplify(text)`
95
132
 
96
- Simplifies ANSI SGR sequences by combining adjacent sequences and removing redundant codes. Useful
97
- for optimizing styled strings.
133
+ Simplifies ANSI SGR sequences by combining adjacent sequences and removing redundant codes (always
134
+ available).
98
135
 
99
136
  ### `visibleLength(text)`
100
137
 
101
- Returns the visible length of a string with all ANSI sequences removed.
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
+ ```
102
153
 
103
154
  ## License
104
155
 
package/dist/ansi.d.ts CHANGED
@@ -1,13 +1,46 @@
1
- import caret = require("./caret");
2
- import erase = require("./erase");
3
- import scroll = require("./scroll");
4
- import { reset } from "./sgr/reset";
5
- import { style } from "./sgr/style";
6
- import { fg } from "./sgr/color";
7
- import { bg } from "./sgr/color";
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";
8
26
  import { strip } from "./strip";
9
27
  import { visibleLength } from "./strip";
10
28
  import { sanitize } from "./strip";
11
29
  import { slice } from "./slice";
12
30
  import { simplify } from "./simplify/simplify";
13
- export { caret, erase, scroll, reset, style, fg, bg, strip, visibleLength, sanitize, slice, 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 CHANGED
@@ -1,23 +1,49 @@
1
1
  "use strict";
2
- const caret = require("./caret");
3
- const erase = require("./erase");
4
- const scroll = require("./scroll");
5
- const { bg, fg, reset, style } = require("./sgr");
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");
6
7
  const { simplify } = require("./simplify");
7
8
  const { slice } = require("./slice");
8
9
  const { sanitize, strip, visibleLength } = require("./strip");
9
- const ansi = {
10
- caret,
11
- erase,
12
- scroll,
13
- reset,
14
- style,
15
- fg,
16
- bg,
17
- strip,
18
- visibleLength,
19
- sanitize,
20
- slice,
21
- simplify,
22
- };
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());
23
49
  module.exports = ansi;
package/dist/caret.d.ts CHANGED
@@ -1,25 +1,28 @@
1
- export let up: (count?: number) => string;
2
- export let down: (count?: number) => string;
3
- export let forward: (count?: number) => string;
4
- export let backward: (count?: number) => string;
5
- export let nextLine: (count?: number) => string;
6
- export let prevLine: (count?: number) => string;
7
- export let x: (x: number) => string;
8
- export let save: string;
9
- export let restore: string;
10
- export let hide: string;
11
- export let show: string;
12
- export namespace position {
13
- let get: string;
14
- let set: (x: number, y: number) => string;
15
- }
16
- export namespace shape {
17
- export let steadyBlock: string;
18
- export let steadyBar: string;
19
- export let steadyUnderline: string;
20
- export let blinkingBlock: string;
21
- export let blinkingBar: string;
22
- export let blinkingUnderline: string;
23
- let _default: string;
24
- export { _default as default };
25
- }
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 CHANGED
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  /** @type {(code: string) => (count?: number) => string} */
3
3
  const move = code => count => `\x1b[${count === undefined ? "" : count ? count : "?"}${code}`;
4
+ /** @type {(count?: number) => string} */
5
+ const noop = () => "";
4
6
  const caret = {
5
7
  up: move("A"),
6
8
  down: move("B"),
@@ -37,4 +39,32 @@ const caret = {
37
39
  default: "\x1b[0 q",
38
40
  },
39
41
  };
40
- module.exports = caret;
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 CHANGED
@@ -1,14 +1,13 @@
1
- export namespace line {
2
- let toStart: string;
3
- let toEnd: string;
4
- let full: string;
5
- }
6
- export namespace screen {
7
- let toStart_1: string;
8
- export { toStart_1 as toStart };
9
- let toEnd_1: string;
10
- export { toEnd_1 as toEnd };
11
- let full_1: string;
12
- export { full_1 as full };
13
- export let scrollback: string;
14
- }
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 CHANGED
@@ -12,4 +12,19 @@ const erase = {
12
12
  scrollback: "\x1b[3J",
13
13
  },
14
14
  };
15
- module.exports = erase;
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");