Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ora

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ora - npm Package Compare versions

Comparing version 6.0.1 to 6.1.0

utilities.js

56

index.d.ts

@@ -50,3 +50,3 @@ import {SpinnerName} from 'cli-spinners';

/**
Color of the spinner.
The color of the spinner.

@@ -154,7 +154,2 @@ @default 'cyan'

/**
A boolean of whether the instance is currently spinning.
*/
readonly isSpinning: boolean;
/**
Change the text after the spinner.

@@ -165,5 +160,7 @@ */

/**
Change the text or function that returns text before the spinner. No prefix text will be displayed if set to an empty string.
Change the text or function that returns text before the spinner.
No prefix text will be displayed if set to an empty string.
*/
prefixText: string | PrefixTextGenerator;
prefixText: string;

@@ -176,12 +173,29 @@ /**

/**
Change the spinner.
Change the spinner indent.
*/
spinner: SpinnerName | Spinner;
indent: number;
/**
Change the spinner indent.
Get the spinner.
*/
indent: number;
get spinner(): Spinner;
/**
Set the spinner.
*/
set spinner(spinner: SpinnerName | Spinner);
/**
A boolean of whether the instance is currently spinning.
*/
get isSpinning(): boolean;
/**
The interval between each frame.
The interval is decided by the chosen spinner.
*/
get interval(): number;
/**
Start the spinner.

@@ -192,3 +206,3 @@

*/
start(text?: string): Ora;
start(text?: string): this;

@@ -200,3 +214,3 @@ /**

*/
stop(): Ora;
stop(): this;

@@ -209,3 +223,3 @@ /**

*/
succeed(text?: string): Ora;
succeed(text?: string): this;

@@ -218,3 +232,3 @@ /**

*/
fail(text?: string): Ora;
fail(text?: string): this;

@@ -227,3 +241,3 @@ /**

*/
warn(text?: string): Ora;
warn(text?: string): this;

@@ -236,3 +250,3 @@ /**

*/
info(text?: string): Ora;
info(text?: string): this;

@@ -244,3 +258,3 @@ /**

*/
stopAndPersist(options?: PersistOptions): Ora;
stopAndPersist(options?: PersistOptions): this;

@@ -252,3 +266,3 @@ /**

*/
clear(): Ora;
clear(): this;

@@ -260,3 +274,3 @@ /**

*/
render(): Ora;
render(): this;

