UNPKG

4.77 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const _ = tslib_1.__importStar(require("lodash"));
5const util_1 = require("util");
6class ActionBase {
7 constructor() {
8 this.std = 'stderr';
9 this.stdmockOrigs = {
10 stdout: process.stdout.write,
11 stderr: process.stderr.write,
12 };
13 }
14 start(action, status, opts = {}) {
15 this.std = opts.stdout ? 'stdout' : 'stderr';
16 const task = (this.task = { action, status, active: !!(this.task && this.task.active) });
17 this._start();
18 task.active = true;
19 this._stdout(true);
20 }
21 stop(msg = 'done') {
22 const task = this.task;
23 if (!task) {
24 return;
25 }
26 this._stop(msg);
27 task.active = false;
28 this.task = undefined;
29 this._stdout(false);
30 }
31 get globals() {
32 const globals = (global['cli-ux'] = global['cli-ux'] || {});
33 globals.action = globals.action || {};
34 return globals;
35 }
36 get task() {
37 return this.globals.action.task;
38 }
39 set task(task) {
40 this.globals.action.task = task;
41 }
42 get output() {
43 return this.globals.output;
44 }
45 set output(output) {
46 this.globals.output = output;
47 }
48 get running() {
49 return !!this.task;
50 }
51 get status() {
52 return this.task ? this.task.status : undefined;
53 }
54 set status(status) {
55 const task = this.task;
56 if (!task) {
57 return;
58 }
59 if (task.status === status) {
60 return;
61 }
62 this._updateStatus(status, task.status);
63 task.status = status;
64 }
65 async pauseAsync(fn, icon) {
66 const task = this.task;
67 const active = task && task.active;
68 if (task && active) {
69 this._pause(icon);
70 this._stdout(false);
71 task.active = false;
72 }
73 const ret = await fn();
74 if (task && active) {
75 this._resume();
76 }
77 return ret;
78 }
79 pause(fn, icon) {
80 const task = this.task;
81 const active = task && task.active;
82 if (task && active) {
83 this._pause(icon);
84 this._stdout(false);
85 task.active = false;
86 }
87 const ret = fn();
88 if (task && active) {
89 this._resume();
90 }
91 return ret;
92 }
93 _start() {
94 throw new Error('not implemented');
95 }
96 _stop(_) {
97 throw new Error('not implemented');
98 }
99 _resume() {
100 if (this.task)
101 this.start(this.task.action, this.task.status);
102 }
103 _pause(_) {
104 throw new Error('not implemented');
105 }
106 _updateStatus(_, __) { }
107 /**
108 * mock out stdout/stderr so it doesn't screw up the rendering
109 */
110 _stdout(toggle) {
111 try {
112 const outputs = ['stdout', 'stderr'];
113 if (toggle) {
114 if (this.stdmocks)
115 return;
116 this.stdmockOrigs = {
117 stdout: process.stdout.write,
118 stderr: process.stderr.write,
119 };
120 this.stdmocks = [];
121 for (let std of outputs) {
122 process[std].write = (...args) => {
123 this.stdmocks.push([std, args]);
124 };
125 }
126 }
127 else {
128 if (!this.stdmocks)
129 return;
130 // this._write('stderr', '\nresetstdmock\n\n\n')
131 delete this.stdmocks;
132 for (let std of outputs)
133 process[std].write = this.stdmockOrigs[std];
134 }
135 }
136 catch (err) {
137 this._write('stderr', util_1.inspect(err));
138 }
139 }
140 /**
141 * flush mocked stdout/stderr
142 */
143 _flushStdout() {
144 try {
145 let output = '';
146 let std;
147 while (this.stdmocks && this.stdmocks.length) {
148 let cur = this.stdmocks.shift();
149 std = cur[0];
150 this._write(std, cur[1]);
151 output += cur[1][0].toString('utf8');
152 }
153 // add newline if there isn't one already
154 // otherwise we'll just overwrite it when we render
155 if (output && std && output[output.length - 1] !== '\n') {
156 this._write(std, '\n');
157 }
158 }
159 catch (err) {
160 this._write('stderr', util_1.inspect(err));
161 }
162 }
163 /**
164 * write to the real stdout/stderr
165 */
166 _write(std, s) {
167 this.stdmockOrigs[std].apply(process[std], _.castArray(s));
168 }
169}
170exports.ActionBase = ActionBase;