@hubspot/cli 3.0.12-beta.1 → 3.0.13-beta.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/project/upload.js +2 -0
- package/commands/project/watch.js +24 -9
- package/lib/projects.js +39 -20
- package/lib/prompts/personalAccessKeyPrompt.js +1 -1
- package/lib/serverlessLogs.js +8 -16
- package/lib/ui.js +8 -1
- package/package.json +4 -4
- package/bin/hubspot +0 -3
|
@@ -26,6 +26,7 @@ const {
|
|
|
26
26
|
} = require('@hubspot/cli-lib/api/dfs');
|
|
27
27
|
const { loadAndValidateOptions } = require('../../lib/validation');
|
|
28
28
|
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
29
|
+
const { handleKeypress, handleExit } = require('@hubspot/cli-lib/lib/process');
|
|
29
30
|
|
|
30
31
|
const i18nKey = 'cli.commands.project.subcommands.watch';
|
|
31
32
|
|
|
@@ -48,13 +49,13 @@ const handleBuildStatus = async (accountId, projectName, buildId) => {
|
|
|
48
49
|
}
|
|
49
50
|
};
|
|
50
51
|
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
const handleUserInput = (accountId, projectName, currentBuildId) => {
|
|
53
|
+
const onTerminate = async () => {
|
|
54
|
+
logger.log(i18n(`${i18nKey}.logs.processExited`));
|
|
55
|
+
|
|
54
56
|
if (currentBuildId) {
|
|
55
57
|
try {
|
|
56
58
|
await cancelStagedBuild(accountId, projectName);
|
|
57
|
-
logger.debug(i18n(`${i18nKey}.debug.buildCancelled`));
|
|
58
59
|
process.exit(EXIT_CODES.SUCCESS);
|
|
59
60
|
} catch (err) {
|
|
60
61
|
logApiErrorInstance(
|
|
@@ -66,13 +67,20 @@ const handleSigInt = (accountId, projectName, currentBuildId) => {
|
|
|
66
67
|
} else {
|
|
67
68
|
process.exit(EXIT_CODES.SUCCESS);
|
|
68
69
|
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
handleExit(onTerminate);
|
|
73
|
+
handleKeypress(key => {
|
|
74
|
+
if ((key.ctrl && key.name === 'c') || key.name === 'q') {
|
|
75
|
+
onTerminate();
|
|
76
|
+
}
|
|
69
77
|
});
|
|
70
78
|
};
|
|
71
79
|
|
|
72
80
|
exports.handler = async options => {
|
|
73
81
|
await loadAndValidateOptions(options);
|
|
74
82
|
|
|
75
|
-
const { path: projectPath } = options;
|
|
83
|
+
const { initialUpload, path: projectPath } = options;
|
|
76
84
|
const accountId = getAccountId(options);
|
|
77
85
|
|
|
78
86
|
trackCommandUsage('project-watch', { projectPath }, accountId);
|
|
@@ -83,11 +91,12 @@ exports.handler = async options => {
|
|
|
83
91
|
|
|
84
92
|
await ensureProjectExists(accountId, projectConfig.name);
|
|
85
93
|
|
|
86
|
-
const { results } = await fetchProjectBuilds(
|
|
94
|
+
const { results: builds } = await fetchProjectBuilds(
|
|
87
95
|
accountId,
|
|
88
96
|
projectConfig.name,
|
|
89
97
|
options
|
|
90
98
|
);
|
|
99
|
+
const hasNoBuilds = !builds || !builds.length;
|
|
91
100
|
|
|
92
101
|
const startWatching = async () => {
|
|
93
102
|
await createWatcher(
|
|
@@ -95,12 +104,12 @@ exports.handler = async options => {
|
|
|
95
104
|
projectConfig,
|
|
96
105
|
projectDir,
|
|
97
106
|
handleBuildStatus,
|
|
98
|
-
|
|
107
|
+
handleUserInput
|
|
99
108
|
);
|
|
100
109
|
};
|
|
101
110
|
|
|
102
111
|
// Upload all files if no build exists for this project yet
|
|
103
|
-
if (
|
|
112
|
+
if (initialUpload || hasNoBuilds) {
|
|
104
113
|
await handleProjectUpload(
|
|
105
114
|
accountId,
|
|
106
115
|
projectConfig,
|
|
@@ -114,10 +123,16 @@ exports.handler = async options => {
|
|
|
114
123
|
|
|
115
124
|
exports.builder = yargs => {
|
|
116
125
|
yargs.positional('path', {
|
|
117
|
-
describe: i18n(`${i18nKey}.describe`),
|
|
126
|
+
describe: i18n(`${i18nKey}.positionals.path.describe`),
|
|
118
127
|
type: 'string',
|
|
119
128
|
});
|
|
120
129
|
|
|
130
|
+
yargs.option('initial-upload', {
|
|
131
|
+
alias: 'i',
|
|
132
|
+
describe: i18n(`${i18nKey}.options.initialUpload.describe`),
|
|
133
|
+
type: 'boolean',
|
|
134
|
+
});
|
|
135
|
+
|
|
121
136
|
yargs.example([
|
|
122
137
|
['$0 project watch myProjectFolder', i18n(`${i18nKey}.examples.default`)],
|
|
123
138
|
]);
|
package/lib/projects.js
CHANGED
|
@@ -32,7 +32,7 @@ const { shouldIgnoreFile } = require('@hubspot/cli-lib/ignoreRules');
|
|
|
32
32
|
const { getCwd } = require('@hubspot/cli-lib/path');
|
|
33
33
|
const { promptUser } = require('./prompts/promptUtils');
|
|
34
34
|
const { EXIT_CODES } = require('./enums/exitCodes');
|
|
35
|
-
const { uiLine, uiAccountDescription } = require('../lib/ui');
|
|
35
|
+
const { uiLine, uiLink, uiAccountDescription } = require('../lib/ui');
|
|
36
36
|
const { i18n } = require('@hubspot/cli-lib/lib/lang');
|
|
37
37
|
|
|
38
38
|
const writeProjectConfig = (configPath, config) => {
|
|
@@ -165,7 +165,7 @@ const validateProjectConfig = (projectConfig, projectDir) => {
|
|
|
165
165
|
const ensureProjectExists = async (
|
|
166
166
|
accountId,
|
|
167
167
|
projectName,
|
|
168
|
-
{ forceCreate
|
|
168
|
+
{ forceCreate = false, allowCreate = true } = {}
|
|
169
169
|
) => {
|
|
170
170
|
try {
|
|
171
171
|
await fetchProject(accountId, projectName);
|
|
@@ -214,6 +214,11 @@ const getProjectDetailUrl = (projectName, accountId) => {
|
|
|
214
214
|
return `${baseUrl}/developer-projects/${accountId}/project/${projectName}`;
|
|
215
215
|
};
|
|
216
216
|
|
|
217
|
+
const getProjectBuildDetailUrl = (projectName, buildId, accountId) => {
|
|
218
|
+
if (!projectName || !buildId || !accountId) return;
|
|
219
|
+
return `${getProjectDetailUrl(projectName, accountId)}/build/${buildId}`;
|
|
220
|
+
};
|
|
221
|
+
|
|
217
222
|
const uploadProjectFiles = async (accountId, projectName, filePath) => {
|
|
218
223
|
const i18nKey = 'cli.commands.project.subcommands.upload';
|
|
219
224
|
const spinnies = new Spinnies({
|
|
@@ -336,7 +341,12 @@ const showProjectWelcomeMessage = () => {
|
|
|
336
341
|
uiLine();
|
|
337
342
|
};
|
|
338
343
|
|
|
339
|
-
const makePollTaskStatusFunc = ({
|
|
344
|
+
const makePollTaskStatusFunc = ({
|
|
345
|
+
statusFn,
|
|
346
|
+
statusText,
|
|
347
|
+
statusStrings,
|
|
348
|
+
linkToHubSpot,
|
|
349
|
+
}) => {
|
|
340
350
|
const isTaskComplete = task => {
|
|
341
351
|
if (
|
|
342
352
|
!task[statusText.SUBTASK_KEY].length ||
|
|
@@ -348,7 +358,12 @@ const makePollTaskStatusFunc = ({ statusFn, statusText, statusStrings }) => {
|
|
|
348
358
|
}
|
|
349
359
|
};
|
|
350
360
|
|
|
351
|
-
return async (accountId, taskName, taskId
|
|
361
|
+
return async (accountId, taskName, taskId) => {
|
|
362
|
+
let hubspotLinkText = '';
|
|
363
|
+
if (linkToHubSpot) {
|
|
364
|
+
logger.log(`\n${linkToHubSpot(taskName, taskId, accountId)}\n`);
|
|
365
|
+
}
|
|
366
|
+
|
|
352
367
|
const spinnies = new Spinnies({
|
|
353
368
|
succeedColor: 'white',
|
|
354
369
|
failColor: 'white',
|
|
@@ -359,20 +374,23 @@ const makePollTaskStatusFunc = ({ statusFn, statusText, statusStrings }) => {
|
|
|
359
374
|
|
|
360
375
|
const initialTaskStatus = await statusFn(accountId, taskName, taskId);
|
|
361
376
|
|
|
377
|
+
const numOfComponents = initialTaskStatus[statusText.SUBTASK_KEY].length;
|
|
378
|
+
const componentCountText = `\nFound ${numOfComponents} component${
|
|
379
|
+
numOfComponents !== 1 ? 's' : ''
|
|
380
|
+
} in this project ...\n`;
|
|
381
|
+
|
|
362
382
|
spinnies.update('overallTaskStatus', {
|
|
363
|
-
text: statusStrings.INITIALIZE(
|
|
364
|
-
taskName,
|
|
365
|
-
initialTaskStatus[statusText.SUBTASK_KEY].length
|
|
366
|
-
),
|
|
383
|
+
text: `${statusStrings.INITIALIZE(taskName)}${componentCountText}`,
|
|
367
384
|
});
|
|
368
385
|
|
|
369
386
|
for (let subTask of initialTaskStatus[statusText.SUBTASK_KEY]) {
|
|
370
387
|
const subTaskName = subTask[statusText.SUBTASK_NAME_KEY];
|
|
371
388
|
|
|
372
389
|
spinnies.add(subTaskName, {
|
|
373
|
-
text: `${chalk.bold(subTaskName)} #${
|
|
390
|
+
text: `${chalk.bold(subTaskName)} #${taskId} ${
|
|
374
391
|
statusText.STATUS_TEXT[statusText.STATES.ENQUEUED]
|
|
375
392
|
}\n`,
|
|
393
|
+
indent: 2,
|
|
376
394
|
});
|
|
377
395
|
}
|
|
378
396
|
|
|
@@ -416,11 +434,11 @@ const makePollTaskStatusFunc = ({ statusFn, statusText, statusStrings }) => {
|
|
|
416
434
|
|
|
417
435
|
if (status === statusText.STATES.SUCCESS) {
|
|
418
436
|
spinnies.succeed('overallTaskStatus', {
|
|
419
|
-
text: statusStrings.SUCCESS(taskName)
|
|
437
|
+
text: `${statusStrings.SUCCESS(taskName)}${hubspotLinkText}`,
|
|
420
438
|
});
|
|
421
439
|
} else if (status === statusText.STATES.FAILURE) {
|
|
422
440
|
spinnies.fail('overallTaskStatus', {
|
|
423
|
-
text: statusStrings.FAIL(taskName)
|
|
441
|
+
text: `${statusStrings.FAIL(taskName)}${hubspotLinkText}`,
|
|
424
442
|
});
|
|
425
443
|
|
|
426
444
|
const failedSubtask = subTaskStatus.filter(
|
|
@@ -430,7 +448,7 @@ const makePollTaskStatusFunc = ({ statusFn, statusText, statusStrings }) => {
|
|
|
430
448
|
uiLine();
|
|
431
449
|
logger.log(
|
|
432
450
|
`${statusStrings.SUBTASK_FAIL(
|
|
433
|
-
|
|
451
|
+
taskId,
|
|
434
452
|
failedSubtask.length === 1
|
|
435
453
|
? failedSubtask[0][statusText.SUBTASK_NAME_KEY]
|
|
436
454
|
: failedSubtask.length + ' components'
|
|
@@ -459,13 +477,16 @@ const makePollTaskStatusFunc = ({ statusFn, statusText, statusStrings }) => {
|
|
|
459
477
|
};
|
|
460
478
|
|
|
461
479
|
const pollBuildStatus = makePollTaskStatusFunc({
|
|
480
|
+
linkToHubSpot: (projectName, buildId, accountId) =>
|
|
481
|
+
uiLink(
|
|
482
|
+
`View build #${buildId} in HubSpot`,
|
|
483
|
+
getProjectBuildDetailUrl(projectName, buildId, accountId),
|
|
484
|
+
{ useColor: true }
|
|
485
|
+
),
|
|
462
486
|
statusFn: getBuildStatus,
|
|
463
487
|
statusText: PROJECT_BUILD_TEXT,
|
|
464
488
|
statusStrings: {
|
|
465
|
-
INITIALIZE: (name
|
|
466
|
-
`Building ${chalk.bold(name)}\n\nFound ${numOfComponents} component${
|
|
467
|
-
numOfComponents !== 1 ? 's' : ''
|
|
468
|
-
} in this project ...\n`,
|
|
489
|
+
INITIALIZE: name => `Building ${chalk.bold(name)}`,
|
|
469
490
|
SUCCESS: name => `Built ${chalk.bold(name)}`,
|
|
470
491
|
FAIL: name => `Failed to build ${chalk.bold(name)}`,
|
|
471
492
|
SUBTASK_FAIL: (taskId, name) =>
|
|
@@ -479,10 +500,7 @@ const pollDeployStatus = makePollTaskStatusFunc({
|
|
|
479
500
|
statusFn: getDeployStatus,
|
|
480
501
|
statusText: PROJECT_DEPLOY_TEXT,
|
|
481
502
|
statusStrings: {
|
|
482
|
-
INITIALIZE: (name
|
|
483
|
-
`Deploying ${chalk.bold(name)}\n\nFound ${numOfComponents} component${
|
|
484
|
-
numOfComponents !== 1 ? 's' : ''
|
|
485
|
-
} in this project ...\n`,
|
|
503
|
+
INITIALIZE: name => `Deploying ${chalk.bold(name)}`,
|
|
486
504
|
SUCCESS: name => `Deployed ${chalk.bold(name)}`,
|
|
487
505
|
FAIL: name => `Failed to deploy ${chalk.bold(name)}`,
|
|
488
506
|
SUBTASK_FAIL: (taskId, name) =>
|
|
@@ -501,6 +519,7 @@ module.exports = {
|
|
|
501
519
|
validateProjectConfig,
|
|
502
520
|
showProjectWelcomeMessage,
|
|
503
521
|
getProjectDetailUrl,
|
|
522
|
+
getProjectBuildDetailUrl,
|
|
504
523
|
pollBuildStatus,
|
|
505
524
|
pollDeployStatus,
|
|
506
525
|
ensureProjectExists,
|
|
@@ -107,7 +107,7 @@ const PERSONAL_ACCESS_KEY = {
|
|
|
107
107
|
name: 'personalAccessKey',
|
|
108
108
|
message: i18n(`${i18nKey}.enterPersonalAccessKey`),
|
|
109
109
|
validate(val) {
|
|
110
|
-
if (typeof val !== 'string') {
|
|
110
|
+
if (!val || typeof val !== 'string') {
|
|
111
111
|
return i18n(`${i18nKey}.errors.invalidPersonalAccessKey`);
|
|
112
112
|
} else if (val[0] === '•') {
|
|
113
113
|
return i18n(`${i18nKey}.errors.invalidPersonalAccessKeyCopy`);
|
package/lib/serverlessLogs.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const https = require('https');
|
|
2
|
-
const readline = require('readline');
|
|
3
2
|
|
|
4
3
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
5
4
|
const { outputLogs } = require('@hubspot/cli-lib/lib/logs');
|
|
@@ -9,20 +8,12 @@ const {
|
|
|
9
8
|
ApiErrorContext,
|
|
10
9
|
} = require('@hubspot/cli-lib/errorHandlers');
|
|
11
10
|
const { base64EncodeString } = require('@hubspot/cli-lib/lib/encoding');
|
|
11
|
+
const { handleKeypress } = require('@hubspot/cli-lib/lib/process');
|
|
12
|
+
|
|
12
13
|
const { EXIT_CODES } = require('../lib/enums/exitCodes');
|
|
13
14
|
|
|
14
15
|
const TAIL_DELAY = 5000;
|
|
15
16
|
|
|
16
|
-
const handleKeypressToExit = exit => {
|
|
17
|
-
readline.emitKeypressEvents(process.stdin);
|
|
18
|
-
process.stdin.setRawMode(true);
|
|
19
|
-
process.stdin.on('keypress', (str, key) => {
|
|
20
|
-
if (key && ((key.ctrl && key.name == 'c') || key.name === 'escape')) {
|
|
21
|
-
exit(key.name === 'escape' ? 'esc' : 'ctrl+c');
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
};
|
|
25
|
-
|
|
26
17
|
const tailLogs = async ({
|
|
27
18
|
accountId,
|
|
28
19
|
compact,
|
|
@@ -76,12 +67,13 @@ const tailLogs = async ({
|
|
|
76
67
|
}, TAIL_DELAY);
|
|
77
68
|
};
|
|
78
69
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
text: `Stopped polling
|
|
82
|
-
|
|
83
|
-
|
|
70
|
+
handleKeypress(key => {
|
|
71
|
+
if ((key.ctrl && key.name == 'c') || key.name === 'escape') {
|
|
72
|
+
spinnies.succeed('tailLogs', { text: `Stopped polling` });
|
|
73
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
74
|
+
}
|
|
84
75
|
});
|
|
76
|
+
|
|
85
77
|
await tail(initialAfter);
|
|
86
78
|
};
|
|
87
79
|
|
package/lib/ui.js
CHANGED
|
@@ -22,7 +22,14 @@ const uiLine = () => {
|
|
|
22
22
|
*/
|
|
23
23
|
const uiLink = (linkText, url, options = {}) => {
|
|
24
24
|
if (supportsHyperlinks.stdout) {
|
|
25
|
-
|
|
25
|
+
const result = [
|
|
26
|
+
'\u001B]8;;',
|
|
27
|
+
url,
|
|
28
|
+
'\u0007',
|
|
29
|
+
linkText,
|
|
30
|
+
'\u001B]8;;\u0007',
|
|
31
|
+
].join('');
|
|
32
|
+
return options.useColor ? chalk.cyan(result) : result;
|
|
26
33
|
} else {
|
|
27
34
|
return options.fallback ? `${linkText}: ${url}` : linkText;
|
|
28
35
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.13-beta.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/cli-lib": "^3.0.12
|
|
12
|
-
"@hubspot/serverless-dev-runtime": "^3.0.12
|
|
11
|
+
"@hubspot/cli-lib": "^3.0.12",
|
|
12
|
+
"@hubspot/serverless-dev-runtime": "^3.0.12",
|
|
13
13
|
"archiver": "^5.3.0",
|
|
14
14
|
"chalk": "^4.1.2",
|
|
15
15
|
"express": "^4.17.1",
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "a4c15c0ae8f06064273c51c44a7b7b38863bcd38"
|
|
43
43
|
}
|
package/bin/hubspot
DELETED