bananass-utils-console 0.3.0 → 0.4.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.
@@ -0,0 +1,2 @@
1
+ export default isInteractive;
2
+ import isInteractive from './is-interactive.js';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @fileoverview Check if stdout or stderr is interactive.
3
+ * @module bananass-utils-console/is-interactive
4
+ * @license MIT Portions of this code were borrowed from [`is-interactive`](https://github.com/sindresorhus/is-interactive).
5
+ */
6
+ /**
7
+ * Check if stdout or stderr is [interactive](https://unix.stackexchange.com/a/43389/7678).
8
+ *
9
+ * It checks that the stream is [TTY](https://jameshfisher.com/2017/12/09/what-is-a-tty/), not a dumb terminal, and not running in a CI.
10
+ *
11
+ * This can be useful to decide whether to present interactive UI or animations in the terminal.
12
+ * @param {NodeJS.WriteStream} [stream] The stream to check. (default: `process.stdout`)
13
+ * @returns {boolean}
14
+ * @example
15
+ * ```
16
+ * import isInteractive from 'bananass-utils-console/is-interactive';
17
+ *
18
+ * isInteractive(); // true
19
+ * ```
20
+ */
21
+ export default function isInteractive(stream?: NodeJS.WriteStream): boolean;
@@ -0,0 +1,2 @@
1
+ export default isUnicodeSupported;
2
+ import isUnicodeSupported from './is-unicode-supported.js';
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Detect whether the terminal supports Unicode.
3
+ *
4
+ * This can be useful to decide whether to use Unicode characters or
5
+ * fallback ASCII characters in command-line output.
6
+ *
7
+ * Note that the check is quite naive.
8
+ * It just assumes all non-Windows terminals support Unicode and hard-codes
9
+ * which Windows terminals that do support Unicode.
10
+ * However, I have been using this logic in some popular packages for years without problems.
11
+ *
12
+ * @returns {boolean} Returns a `boolean` for whether the terminal supports Unicode.
13
+ * @example
14
+ * ```
15
+ * import isUnicodeSupported from 'bananass-utils-console/is-unicode-supported';
16
+ *
17
+ * isUnicodeSupported(); // true
18
+ * ```
19
+ */
20
+ export default function isUnicodeSupported(): boolean;
@@ -22,7 +22,7 @@
22
22
  * }, 2000);
23
23
  */
24
24
  export default function createSpinner(options?: Options): Spinner;
