@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
package/lib/projects.js
CHANGED
|
@@ -179,15 +179,15 @@ const pollFetchProject = async (accountId, projectName) => {
|
|
|
179
179
|
// Temporary solution for gating slowness. Retry on 403 statusCode
|
|
180
180
|
return new Promise((resolve, reject) => {
|
|
181
181
|
let pollCount = 0;
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
SpinniesManager.init();
|
|
183
|
+
SpinniesManager.add('pollFetchProject', {
|
|
184
184
|
text: 'Fetching project status',
|
|
185
185
|
});
|
|
186
186
|
const pollInterval = setInterval(async () => {
|
|
187
187
|
try {
|
|
188
188
|
const project = await fetchProject(accountId, projectName);
|
|
189
189
|
if (project) {
|
|
190
|
-
|
|
190
|
+
SpinniesManager.remove('pollFetchProject');
|
|
191
191
|
clearInterval(pollInterval);
|
|
192
192
|
resolve(project);
|
|
193
193
|
}
|
|
@@ -202,11 +202,11 @@ const pollFetchProject = async (accountId, projectName) => {
|
|
|
202
202
|
pollCount += 1;
|
|
203
203
|
} else if (pollCount >= 15) {
|
|
204
204
|
// Poll up to max 30s
|
|
205
|
-
|
|
205
|
+
SpinniesManager.remove('pollFetchProject');
|
|
206
206
|
clearInterval(pollInterval);
|
|
207
207
|
reject(err);
|
|
208
208
|
} else {
|
|
209
|
-
|
|
209
|
+
SpinniesManager.remove('pollFetchProject');
|
|
210
210
|
clearInterval(pollInterval);
|
|
211
211
|
reject(err);
|
|
212
212
|
}
|
|
@@ -314,10 +314,10 @@ const uploadProjectFiles = async (
|
|
|
314
314
|
filePath,
|
|
315
315
|
uploadMessage
|
|
316
316
|
) => {
|
|
317
|
-
|
|
317
|
+
SpinniesManager.init({});
|
|
318
318
|
const accountIdentifier = uiAccountDescription(accountId);
|
|
319
319
|
|
|
320
|
-
|
|
320
|
+
SpinniesManager.add('upload', {
|
|
321
321
|
text: i18n(`${i18nKey}.uploadProjectFiles.add`, {
|
|
322
322
|
accountIdentifier,
|
|
323
323
|
projectName,
|
|
@@ -338,7 +338,7 @@ const uploadProjectFiles = async (
|
|
|
338
338
|
|
|
339
339
|
buildId = upload.buildId;
|
|
340
340
|
|
|
341
|
-
|
|
341
|
+
SpinniesManager.succeed('upload', {
|
|
342
342
|
text: i18n(`${i18nKey}.uploadProjectFiles.succeed`, {
|
|
343
343
|
accountIdentifier,
|
|
344
344
|
projectName,
|
|
@@ -352,7 +352,7 @@ const uploadProjectFiles = async (
|
|
|
352
352
|
})
|
|
353
353
|
);
|
|
354
354
|
} catch (err) {
|
|
355
|
-
|
|
355
|
+
SpinniesManager.fail('upload', {
|
|
356
356
|
text: i18n(`${i18nKey}.uploadProjectFiles.fail`, {
|
|
357
357
|
accountIdentifier,
|
|
358
358
|
projectName,
|
|
@@ -372,18 +372,20 @@ const pollProjectBuildAndDeploy = async (
|
|
|
372
372
|
buildId,
|
|
373
373
|
silenceLogs = false
|
|
374
374
|
) => {
|
|
375
|
-
const
|
|
376
|
-
autoDeployId,
|
|
377
|
-
isAutoDeployEnabled,
|
|
378
|
-
deployStatusTaskLocator,
|
|
379
|
-
status,
|
|
380
|
-
} = await pollBuildStatus(
|
|
375
|
+
const buildStatus = await pollBuildStatus(
|
|
381
376
|
accountId,
|
|
382
377
|
projectConfig.name,
|
|
383
378
|
buildId,
|
|
384
379
|
null,
|
|
385
380
|
silenceLogs
|
|
386
381
|
);
|
|
382
|
+
|
|
383
|
+
const {
|
|
384
|
+
autoDeployId,
|
|
385
|
+
isAutoDeployEnabled,
|
|
386
|
+
deployStatusTaskLocator,
|
|
387
|
+
} = buildStatus;
|
|
388
|
+
|
|
387
389
|
// autoDeployId of 0 indicates a skipped deploy
|
|
388
390
|
const isDeploying =
|
|
389
391
|
isAutoDeployEnabled && autoDeployId > 0 && deployStatusTaskLocator;
|
|
@@ -395,12 +397,11 @@ const pollProjectBuildAndDeploy = async (
|
|
|
395
397
|
const result = {
|
|
396
398
|
succeeded: true,
|
|
397
399
|
buildId,
|
|
398
|
-
|
|
399
|
-
|
|
400
|
+
buildResult: buildStatus,
|
|
401
|
+
deployResult: null,
|
|
400
402
|
};
|
|
401
403
|
|
|
402
|
-
if (status === 'FAILURE') {
|
|
403
|
-
result.buildSucceeded = false;
|
|
404
|
+
if (buildStatus.status === 'FAILURE') {
|
|
404
405
|
result.succeeded = false;
|
|
405
406
|
return result;
|
|
406
407
|
} else if (isDeploying) {
|
|
@@ -415,14 +416,16 @@ const pollProjectBuildAndDeploy = async (
|
|
|
415
416
|
)
|
|
416
417
|
);
|
|
417
418
|
}
|
|
418
|
-
const
|
|
419
|
+
const deployStatus = await pollDeployStatus(
|
|
419
420
|
accountId,
|
|
420
421
|
projectConfig.name,
|
|
421
422
|
deployStatusTaskLocator.id,
|
|
422
423
|
buildId,
|
|
423
424
|
silenceLogs
|
|
424
425
|
);
|
|
425
|
-
|
|
426
|
+
result.deployResult = deployStatus;
|
|
427
|
+
|
|
428
|
+
if (deployStatus.status === 'FAILURE') {
|
|
426
429
|
result.succeeded = false;
|
|
427
430
|
}
|
|
428
431
|
}
|
|
@@ -491,7 +494,7 @@ const handleProjectUpload = async (
|
|
|
491
494
|
);
|
|
492
495
|
|
|
493
496
|
if (error) {
|
|
494
|
-
uploadResult.
|
|
497
|
+
uploadResult.uploadError = error;
|
|
495
498
|
} else if (callbackFunc) {
|
|
496
499
|
uploadResult = await callbackFunc(
|
|
497
500
|
accountId,
|
|
@@ -548,11 +551,11 @@ const makePollTaskStatusFunc = ({
|
|
|
548
551
|
);
|
|
549
552
|
}
|
|
550
553
|
|
|
551
|
-
|
|
554
|
+
SpinniesManager.init();
|
|
552
555
|
|
|
553
556
|
const overallTaskSpinniesKey = `overallTaskStatus-${statusText.STATUS_TEXT}`;
|
|
554
557
|
|
|
555
|
-
|
|
558
|
+
SpinniesManager.add(overallTaskSpinniesKey, {
|
|
556
559
|
text: 'Beginning',
|
|
557
560
|
succeedColor: 'white',
|
|
558
561
|
failColor: 'white',
|
|
@@ -598,7 +601,7 @@ const makePollTaskStatusFunc = ({
|
|
|
598
601
|
{ numComponents }
|
|
599
602
|
) + '\n';
|
|
600
603
|
|
|
601
|
-
|
|
604
|
+
SpinniesManager.update(overallTaskSpinniesKey, {
|
|
602
605
|
text: `${statusStrings.INITIALIZE(taskName)}\n${componentCountText}`,
|
|
603
606
|
});
|
|
604
607
|
|
|
@@ -613,7 +616,7 @@ const makePollTaskStatusFunc = ({
|
|
|
613
616
|
taskName
|
|
614
617
|
)} ${formattedTaskType} ...${newline ? '\n' : ''}`;
|
|
615
618
|
|
|
616
|
-
|
|
619
|
+
SpinniesManager.add(task.id, {
|
|
617
620
|
text,
|
|
618
621
|
indent,
|
|
619
622
|
succeedColor: 'white',
|
|
@@ -638,10 +641,10 @@ const makePollTaskStatusFunc = ({
|
|
|
638
641
|
|
|
639
642
|
const { status, [statusText.SUBTASK_KEY]: subTaskStatus } = taskStatus;
|
|
640
643
|
|
|
641
|
-
if (
|
|
644
|
+
if (SpinniesManager.hasActiveSpinners()) {
|
|
642
645
|
subTaskStatus.forEach(subTask => {
|
|
643
646
|
const { id, status } = subTask;
|
|
644
|
-
const spinner =
|
|
647
|
+
const spinner = SpinniesManager.pick(id);
|
|
645
648
|
|
|
646
649
|
if (!spinner || spinner.status !== SPINNER_STATUS.SPINNING) {
|
|
647
650
|
return;
|
|
@@ -665,12 +668,12 @@ const makePollTaskStatusFunc = ({
|
|
|
665
668
|
)} ${taskStatusText}${hasNewline ? '\n' : ''}`;
|
|
666
669
|
|
|
667
670
|
status === statusText.STATES.SUCCESS
|
|
668
|
-
?
|
|
669
|
-
:
|
|
671
|
+
? SpinniesManager.succeed(id, { text: updatedText })
|
|
672
|
+
: SpinniesManager.fail(id, { text: updatedText });
|
|
670
673
|
|
|
671
674
|
if (topLevelTask) {
|
|
672
675
|
topLevelTask.subtasks.forEach(currentSubtask =>
|
|
673
|
-
|
|
676
|
+
SpinniesManager.remove(currentSubtask.id)
|
|
674
677
|
);
|
|
675
678
|
}
|
|
676
679
|
}
|
|
@@ -678,11 +681,11 @@ const makePollTaskStatusFunc = ({
|
|
|
678
681
|
|
|
679
682
|
if (isTaskComplete(taskStatus)) {
|
|
680
683
|
if (status === statusText.STATES.SUCCESS) {
|
|
681
|
-
|
|
684
|
+
SpinniesManager.succeed(overallTaskSpinniesKey, {
|
|
682
685
|
text: statusStrings.SUCCESS(taskName),
|
|
683
686
|
});
|
|
684
687
|
} else if (status === statusText.STATES.FAILURE) {
|
|
685
|
-
|
|
688
|
+
SpinniesManager.fail(overallTaskSpinniesKey, {
|
|
686
689
|
text: statusStrings.FAIL(taskName),
|
|
687
690
|
});
|
|
688
691
|
|
package/lib/sandbox-create.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const SpinniesManager = require('./SpinniesManager');
|
|
2
2
|
const {
|
|
3
3
|
getSandboxLimit,
|
|
4
4
|
getHasSandboxesByType,
|
|
@@ -38,7 +38,7 @@ const buildSandbox = async ({
|
|
|
38
38
|
env,
|
|
39
39
|
force = false,
|
|
40
40
|
}) => {
|
|
41
|
-
|
|
41
|
+
SpinniesManager.init({
|
|
42
42
|
succeedColor: 'white',
|
|
43
43
|
});
|
|
44
44
|
const accountId = getAccountId(accountConfig.portalId);
|
|
@@ -48,7 +48,7 @@ const buildSandbox = async ({
|
|
|
48
48
|
|
|
49
49
|
try {
|
|
50
50
|
logger.log('');
|
|
51
|
-
|
|
51
|
+
SpinniesManager.add('sandboxCreate', {
|
|
52
52
|
text: i18n(`${spinniesI18nKey}.add`, {
|
|
53
53
|
sandboxName: name,
|
|
54
54
|
}),
|
|
@@ -57,7 +57,7 @@ const buildSandbox = async ({
|
|
|
57
57
|
const sandboxApiType = sandboxApiTypeMap[type]; // API expects sandbox type as 1 or 2
|
|
58
58
|
result = await createSandbox(accountId, name, sandboxApiType);
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
SpinniesManager.succeed('sandboxCreate', {
|
|
61
61
|
text: i18n(`${spinniesI18nKey}.succeed`, {
|
|
62
62
|
name: result.sandbox.name,
|
|
63
63
|
sandboxHubId: result.sandbox.sandboxHubId,
|
|
@@ -66,7 +66,7 @@ const buildSandbox = async ({
|
|
|
66
66
|
} catch (err) {
|
|
67
67
|
debugErrorAndContext(err);
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
SpinniesManager.fail('sandboxCreate', {
|
|
70
70
|
text: i18n(`${spinniesI18nKey}.fail`, {
|
|
71
71
|
sandboxName: name,
|
|
72
72
|
}),
|
package/lib/sandbox-sync.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const SpinniesManager = require('./SpinniesManager');
|
|
2
2
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
|
|
3
3
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
4
4
|
const { i18n } = require('./lang');
|
|
@@ -44,7 +44,7 @@ const syncSandbox = async ({
|
|
|
44
44
|
}) => {
|
|
45
45
|
const accountId = getAccountId(accountConfig.portalId);
|
|
46
46
|
const parentAccountId = getAccountId(parentAccountConfig.portalId);
|
|
47
|
-
|
|
47
|
+
SpinniesManager.init({
|
|
48
48
|
succeedColor: 'white',
|
|
49
49
|
});
|
|
50
50
|
let initiateSyncResponse;
|
|
@@ -68,7 +68,7 @@ const syncSandbox = async ({
|
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
SpinniesManager.add('sandboxSync', {
|
|
72
72
|
text: i18n(`${i18nKey}.loading.startSync`),
|
|
73
73
|
});
|
|
74
74
|
|
|
@@ -82,7 +82,7 @@ const syncSandbox = async ({
|
|
|
82
82
|
if (allowEarlyTermination) {
|
|
83
83
|
logger.log(i18n(`${i18nKey}.info.earlyExit`));
|
|
84
84
|
}
|
|
85
|
-
|
|
85
|
+
SpinniesManager.succeed('sandboxSync', {
|
|
86
86
|
text: i18n(`${i18nKey}.loading.succeed`, {
|
|
87
87
|
accountName: uiAccountDescription(accountId),
|
|
88
88
|
}),
|
|
@@ -101,7 +101,7 @@ const syncSandbox = async ({
|
|
|
101
101
|
} catch (err) {
|
|
102
102
|
debugErrorAndContext(err);
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
SpinniesManager.fail('sandboxSync', {
|
|
105
105
|
text: i18n(`${i18nKey}.loading.fail`),
|
|
106
106
|
});
|
|
107
107
|
|
|
@@ -182,10 +182,10 @@ const syncSandbox = async ({
|
|
|
182
182
|
);
|
|
183
183
|
|
|
184
184
|
logger.log('');
|
|
185
|
-
|
|
185
|
+
SpinniesManager.add('syncComplete', {
|
|
186
186
|
text: i18n(`${i18nKey}.polling.syncing`),
|
|
187
187
|
});
|
|
188
|
-
|
|
188
|
+
SpinniesManager.succeed('syncComplete', {
|
|
189
189
|
text: i18n(`${i18nKey}.polling.succeed`),
|
|
190
190
|
});
|
|
191
191
|
logger.log('');
|
|
@@ -198,10 +198,10 @@ const syncSandbox = async ({
|
|
|
198
198
|
// If polling fails at this point, we do not track a failed sync since it is running in the background.
|
|
199
199
|
logErrorInstance(err);
|
|
200
200
|
|
|
201
|
-
|
|
201
|
+
SpinniesManager.add('syncComplete', {
|
|
202
202
|
text: i18n(`${i18nKey}.polling.syncing`),
|
|
203
203
|
});
|
|
204
|
-
|
|
204
|
+
SpinniesManager.fail('syncComplete', {
|
|
205
205
|
text: i18n(`${i18nKey}.polling.fail`, {
|
|
206
206
|
url: syncStatusUrl,
|
|
207
207
|
}),
|
package/lib/serverlessLogs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const https = require('https');
|
|
2
|
-
const
|
|
2
|
+
const SpinniesManager = require('./SpinniesManager');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
5
5
|
const { outputLogs } = require('@hubspot/cli-lib/lib/logs');
|
|
@@ -15,10 +15,10 @@ const { EXIT_CODES } = require('../lib/enums/exitCodes');
|
|
|
15
15
|
|
|
16
16
|
const TAIL_DELAY = 5000;
|
|
17
17
|
|
|
18
|
-
const handleUserInput =
|
|
18
|
+
const handleUserInput = () => {
|
|
19
19
|
const onTerminate = async () => {
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
SpinniesManager.remove('tailLogs');
|
|
21
|
+
SpinniesManager.remove('stopMessage');
|
|
22
22
|
process.exit(EXIT_CODES.SUCCESS);
|
|
23
23
|
};
|
|
24
24
|
|
|
@@ -82,17 +82,17 @@ const tailLogs = async ({
|
|
|
82
82
|
}, TAIL_DELAY);
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
SpinniesManager.init();
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
SpinniesManager.add('tailLogs', {
|
|
88
88
|
text: `Following logs for ${name}`,
|
|
89
89
|
});
|
|
90
|
-
|
|
90
|
+
SpinniesManager.add('stopMessage', {
|
|
91
91
|
text: `> Press ${chalk.bold('q')} to stop following`,
|
|
92
92
|
status: 'non-spinnable',
|
|
93
93
|
});
|
|
94
94
|
|
|
95
|
-
handleUserInput(
|
|
95
|
+
handleUserInput();
|
|
96
96
|
|
|
97
97
|
await tail(initialAfter);
|
|
98
98
|
};
|
|
@@ -0,0 +1,174 @@
|
|
|
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
|
+
const readline = require('readline');
|
|
11
|
+
const stripAnsi = require('strip-ansi');
|
|
12
|
+
|
|
13
|
+
const VALID_STATUSES = [
|
|
14
|
+
'succeed',
|
|
15
|
+
'fail',
|
|
16
|
+
'spinning',
|
|
17
|
+
'non-spinnable',
|
|
18
|
+
'stopped',
|
|
19
|
+
];
|
|
20
|
+
const VALID_COLORS = [
|
|
21
|
+
'black',
|
|
22
|
+
'red',
|
|
23
|
+
'green',
|
|
24
|
+
'yellow',
|
|
25
|
+
'blue',
|
|
26
|
+
'magenta',
|
|
27
|
+
'cyan',
|
|
28
|
+
'white',
|
|
29
|
+
'gray',
|
|
30
|
+
'redBright',
|
|
31
|
+
'greenBright',
|
|
32
|
+
'yellowBright',
|
|
33
|
+
'blueBright',
|
|
34
|
+
'magentaBright',
|
|
35
|
+
'cyanBright',
|
|
36
|
+
'whiteBright',
|
|
37
|
+
];
|
|
38
|
+
const SPINNERS = {
|
|
39
|
+
dots: {
|
|
40
|
+
interval: 50,
|
|
41
|
+
frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
|
|
42
|
+
},
|
|
43
|
+
dashes: {
|
|
44
|
+
interval: 80,
|
|
45
|
+
frames: ['-', '_'],
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
function purgeSpinnerOptions(options) {
|
|
50
|
+
const { text, status, indent } = options;
|
|
51
|
+
const opts = { text, status, indent };
|
|
52
|
+
const colors = colorOptions(options);
|
|
53
|
+
|
|
54
|
+
if (!VALID_STATUSES.includes(status)) delete opts.status;
|
|
55
|
+
if (typeof text !== 'string') delete opts.text;
|
|
56
|
+
if (typeof indent !== 'number') delete opts.indent;
|
|
57
|
+
|
|
58
|
+
return { ...colors, ...opts };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function purgeSpinnersOptions({ spinner, disableSpins, ...others }) {
|
|
62
|
+
const colors = colorOptions(others);
|
|
63
|
+
const prefixes = prefixOptions(others);
|
|
64
|
+
const disableSpinsOption =
|
|
65
|
+
typeof disableSpins === 'boolean' ? { disableSpins } : {};
|
|
66
|
+
spinner = turnToValidSpinner(spinner);
|
|
67
|
+
|
|
68
|
+
return { ...colors, ...prefixes, ...disableSpinsOption, spinner };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function turnToValidSpinner(spinner = {}) {
|
|
72
|
+
const platformSpinner = terminalSupportsUnicode()
|
|
73
|
+
? SPINNERS.dots
|
|
74
|
+
: SPINNERS.dashes;
|
|
75
|
+
if (typeof spinner !== 'object') {
|
|
76
|
+
return platformSpinner;
|
|
77
|
+
}
|
|
78
|
+
let { interval, frames } = spinner;
|
|
79
|
+
if (!Array.isArray(frames) || frames.length < 1)
|
|
80
|
+
frames = platformSpinner.frames;
|
|
81
|
+
if (typeof interval !== 'number') {
|
|
82
|
+
interval = platformSpinner.interval;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return { interval, frames };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function colorOptions({ color, succeedColor, failColor, spinnerColor }) {
|
|
89
|
+
const colors = { color, succeedColor, failColor, spinnerColor };
|
|
90
|
+
Object.keys(colors).forEach(key => {
|
|
91
|
+
if (!VALID_COLORS.includes(colors[key])) {
|
|
92
|
+
delete colors[key];
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return colors;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function prefixOptions({ succeedPrefix, failPrefix }) {
|
|
100
|
+
if (terminalSupportsUnicode()) {
|
|
101
|
+
succeedPrefix = succeedPrefix || '✓';
|
|
102
|
+
failPrefix = failPrefix || '✖';
|
|
103
|
+
} else {
|
|
104
|
+
succeedPrefix = succeedPrefix || '√';
|
|
105
|
+
failPrefix = failPrefix || '×';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return { succeedPrefix, failPrefix };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function breakText(text, prefixLength) {
|
|
112
|
+
return text
|
|
113
|
+
.split('\n')
|
|
114
|
+
.map((line, index) =>
|
|
115
|
+
index === 0 ? breakLine(line, prefixLength) : breakLine(line, 0)
|
|
116
|
+
)
|
|
117
|
+
.join('\n');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function breakLine(line, prefixLength) {
|
|
121
|
+
const columns = process.stderr.columns || 95;
|
|
122
|
+
return line.length >= columns - prefixLength
|
|
123
|
+
? `${line.substring(0, columns - prefixLength - 1)}\n${breakLine(
|
|
124
|
+
line.substring(columns - prefixLength - 1, line.length),
|
|
125
|
+
0
|
|
126
|
+
)}`
|
|
127
|
+
: line;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function getLinesLength(text, prefixLength) {
|
|
131
|
+
return stripAnsi(text)
|
|
132
|
+
.split('\n')
|
|
133
|
+
.map((line, index) =>
|
|
134
|
+
index === 0 ? line.length + prefixLength : line.length
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function writeStream(stream, output, rawLines) {
|
|
139
|
+
stream.write(output);
|
|
140
|
+
readline.moveCursor(stream, 0, -rawLines.length);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function cleanStream(stream, rawLines) {
|
|
144
|
+
rawLines.forEach((lineLength, index) => {
|
|
145
|
+
readline.moveCursor(stream, lineLength, index);
|
|
146
|
+
readline.clearLine(stream, 1);
|
|
147
|
+
readline.moveCursor(stream, -lineLength, -index);
|
|
148
|
+
});
|
|
149
|
+
readline.moveCursor(stream, 0, rawLines.length);
|
|
150
|
+
readline.clearScreenDown(stream);
|
|
151
|
+
readline.moveCursor(stream, 0, -rawLines.length);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function terminalSupportsUnicode() {
|
|
155
|
+
// The default command prompt and powershell in Windows do not support Unicode characters.
|
|
156
|
+
// However, the VSCode integrated terminal and the Windows Terminal both do.
|
|
157
|
+
return (
|
|
158
|
+
process.platform !== 'win32' ||
|
|
159
|
+
process.env.TERM_PROGRAM === 'vscode' ||
|
|
160
|
+
!!process.env.WT_SESSION
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
module.exports = {
|
|
165
|
+
breakText,
|
|
166
|
+
cleanStream,
|
|
167
|
+
colorOptions,
|
|
168
|
+
getLinesLength,
|
|
169
|
+
purgeSpinnerOptions,
|
|
170
|
+
purgeSpinnersOptions,
|
|
171
|
+
SPINNERS,
|
|
172
|
+
terminalSupportsUnicode,
|
|
173
|
+
writeStream,
|
|
174
|
+
};
|
package/lib/ui.js
CHANGED
|
@@ -105,6 +105,12 @@ const uiFeatureHighlight = (commands, title) => {
|
|
|
105
105
|
});
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
+
const uiBetaMessage = message => {
|
|
109
|
+
const i18nKey = 'cli.lib.ui';
|
|
110
|
+
|
|
111
|
+
logger.log(chalk.hex('#bda9ea')(i18n(`${i18nKey}.betaTag`)), message);
|
|
112
|
+
};
|
|
113
|
+
|
|
108
114
|
const uiBetaWarning = logMessage => {
|
|
109
115
|
const i18nKey = 'cli.lib.ui.betaWarning';
|
|
110
116
|
|
|
@@ -115,6 +121,7 @@ const uiBetaWarning = logMessage => {
|
|
|
115
121
|
|
|
116
122
|
module.exports = {
|
|
117
123
|
uiAccountDescription,
|
|
124
|
+
uiBetaMessage,
|
|
118
125
|
uiBetaWarning,
|
|
119
126
|
uiFeatureHighlight,
|
|
120
127
|
uiInfoSection,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.1-beta.1",
|
|
4
4
|
"description": "CLI for working with HubSpot",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@hubspot/cli-lib": "^4.1.14",
|
|
12
12
|
"@hubspot/serverless-dev-runtime": "4.1.8-beta.6",
|
|
13
|
+
"@hubspot/ui-extensions-dev-server": "^0.4.0",
|
|
13
14
|
"archiver": "^5.3.0",
|
|
14
15
|
"body-parser": "^1.19.0",
|
|
15
16
|
"chalk": "^4.1.2",
|
|
16
17
|
"chokidar": "^3.0.1",
|
|
18
|
+
"cli-cursor": "^3.1.0",
|
|
17
19
|
"cli-progress": "^3.11.2",
|
|
18
20
|
"cors": "^2.8.5",
|
|
19
21
|
"express": "^4.17.1",
|
|
@@ -25,7 +27,7 @@
|
|
|
25
27
|
"open": "^7.0.3",
|
|
26
28
|
"ora": "^4.0.3",
|
|
27
29
|
"p-queue": "^6.0.2",
|
|
28
|
-
"
|
|
30
|
+
"strip-ansi": "^5.2.0",
|
|
29
31
|
"tmp": "^0.2.1",
|
|
30
32
|
"update-notifier": "^5.1.0",
|
|
31
33
|
"yargs": "15.4.1"
|
|
@@ -34,7 +36,7 @@
|
|
|
34
36
|
"mock-stdin": "^1.0.0"
|
|
35
37
|
},
|
|
36
38
|
"engines": {
|
|
37
|
-
"node": ">=
|
|
39
|
+
"node": ">=16"
|
|
38
40
|
},
|
|
39
41
|
"bin": {
|
|
40
42
|
"hs": "./bin/hs",
|
|
@@ -43,5 +45,5 @@
|
|
|
43
45
|
"publishConfig": {
|
|
44
46
|
"access": "public"
|
|
45
47
|
},
|
|
46
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "a79d4a4d6c61971986a7df3aaa8374cbe2405a0b"
|
|
47
49
|
}
|