@hubspot/cli 4.0.2-beta.4 → 4.0.2-beta.6

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/bin/cli.js CHANGED
@@ -40,6 +40,7 @@ const accountsCommand = require('../commands/accounts');
40
40
  const sandboxesCommand = require('../commands/sandbox');
41
41
  const processCommand = require('../commands/process');
42
42
  const cmsCommand = require('../commands/cms');
43
+ const feedbackCommand = require('../commands/feedback');
43
44
  const { EXIT_CODES } = require('../lib/enums/exitCodes');
44
45
 
45
46
  const notifier = updateNotifier({ pkg: { ...pkg, name: '@hubspot/cli' } });
@@ -159,6 +160,7 @@ const argv = yargs
159
160
  .command(accountsCommand)
160
161
  .command(sandboxesCommand)
161
162
  .command(processCommand, false)
163
+ .command(feedbackCommand)
162
164
  .help()
163
165
  .recommendCommands()
164
166
  .demandCommand(1, '')
@@ -0,0 +1,48 @@
1
+ const open = require('open');
2
+
3
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
4
+ const {
5
+ FEEDBACK_OPTIONS,
6
+ FEEDBACK_URLS,
7
+ } = require('@hubspot/cli-lib/lib/constants');
8
+ const { logger } = require('@hubspot/cli-lib/logger');
9
+
10
+ const {
11
+ feedbackTypePrompt,
12
+ shouldOpenBrowserPrompt,
13
+ } = require('../lib/prompts/feedbackPrompt');
14
+
15
+ const i18nKey = 'cli.commands.project.subcommands.feedback';
16
+
17
+ exports.command = 'feedback';
18
+ exports.describe = i18n(`${i18nKey}.describe`);
19
+
20
+ exports.handler = async options => {
21
+ const { bug: bugFlag, general: generalFlag } = options;
22
+ const usedTypeFlag = bugFlag !== generalFlag;
23
+
24
+ const { type } = await feedbackTypePrompt(usedTypeFlag);
25
+ const { shouldOpen } = await shouldOpenBrowserPrompt(type, usedTypeFlag);
26
+
27
+ if (shouldOpen || usedTypeFlag) {
28
+ const url =
29
+ type === FEEDBACK_OPTIONS.BUG || bugFlag
30
+ ? FEEDBACK_URLS.BUG
31
+ : FEEDBACK_URLS.GENERAL;
32
+ open(url, { url: true });
33
+ logger.success(i18n(`${i18nKey}.success`, { url }));
34
+ }
35
+ };
36
+
37
+ exports.builder = yargs => {
38
+ yargs.options({
39
+ bug: {
40
+ describe: i18n(`${i18nKey}.options.bug.describe`),
41
+ type: 'boolean',
42
+ },
43
+ general: {
44
+ describe: i18n(`${i18nKey}.options.general.describe`),
45
+ type: 'boolean',
46
+ },
47
+ });
48
+ };
@@ -45,6 +45,7 @@ exports.handler = async options => {
45
45
  'projectUploadCommand',
46
46
  'projectDeployCommand',
47
47
  'projectHelpCommand',
48
+ 'feedbackCommand',
48
49
  ]);
49
50
  };
50
51
 
@@ -15,7 +15,7 @@ const { loadAndValidateOptions } = require('../../lib/validation');
15
15
  const { getProjectConfig, pollDeployStatus } = require('../../lib/projects');
16
16
  const { projectNamePrompt } = require('../../lib/prompts/projectNamePrompt');
17
17
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
18
- // const { getAccountConfig } = require('@hubspot/cli-lib');
18
+ const { getAccountConfig } = require('@hubspot/cli-lib');
19
19
 
20
20
  const i18nKey = 'cli.commands.project.subcommands.deploy';
21
21
  const { EXIT_CODES } = require('../../lib/enums/exitCodes');