25
- export type ForegroundColorName = "black" | "red" | "green" | "yellow" | "blue" | "cyan" | "magenta" | "white" | "gray" | "grey" | "blackBright" | "redBright" | "greenBright" | "yellowBright" | "blueBright" | "cyanBright" | "magentaBright" | "whiteBright";
25
+ export type ForegroundColors = "black" | "blackBright" | "blue" | "blueBright" | "cyan" | "cyanBright" | "gray" | "green" | "greenBright" | "grey" | "magenta" | "magentaBright" | "red" | "redBright" | "white" | "whiteBright" | "yellow" | "yellowBright";
26
26
  export type SpinnerStyle = {
27
27
  frames: string[];
28
28
  interval?: number;
@@ -38,7 +38,7 @@ export type Options = {
38
38
  /**
39
39
  * The color of the spinner. (default: `'yellow'`)
40
40
  */
41
- color?: ForegroundColorName;
41
+ color?: ForegroundColors;
42
42
  /**
43
43
  * The stream to which the spinner is written. (default: `process.stderr`)
44
44
  */
@@ -62,7 +62,7 @@ export type Options = {
62
62
  spinner?: SpinnerStyle;
63
63
  };
64
64
  /**
65
- * @typedef {'black'|'red'|'green'|'yellow'|'blue'|'cyan'|'magenta'|'white'|'gray'|'grey'|'blackBright'|'redBright'|'greenBright'|'yellowBright'|'blueBright'|'cyanBright'|'magentaBright'|'whiteBright'} ForegroundColorName
65
+ * @typedef {"black"|"blackBright"|"blue"|"blueBright"|"cyan"|"cyanBright"|"gray"|"green"|"greenBright"|"grey"|"magenta"|"magentaBright"|"red"|"redBright"|"white"|"whiteBright"|"yellow"|"yellowBright"} ForegroundColors
66
66
  */
67
67
  /**
68
68
  * @typedef {object} SpinnerStyle
@@ -72,7 +72,7 @@ export type Options = {
72
72
  /**
73
73
  * @typedef {object} Options Spinner options.
74
74
  * @property {string} [text] Text to display next to the spinner. (default: `''`)
75
- * @property {ForegroundColorName} [color] The color of the spinner. (default: `'yellow'`)
75
+ * @property {ForegroundColors} [color] The color of the spinner. (default: `'yellow'`)
76
76
  * @property {NodeJS.WriteStream} [stream] The stream to which the spinner is written. (default: `process.stderr`)
77
77
  * @property {boolean} [isInteractive] Whether the spinner should be interactive. (default: Auto-detected)
78
78
  * @property {SpinnerStyle} [spinner]
@@ -159,11 +159,11 @@ declare class Spinner {
159
159
  /**
160
160
  * Change the spinner color.
161
161
  */
162
- set color(value: ForegroundColorName);
162
+ set color(value: ForegroundColors);
163
163
  /**
164
164
  * Change the spinner color.
165
165
  */
166
- get color(): ForegroundColorName;
166
+ get color(): ForegroundColors;
167
167
  /**
168
168
  * Returns whether the spinner is currently spinning.
169
169
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bananass-utils-console",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "description": "Console Utilities for Bananass Framework.🍌",
6
6
  "exports": {
@@ -8,6 +8,14 @@
8
8
  "types": "./build/icons/index.d.ts",
9
9
  "default": "./src/icons/index.js"
10
10
  },
11
+ "./is-interactive": {
12
+ "types": "./build/is-interactive/index.d.ts",
13
+ "default": "./src/is-interactive/index.js"
14
+ },
15
+ "./is-unicode-supported": {
16
+ "types": "./build/is-unicode-supported/index.d.ts",
17
+ "default": "./src/is-unicode-supported/index.js"
18
+ },
11
19
  "./logger": {
12
20
  "types": "./build/logger/index.d.ts",
13
21
  "default": "./src/logger/index.js"
@@ -30,6 +38,12 @@
30
38
  "icons": [
31
39
  "./build/icons/index.d.ts"
32
40
  ],
41
+ "is-interactive": [
42
+ "./build/is-interactive/index.d.ts"
43
+ ],
44
+ "is-unicode-supported": [
45
+ "./build/is-unicode-supported/index.d.ts"
46
+ ],
33
47
  "logger": [
34
48
  "./build/logger/index.d.ts"
35
49
  ],
@@ -84,10 +98,5 @@
84
98
  "build": "npx tsc && node ../../scripts/cp.mjs ../../LICENSE.md LICENSE.md ../../README.md README.md",
85
99
  "test": "node --test"
86
100
  },
87
- "dependencies": {
88
- "chalk": "^5.4.1",
89
- "is-interactive": "^2.0.0",
90
- "is-unicode-supported": "^2.1.0"
91
- },
92
- "gitHead": "7fea6da59ab3a9d9fba47425878281ea91486e5f"
101
+ "gitHead": "9ef4b5d85c599fd179cd90de4619668d6ee6867f"
93
102
  }
@@ -6,8 +6,8 @@
6
6
  // Import
7
7
  // --------------------------------------------------------------------------------
8
8
 
9
- import c from 'chalk';
10
- import isUnicodeSupported from 'is-unicode-supported';
9
+ import { styleText } from 'node:util';
10
+ import isUnicodeSupported from '../is-unicode-supported/index.js';
11
11
 
12
12
  // --------------------------------------------------------------------------------
13
13
  // Typedef
@@ -35,13 +35,13 @@ const choose = (unicode, ascii) => (isUnicodeSupported() ? unicode : ascii);
35
35
  // --------------------------------------------------------------------------------
36
36
 
37
37
  /** @type {string} */
38
- export const successIcon = c.green.bold(choose('✓', 'V'));
38
+ export const successIcon = styleText(['green', 'bold'], choose('✓', 'V'));
39
39
  /** @type {string} */
40
- export const errorIcon = c.red.bold(choose('✕', 'X'));
40
+ export const errorIcon = styleText(['red', 'bold'], choose('✕', 'X'));
41
41
  /** @type {string} */
42
- export const warningIcon = c.yellow.bold(choose('⚠', '!'));
42
+ export const warningIcon = styleText(['yellow', 'bold'], choose('⚠', '!'));
43
43
  /** @type {string} */
44
- export const infoIcon = c.blue.bold(choose('✦', 'i'));
44
+ export const infoIcon = styleText(['blue', 'bold'], choose('✦', 'i'));
45
45
  /** @type {string} */
46
46
  export const bananassIcon = choose('🍌', '');
47
47
  /** @type {string} U+2022: "Bullet" (•) */
@@ -52,13 +52,19 @@ export const boxDrawingsLightHorizontalIcon = choose('\u2500', '-');
52
52
  // --------------------------------------------------------------------------------
53
53
 
54
54
  /** @type {string} */
55
- export const successText = c.white.bgGreen.bold(` ${successIcon} SUCCESS `);
55
+ export const successText = styleText(
56
+ ['white', 'bgGreen', 'bold'],
57
+ ` ${successIcon} SUCCESS `,
58
+ );
56
59
  /** @type {string} */
57
- export const errorText = c.white.bgRed.bold(` ${errorIcon} ERROR `);
60
+ export const errorText = styleText(['white', 'bgRed', 'bold'], ` ${errorIcon} ERROR `);
58
61
  /** @type {string} */
59
- export const warningText = c.white.bgYellow.bold(` ${warningIcon} WARN `);
62
+ export const warningText = styleText(
63
+ ['white', 'bgYellow', 'bold'],
64
+ ` ${warningIcon} WARN `,
65
+ );
60
66
  /** @type {string} */
61
- export const infoText = c.white.bgBlue.bold(` ${infoIcon} INFO `);
67
+ export const infoText = styleText(['white', 'bgBlue', 'bold'], ` ${infoIcon} INFO `);
62
68
 
63
69
  // --------------------------------------------------------------------------------
64
70
 
@@ -0,0 +1,3 @@
1
+ import isInteractive from './is-interactive.js';
2
+
3
+ export default isInteractive;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @fileoverview Check if stdout or stderr is interactive.
3
+ * @module bananass-utils-console/is-interactive
4
+ * @license MIT Portions of this code were borrowed from [`is-interactive`](https://github.com/sindresorhus/is-interactive).
5
+ */
6
+
7
+ // --------------------------------------------------------------------------------
8
+ // Export
9
+ // --------------------------------------------------------------------------------
10
+
11
+ /**
12
+ * Check if stdout or stderr is [interactive](https://unix.stackexchange.com/a/43389/7678).
13
+ *
14
+ * It checks that the stream is [TTY](https://jameshfisher.com/2017/12/09/what-is-a-tty/), not a dumb terminal, and not running in a CI.
15
+ *
16
+ * This can be useful to decide whether to present interactive UI or animations in the terminal.
17
+ * @param {NodeJS.WriteStream} [stream] The stream to check. (default: `process.stdout`)
18
+ * @returns {boolean}
19
+ * @example
20
+ * ```
21
+ * import isInteractive from 'bananass-utils-console/is-interactive';
22
+ *
23
+ * isInteractive(); // true
24
+ * ```
25
+ */
26
+ export default function isInteractive(stream = process.stdout) {
27
+ return Boolean(
28
+ stream && stream.isTTY && process.env.TERM !== 'dumb' && !('CI' in process.env),
29
+ );
30
+ }
@@ -0,0 +1,3 @@
1
+ import isUnicodeSupported from './is-unicode-supported.js';
2
+
3
+ export default isUnicodeSupported;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @fileoverview Detect whether the terminal supports Unicode.
3
+ * @module bananass-utils-console/is-unicode-supported
4
+ * @license MIT Portions of this code were borrowed from [`is-unicode-supported`](https://github.com/sindresorhus/is-unicode-supported).
5
+ */
6
+
7
+ // --------------------------------------------------------------------------------
8
+ // Import
9
+ // --------------------------------------------------------------------------------
10
+
11
+ import process from 'node:process';
12
+
13
+ // --------------------------------------------------------------------------------
14
+ // Export
15
+ // --------------------------------------------------------------------------------
16
+
17
+ /**
18
+ * Detect whether the terminal supports Unicode.
19
+ *
20
+ * This can be useful to decide whether to use Unicode characters or
21
+ * fallback ASCII characters in command-line output.
22
+ *
23
+ * Note that the check is quite naive.
24
+ * It just assumes all non-Windows terminals support Unicode and hard-codes
25
+ * which Windows terminals that do support Unicode.
26
+ * However, I have been using this logic in some popular packages for years without problems.
27
+ *
28
+ * @returns {boolean} Returns a `boolean` for whether the terminal supports Unicode.
29
+ * @example
30
+ * ```
31
+ * import isUnicodeSupported from 'bananass-utils-console/is-unicode-supported';
32
+ *
33
+ * isUnicodeSupported(); // true
34
+ * ```
35
+ */
36
+ export default function isUnicodeSupported() {
37
+ const { env } = process;
38
+ const { TERM, TERM_PROGRAM } = env;
39
+
40
+ if (process.platform !== 'win32') {
41
+ return TERM !== 'linux'; // Linux console (kernel)
42
+ }
43
+
44
+ return (
45
+ Boolean(env.WT_SESSION) || // Windows Terminal
46
+ Boolean(env.TERMINUS_SUBLIME) || // Terminus (<0.2.27)
47
+ env.ConEmuTask === '{cmd::Cmder}' || // ConEmu and cmder
48
+ TERM_PROGRAM === 'Terminus-Sublime' ||
49
+ TERM_PROGRAM === 'vscode' ||
50
+ TERM === 'xterm-256color' ||
51
+ TERM === 'alacritty' ||
52
+ TERM === 'rxvt-unicode' ||
53
+ TERM === 'rxvt-unicode-256color' ||
54
+ env.TERMINAL_EMULATOR === 'JetBrains-JediTerm'
55
+ );
56
+ }
@@ -7,7 +7,7 @@
7
7
  // Import
8
8
  // --------------------------------------------------------------------------------
9
9
 
10
- import c from 'chalk';
10
+ import { styleText } from 'node:util';
11
11
 
12
12
  // --------------------------------------------------------------------------------
13
13
  // Typedefs
@@ -135,7 +135,7 @@ class Logger {
135
135
  console.log(
136
136
  ...[this.#textPrefix, textOrCallback, ...args]
137
137
  .filter(arg => arg !== this.#undeclaredValue)
138
- .map(arg => (typeof arg === 'string' ? c.gray(arg) : arg)),
138
+ .map(arg => (typeof arg === 'string' ? styleText('gray', arg) : arg)),
139
139
  );
140
140
  }
141
141
 
@@ -1,16 +1,15 @@
1
1
  /**
2
2
  * @fileoverview Console spinner.
3
3
  * @module bananass-utils-console/spinner
4
- * @see https://github.com/sindresorhus/yocto-spinner/tree/v0.1.2 `yocto-spinner` package `v0.1.2`.
4
+ * @license MIT Portions of this code were borrowed from [`yocto-spinner`](https://github.com/sindresorhus/yocto-spinner).
5
5
  */
6
6
 
7
7
  // --------------------------------------------------------------------------------
8
8
  // Import
9
9
  // --------------------------------------------------------------------------------
10
10
 
11
- import c from 'chalk';
12
- import isInteractive from 'is-interactive';
13
-
11
+ import { styleText } from 'node:util';
12
+ import isInteractive from '../is-interactive/index.js';
14
13
  import {
15
14
  successIcon,
16
15
  errorIcon,
@@ -24,7 +23,7 @@ import {
24
23
  // --------------------------------------------------------------------------------
25
24
 
26
25
  /**
27
- * @typedef {'black'|'red'|'green'|'yellow'|'blue'|'cyan'|'magenta'|'white'|'gray'|'grey'|'blackBright'|'redBright'|'greenBright'|'yellowBright'|'blueBright'|'cyanBright'|'magentaBright'|'whiteBright'} ForegroundColorName
26
+ * @typedef {"black"|"blackBright"|"blue"|"blueBright"|"cyan"|"cyanBright"|"gray"|"green"|"greenBright"|"grey"|"magenta"|"magentaBright"|"red"|"redBright"|"white"|"whiteBright"|"yellow"|"yellowBright"} ForegroundColors
28
27
  */
29
28
 
30
29
  /**
@@ -36,7 +35,7 @@ import {
36
35
  /**
37
36
  * @typedef {object} Options Spinner options.
38
37
  * @property {string} [text] Text to display next to the spinner. (default: `''`)
39
- * @property {ForegroundColorName} [color] The color of the spinner. (default: `'yellow'`)
38
+ * @property {ForegroundColors} [color] The color of the spinner. (default: `'yellow'`)
40
39
  * @property {NodeJS.WriteStream} [stream] The stream to which the spinner is written. (default: `process.stderr`)
41
40
  * @property {boolean} [isInteractive] Whether the spinner should be interactive. (default: Auto-detected)
42
41
  * @property {SpinnerStyle} [spinner]
@@ -73,7 +72,7 @@ class Spinner {
73
72
  #text;
74
73
  /** @type {NodeJS.WriteStream} */
75
74
  #stream;
76
- /** @type {ForegroundColorName} */
75
+ /** @type {ForegroundColors} */
77
76
  #color;
78
77
  /** @type {number} */
79
78
  #lines = 0;
@@ -93,8 +92,7 @@ class Spinner {
93
92
  this.#text = options.text ?? '';
94
93
  this.#stream = options.stream ?? process.stderr;
95
94
  this.#color = options.color ?? 'yellow';
96
- this.#isInteractive =
97
- options.isInteractive ?? isInteractive({ stream: this.#stream });
95
+ this.#isInteractive = options.isInteractive ?? isInteractive(this.#stream);
98
96
  this.#exitHandlerBound = this.#exitHandler.bind(this);
99
97
  }
100
98
 
@@ -119,9 +117,9 @@ class Spinner {
119
117
  this.#lastSpinnerFrameTime = currentTime;
120
118
  }
121
119
 
122
- const applyColor = c[this.#color] ?? c.yellow;
120
+ const color = this.#color ?? 'yellow';
123
121
  const frame = this.#frames[this.#currentFrame];
124
- let string = `${applyColor(frame)} ${this.#text}`;
122
+ let string = `${styleText(color, frame)} ${this.#text}`;
125
123
 
126
124
  if (!this.#isInteractive) {
127
125
  string += '\n';
@@ -7,7 +7,7 @@
7
7
  // Import
8
8
  // --------------------------------------------------------------------------------
9
9
 
10
- import c from 'chalk';
10
+ import { styleText } from 'node:util';
11
11
  import {
12
12
  successText,
13
13
  errorText,
@@ -22,16 +22,15 @@ import {
22
22
 
23
23
  /**
24
24
  * Formats a string with an optional color and icon.
25
- *
26
25
  * @param {string} str The string to format.
27
26
  * @param {boolean} showIcon Whether to show the icon.
28
- * @param {function} color The function to apply color to the string.
27
+ * @param {'green'|'red'|'yellow'|'blue'} color The color to apply to the string.
29
28
  * @param {string} icon The icon to prepend to the string if `showIcon` is true.
30
29
  * @returns {string} The formatted string with the optional icon and color applied.
31
30
  * @private
32
31
  */
33
32
  const format = (str, showIcon, color, icon) =>
34
- `${showIcon ? `${icon} ` : ''}${color(str)}`;
33
+ `${showIcon ? `${icon} ` : ''}${styleText(color, str)}`;
35
34
 
36
35
  // --------------------------------------------------------------------------------
37
36
  // Export
@@ -49,7 +48,7 @@ const format = (str, showIcon, color, icon) =>
49
48
  * // Output: (icon?) Operation successful. (displayed in green text in the terminal.)
50
49
  */
51
50
  export function success(str, showIcon = false) {
52
- return format(str, showIcon, c.green, successText);
51
+ return format(str, showIcon, 'green', successText);
53
52
  }
54
53
 
55
54
  /**
@@ -64,7 +63,7 @@ export function success(str, showIcon = false) {
64
63
  * // Output: (icon?) Something went wrong. (displayed in red text in the terminal.)
65
64
  */
66
65
  export function error(str, showIcon = false) {
67
- return format(str, showIcon, c.red, errorText);
66
+ return format(str, showIcon, 'red', errorText);
68
67
  }
69
68
 
70
69
  /**
@@ -79,7 +78,7 @@ export function error(str, showIcon = false) {
79
78
  * // Output: (icon?) This is a warning. (displayed in yellow text in the terminal.)
80
79
  */
81
80
  export function warning(str, showIcon = false) {
82
- return format(str, showIcon, c.yellow, warningText);
81
+ return format(str, showIcon, 'yellow', warningText);
83
82
  }
84
83
 
85
84
  /**
@@ -94,7 +93,7 @@ export function warning(str, showIcon = false) {
94
93
  * // Output: (icon?) Informational message. (displayed in blue text in the terminal.)
95
94
  */
96
95
  export function info(str, showIcon = false) {
97
- return format(str, showIcon, c.blue, infoText);
96
+ return format(str, showIcon, 'blue', infoText);
98
97
  }
99
98
 
100
99
  /**
@@ -109,5 +108,5 @@ export function info(str, showIcon = false) {
109
108
  * // Output: (icon?) Hello, Bananass. (displayed in yellow text in the terminal.)
110
109
  */
111
110
  export function bananass(str, showIcon = false) {
112
- return format(str, showIcon, c.yellow, bananassIcon);
111
+ return format(str, showIcon, 'yellow', bananassIcon);
113
112
  }