@hubspot/cli 8.0.10-experimental.7 → 8.0.11-experimental.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.
Files changed (170) hide show
  1. package/bin/cli.js +2 -0
  2. package/commands/account/auth.js +12 -22
  3. package/commands/account/clean.js +5 -6
  4. package/commands/account/createOverride.js +7 -7
  5. package/commands/account/info.js +2 -1
  6. package/commands/account/list.js +3 -5
  7. package/commands/account/remove.js +2 -3
  8. package/commands/account/removeOverride.js +8 -10
  9. package/commands/account/rename.js +5 -6
  10. package/commands/account/use.js +8 -19
  11. package/commands/api.d.ts +10 -0
  12. package/commands/api.js +164 -0
  13. package/commands/app/migrate.js +8 -8
  14. package/commands/app/secret/add.js +6 -7
  15. package/commands/app/secret/delete.js +9 -10
  16. package/commands/app/secret/list.js +6 -7
  17. package/commands/app/secret/update.js +8 -9
  18. package/commands/auth.js +12 -12
  19. package/commands/cms/app/create.js +9 -5
  20. package/commands/cms/convertFields.js +8 -8
  21. package/commands/cms/delete.js +2 -3
  22. package/commands/cms/fetch.js +7 -7
  23. package/commands/cms/function/create.js +9 -5
  24. package/commands/cms/function/deploy.js +2 -3
  25. package/commands/cms/function/list.js +11 -7
  26. package/commands/cms/function/logs.js +17 -23
  27. package/commands/cms/function/server.js +2 -3
  28. package/commands/cms/getReactModule.js +7 -8
  29. package/commands/cms/lighthouseScore.js +25 -24
  30. package/commands/cms/lint.js +4 -5
  31. package/commands/cms/list.js +5 -6
  32. package/commands/cms/module/create.js +9 -5
  33. package/commands/cms/module/marketplace-validate.js +7 -8
  34. package/commands/cms/mv.js +2 -3
  35. package/commands/cms/template/create.js +10 -6
  36. package/commands/cms/theme/create.js +5 -5
  37. package/commands/cms/theme/generate-selectors.js +5 -4
  38. package/commands/cms/theme/marketplace-validate.js +8 -9
  39. package/commands/cms/theme/preview.js +16 -8
  40. package/commands/cms/upload.js +15 -12
  41. package/commands/cms/watch.js +5 -5
  42. package/commands/cms/webpack/create.js +5 -5
  43. package/commands/completion.js +3 -5
  44. package/commands/config/migrate.js +6 -7
  45. package/commands/config/set.js +5 -6
  46. package/commands/customObject/create.js +4 -5
  47. package/commands/customObject/createSchema.js +4 -5
  48. package/commands/customObject/deleteSchema.js +4 -5
  49. package/commands/customObject/fetchAllSchemas.js +2 -3
  50. package/commands/customObject/fetchSchema.js +2 -3
  51. package/commands/customObject/listSchemas.js +2 -3
  52. package/commands/customObject/updateSchema.js +4 -5
  53. package/commands/doctor.js +8 -8
  54. package/commands/feedback.js +6 -4
  55. package/commands/filemanager/fetch.js +5 -6
  56. package/commands/filemanager/upload.js +5 -5
  57. package/commands/getStarted.js +14 -16
  58. package/commands/hubdb/clear.js +5 -6
  59. package/commands/hubdb/create.js +4 -5
  60. package/commands/hubdb/delete.js +8 -9
  61. package/commands/hubdb/fetch.js +5 -6
  62. package/commands/hubdb/list.js +16 -14
  63. package/commands/init.js +14 -17
  64. package/commands/mcp/setup.js +5 -6
  65. package/commands/mcp/start.js +2 -3
  66. package/commands/open.js +4 -5
  67. package/commands/project/add.js +10 -5
  68. package/commands/project/create.js +10 -10
  69. package/commands/project/delete.d.ts +7 -0
  70. package/commands/project/delete.js +74 -0
  71. package/commands/project/deploy.js +36 -34
  72. package/commands/project/dev/deprecatedFlow.js +42 -15
  73. package/commands/project/dev/index.d.ts +3 -3
  74. package/commands/project/dev/index.js +24 -30
  75. package/commands/project/dev/unifiedFlow.js +37 -14
  76. package/commands/project/download.js +10 -11
  77. package/commands/project/info.d.ts +4 -0
  78. package/commands/project/info.js +67 -0
  79. package/commands/project/installDeps.js +9 -6
  80. package/commands/project/lint.js +11 -8
  81. package/commands/project/list.js +14 -14
  82. package/commands/project/listBuilds.js +8 -6
  83. package/commands/project/logs.js +5 -6
  84. package/commands/project/migrate.js +8 -8
  85. package/commands/project/open.js +5 -6
  86. package/commands/project/profile/add.js +12 -8
  87. package/commands/project/profile/delete.js +15 -11
  88. package/commands/project/updateDeps.js +9 -6
  89. package/commands/project/upload.js +31 -17
  90. package/commands/project/validate.js +11 -11
  91. package/commands/project/watch.js +20 -20
  92. package/commands/project.js +4 -0
  93. package/commands/sandbox/create.js +15 -15
  94. package/commands/sandbox/delete.js +13 -14
  95. package/commands/secret/addSecret.js +6 -7
  96. package/commands/secret/deleteSecret.js +5 -6
  97. package/commands/secret/listSecret.js +2 -3
  98. package/commands/secret/updateSecret.js +4 -5
  99. package/commands/testAccount/create.d.ts +1 -1
  100. package/commands/testAccount/create.js +20 -16
  101. package/commands/testAccount/createConfig.js +7 -8
  102. package/commands/testAccount/delete.js +27 -18
  103. package/commands/testAccount/importData.js +6 -7
  104. package/commands/upgrade.js +9 -10
  105. package/lang/en.d.ts +123 -5
  106. package/lang/en.js +121 -6
  107. package/lib/accountAuth.js +2 -2
  108. package/lib/buildAccount.js +3 -3
  109. package/lib/constants.d.ts +0 -1
  110. package/lib/constants.js +0 -1
  111. package/lib/doctor/Diagnosis.js +5 -5
  112. package/lib/errorHandlers/index.js +4 -3
  113. package/lib/errorHandlers/suppressError.js +4 -0
  114. package/lib/errors/PromptExitError.d.ts +4 -2
  115. package/lib/errors/PromptExitError.js +3 -0
  116. package/lib/hasFeature.js +1 -2
  117. package/lib/middleware/autoUpdateMiddleware.js +6 -3
  118. package/lib/process.d.ts +1 -1
  119. package/lib/process.js +10 -3
  120. package/lib/projects/create/v2.js +1 -2
  121. package/lib/projects/delete.d.ts +13 -0
  122. package/lib/projects/delete.js +193 -0
  123. package/lib/projects/localDev/AppDevModeInterface.js +11 -11
  124. package/lib/projects/localDev/DevServerManager_DEPRECATED.d.ts +3 -1
  125. package/lib/projects/localDev/DevServerManager_DEPRECATED.js +2 -2
  126. package/lib/projects/localDev/DevSessionManager.d.ts +6 -3
  127. package/lib/projects/localDev/DevSessionManager.js +31 -19
  128. package/lib/projects/localDev/LocalDevManager_DEPRECATED.d.ts +3 -0
  129. package/lib/projects/localDev/LocalDevManager_DEPRECATED.js +16 -12
  130. package/lib/projects/localDev/LocalDevProcess.js +6 -5
  131. package/lib/projects/localDev/LocalDevState.d.ts +3 -2
  132. package/lib/projects/localDev/LocalDevState.js +3 -1
  133. package/lib/projects/localDev/helpers/account.d.ts +4 -3
  134. package/lib/projects/localDev/helpers/account.js +16 -19
  135. package/lib/projects/localDev/helpers/process.d.ts +1 -1
  136. package/lib/projects/localDev/helpers/process.js +4 -10
  137. package/lib/projects/localDev/helpers/project.d.ts +4 -3
  138. package/lib/projects/localDev/helpers/project.js +31 -15
  139. package/lib/projects/projectInfo.d.ts +5 -0
  140. package/lib/projects/projectInfo.js +82 -0
  141. package/lib/projects/projectProfiles.d.ts +1 -2
  142. package/lib/projects/projectProfiles.js +5 -17
  143. package/lib/projects/upload.js +19 -0
  144. package/lib/projects/workspaces.d.ts +42 -0
  145. package/lib/projects/workspaces.js +350 -0
  146. package/lib/prompts/createApiSamplePrompt.js +4 -0
  147. package/lib/prompts/projectProfilePrompt.d.ts +2 -0
  148. package/lib/prompts/projectProfilePrompt.js +46 -0
  149. package/lib/prompts/promptUtils.js +3 -2
  150. package/lib/prompts/selectHubDBTablePrompt.js +2 -2
  151. package/lib/prompts/selectPublicAppForMigrationPrompt.js +2 -2
  152. package/lib/theme/cmsDevServerProcess.d.ts +2 -0
  153. package/lib/theme/cmsDevServerProcess.js +7 -6
  154. package/lib/ui/SpinniesManager.d.ts +1 -0
  155. package/lib/ui/SpinniesManager.js +20 -6
  156. package/lib/ui/spinniesUtils.d.ts +0 -1
  157. package/lib/ui/spinniesUtils.js +6 -16
  158. package/lib/usageTracking.d.ts +3 -4
  159. package/lib/yargs/makeYargsBuilder.d.ts +13 -0
  160. package/lib/yargs/makeYargsBuilder.js +33 -0
  161. package/lib/yargs/makeYargsHandlerWithUsageTracking.d.ts +3 -0
  162. package/lib/yargs/makeYargsHandlerWithUsageTracking.js +95 -0
  163. package/lib/yargs/strictEnforceBoolean.d.ts +1 -0
  164. package/lib/yargs/strictEnforceBoolean.js +13 -0
  165. package/lib/yargsUtils.d.ts +3 -16
  166. package/lib/yargsUtils.js +3 -48
  167. package/package.json +5 -4
  168. package/types/LocalDev.d.ts +5 -0
  169. package/types/Projects.d.ts +19 -0
  170. package/types/Yargs.d.ts +18 -1
