@hubspot/cli 7.6.0-beta.1 → 7.6.0-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.
Files changed (57) hide show
  1. package/bin/hs +1 -1
  2. package/commands/account/auth.js +3 -3
  3. package/commands/auth.js +23 -25
  4. package/commands/getStarted.js +55 -8
  5. package/commands/init.js +29 -31
  6. package/commands/project/cloneApp.js +4 -4
  7. package/commands/project/create.js +9 -9
  8. package/commands/project/dev/deprecatedFlow.js +4 -4
  9. package/commands/project/dev/index.js +5 -5
  10. package/commands/project/dev/unifiedFlow.js +8 -0
  11. package/commands/project/upload.d.ts +2 -2
  12. package/commands/project/upload.js +13 -2
  13. package/commands/sandbox/delete.js +5 -5
  14. package/commands/testAccount/create.d.ts +2 -2
  15. package/commands/testAccount/create.js +41 -3
  16. package/lang/en.d.ts +53 -38
  17. package/lang/en.js +50 -35
  18. package/lang/en.lyaml +2 -0
  19. package/lib/accountTypes.d.ts +1 -0
  20. package/lib/accountTypes.js +20 -9
  21. package/lib/app/migrate_legacy.js +2 -3
  22. package/lib/app/urls.d.ts +1 -1
  23. package/lib/commonOpts.d.ts +2 -0
  24. package/lib/commonOpts.js +21 -9
  25. package/lib/middleware/__test__/configMiddleware.test.js +2 -2
  26. package/lib/middleware/configMiddleware.js +10 -2
  27. package/lib/parsing.d.ts +1 -0
  28. package/lib/parsing.js +11 -0
  29. package/lib/polling.d.ts +1 -1
  30. package/lib/polling.js +11 -1
  31. package/lib/projects/add/v3AddComponent.js +4 -0
  32. package/lib/projects/create/index.d.ts +3 -2
  33. package/lib/projects/create/index.js +11 -5
  34. package/lib/projects/create/v3.d.ts +3 -3
  35. package/lib/projects/create/v3.js +2 -2
  36. package/lib/projects/localDev/AppDevModeInterface.js +1 -1
  37. package/lib/projects/localDev/LocalDevProcess.d.ts +3 -2
  38. package/lib/projects/localDev/LocalDevProcess.js +16 -12
  39. package/lib/projects/localDev/LocalDevState.d.ts +10 -5
  40. package/lib/projects/localDev/LocalDevState.js +18 -20
  41. package/lib/projects/localDev/LocalDevWatcher.js +1 -1
  42. package/lib/prompts/personalAccessKeyPrompt.js +2 -2
  43. package/lib/prompts/projectNameAndDestPrompt.d.ts +3 -0
  44. package/lib/prompts/projectNameAndDestPrompt.js +60 -0
  45. package/lib/prompts/selectProjectTemplatePrompt.d.ts +26 -0
  46. package/lib/prompts/{createProjectPrompt.js → selectProjectTemplatePrompt.js} +6 -55
  47. package/lib/ui/logger.d.ts +1 -0
  48. package/lib/ui/logger.js +1 -0
  49. package/lib/validation.d.ts +1 -1
  50. package/lib/validation.js +4 -4
  51. package/lib/yargsUtils.d.ts +1 -0
  52. package/lib/yargsUtils.js +3 -0
  53. package/mcp-server/tools/project/CreateProjectTool.d.ts +2 -2
  54. package/package.json +3 -3
  55. package/types/LocalDev.d.ts +1 -0
  56. package/types/Yargs.d.ts +5 -1
  57. package/lib/prompts/createProjectPrompt.d.ts +0 -28
package/bin/hs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- require('./silenceErrors')
3
+ require('./silenceErrors');
4
4
 
5
5
  require('./cli');
