diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 441975c..1ed55d5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,10 +10,12 @@ jobs: fail-fast: false matrix: node-version: + - 20 + - 18 - 16 steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - run: npm install diff --git a/index.d.ts b/index.d.ts index 400cea2..2f6ea26 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,9 +1,9 @@ -import {SpinnerName} from 'cli-spinners'; +import {type SpinnerName} from 'cli-spinners'; -export interface Spinner { +export type Spinner = { readonly interval?: number; readonly frames: string[]; -} +}; export type Color = | 'black' @@ -20,7 +20,7 @@ export type PrefixTextGenerator = () => string; export type SuffixTextGenerator = () => string; -export interface Options { +export type Options = { /** Text to display after the spinner. */ @@ -114,9 +114,9 @@ export interface Options { @default true */ readonly discardStdin?: boolean; -} +}; -export interface PersistOptions { +export type PersistOptions = { /** Symbol to replace the spinner with. @@ -144,9 +144,9 @@ export interface PersistOptions { Default: Current `suffixText`. */ readonly suffixText?: string | SuffixTextGenerator; -} +}; -export interface PromiseOptions extends Options { +export type PromiseOptions = { /** The new text of the spinner when the promise is resolved. @@ -160,8 +160,9 @@ export interface PromiseOptions extends Options { Keeps the existing text if `undefined`. */ failText?: string | ((error: Error) => string) | undefined; -} +} & Options; +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions export interface Ora { /** Change the text after the spinner. diff --git a/index.js b/index.js index a503eb5..a030362 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,7 @@ import cliCursor from 'cli-cursor'; import cliSpinners from 'cli-spinners'; import logSymbols from 'log-symbols'; import stripAnsi from 'strip-ansi'; -import wcwidth from 'wcwidth'; +import stringWidth from 'string-width'; import isInteractive from 'is-interactive'; import isUnicodeSupported from 'is-unicode-supported'; import stdinDiscarder from 'stdin-discarder'; @@ -98,11 +98,11 @@ class Ora { } this.#indent = indent; - this.updateLineCount(); + this.#updateLineCount(); } get interval() { - return this.#initialInterval || this.#spinner.interval || 100; + return this.#initialInterval ?? this.#spinner.interval ?? 100; } get spinner() { @@ -135,35 +135,34 @@ class Ora { return this.#text; } - set text(value) { - this.#text = value || ''; - this.updateLineCount(); + set text(value = '') { + this.#text = value; + this.#updateLineCount(); } get prefixText() { return this.#prefixText; } - set prefixText(value) { - this.#prefixText = value || ''; - this.updateLineCount(); + set prefixText(value = '') { + this.#prefixText = value; + this.#updateLineCount(); } get suffixText() { return this.#suffixText; } - set suffixText(value) { - this.#suffixText = value || ''; - this.updateLineCount(); + set suffixText(value = '') { + this.#suffixText = value; + this.#updateLineCount(); } get isSpinning() { return this.#id !== undefined; } - // TODO: Use private methods when targeting Node.js 14. - getFullPrefixText(prefixText = this.#prefixText, postfix = ' ') { + #getFullPrefixText(prefixText = this.#prefixText, postfix = ' ') { if (typeof prefixText === 'string' && prefixText !== '') { return prefixText + postfix; } @@ -175,7 +174,7 @@ class Ora { return ''; } - getFullSuffixText(suffixText = this.#suffixText, prefix = ' ') { + #getFullSuffixText(suffixText = this.#suffixText, prefix = ' ') { if (typeof suffixText === 'string' && suffixText !== '') { return prefix + suffixText; } @@ -187,15 +186,15 @@ class Ora { return ''; } - updateLineCount() { - const columns = this.#stream.columns || 80; - const fullPrefixText = this.getFullPrefixText(this.#prefixText, '-'); - const fullSuffixText = this.getFullSuffixText(this.#suffixText, '-'); + #updateLineCount() { + const columns = this.#stream.columns ?? 80; + const fullPrefixText = this.#getFullPrefixText(this.#prefixText, '-'); + const fullSuffixText = this.#getFullSuffixText(this.#suffixText, '-'); const fullText = ' '.repeat(this.#indent) + fullPrefixText + '--' + this.#text + '--' + fullSuffixText; this.#lineCount = 0; for (const line of stripAnsi(fullText).split('\n')) { - this.#lineCount += Math.max(1, Math.ceil(wcwidth(line) / columns)); + this.#lineCount += Math.max(1, Math.ceil(stringWidth(line, {countAnsiEscapeCodes: true}) / columns)); } } @@ -354,16 +353,16 @@ class Ora { return this; } - const prefixText = options.prefixText || this.#prefixText; - const fullPrefixText = this.getFullPrefixText(prefixText, ' '); + const prefixText = options.prefixText ?? this.#prefixText; + const fullPrefixText = this.#getFullPrefixText(prefixText, ' '); - const symbolText = options.symbol || ' '; + const symbolText = options.symbol ?? ' '; - const text = options.text || this.text; + const text = options.text ?? this.text; const fullText = (typeof text === 'string') ? ' ' + text : ''; - const suffixText = options.suffixText !== undefined ? options.suffixText : this.#suffixText; - const fullSuffixText = this.getFullSuffixText(suffixText, ' '); + const suffixText = options.suffixText ?? this.#suffixText; + const fullSuffixText = this.#getFullSuffixText(suffixText, ' '); const textToWrite = fullPrefixText + symbolText + fullText + fullSuffixText + '\n'; diff --git a/index.test-d.ts b/index.test-d.ts index ea954ea..4315163 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,6 +1,6 @@ import {PassThrough as PassThroughStream} from 'node:stream'; import {expectType} from 'tsd'; -import cliSpinners from 'cli-spinners'; +import type cliSpinners from 'cli-spinners'; import ora, {oraPromise, spinners} from './index.js'; const spinner = ora('Loading unicorns'); diff --git a/package.json b/package.json index 5f31bc2..196c180 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "type": "module", "exports": "./index.js", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=16" }, "scripts": { "test": "xo && ava && tsd" @@ -39,22 +39,26 @@ "idle" ], "dependencies": { - "chalk": "^5.0.0", + "chalk": "^5.3.0", "cli-cursor": "^4.0.0", - "cli-spinners": "^2.6.1", + "cli-spinners": "^2.9.0", "is-interactive": "^2.0.0", - "is-unicode-supported": "^1.1.0", + "is-unicode-supported": "^1.3.0", "log-symbols": "^5.1.0", "stdin-discarder": "^0.1.0", - "strip-ansi": "^7.0.1", - "wcwidth": "^1.0.1" + "strip-ansi": "^7.1.0" }, "devDependencies": { - "@types/node": "^17.0.18", - "ava": "^4.0.1", - "get-stream": "^6.0.1", + "@types/node": "^20.4.5", + "ava": "^5.3.1", + "get-stream": "^7.0.1", "transform-tty": "^1.0.11", - "tsd": "^0.19.1", - "xo": "^0.48.0" + "tsd": "^0.28.1", + "xo": "^0.55.0" + }, + "xo": { + "rules": { + "@typescript-eslint/no-redundant-type-constituents": "off" + } } }