UNPKG

2.5 kBJavaScriptView Raw
1'use strict';
2const chalk = require('chalk');
3const cliCursor = require('cli-cursor');
4const cliSpinners = require('cli-spinners');
5const logSymbols = require('log-symbols');
6
7class Ora {
8 constructor(options) {
9 if (typeof options === 'string') {
10 options = {
11 text: options
12 };
13 }
14
15 this.options = Object.assign({
16 text: '',
17 color: 'cyan',
18 stream: process.stderr
19 }, options);
20
21 const sp = this.options.spinner;
22 this.spinner = typeof sp === 'object' ? sp : (process.platform === 'win32' ? cliSpinners.line : (cliSpinners[sp] || cliSpinners.dots)); // eslint-disable-line no-nested-ternary
23
24 if (this.spinner.frames === undefined) {
25 throw new Error('Spinner must define `frames`');
26 }
27
28 this.text = this.options.text;
29 this.color = this.options.color;
30 this.interval = this.options.interval || this.spinner.interval || 100;
31 this.stream = this.options.stream;
32 this.id = null;
33 this.frameIndex = 0;
34 this.enabled = this.options.enabled || ((this.stream && this.stream.isTTY) && !process.env.CI);
35 }
36 frame() {
37 const frames = this.spinner.frames;
38 let frame = frames[this.frameIndex];
39
40 if (this.color) {
41 frame = chalk[this.color](frame);
42 }
43
44 this.frameIndex = ++this.frameIndex % frames.length;
45
46 return frame + ' ' + this.text;
47 }
48 clear() {
49 if (!this.enabled) {
50 return this;
51 }
52
53 this.stream.clearLine();
54 this.stream.cursorTo(0);
55
56 return this;
57 }
58 render() {
59 this.clear();
60 this.stream.write(this.frame());
61
62 return this;
63 }
64 start() {
65 if (!this.enabled || this.id) {
66 return this;
67 }
68
69 cliCursor.hide(this.stream);
70 this.render();
71 this.id = setInterval(this.render.bind(this), this.interval);
72
73 return this;
74 }
75 stop() {
76 if (!this.enabled) {
77 return this;
78 }
79
80 clearInterval(this.id);
81 this.id = null;
82 this.frameIndex = 0;
83 this.clear();
84 cliCursor.show(this.stream);
85
86 return this;
87 }
88 succeed() {
89 return this.stopAndPersist(logSymbols.success);
90 }
91 fail() {
92 return this.stopAndPersist(logSymbols.error);
93 }
94 stopAndPersist(symbol) {
95 this.stop();
96 this.stream.write(`${symbol || ' '} ${this.text}\n`);
97
98 return this;
99 }
100}
101
102module.exports = function (opts) {
103 return new Ora(opts);
104};
105
106module.exports.promise = (action, options) => {
107 if (typeof action.then !== 'function') {
108 throw new Error('Parameter `action` must be a Promise');
109 }
110
111 const spinner = new Ora(options);
112 spinner.start();
113
114 action.then(
115 () => {
116 spinner.succeed();
117 },
118 () => {
119 spinner.fail();
120 }
121 );
122
123 return spinner;
124};