@hubspot/cli 5.2.1-beta.1 → 5.2.1-beta.2

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/init.js CHANGED
@@ -62,7 +62,7 @@ const personalAccessKeyConfigCreationFlow = async (env, account) => {
62
62
 
63
63
  try {
64
64
  const token = await getAccessToken(personalAccessKey, env);
65
- const defaultName = toKebabCase(token.hubName);
65
+ const defaultName = token.hubName ? toKebabCase(token.hubName) : null;
66
66
  const { name } = await enterAccountNamePrompt(defaultName);
67
67
 
68
68
  updatedConfig = updateConfigWithAccessToken(
@@ -42,10 +42,12 @@ const {
42
42
  confirmDefaultAccountIsTarget,
43
43
  suggestRecommendedNestedAccount,
44
44
  checkIfAppDeveloperAccount,
45
+ checkIfDeveloperTestAccount,
45
46
  createSandboxForLocalDev,
46
47
  createDeveloperTestAccountForLocalDev,
47
48
  createNewProjectForLocalDev,
48
49
  createInitialBuildForNewProject,
50
+ useExistingDevTestAccount,
49
51
  } = require('../../lib/localDev');
50
52
 
51
53
  const i18nKey = 'cli.commands.project.subcommands.dev';
@@ -91,7 +93,13 @@ exports.handler = async options => {
91
93
  // The account that the project must exist in
92
94
  let targetProjectAccountId = options.account ? accountId : null;
93
95
  // The account that we are locally testing against
94
- let targetTestingAccountId = targetProjectAccountId;
96
+ let targetTestingAccountId = options.account ? accountId : null;
97
+
98
+ if (options.account && hasPublicApps) {
99
+ checkIfDeveloperTestAccount(accountConfig);
100
+ targetProjectAccountId = accountConfig.parentAccountId;
101
+ targetTestingAccountId = accountId;
102
+ }
95
103
 
96
104
  let createNewSandbox = false;
97
105
  let createNewDeveloperTestAccount = false;
@@ -101,6 +109,7 @@ exports.handler = async options => {
101
109
  targetProjectAccountId = hasPublicApps
102
110
  ? accountConfig.parentAccountId
103
111
  : accountId;
112
+ targetTestingAccountId = accountId;
104
113
  } else if (!targetProjectAccountId && hasPublicApps) {
105
114
  checkIfAppDeveloperAccount(accountConfig);
106
115
  }
@@ -110,6 +119,7 @@ exports.handler = async options => {
110
119
  targetAccountId,
111
120
  parentAccountId,
112
121
  createNestedAccount,
122
+ notInConfigAccount,
113
123
  } = await suggestRecommendedNestedAccount(
114
124
  accounts,
115
125
  accountConfig,
@@ -119,6 +129,11 @@ exports.handler = async options => {
119
129
  targetProjectAccountId = hasPublicApps ? parentAccountId : targetAccountId;
120
130
  targetTestingAccountId = targetAccountId;
121
131
 
132
+ // Only used for developer test accounts that are not yet in the config
133
+ if (notInConfigAccount) {
134
+ await useExistingDevTestAccount(env, notInConfigAccount);
135
+ }
136
+
122
137
  createNewSandbox = isStandardAccount(accountConfig) && createNestedAccount;
123
138
  createNewDeveloperTestAccount =
124
139
  isAppDeveloperAccount(accountConfig) && createNestedAccount;
@@ -139,6 +154,7 @@ exports.handler = async options => {
139
154
  accountConfig,
140
155
  env
141
156
  );
157
+ targetProjectAccountId = accountId;
142
158
  }
143
159
 
144
160
  const projectExists = await ensureProjectExists(
@@ -171,7 +187,8 @@ exports.handler = async options => {
171
187
  await createNewProjectForLocalDev(
172
188
  projectConfig,
173
189
  targetProjectAccountId,
174
- createNewSandbox
190
+ createNewSandbox,
191
+ hasPublicApps
175
192
  );
176
193
 
177
194
  deployedBuild = await createInitialBuildForNewProject(
@@ -12,19 +12,28 @@ const { preview } = require('@hubspot/theme-preview-dev-server');
12
12
  const { getUploadableFileList } = require('../../lib/upload');
13
13
  const { trackCommandUsage } = require('../../lib/usageTracking');
14
14
  const { loadAndValidateOptions } = require('../../lib/validation');
15
- const { previewPrompt } = require('../../lib/prompts/previewPrompt');
15
+ const {
16
+ previewPrompt,
17
+ previewProjectPrompt,
18
+ } = require('../../lib/prompts/previewPrompt');
16
19
  const { EXIT_CODES } = require('../../lib/enums/exitCodes');
17
20
  const {
18
21
  FILE_UPLOAD_RESULT_TYPES,
19
22
  } = require('@hubspot/local-dev-lib/constants/files');
20
- const i18nKey = 'cli.commands.preview';
21
23
  const cliProgress = require('cli-progress');
22
24
  const {
23
25
  ApiErrorContext,
24
26
  logApiUploadErrorInstance,
25
27
  } = require('../../lib/errorHandlers/apiErrors');
26
28
  const { handleExit, handleKeypress } = require('../../lib/process');
29
+ const { getThemeJSONPath } = require('@hubspot/local-dev-lib/cms/themes');
30
+ const { getProjectConfig } = require('../../lib/projects');
31
+ const {
32
+ findProjectComponents,
33
+ COMPONENT_TYPES,
34
+ } = require('../../lib/projectStructure');
27
35
 
36
+ const i18nKey = 'cli.commands.preview';
28
37
  exports.command = 'preview [--src] [--dest]';
29
38
  exports.describe = false; // i18n(`${i18nKey}.describe`) - Hiding command
30
39
 
@@ -63,6 +72,42 @@ const handleUserInput = () => {
63
72
  });
64
73
  };
65
74
 
75
+ const determineSrcAndDest = async options => {
76
+ let absoluteSrc;
77
+ let dest;
78
+ const { projectDir, projectConfig } = await getProjectConfig();
79
+ if (!(projectDir && projectConfig)) {
80
+ // Not in a project, prompt for src and dest of traditional theme
81
+ const previewPromptAnswers = await previewPrompt(options);
82
+ const src = options.src || previewPromptAnswers.src;
83
+ dest = options.dest || previewPromptAnswers.dest;
84
+ absoluteSrc = path.resolve(getCwd(), src);
85
+ if (!dest || !validateSrcPath(absoluteSrc)) {
86
+ process.exit(EXIT_CODES.ERROR);
87
+ }
88
+ } else {
89
+ // In a project
90
+ let themeJsonPath = getThemeJSONPath();
91
+ if (!themeJsonPath) {
92
+ const projectComponents = await findProjectComponents(projectDir);
93
+ const themeComponents = projectComponents.filter(
94
+ c => c.type === COMPONENT_TYPES.hublTheme
95
+ );
96
+ if (themeComponents.length === 0) {
97
+ logger.error(i18n(`${i18nKey}.errors.noThemeComponents`));
98
+ process.exit(EXIT_CODES.ERROR);
99
+ }
100
+ const answer = await previewProjectPrompt(themeComponents);
101
+ themeJsonPath = `${answer.themeComponentPath}/theme.json`;
102
+ }
103
+ const { dir: themeDir } = path.parse(themeJsonPath);
104
+ absoluteSrc = themeDir;
105
+ const { base: themeName } = path.parse(themeDir);
106
+ dest = `@projects/${projectConfig.name}/${themeName}`;
107
+ }
108
+ return { absoluteSrc, dest };
109
+ };
110
+
66
111
  exports.handler = async options => {
67
112
  const { notify, skipUpload, noSsl, port, debug } = options;
68
113
 
@@ -70,18 +115,7 @@ exports.handler = async options => {
70
115
 
71
116
  const accountId = getAccountId(options);
72
117
 
73
- const previewPromptAnswers = await previewPrompt(options);
74
- const src = options.src || previewPromptAnswers.src;
75
- let dest = options.dest || previewPromptAnswers.dest;
76
- if (!dest) {
77
- logger.error(i18n(`${i18nKey}.errors.destinationRequired`));
78
- return;
79
- }
80
-
81
- const absoluteSrc = path.resolve(getCwd(), src);
82
- if (!validateSrcPath(absoluteSrc)) {
83
- process.exit(EXIT_CODES.ERROR);
84
- }
118
+ const { absoluteSrc, dest } = await determineSrcAndDest(options);
85
119
 
86
120
  const filePaths = await getUploadableFileList(absoluteSrc, false);
87
121
 
package/lang/en.lyaml CHANGED
@@ -882,6 +882,7 @@ en:
882
882
  describe: "Upload and watch a theme directory on your computer for changes and start a local development server to preview theme changes on a site"
883
883
  errors:
884
884
  invalidPath: "The path \"{{ path }}\" is not a path to a directory"
885
+ noThemeComponents: "Your project has no theme components available to preview."
885
886
  options:
886
887
  src:
887
888
  describe: "Path to the local directory your theme is in, relative to your current working directory"
@@ -944,14 +945,15 @@ en:
944
945
  localDev:
945
946
  confirmDefaultAccountIsTarget:
946
947
  declineDefaultAccountExplanation: "To develop on a different account, run {{ useCommand }} to change your default account, then re-run {{ devCommand }}."
947
- checkCorrectParentAccountType:
948
- standardAccountNotSupported: "This project contains a public app. Local development of public apps is only supported on developer accounts and developer test accounts. Change your default account using {{#bold}}`hs accounts use`{{/bold}}, or link a new account with {{#bold}}`hs auth`{{/bold}}."
948
+ checkIfAppDevloperAccount: "This project contains a public app. Local development of public apps is only supported on developer accounts and developer test accounts. Change your default account using {{#bold}}`hs accounts use`{{/bold}}, or link a new account with {{#bold}}`hs auth`{{/bold}}."
949
+ checkIfDeveloperTestAccount: "This project contains a public app. The \"--account\" flag must point to a developer test account to develop this project locally. Alternatively, change your default account to an App Developer Account using {{#bold}}`hs accounts use`{{/bold}} and run {{#bold}}`hs project dev`{{/bold}} to set up a new Developer Test Account."
949
950
  suggestRecommendedNestedAccount:
950
951
  nonSandboxWarning: "Testing in a sandbox is strongly recommended. To switch the target account, select an option below or run {{#bold}}`hs accounts use`{{/bold}} before running the command again."
951
952
  publicAppNonDeveloperTestAccountWarning: "Local development of public apps is only supported in {{#bold}}developer test accounts{{/bold}}."
952
953
  privateAppNonDeveloperTestAccountWarning: "Local development of private apps is only supported in {{#bold}}developer test accounts{{/bold}}"
953
954
  createNewProjectForLocalDev:
954
955
  projectMustExistExplanation: "The project {{ projectName }} does not exist in the target account {{ accountIdentifier}}. This command requires the project to exist in the target account."
956
+ publicAppProjectMustExistExplanation: "The project {{ projectName }} does not exist in {{ accountIdentifier}}, the app developer account associated with your target account. This command requires the project to exist in this app developer account."
955
957
  createProject: "Create new project {{ projectName}} in {{#bold}}[{{ accountIdentifier }}]{{/bold}}?"
956
958
  choseNotToCreateProject: "Exiting because this command requires the project to exist in the target account."
957
959
  creatingProject: "Creating project {{ projectName }} in {{ accountIdentifier }}"
@@ -1080,6 +1082,7 @@ en:
1080
1082
  sandboxLimitWithSuggestion: "Your account reached the limit of {{ limit }} development sandboxes. Run {{ authCommand }} to add an existing one to the config."
1081
1083
  developerTestAccountLimit: "Your account reached the limit of {{ limit }} developer test accounts."
1082
1084
  confirmDefaultAccount: "Continue testing on {{#bold}}{{ accountName }} ({{ accountType }}){{/bold}}? (Y/n)"
1085
+ confirmUseExistingDeveloperTestAccount: "Continue with {{ accountName }}? This account isn't currently connected to the HubSpot CLI. By continuing, you'll be prompted to generate a personal access key and connect it."
1083
1086
  projectLogsPrompt:
1084
1087
  projectName:
1085
1088
  message: "[--project] Enter the project name:"
@@ -1222,6 +1225,7 @@ en:
1222
1225
  previewPrompt:
1223
1226
  enterSrc: "[--src] Enter a local theme directory to preview."
1224
1227
  enterDest: "[--dest] Enter the destination path for the src theme in HubSpot Design Tools."
1228
+ themeProjectSelect: "[--theme] Select which theme to preview."
1225
1229
  errors:
1226
1230
  srcRequired: "You must specify a source directory."
1227
1231
  destRequired: "You must specify a destination directory."
@@ -1241,7 +1245,7 @@ en:
1241
1245
  fail: "Failed to create a developer test account {{#bold}}{{ accountName }}{{/bold}}."
1242
1246
  succeed: "Successfully created a developer test account {{#bold}}{{ name }}{{/bold}} with portalId {{#bold}}{{ accountId }}{{/bold}}."
1243
1247
  success:
1244
- configFileUpdated: "{{ configFilename }} updated with {{ authMethod }} for account {{ account }}."
1248
+ configFileUpdated: "Account \"{{ accountName }}\" updated using \"{{ authType }}\""
1245
1249
  failure:
1246
1250
  invalidUser: "Couldn't create {{#bold}}{{ accountName }}{{/bold}} because your account has been removed from {{#bold}}{{ parentAccountName }}{{/bold}} or your permission set doesn't allow you to create the sandbox. To update your permissions, contact a super admin in {{#bold}}{{ parentAccountName }}{{/bold}}."
1247
1251
  limit: "{{#bold}}{{ accountName }}{{/bold}} reached the limit of {{ limit }} developer test accounts.
@@ -1264,8 +1268,6 @@ en:
1264
1268
  add: "Creating standard sandbox {{#bold}}{{ sandboxName }}{{/bold}}"
1265
1269
  fail: "Failed to create a standard sandbox {{#bold}}{{ sandboxName }}{{/bold}}."
1266
1270
  succeed: "Successfully created a standard sandbox {{#bold}}{{ name }}{{/bold}} with portalId {{#bold}}{{ sandboxHubId }}{{/bold}}."
1267
- success:
1268
- configFileUpdated: "{{ configFilename }} updated with {{ authMethod }} for account {{ account }}."
1269
1271
  failure:
1270
1272
  invalidUser: "Couldn't create {{#bold}}{{ accountName }}{{/bold}} because your account has been removed from {{#bold}}{{ parentAccountName }}{{/bold}} or your permission set doesn't allow you to create the sandbox. To update your permissions, contact a super admin in {{#bold}}{{ parentAccountName }}{{/bold}}."
1271
1273
  403Gating: "Couldn't create {{#bold}}{{ accountName }}{{/bold}} because {{#bold}}{{ parentAccountName }}{{/bold}} does not have access to development sandboxes. To opt in to the CRM Development Beta and use development sandboxes, visit https://app.hubspot.com/l/product-updates/in-beta?update=13899236."
@@ -183,4 +183,5 @@ const buildDeveloperTestAccount = async ({
183
183
 
184
184
  module.exports = {
185
185
  buildDeveloperTestAccount,
186
+ saveDevTestAccountToConfig,
186
187
  };
package/lib/localDev.js CHANGED
@@ -15,6 +15,7 @@ const {
15
15
  confirmDefaultAccountPrompt,
16
16
  selectSandboxTargetAccountPrompt,
17
17
  selectDeveloperTestTargetAccountPrompt,
18
+ confirmUseExistingDeveloperTestAccountPrompt,
18
19
  } = require('./prompts/projectDevTargetAccountPrompt');
19
20
  const { sandboxNamePrompt } = require('./prompts/sandboxesPrompt');
20
21
  const {
@@ -31,7 +32,10 @@ const { syncSandbox } = require('./sandboxSync');
31
32
  const {
32
33
  validateDevTestAccountUsageLimits,
33
34
  } = require('./developerTestAccounts');
34
- const { buildDeveloperTestAccount } = require('./developerTestAccountCreate');
35
+ const {
36
+ buildDeveloperTestAccount,
37
+ saveDevTestAccountToConfig,
38
+ } = require('./developerTestAccountCreate');
35
39
  const { logErrorInstance } = require('./errorHandlers/standardErrors');
36
40
  const { uiCommandReference, uiLine, uiAccountDescription } = require('./ui');
37
41
  const SpinniesManager = require('./ui/SpinniesManager');
@@ -55,6 +59,9 @@ const {
55
59
  logApiErrorInstance,
56
60
  ApiErrorContext,
57
61
  } = require('./errorHandlers/apiErrors');
62
+ const {
63
+ PERSONAL_ACCESS_KEY_AUTH_METHOD,
64
+ } = require('@hubspot/local-dev-lib/constants/auth');
58
65
 
59
66
  const i18nKey = 'cli.lib.localDev';
60
67
 
@@ -86,11 +93,15 @@ const confirmDefaultAccountIsTarget = async accountConfig => {
86
93
  // Confirm the default account is a developer account if developing public apps
87
94
  const checkIfAppDeveloperAccount = accountConfig => {
88
95
  if (!isAppDeveloperAccount(accountConfig)) {
89
- logger.error(
90
- i18n(
91
- `${i18nKey}.checkCorrectParentAccountType.standardAccountNotSupported`
92
- )
93
- );
96
+ logger.error(i18n(`${i18nKey}.checkIfAppDevloperAccount`));
97
+ process.exit(EXIT_CODES.SUCCESS);
98
+ }
99
+ };
100
+
101
+ // Confirm the default account is a developer account if developing public apps
102
+ const checkIfDeveloperTestAccount = accountConfig => {
103
+ if (!isDeveloperTestAccount(accountConfig)) {
104
+ logger.error(i18n(`${i18nKey}.checkIfDeveloperTestAccount`));
94
105
  process.exit(EXIT_CODES.SUCCESS);
95
106
  }
96
107
  };
@@ -262,27 +273,57 @@ const createDeveloperTestAccountForLocalDev = async (
262
273
  }
263
274
  };
264
275
 
276
+ // Prompt user to confirm usage of an existing developer test account that is not currently in the config
277
+ const useExistingDevTestAccount = async (env, account) => {
278
+ const useExistingDevTestAcct = await confirmUseExistingDeveloperTestAccountPrompt(
279
+ account
280
+ );
281
+ if (!useExistingDevTestAcct) {
282
+ logger.log('');
283
+ logger.log(
284
+ i18n(
285
+ `${i18nKey}.confirmDefaultAccountIsTarget.declineDefaultAccountExplanation`,
286
+ {
287
+ useCommand: uiCommandReference('hs accounts use'),
288
+ devCommand: uiCommandReference('hs project dev'),
289
+ }
290
+ )
291
+ );
292
+ logger.log('');
293
+ process.exit(EXIT_CODES.SUCCESS);
294
+ }
295
+ const devTestAcctConfigName = await saveDevTestAccountToConfig(env, account);
296
+ logger.success(
297
+ i18n(`cli.lib.developerTestAccount.create.success.configFileUpdated`, {
298
+ accountName: devTestAcctConfigName,
299
+ authType: PERSONAL_ACCESS_KEY_AUTH_METHOD.name,
300
+ })
301
+ );
302
+ };
303
+
265
304
  // Prompt the user to create a new project if one doesn't exist on their target account
266
305
  const createNewProjectForLocalDev = async (
267
306
  projectConfig,
268
307
  targetAccountId,
269
- shouldCreateWithoutConfirmation
308
+ shouldCreateWithoutConfirmation,
309
+ hasPublicApps
270
310
  ) => {
271
311
  // Create the project without prompting if this is a newly created sandbox
272
312
  let shouldCreateProject = shouldCreateWithoutConfirmation;
273
313
 
274
314
  if (!shouldCreateProject) {
315
+ const explanationString = i18n(
316
+ hasPublicApps
317
+ ? `${i18nKey}.createNewProjectForLocalDev.publicAppProjectMustExistExplanation`
318
+ : `${i18nKey}.createNewProjectForLocalDev.projectMustExistExplanation`,
319
+ {
320
+ accountIdentifier: uiAccountDescription(targetAccountId),
321
+ projectName: projectConfig.name,
322
+ }
323
+ );
275
324
  logger.log();
276
325
  uiLine();
277
- logger.warn(
278
- i18n(
279
- `${i18nKey}.createNewProjectForLocalDev.projectMustExistExplanation`,
280
- {
281
- accountIdentifier: uiAccountDescription(targetAccountId),
282
- projectName: projectConfig.name,
283
- }
284
- )
285
- );
326
+ logger.warn(explanationString);
286
327
  uiLine();
287
328
 
288
329
  shouldCreateProject = await confirmPrompt(
@@ -393,9 +434,11 @@ const createInitialBuildForNewProject = async (
393
434
  module.exports = {
394
435
  confirmDefaultAccountIsTarget,
395
436
  checkIfAppDeveloperAccount,
437
+ checkIfDeveloperTestAccount,
396
438
  suggestRecommendedNestedAccount,
397
439
  createSandboxForLocalDev,
398
440
  createDeveloperTestAccountForLocalDev,
441
+ useExistingDevTestAccount,
399
442
  createNewProjectForLocalDev,
400
443
  createInitialBuildForNewProject,
401
444
  };
@@ -7,11 +7,13 @@ const { logErrorInstance } = require('./errorHandlers/standardErrors');
7
7
  const COMPONENT_TYPES = Object.freeze({
8
8
  privateApp: 'private-app',
9
9
  publicApp: 'public-app',
10
+ hublTheme: 'hubl-theme',
10
11
  });
11
12
 
12
13
  const CONFIG_FILES = {
13
14
  [COMPONENT_TYPES.privateApp]: 'app.json',
14
15
  [COMPONENT_TYPES.publicApp]: 'public-app.json',
16
+ [COMPONENT_TYPES.hublTheme]: 'theme.json',
15
17
  };
16
18
 
17
19
  function getTypeFromConfigFile(configFile) {
@@ -102,13 +104,14 @@ async function findProjectComponents(projectSourceDir) {
102
104
  if (Object.values(CONFIG_FILES).includes(base)) {
103
105
  const parsedAppConfig = loadConfigFile(projectFile);
104
106
 
105
- if (parsedAppConfig && parsedAppConfig.name) {
107
+ if (parsedAppConfig) {
106
108
  const isLegacy = getIsLegacyApp(parsedAppConfig, dir);
109
+ const isHublTheme = base === CONFIG_FILES[COMPONENT_TYPES.hublTheme];
107
110
 
108
111
  components.push({
109
112
  type: getTypeFromConfigFile(base),
110
113
  config: parsedAppConfig,
111
- runnable: !isLegacy,
114
+ runnable: !isLegacy && !isHublTheme,
112
115
  path: dir,
113
116
  });
114
117
  }
@@ -34,6 +34,24 @@ const previewPrompt = (promptOptions = {}) => {
34
34
  ]);
35
35
  };
36
36
 
37
+ const previewProjectPrompt = async themeComponents => {
38
+ return promptUser([
39
+ {
40
+ name: 'themeComponentPath',
41
+ message: i18n(`${i18nKey}.themeProjectSelect`),
42
+ type: 'list',
43
+ choices: themeComponents.map(t => {
44
+ const themeName = path.basename(t.path);
45
+ return {
46
+ name: themeName,
47
+ value: t.path,
48
+ };
49
+ }),
50
+ },
51
+ ]);
52
+ };
53
+
37
54
  module.exports = {
38
55
  previewPrompt,
56
+ previewProjectPrompt,
39
57
  };
@@ -24,6 +24,12 @@ const mapNestedAccount = accountConfig => ({
24
24
  },
25
25
  });
26
26
 
27
+ const getNonConfigDeveloperTestAccountName = account => {
28
+ return `${account.accountName} [${
29
+ HUBSPOT_ACCOUNT_TYPE_STRINGS[HUBSPOT_ACCOUNT_TYPES.DEVELOPER_TEST]
30
+ }] (${account.id})`;
31
+ };
32
+
27
33
  const selectSandboxTargetAccountPrompt = async (
28
34
  accounts,
29
35
  defaultAccountConfig
@@ -94,9 +100,11 @@ const selectDeveloperTestTargetAccountPrompt = async (
94
100
  ) => {
95
101
  const defaultAccountId = getAccountId(defaultAccountConfig.name);
96
102
  let choices = [];
97
- let devTestAccountUsage = undefined;
103
+ let devTestAccountsResponse = undefined;
98
104
  try {
99
- devTestAccountUsage = await fetchDeveloperTestAccounts(defaultAccountId);
105
+ devTestAccountsResponse = await fetchDeveloperTestAccounts(
106
+ defaultAccountId
107
+ );
100
108
  } catch (err) {
101
109
  logger.debug('Unable to fetch developer test account usage limits: ', err);
102
110
  }
@@ -110,17 +118,37 @@ const selectDeveloperTestTargetAccountPrompt = async (
110
118
  );
111
119
  let disabledMessage = false;
112
120
  if (
113
- devTestAccountUsage &&
114
- devTestAccountUsage.results.length >= devTestAccountUsage.maxTestPortals
121
+ devTestAccountsResponse &&
122
+ devTestAccountsResponse.results.length >=
123
+ devTestAccountsResponse.maxTestPortals
115
124
  ) {
116
125
  disabledMessage = i18n(`${i18nKey}.developerTestAccountLimit`, {
117
126
  authCommand: uiCommandReference('hs auth'),
118
- limit: devTestAccountUsage.maxTestPortals,
127
+ limit: devTestAccountsResponse.maxTestPortals,
128
+ });
129
+ }
130
+
131
+ let devTestAccountsNotInConfig = [];
132
+ if (devTestAccountsResponse && devTestAccountsResponse.results) {
133
+ const inConfigIds = devTestAccounts.map(d => d.portalId);
134
+ devTestAccountsResponse.results.forEach(acct => {
135
+ if (inConfigIds.indexOf(acct.id) < 0) {
136
+ devTestAccountsNotInConfig.push({
137
+ name: getNonConfigDeveloperTestAccountName(acct),
138
+ value: {
139
+ targetAccountId: acct.id,
140
+ createdNestedAccount: false,
141
+ parentAccountId: defaultAccountId,
142
+ notInConfigAccount: acct,
143
+ },
144
+ });
145
+ }
119
146
  });
120
147
  }
121
148
 
122
149
  choices = [
123
150
  ...devTestAccounts.map(mapNestedAccount),
151
+ ...devTestAccountsNotInConfig,
124
152
  {
125
153
  name: i18n(`${i18nKey}.createNewDeveloperTestAccountOption`),
126
154
  value: {
@@ -172,8 +200,22 @@ const confirmDefaultAccountPrompt = async (accountName, accountType) => {
172
200
  return useDefaultAccount;
173
201
  };
174
202
 
203
+ const confirmUseExistingDeveloperTestAccountPrompt = async account => {
204
+ const { confirmUseExistingDeveloperTestAccount } = await promptUser([
205
+ {
206
+ name: 'confirmUseExistingDeveloperTestAccount',
207
+ type: 'confirm',
208
+ message: i18n(`${i18nKey}.confirmUseExistingDeveloperTestAccount`, {
209
+ accountName: getNonConfigDeveloperTestAccountName(account),
210
+ }),
211
+ },
212
+ ]);
213
+ return confirmUseExistingDeveloperTestAccount;
214
+ };
215
+
175
216
  module.exports = {
176
217
  selectSandboxTargetAccountPrompt,
177
218
  selectDeveloperTestTargetAccountPrompt,
178
219
  confirmDefaultAccountPrompt,
220
+ confirmUseExistingDeveloperTestAccountPrompt,
179
221
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "5.2.1-beta.1",
3
+ "version": "5.2.1-beta.2",
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": "^0.3.15",
12
- "@hubspot/serverless-dev-runtime": "5.2.1-beta.1",
11
+ "@hubspot/local-dev-lib": "1.0.1",
12
+ "@hubspot/serverless-dev-runtime": "5.2.1-beta.2",
13
13
  "@hubspot/theme-preview-dev-server": "0.0.4",
14
14
  "@hubspot/ui-extensions-dev-server": "0.8.12",
15
15
  "archiver": "^5.3.0",
@@ -45,5 +45,5 @@
45
45
  "publishConfig": {
46
46
  "access": "public"
47
47
  },
48
- "gitHead": "201cb501441677860b93c2721f88d2811b5a0276"
48
+ "gitHead": "eeed6c79043020a0be2552fd0b5271866f8d73f9"
49
49
  }