@hubspot/cli 4.1.7 → 4.1.8-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.
@@ -12,7 +12,7 @@ const {
12
12
  } = require('../../lib/commonOpts');
13
13
  const { trackCommandUsage } = require('../../lib/usageTracking');
14
14
  const { loadAndValidateOptions } = require('../../lib/validation');
15
- const { getSandboxType } = require('../../lib/sandboxes');
15
+ const { getSandboxTypeAsString } = require('../../lib/sandboxes');
16
16
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
17
17
 
18
18
  const i18nKey = 'cli.commands.accounts.subcommands.list';
@@ -58,7 +58,7 @@ const getPortalData = mappedPortalData => {
58
58
  portalData.push([portal.name, portal.portalId, portal.authType]);
59
59
  } else {
60
60
  portalData.push([
61
- `↳ ${portal.name} [${getSandboxType(
61
+ `↳ ${portal.name} [${getSandboxTypeAsString(
62
62
  portal.sandboxAccountType
63
63
  )} sandbox]`,
64
64
  portal.portalId,
@@ -0,0 +1,84 @@
1
+ const { logger } = require('@hubspot/cli-lib/logger');
2
+ const {
3
+ getConfig,
4
+ getConfigPath,
5
+ deleteAccount,
6
+ getConfigDefaultAccount,
7
+ getAccountId: getAccountIdFromConfig,
8
+ updateDefaultAccount,
9
+ } = require('@hubspot/cli-lib/lib/config');
10
+
11
+ const { trackCommandUsage } = require('../../lib/usageTracking');
12
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
13
+ const { selectAccountFromConfig } = require('../../lib/prompts/accountsPrompt');
14
+ const { loadAndValidateOptions } = require('../../lib/validation');
15
+
16
+ const i18nKey = 'cli.commands.accounts.subcommands.remove';
17
+
18
+ exports.command = 'remove [--account]';
19
+ exports.describe = i18n(`${i18nKey}.describe`);
20
+
21
+ exports.handler = async options => {
22
+ await loadAndValidateOptions(options, false);
23
+
24
+ let config = getConfig();
25
+
26
+ let accountToRemove = options.account;
27
+
28
+ if (accountToRemove && !getAccountIdFromConfig(accountToRemove)) {
29
+ logger.error(
30
+ i18n(`${i18nKey}.errors.accountNotFound`, {
31
+ specifiedAccount: accountToRemove,
32
+ configPath: getConfigPath(),
33
+ })
34
+ );
35
+ }
36
+
37
+ if (!accountToRemove || !getAccountIdFromConfig(accountToRemove)) {
38
+ accountToRemove = await selectAccountFromConfig(
39
+ config,
40
+ i18n(`${i18nKey}.prompts.selectAccountToRemove`)
41
+ );
42
+ }
43
+
44
+ trackCommandUsage(
45
+ 'accounts-remove',
46
+ null,
47
+ getAccountIdFromConfig(accountToRemove)
48
+ );
49
+
50
+ const currentDefaultAccount = getConfigDefaultAccount();
51
+
52
+ await deleteAccount(accountToRemove);
53
+ logger.success(
54
+ i18n(`${i18nKey}.success.accountRemoved`, {
55
+ accountName: accountToRemove,
56
+ })
57
+ );
58
+
59
+ // Get updated version of the config
60
+ config = getConfig();
61
+
62
+ if (accountToRemove === currentDefaultAccount) {
63
+ logger.log();
64
+ logger.log(i18n(`${i18nKey}.logs.replaceDefaultAccount`));
65
+ const newDefaultAccount = await selectAccountFromConfig(config);
66
+ updateDefaultAccount(newDefaultAccount);
67
+ }
68
+ };
69
+
70
+ exports.builder = yargs => {
71
+ yargs.option('account', {
72
+ describe: i18n(`${i18nKey}.options.account.describe`),
73
+ type: 'string',
74
+ });
75
+ yargs.example([
76
+ ['$0 accounts remove', i18n(`${i18nKey}.examples.default`)],
77
+ [
78
+ '$0 accounts remove --account=MyAccount',
79
+ i18n(`${i18nKey}.examples.byName`),
80
+ ],
81
+ ]);
82
+
83
+ return yargs;
84
+ };
@@ -4,6 +4,7 @@ const list = require('./accounts/list');
4
4
  const rename = require('./accounts/rename');
5
5
  const use = require('./accounts/use');
6
6
  const info = require('./accounts/info');
7
+ const remove = require('./accounts/remove');
7
8
 
8
9
  const i18nKey = 'cli.commands.accounts';
9
10
 
@@ -22,6 +23,7 @@ exports.builder = yargs => {
22
23
  .command(rename)
23
24
  .command(use)
24
25
  .command(info)
26
+ .command(remove)
25
27
  .demandCommand(1, '');
26
28
 
27
29
  return yargs;
@@ -108,7 +108,6 @@ exports.handler = async options => {
108
108
  );
109
109
  } else {
110
110
  logApiErrorInstance(
111
- accountId,
112
111
  e,
113
112
  new ApiErrorContext({ accountId, request: functionPath })
114
113
  );
@@ -36,7 +36,7 @@ exports.handler = async options => {
36
36
  logger.debug(i18n(`${i18nKey}.debug.gettingFunctions`));
37
37
 
38
38
  const routesResp = await getRoutes(accountId).catch(async e => {
39
- await logApiErrorInstance(accountId, e, new ApiErrorContext({ accountId }));
39
+ await logApiErrorInstance(e, new ApiErrorContext({ accountId }));
40
40
  process.exit(EXIT_CODES.SUCCESS);
41
41
  });
42
42
 
package/commands/list.js CHANGED
@@ -48,11 +48,7 @@ exports.handler = async options => {
48
48
  try {
49
49
  contentsResp = await getDirectoryContentsByPath(accountId, directoryPath);
50
50
  } catch (e) {
51
- logApiErrorInstance(
52
- accountId,
53
- e,
54
- new ApiErrorContext({ accountId, directoryPath })
55
- );
51
+ logApiErrorInstance(e, new ApiErrorContext({ accountId, directoryPath }));
56
52
  process.exit(EXIT_CODES.SUCCESS);
57
53
  }
58
54
 
@@ -5,156 +5,70 @@ const {
5
5
  addUseEnvironmentOptions,
6
6
  addTestingOptions,
7
7
  } = require('../../lib/commonOpts');
8
- const { trackCommandUsage } = require('../../lib/usageTracking');
9
- const { logger } = require('@hubspot/cli-lib/logger');
10
- const Spinnies = require('spinnies');
11
- const { createSandbox } = require('@hubspot/cli-lib/sandboxes');
12
8
  const { loadAndValidateOptions } = require('../../lib/validation');
13
- const { createSandboxPrompt } = require('../../lib/prompts/sandboxesPrompt');
14
- const {
15
- getSandboxType,
16
- sandboxCreatePersonalAccessKeyFlow,
17
- } = require('../../lib/sandboxes');
18
9
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
19
- const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers');
20
- const {
21
- debugErrorAndContext,
22
- } = require('@hubspot/cli-lib/errorHandlers/standardErrors');
23
- const { ENVIRONMENTS } = require('@hubspot/cli-lib/lib/constants');
24
10
  const { EXIT_CODES } = require('../../lib/enums/exitCodes');
25
- const { getAccountConfig } = require('@hubspot/cli-lib');
26
- const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
27
- const {
28
- isMissingScopeError,
29
- isSpecifiedError,
30
- } = require('@hubspot/cli-lib/errorHandlers/apiErrors');
11
+ const { getAccountConfig, getEnv } = require('@hubspot/cli-lib');
12
+ const { buildSandbox } = require('../../lib/sandbox-create');
13
+ const { uiFeatureHighlight } = require('../../lib/ui');
14
+ const { sandboxTypeMap, DEVELOPER_SANDBOX } = require('../../lib/sandboxes');
15
+ const { getValidEnv } = require('@hubspot/cli-lib/lib/environment');
31
16
 
32
17
  const i18nKey = 'cli.commands.sandbox.subcommands.create';
33
18
 
34
- exports.command = 'create [--name]';
19
+ exports.command = 'create [--name] [--type]';
35
20
  exports.describe = i18n(`${i18nKey}.describe`);
36
21
 
37
22
  exports.handler = async options => {
38
23
  await loadAndValidateOptions(options);
39
24
 
40
- const { name } = options;
25
+ const { name, type, force } = options;
41
26
  const accountId = getAccountId(options);
42
27
  const accountConfig = getAccountConfig(accountId);
43
- const env = options.qa ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD;
44
- const spinnies = new Spinnies({
45
- succeedColor: 'white',
46
- });
47
-
48
- trackCommandUsage('sandbox-create', null, accountId);
49
-
50
- if (
51
- accountConfig.sandboxAccountType &&
52
- accountConfig.sandboxAccountType !== null
53
- ) {
54
- trackCommandUsage('sandbox-create', { successful: false }, accountId);
55
-
56
- logger.error(
57
- i18n(`${i18nKey}.failure.creatingWithinSandbox`, {
58
- sandboxType: getSandboxType(accountConfig.sandboxAccountType),
59
- })
60
- );
61
-
62
- process.exit(EXIT_CODES.ERROR);
63
- }
64
-
65
- let namePrompt;
66
-
67
- logger.log(i18n(`${i18nKey}.sandboxLimitation`));
68
- logger.log('');
69
-
70
- if (!name) {
71
- namePrompt = await createSandboxPrompt();
72
- }
73
-
74
- const sandboxName = name || namePrompt.name;
75
-
76
- let result;
28
+ const env = getValidEnv(getEnv(accountId));
77
29
 
78
30
  try {
79
- spinnies.add('sandboxCreate', {
80
- text: i18n(`${i18nKey}.loading.add`, {
81
- sandboxName,
82
- }),
83
- });
84
-
85
- result = await createSandbox(accountId, sandboxName);
86
-
87
- logger.log('');
88
- spinnies.succeed('sandboxCreate', {
89
- text: i18n(`${i18nKey}.loading.succeed`, {
90
- name: result.name,
91
- sandboxHubId: result.sandboxHubId,
92
- }),
93
- });
94
- } catch (err) {
95
- debugErrorAndContext(err);
96
-
97
- trackCommandUsage('sandbox-create', { successful: false }, accountId);
98
-
99
- spinnies.fail('sandboxCreate', {
100
- text: i18n(`${i18nKey}.loading.fail`, {
101
- sandboxName,
102
- }),
31
+ const { result } = await buildSandbox({
32
+ name,
33
+ type,
34
+ accountConfig,
35
+ env,
36
+ force,
103
37
  });
104
38
 
105
- if (isMissingScopeError(err)) {
106
- logger.error(
107
- i18n(`${i18nKey}.failure.scopes.message`, {
108
- accountName: accountConfig.name || accountId,
109
- })
110
- );
111
- const websiteOrigin = getHubSpotWebsiteOrigin(env);
112
- const url = `${websiteOrigin}/personal-access-key/${accountId}`;
113
- logger.info(
114
- i18n(`${i18nKey}.failure.scopes.instructions`, {
115
- accountName: accountConfig.name || accountId,
116
- url,
117
- })
118
- );
119
- } else if (
120
- isSpecifiedError(
121
- err,
122
- 400,
123
- 'VALIDATION_ERROR',
124
- 'SandboxErrors.NUM_DEVELOPMENT_SANDBOXES_LIMIT_EXCEEDED_ERROR'
125
- ) &&
126
- err.error &&
127
- err.error.message
128
- ) {
129
- logger.log('');
130
- logger.error(err.error.message);
131
- } else {
132
- logErrorInstance(err);
133
- }
134
- process.exit(EXIT_CODES.ERROR);
135
- }
136
- try {
137
- await sandboxCreatePersonalAccessKeyFlow(
138
- env,
139
- result.sandboxHubId,
140
- result.name
141
- );
39
+ const sandboxType = sandboxTypeMap[result.sandbox.type];
40
+ uiFeatureHighlight([
41
+ // 'projectDevCommand',
42
+ 'projectUploadCommand',
43
+ sandboxType === DEVELOPER_SANDBOX
44
+ ? 'sandboxSyncDevelopmentCommand'
45
+ : 'sandboxSyncStandardCommand',
46
+ ]);
142
47
  process.exit(EXIT_CODES.SUCCESS);
143
- } catch (err) {
144
- logErrorInstance(err);
48
+ } catch (error) {
49
+ // Errors are logged in buildSandbox
145
50
  process.exit(EXIT_CODES.ERROR);
146
51
  }
147
52
  };
148
53
 
149
54
  exports.builder = yargs => {
55
+ yargs.option('f', {
56
+ type: 'boolean',
57
+ alias: 'force',
58
+ describe: i18n(`${i18nKey}.examples.force`),
59
+ });
150
60
  yargs.option('name', {
151
61
  describe: i18n(`${i18nKey}.options.name.describe`),
152
62
  type: 'string',
153
63
  });
64
+ yargs.option('type', {
65
+ describe: i18n(`${i18nKey}.options.type.describe`),
66
+ type: 'string',
67
+ });
154
68
 
155
69
  yargs.example([
156
70
  [
157
- '$0 sandbox create --name=MySandboxAccount',
71
+ '$0 sandbox create --name=MySandboxAccount --type=STANDARD',
158
72
  i18n(`${i18nKey}.examples.default`),
159
73
  ],
160
74
  ]);
@@ -14,7 +14,7 @@ const {
14
14
  const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers');
15
15
  const { deleteSandbox } = require('@hubspot/cli-lib/sandboxes');
16
16
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
17
- const { getConfig, getEnv } = require('@hubspot/cli-lib');
17
+ const { getConfig, getEnv, getAccountConfig } = require('@hubspot/cli-lib');
18
18
  const { deleteSandboxPrompt } = require('../../lib/prompts/sandboxesPrompt');
19
19
  const {
20
20
  removeSandboxAccountFromConfig,
@@ -26,10 +26,12 @@ const {
26
26
  const { EXIT_CODES } = require('../../lib/enums/exitCodes');
27
27
  const { promptUser } = require('../../lib/prompts/promptUtils');
28
28
  const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
29
- const { ENVIRONMENTS } = require('@hubspot/cli-lib/lib/constants');
30
29
  const {
31
30
  isSpecifiedError,
32
31
  } = require('@hubspot/cli-lib/errorHandlers/apiErrors');
32
+ const { HubSpotAuthError } = require('@hubspot/cli-lib/lib/models/Errors');
33
+ const { getAccountName } = require('../../lib/sandboxes');
34
+ const { getValidEnv } = require('@hubspot/cli-lib/lib/environment');
33
35
 
34
36
  const i18nKey = 'cli.commands.sandbox.subcommands.delete';
35
37
 
@@ -62,14 +64,14 @@ exports.handler = async options => {
62
64
  const sandboxAccountId = getAccountId({
63
65
  account: account || accountPrompt.account,
64
66
  });
65
-
67
+ const accountConfig = getAccountConfig(sandboxAccountId);
66
68
  const isDefaultAccount =
67
69
  sandboxAccountId === getAccountId(config.defaultPortal);
68
70
 
69
71
  trackCommandUsage('sandbox-delete', null, sandboxAccountId);
70
72
 
71
73
  const baseUrl = getHubSpotWebsiteOrigin(
72
- getEnv(sandboxAccountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD
74
+ getValidEnv(getEnv(sandboxAccountId))
73
75
  );
74
76
 
75
77
  let parentAccountId;
@@ -89,12 +91,13 @@ exports.handler = async options => {
89
91
  }
90
92
  }
91
93
 
94
+ const parentAccount = getAccountConfig(parentAccountId);
92
95
  const url = `${baseUrl}/sandboxes/${parentAccountId}`;
93
96
  const command = `hs auth ${
94
97
  getEnv(sandboxAccountId) === 'qa' ? '--qa' : ''
95
98
  } --account=${parentAccountId}`;
96
99
 
97
- if (!getAccountId({ account: parentAccountId })) {
100
+ if (parentAccountId && !getAccountId({ account: parentAccountId })) {
98
101
  logger.log('');
99
102
  logger.error(
100
103
  i18n(`${i18nKey}.failure.noParentPortalAvailable`, {
@@ -109,16 +112,17 @@ exports.handler = async options => {
109
112
 
110
113
  logger.debug(
111
114
  i18n(`${i18nKey}.debug.deleting`, {
112
- account: account || accountPrompt.account,
115
+ account: getAccountName(accountConfig),
113
116
  })
114
117
  );
115
118
 
116
119
  if (isDefaultAccount) {
117
- logger.log(
120
+ logger.info(
118
121
  i18n(`${i18nKey}.defaultAccountWarning`, {
119
- account: account || accountPrompt.account,
122
+ account: getAccountName(accountConfig),
120
123
  })
121
124
  );
125
+ logger.log('');
122
126
  }
123
127
 
124
128
  try {
@@ -128,7 +132,7 @@ exports.handler = async options => {
128
132
  name: 'confirmSandboxDeletePrompt',
129
133
  type: 'confirm',
130
134
  message: i18n(`${i18nKey}.confirm`, {
131
- account: account || accountPrompt.account,
135
+ account: getAccountName(accountConfig),
132
136
  }),
133
137
  },
134
138
  ]);
@@ -170,7 +174,20 @@ exports.handler = async options => {
170
174
  sandboxAccountId
171
175
  );
172
176
 
173
- if (
177
+ if (err instanceof HubSpotAuthError) {
178
+ // Intercept invalid key error
179
+ // This command uses the parent portal PAK to delete a sandbox, so we must specify which account needs a new key
180
+ const regex = /\bYour personal access key is invalid\b/;
181
+ const match = err.message.match(regex);
182
+ if (match && match[0]) {
183
+ logger.log('');
184
+ logger.error(
185
+ i18n(`${i18nKey}.failure.invalidKey`, {
186
+ account: getAccountName(parentAccount),
187
+ })
188
+ );
189
+ }
190
+ } else if (
174
191
  isSpecifiedError(
175
192
  err,
176
193
  404,
@@ -181,7 +198,7 @@ exports.handler = async options => {
181
198
  logger.log('');
182
199
  logger.warn(
183
200
  i18n(`${i18nKey}.failure.objectNotFound`, {
184
- account: account || accountPrompt.account,
201
+ account: getAccountName(accountConfig),
185
202
  })
186
203
  );
187
204
  logger.log('');