@@ -27,11 +27,11 @@ exports.handler = async options => {
27
27
  await loadAndValidateOptions(options);
28
28
 
29
29
  const accountId = getAccountId(options);
30
- // const accountConfig = getAccountConfig(accountId);
30
+ const accountConfig = getAccountConfig(accountId);
31
31
  const { project, buildId } = options;
32
- // const sandboxType = accountConfig && accountConfig.sandboxAccountType;
32
+ const sandboxType = accountConfig && accountConfig.sandboxAccountType;
33
33
 
34
- trackCommandUsage('project-deploy', null, accountId);
34
+ trackCommandUsage('project-deploy', { type: sandboxType }, accountId);
35
35
 
36
36
  const { projectConfig } = await getProjectConfig();
37
37
 
@@ -13,12 +13,13 @@ const {
13
13
  ensureProjectExists,
14
14
  getProjectConfig,
15
15
  handleProjectUpload,
16
+ logFeedbackMessage,
16
17
  pollBuildStatus,
17
18
  pollDeployStatus,
18
19
  validateProjectConfig,
19
20
  } = require('../../lib/projects');
20
21
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
21
- // const { getAccountConfig } = require('@hubspot/cli-lib');
22
+ const { getAccountConfig } = require('@hubspot/cli-lib');
22
23
  const { EXIT_CODES } = require('../../lib/enums/exitCodes');
23
24
 
24
25
  const i18nKey = 'cli.commands.project.subcommands.upload';
@@ -31,10 +32,10 @@ exports.handler = async options => {
31
32
 
32
33
  const { forceCreate, path: projectPath } = options;
33
34
  const accountId = getAccountId(options);
34
- // const accountConfig = getAccountConfig(accountId);
35
- // const sandboxType = accountConfig && accountConfig.sandboxAccountType;
35
+ const accountConfig = getAccountConfig(accountId);
36
+ const sandboxType = accountConfig && accountConfig.sandboxAccountType;
36
37
 
37
- trackCommandUsage('project-upload', null, accountId);
38
+ trackCommandUsage('project-upload', { type: sandboxType }, accountId);
38
39
 
39
40
  const { projectConfig, projectDir } = await getProjectConfig(projectPath);
40
41
 
@@ -46,17 +47,21 @@ exports.handler = async options => {
46
47
  let exitCode = EXIT_CODES.SUCCESS;
47
48
 
48
49
  const {
50
+ autoDeployId,
49
51
  isAutoDeployEnabled,
50
52
  deployStatusTaskLocator,
51
53
  status,
52
54
  } = await pollBuildStatus(accountId, projectConfig.name, buildId);
55
+ // autoDeployId of 0 indicates a skipped deploy
56
+ const isDeploying =
57
+ isAutoDeployEnabled && autoDeployId > 0 && deployStatusTaskLocator;
53
58
 
54
59
  uiLine();
55
60
 
56
61
  if (status === 'FAILURE') {
57
62
  exitCode = EXIT_CODES.ERROR;
58
63
  return;
59
- } else if (isAutoDeployEnabled && deployStatusTaskLocator) {
64
+ } else if (isDeploying) {
60
65
  logger.log(
61
66
  i18n(`${i18nKey}.logs.buildSucceededAutomaticallyDeploying`, {
62
67
  accountIdentifier: uiAccountDescription(accountId),
@@ -101,6 +106,8 @@ exports.handler = async options => {
101
106
  logger.error(e);
102
107
  }
103
108
 
109
+ logFeedbackMessage(buildId);
110
+
104
111
  process.exit(exitCode);
105
112
  };
106
113
 
@@ -19,6 +19,7 @@ const {
19
19
  pollBuildStatus,
20
20
  pollDeployStatus,
21
21
  validateProjectConfig,
22
+ logFeedbackMessage,
22
23
  } = require('../../lib/projects');
23
24
  const {
24
25
  cancelStagedBuild,
@@ -47,6 +48,8 @@ const handleBuildStatus = async (accountId, projectName, buildId) => {
47
48
  buildId
48
49
  );
49
50
  }
51
+
52
+ logFeedbackMessage(buildId);
50
53
  };
51
54
 
52
55
  const handleUserInput = (accountId, projectName, currentBuildId) => {
@@ -151,6 +151,8 @@ exports.handler = async options => {
151
151
  } catch (err) {
152
152
  debugErrorAndContext(err);
153
153
 
154
+ trackCommandUsage('sandbox-create', { successful: false }, accountId);
155
+
154
156
  spinnies.fail('sandboxCreate', {
155
157
  text: i18n(`${i18nKey}.loading.fail`, {
156
158
  sandboxName,
@@ -126,6 +126,12 @@ exports.handler = async options => {
126
126
  } catch (err) {
127
127
  debugErrorAndContext(err);
128
128
 
129
+ trackCommandUsage(
130
+ 'sandbox-delete',
131
+ { successful: false },
132
+ sandboxAccountId
133
+ );
134
+
129
135
  if (
130
136
  err.error &&
131
137
  err.error.category === OBJECT_NOT_FOUND &&
@@ -78,13 +78,16 @@ exports.handler = async options => {
78
78
  logger.error(i18n(`${i18nKey}.errors.destinationRequired`));
79
79
  return;
80
80
  }
81
- // The theme.json file must always be at the root of the project - so we look for that and determine the root path based on it.
82
- const projectRoot = path.dirname(getThemeJSONPath(absoluteSrcPath));
83
- const processFieldsJs = isProcessableFieldsJs(
84
- projectRoot,
85
- absoluteSrcPath,
86
- options.processFieldsJs
87
- );
81
+ // Check for theme.json file and determine the root path for the project based on it if it exists
82
+ const themeJsonPath = getThemeJSONPath(absoluteSrcPath);
83
+ const projectRoot = themeJsonPath && path.dirname(themeJsonPath);
84
+ const processFieldsJs =
85
+ projectRoot &&
86
+ isProcessableFieldsJs(
87
+ projectRoot,
88
+ absoluteSrcPath,
89
+ options.processFieldsJs
90
+ );
88
91
  let fieldsJs;
89
92
  if (processFieldsJs) {
90
93
  fieldsJs = await new FieldsJs(
package/lib/projects.js CHANGED
@@ -11,6 +11,8 @@ const { cloneGitHubRepo } = require('@hubspot/cli-lib/github');
11
11
  const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
12
12
  const {
13
13
  ENVIRONMENTS,
14
+ FEEDBACK_INTERVAL,
15
+ ERROR_TYPES,
14
16
  POLLING_DELAY,
15
17
  PROJECT_TEMPLATES,
16
18
  PROJECT_BUILD_TEXT,
@@ -280,6 +282,9 @@ const uploadProjectFiles = async (accountId, projectName, filePath) => {
280
282
  projectName,
281
283
  })
282
284
  );
285
+ if (err.error.subCategory === ERROR_TYPES.PROJECT_LOCKED) {
286
+ logger.log(i18n(`${i18nKey}.logs.projectLockedError`));
287
+ }
283
288
  process.exit(EXIT_CODES.ERROR);
284
289
  }
285
290
 
@@ -382,7 +387,7 @@ const makePollTaskStatusFunc = ({
382
387
  const subTaskName = subTask[statusText.SUBTASK_NAME_KEY];
383
388
 
384
389
  spinnies.add(subTaskName, {
385
- text: `${chalk.bold(subTaskName)} #${displayId} ${
390
+ text: `${chalk.bold(subTaskName)} ${
386
391
  statusText.STATUS_TEXT[statusText.STATES.ENQUEUED]
387
392
  }\n`,
388
393
  indent: 2,
@@ -405,7 +410,7 @@ const makePollTaskStatusFunc = ({
405
410
  return;
406
411
  }
407
412
 
408
- const updatedText = `${chalk.bold(subTaskName)} #${displayId} ${
413
+ const updatedText = `${chalk.bold(subTaskName)} ${
409
414
  statusText.STATUS_TEXT[subTask.status]
410
415
  }\n`;
411
416
 
@@ -517,6 +522,16 @@ const pollDeployStatus = makePollTaskStatusFunc({
517
522
  },
518
523
  });
519
524
 
525
+ const logFeedbackMessage = buildId => {
526
+ const i18nKey = 'cli.commands.project.subcommands.upload';
527
+ if (buildId > 0 && buildId % FEEDBACK_INTERVAL === 0) {
528
+ uiLine();
529
+ logger.log(i18n(`${i18nKey}.logs.feedbackHeader`));
530
+ uiLine();
531
+ logger.log(i18n(`${i18nKey}.logs.feedbackMessage`));
532
+ }
533
+ };
534
+
520
535
  module.exports = {
521
536
  writeProjectConfig,
522
537
  getProjectConfig,
@@ -529,4 +544,5 @@ module.exports = {
529
544
  pollBuildStatus,
530
545
  pollDeployStatus,
531
546
  ensureProjectExists,
547
+ logFeedbackMessage,
532
548
  };
@@ -0,0 +1,40 @@
1
+ const { promptUser } = require('./promptUtils');
2
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
3
+ const { FEEDBACK_OPTIONS } = require('@hubspot/cli-lib/lib/constants');
4
+
5
+ const i18nKey = 'cli.lib.prompts.feedbackPrompt';
6
+
7
+ const feedbackTypePrompt = bypassPrompt => {
8
+ return promptUser([
9
+ {
10
+ name: 'type',
11
+ message: i18n(`${i18nKey}.feedbackType.message`),
12
+ type: 'list',
13
+ when: !bypassPrompt,
14
+ choices: Object.values(FEEDBACK_OPTIONS).map(option => ({
15
+ name: i18n(`${i18nKey}.feedbackType.${option}`),
16
+ value: option,
17
+ })),
18
+ },
19
+ ]);
20
+ };
21
+
22
+ const shouldOpenBrowserPrompt = (type, bypassPrompt) => {
23
+ return promptUser([
24
+ {
25
+ name: 'shouldOpen',
26
+ message: () => {
27
+ return type === FEEDBACK_OPTIONS.BUG
28
+ ? i18n(`${i18nKey}.bugPrompt`)
29
+ : i18n(`${i18nKey}.generalPrompt`);
30
+ },
31
+ type: 'confirm',
32
+ when: !bypassPrompt,
33
+ },
34
+ ]);
35
+ };
36
+
37
+ module.exports = {
38
+ feedbackTypePrompt,
39
+ shouldOpenBrowserPrompt,
40
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "4.0.2-beta.4",
3
+ "version": "4.0.2-beta.6",
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": "4.0.2-beta.4",
12
- "@hubspot/serverless-dev-runtime": "4.0.2-beta.4",
11
+ "@hubspot/cli-lib": "4.0.2-beta.6",
12
+ "@hubspot/serverless-dev-runtime": "4.0.2-beta.6",
13
13
  "archiver": "^5.3.0",
14
14
  "chalk": "^4.1.2",
15
15
  "express": "^4.17.1",
@@ -37,5 +37,5 @@
37
37
  "publishConfig": {
38
38
  "access": "public"
39
39
  },
40
- "gitHead": "56347c4026ac958b9a721ed0057b68c7c4c4918d"
40
+ "gitHead": "e738be958be36d5ec5aa4957483cd096bef13ef0"
41
41
  }