@hubspot/cli 4.1.8-beta.0 → 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,
@@ -5,183 +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
- getHasDevelopmentSandboxes,
18
- getDevSandboxLimit,
19
- } = require('../../lib/sandboxes');
20
9
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
21
- const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers');
22
- const {
23
- debugErrorAndContext,
24
- } = require('@hubspot/cli-lib/errorHandlers/standardErrors');
25
- const { ENVIRONMENTS } = require('@hubspot/cli-lib/lib/constants');
26
10
  const { EXIT_CODES } = require('../../lib/enums/exitCodes');
27
11
  const { getAccountConfig, getEnv } = require('@hubspot/cli-lib');
28
- const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
29
- const {
30
- isMissingScopeError,
31
- isSpecifiedError,
32
- } = require('@hubspot/cli-lib/errorHandlers/apiErrors');
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');
33
16
 
34
17
  const i18nKey = 'cli.commands.sandbox.subcommands.create';
35
18
 
36
- exports.command = 'create [--name]';
19
+ exports.command = 'create [--name] [--type]';
37
20
  exports.describe = i18n(`${i18nKey}.describe`);
38
21
 
39
22
  exports.handler = async options => {
40
23
  await loadAndValidateOptions(options);
41
24
 
42
- const { name } = options;
25
+ const { name, type, force } = options;
43
26
  const accountId = getAccountId(options);
44
27
  const accountConfig = getAccountConfig(accountId);
45
- const env = options.qa ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD;
46
- const spinnies = new Spinnies({
47
- succeedColor: 'white',
48
- });
49
-
50
- trackCommandUsage('sandbox-create', null, accountId);
51
-
52
- if (
53
- accountConfig.sandboxAccountType &&
54
- accountConfig.sandboxAccountType !== null
55
- ) {
56
- trackCommandUsage('sandbox-create', { successful: false }, accountId);
57
-
58
- logger.error(
59
- i18n(`${i18nKey}.failure.creatingWithinSandbox`, {
60
- sandboxType: getSandboxType(accountConfig.sandboxAccountType),
61
- })
62
- );
63
-
64
- process.exit(EXIT_CODES.ERROR);
65
- }
66
-
67
- let namePrompt;
68
-
69
- logger.log(i18n(`${i18nKey}.sandboxLimitation`));
70
- logger.log('');
71
-
72
- if (!name) {
73
- namePrompt = await createSandboxPrompt();
74
- }
75
-
76
- const sandboxName = name || namePrompt.name;
77
-
78
- let result;
28
+ const env = getValidEnv(getEnv(accountId));
79
29
 
80
30
  try {
81
- spinnies.add('sandboxCreate', {
82
- text: i18n(`${i18nKey}.loading.add`, {
83
- sandboxName,
84
- }),
85
- });
86
-
87
- result = await createSandbox(accountId, sandboxName);
88
-
89
- logger.log('');
90
- spinnies.succeed('sandboxCreate', {
91
- text: i18n(`${i18nKey}.loading.succeed`, {
92
- name: result.name,
93
- sandboxHubId: result.sandboxHubId,
94
- }),
95
- });
96
- } catch (err) {
97
- debugErrorAndContext(err);
98
-
99
- trackCommandUsage('sandbox-create', { successful: false }, accountId);
100
-
101
- spinnies.fail('sandboxCreate', {
102
- text: i18n(`${i18nKey}.loading.fail`, {
103
- sandboxName,
104
- }),
31
+ const { result } = await buildSandbox({
32
+ name,
33
+ type,
34
+ accountConfig,
35
+ env,
36
+ force,
105
37
  });
106
38
 
107
- if (isMissingScopeError(err)) {
108
- logger.error(
109
- i18n(`${i18nKey}.failure.scopes.message`, {
110
- accountName: accountConfig.name || accountId,
111
- })
112
- );
113
- const websiteOrigin = getHubSpotWebsiteOrigin(env);
114
- const url = `${websiteOrigin}/personal-access-key/${accountId}`;
115
- logger.info(
116
- i18n(`${i18nKey}.failure.scopes.instructions`, {
117
- accountName: accountConfig.name || accountId,
118
- url,
119
- })
120
- );
121
- } else if (
122
- isSpecifiedError(
123
- err,
124
- 400,
125
- 'VALIDATION_ERROR',
126
- 'SandboxErrors.NUM_DEVELOPMENT_SANDBOXES_LIMIT_EXCEEDED_ERROR'
127
- ) &&
128
- err.error &&
129
- err.error.message
130
- ) {
131
- logger.log('');
132
- const devSandboxLimit = getDevSandboxLimit(err.error);
133
- const plural = devSandboxLimit !== 1;
134
- const hasDevelopmentSandboxes = getHasDevelopmentSandboxes(accountConfig);
135
- if (hasDevelopmentSandboxes) {
136
- logger.error(
137
- i18n(
138
- `${i18nKey}.failure.alreadyInConfig.${plural ? 'other' : 'one'}`,
139
- {
140
- accountName: accountConfig.name || accountId,
141
- limit: devSandboxLimit,
142
- }
143
- )
144
- );
145
- } else {
146
- const baseUrl = getHubSpotWebsiteOrigin(
147
- getEnv(accountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD
148
- );
149
- logger.error(
150
- i18n(`${i18nKey}.failure.limit.${plural ? 'other' : 'one'}`, {
151
- accountName: accountConfig.name || accountId,
152
- limit: devSandboxLimit,
153
- devSandboxesLink: `${baseUrl}/sandboxes-developer/${accountId}/development`,
154
- })
155
- );
156
- }
157
- logger.log('');
158
- } else {
159
- logErrorInstance(err);
160
- }
161
- process.exit(EXIT_CODES.ERROR);
162
- }
163
- try {
164
- await sandboxCreatePersonalAccessKeyFlow(
165
- env,
166
- result.sandboxHubId,
167
- result.name
168
- );
39
+ const sandboxType = sandboxTypeMap[result.sandbox.type];
40
+ uiFeatureHighlight([
41
+ // 'projectDevCommand',
42
+ 'projectUploadCommand',
43
+ sandboxType === DEVELOPER_SANDBOX
44
+ ? 'sandboxSyncDevelopmentCommand'
45
+ : 'sandboxSyncStandardCommand',
46
+ ]);
169
47
  process.exit(EXIT_CODES.SUCCESS);
170
- } catch (err) {
171
- logErrorInstance(err);
48
+ } catch (error) {
49
+ // Errors are logged in buildSandbox
172
50
  process.exit(EXIT_CODES.ERROR);
173
51
  }
174
52
  };
175
53
 
176
54
  exports.builder = yargs => {
55
+ yargs.option('f', {
56
+ type: 'boolean',
57
+ alias: 'force',
58
+ describe: i18n(`${i18nKey}.examples.force`),
59
+ });
177
60
  yargs.option('name', {
178
61
  describe: i18n(`${i18nKey}.options.name.describe`),
179
62
  type: 'string',
180
63
  });
64
+ yargs.option('type', {
65
+ describe: i18n(`${i18nKey}.options.type.describe`),
66
+ type: 'string',
67
+ });
181
68
 
182
69
  yargs.example([
183
70
  [
184
- '$0 sandbox create --name=MySandboxAccount',
71
+ '$0 sandbox create --name=MySandboxAccount --type=STANDARD',
185
72
  i18n(`${i18nKey}.examples.default`),
186
73
  ],
187
74
  ]);
@@ -26,12 +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');
33
32
  const { HubSpotAuthError } = require('@hubspot/cli-lib/lib/models/Errors');
34
33
  const { getAccountName } = require('../../lib/sandboxes');
34
+ const { getValidEnv } = require('@hubspot/cli-lib/lib/environment');
35
35
 
36
36
  const i18nKey = 'cli.commands.sandbox.subcommands.delete';
37
37
 
@@ -71,7 +71,7 @@ exports.handler = async options => {
71
71
  trackCommandUsage('sandbox-delete', null, sandboxAccountId);
72
72
 
73
73
  const baseUrl = getHubSpotWebsiteOrigin(
74
- getEnv(sandboxAccountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD
74
+ getValidEnv(getEnv(sandboxAccountId))
75
75
  );
76
76
 
77
77
  let parentAccountId;
@@ -117,11 +117,12 @@ exports.handler = async options => {
117
117
  );
118
118
 
119
119
  if (isDefaultAccount) {
120
- logger.log(
120
+ logger.info(
121
121
  i18n(`${i18nKey}.defaultAccountWarning`, {
122
122
  account: getAccountName(accountConfig),
123
123
  })
124
124
  );
125
+ logger.log('');
125
126
  }
126
127
 
127
128
  try {
@@ -7,12 +7,8 @@ const {
7
7
  } = require('../../lib/commonOpts');
8
8
  const { trackCommandUsage } = require('../../lib/usageTracking');
9
9
  const { logger } = require('@hubspot/cli-lib/logger');
10
- const Spinnies = require('spinnies');
11
- const { initiateSync } = require('@hubspot/cli-lib/sandboxes');
12
10
  const { loadAndValidateOptions } = require('../../lib/validation');
13
11
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
14
- const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers');
15
- const { ENVIRONMENTS } = require('@hubspot/cli-lib/lib/constants');
16
12
  const { EXIT_CODES } = require('../../lib/enums/exitCodes');
17
13
  const { getAccountConfig, getEnv } = require('@hubspot/cli-lib');
18
14
  const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
@@ -20,13 +16,12 @@ const { promptUser } = require('../../lib/prompts/promptUtils');
20
16
  const { uiLine } = require('../../lib/ui');
21
17
  const {
22
18
  getAccountName,
23
- getAvailableSyncTypes,
24
- pollSyncTaskStatus,
19
+ sandboxTypeMap,
20
+ DEVELOPER_SANDBOX,
21
+ STANDARD_SANDBOX,
25
22
  } = require('../../lib/sandboxes');
26
- const {
27
- isMissingScopeError,
28
- isSpecifiedError,
29
- } = require('@hubspot/cli-lib/errorHandlers/apiErrors');
23
+ const { syncSandbox } = require('../../lib/sandbox-sync');
24
+ const { getValidEnv } = require('@hubspot/cli-lib/lib/environment');
30
25
 
31
26
  const i18nKey = 'cli.commands.sandbox.subcommands.sync';
32
27
 
@@ -39,9 +34,7 @@ exports.handler = async options => {
39
34
  const { force } = options; // For scripting purposes
40
35
  const accountId = getAccountId(options);
41
36
  const accountConfig = getAccountConfig(accountId);
42
- const spinnies = new Spinnies({
43
- succeedColor: 'white',
44
- });
37
+ const env = getValidEnv(getEnv(accountId));
45
38
 
46
39
  trackCommandUsage('sandbox-sync', null, accountId);
47
40
 
@@ -51,10 +44,8 @@ exports.handler = async options => {
51
44
  accountConfig.sandboxAccountType === undefined ||
52
45
  accountConfig.sandboxAccountType === null
53
46
  ) {
54
- trackCommandUsage('sandbox-sync', { successful: false }, accountId);
55
-
56
47
  logger.error(i18n(`${i18nKey}.failure.notSandbox`));
57
-
48
+ trackCommandUsage('sandbox-sync', { successful: false }, accountId);
58
49
  process.exit(EXIT_CODES.ERROR);
59
50
  }
60
51
 
@@ -67,12 +58,15 @@ exports.handler = async options => {
67
58
  sandboxName: getAccountName(accountConfig),
68
59
  })
69
60
  );
61
+ trackCommandUsage('sandbox-sync', { successful: false }, accountId);
70
62
  process.exit(EXIT_CODES.ERROR);
71
63
  }
72
64
 
73
65
  const parentAccountConfig = getAccountConfig(parentAccountId);
74
- const isDevelopmentSandbox = accountConfig.sandboxAccountType === 'DEVELOPER';
75
- const isStandardSandbox = accountConfig.sandboxAccountType === 'STANDARD';
66
+ const isDevelopmentSandbox =
67
+ sandboxTypeMap[accountConfig.sandboxAccountType] === DEVELOPER_SANDBOX;
68
+ const isStandardSandbox =
69
+ sandboxTypeMap[accountConfig.sandboxAccountType] === STANDARD_SANDBOX;
76
70
 
77
71
  if (isDevelopmentSandbox) {
78
72
  logger.log(i18n(`${i18nKey}.info.developmentSandbox`));
@@ -100,12 +94,13 @@ exports.handler = async options => {
100
94
  },
101
95
  ]);
102
96
  if (!confirmed) {
97
+ trackCommandUsage('sandbox-sync', { successful: false }, accountId);
103
98
  process.exit(EXIT_CODES.SUCCESS);
104
99
  }
105
100
  }
106
101
  } else if (isStandardSandbox) {
107
102
  const standardSyncUrl = `${getHubSpotWebsiteOrigin(
108
- getEnv(accountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD
103
+ env
109
104
  )}/sandboxes-developer/${parentAccountId}/sync?step=select_sync_path&id=${parentAccountId}_${accountId}`;
110
105
 
111
106
  logger.log(
@@ -137,147 +132,26 @@ exports.handler = async options => {
137
132
  },
138
133
  ]);
139
134
  if (!confirmed) {
135
+ trackCommandUsage('sandbox-sync', { successful: false }, accountId);
140
136
  process.exit(EXIT_CODES.SUCCESS);
141
137
  }
142
138
  }
143
139
  } else {
144
140
  logger.error('Sync must be run in a sandbox account.');
145
- process.exit(EXIT_CODES.ERROR);
146
- }
147
-
148
- let initiateSyncResponse;
149
-
150
- const baseUrl = getHubSpotWebsiteOrigin(
151
- getEnv(accountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD
152
- );
153
- const syncStatusUrl = `${baseUrl}/sandboxes-developer/${parentAccountId}/${
154
- isDevelopmentSandbox ? 'development' : 'standard'
155
- }`;
156
-
157
- try {
158
- logger.log('');
159
- spinnies.add('sandboxSync', {
160
- text: i18n(`${i18nKey}.loading.startSync`),
161
- });
162
-
163
- // Fetches sync types based on default account. Parent account required for fetch
164
- const tasks = await getAvailableSyncTypes(
165
- parentAccountConfig,
166
- accountConfig
167
- );
168
-
169
- initiateSyncResponse = await initiateSync(
170
- parentAccountId,
171
- accountId,
172
- tasks,
173
- accountId
174
- );
175
-
176
- logger.log(i18n(`${i18nKey}.info.earlyExit`));
177
- logger.log('');
178
- spinnies.succeed('sandboxSync', {
179
- text: i18n(`${i18nKey}.loading.succeed`),
180
- });
181
- } catch (err) {
182
141
  trackCommandUsage('sandbox-sync', { successful: false }, accountId);
183
-
184
- spinnies.fail('sandboxSync', {
185
- text: i18n(`${i18nKey}.loading.fail`),
186
- });
187
-
188
- logger.log('');
189
- if (isMissingScopeError(err)) {
190
- logger.error(
191
- i18n(`${i18nKey}.failure.missingScopes`, {
192
- accountName: getAccountName(parentAccountConfig),
193
- })
194
- );
195
- } else if (
196
- isSpecifiedError(
197
- err,
198
- 429,
199
- 'RATE_LIMITS',
200
- 'sandboxes-sync-api.SYNC_IN_PROGRESS'
201
- )
202
- ) {
203
- logger.error(
204
- i18n(`${i18nKey}.failure.syncInProgress`, {
205
- url: `${baseUrl}/sandboxes-developer/${parentAccountId}/syncactivitylog`,
206
- })
207
- );
208
- } else if (
209
- isSpecifiedError(
210
- err,
211
- 403,
212
- 'BANNED',
213
- 'sandboxes-sync-api.SYNC_NOT_ALLOWED_INVALID_USERID'
214
- )
215
- ) {
216
- // This will only trigger if a user is not a super admin of the target account.
217
- logger.error(
218
- i18n(`${i18nKey}.failure.notSuperAdmin`, {
219
- account: getAccountName(accountConfig),
220
- })
221
- );
222
- } else if (
223
- isSpecifiedError(
224
- err,
225
- 404,
226
- 'OBJECT_NOT_FOUND',
227
- 'SandboxErrors.SANDBOX_NOT_FOUND'
228
- )
229
- ) {
230
- logger.error(
231
- i18n(`${i18nKey}.failure.objectNotFound`, {
232
- account: getAccountName(accountConfig),
233
- })
234
- );
235
- } else {
236
- logErrorInstance(err);
237
- }
238
- logger.log('');
239
-
240
142
  process.exit(EXIT_CODES.ERROR);
241
143
  }
242
144
 
243
145
  try {
244
- logger.log('');
245
- logger.log('Sync progress:');
246
- // Poll sync task status to show progress bars
247
- await pollSyncTaskStatus(
248
- parentAccountId,
249
- initiateSyncResponse.id,
250
- syncStatusUrl
251
- );
252
-
253
- logger.log('');
254
- spinnies.add('syncComplete', {
255
- text: i18n(`${i18nKey}.polling.syncing`),
256
- });
257
- spinnies.succeed('syncComplete', {
258
- text: i18n(`${i18nKey}.polling.succeed`),
146
+ await syncSandbox({
147
+ accountConfig,
148
+ parentAccountConfig,
149
+ env,
150
+ allowEarlyTermination: true,
259
151
  });
260
- logger.log('');
261
- logger.log(
262
- i18n(`${i18nKey}.info.syncStatus`, {
263
- url: syncStatusUrl,
264
- })
265
- );
266
-
267
152
  process.exit(EXIT_CODES.SUCCESS);
268
- } catch (err) {
269
- // If polling fails at this point, we do not track a failed sync since it is running in the background.
270
- logErrorInstance(err);
271
-
272
- spinnies.add('syncComplete', {
273
- text: i18n(`${i18nKey}.polling.syncing`),
274
- });
275
- spinnies.fail('syncComplete', {
276
- text: i18n(`${i18nKey}.polling.fail`, {
277
- url: syncStatusUrl,
278
- }),
279
- });
280
-
153
+ } catch (error) {
154
+ trackCommandUsage('sandbox-sync', { successful: false }, accountId);
281
155
  process.exit(EXIT_CODES.ERROR);
282
156
  }
283
157
  };
@@ -0,0 +1,66 @@
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();
@@ -1,12 +1,14 @@
1
1
  const { updateDefaultAccount } = require('@hubspot/cli-lib/lib/config');
2
2
  const { promptUser } = require('./promptUtils');
3
3
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
4
- const { getSandboxType } = require('../sandboxes');
4
+ const { getSandboxTypeAsString } = require('../sandboxes');
5
5
 
6
6
  const mapAccountChoices = portals =>
7
7
  portals.map(p => {
8
8
  const isSandbox = p.sandboxAccountType && p.sandboxAccountType !== null;
9
- const sandboxName = `[${getSandboxType(p.sandboxAccountType)} sandbox] `;
9
+ const sandboxName = `[${getSandboxTypeAsString(
10
+ p.sandboxAccountType
11
+ )} sandbox] `;
10
12
  return {
11
13
  name: `${p.name} ${isSandbox ? sandboxName : ''}(${p.portalId})`,
12
14
  value: p.name || p.portalId,
@@ -1,6 +1,7 @@
1
1
  const { promptUser } = require('./promptUtils');
2
2
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
3
- const { getSandboxType } = require('../sandboxes');
3
+ const { getSandboxTypeAsString } = require('../sandboxes');
4
+ const { accountNameExistsInConfig } = require('@hubspot/cli-lib/lib/config');
4
5
 
5
6
  const i18nKey = 'cli.lib.prompts.sandboxesPrompt';
6
7
 
@@ -8,7 +9,9 @@ const mapSandboxAccountChoices = portals =>
8
9
  portals
9
10
  .filter(p => p.sandboxAccountType && p.sandboxAccountType !== null)
10
11
  .map(p => {
11
- const sandboxName = `[${getSandboxType(p.sandboxAccountType)} sandbox] `;
12
+ const sandboxName = `[${getSandboxTypeAsString(
13
+ p.sandboxAccountType
14
+ )} sandbox] `;
12
15
  return {
13
16
  name: `${p.name} ${sandboxName}(${p.portalId})`,
14
17
  value: p.name || p.portalId,
@@ -27,22 +30,50 @@ const mapNonSandboxAccountChoices = portals =>
27
30
  };
28
31
  });
29
32
 
30
- const createSandboxPrompt = () => {
33
+ const sandboxNamePrompt = () => {
31
34
  return promptUser([
32
35
  {
33
36
  name: 'name',
34
- message: i18n(`${i18nKey}.enterName`),
37
+ message: i18n(`${i18nKey}.name.message`),
35
38
  validate(val) {
36
39
  if (typeof val !== 'string') {
37
- return i18n(`${i18nKey}.errors.invalidName`);
40
+ return i18n(`${i18nKey}.name.errors.invalidName`);
41
+ } else if (!val.length) {
42
+ return i18n(`${i18nKey}.name.errors.nameRequired`);
38
43
  }
39
- return true;
44
+ return accountNameExistsInConfig(val)
45
+ ? i18n(`${i18nKey}.name.errors.accountNameExists`, { name: val })
46
+ : true;
40
47
  },
41
48
  default: 'New sandbox',
42
49
  },
43
50
  ]);
44
51
  };
45
52
 
53
+ const sandboxTypeChoices = [
54
+ {
55
+ name: i18n(`${i18nKey}.type.developer`),
56
+ value: 'DEVELOPER',
57
+ },
58
+ {
59
+ name: i18n(`${i18nKey}.type.standard`),
60
+ value: 'STANDARD',
61
+ },
62
+ ];
63
+
64
+ const sandboxTypePrompt = () => {
65
+ return promptUser([
66
+ {
67
+ name: 'type',
68
+ message: i18n(`${i18nKey}.type.message`),
69
+ type: 'list',
70
+ look: false,
71
+ choices: sandboxTypeChoices,
72
+ default: 'DEVELOPER',
73
+ },
74
+ ]);
75
+ };
76
+
46
77
  const deleteSandboxPrompt = (config, promptParentAccount = false) => {
47
78
  const choices = promptParentAccount
48
79
  ? mapNonSandboxAccountChoices(config.portals)
@@ -55,8 +86,8 @@ const deleteSandboxPrompt = (config, promptParentAccount = false) => {
55
86
  name: 'account',
56
87
  message: i18n(
57
88
  promptParentAccount
58
- ? `${i18nKey}.selectParentAccountName`
59
- : `${i18nKey}.selectAccountName`
89
+ ? `${i18nKey}.name.selectParentAccountName`
90
+ : `${i18nKey}.name.selectAccountName`
60
91
  ),
61
92
  type: 'list',
62
93
  look: false,
@@ -68,7 +99,7 @@ const deleteSandboxPrompt = (config, promptParentAccount = false) => {
68
99
  };
69
100
 
70
101
  module.exports = {
71
- createSandboxPrompt,
102
+ sandboxNamePrompt,
103
+ sandboxTypePrompt,
72
104
  deleteSandboxPrompt,
73
- getSandboxType,
74
105
  };