@hubspot/cli 5.2.1-beta.9 → 5.3.0
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/functions/deploy.js +2 -2
- package/commands/project/__tests__/deploy.test.js +432 -0
- package/commands/project/cloneApp.js +208 -0
- package/commands/project/deploy.js +82 -27
- package/commands/project/listBuilds.js +1 -1
- package/commands/project/logs.js +1 -1
- package/commands/project/migrateApp.js +66 -24
- package/commands/project/upload.js +1 -1
- package/commands/project.js +15 -12
- package/commands/sandbox/create.js +12 -43
- package/commands/sandbox/delete.js +5 -2
- package/commands/sandbox/sync.js +12 -2
- package/commands/sandbox.js +2 -1
- package/lang/en.lyaml +56 -48
- package/lib/LocalDevManager.js +12 -9
- package/lib/constants.js +3 -1
- package/lib/interpolationHelpers.js +3 -0
- package/lib/localDev.js +1 -2
- package/lib/polling.js +16 -10
- package/lib/projects.js +143 -100
- package/lib/prompts/accountNamePrompt.js +1 -4
- package/lib/prompts/createProjectPrompt.js +12 -2
- package/lib/prompts/deployBuildIdPrompt.js +22 -0
- package/lib/prompts/installPublicAppPrompt.js +13 -4
- package/lib/prompts/selectPublicAppPrompt.js +34 -10
- package/lib/sandboxSync.js +49 -68
- package/lib/sandboxes.js +8 -149
- package/lib/serverlessLogs.js +2 -2
- package/lib/ui/index.js +74 -0
- package/package.json +5 -4
- package/lib/prompts/buildIdPrompt.js +0 -35
- package/lib/ui/CliProgressMultibarManager.js +0 -66
package/lib/sandboxSync.js
CHANGED
|
@@ -2,12 +2,7 @@ const SpinniesManager = require('./ui/SpinniesManager');
|
|
|
2
2
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
3
3
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
4
4
|
const { i18n } = require('./lang');
|
|
5
|
-
const {
|
|
6
|
-
const {
|
|
7
|
-
getAvailableSyncTypes,
|
|
8
|
-
pollSyncTaskStatus,
|
|
9
|
-
syncTypes,
|
|
10
|
-
} = require('./sandboxes');
|
|
5
|
+
const { getAvailableSyncTypes } = require('./sandboxes');
|
|
11
6
|
const { initiateSync } = require('@hubspot/local-dev-lib/sandboxes');
|
|
12
7
|
const {
|
|
13
8
|
debugErrorAndContext,
|
|
@@ -19,7 +14,13 @@ const {
|
|
|
19
14
|
} = require('@hubspot/local-dev-lib/errors/apiErrors');
|
|
20
15
|
const { getSandboxTypeAsString } = require('./sandboxes');
|
|
21
16
|
const { getAccountId } = require('@hubspot/local-dev-lib/config');
|
|
22
|
-
const {
|
|
17
|
+
const {
|
|
18
|
+
uiAccountDescription,
|
|
19
|
+
uiLine,
|
|
20
|
+
uiLink,
|
|
21
|
+
uiCommandDisabledBanner,
|
|
22
|
+
} = require('./ui');
|
|
23
|
+
const { isDevelopmentSandbox } = require('./accountTypes');
|
|
23
24
|
|
|
24
25
|
const i18nKey = 'lib.sandbox.sync';
|
|
25
26
|
|
|
@@ -28,8 +29,6 @@ const i18nKey = 'lib.sandbox.sync';
|
|
|
28
29
|
* @param {Object} parentAccountConfig - Account config of parent portal
|
|
29
30
|
* @param {String} env - Environment (QA/Prod)
|
|
30
31
|
* @param {Array} syncTasks - Array of available sync tasks
|
|
31
|
-
* @param {Boolean} allowEarlyTermination - Option to allow a keypress to terminate early
|
|
32
|
-
* @param {Boolean} skipPolling - Option to skip progress bars for polling and let sync run in background
|
|
33
32
|
* @returns
|
|
34
33
|
*/
|
|
35
34
|
const syncSandbox = async ({
|
|
@@ -37,15 +36,14 @@ const syncSandbox = async ({
|
|
|
37
36
|
parentAccountConfig,
|
|
38
37
|
env,
|
|
39
38
|
syncTasks,
|
|
40
|
-
|
|
41
|
-
skipPolling = false,
|
|
39
|
+
slimInfoMessage = false,
|
|
42
40
|
}) => {
|
|
43
41
|
const accountId = getAccountId(accountConfig.portalId);
|
|
44
42
|
const parentAccountId = getAccountId(parentAccountConfig.portalId);
|
|
43
|
+
const isDevSandbox = isDevelopmentSandbox(accountConfig);
|
|
45
44
|
SpinniesManager.init({
|
|
46
45
|
succeedColor: 'white',
|
|
47
46
|
});
|
|
48
|
-
let initiateSyncResponse;
|
|
49
47
|
let availableSyncTasks = syncTasks;
|
|
50
48
|
|
|
51
49
|
const baseUrl = getHubSpotWebsiteOrigin(env);
|
|
@@ -70,29 +68,27 @@ const syncSandbox = async ({
|
|
|
70
68
|
text: i18n(`${i18nKey}.loading.startSync`),
|
|
71
69
|
});
|
|
72
70
|
|
|
73
|
-
|
|
71
|
+
await initiateSync(
|
|
74
72
|
parentAccountId,
|
|
75
73
|
accountId,
|
|
76
74
|
availableSyncTasks,
|
|
77
75
|
accountId
|
|
78
76
|
);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
77
|
+
let spinniesText = isDevSandbox
|
|
78
|
+
? `${i18nKey}.loading.succeedDevSb`
|
|
79
|
+
: `${i18nKey}.loading.succeed`;
|
|
83
80
|
SpinniesManager.succeed('sandboxSync', {
|
|
84
|
-
text: i18n(
|
|
85
|
-
|
|
86
|
-
|
|
81
|
+
text: i18n(
|
|
82
|
+
slimInfoMessage ? `${i18nKey}.loading.successDevSbInfo` : spinniesText,
|
|
83
|
+
{
|
|
84
|
+
accountName: uiAccountDescription(accountId),
|
|
85
|
+
url: uiLink(
|
|
86
|
+
i18n(`${i18nKey}.info.syncStatusDetailsLinkText`),
|
|
87
|
+
syncStatusUrl
|
|
88
|
+
),
|
|
89
|
+
}
|
|
90
|
+
),
|
|
87
91
|
});
|
|
88
|
-
if (skipPolling && isDevelopmentSandbox(accountConfig)) {
|
|
89
|
-
if (syncTasks.some(t => t.type === syncTypes.OBJECT_RECORDS)) {
|
|
90
|
-
logger.log(i18n(`${i18nKey}.loading.skipPollingWithContacts`));
|
|
91
|
-
} else {
|
|
92
|
-
logger.log(i18n(`${i18nKey}.loading.skipPolling`));
|
|
93
|
-
}
|
|
94
|
-
logger.log('');
|
|
95
|
-
}
|
|
96
92
|
} catch (err) {
|
|
97
93
|
debugErrorAndContext(err);
|
|
98
94
|
|
|
@@ -157,6 +153,15 @@ const syncSandbox = async ({
|
|
|
157
153
|
account: uiAccountDescription(accountId),
|
|
158
154
|
})
|
|
159
155
|
);
|
|
156
|
+
} else if (
|
|
157
|
+
isSpecifiedError(err, {
|
|
158
|
+
statusCode: 404,
|
|
159
|
+
})
|
|
160
|
+
) {
|
|
161
|
+
uiCommandDisabledBanner(
|
|
162
|
+
'hs sandbox sync',
|
|
163
|
+
'https://app.hubspot.com/l/docs/guides/crm/project-cli-commands#developer-projects-cli-commands-beta'
|
|
164
|
+
);
|
|
160
165
|
} else {
|
|
161
166
|
logErrorInstance(err);
|
|
162
167
|
}
|
|
@@ -164,46 +169,22 @@ const syncSandbox = async ({
|
|
|
164
169
|
throw err;
|
|
165
170
|
}
|
|
166
171
|
|
|
167
|
-
if (!
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
SpinniesManager.succeed('syncComplete', {
|
|
184
|
-
text: i18n(`${i18nKey}.polling.succeed`),
|
|
185
|
-
});
|
|
186
|
-
logger.log('');
|
|
187
|
-
logger.log(
|
|
188
|
-
i18n(`${i18nKey}.info.syncStatus`, {
|
|
189
|
-
url: syncStatusUrl,
|
|
190
|
-
})
|
|
191
|
-
);
|
|
192
|
-
} catch (err) {
|
|
193
|
-
// If polling fails at this point, we do not track a failed sync since it is running in the background.
|
|
194
|
-
logErrorInstance(err);
|
|
195
|
-
|
|
196
|
-
SpinniesManager.add('syncComplete', {
|
|
197
|
-
text: i18n(`${i18nKey}.polling.syncing`),
|
|
198
|
-
});
|
|
199
|
-
SpinniesManager.fail('syncComplete', {
|
|
200
|
-
text: i18n(`${i18nKey}.polling.fail`, {
|
|
201
|
-
url: syncStatusUrl,
|
|
202
|
-
}),
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
throw err;
|
|
206
|
-
}
|
|
172
|
+
if (!slimInfoMessage) {
|
|
173
|
+
logger.log();
|
|
174
|
+
uiLine();
|
|
175
|
+
logger.info(
|
|
176
|
+
i18n(
|
|
177
|
+
`${i18nKey}.info.${isDevSandbox ? 'syncMessageDevSb' : 'syncMessage'}`,
|
|
178
|
+
{
|
|
179
|
+
url: uiLink(
|
|
180
|
+
i18n(`${i18nKey}.info.syncStatusDetailsLinkText`),
|
|
181
|
+
syncStatusUrl
|
|
182
|
+
),
|
|
183
|
+
}
|
|
184
|
+
)
|
|
185
|
+
);
|
|
186
|
+
uiLine();
|
|
187
|
+
logger.log();
|
|
207
188
|
}
|
|
208
189
|
};
|
|
209
190
|
|
package/lib/sandboxes.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
const { i18n
|
|
2
|
-
const { handleExit, handleKeypress } = require('./process');
|
|
1
|
+
const { i18n } = require('./lang');
|
|
3
2
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
4
|
-
const { EXIT_CODES } = require('./enums/exitCodes');
|
|
5
3
|
const {
|
|
6
|
-
fetchTaskStatus,
|
|
7
4
|
fetchTypes,
|
|
8
5
|
getSandboxUsageLimits,
|
|
9
6
|
} = require('@hubspot/local-dev-lib/sandboxes');
|
|
@@ -12,7 +9,6 @@ const {
|
|
|
12
9
|
getAccountId,
|
|
13
10
|
getEnv,
|
|
14
11
|
} = require('@hubspot/local-dev-lib/config');
|
|
15
|
-
const CliProgressMultibarManager = require('./ui/CliProgressMultibarManager');
|
|
16
12
|
const { promptUser } = require('./prompts/promptUtils');
|
|
17
13
|
const { isDevelopmentSandbox } = require('./accountTypes');
|
|
18
14
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
@@ -97,21 +93,22 @@ const getSyncTypesWithContactRecordsPrompt = async (
|
|
|
97
93
|
syncTasks,
|
|
98
94
|
skipPrompt = false
|
|
99
95
|
) => {
|
|
100
|
-
//
|
|
101
|
-
|
|
96
|
+
// TODO: remove this entire helper once hs sandbox sync is fully deprecated
|
|
97
|
+
const isDevSandbox = isDevelopmentSandbox(accountConfig);
|
|
98
|
+
if (isDevSandbox) {
|
|
99
|
+
// Disable dev sandbox from syncing contacts
|
|
100
|
+
return syncTasks.filter(t => t.type !== syncTypes.OBJECT_RECORDS);
|
|
101
|
+
}
|
|
102
102
|
if (
|
|
103
103
|
syncTasks &&
|
|
104
104
|
syncTasks.some(t => t.type === syncTypes.OBJECT_RECORDS) &&
|
|
105
105
|
!skipPrompt
|
|
106
106
|
) {
|
|
107
|
-
const langKey = isDevelopmentSandbox(accountConfig)
|
|
108
|
-
? 'developer'
|
|
109
|
-
: 'standard';
|
|
110
107
|
const { contactRecordsSyncPrompt } = await promptUser([
|
|
111
108
|
{
|
|
112
109
|
name: 'contactRecordsSyncPrompt',
|
|
113
110
|
type: 'confirm',
|
|
114
|
-
message: i18n(
|
|
111
|
+
message: i18n('lib.sandbox.sync.confirm.syncContactRecords.standard'),
|
|
115
112
|
},
|
|
116
113
|
]);
|
|
117
114
|
if (!contactRecordsSyncPrompt) {
|
|
@@ -356,143 +353,6 @@ function handleSandboxCreateError({
|
|
|
356
353
|
throw err;
|
|
357
354
|
}
|
|
358
355
|
|
|
359
|
-
const ACTIVE_TASK_POLL_INTERVAL = 1000;
|
|
360
|
-
|
|
361
|
-
const isTaskComplete = task => {
|
|
362
|
-
if (!task) {
|
|
363
|
-
return false;
|
|
364
|
-
}
|
|
365
|
-
return task.status === 'COMPLETE';
|
|
366
|
-
};
|
|
367
|
-
|
|
368
|
-
const incrementBy = (value, multiplier = 3) => {
|
|
369
|
-
return Math.min(value + Math.floor(Math.random() * multiplier), 99);
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* @param {Number} accountId - Parent portal ID (needs sandbox scopes)
|
|
374
|
-
* @param {String} taksId - Task ID to poll
|
|
375
|
-
* @param {String} syncStatusUrl - Link to UI to check polling status
|
|
376
|
-
* @param {Boolean} allowEarlyTermination - Option to allow a keypress to terminate early
|
|
377
|
-
* @returns {Promise} Interval runs until sync task status is equal to 'COMPLETE'
|
|
378
|
-
*/
|
|
379
|
-
function pollSyncTaskStatus(
|
|
380
|
-
accountId,
|
|
381
|
-
taskId,
|
|
382
|
-
syncStatusUrl,
|
|
383
|
-
allowEarlyTermination = true
|
|
384
|
-
) {
|
|
385
|
-
const i18nKey = 'lib.sandbox.sync.types';
|
|
386
|
-
const progressBar = CliProgressMultibarManager.init();
|
|
387
|
-
const mergeTasks = {
|
|
388
|
-
'lead-flows': 'forms', // lead-flows are a subset of forms. We combine these in the UI as a single item, so we want to merge here for consistency.
|
|
389
|
-
};
|
|
390
|
-
let progressCounter = {};
|
|
391
|
-
let pollInterval;
|
|
392
|
-
// Handle manual exit for return key and ctrl+c
|
|
393
|
-
const onTerminate = () => {
|
|
394
|
-
clearInterval(pollInterval);
|
|
395
|
-
progressBar.stop();
|
|
396
|
-
logger.log('');
|
|
397
|
-
logger.log('Exiting, sync will continue in the background.');
|
|
398
|
-
logger.log('');
|
|
399
|
-
logger.log(
|
|
400
|
-
i18n('lib.sandbox.sync.info.syncStatus', {
|
|
401
|
-
url: syncStatusUrl,
|
|
402
|
-
})
|
|
403
|
-
);
|
|
404
|
-
process.exit(EXIT_CODES.SUCCESS);
|
|
405
|
-
};
|
|
406
|
-
if (allowEarlyTermination) {
|
|
407
|
-
handleExit(onTerminate);
|
|
408
|
-
handleKeypress(key => {
|
|
409
|
-
if (
|
|
410
|
-
(key && key.ctrl && key.name == 'c') ||
|
|
411
|
-
key.name === 'enter' ||
|
|
412
|
-
key.name === 'return'
|
|
413
|
-
) {
|
|
414
|
-
onTerminate();
|
|
415
|
-
}
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
return new Promise((resolve, reject) => {
|
|
419
|
-
pollInterval = setInterval(async () => {
|
|
420
|
-
const taskResult = await fetchTaskStatus(accountId, taskId).catch(reject);
|
|
421
|
-
if (taskResult.tasks) {
|
|
422
|
-
// Array of sync tasks, eg: workflows, pipelines, object-schemas, etc. with each task containing a status of 'PENDING', 'IN_PROGRESS', 'COMPLETE', and 'FAILURE'
|
|
423
|
-
for (const task of taskResult.tasks) {
|
|
424
|
-
// For each sync task, show a progress bar and increment bar each time we run this interval until status is 'COMPLETE'
|
|
425
|
-
let taskType = task.type;
|
|
426
|
-
const taskTypeLabel = i18n(`${i18nKey}.${taskType}.label`);
|
|
427
|
-
if (taskTypeLabel.startsWith(MISSING_LANGUAGE_DATA_PREFIX)) {
|
|
428
|
-
continue;
|
|
429
|
-
}
|
|
430
|
-
if (!progressBar.get(taskType) && !mergeTasks[taskType]) {
|
|
431
|
-
// skip creation of lead-flows bar because we're combining lead-flows into the forms bar, otherwise create a bar instance for the type
|
|
432
|
-
progressCounter[taskType] = 0;
|
|
433
|
-
progressBar.create(taskType, 100, 0, {
|
|
434
|
-
label: taskTypeLabel,
|
|
435
|
-
});
|
|
436
|
-
} else if (mergeTasks[taskType]) {
|
|
437
|
-
// It's a lead-flow here, merge status into the forms progress bar
|
|
438
|
-
if (!progressCounter[mergeTasks[taskType]]) {
|
|
439
|
-
progressCounter[mergeTasks[taskType]] = 0;
|
|
440
|
-
}
|
|
441
|
-
const formsTask = taskResult.tasks.filter(
|
|
442
|
-
t => t.type === mergeTasks[taskType]
|
|
443
|
-
)[0];
|
|
444
|
-
const formsTaskStatus = formsTask.status;
|
|
445
|
-
const leadFlowsTaskStatus = task.status;
|
|
446
|
-
if (
|
|
447
|
-
formsTaskStatus !== 'COMPLETE' ||
|
|
448
|
-
leadFlowsTaskStatus !== 'COMPLETE'
|
|
449
|
-
) {
|
|
450
|
-
// Randomly increment bar while sync is in progress. Sandboxes currently does not have an accurate measurement for progress.
|
|
451
|
-
progressCounter[mergeTasks[taskType]] = incrementBy(
|
|
452
|
-
progressCounter[mergeTasks[taskType]]
|
|
453
|
-
);
|
|
454
|
-
progressBar.update(
|
|
455
|
-
mergeTasks[taskType],
|
|
456
|
-
progressCounter[mergeTasks[taskType]],
|
|
457
|
-
{
|
|
458
|
-
label: i18n(`${i18nKey}.${mergeTasks[taskType]}.label`),
|
|
459
|
-
}
|
|
460
|
-
);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
if (progressBar.get(taskType) && task.status === 'COMPLETE') {
|
|
464
|
-
progressBar.update(taskType, 100, {
|
|
465
|
-
label: taskTypeLabel,
|
|
466
|
-
});
|
|
467
|
-
} else if (
|
|
468
|
-
// Do not start incrementing for tasks still in PENDING state
|
|
469
|
-
progressBar.get(taskType) &&
|
|
470
|
-
task.status === 'PROCESSING'
|
|
471
|
-
) {
|
|
472
|
-
// Randomly increment bar while sync is in progress. Sandboxes currently does not have an accurate measurement for progress.
|
|
473
|
-
progressCounter[taskType] = incrementBy(
|
|
474
|
-
progressCounter[taskType],
|
|
475
|
-
taskType === syncTypes.OBJECT_RECORDS ? 2 : 3 // slower progress for object-records, sync can take up to a few minutes
|
|
476
|
-
);
|
|
477
|
-
progressBar.update(taskType, progressCounter[taskType], {
|
|
478
|
-
label: taskTypeLabel,
|
|
479
|
-
});
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
} else {
|
|
483
|
-
clearInterval(pollInterval);
|
|
484
|
-
reject();
|
|
485
|
-
progressBar.stop();
|
|
486
|
-
}
|
|
487
|
-
if (isTaskComplete(taskResult)) {
|
|
488
|
-
clearInterval(pollInterval);
|
|
489
|
-
resolve(taskResult);
|
|
490
|
-
progressBar.stop();
|
|
491
|
-
}
|
|
492
|
-
}, ACTIVE_TASK_POLL_INTERVAL);
|
|
493
|
-
});
|
|
494
|
-
}
|
|
495
|
-
|
|
496
356
|
module.exports = {
|
|
497
357
|
sandboxTypeMap,
|
|
498
358
|
sandboxApiTypeMap,
|
|
@@ -503,6 +363,5 @@ module.exports = {
|
|
|
503
363
|
validateSandboxUsageLimits,
|
|
504
364
|
getAvailableSyncTypes,
|
|
505
365
|
getSyncTypesWithContactRecordsPrompt,
|
|
506
|
-
pollSyncTaskStatus,
|
|
507
366
|
handleSandboxCreateError,
|
|
508
367
|
};
|
package/lib/serverlessLogs.js
CHANGED
|
@@ -52,7 +52,7 @@ const tailLogs = async ({
|
|
|
52
52
|
initialAfter = latestLog && base64EncodeString(latestLog.id);
|
|
53
53
|
} catch (e) {
|
|
54
54
|
// A 404 means no latest log exists(never executed)
|
|
55
|
-
if (e.
|
|
55
|
+
if (e.response && e.response.status !== 404) {
|
|
56
56
|
await logServerlessFunctionApiErrorInstance(
|
|
57
57
|
accountId,
|
|
58
58
|
e,
|
|
@@ -68,7 +68,7 @@ const tailLogs = async ({
|
|
|
68
68
|
latestLog = await tailCall(after);
|
|
69
69
|
nextAfter = latestLog.paging.next.after;
|
|
70
70
|
} catch (e) {
|
|
71
|
-
if (e.
|
|
71
|
+
if (e.response && e.response.status !== 404) {
|
|
72
72
|
logApiErrorInstance(
|
|
73
73
|
e,
|
|
74
74
|
new ApiErrorContext({
|
package/lib/ui/index.js
CHANGED
|
@@ -139,13 +139,87 @@ const uiBetaTag = (message, log = true) => {
|
|
|
139
139
|
}
|
|
140
140
|
};
|
|
141
141
|
|
|
142
|
+
const uiDeprecatedTag = (message, log = true) => {
|
|
143
|
+
const i18nKey = 'lib.ui';
|
|
144
|
+
|
|
145
|
+
const terminalUISupport = getTerminalUISupport();
|
|
146
|
+
const tag = i18n(`${i18nKey}.deprecatedTag`);
|
|
147
|
+
|
|
148
|
+
const result = `${
|
|
149
|
+
terminalUISupport.color ? chalk.yellow(tag) : tag
|
|
150
|
+
} ${message}`;
|
|
151
|
+
|
|
152
|
+
if (log) {
|
|
153
|
+
logger.log(result);
|
|
154
|
+
} else {
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const uiCommandDisabledBanner = (
|
|
160
|
+
command,
|
|
161
|
+
url = undefined,
|
|
162
|
+
message = undefined
|
|
163
|
+
) => {
|
|
164
|
+
const i18nKey = 'lib.ui';
|
|
165
|
+
|
|
166
|
+
const tag =
|
|
167
|
+
message ||
|
|
168
|
+
i18n(`${i18nKey}.disabledMessage`, {
|
|
169
|
+
command: uiCommandReference(command),
|
|
170
|
+
url: url ? uiLink(i18n(`${i18nKey}.disabledUrlText`), url) : undefined,
|
|
171
|
+
npmCommand: uiCommandReference('npm i -g @hubspot/cli@latest'),
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
logger.log();
|
|
175
|
+
uiLine();
|
|
176
|
+
logger.error(tag);
|
|
177
|
+
uiLine();
|
|
178
|
+
logger.log();
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const uiDeprecatedDescription = (
|
|
182
|
+
message,
|
|
183
|
+
command,
|
|
184
|
+
url = undefined,
|
|
185
|
+
log = false
|
|
186
|
+
) => {
|
|
187
|
+
const i18nKey = 'lib.ui';
|
|
188
|
+
|
|
189
|
+
const tag = i18n(`${i18nKey}.deprecatedDescription`, {
|
|
190
|
+
message,
|
|
191
|
+
command: uiCommandReference(command),
|
|
192
|
+
url,
|
|
193
|
+
});
|
|
194
|
+
return uiDeprecatedTag(tag, log);
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const uiDeprecatedMessage = (command, url = undefined, message = undefined) => {
|
|
198
|
+
const i18nKey = 'lib.ui';
|
|
199
|
+
|
|
200
|
+
const tag =
|
|
201
|
+
message ||
|
|
202
|
+
i18n(`${i18nKey}.deprecatedMessage`, {
|
|
203
|
+
command: uiCommandReference(command),
|
|
204
|
+
url: url ? uiLink(i18n(`${i18nKey}.deprecatedUrlText`), url) : undefined,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
logger.log();
|
|
208
|
+
uiDeprecatedTag(tag, true);
|
|
209
|
+
logger.log();
|
|
210
|
+
};
|
|
211
|
+
|
|
142
212
|
module.exports = {
|
|
143
213
|
UI_COLORS,
|
|
144
214
|
uiAccountDescription,
|
|
145
215
|
uiCommandReference,
|
|
146
216
|
uiBetaTag,
|
|
217
|
+
uiDeprecatedTag,
|
|
147
218
|
uiFeatureHighlight,
|
|
148
219
|
uiInfoSection,
|
|
149
220
|
uiLine,
|
|
150
221
|
uiLink,
|
|
222
|
+
uiDeprecatedMessage,
|
|
223
|
+
uiDeprecatedDescription,
|
|
224
|
+
uiCommandDisabledBanner,
|
|
151
225
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "CLI for working with HubSpot",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"url": "https://github.com/HubSpot/hubspot-cms-tools"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@hubspot/local-dev-lib": "1.
|
|
12
|
-
"@hubspot/serverless-dev-runtime": "5.
|
|
11
|
+
"@hubspot/local-dev-lib": "1.10.0",
|
|
12
|
+
"@hubspot/serverless-dev-runtime": "5.3.0",
|
|
13
13
|
"@hubspot/theme-preview-dev-server": "0.0.7",
|
|
14
14
|
"@hubspot/ui-extensions-dev-server": "0.8.20",
|
|
15
15
|
"archiver": "^5.3.0",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"yargs": "15.4.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
+
"axios": "^1.7.2",
|
|
36
37
|
"mock-stdin": "^1.0.0"
|
|
37
38
|
},
|
|
38
39
|
"engines": {
|
|
@@ -45,5 +46,5 @@
|
|
|
45
46
|
"publishConfig": {
|
|
46
47
|
"access": "public"
|
|
47
48
|
},
|
|
48
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "f55582baa2ac86396c72861b31998e54580c8c6a"
|
|
49
50
|
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
const { promptUser } = require('./promptUtils');
|
|
2
|
-
const { i18n } = require('../lang');
|
|
3
|
-
|
|
4
|
-
const i18nKey = 'lib.prompts.buildIdPrompt';
|
|
5
|
-
|
|
6
|
-
const buildIdPrompt = (latestBuildId, deployedBuildId, projectName) => {
|
|
7
|
-
return promptUser({
|
|
8
|
-
name: 'buildId',
|
|
9
|
-
message: i18n(`${i18nKey}.enterBuildId`),
|
|
10
|
-
default: () => {
|
|
11
|
-
if (latestBuildId === deployedBuildId) {
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
return latestBuildId;
|
|
15
|
-
},
|
|
16
|
-
validate: val => {
|
|
17
|
-
if (Number(val) > latestBuildId) {
|
|
18
|
-
return i18n(`${i18nKey}.errors.buildIdDoesNotExist`, {
|
|
19
|
-
buildId: val,
|
|
20
|
-
projectName,
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
if (Number(val) === deployedBuildId) {
|
|
24
|
-
return i18n(`${i18nKey}.errors.buildAlreadyDeployed`, {
|
|
25
|
-
buildId: val,
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
return true;
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
module.exports = {
|
|
34
|
-
buildIdPrompt,
|
|
35
|
-
};
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
// https://github.com/npkgz/cli-progress/blob/master/README.md
|
|
2
|
-
const ProgressMultibarManager = require('cli-progress');
|
|
3
|
-
|
|
4
|
-
class CliProgressMultibarManager {
|
|
5
|
-
constructor() {
|
|
6
|
-
this.multibar = null;
|
|
7
|
-
this.barInstances = {};
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
init(options) {
|
|
11
|
-
if (!this.multibar) {
|
|
12
|
-
this.multibar = new ProgressMultibarManager.MultiBar(
|
|
13
|
-
{
|
|
14
|
-
hideCursor: true,
|
|
15
|
-
format: '[{bar}] {percentage}% | {label}',
|
|
16
|
-
gracefulExit: true,
|
|
17
|
-
...options,
|
|
18
|
-
},
|
|
19
|
-
ProgressMultibarManager.Presets.rect
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
get: this.get.bind(this),
|
|
25
|
-
create: this.create.bind(this),
|
|
26
|
-
update: this.update.bind(this),
|
|
27
|
-
increment: this.increment.bind(this),
|
|
28
|
-
remove: this.multibar.remove.bind(this.multibar),
|
|
29
|
-
stop: this.multibar.stop.bind(this.multibar),
|
|
30
|
-
log: this.multibar.log.bind(this.multibar),
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
get(barName) {
|
|
35
|
-
return this.barInstances[barName];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
create(barName, total = 100, startValue = 0, options = {}) {
|
|
39
|
-
if (!this.multibar) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
if (!this.barInstances[barName]) {
|
|
43
|
-
this.barInstances[barName] = this.multibar.create(
|
|
44
|
-
total,
|
|
45
|
-
startValue,
|
|
46
|
-
options
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
update(barName, value, options = {}) {
|
|
52
|
-
const barInstance = this.barInstances[barName];
|
|
53
|
-
if (barInstance) {
|
|
54
|
-
barInstance.update(value, options);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
increment(barName, value, options = {}) {
|
|
59
|
-
const barInstance = this.barInstances[barName];
|
|
60
|
-
if (barInstance) {
|
|
61
|
-
barInstance.increment(value, options);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
module.exports = new CliProgressMultibarManager();
|