@@ -1,49 +1,51 @@
1
- import { trackCommandUsage } from '../../../lib/usageTracking.js';
2
1
  import { getConfigAccountIfExists } from '@hubspot/local-dev-lib/config';
3
- import { getAllHsProfiles, } from '@hubspot/project-parsing-lib/profiles';
4
2
  import { getProjectConfig, validateProjectConfig, } from '../../../lib/projects/config.js';
5
3
  import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
6
4
  import { uiLine } from '../../../lib/ui/index.js';
5
+ import { makeYargsHandlerWithUsageTracking } from '../../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
7
6
  import { deprecatedProjectDevFlow } from './deprecatedFlow.js';
8
7
  import { unifiedProjectDevFlow } from './unifiedFlow.js';
9
8
  import { isV2Project } from '../../../lib/projects/platformVersion.js';
10
9
  import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
11
- import { loadProfile } from '../../../lib/projects/projectProfiles.js';
10
+ import { loadAndValidateProfile } from '../../../lib/projects/projectProfiles.js';
12
11
  import { commands } from '../../../lang/en.js';
13
12
  import { uiLogger } from '../../../lib/ui/logger.js';
14
13
  import { logError } from '../../../lib/errorHandlers/index.js';
15
- import { PromptExitError } from '../../../lib/errors/PromptExitError.js';
16
- import path from 'path';
17
- import { listPrompt } from '../../../lib/prompts/promptUtils.js';
14
+ import { projectProfilePrompt } from '../../../lib/prompts/projectProfilePrompt.js';
15
+ import { isPromptExitError } from '../../../lib/errors/PromptExitError.js';
18
16
  const command = 'dev';