@@ -263,0 +277,0 @@ /**

import process from 'node:process';
import readline from 'node:readline';
import chalk from 'chalk';

@@ -11,90 +10,24 @@ import cliCursor from 'cli-cursor';

import isUnicodeSupported from 'is-unicode-supported';
import {BufferListStream} from 'bl';
import {StdinDiscarder} from './utilities.js';
const TEXT = Symbol('text');
const PREFIX_TEXT = Symbol('prefixText');
const ASCII_ETX_CODE = 0x03; // Ctrl+C emits this code
let stdinDiscarder;
// TODO: Use class fields when ESLint 8 is out.
class Ora {
#linesToClear = 0;
#isDiscardingStdin = false;
#lineCount = 0;
#frameIndex = 0;
#options;
#spinner;
#stream;
#id;
#initialInterval;
#isEnabled;
#isSilent;
#indent;
#text;
#prefixText;
class StdinDiscarder {
constructor() {
this.requests = 0;
color;
this.mutedStream = new BufferListStream();
this.mutedStream.pipe(process.stdout);
const self = this; // eslint-disable-line unicorn/no-this-assignment
this.ourEmit = function (event, data, ...args) {
const {stdin} = process;
if (self.requests > 0 || stdin.emit === self.ourEmit) {
if (event === 'keypress') { // Fixes readline behavior
return;
}
if (event === 'data' && data.includes(ASCII_ETX_CODE)) {
process.emit('SIGINT');
}
Reflect.apply(self.oldEmit, this, [event, data, ...args]);
} else {
Reflect.apply(process.stdin.emit, this, [event, data, ...args]);
}
};
}
start() {
this.requests++;
if (this.requests === 1) {
this.realStart();
}
}
stop() {
if (this.requests <= 0) {
throw new Error('`stop` called more times than `start`');
}
this.requests--;
if (this.requests === 0) {
this.realStop();
}
}
realStart() {
// No known way to make it work reliably on Windows
if (process.platform === 'win32') {
return;
}
this.rl = readline.createInterface({
input: process.stdin,
output: this.mutedStream,
});
this.rl.on('SIGINT', () => {
if (process.listenerCount('SIGINT') === 0) {
process.emit('SIGINT');
} else {
this.rl.close();
process.kill(process.pid, 'SIGINT');
}
});
}
realStop() {
if (process.platform === 'win32') {
return;
}
this.rl.close();
this.rl = undefined;
}
}
let stdinDiscarder;
class Ora {
constructor(options) {

@@ -111,31 +44,56 @@ if (!stdinDiscarder) {

this.options = {
text: '',
this.#options = {
color: 'cyan',
stream: process.stderr,
discardStdin: true,
hideCursor: true,
...options,
};
this.spinner = this.options.spinner;
// Public
this.color = this.#options.color;
this.color = this.options.color;
this.hideCursor = this.options.hideCursor !== false;
this.interval = this.options.interval || this.spinner.interval || 100;
this.stream = this.options.stream;
this.id = undefined;
this.isEnabled = typeof this.options.isEnabled === 'boolean' ? this.options.isEnabled : isInteractive({stream: this.stream});
this.isSilent = typeof this.options.isSilent === 'boolean' ? this.options.isSilent : false;
// It's important that these use the public setters.
this.spinner = this.#options.spinner;
// Set *after* `this.stream`
this.text = this.options.text;
this.prefixText = this.options.prefixText;
this.linesToClear = 0;
this.indent = this.options.indent;
this.discardStdin = this.options.discardStdin;
this.isDiscardingStdin = false;
this.#initialInterval = this.#options.interval;
this.#stream = this.#options.stream;
this.#isEnabled = typeof this.#options.isEnabled === 'boolean' ? this.#options.isEnabled : isInteractive({stream: this.#stream});
this.#isSilent = typeof this.#options.isSilent === 'boolean' ? this.#options.isSilent : false;
// Set *after* `this.#stream`.
// It's important that these use the public setters.
this.text = this.#options.text;
this.prefixText = this.#options.prefixText;
this.indent = this.#options.indent;
if (process.env.NODE_ENV === 'test') {
this._stream = this.#stream;
this._isEnabled = this.#isEnabled;
Object.defineProperty(this, '_linesToClear', {
get() {
return this.#linesToClear;
},
set(newValue) {
this.#linesToClear = newValue;
},
});
Object.defineProperty(this, '_frameIndex', {
get() {
return this.#frameIndex;
},
});
Object.defineProperty(this, '_lineCount', {
get() {
return this.#lineCount;
},
});
}
}
get indent() {
return this._indent;
return this.#indent;
}

@@ -148,18 +106,17 @@

this._indent = indent;
this.#indent = indent;
this.updateLineCount();
}
_updateInterval(interval) {
if (interval !== undefined) {
this.interval = interval;
}
get interval() {
return this.#initialInterval || this.#spinner.interval || 100;
}
get spinner() {
return this._spinner;
return this.#spinner;
}
set spinner(spinner) {
this.frameIndex = 0;
this.#frameIndex = 0;
this.#initialInterval = undefined;

@@ -171,23 +128,21 @@ if (typeof spinner === 'object') {

this._spinner = spinner;
this.#spinner = spinner;
} else if (!isUnicodeSupported()) {
this._spinner = cliSpinners.line;
this.#spinner = cliSpinners.line;
} else if (spinner === undefined) {
// Set default spinner
this._spinner = cliSpinners.dots;
this.#spinner = cliSpinners.dots;
} else if (spinner !== 'default' && cliSpinners[spinner]) {
this._spinner = cliSpinners[spinner];
this.#spinner = cliSpinners[spinner];
} else {
throw new Error(`There is no built-in spinner named '${spinner}'. See https://github.com/sindresorhus/cli-spinners/blob/main/spinners.json for a full list.`);
}
this._updateInterval(this._spinner.interval);
}
get text() {
return this[TEXT];
return this.#text;
}
set text(value) {
this[TEXT] = value;
this.#text = value || '';
this.updateLineCount();

@@ -197,7 +152,7 @@ }

get prefixText() {
return this[PREFIX_TEXT];
return this.#prefixText;
}
set prefixText(value) {
this[PREFIX_TEXT] = value;
this.#prefixText = value || '';
this.updateLineCount();

@@ -207,7 +162,8 @@ }

get isSpinning() {
return this.id !== undefined;
return this.#id !== undefined;
}
getFullPrefixText(prefixText = this[PREFIX_TEXT], postfix = ' ') {
if (typeof prefixText === 'string') {
// TODO: Use private methods when targeting Node.js 14.
getFullPrefixText(prefixText = this.#prefixText, postfix = ' ') {
if (typeof prefixText === 'string' && prefixText !== '') {
return prefixText + postfix;

@@ -224,7 +180,8 @@ }

updateLineCount() {
const columns = this.stream.columns || 80;
const fullPrefixText = this.getFullPrefixText(this.prefixText, '-');
this.lineCount = 0;
for (const line of stripAnsi(' '.repeat(this.indent) + fullPrefixText + '--' + this[TEXT]).split('\n')) {
this.lineCount += Math.max(1, Math.ceil(wcwidth(line) / columns));
const columns = this.#stream.columns || 80;
const fullPrefixText = this.getFullPrefixText(this.#prefixText, '-');
this.#lineCount = 0;
for (const line of stripAnsi(' '.repeat(this.#indent) + fullPrefixText + '--' + this.#text).split('\n')) {
this.#lineCount += Math.max(1, Math.ceil(wcwidth(line) / columns));
}

@@ -234,3 +191,3 @@ }

get isEnabled() {
return this._isEnabled && !this.isSilent;
return this.#isEnabled && !this.#isSilent;
}

@@ -243,7 +200,7 @@

this._isEnabled = value;
this.#isEnabled = value;
}
get isSilent() {
return this._isSilent;
return this.#isSilent;
}

@@ -256,8 +213,8 @@

this._isSilent = value;
this.#isSilent = value;
}
frame() {
const {frames} = this.spinner;
let frame = frames[this.frameIndex];
const {frames} = this.#spinner;
let frame = frames[this.#frameIndex];

@@ -268,4 +225,4 @@ if (this.color) {

this.frameIndex = ++this.frameIndex % frames.length;
const fullPrefixText = (typeof this.prefixText === 'string' && this.prefixText !== '') ? this.prefixText + ' ' : '';
this.#frameIndex = ++this.#frameIndex % frames.length;
const fullPrefixText = (typeof this.#prefixText === 'string' && this.#prefixText !== '') ? this.#prefixText + ' ' : '';
const fullText = typeof this.text === 'string' ? ' ' + this.text : '';

@@ -277,22 +234,22 @@

clear() {
if (!this.isEnabled || !this.stream.isTTY) {
if (!this.#isEnabled || !this.#stream.isTTY) {
return this;
}
this.stream.cursorTo(0);
this.#stream.cursorTo(0);
for (let index = 0; index < this.linesToClear; index++) {
for (let index = 0; index < this.#linesToClear; index++) {
if (index > 0) {
this.stream.moveCursor(0, -1);
this.#stream.moveCursor(0, -1);
}
this.stream.clearLine(1);
this.#stream.clearLine(1);
}
if (this.indent || this.lastIndent !== this.indent) {
this.stream.cursorTo(this.indent);
if (this.#indent || this.lastIndent !== this.#indent) {
this.#stream.cursorTo(this.#indent);
}
this.lastIndent = this.indent;
this.linesToClear = 0;
this.lastIndent = this.#indent;
this.#linesToClear = 0;

@@ -303,3 +260,3 @@ return this;

render() {
if (this.isSilent) {
if (this.#isSilent) {
return this;

@@ -309,4 +266,4 @@ }

this.clear();
this.stream.write(this.frame());
this.linesToClear = this.lineCount;
this.#stream.write(this.frame());
this.#linesToClear = this.#lineCount;

@@ -321,9 +278,9 @@ return this;

if (this.isSilent) {
if (this.#isSilent) {
return this;
}
if (!this.isEnabled) {
if (!this.#isEnabled) {
if (this.text) {
this.stream.write(`- ${this.text}\n`);
this.#stream.write(`- ${this.text}\n`);
}

@@ -338,8 +295,8 @@

if (this.hideCursor) {
cliCursor.hide(this.stream);
if (this.#options.hideCursor) {
cliCursor.hide(this.#stream);
}
if (this.discardStdin && process.stdin.isTTY) {
this.isDiscardingStdin = true;
if (this.#options.discardStdin && process.stdin.isTTY) {
this.#isDiscardingStdin = true;
stdinDiscarder.start();

@@ -349,3 +306,3 @@ }

this.render();
this.id = setInterval(this.render.bind(this), this.interval);
this.#id = setInterval(this.render.bind(this), this.interval);

@@ -356,17 +313,17 @@ return this;

stop() {
if (!this.isEnabled) {
if (!this.#isEnabled) {
return this;
}
clearInterval(this.id);
this.id = undefined;
this.frameIndex = 0;
clearInterval(this.#id);
this.#id = undefined;
this.#frameIndex = 0;
this.clear();
if (this.hideCursor) {
cliCursor.show(this.stream);
if (this.#options.hideCursor) {
cliCursor.show(this.#stream);
}
if (this.discardStdin && process.stdin.isTTY && this.isDiscardingStdin) {
if (this.#options.discardStdin && process.stdin.isTTY && this.#isDiscardingStdin) {
stdinDiscarder.stop();
this.isDiscardingStdin = false;
this.#isDiscardingStdin = false;
}

@@ -394,7 +351,7 @@

stopAndPersist(options = {}) {
if (this.isSilent) {
if (this.#isSilent) {
return this;
}
const prefixText = options.prefixText || this.prefixText;
const prefixText = options.prefixText || this.#prefixText;
const text = options.text || this.text;

@@ -404,3 +361,3 @@ const fullText = (typeof text === 'string') ? ' ' + text : '';

this.stop();
this.stream.write(`${this.getFullPrefixText(prefixText, ' ')}${options.symbol || ' '}${fullText}\n`);
this.#stream.write(`${this.getFullPrefixText(prefixText, ' ')}${options.symbol || ' '}${fullText}\n`);

@@ -417,3 +374,2 @@ return this;

const actionIsFunction = typeof action === 'function';
// eslint-disable-next-line promise/prefer-await-to-then
const actionIsPromise = typeof action.then === 'function';

@@ -420,0 +376,0 @@

{
"name": "ora",
"version": "6.0.1",
"version": "6.1.0",
"description": "Elegant terminal spinner",

@@ -23,3 +23,4 @@ "license": "MIT",

"index.js",
"index.d.ts"
"index.d.ts",
"utilities.js"
],

@@ -44,8 +45,8 @@ "keywords": [

"bl": "^5.0.0",
"chalk": "^4.1.2",
"chalk": "^5.0.0",
"cli-cursor": "^4.0.0",
"cli-spinners": "^2.6.0",
"cli-spinners": "^2.6.1",
"is-interactive": "^2.0.0",
"is-unicode-supported": "^1.1.0",
"log-symbols": "^5.0.0",
"log-symbols": "^5.1.0",
"strip-ansi": "^7.0.1",

@@ -55,9 +56,9 @@ "wcwidth": "^1.0.1"

"devDependencies": {
"@types/node": "^16.9.1",
"ava": "^3.15.0",
"@types/node": "^17.0.18",
"ava": "^4.0.1",
"get-stream": "^6.0.1",
"transform-tty": "^1.0.11",
"tsd": "^0.17.0",
"xo": "^0.44.0"
"tsd": "^0.19.1",
"xo": "^0.48.0"
}
}

@@ -13,5 +13,5 @@ # ora

```sh
npm install ora
```
$ npm install ora
```

@@ -76,3 +76,3 @@ ## Usage

Color of the spinner.
The color of the spinner.

@@ -137,2 +137,34 @@ ##### hideCursor

#### .text <sup>get/set</sup>
Change the text after the spinner.
#### .prefixText <sup>get/set</sup>
Change the text before the spinner.
No prefix text will be displayed if set to an empty string.
#### .color <sup>get/set</sup>
Change the spinner color.
#### .spinner <sup>get/set</sup>
Change the spinner.
#### .indent <sup>get/set</sup>
Change the spinner indent.
#### .isSpinning <sup>get</sup>
A boolean of whether the instance is currently spinning.
#### .interval <sup>get</sup>
The interval between each frame.
The interval is decided by the chosen spinner.
#### .start(text?)

@@ -162,6 +194,2 @@

#### .isSpinning
A boolean of whether the instance is currently spinning.
#### .stopAndPersist(options?)

@@ -210,22 +238,2 @@

#### .text
Change the text after the spinner.
#### .prefixText
Change the text before the spinner. No prefix text will be displayed if set to an empty string.
#### .color
Change the spinner color.
#### .spinner
Change the spinner.
#### .indent
Change the spinner indent.
### oraPromise(action, text)

@@ -232,0 +240,0 @@ ### oraPromise(action, options)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc