@hubspot/cli 4.2.0 → 4.2.1-beta.1
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.
- package/commands/cms/lighthouseScore.js +4 -5
- package/commands/module/marketplace-validate.js +5 -5
- package/commands/project/dev.js +101 -42
- package/commands/project/logs.js +132 -129
- package/commands/project/upload.js +4 -4
- package/commands/sandbox/create.js +0 -5
- package/commands/sandbox/delete.js +2 -8
- package/commands/sandbox/sync.js +5 -8
- package/commands/theme/marketplace-validate.js +5 -5
- package/lang/en.lyaml +25 -7
- package/lib/DevServerManager.js +53 -28
- package/lib/LocalDevManager.js +256 -168
- package/lib/LocalDevManagerV2.js +129 -0
- package/lib/SpinniesManager.js +318 -59
- package/lib/projects.js +36 -33
- package/lib/sandbox-create.js +5 -5
- package/lib/sandbox-sync.js +9 -9
- package/lib/serverlessLogs.js +8 -8
- package/lib/spinniesUtils.js +174 -0
- package/lib/ui.js +7 -0
- package/package.json +6 -4
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
const { i18n } = require('./lang');
|
|
4
|
+
const { logger } = require('@hubspot/cli-lib/logger');
|
|
5
|
+
const { handleKeypress } = require('@hubspot/cli-lib/lib/process');
|
|
6
|
+
const SpinniesManager = require('./SpinniesManager');
|
|
7
|
+
const DevServerManager = require('./DevServerManager');
|
|
8
|
+
const { EXIT_CODES } = require('./enums/exitCodes');
|
|
9
|
+
const { getProjectDetailUrl } = require('./projects');
|
|
10
|
+
const { uiAccountDescription, uiBetaMessage, uiLink, uiLine } = require('./ui');
|
|
11
|
+
|
|
12
|
+
const i18nKey = 'cli.lib.LocalDevManagerV2';
|
|
13
|
+
|
|
14
|
+
class LocalDevManagerV2 {
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.targetAccountId = options.targetAccountId;
|
|
17
|
+
this.projectConfig = options.projectConfig;
|
|
18
|
+
this.projectDir = options.projectDir;
|
|
19
|
+
this.extension = options.extension;
|
|
20
|
+
this.debug = options.debug || false;
|
|
21
|
+
|
|
22
|
+
this.projectSourceDir = path.join(
|
|
23
|
+
this.projectDir,
|
|
24
|
+
this.projectConfig.srcDir
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
if (!this.targetAccountId || !this.projectConfig || !this.projectDir) {
|
|
28
|
+
logger.log(i18n(`${i18nKey}.failedToInitialize`));
|
|
29
|
+
process.exit(EXIT_CODES.ERROR);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async start() {
|
|
34
|
+
console.clear();
|
|
35
|
+
SpinniesManager.removeAll();
|
|
36
|
+
SpinniesManager.init();
|
|
37
|
+
|
|
38
|
+
uiBetaMessage(i18n(`${i18nKey}.betaMessage`));
|
|
39
|
+
logger.log();
|
|
40
|
+
logger.log(
|
|
41
|
+
chalk.hex('#FF8F59')(
|
|
42
|
+
i18n(`${i18nKey}.running`, {
|
|
43
|
+
accountIdentifier: uiAccountDescription(this.targetAccountId),
|
|
44
|
+
projectName: this.projectConfig.name,
|
|
45
|
+
})
|
|
46
|
+
)
|
|
47
|
+
);
|
|
48
|
+
logger.log(
|
|
49
|
+
uiLink(
|
|
50
|
+
i18n(`${i18nKey}.viewInHubSpotLink`),
|
|
51
|
+
getProjectDetailUrl(this.projectConfig.name, this.targetAccountId)
|
|
52
|
+
)
|
|
53
|
+
);
|
|
54
|
+
logger.log();
|
|
55
|
+
logger.log(i18n(`${i18nKey}.quitHelper`));
|
|
56
|
+
uiLine();
|
|
57
|
+
logger.log();
|
|
58
|
+
|
|
59
|
+
await this.devServerStart();
|
|
60
|
+
|
|
61
|
+
this.updateKeypressListeners();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async stop() {
|
|
65
|
+
SpinniesManager.add('cleanupMessage', {
|
|
66
|
+
text: i18n(`${i18nKey}.exitingStart`),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const cleanupSucceeded = await this.devServerCleanup();
|
|
70
|
+
|
|
71
|
+
if (!cleanupSucceeded) {
|
|
72
|
+
SpinniesManager.fail('cleanupMessage', {
|
|
73
|
+
text: i18n(`${i18nKey}.exitingFail`),
|
|
74
|
+
});
|
|
75
|
+
process.exit(EXIT_CODES.ERROR);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
SpinniesManager.succeed('cleanupMessage', {
|
|
79
|
+
text: i18n(`${i18nKey}.exitingSucceed`),
|
|
80
|
+
});
|
|
81
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
updateKeypressListeners() {
|
|
85
|
+
handleKeypress(async key => {
|
|
86
|
+
if ((key.ctrl && key.name === 'c') || key.name === 'q') {
|
|
87
|
+
this.stop();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async devServerStart() {
|
|
93
|
+
try {
|
|
94
|
+
DevServerManager.safeLoadServer();
|
|
95
|
+
await DevServerManager.start({
|
|
96
|
+
accountId: this.targetAccountId,
|
|
97
|
+
debug: this.debug,
|
|
98
|
+
extension: this.extension,
|
|
99
|
+
projectConfig: this.projectConfig,
|
|
100
|
+
projectSourceDir: this.projectSourceDir,
|
|
101
|
+
});
|
|
102
|
+
} catch (e) {
|
|
103
|
+
if (this.debug) {
|
|
104
|
+
logger.error(e);
|
|
105
|
+
}
|
|
106
|
+
logger.error(
|
|
107
|
+
i18n(`${i18nKey}.devServer.startError`, { message: e.message })
|
|
108
|
+
);
|
|
109
|
+
process.exit(EXIT_CODES.ERROR);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async devServerCleanup() {
|
|
114
|
+
try {
|
|
115
|
+
await DevServerManager.cleanup();
|
|
116
|
+
return true;
|
|
117
|
+
} catch (e) {
|
|
118
|
+
if (this.debug) {
|
|
119
|
+
logger.error(e);
|
|
120
|
+
}
|
|
121
|
+
logger.error(
|
|
122
|
+
i18n(`${i18nKey}.devServer.cleanupError`, { message: e.message })
|
|
123
|
+
);
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
module.exports = LocalDevManagerV2;
|
package/lib/SpinniesManager.js
CHANGED
|
@@ -1,105 +1,364 @@
|
|
|
1
|
-
|
|
1
|
+
/*
|
|
2
|
+
https://github.com/jbcarpanelli/spinnies
|
|
3
|
+
|
|
4
|
+
Copyright 2019 Juan Bautista Carpanelli (jcarpanelli)
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
7
|
+
|
|
8
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
9
|
+
**/
|
|
10
|
+
|
|
11
|
+
const readline = require('readline');
|
|
12
|
+
const chalk = require('chalk');
|
|
13
|
+
const cliCursor = require('cli-cursor');
|
|
14
|
+
const {
|
|
15
|
+
breakText,
|
|
16
|
+
cleanStream,
|
|
17
|
+
colorOptions,
|
|
18
|
+
getLinesLength,
|
|
19
|
+
purgeSpinnerOptions,
|
|
20
|
+
purgeSpinnersOptions,
|
|
21
|
+
SPINNERS,
|
|
22
|
+
terminalSupportsUnicode,
|
|
23
|
+
writeStream,
|
|
24
|
+
} = require('./spinniesUtils');
|
|
2
25
|
|
|
3
|
-
// Allows us to maintain a single instance of spinnies across multiple files
|
|
4
26
|
class SpinniesManager {
|
|
5
27
|
constructor() {
|
|
6
|
-
this.
|
|
7
|
-
this.parentKey = null;
|
|
8
|
-
this.categories = {};
|
|
28
|
+
this.resetState();
|
|
9
29
|
}
|
|
10
30
|
|
|
11
|
-
init(options) {
|
|
12
|
-
|
|
13
|
-
|
|
31
|
+
init(options = {}) {
|
|
32
|
+
this.options = {
|
|
33
|
+
spinnerColor: 'greenBright',
|
|
34
|
+
succeedColor: 'green',
|
|
35
|
+
failColor: 'red',
|
|
36
|
+
spinner: terminalSupportsUnicode() ? SPINNERS.dots : SPINNERS.dashes,
|
|
37
|
+
disableSpins: false,
|
|
38
|
+
...purgeSpinnersOptions(options),
|
|
39
|
+
};
|
|
40
|
+
this.spin =
|
|
41
|
+
!this.options.disableSpins &&
|
|
42
|
+
!process.env.CI &&
|
|
43
|
+
process.stderr &&
|
|
44
|
+
process.stderr.isTTY;
|
|
45
|
+
|
|
46
|
+
if (!this.hasAnySpinners()) {
|
|
47
|
+
this.resetState();
|
|
14
48
|
}
|
|
49
|
+
this.bindSigint();
|
|
50
|
+
}
|
|
15
51
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
52
|
+
resetState() {
|
|
53
|
+
// Default Spinnies fields
|
|
54
|
+
this.spinners = {};
|
|
55
|
+
this.isCursorHidden = false;
|
|
56
|
+
if (this.currentInterval) {
|
|
57
|
+
clearInterval(this.currentInterval);
|
|
58
|
+
}
|
|
59
|
+
this.currentInterval = null;
|
|
60
|
+
this.stream = process.stderr;
|
|
61
|
+
this.lineCount = 0;
|
|
62
|
+
this.currentFrameIndex = 0;
|
|
63
|
+
|
|
64
|
+
// Custom fields
|
|
65
|
+
this.parentSpinnerName = null;
|
|
66
|
+
this.categories = {};
|
|
27
67
|
}
|
|
28
68
|
|
|
29
|
-
|
|
69
|
+
addSpinnerToCategory(name, category) {
|
|
30
70
|
if (!this.categories[category]) {
|
|
31
|
-
this.categories[category] =
|
|
71
|
+
this.categories[category] = {};
|
|
32
72
|
}
|
|
33
|
-
this.categories[category]
|
|
73
|
+
this.categories[category][name] = true;
|
|
34
74
|
}
|
|
35
75
|
|
|
36
|
-
|
|
37
|
-
return Object.keys(this.categories).find(
|
|
38
|
-
this.categories[category]
|
|
76
|
+
getSpinnerCategory(name) {
|
|
77
|
+
return Object.keys(this.categories).find(
|
|
78
|
+
category => !!this.categories[category][name]
|
|
39
79
|
);
|
|
40
80
|
}
|
|
41
81
|
|
|
42
|
-
|
|
43
|
-
const category = this.
|
|
82
|
+
removeSpinnerFromCategory(name) {
|
|
83
|
+
const category = this.getSpinnerCategory(name);
|
|
44
84
|
if (category) {
|
|
45
|
-
|
|
46
|
-
this.categories[category].splice(index, 1);
|
|
85
|
+
delete this.categories[category][name];
|
|
47
86
|
}
|
|
48
87
|
}
|
|
49
88
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
89
|
+
pick(name) {
|
|
90
|
+
return this.spinners[name];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
add(name, options = {}) {
|
|
94
|
+
const { category, isParent, noIndent, ...spinnerOptions } = options;
|
|
53
95
|
|
|
54
|
-
// Support adding generic spinnies lines without specifying a
|
|
55
|
-
const
|
|
96
|
+
// Support adding generic spinnies lines without specifying a name
|
|
97
|
+
const resolvedName = name || `${Date.now()}-${Math.random()}`;
|
|
56
98
|
|
|
57
99
|
if (category) {
|
|
58
|
-
this.
|
|
100
|
+
this.addSpinnerToCategory(resolvedName, category);
|
|
59
101
|
}
|
|
60
102
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
103
|
+
if (!options.text) {
|
|
104
|
+
spinnerOptions.text = resolvedName;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const originalIndent = spinnerOptions.indent || 0;
|
|
108
|
+
|
|
109
|
+
const spinnerProperties = {
|
|
110
|
+
...colorOptions(this.options),
|
|
111
|
+
succeedPrefix: this.options.succeedPrefix,
|
|
112
|
+
failPrefix: this.options.failPrefix,
|
|
113
|
+
status: 'spinning',
|
|
114
|
+
...purgeSpinnerOptions(spinnerOptions),
|
|
115
|
+
indent:
|
|
116
|
+
this.parentSpinnerName && !noIndent
|
|
117
|
+
? originalIndent + 1
|
|
118
|
+
: originalIndent,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
this.spinners[resolvedName] = spinnerProperties;
|
|
122
|
+
this.updateSpinnerState();
|
|
65
123
|
|
|
66
124
|
if (isParent) {
|
|
67
|
-
this.
|
|
125
|
+
this.parentSpinnerName = resolvedName;
|
|
68
126
|
}
|
|
69
127
|
|
|
70
|
-
return
|
|
128
|
+
return { name: resolvedName, ...spinnerProperties };
|
|
71
129
|
}
|
|
72
130
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
131
|
+
update(name, options = {}) {
|
|
132
|
+
const { status } = options;
|
|
133
|
+
this.setSpinnerProperties(name, options, status);
|
|
134
|
+
this.updateSpinnerState();
|
|
135
|
+
|
|
136
|
+
return this.spinners[name];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// TODO there is an issue here with the usage of "non-spinnable"
|
|
140
|
+
// The spinnies lib automatically removes any non-active spinners
|
|
141
|
+
// after adding a new spinner (add -> updateSpinnerState -> checkIfActiveSpinners)
|
|
142
|
+
// so "pick" is telling us that these newly-added spinners don't exist.
|
|
143
|
+
addOrUpdate(name, options = {}) {
|
|
144
|
+
const spinner = this.pick(name);
|
|
145
|
+
|
|
146
|
+
if (spinner) {
|
|
147
|
+
this.update(name, options);
|
|
148
|
+
} else {
|
|
149
|
+
this.add(name, options);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
succeed(name, options = {}) {
|
|
154
|
+
this.setSpinnerProperties(name, options, 'succeed');
|
|
155
|
+
this.updateSpinnerState();
|
|
156
|
+
|
|
157
|
+
return this.spinners[name];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
fail(name, options = {}) {
|
|
161
|
+
this.setSpinnerProperties(name, options, 'fail');
|
|
162
|
+
this.updateSpinnerState();
|
|
163
|
+
|
|
164
|
+
return this.spinners[name];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
remove(name) {
|
|
168
|
+
if (typeof name !== 'string') {
|
|
169
|
+
throw Error('A spinner reference name must be specified');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (name === this.parentSpinnerName) {
|
|
173
|
+
this.parentSpinnerName = null;
|
|
80
174
|
}
|
|
175
|
+
|
|
176
|
+
this.removeSpinnerFromCategory(name);
|
|
177
|
+
|
|
178
|
+
const spinner = this.spinners[name];
|
|
179
|
+
delete this.spinners[name];
|
|
180
|
+
return spinner;
|
|
81
181
|
}
|
|
82
182
|
|
|
83
183
|
/**
|
|
84
184
|
* Removes all spinnies instances
|
|
185
|
+
* @param {string} targetCategory - remove all spinnies with a matching category
|
|
85
186
|
* @param {string} preserveCategory - do not remove spinnies with a matching category
|
|
86
187
|
*/
|
|
87
188
|
removeAll({ preserveCategory = null, targetCategory = null } = {}) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (targetCategory) {
|
|
91
|
-
|
|
92
|
-
|
|
189
|
+
Object.keys(this.spinners).forEach(name => {
|
|
190
|
+
if (targetCategory) {
|
|
191
|
+
if (this.getSpinnerCategory(name) === targetCategory) {
|
|
192
|
+
this.remove(name);
|
|
193
|
+
}
|
|
194
|
+
} else if (
|
|
195
|
+
!preserveCategory ||
|
|
196
|
+
this.getSpinnerCategory(name) !== preserveCategory
|
|
197
|
+
) {
|
|
198
|
+
this.remove(name);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
stopAll(newStatus = 'stopped') {
|
|
204
|
+
Object.keys(this.spinners).forEach(name => {
|
|
205
|
+
const { status: currentStatus } = this.spinners[name];
|
|
206
|
+
if (
|
|
207
|
+
currentStatus !== 'fail' &&
|
|
208
|
+
currentStatus !== 'succeed' &&
|
|
209
|
+
currentStatus !== 'non-spinnable'
|
|
210
|
+
) {
|
|
211
|
+
if (newStatus === 'succeed' || newStatus === 'fail') {
|
|
212
|
+
this.spinners[name].status = newStatus;
|
|
213
|
+
this.spinners[name].color = this.options[`${newStatus}Color`];
|
|
214
|
+
} else {
|
|
215
|
+
this.spinners[name].status = 'stopped';
|
|
216
|
+
this.spinners[name].color = 'grey';
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
this.checkIfActiveSpinners();
|
|
221
|
+
|
|
222
|
+
return this.spinners;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
hasAnySpinners() {
|
|
226
|
+
return !!Object.keys(this.spinners).length;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
hasActiveSpinners() {
|
|
230
|
+
return !!Object.values(this.spinners).find(
|
|
231
|
+
({ status }) => status === 'spinning'
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
setSpinnerProperties(name, options, status) {
|
|
236
|
+
if (typeof name !== 'string') {
|
|
237
|
+
throw Error('A spinner reference name must be specified');
|
|
238
|
+
}
|
|
239
|
+
if (!this.spinners[name]) {
|
|
240
|
+
throw Error(`No spinner initialized with name ${name}`);
|
|
241
|
+
}
|
|
242
|
+
options = purgeSpinnerOptions(options);
|
|
243
|
+
status = status || 'spinning';
|
|
244
|
+
|
|
245
|
+
this.spinners[name] = { ...this.spinners[name], ...options, status };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
updateSpinnerState() {
|
|
249
|
+
if (this.spin) {
|
|
250
|
+
clearInterval(this.currentInterval);
|
|
251
|
+
this.currentInterval = this.loopStream();
|
|
252
|
+
if (!this.isCursorHidden) {
|
|
253
|
+
cliCursor.hide();
|
|
254
|
+
}
|
|
255
|
+
this.isCursorHidden = true;
|
|
256
|
+
this.checkIfActiveSpinners();
|
|
257
|
+
} else {
|
|
258
|
+
this.setRawStreamOutput();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
loopStream() {
|
|
263
|
+
const { frames, interval } = this.options.spinner;
|
|
264
|
+
return setInterval(() => {
|
|
265
|
+
this.setStreamOutput(frames[this.currentFrameIndex]);
|
|
266
|
+
this.currentFrameIndex =
|
|
267
|
+
this.currentFrameIndex === frames.length - 1
|
|
268
|
+
? 0
|
|
269
|
+
: ++this.currentFrameIndex;
|
|
270
|
+
}, interval);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
setStreamOutput(frame = '') {
|
|
274
|
+
let output = '';
|
|
275
|
+
const linesLength = [];
|
|
276
|
+
const hasActiveSpinners = this.hasActiveSpinners();
|
|
277
|
+
Object.values(this.spinners).map(
|
|
278
|
+
({
|
|
279
|
+
text,
|
|
280
|
+
status,
|
|
281
|
+
color,
|
|
282
|
+
spinnerColor,
|
|
283
|
+
succeedColor,
|
|
284
|
+
failColor,
|
|
285
|
+
succeedPrefix,
|
|
286
|
+
failPrefix,
|
|
287
|
+
indent,
|
|
288
|
+
}) => {
|
|
289
|
+
let line;
|
|
290
|
+
let prefixLength = indent || 0;
|
|
291
|
+
if (status === 'spinning') {
|
|
292
|
+
prefixLength += frame.length + 1;
|
|
293
|
+
text = breakText(text, prefixLength);
|
|
294
|
+
line = `${chalk[spinnerColor](frame)} ${
|
|
295
|
+
color ? chalk[color](text) : text
|
|
296
|
+
}`;
|
|
297
|
+
} else {
|
|
298
|
+
if (status === 'succeed') {
|
|
299
|
+
prefixLength += succeedPrefix.length + 1;
|
|
300
|
+
if (hasActiveSpinners) {
|
|
301
|
+
text = breakText(text, prefixLength);
|
|
302
|
+
}
|
|
303
|
+
line = `${chalk.green(succeedPrefix)} ${chalk[succeedColor](text)}`;
|
|
304
|
+
} else if (status === 'fail') {
|
|
305
|
+
prefixLength += failPrefix.length + 1;
|
|
306
|
+
if (hasActiveSpinners) {
|
|
307
|
+
text = breakText(text, prefixLength);
|
|
308
|
+
}
|
|
309
|
+
line = `${chalk.red(failPrefix)} ${chalk[failColor](text)}`;
|
|
310
|
+
} else {
|
|
311
|
+
if (hasActiveSpinners) {
|
|
312
|
+
text = breakText(text, prefixLength);
|
|
313
|
+
}
|
|
314
|
+
line = color ? chalk[color](text) : text;
|
|
93
315
|
}
|
|
94
|
-
} else if (
|
|
95
|
-
!preserveCategory ||
|
|
96
|
-
this.getCategoryForKey(key) !== preserveCategory
|
|
97
|
-
) {
|
|
98
|
-
this.remove(key);
|
|
99
316
|
}
|
|
100
|
-
|
|
317
|
+
linesLength.push(...getLinesLength(text, prefixLength));
|
|
318
|
+
output += indent ? `${' '.repeat(indent)}${line}\n` : `${line}\n`;
|
|
319
|
+
}
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
if (!hasActiveSpinners) {
|
|
323
|
+
readline.clearScreenDown(this.stream);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
writeStream(this.stream, output, linesLength);
|
|
327
|
+
|
|
328
|
+
if (hasActiveSpinners) {
|
|
329
|
+
cleanStream(this.stream, linesLength);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
this.lineCount = linesLength.length;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
setRawStreamOutput() {
|
|
336
|
+
Object.values(this.spinners).forEach(i => {
|
|
337
|
+
process.stderr.write(`- ${i.text}\n`);
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
checkIfActiveSpinners() {
|
|
342
|
+
if (!this.hasActiveSpinners()) {
|
|
343
|
+
if (this.spin) {
|
|
344
|
+
this.setStreamOutput();
|
|
345
|
+
readline.moveCursor(this.stream, 0, this.lineCount);
|
|
346
|
+
clearInterval(this.currentInterval);
|
|
347
|
+
this.isCursorHidden = false;
|
|
348
|
+
cliCursor.show();
|
|
349
|
+
}
|
|
350
|
+
this.spinners = {};
|
|
101
351
|
}
|
|
102
352
|
}
|
|
353
|
+
|
|
354
|
+
bindSigint() {
|
|
355
|
+
process.removeAllListeners('SIGINT');
|
|
356
|
+
process.on('SIGINT', () => {
|
|
357
|
+
cliCursor.show();
|
|
358
|
+
readline.moveCursor(process.stderr, 0, this.lineCount);
|
|
359
|
+
process.exit(0);
|
|
360
|
+
});
|
|
361
|
+
}
|
|
103
362
|
}
|
|
104
363
|
|
|
105
364
|
module.exports = new SpinniesManager();
|