19
17
  const describe = commands.project.dev.describe;
20
18
  function validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV2) {
21
19
  // Legacy projects do not support targetTestingAccount and targetProjectAccount
22
20
  if (testingAccount && projectAccount && !useV2) {
23
- uiLogger.error(commands.project.dev.errors.unsupportedAccountFlagLegacy);
24
- process.exit(EXIT_CODES.ERROR);
21
+ throw new Error(commands.project.dev.errors.unsupportedAccountFlagLegacy);
25
22
  }
26
23
  if (userProvidedAccount && useV2) {
27
- uiLogger.error(commands.project.dev.errors.unsupportedAccountFlagV2);
28
- process.exit(EXIT_CODES.ERROR);
24
+ throw new Error(commands.project.dev.errors.unsupportedAccountFlagV2);
29
25
  }
30
26
  }
31
27
  async function handler(args) {
32
- const { derivedAccountId, userProvidedAccount, testingAccount, projectAccount, } = args;
28
+ const { derivedAccountId, userProvidedAccount, testingAccount, projectAccount, profile: profileOption, exit, addUsageMetadata, } = args;
33
29
  const { projectConfig, projectDir } = await getProjectConfig();
34
30
  try {
35
31
  validateProjectConfig(projectConfig, projectDir);
36
32
  }
37
33
  catch (error) {
38
34
  logError(error);
39
- process.exit(EXIT_CODES.ERROR);
35
+ return exit(EXIT_CODES.ERROR);
40
36
  }
41
37
  const useV2Projects = isV2Project(projectConfig.platformVersion);
42
38
  if (!projectDir) {
43
39
  uiLogger.error(commands.project.dev.errors.noProjectConfig);
44
- process.exit(EXIT_CODES.ERROR);
40
+ return exit(EXIT_CODES.ERROR);
41
+ }
42
+ try {
43
+ validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV2Projects);
44
+ }
45
+ catch (error) {
46
+ logError(error);
47
+ return exit(EXIT_CODES.ERROR);
45
48
  }
46
- validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV2Projects);
47
49
  uiLogger.log(commands.project.dev.logs.header);