@@ -98,9 +98,9 @@ async function handleConfigMigration() {
98
98
  const describe = en_1.commands.account.subcommands.auth.describe;
99
99
  const command = 'auth';
100
100
  async function handler(args) {
101
- const { providedAccountId, disableTracking, personalAccessKey: providedPersonalAccessKey, } = args;
101
+ const { disableTracking, personalAccessKey: providedPersonalAccessKey, derivedAccountId, } = args;
102
102
  if (!disableTracking) {
103
- (0, usageTracking_1.trackCommandUsage)('account-auth', {}, providedAccountId);
103
+ (0, usageTracking_1.trackCommandUsage)('account-auth', {}, derivedAccountId);
104
104
  await (0, usageTracking_1.trackAuthAction)('account-auth', authType, TRACKING_STATUS.STARTED);
105
105
  }
106
106
  const configMigrationSuccess = await handleConfigMigration();
@@ -114,7 +114,7 @@ async function handler(args) {
114
114
  }
115
115
  (0, config_1.loadConfig)('');
116
116
  (0, process_1.handleExit)(config_1.deleteEmptyConfigFile);
117
- const updatedConfig = await updateConfigWithNewAccount(args.qa ? environments_1.ENVIRONMENTS.QA : environments_1.ENVIRONMENTS.PROD, configAlreadyExists, providedPersonalAccessKey, providedAccountId);
117
+ const updatedConfig = await updateConfigWithNewAccount(args.qa ? environments_1.ENVIRONMENTS.QA : environments_1.ENVIRONMENTS.PROD, configAlreadyExists, providedPersonalAccessKey, derivedAccountId);
118
118
  if (!updatedConfig) {
119
119
  if (!disableTracking) {
120
120
  await (0, usageTracking_1.trackAuthAction)('account-auth', authType, TRACKING_STATUS.ERROR);
package/commands/auth.js CHANGED
@@ -1,11 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const git_1 = require("../lib/ui/git");
4
- const logger_1 = require("@hubspot/local-dev-lib/logger");
5
4
  const auth_1 = require("@hubspot/local-dev-lib/constants/auth");
6
5
  const environments_1 = require("@hubspot/local-dev-lib/constants/environments");
7
6
  const config_1 = require("@hubspot/local-dev-lib/constants/config");
8
- const lang_1 = require("../lib/lang");
9
7
  const personalAccessKey_1 = require("@hubspot/local-dev-lib/personalAccessKey");
10
8
  const config_2 = require("@hubspot/local-dev-lib/config");
11
9
  const text_1 = require("@hubspot/local-dev-lib/text");
@@ -21,6 +19,8 @@ const exitCodes_1 = require("../lib/enums/exitCodes");
21
19
  const ui_1 = require("../lib/ui");
22
20
  const index_1 = require("../lib/errorHandlers/index");
23
21
  const en_1 = require("../lang/en");
22
+ const logger_1 = require("../lib/ui/logger");
23
+ const parsing_1 = require("../lib/parsing");
24
24
  const TRACKING_STATUS = {
25
25
  STARTED: 'started',
26
26
  ERROR: 'error',
@@ -32,9 +32,19 @@ const ALLOWED_AUTH_METHODS = [
32
32
  ];
33
33
  const SUPPORTED_AUTHENTICATION_PROTOCOLS_TEXT = (0, text_1.commaSeparatedValues)(ALLOWED_AUTH_METHODS);
34
34
  const command = 'auth';
35
- const describe = (0, lang_1.i18n)('commands.auth.describe');
35
+ const describe = en_1.commands.auth.describe;
36
36
  async function handler(args) {
37
- const { authType: authTypeFlagValue, config: configFlagValue, qa, providedAccountId, personalAccessKey: providedPersonalAccessKey, } = args;
37
+ const { authType: authTypeFlagValue, config: configFlagValue, qa, personalAccessKey: providedPersonalAccessKey, userProvidedAccount, } = args;
38
+ let parsedUserProvidedAccountId;
39
+ try {
40
+ if (userProvidedAccount) {
41
+ parsedUserProvidedAccountId = (0, parsing_1.parseStringToNumber)(userProvidedAccount);
42
+ }
43
+ }
44
+ catch (err) {
45
+ (0, index_1.logError)(en_1.commands.auth.errors.invalidAccountIdProvided);
46
+ process.exit(exitCodes_1.EXIT_CODES.ERROR);
47
+ }
38
48
  const authType = (authTypeFlagValue && authTypeFlagValue.toLowerCase()) ||
39
49
  auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value;
40
50
  (0, commonOpts_1.setLogLevel)(args);
@@ -46,13 +56,11 @@ async function handler(args) {
46
56
  (0, git_1.checkAndWarnGitInclusion)(configPath);
47
57
  }
48
58
  if ((0, config_2.configFileExists)(true)) {
49
- logger_1.logger.error((0, lang_1.i18n)(`commands.auth.errors.globalConfigFileExists`, {
50
- accountAuthCommand: (0, ui_1.uiCommandReference)('hs account auth'),
51
- }));
59
+ logger_1.uiLogger.error(en_1.commands.auth.errors.globalConfigFileExists('hs account auth'));
52
60
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
53
61
  }
54
62
  (0, usageTracking_1.trackCommandUsage)('auth');
55
- (0, usageTracking_1.trackAuthAction)('auth', authType, TRACKING_STATUS.STARTED, providedAccountId);
63
+ (0, usageTracking_1.trackAuthAction)('auth', authType, TRACKING_STATUS.STARTED, parsedUserProvidedAccountId);
56
64
  let configData;
57
65
  let updatedConfig;
58
66
  let validName;
@@ -73,7 +81,7 @@ async function handler(args) {
73
81
  ? { personalAccessKey: providedPersonalAccessKey }
74
82
  : await (0, personalAccessKeyPrompt_1.personalAccessKeyPrompt)({
75
83
  env,
76
- account: providedAccountId,
84
+ account: parsedUserProvidedAccountId,
77
85
  });
78
86
  try {
79
87
  token = await (0, personalAccessKey_1.getAccessToken)(personalAccessKey, env);
@@ -101,24 +109,17 @@ async function handler(args) {
101
109
  successAuthMethod = auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.name;
102
110
  break;
103
111
  default:
104
- logger_1.logger.error((0, lang_1.i18n)('commands.auth.errors.unsupportedAuthType', {
105
- supportedProtocols: SUPPORTED_AUTHENTICATION_PROTOCOLS_TEXT,
106
- type: authType,
107
- }));
112
+ logger_1.uiLogger.error(en_1.commands.auth.errors.unsupportedAuthType(authType, SUPPORTED_AUTHENTICATION_PROTOCOLS_TEXT));
108
113
  break;
109
114
  }
110
115
  if (!successAuthMethod) {
111
- await (0, usageTracking_1.trackAuthAction)('auth', authType, TRACKING_STATUS.ERROR, providedAccountId);
116
+ await (0, usageTracking_1.trackAuthAction)('auth', authType, TRACKING_STATUS.ERROR, parsedUserProvidedAccountId);
112
117
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
113
118
  }
114
119
  const nameFromConfigData = configData && 'name' in configData ? configData.name : undefined;
115
120
  const accountName = (updatedConfig && updatedConfig.name) || validName || nameFromConfigData;
116
121
  await (0, setAsDefaultAccountPrompt_1.setAsDefaultAccountPrompt)(accountName);
117
- logger_1.logger.success((0, lang_1.i18n)('commands.auth.success.configFileUpdated', {
118
- configFilename: config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME,
119
- authType: successAuthMethod,
120
- accountName,
121
- }));
122
+ logger_1.uiLogger.success(en_1.commands.auth.success.configFileUpdated(accountName, config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME, successAuthMethod));
122
123
  (0, ui_1.uiFeatureHighlight)([
123
124
  'accountsUseCommand',
124
125
  'accountOption',
@@ -131,7 +132,7 @@ async function handler(args) {
131
132
  function authBuilder(yargs) {
132
133
  yargs.options({
133
134
  'auth-type': {
134
- describe: (0, lang_1.i18n)('commands.auth.options.authType.describe'),
135
+ describe: en_1.commands.auth.options.authType.describe,
135
136
  type: 'string',
136
137
  choices: [
137
138
  `${auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value}`,
@@ -140,7 +141,7 @@ function authBuilder(yargs) {
140
141
  default: auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value,
141
142
  },
142
143
  account: {
143
- describe: (0, lang_1.i18n)('commands.auth.options.account.describe'),
144
+ describe: en_1.commands.auth.options.account.describe,
144
145
  type: 'string',
145
146
  alias: 'a',
146
147
  },
@@ -153,10 +154,7 @@ function authBuilder(yargs) {
153
154
  });
154
155
  return yargs;
155
156
  }
156
- const builder = (0, yargsUtils_1.makeYargsBuilder)(authBuilder, command, (0, lang_1.i18n)('commands.auth.verboseDescribe', {
157
- authMethod: auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value,
158
- configName: config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME,
159
- }), {
157
+ const builder = (0, yargsUtils_1.makeYargsBuilder)(authBuilder, command, en_1.commands.auth.verboseDescribe(auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value, config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME), {
160
158
  useGlobalOptions: true,
161
159
  useConfigOptions: true,
162
160
  useTestingOptions: true,
@@ -14,20 +14,25 @@ const usageTracking_1 = require("../lib/usageTracking");
14
14
  const exitCodes_1 = require("../lib/enums/exitCodes");
15
15
  const yargsUtils_1 = require("../lib/yargsUtils");
16
16
  const promptUtils_1 = require("../lib/prompts/promptUtils");
17
- const createProjectPrompt_1 = require("../lib/prompts/createProjectPrompt");
17
+ const projectNameAndDestPrompt_1 = require("../lib/prompts/projectNameAndDestPrompt");
18
18
  const ui_1 = require("../lib/ui");
19
19
  const logger_1 = require("../lib/ui/logger");
20
20
  const errorHandlers_1 = require("../lib/errorHandlers");
21
21
  const upload_1 = require("../lib/projects/upload");
22
22
  const constants_1 = require("../lib/constants");
23
23
  const config_1 = require("../lib/projects/config");
24
+ const dependencyManagement_1 = require("../lib/dependencyManagement");
24
25
  const buildAndDeploy_1 = require("../lib/projects/buildAndDeploy");
25
- const urls_1 = require("../lib/projects/urls");
26
26
  const links_1 = require("../lib/links");
27
+ const urls_1 = require("../lib/app/urls");
28
+ const config_2 = require("@hubspot/local-dev-lib/config");
29
+ const environments_1 = require("@hubspot/local-dev-lib/constants/environments");
30
+ const appsDev_1 = require("@hubspot/local-dev-lib/api/appsDev");
27
31
  exports.command = 'get-started';
28
32
  exports.describe = undefined;
29
33
  async function handler(args) {
30
34
  const { derivedAccountId } = args;
35
+ const env = (0, config_2.getEnv)(derivedAccountId) === 'qa' ? environments_1.ENVIRONMENTS.QA : environments_1.ENVIRONMENTS.PROD;
31
36
  // TODO: Put this in constants.ts once we have a defined place for the template before INBOUND
32
37
  const templateSource = 'robrown-hubspot/hubspot-project-components-ua-app-objects-beta';
33
38
  (0, usageTracking_1.trackCommandUsage)('get-started', {}, derivedAccountId);
@@ -73,10 +78,10 @@ async function handler(args) {
73
78
  }
74
79
  else {
75
80
  logger_1.uiLogger.log(' ');
76
- logger_1.uiLogger.log(en_1.commands.getStarted.prompts.appSelected);
81
+ logger_1.uiLogger.log(en_1.commands.getStarted.logs.appSelected);
77
82
  // 1. Fetch project templates
78
83
  let latestRepoReleaseTag;
79
- const { dest, name } = await (0, createProjectPrompt_1.createProjectPrompt)(args);
84
+ const { dest, name } = await (0, projectNameAndDestPrompt_1.projectNameAndDestPrompt)(args);
80
85
  // Specific template for get-started command
81
86
  const projectTemplate = {
82
87
  name: 'private-app-get-started-template',
@@ -122,7 +127,44 @@ async function handler(args) {
122
127
  logger_1.uiLogger.log(' ');
123
128
  logger_1.uiLogger.log(en_1.commands.getStarted.prompts.projectCreated.description);
124
129
  logger_1.uiLogger.log(' ');
125
- // 5. Ask user if they want to upload the project
130
+ // 5. Install dependencies - Ask user if they want to install dependencies
131
+ const { shouldInstallDependencies } = await (0, promptUtils_1.promptUser)([
132
+ {
133
+ type: 'confirm',
134
+ name: 'shouldInstallDependencies',
135
+ message: en_1.commands.getStarted.prompts.installDependencies,
136
+ default: true,
137
+ },
138
+ ]);
139
+ if (shouldInstallDependencies) {
140
+ try {
141
+ // Change to the project directory to install dependencies
142
+ const originalCwd = process.cwd();
143
+ process.chdir(projectDest);
144
+ try {
145
+ await (0, dependencyManagement_1.installPackages)({});
146
+ logger_1.uiLogger.log(' ');
147
+ logger_1.uiLogger.success(en_1.commands.getStarted.logs.dependenciesInstalled);
148
+ logger_1.uiLogger.log(' ');
149
+ }
150
+ finally {
151
+ // Always restore the original working directory
152
+ process.chdir(originalCwd);
153
+ }
154
+ }
155
+ catch (err) {
156
+ logger_1.uiLogger.log(' ');
157
+ logger_1.uiLogger.error(en_1.commands.getStarted.errors.installDepsFailed);
158
+ console.log(err);
159
+ logger_1.uiLogger.log(' ');
160
+ }
161
+ }
162
+ else {
163
+ logger_1.uiLogger.log(' ');
164
+ logger_1.uiLogger.log(en_1.commands.getStarted.logs.dependenciesNotInstalled);
165
+ logger_1.uiLogger.log(' ');
166
+ }
167
+ // 6. Ask user if they want to upload the project
126
168
  const { shouldUpload } = await (0, promptUtils_1.promptUser)([
127
169
  {
128
170
  type: 'confirm',
@@ -162,8 +204,9 @@ async function handler(args) {
162
204
  (0, errorHandlers_1.debugError)(uploadError);
163
205
  }
164
206
  else if (result) {
165
- logger_1.uiLogger.log(' ');
166
207
  logger_1.uiLogger.success(en_1.commands.getStarted.logs.uploadSuccess);
208
+ const { data: { results }, } = await (0, appsDev_1.fetchPublicAppsForPortal)(derivedAccountId);
209
+ const lastCreatedApp = results.sort((a, b) => b.createdAt - a.createdAt)[0];
167
210
  if (process.env.BROWSER !== 'none') {
168
211
  logger_1.uiLogger.log(' ');
169
212
  logger_1.uiLogger.log(en_1.commands.getStarted.developerOverviewBrowserOpenPrep);
@@ -172,11 +215,15 @@ async function handler(args) {
172
215
  {
173
216
  name: 'shouldOpenOverview',
174
217
  type: 'confirm',
175
- message: en_1.commands.getStarted.openDeveloperOverviewPrompt,
218
+ message: en_1.commands.getStarted.openInstallUrl,
176
219
  },
177
220
  ]);
178
221
  if (shouldOpenOverview) {
179
- (0, open_1.default)((0, urls_1.getProjectComponentDistributionUrl)(name, 'get_started_app', derivedAccountId), { url: true });
222
+ (0, open_1.default)((0, urls_1.getStaticAuthAppInstallUrl)({
223
+ targetAccountId: derivedAccountId,
224
+ env: env,
225
+ appId: lastCreatedApp.id,
226
+ }), { url: true });
180
227
  logger_1.uiLogger.log(' ');
181
228
  logger_1.uiLogger.success(en_1.commands.getStarted.openedDeveloperOverview);
182
229
  }
package/commands/init.js CHANGED
@@ -13,13 +13,11 @@ const personalAccessKey_1 = require("@hubspot/local-dev-lib/personalAccessKey");
13
13
  const path_2 = require("@hubspot/local-dev-lib/path");
14
14
  const text_1 = require("@hubspot/local-dev-lib/text");
15
15
  const environments_1 = require("@hubspot/local-dev-lib/constants/environments");
16
- const logger_1 = require("@hubspot/local-dev-lib/logger");
17
16
  const getAccountIdentifier_1 = require("@hubspot/local-dev-lib/config/getAccountIdentifier");
18
17
  const commonOpts_1 = require("../lib/commonOpts");
19
18
  const yargsUtils_1 = require("../lib/yargsUtils");
20
19
  const process_1 = require("../lib/process");
21
20
  const index_1 = require("../lib/errorHandlers/index");
22
- const lang_1 = require("../lib/lang");
23
21
  const usageTracking_1 = require("../lib/usageTracking");
24
22
  const promptUtils_1 = require("../lib/prompts/promptUtils");
25
23
  const personalAccessKeyPrompt_1 = require("../lib/prompts/personalAccessKeyPrompt");
@@ -27,6 +25,9 @@ const accountNamePrompt_1 = require("../lib/prompts/accountNamePrompt");
27
25
  const oauth_1 = require("../lib/oauth");
28
26
  const exitCodes_1 = require("../lib/enums/exitCodes");
29
27
  const ui_1 = require("../lib/ui");
28
+ const logger_1 = require("../lib/ui/logger");
29
+ const en_1 = require("../lang/en");
30
+ const parsing_1 = require("../lib/parsing");
30
31
  const TRACKING_STATUS = {
31
32
  STARTED: 'started',
32
33
  ERROR: 'error',
@@ -61,9 +62,19 @@ const AUTH_TYPE_NAMES = {
61
62
  [auth_1.OAUTH_AUTH_METHOD.value]: auth_1.OAUTH_AUTH_METHOD.name,
62
63
  };
63
64
  const command = 'init';
64
- const describe = (0, lang_1.i18n)(`commands.init.describe`);
65
+ const describe = en_1.commands.init.describe;
65
66
  async function handler(args) {
66
- const { authType: authTypeFlagValue, c: configFlagValue, providedAccountId, disableTracking, useHiddenConfig, } = args;
67
+ const { authType: authTypeFlagValue, c: configFlagValue, disableTracking, useHiddenConfig, userProvidedAccount, } = args;
68
+ let parsedUserProvidedAccountId;
69
+ try {
70
+ if (userProvidedAccount) {
71
+ parsedUserProvidedAccountId = (0, parsing_1.parseStringToNumber)(userProvidedAccount);
72
+ }
73
+ }
74
+ catch (err) {
75
+ logger_1.uiLogger.error(en_1.commands.init.errors.invalidAccountIdProvided);
76
+ process.exit(exitCodes_1.EXIT_CODES.ERROR);
77
+ }
67
78
  const authType = (authTypeFlagValue && authTypeFlagValue.toLowerCase()) ||
68
79
  auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value;
69
80
  const configPath = (configFlagValue && path_1.default.join((0, path_2.getCwd)(), configFlagValue)) ||
@@ -76,28 +87,24 @@ async function handler(args) {
76
87
  }
77
88
  const env = args.qa ? environments_1.ENVIRONMENTS.QA : environments_1.ENVIRONMENTS.PROD;
78
89
  if ((0, config_1.configFileExists)(true)) {
79
- logger_1.logger.error((0, lang_1.i18n)(`commands.init.errors.globalConfigFileExists`, {
80
- accountAuthCommand: (0, ui_1.uiCommandReference)('hs account auth'),
81
- }));
90
+ logger_1.uiLogger.error(en_1.commands.init.errors.globalConfigFileExists);
82
91
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
83
92
  }
84
93
  if (fs_extra_1.default.existsSync(configPath)) {
85
- logger_1.logger.error((0, lang_1.i18n)(`commands.init.errors.configFileExists`, {
86
- configPath: configPath,
87
- }));
88
- logger_1.logger.info((0, lang_1.i18n)(`commands.init.logs.updateConfig`));
94
+ logger_1.uiLogger.error(en_1.commands.init.errors.configFileExists(configPath));
95
+ logger_1.uiLogger.info(en_1.commands.init.logs.updateConfig);
89
96
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
90
97
  }
91
98
  if (!disableTracking) {
92
- await (0, usageTracking_1.trackAuthAction)('init', authType, TRACKING_STATUS.STARTED, providedAccountId);
99
+ await (0, usageTracking_1.trackAuthAction)('init', authType, TRACKING_STATUS.STARTED, parsedUserProvidedAccountId);
93
100
  }
94
101
  const doesOtherConfigFileExist = (0, config_1.configFileExists)(!useHiddenConfig);
95
102
  if (doesOtherConfigFileExist) {
96
103
  const path = (0, config_1.getConfigPath)('', !useHiddenConfig);
97
- logger_1.logger.error((0, lang_1.i18n)(`commands.init.errors.bothConfigFilesNotAllowed`, { path: path }));
104
+ logger_1.uiLogger.error(en_1.commands.init.errors.bothConfigFilesNotAllowed(path));
98
105
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
99
106
  }
100
- (0, usageTracking_1.trackAuthAction)('init', authType, TRACKING_STATUS.STARTED, providedAccountId);
107
+ (0, usageTracking_1.trackAuthAction)('init', authType, TRACKING_STATUS.STARTED, parsedUserProvidedAccountId);
101
108
  (0, config_1.createEmptyConfigFile)({ path: configPath }, useHiddenConfig);
102
109
  //Needed to load deprecated config
103
110
  (0, config_1.loadConfig)(configPath, args);
@@ -106,7 +113,7 @@ async function handler(args) {
106
113
  let accountId;
107
114
  let name;
108
115
  if (authType === auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value) {
109
- const personalAccessKeyResult = await personalAccessKeyConfigCreationFlow(env, providedAccountId);
116
+ const personalAccessKeyResult = await personalAccessKeyConfigCreationFlow(env, parsedUserProvidedAccountId);
110
117
  if (personalAccessKeyResult) {
111
118
  accountId = (0, getAccountIdentifier_1.getAccountIdentifier)(personalAccessKeyResult);
112
119
  name = personalAccessKeyResult.name;
@@ -124,14 +131,9 @@ async function handler(args) {
124
131
  catch (e) {
125
132
  (0, index_1.debugError)(e);
126
133
  }
127
- logger_1.logger.log('');
128
- logger_1.logger.success((0, lang_1.i18n)(`commands.init.success.configFileCreated`, {
129
- configPath: configPath,
130
- }));
131
- logger_1.logger.success((0, lang_1.i18n)(`commands.init.success.configFileUpdated`, {
132
- authType: AUTH_TYPE_NAMES[authType],
133
- account: name || accountId,
134
- }));
134
+ logger_1.uiLogger.log('');
135
+ logger_1.uiLogger.success(en_1.commands.init.success.configFileCreated(configPath));
136
+ logger_1.uiLogger.success(en_1.commands.init.success.configFileUpdated(AUTH_TYPE_NAMES[authType], name || accountId));
135
137
  (0, ui_1.uiFeatureHighlight)([
136
138
  'getStartedCommand',
137
139
  'helpCommand',
@@ -146,7 +148,7 @@ async function handler(args) {
146
148
  catch (err) {
147
149
  (0, index_1.logError)(err);
148
150
  if (!disableTracking) {
149
- await (0, usageTracking_1.trackAuthAction)('init', authType, TRACKING_STATUS.ERROR, providedAccountId);
151
+ await (0, usageTracking_1.trackAuthAction)('init', authType, TRACKING_STATUS.ERROR, parsedUserProvidedAccountId);
150
152
  }
151
153
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
152
154
  }
@@ -154,7 +156,7 @@ async function handler(args) {
154
156
  function initBuilder(yargs) {
155
157
  yargs.options({
156
158
  'auth-type': {
157
- describe: (0, lang_1.i18n)(`commands.init.options.authType.describe`),
159
+ describe: en_1.commands.init.options.authType.describe,
158
160
  type: 'string',
159
161
  choices: [
160
162
  `${auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value}`,
@@ -163,7 +165,7 @@ function initBuilder(yargs) {
163
165
  default: auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value,
164
166
  },
165
167
  account: {
166
- describe: (0, lang_1.i18n)(`commands.init.options.account.describe`),
168
+ describe: en_1.commands.init.options.account.describe,
167
169
  type: 'string',
168
170
  alias: 'a',
169
171
  },
@@ -176,11 +178,7 @@ function initBuilder(yargs) {
176
178
  yargs.conflicts('use-hidden-config', 'config');
177
179
  return yargs;
178
180
  }
179
- const builder = (0, yargsUtils_1.makeYargsBuilder)(initBuilder, command, (0, lang_1.i18n)(`commands.init.verboseDescribe`, {
180
- command: (0, ui_1.uiCommandReference)('hs auth'),
181
- configName: config_2.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME,
182
- authMethod: auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value,
183
- }), {
181
+ const builder = (0, yargsUtils_1.makeYargsBuilder)(initBuilder, command, en_1.commands.init.verboseDescribe(config_2.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME, (0, ui_1.uiCommandReference)('hs auth'), auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value), {
184
182
  useGlobalOptions: true,
185
183
  useConfigOptions: true,
186
184
  useTestingOptions: true,
@@ -8,7 +8,7 @@ const fs_1 = __importDefault(require("fs"));
8
8
  const usageTracking_1 = require("../../lib/usageTracking");
9
9
  const lang_1 = require("../../lib/lang");
10
10
  const selectPublicAppForMigrationPrompt_1 = require("../../lib/prompts/selectPublicAppForMigrationPrompt");
11
- const createProjectPrompt_1 = require("../../lib/prompts/createProjectPrompt");
11
+ const projectNameAndDestPrompt_1 = require("../../lib/prompts/projectNameAndDestPrompt");
12
12
  const polling_1 = require("../../lib/polling");
13
13
  const errorHandlers_1 = require("../../lib/errorHandlers");
14
14
  const exitCodes_1 = require("../../lib/enums/exitCodes");
@@ -53,9 +53,9 @@ async function handler(args) {
53
53
  });
54
54
  appId = appIdResponse.appId;
55
55
  }
56
- const createProjectPromptResponse = await (0, createProjectPrompt_1.createProjectPrompt)(args);
57
- projectName = createProjectPromptResponse.name;
58
- projectDest = createProjectPromptResponse.dest;
56
+ const projectNameAndDestPromptResponse = await (0, projectNameAndDestPrompt_1.projectNameAndDestPrompt)(args);
57
+ projectName = projectNameAndDestPromptResponse.name;
58
+ projectDest = projectNameAndDestPromptResponse.dest;
59
59
  }
60
60
  catch (error) {
61
61
  (0, errorHandlers_1.logError)(error, new errorHandlers_1.ApiErrorContext({ accountId: derivedAccountId }));
@@ -39,15 +39,15 @@ async function handler(args) {
39
39
  (0, errorHandlers_1.logError)(error);
40
40
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
41
41
  }
42
- const { authType, distribution, repoConfig, projectContents, createProjectPromptResponse, } = handleResult;
42
+ const { authType, distribution, repoConfig, projectContents, selectProjectTemplatePromptResponse, projectNameAndDestPromptResponse, } = handleResult;
43
43
  (0, usageTracking_1.trackCommandUsage)('project-create', {
44
- type: createProjectPromptResponse.projectTemplate?.name ||
45
- (createProjectPromptResponse.componentTemplates || [])
44
+ type: selectProjectTemplatePromptResponse.projectTemplate?.name ||
45
+ (selectProjectTemplatePromptResponse.componentTemplates || [])
46
46
  // @ts-expect-error
47
47
  .map((item) => item.label)
48
48
  .join(','),
49
49
  }, derivedAccountId);
50
- const projectDest = path_1.default.resolve((0, path_2.getCwd)(), createProjectPromptResponse.dest);
50
+ const projectDest = path_1.default.resolve((0, path_2.getCwd)(), projectNameAndDestPromptResponse.dest);
51
51
  const { projectConfig: existingProjectConfig, projectDir: existingProjectDir, } = await (0, config_1.getProjectConfig)(projectDest);
52
52
  // Exit if the target destination is within an existing project
53
53
  if (existingProjectConfig &&
@@ -57,7 +57,7 @@ async function handler(args) {
57
57
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
58
58
  }
59
59
  const components = (0, v3_2.generateComponentPaths)({
60
- createProjectPromptResponse,
60
+ selectProjectTemplatePromptResponse,
61
61
  platformVersion,
62
62
  repoConfig,
63
63
  projectContents,
@@ -66,7 +66,7 @@ async function handler(args) {
66
66
  });
67
67
  try {
68
68
  await (0, github_1.cloneGithubRepo)(repo, projectDest, {
69
- sourceDir: createProjectPromptResponse.projectTemplate?.path || components,
69
+ sourceDir: selectProjectTemplatePromptResponse.projectTemplate?.path || components,
70
70
  hideLogs: true,
71
71
  branch: 'main',
72
72
  });
@@ -80,15 +80,15 @@ async function handler(args) {
80
80
  const parsedConfigFile = JSON.parse(fs_extra_1.default.readFileSync(projectConfigPath).toString());
81
81
  (0, config_1.writeProjectConfig)(projectConfigPath, {
82
82
  ...parsedConfigFile,
83
- name: createProjectPromptResponse.name,
83
+ name: projectNameAndDestPromptResponse.name,
84
84
  });
85
85
  // If the template is 'no-template', we need to manually create a src directory
86
- if (createProjectPromptResponse.projectTemplate?.name ===
86
+ if (selectProjectTemplatePromptResponse.projectTemplate?.name ===
87
87
  legacy_1.EMPTY_PROJECT_TEMPLATE_NAME ||
88
88
  projectContents === v3_1.EMPTY_PROJECT) {
89
89
  fs_extra_1.default.ensureDirSync(path_1.default.join(projectDest, 'src'));
90
90
  }
91
- logger_1.uiLogger.success(en_1.commands.project.create.logs.success(createProjectPromptResponse.name, projectDest));
91
+ logger_1.uiLogger.success(en_1.commands.project.create.logs.success(projectNameAndDestPromptResponse.name, projectDest));
92
92
  logger_1.uiLogger.log(en_1.commands.project.create.logs.welcomeMessage);
93
93
  (0, ui_1.uiFeatureHighlight)([
94
94
  'projectCommandTip',
@@ -19,7 +19,7 @@ const process_1 = require("../../../lib/process");
19
19
  const accountTypes_1 = require("../../../lib/accountTypes");
20
20
  const ensureProjectExists_1 = require("../../../lib/projects/ensureProjectExists");
21
21
  async function deprecatedProjectDevFlow({ args, accountId, projectConfig, projectDir, }) {
22
- const { providedAccountId, derivedAccountId } = args;
22
+ const { userProvidedAccount, derivedAccountId } = args;
23
23
  const env = (0, environment_1.getValidEnv)((0, config_1.getEnv)(derivedAccountId));
24
24
  const components = await (0, structure_1.findProjectComponents)(projectDir);
25
25
  const runnableComponents = components.filter(component => component.runnable);
@@ -65,11 +65,11 @@ async function deprecatedProjectDevFlow({ args, accountId, projectConfig, projec
65
65
  }
66
66
  // targetProjectAccountId and targetTestingAccountId are set to null if --account flag is not provided.
67
67
  // By setting them to null, we can later check if they need to be assigned based on the default account configuration and the type of app.
68
- let targetProjectAccountId = providedAccountId ? derivedAccountId : null;
68
+ let targetProjectAccountId = userProvidedAccount ? derivedAccountId : null;
69
69
  // The account that we are locally testing against
70
- let targetTestingAccountId = providedAccountId ? derivedAccountId : null;
70
+ let targetTestingAccountId = userProvidedAccount ? derivedAccountId : null;
71
71
  // Check that the default account or flag option is valid for the type of app in this project
72
- if (providedAccountId) {
72
+ if (userProvidedAccount) {
73
73
  (0, helpers_1.checkIfAccountFlagIsSupported)(accountConfig, hasPublicApps);
74
74
  if (hasPublicApps) {
75
75
  targetProjectAccountId = accountConfig.parentAccountId || null;
@@ -15,19 +15,19 @@ const en_1 = require("../../../lang/en");
15
15
  const logger_1 = require("../../../lib/ui/logger");
16
16
  const command = 'dev';
17
17
  const describe = (0, ui_1.uiBetaTag)(en_1.commands.project.dev.describe, false);
18
- function validateAccountFlags(testingAccount, projectAccount, providedAccountId, useV3) {
18
+ function validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV3) {
19
19
  // Legacy projects do not support targetTestingAccount and targetProjectAccount
20
20
  if (testingAccount && projectAccount && !useV3) {
21
21
  logger_1.uiLogger.error(en_1.commands.project.dev.errors.unsupportedAccountFlagLegacy);
22
22
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
23
23
  }
24
- if (providedAccountId && useV3) {
24
+ if (userProvidedAccount && useV3) {
25
25
  logger_1.uiLogger.error(en_1.commands.project.dev.errors.unsupportedAccountFlagV3);
26
26
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
27
27
  }
28
28
  }
29
29
  async function handler(args) {
30
- const { derivedAccountId, providedAccountId, testingAccount, projectAccount, } = args;
30
+ const { derivedAccountId, userProvidedAccount, testingAccount, projectAccount, } = args;
31
31
  const { projectConfig, projectDir } = await (0, config_2.getProjectConfig)();
32
32
  (0, config_2.validateProjectConfig)(projectConfig, projectDir);
33
33
  const useV3 = (0, buildAndDeploy_1.useV3Api)(projectConfig.platformVersion);
@@ -35,9 +35,9 @@ async function handler(args) {
35
35
  logger_1.uiLogger.error(en_1.commands.project.dev.errors.noProjectConfig);
36
36
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
37
37
  }
38
- validateAccountFlags(testingAccount, projectAccount, providedAccountId, useV3);
38
+ validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV3);
39
39
  let targetProjectAccountId = (projectAccount && (0, config_1.getAccountId)(projectAccount)) ||
40
- (providedAccountId && derivedAccountId);
40
+ (userProvidedAccount && derivedAccountId);
41
41
  let profile;
42
42
  if (!targetProjectAccountId && (0, buildAndDeploy_1.useV3Api)(projectConfig.platformVersion)) {
43
43
  if (args.profile) {
@@ -58,6 +58,7 @@ async function unifiedProjectDevFlow({ args, targetProjectAccountId, providedTar
58
58
  }
59
59
  const accounts = (0, config_2.getConfigAccounts)();
60
60
  const accountIsCombined = await (0, accountTypes_1.isUnifiedAccount)(targetProjectAccountConfig);
61
+ const targetProjectAccountIsTestAccountOrSandbox = (0, accountTypes_1.isTestAccountOrSandbox)(targetProjectAccountConfig);
61
62
  if (!accountIsCombined && !profileConfig) {
62
63
  logger_1.uiLogger.error(en_1.commands.project.dev.errors.accountNotCombined);
63
64
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
@@ -67,6 +68,12 @@ async function unifiedProjectDevFlow({ args, targetProjectAccountId, providedTar
67
68
  // Bypass the prompt for the testing account if the user has a profile configured
68
69
  targetTestingAccountId = profileConfig.accountId;
69
70
  }
71
+ else if (
72
+ // Bypass the prompt for the testing account if default account is already a test account
73
+ !targetTestingAccountId &&
74
+ targetProjectAccountIsTestAccountOrSandbox) {
75
+ targetTestingAccountId = targetProjectAccountId;
76
+ }
70
77
  else if (!targetTestingAccountId) {
71
78
  logger_1.uiLogger.log('');
72
79
  (0, ui_1.uiLine)();
@@ -121,6 +128,7 @@ async function unifiedProjectDevFlow({ args, targetProjectAccountId, providedTar
121
128
  debug: args.debug,
122
129
  deployedBuild,
123
130
  isGithubLinked,
131
+ profile: args.profile,
124
132
  targetProjectAccountId,
125
133
  targetTestingAccountId: targetTestingAccountId,
126
134
  projectConfig,
@@ -1,5 +1,5 @@
1
- import { CommonArgs, YargsCommandModule } from '../../types/Yargs';
2
- type ProjectUploadArgs = CommonArgs & {
1
+ import { CommonArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs';
2
+ type ProjectUploadArgs = CommonArgs & JSONOutputArgs & {
3
3
  forceCreate: boolean;
4
4
  message: string;
5
5
  m: string;
@@ -20,10 +20,12 @@ const constants_1 = require("../../lib/constants");
20
20
  const index_2 = require("../../lib/errorHandlers/index");
21
21
  const exitCodes_1 = require("../../lib/enums/exitCodes");
22
22
  const yargsUtils_1 = require("../../lib/yargsUtils");
23
+ const logger_2 = require("../../lib/ui/logger");
23
24
  const command = 'upload';
24
25
  const describe = (0, ui_1.uiBetaTag)((0, lang_1.i18n)(`commands.project.subcommands.upload.describe`), false);
25
26
  async function handler(args) {
26
- const { forceCreate, message, derivedAccountId, skipValidation, profile } = args;
27
+ const { forceCreate, message, derivedAccountId, skipValidation, formatOutputAsJson, profile, } = args;
28
+ const jsonOutput = {};
27
29
  const { projectConfig, projectDir } = await (0, config_2.getProjectConfig)();
28
30
  (0, config_2.validateProjectConfig)(projectConfig, projectDir);
29
31
  let targetAccountId;
@@ -72,7 +74,12 @@ async function handler(args) {
72
74
  }));
73
75
  (0, ui_2.logFeedbackMessage)(result.buildId);
74
76
  await (0, buildAndDeploy_2.displayWarnLogs)(targetAccountId, projectConfig.name, result.buildId);
75
- process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
77
+ }
78
+ if (result && result.succeeded && formatOutputAsJson) {
79
+ jsonOutput.buildId = result.buildId;
80
+ if (result.deployResult) {
81
+ jsonOutput.deployId = result.deployResult.deployId;
82
+ }
76
83
  }
77
84
  }
78
85
  catch (e) {
@@ -82,6 +89,9 @@ async function handler(args) {
82
89
  }));
83
90
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
84
91
  }
92
+ if (formatOutputAsJson) {
93
+ logger_2.uiLogger.json(jsonOutput);
94
+ }
85
95
  process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
86
96
  }
87
97
  function projectUploadBuilder(yargs) {
@@ -123,6 +133,7 @@ const builder = (0, yargsUtils_1.makeYargsBuilder)(projectUploadBuilder, command
123
133
  useConfigOptions: true,
124
134
  useAccountOptions: true,
125
135
  useEnvironmentOptions: true,
136
+ useJSONOutputOptions: true,
126
137
  });
127
138
  const projectUploadCommand = {
128
139
  command,