48
50
  if (useV2Projects) {
49
51
  uiLogger.log(commands.project.dev.logs.learnMoreMessageV2);
@@ -68,18 +70,10 @@ async function handler(args) {
68
70
  }
69
71
  // Determine profile name: from flag or prompt
70
72
  if (!targetProjectAccountId && isV2Project(projectConfig.platformVersion)) {
71
- let profileName = args.profile;
72
- if (!profileName) {
73
- const existingProfiles = await getAllHsProfiles(path.join(projectDir, projectConfig.srcDir));
74
- if (existingProfiles.length !== 0) {
75
- profileName = await listPrompt(commands.project.dev.prompts.selectProfile, {
76
- choices: existingProfiles,
77
- });
78
- }
79
- }
73
+ const profileName = await projectProfilePrompt(projectDir, projectConfig, profileOption);
80
74
  if (profileName) {
81
75
  try {
82
- profile = loadProfile(projectConfig, projectDir, profileName);
76
+ profile = await loadAndValidateProfile(projectConfig, projectDir, profileName);
83
77
  targetProjectAccountId = profile.accountId;
84
78
  uiLogger.log('');
85
79
  uiLogger.log(commands.project.dev.logs.profileProjectAccountExplanation(targetProjectAccountId, profileName));
@@ -87,7 +81,7 @@ async function handler(args) {
87
81
  catch (error) {
88
82
  logError(error);
89
83
  uiLine();
90
- process.exit(EXIT_CODES.ERROR);
84
+ return exit(EXIT_CODES.ERROR);
91
85
  }
92
86
  }
93
87
  }
@@ -99,7 +93,7 @@ async function handler(args) {
99
93
  uiLogger.log(commands.project.dev.logs.defaultProjectAccountExplanation(targetProjectAccountId));
100
94
  }
101
95
  }
102
- trackCommandUsage('project-dev', {}, targetProjectAccountId);
96
+ addUsageMetadata({ accountId: targetProjectAccountId ?? undefined });
103
97
  try {
104
98
  if (isV2Project(projectConfig.platformVersion)) {
105
99
  const targetTestingAccountId = testingAccount
@@ -124,11 +118,11 @@ async function handler(args) {
124
118
  }
125
119
  }
126
120
  catch (e) {
127
- if (e instanceof PromptExitError) {
128
- process.exit(e.exitCode);
121
+ if (isPromptExitError(e)) {
122
+ throw e;
129
123
  }
130
124
  logError(e);
131
- process.exit(EXIT_CODES.ERROR);
125
+ return exit(EXIT_CODES.ERROR);
132
126
  }
133
127
  }
134
128
  function projectDevBuilder(yargs) {
@@ -168,7 +162,7 @@ export const builder = makeYargsBuilder(projectDevBuilder, command, describe, {
168
162
  const projectDevCommand = {
169
163
  command,
170
164
  describe,
171
- handler,
165
+ handler: makeYargsHandlerWithUsageTracking('project-dev', handler),
172
166
  builder,
173
167
  };
174
168
  export default projectDevCommand;
@@ -17,9 +17,13 @@ import { isTestAccountOrSandbox, isUnifiedAccount, } from '../../../lib/accountT
17
17
  import { uiLogger } from '../../../lib/ui/logger.js';
18
18
  import { commands } from '../../../lang/en.js';
19
19
  import LocalDevWebsocketServer from '../../../lib/projects/localDev/LocalDevWebsocketServer.js';
20
- import { confirmLocalDevIsNotRunning } from '../../../lib/projects/localDev/helpers/process.js';
20
+ import { isLocalDevRunning } from '../../../lib/projects/localDev/helpers/process.js';
21
21
  export async function unifiedProjectDevFlow({ args, targetProjectAccountId, providedTargetTestingAccountId, projectConfig, projectDir, }) {
22
- await confirmLocalDevIsNotRunning();
22
+ const { exit } = args;
23
+ if (await isLocalDevRunning()) {
24
+ uiLogger.error(commands.project.dev.errors.localDevAlreadyRunning);
25
+ return exit(EXIT_CODES.ERROR);
26
+ }
23
27
  const env = getConfigAccountEnvironment(targetProjectAccountId);
24
28
  let projectNodes;
25
29
  let projectProfileData;
@@ -41,23 +45,23 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
41
45
  else {
42
46
  logError(e);
43
47
  }
44
- return process.exit(EXIT_CODES.ERROR);
48
+ return exit(EXIT_CODES.ERROR);
45
49
  }
46
50
  if (!Object.keys(projectNodes).length) {
47
51
  uiLogger.error(commands.project.dev.errors.noRunnableComponents);
48
- process.exit(EXIT_CODES.SUCCESS);
52
+ return exit(EXIT_CODES.SUCCESS);
49
53
  }
50
54
  const targetProjectAccountConfig = getConfigAccountById(targetProjectAccountId);
51
55
  if (!targetProjectAccountConfig) {
52
56
  uiLogger.error(commands.project.dev.errors.noAccount(targetProjectAccountId));
53
- process.exit(EXIT_CODES.ERROR);
57
+ return exit(EXIT_CODES.ERROR);
54
58
  }
55
59
  const accounts = getAllConfigAccounts();
56
60
  const accountIsCombined = await isUnifiedAccount(targetProjectAccountConfig);
57
61
  const targetProjectAccountIsTestAccountOrSandbox = isTestAccountOrSandbox(targetProjectAccountConfig);
58
62
  if (!accountIsCombined) {
59
63
  uiLogger.error(commands.project.dev.errors.accountNotCombined);
60
- process.exit(EXIT_CODES.ERROR);
64
+ return exit(EXIT_CODES.ERROR);
61
65
  }
62
66
  let targetTestingAccountId = providedTargetTestingAccountId;
63
67
  // Temporarily removing logic to use profile account as testing account
@@ -82,11 +86,19 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
82
86
  if (!!devAccountPromptResponse.notInConfigAccount) {
83
87
  // When the developer test account isn't configured in the CLI config yet
84
88
  // Walk the user through adding the account's PAK to the config
85
- await useExistingDevTestAccount(env, devAccountPromptResponse.notInConfigAccount);
89
+ const accountAdded = await useExistingDevTestAccount(env, devAccountPromptResponse.notInConfigAccount);
90
+ if (!accountAdded) {
91
+ return exit(EXIT_CODES.SUCCESS);
92
+ }
86
93
  }
87
94
  else if (devAccountPromptResponse.createNestedAccount) {
88
95
  // Create a new developer test account and automatically add it to the CLI config
89
- targetTestingAccountId = await createDeveloperTestAccountForLocalDev(targetProjectAccountId, targetProjectAccountConfig, env, true);
96
+ try {
97
+ targetTestingAccountId = await createDeveloperTestAccountForLocalDev(targetProjectAccountId, targetProjectAccountConfig, env, true);
98
+ }
99
+ catch {
100
+ return exit(EXIT_CODES.ERROR);
101
+ }
90
102
  }
91
103
  }
92
104
  else if (accountType === HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX) {
@@ -94,7 +106,12 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
94
106
  targetTestingAccountId =
95
107
  sandboxAccountPromptResponse.targetAccountId || undefined;
96
108
  if (sandboxAccountPromptResponse.createNestedAccount) {
97
- targetTestingAccountId = await createSandboxForLocalDev(targetProjectAccountId, targetProjectAccountConfig, env);
109
+ try {
110
+ targetTestingAccountId = await createSandboxForLocalDev(targetProjectAccountId, targetProjectAccountConfig, env);
111
+ }
112
+ catch {
113
+ return exit(EXIT_CODES.ERROR);
114
+ }
98
115
  }
99
116
  }
100
117
  else {
@@ -111,21 +128,26 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
111
128
  });
112
129
  let project = uploadedProject;
113
130
  if (projectExists && project) {
114
- await compareLocalProjectToDeployed(projectConfig, targetProjectAccountId, project.deployedBuild?.buildId, projectNodes, args.profile);
131
+ await compareLocalProjectToDeployed(projectConfig, targetProjectAccountId, project.deployedBuild?.buildId, projectNodes, exit, args.profile);
115
132
  }
116
133
  else {
117
- project = await createNewProjectForLocalDev(projectConfig, targetProjectAccountId, false, false);
118
- await createInitialBuildForNewProject(projectConfig, projectDir, targetProjectAccountId, true, args.profile);
134
+ project = await createNewProjectForLocalDev(projectConfig, targetProjectAccountId, false, false, exit);
135
+ await createInitialBuildForNewProject(projectConfig, projectDir, targetProjectAccountId, exit, true, args.profile);
119
136
  }
120
137
  // Check for missing/outdated dependencies
121
- await checkAndInstallDependencies();
138
+ try {
139
+ await checkAndInstallDependencies();
140
+ }
141
+ catch {
142
+ return exit(EXIT_CODES.ERROR);
143
+ }
122
144
  // End setup, start local dev process
123
145
  try {
124
146
  await startPortManagerServer();
125
147
  }
126
148
  catch (e) {
127
149
  logError(e);
128
- process.exit(EXIT_CODES.ERROR);
150
+ return exit(EXIT_CODES.ERROR);
129
151
  }
130
152
  const localDevProcess = new LocalDevProcess({
131
153
  initialProjectNodes: projectNodes,
@@ -138,6 +160,7 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
138
160
  projectDir,
139
161
  projectData: project,
140
162
  env,
163
+ actions: { exit },
141
164
  });
142
165
  const websocketServer = new LocalDevWebsocketServer(localDevProcess, args.debug);
143
166
  const watcher = new LocalDevWatcher(localDevProcess);
@@ -3,25 +3,24 @@ import { getCwd, sanitizeFileName } from '@hubspot/local-dev-lib/path';
3
3
  import { extractZipArchive } from '@hubspot/local-dev-lib/archive';
4
4
  import { downloadProject, fetchProjectBuilds, } from '@hubspot/local-dev-lib/api/projects';
5
5
  import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
6
- import { PromptExitError } from '../../lib/errors/PromptExitError.js';
6
+ import { isPromptExitError } from '../../lib/errors/PromptExitError.js';
7
7
  import { getProjectConfig } from '../../lib/projects/config.js';
8
8
  import { downloadProjectPrompt } from '../../lib/prompts/downloadProjectPrompt.js';
9
9
  import { commands } from '../../lang/en.js';
10
10
  import { uiLogger } from '../../lib/ui/logger.js';
11
- import { trackCommandUsage } from '../../lib/usageTracking.js';
12
11
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
12
+ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
13
13
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
14
14
  const command = 'download';
15
15
  const describe = commands.project.download.describe;
16
16
  async function handler(args) {
17
+ const { dest, build, derivedAccountId, exit } = args;
17
18
  const { projectConfig } = await getProjectConfig();
18
19
  if (projectConfig) {
19
20
  uiLogger.error(commands.project.download.warnings.cannotDownloadWithinProject);
20
- process.exit(EXIT_CODES.ERROR);
21
+ return exit(EXIT_CODES.ERROR);
21
22
  }
22
- const { dest, build, derivedAccountId } = args;
23
23
  let buildNumberToDownload = build;
24
- trackCommandUsage('project-download', undefined, derivedAccountId);
25
24
  try {
26
25
  const { project: projectName } = await downloadProjectPrompt(args);
27
26
  if (!buildNumberToDownload) {
@@ -34,7 +33,7 @@ async function handler(args) {
34
33
  }
35
34
  if (!buildNumberToDownload) {
36
35
  uiLogger.error(commands.project.download.errors.noBuildIdToDownload);
37
- process.exit(EXIT_CODES.ERROR);
36
+ return exit(EXIT_CODES.ERROR);
38
37
  }
39
38
  const sanitizedProjectName = sanitizeFileName(projectName);
40
39
  const absoluteDestPath = dest
@@ -43,17 +42,17 @@ async function handler(args) {
43
42
  const { data: zippedProject } = await downloadProject(derivedAccountId, projectName, buildNumberToDownload);
44
43
  await extractZipArchive(zippedProject, sanitizeFileName(projectName), path.resolve(absoluteDestPath));
45
44
  uiLogger.log(commands.project.download.logs.downloadSucceeded(buildNumberToDownload, projectName));
46
- process.exit(EXIT_CODES.SUCCESS);
45
+ return exit(EXIT_CODES.SUCCESS);
47
46
  }
48
47
  catch (e) {
49
- if (e instanceof PromptExitError) {
50
- process.exit(e.exitCode);
48
+ if (isPromptExitError(e)) {
49
+ throw e;
51
50
  }
52
51
  logError(e, new ApiErrorContext({
53
52
  accountId: derivedAccountId,
54
53
  request: 'project download',
55
54
  }));
56
- process.exit(EXIT_CODES.ERROR);
55
+ return exit(EXIT_CODES.ERROR);
57
56
  }
58
57
  }
59
58
  function projectDownloadBuilder(yargs) {
@@ -89,7 +88,7 @@ const builder = makeYargsBuilder(projectDownloadBuilder, command, describe, {
89
88
  const projectDownloadCommand = {
90
89
  command,
91
90
  describe,
92
- handler,
91
+ handler: makeYargsHandlerWithUsageTracking('project-download', handler),
93
92
  builder,
94
93
  };
95
94
  export default projectDownloadCommand;
@@ -0,0 +1,4 @@
1
+ import { AccountArgs, CommonArgs, ConfigArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
2
+ type ProjectInfoArgs = CommonArgs & ConfigArgs & AccountArgs & JSONOutputArgs;
3
+ declare const projectInfoCommand: YargsCommandModule<unknown, ProjectInfoArgs>;
4
+ export default projectInfoCommand;
@@ -0,0 +1,67 @@
1
+ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
2
+ import { makeYargsBuilder } from '../../lib/yargsUtils.js';
3
+ import { fetchProject } from '@hubspot/local-dev-lib/api/projects';
4
+ import { debugError } from '../../lib/errorHandlers/index.js';
5
+ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
6
+ import { uiLogger } from '../../lib/ui/logger.js';
7
+ import { commands } from '../../lang/en.js';
8
+ import { getProjectConfig } from '../../lib/projects/config.js';
9
+ import { isV2Project } from '../../lib/projects/platformVersion.js';
10
+ import { getProjectInfo, logProjectInfo, } from '../../lib/projects/projectInfo.js';
11
+ const command = 'info';
12
+ const describe = commands.project.info.describe;
13
+ const verboseDescribe = commands.project.info.verboseDescribe;
14
+ async function handler(args) {
15
+ const { derivedAccountId, formatOutputAsJson, exit } = args;
16
+ const { projectConfig } = await getProjectConfig();
17
+ if (!projectConfig) {
18
+ uiLogger.error(commands.project.info.errors.noProjectConfig);
19
+ return exit(EXIT_CODES.ERROR);
20
+ }
21
+ if (!isV2Project(projectConfig.platformVersion)) {
22
+ uiLogger.error(commands.project.info.errors.unsupportedPlatformVersion(projectConfig.platformVersion));
23
+ return exit(EXIT_CODES.ERROR);
24
+ }
25
+ const projectName = projectConfig.name;
26
+ let project;
27
+ try {
28
+ const response = await fetchProject(derivedAccountId, projectName);
29
+ project = response.data;
30
+ }
31
+ catch (error) {
32
+ debugError(error);
33
+ uiLogger.error(commands.project.info.errors.projectNotFound(projectName, derivedAccountId));
34
+ return exit(EXIT_CODES.ERROR);
35
+ }
36
+ const deployedBuild = project.deployedBuild;
37
+ if (!deployedBuild) {
38
+ uiLogger.error(commands.project.info.errors.noDeployedBuild);
39
+ return exit(EXIT_CODES.ERROR);
40
+ }
41
+ const projectInfo = await getProjectInfo(project, projectConfig.platformVersion, derivedAccountId);
42
+ if (formatOutputAsJson) {
43
+ uiLogger.json(projectInfo);
44
+ return;
45
+ }
46
+ logProjectInfo(projectInfo);
47
+ }
48
+ function projectInfoBuilder(yargs) {
49
+ yargs.example([
50
+ ['$0 project info', commands.project.info.examples.default],
51
+ ['$0 project info --json', commands.project.info.examples.json],
52
+ ]);
53
+ return yargs;
54
+ }
55
+ const builder = makeYargsBuilder(projectInfoBuilder, command, verboseDescribe, {
56
+ useGlobalOptions: true,
57
+ useConfigOptions: true,
58
+ useAccountOptions: true,
59
+ useJSONOutputOptions: true,
60
+ });
61
+ const projectInfoCommand = {
62
+ command,
63
+ describe,
64
+ handler: makeYargsHandlerWithUsageTracking('project-info', handler),
65
+ builder,
66
+ };
67
+ export default projectInfoCommand;
@@ -1,23 +1,23 @@
1
1
  import { installPackages, getProjectPackageJsonLocations, } from '../../lib/dependencyManagement.js';
2
2
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
3
+ import { isPromptExitError } from '../../lib/errors/PromptExitError.js';
3
4
  import { getProjectConfig } from '../../lib/projects/config.js';
4
5
  import { promptUser } from '../../lib/prompts/promptUtils.js';
5
6
  import path from 'path';
6
7
  import { commands } from '../../lang/en.js';
7
8
  import { uiLogger } from '../../lib/ui/logger.js';
8
- import { trackCommandUsage } from '../../lib/usageTracking.js';
9
+ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
9
10
  import { logError } from '../../lib/errorHandlers/index.js';
10
11
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
11
12
  const command = 'install-deps [packages..]';
12
13
  const describe = commands.project.installDeps.help.describe;
13
14
  async function handler(args) {
14
- const { derivedAccountId, packages } = args;
15
+ const { packages, exit } = args;
15
16
  try {
16
- trackCommandUsage('project-install-deps', undefined, derivedAccountId);
17
17
  const projectConfig = await getProjectConfig();
18
18
  if (!projectConfig || !projectConfig.projectDir) {
19
19
  uiLogger.error(commands.project.installDeps.noProjectConfig);
20
- return process.exit(EXIT_CODES.ERROR);
20
+ return exit(EXIT_CODES.ERROR);
21
21
  }
22
22
  const { projectDir } = projectConfig;
23
23
  let installLocations = await getProjectPackageJsonLocations();
@@ -50,8 +50,11 @@ async function handler(args) {
50
50
  });
51
51
  }
52
52
  catch (e) {
53
+ if (isPromptExitError(e)) {
54
+ throw e;
55
+ }
53
56
  logError(e);
54
- return process.exit(EXIT_CODES.ERROR);
57
+ return exit(EXIT_CODES.ERROR);
55
58
  }
56
59
  }
57
60
  function projectInstallDepsBuilder(yargs) {
@@ -74,7 +77,7 @@ const builder = makeYargsBuilder(projectInstallDepsBuilder, command, describe, {
74
77
  const projectInstallDepsCommand = {
75
78
  command,
76
79
  describe,
77
- handler,
80
+ handler: makeYargsHandlerWithUsageTracking('project-install-deps', handler),
78
81
  builder,
79
82
  };
80
83
  export default projectInstallDepsCommand;
@@ -1,10 +1,11 @@
1
1
  import path from 'path';
2
2
  import { getProjectPackageJsonLocations, installPackages, } from '../../lib/dependencyManagement.js';
3
3
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
4
+ import { isPromptExitError } from '../../lib/errors/PromptExitError.js';
4
5
  import { getProjectConfig } from '../../lib/projects/config.js';
5
6
  import { commands } from '../../lang/en.js';
6
7
  import { uiLogger } from '../../lib/ui/logger.js';
7
- import { trackCommandUsage } from '../../lib/usageTracking.js';
8
+ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
8
9
  import { logError } from '../../lib/errorHandlers/index.js';
9
10
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
10
11
  import { promptUser } from '../../lib/prompts/promptUtils.js';
@@ -13,13 +14,12 @@ import { areAllLintPackagesInstalled, getMissingLintPackages, lintPackages, disp
13
14
  const command = 'lint';
14
15
  const describe = commands.project.lint.help.describe;
15
16
  async function handler(args) {
16
- const { derivedAccountId, installMissingDeps } = args;
17
+ const { installMissingDeps, exit } = args;
17
18
  try {
18
- trackCommandUsage('project-lint', undefined, derivedAccountId);
19
19
  const projectConfig = await getProjectConfig();
20
20
  if (!projectConfig || !projectConfig.projectDir) {
21
21
  uiLogger.error(commands.project.lint.noProjectConfig);
22
- return process.exit(EXIT_CODES.ERROR);
22
+ return exit(EXIT_CODES.ERROR);
23
23
  }
24
24
  SpinniesManager.init({ succeedColor: 'white' });
25
25
  SpinniesManager.add('lintCheck', {
@@ -129,7 +129,7 @@ async function handler(args) {
129
129
  }
130
130
  else {
131
131
  uiLogger.error(commands.project.lint.eslintConfigRequired);
132
- return process.exit(EXIT_CODES.ERROR);
132
+ return exit(EXIT_CODES.ERROR);
133
133
  }
134
134
  }
135
135
  SpinniesManager.add('lintRun', {
@@ -139,13 +139,16 @@ async function handler(args) {
139
139
  SpinniesManager.succeed('lintRun');
140
140
  displayLintResults(results);
141
141
  if (!success) {
142
- return process.exit(EXIT_CODES.ERROR);
142
+ return exit(EXIT_CODES.ERROR);
143
143
  }
144
144
  }
145
145
  }
146
146
  catch (e) {
147
+ if (isPromptExitError(e)) {
148
+ throw e;
149
+ }
147
150
  logError(e);
148
- return process.exit(EXIT_CODES.ERROR);
151
+ return exit(EXIT_CODES.ERROR);
149
152
  }
150
153
  }
151
154
  function projectLintBuilder(yargs) {
@@ -172,7 +175,7 @@ const builder = makeYargsBuilder(projectLintBuilder, command, describe, {
172
175
  const projectLintCommand = {
173
176
  command,
174
177
  describe,
175
- handler,
178
+ handler: makeYargsHandlerWithUsageTracking('project-lint', handler),
176
179
  builder,
177
180
  };
178
181
  export default projectLintCommand;
@@ -1,4 +1,4 @@
1
- import { trackCommandUsage } from '../../lib/usageTracking.js';
1
+ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
2
2
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
3
3
  import { fetchProjects } from '@hubspot/local-dev-lib/api/projects';
4
4
  import { logError } from '../../lib/errorHandlers/index.js';
@@ -9,14 +9,8 @@ import { renderTable } from '../../ui/render.js';
9
9
  const command = ['list', 'ls'];
10
10
  const describe = commands.project.list.describe;
11
11
  async function getProjectData(accountId) {
12
- try {
13
- const { data: projects } = await fetchProjects(accountId);
14
- return projects.results;
15
- }
16
- catch (e) {
17
- logError(e);
18
- process.exit(EXIT_CODES.ERROR);
19
- }
12
+ const { data: projects } = await fetchProjects(accountId);
13
+ return projects.results;
20
14
  }
21
15
  function formatProjectsAsTableRows(projects) {
22
16
  const projectListData = [];
@@ -29,12 +23,18 @@ function formatProjectsAsTableRows(projects) {
29
23
  return projectListData;
30
24
  }
31
25
  async function handler(args) {
32
- const { derivedAccountId } = args;
33
- trackCommandUsage('projects-list', undefined, derivedAccountId);
34
- const projectData = await getProjectData(derivedAccountId);
26
+ const { derivedAccountId, exit } = args;
27
+ let projectData;
28
+ try {
29
+ projectData = await getProjectData(derivedAccountId);
30
+ }
31
+ catch (e) {
32
+ logError(e);
33
+ return exit(EXIT_CODES.ERROR);
34
+ }
35
35
  if (projectData.length === 0) {
36
36
  uiLogger.error(commands.project.list.errors.noProjectsFound(derivedAccountId));
37
- process.exit(EXIT_CODES.ERROR);
37
+ return exit(EXIT_CODES.ERROR);
38
38
  }
39
39
  const projectListData = formatProjectsAsTableRows(projectData);
40
40
  const tableHeader = [
@@ -56,7 +56,7 @@ const builder = makeYargsBuilder(projectListBuilder, command, describe, {
56
56
  const projectListCommand = {
57
57
  command,
58
58
  describe,
59
- handler,
59
+ handler: makeYargsHandlerWithUsageTracking('projects-list', handler),
60
60
  builder,
61
61
  };
62
62
  export default projectListCommand;
@@ -5,9 +5,9 @@ import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/con
5
5
  import { getProjectDetailUrl } from '../../lib/projects/urls.js';
6
6
  import moment from 'moment';
7
7
  import { promptUser } from '../../lib/prompts/promptUtils.js';
8
- import { trackCommandUsage } from '../../lib/usageTracking.js';
9
8
  import { uiLogger } from '../../lib/ui/logger.js';
10
9
  import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
10
+ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
11
11
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
12
12
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
13
13
  import { commands } from '../../lang/en.js';
@@ -58,8 +58,7 @@ async function fetchAndDisplayBuilds(accountId, project, options) {
58
58
  }
59
59
  }
60
60
  async function handler(args) {
61
- const { project: projectFlagValue, limit, derivedAccountId } = args;
62
- trackCommandUsage('project-list-builds', undefined, derivedAccountId);
61
+ const { project: projectFlagValue, limit, derivedAccountId, exit } = args;
63
62
  let projectName = projectFlagValue;
64
63
  if (!projectName) {
65
64
  const { projectConfig, projectDir } = await getProjectConfig();
@@ -68,7 +67,10 @@ async function handler(args) {
68
67
  }
69
68
  catch (error) {
70
69
  logError(error);
71
- process.exit(EXIT_CODES.ERROR);
70
+ return exit(EXIT_CODES.ERROR);
71
+ }
72
+ if (!projectConfig) {
73
+ return exit(EXIT_CODES.ERROR);
72
74
  }
73
75
  projectName = projectConfig.name;
74
76
  }
@@ -87,7 +89,7 @@ async function handler(args) {
87
89
  }));
88
90
  }
89
91
  }
90
- process.exit(EXIT_CODES.SUCCESS);
92
+ return exit(EXIT_CODES.SUCCESS);
91
93
  }
92
94
  function projectListBuildsBuilder(yargs) {
93
95
  yargs.options({
@@ -114,7 +116,7 @@ const builder = makeYargsBuilder(projectListBuildsBuilder, command, describe, {
114
116
  const projectListBuildsCommand = {
115
117
  command,
116
118
  describe,
117
- handler,
119
+ handler: makeYargsHandlerWithUsageTracking('project-list-builds', handler),
118
120
  builder,
119
121
  };
120
122
  export default projectListBuildsCommand;
@@ -1,6 +1,5 @@
1
1
  import { getConfigAccountEnvironment } from '@hubspot/local-dev-lib/config';
2
2
  import { getHubSpotWebsiteOrigin } from '@hubspot/local-dev-lib/urls';
3
- import { trackCommandUsage } from '../../lib/usageTracking.js';
4
3
  import { logError } from '../../lib/errorHandlers/index.js';
5
4
  import { uiLine } from '../../lib/ui/index.js';
6
5
  import { projectLogsPrompt } from '../../lib/prompts/projectsLogsPrompt.js';
@@ -8,6 +7,7 @@ import { commands } from '../../lang/en.js';
8
7
  import { uiLogger } from '../../lib/ui/logger.js';
9
8
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
10
9
  import { ProjectLogsManager } from '../../lib/projects/ProjectLogsManager.js';
10
+ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
11
11
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
12
12
  import { renderTable } from '../../ui/render.js';
13
13
  function getPrivateAppsUrl(accountId) {
@@ -51,8 +51,7 @@ function logPreamble() {
51
51
  const command = 'logs';
52
52
  const describe = commands.project.logs.describe;
53
53
  async function handler(args) {
54
- const { derivedAccountId } = args;
55
- trackCommandUsage('project-logs', undefined, derivedAccountId);
54
+ const { derivedAccountId, exit } = args;
56
55
  try {
57
56
  await ProjectLogsManager.init(derivedAccountId);
58
57
  const { functionName } = await projectLogsPrompt({
@@ -68,9 +67,9 @@ async function handler(args) {
68
67
  accountId: derivedAccountId,
69
68
  projectName: ProjectLogsManager.projectName,
70
69
  });
71
- return process.exit(EXIT_CODES.ERROR);
70
+ return exit(EXIT_CODES.ERROR);
72
71
  }
73
- process.exit(EXIT_CODES.SUCCESS);
72
+ return exit(EXIT_CODES.SUCCESS);
74
73
  }
75
74
  function projectLogsBuilder(yargs) {
76
75
  yargs.options({
@@ -113,7 +112,7 @@ const builder = makeYargsBuilder(projectLogsBuilder, command, describe, { useGlo
113
112
  const projectLogsCommand = {
114
113
  command,
115
114
  describe,
116
- handler,
115
+ handler: makeYargsHandlerWithUsageTracking('project-logs', handler),
117
116
  builder,
118
117
  };
119
118
  export default projectLogsCommand;