@hubspot/cli 7.8.12-experimental.0 → 7.8.12-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 (244) hide show
  1. package/bin/cli.js +31 -25
  2. package/commands/__tests__/auth.test.js +5 -0
  3. package/commands/__tests__/doctor.test.js +16 -16
  4. package/commands/account/clean.js +18 -27
  5. package/commands/account/createOverride.js +13 -31
  6. package/commands/account/info.js +20 -31
  7. package/commands/account/list.js +16 -22
  8. package/commands/account/remove.js +12 -20
  9. package/commands/account/removeOverride.js +11 -21
  10. package/commands/account/rename.js +6 -9
  11. package/commands/account/use.js +12 -26
  12. package/commands/account.js +2 -2
  13. package/commands/app/__tests__/migrate.test.js +5 -5
  14. package/commands/app/migrate.js +13 -18
  15. package/commands/app.js +1 -6
  16. package/commands/auth.d.ts +1 -0
  17. package/commands/auth.js +16 -7
  18. package/commands/cms/convertFields.js +7 -9
  19. package/commands/cms/getReactModule.js +9 -14
  20. package/commands/cms/lighthouseScore.js +33 -36
  21. package/commands/cms.js +2 -2
  22. package/commands/completion.js +3 -3
  23. package/commands/config/set.d.ts +1 -1
  24. package/commands/config/set.js +64 -36
  25. package/commands/config.js +2 -2
  26. package/commands/create.js +2 -2
  27. package/commands/customObject/create.js +10 -12
  28. package/commands/customObject/schema/create.js +9 -11
  29. package/commands/customObject/schema/delete.js +16 -16
  30. package/commands/customObject/schema/fetch-all.js +12 -11
  31. package/commands/customObject/schema/fetch.js +15 -15
  32. package/commands/customObject/schema/list.js +4 -4
  33. package/commands/customObject/schema/update.js +13 -13
  34. package/commands/customObject/schema.js +2 -2
  35. package/commands/customObject.js +6 -7
  36. package/commands/doctor.js +8 -11
  37. package/commands/feedback.js +6 -11
  38. package/commands/fetch.js +8 -8
  39. package/commands/filemanager/fetch.js +7 -7
  40. package/commands/filemanager/upload.js +15 -34
  41. package/commands/filemanager.js +2 -2
  42. package/commands/function/deploy.js +11 -29
  43. package/commands/function/list.js +8 -8
  44. package/commands/function/server.js +9 -11
  45. package/commands/function.d.ts +1 -1
  46. package/commands/function.js +2 -2
  47. package/commands/getStarted.js +2 -2
  48. package/commands/hubdb/clear.js +7 -15
  49. package/commands/hubdb/create.js +9 -15
  50. package/commands/hubdb/delete.js +8 -15
  51. package/commands/hubdb/fetch.js +6 -9
  52. package/commands/hubdb.d.ts +1 -1
  53. package/commands/hubdb.js +2 -2
  54. package/commands/init.js +2 -3
  55. package/commands/lint.js +16 -16
  56. package/commands/list.js +8 -14
  57. package/commands/logs.js +14 -20
  58. package/commands/mv.js +6 -17
  59. package/commands/open.js +5 -5
  60. package/commands/project/__tests__/add.test.js +4 -2
  61. package/commands/project/__tests__/deploy.test.js +3 -4
  62. package/commands/project/__tests__/installDeps.test.js +8 -8
  63. package/commands/project/__tests__/logs.test.js +1 -1
  64. package/commands/project/__tests__/migrate.test.js +5 -5
  65. package/commands/project/__tests__/migrateApp.test.js +2 -5
  66. package/commands/project/__tests__/validate.test.js +98 -0
  67. package/commands/project/add.js +3 -3
  68. package/commands/project/cloneApp.js +14 -19
  69. package/commands/project/create.js +0 -1
  70. package/commands/project/deploy.js +3 -3
  71. package/commands/project/dev/deprecatedFlow.js +7 -16
  72. package/commands/project/dev/index.js +14 -12
  73. package/commands/project/dev/unifiedFlow.js +3 -1
  74. package/commands/project/download.js +10 -13
  75. package/commands/project/installDeps.js +8 -8
  76. package/commands/project/listBuilds.js +11 -20
  77. package/commands/project/logs.js +21 -24
  78. package/commands/project/migrateApp.js +9 -15
  79. package/commands/project/open.js +6 -13
  80. package/commands/project/upload.d.ts +2 -2
  81. package/commands/project/upload.js +17 -26
  82. package/commands/project/validate.js +6 -6
  83. package/commands/project/watch.js +13 -22
  84. package/commands/project.js +2 -2
  85. package/commands/sandbox/__tests__/create.test.js +5 -5
  86. package/commands/sandbox/create.js +22 -32
  87. package/commands/sandbox/delete.js +38 -63
  88. package/commands/sandbox.js +2 -2
  89. package/commands/secret/addSecret.js +7 -17
  90. package/commands/secret/deleteSecret.js +10 -20
  91. package/commands/secret/listSecret.js +8 -10
  92. package/commands/secret/updateSecret.js +9 -17
  93. package/commands/secret.js +2 -2
  94. package/commands/testAccount/__tests__/delete.test.js +2 -4
  95. package/commands/testAccount/create.js +0 -3
  96. package/commands/testAccount/delete.d.ts +4 -3
  97. package/commands/testAccount/delete.js +155 -14
  98. package/commands/theme/preview.js +1 -4
  99. package/lang/en.d.ts +310 -124
  100. package/lang/en.js +351 -169
  101. package/lang/en.lyaml +2 -2
  102. package/lib/__tests__/buildAccount.test.js +2 -1
  103. package/lib/__tests__/commonOpts.test.js +1 -1
  104. package/lib/__tests__/dependencyManagement.test.js +1 -1
  105. package/lib/__tests__/developerTestAccounts.test.js +3 -3
  106. package/lib/__tests__/npm.test.js +1 -1
  107. package/lib/__tests__/oauth.test.js +4 -4
  108. package/lib/__tests__/process.test.js +10 -5
  109. package/lib/__tests__/sandboxSync.test.js +8 -8
  110. package/lib/__tests__/sandboxes.test.js +8 -8
  111. package/lib/__tests__/serverlessLogs.test.js +1 -1
  112. package/lib/__tests__/usageTracking.test.js +5 -5
  113. package/lib/__tests__/validation.test.js +2 -1
  114. package/lib/__tests__/yargsUtils.test.js +83 -9
  115. package/lib/app/__tests__/migrate.test.js +5 -5
  116. package/lib/app/__tests__/migrate_legacy.test.js +1 -1
  117. package/lib/app/migrate.js +1 -1
  118. package/lib/app/migrate_legacy.js +20 -24
  119. package/lib/buildAccount.js +25 -57
  120. package/lib/commonOpts.d.ts +1 -1
  121. package/lib/commonOpts.js +25 -22
  122. package/lib/configOptions.js +7 -0
  123. package/lib/constants.d.ts +6 -1
  124. package/lib/constants.js +10 -1
  125. package/lib/dependencyManagement.js +9 -27
  126. package/lib/developerTestAccounts.js +9 -23
  127. package/lib/doctor/Diagnosis.js +11 -23
  128. package/lib/doctor/DiagnosticInfoBuilder.js +12 -11
  129. package/lib/doctor/Doctor.js +42 -90
  130. package/lib/doctor/__tests__/Doctor.test.js +4 -4
  131. package/lib/errorHandlers/index.js +12 -20
  132. package/lib/errorHandlers/suppressError.js +11 -18
  133. package/lib/lang.js +6 -5
  134. package/lib/links.js +4 -4
  135. package/lib/middleware/__test__/commandTargetingUtils.test.js +99 -0
  136. package/lib/middleware/__test__/configMiddleware.test.js +11 -11
  137. package/lib/middleware/__test__/yargsChecksMiddleware.test.js +6 -8
  138. package/lib/middleware/commandTargetingUtils.d.ts +8 -0
  139. package/lib/middleware/commandTargetingUtils.js +78 -0
  140. package/lib/middleware/configMiddleware.d.ts +1 -1
  141. package/lib/middleware/configMiddleware.js +21 -81
  142. package/lib/middleware/gitMiddleware.js +5 -1
  143. package/lib/middleware/notificationsMiddleware.js +5 -11
  144. package/lib/middleware/yargsChecksMiddleware.js +6 -9
  145. package/lib/npm.js +2 -2
  146. package/lib/oauth.js +5 -5
  147. package/lib/process.js +5 -4
  148. package/lib/projectProfiles.d.ts +1 -1
  149. package/lib/projectProfiles.js +2 -10
  150. package/lib/projects/__tests__/AppDevModeInterface.test.js +14 -34
  151. package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +70 -39
  152. package/lib/projects/__tests__/localDevProjectHelpers.test.js +2 -0
  153. package/lib/projects/__tests__/platformVersion.test.js +8 -8
  154. package/lib/projects/__tests__/projects.test.js +12 -12
  155. package/lib/projects/__tests__/structure.test.js +3 -3
  156. package/lib/projects/__tests__/upload.test.d.ts +1 -0
  157. package/lib/projects/__tests__/upload.test.js +82 -0
  158. package/lib/projects/add/__tests__/legacyAddComponent.test.js +6 -6
  159. package/lib/projects/add/__tests__/v3AddComponent.test.js +4 -4
  160. package/lib/projects/create/__tests__/legacy.test.js +5 -5
  161. package/lib/projects/create/__tests__/v3.test.js +1 -1
  162. package/lib/projects/create/index.js +2 -2
  163. package/lib/projects/create/legacy.js +2 -2
  164. package/lib/projects/create/v3.js +2 -2
  165. package/lib/projects/localDev/AppDevModeInterface.d.ts +2 -0
  166. package/lib/projects/localDev/AppDevModeInterface.js +22 -20
  167. package/lib/projects/localDev/LocalDevLogger.js +10 -11
  168. package/lib/projects/localDev/LocalDevManager.js +4 -5
  169. package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +0 -1
  170. package/lib/projects/localDev/LocalDevWebsocketServer.js +7 -10
  171. package/lib/projects/localDev/helpers/project.d.ts +1 -0
  172. package/lib/projects/localDev/helpers/project.js +37 -0
  173. package/lib/projects/platformVersion.d.ts +1 -1
  174. package/lib/projects/platformVersion.js +1 -1
  175. package/lib/projects/structure.d.ts +2 -2
  176. package/lib/projects/structure.js +6 -6
  177. package/lib/projects/upload.d.ts +2 -3
  178. package/lib/projects/upload.js +17 -9
  179. package/lib/prompts/__tests__/downloadProjectPrompt.test.js +1 -0
  180. package/lib/prompts/accountNamePrompt.js +14 -19
  181. package/lib/prompts/accountsPrompt.js +2 -2
  182. package/lib/prompts/cmsFieldPrompt.js +2 -2
  183. package/lib/prompts/createApiSamplePrompt.js +5 -5
  184. package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +10 -1
  185. package/lib/prompts/createFunctionPrompt.js +14 -14
  186. package/lib/prompts/createModulePrompt.js +9 -9
  187. package/lib/prompts/createTemplatePrompt.js +2 -2
  188. package/lib/prompts/downloadProjectPrompt.js +5 -8
  189. package/lib/prompts/personalAccessKeyPrompt.js +3 -3
  190. package/lib/prompts/previewPrompt.js +6 -6
  191. package/lib/prompts/projectAddPrompt.js +6 -0
  192. package/lib/prompts/projectDevTargetAccountPrompt.js +20 -32
  193. package/lib/prompts/projectNamePrompt.js +4 -8
  194. package/lib/prompts/projectsLogsPrompt.js +2 -4
  195. package/lib/prompts/promptUtils.js +27 -9
  196. package/lib/prompts/sandboxesPrompt.js +7 -7
  197. package/lib/prompts/secretPrompt.js +3 -3
  198. package/lib/prompts/selectAppPrompt.js +3 -3
  199. package/lib/prompts/selectHubDBTablePrompt.js +9 -13
  200. package/lib/prompts/selectPublicAppForMigrationPrompt.js +15 -19
  201. package/lib/prompts/setAsDefaultAccountPrompt.js +4 -8
  202. package/lib/prompts/uploadPrompt.js +5 -5
  203. package/lib/sandboxSync.js +24 -41
  204. package/lib/sandboxes.js +19 -47
  205. package/lib/schema.js +3 -3
  206. package/lib/serverlessLogs.js +11 -13
  207. package/lib/theme/__tests__/migrate.test.js +3 -3
  208. package/lib/theme/migrate.js +2 -2
  209. package/lib/ui/SpinniesManager.d.ts +2 -0
  210. package/lib/ui/SpinniesManager.js +7 -0
  211. package/lib/ui/boxen.js +1 -2
  212. package/lib/ui/git.js +13 -10
  213. package/lib/ui/index.d.ts +4 -0
  214. package/lib/ui/index.js +47 -38
  215. package/lib/ui/serverlessFunctionLogs.js +9 -7
  216. package/lib/ui/uiMessages.d.ts +68 -0
  217. package/lib/ui/uiMessages.js +71 -0
  218. package/lib/usageTracking.js +7 -7
  219. package/lib/validation.js +20 -23
  220. package/lib/yargsUtils.d.ts +1 -1
  221. package/lib/yargsUtils.js +12 -5
  222. package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +2 -2
  223. package/mcp-server/tools/index.js +4 -0
  224. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +23 -0
  225. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +68 -0
  226. package/mcp-server/tools/project/GetApplicationInfoTool.d.ts +11 -0
  227. package/mcp-server/tools/project/GetApplicationInfoTool.js +49 -0
  228. package/mcp-server/tools/project/GetConfigValuesTool.js +2 -2
  229. package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +2 -2
  230. package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.d.ts +1 -0
  231. package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.js +169 -0
  232. package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.d.ts +1 -0
  233. package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.js +115 -0
  234. package/mcp-server/utils/toolUsageTracking.js +2 -2
  235. package/package.json +6 -6
  236. package/types/Yargs.d.ts +1 -1
  237. package/commands/app/__tests__/install.test.js +0 -47
  238. package/commands/app/install.d.ts +0 -8
  239. package/commands/app/install.js +0 -122
  240. package/lib/middleware/__test__/utils.test.js +0 -51
  241. package/lib/middleware/utils.d.ts +0 -8
  242. package/lib/middleware/utils.js +0 -14
  243. /package/commands/{app/__tests__/install.test.d.ts → project/__tests__/validate.test.d.ts} +0 -0
  244. /package/lib/middleware/__test__/{utils.test.d.ts → commandTargetingUtils.test.d.ts} +0 -0
@@ -1,15 +1,13 @@
1
- import { logger } from '@hubspot/local-dev-lib/logger';
2
1
  import { addSecret, fetchSecrets } from '@hubspot/local-dev-lib/api/secrets';
3
2
  import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
4
3
  import { trackCommandUsage } from '../../lib/usageTracking.js';
5
- import { uiAccountDescription } from '../../lib/ui/index.js';
6
4
  import { secretValuePrompt, secretNamePrompt, } from '../../lib/prompts/secretPrompt.js';
7
- import { i18n } from '../../lib/lang.js';
5
+ import { commands } from '../../lang/en.js';
6
+ import { uiLogger } from '../../lib/ui/logger.js';
8
7
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
9
- import { uiCommandReference } from '../../lib/ui/index.js';
10
8
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
11
9
  const command = 'add [name]';
12
- const describe = i18n(`commands.secret.subcommands.add.describe`);
10
+ const describe = commands.secret.subcommands.add.describe;
13
11
  async function handler(args) {
14
12
  const { name, derivedAccountId } = args;
15
13
  let secretName = name;
@@ -21,23 +19,15 @@ async function handler(args) {
21
19
  }
22
20
  const { data: { results: secrets }, } = await fetchSecrets(derivedAccountId);
23
21
  if (secrets.includes(secretName)) {
24
- logger.error(i18n(`commands.secret.subcommands.add.errors.alreadyExists`, {
25
- secretName,
26
- command: uiCommandReference('hs secret update'),
27
- }));
22
+ uiLogger.error(commands.secret.subcommands.add.errors.alreadyExists(secretName));
28
23
  process.exit(EXIT_CODES.ERROR);
29
24
  }
30
25
  const { secretValue } = await secretValuePrompt();
31
26
  await addSecret(derivedAccountId, secretName, secretValue);
32
- logger.success(i18n(`commands.secret.subcommands.add.success.add`, {
33
- accountIdentifier: uiAccountDescription(derivedAccountId),
34
- secretName,
35
- }));
27
+ uiLogger.success(commands.secret.subcommands.add.success.add(secretName, derivedAccountId));
36
28
  }
37
29
  catch (err) {
38
- logger.error(i18n(`commands.secret.subcommands.add.errors.add`, {
39
- secretName: secretName || '',
40
- }));
30
+ uiLogger.error(commands.secret.subcommands.add.errors.add(secretName || ''));
41
31
  logError(err, new ApiErrorContext({
42
32
  request: 'add secret',
43
33
  accountId: derivedAccountId,
@@ -46,7 +36,7 @@ async function handler(args) {
46
36
  }
47
37
  function addSecretBuilder(yargs) {
48
38
  yargs.positional('name', {
49
- describe: i18n(`commands.secret.subcommands.add.positionals.name.describe`),
39
+ describe: commands.secret.subcommands.add.positionals.name.describe,
50
40
  type: 'string',
51
41
  });
52
42
  return yargs;
@@ -1,15 +1,14 @@
1
- import { logger } from '@hubspot/local-dev-lib/logger';
2
1
  import { deleteSecret, fetchSecrets } from '@hubspot/local-dev-lib/api/secrets';
3
2
  import { secretListPrompt } from '../../lib/prompts/secretPrompt.js';
4
3
  import { confirmPrompt } from '../../lib/prompts/promptUtils.js';
5
4
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
6
5
  import { ApiErrorContext, logError } from '../../lib/errorHandlers/index.js';
7
6
  import { trackCommandUsage } from '../../lib/usageTracking.js';
8
- import { uiAccountDescription } from '../../lib/ui/index.js';
9
- import { i18n } from '../../lib/lang.js';
7
+ import { commands } from './../../lang/en.js';
8
+ import { uiLogger } from '../../lib/ui/logger.js';
10
9
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
11
10
  const command = 'delete [name]';
12
- const describe = i18n(`commands.secret.subcommands.delete.describe`);
11
+ const describe = commands.secret.subcommands.delete.describe;
13
12
  async function handler(args) {
14
13
  const { name, derivedAccountId, force } = args;
15
14
  let secretName = name;
@@ -17,36 +16,27 @@ async function handler(args) {
17
16
  try {
18
17
  const { data: { results: secrets }, } = await fetchSecrets(derivedAccountId);
19
18
  if (secretName && !secrets.includes(secretName)) {
20
- logger.error(i18n(`commands.secret.subcommands.delete.errors.noSecret`, {
21
- secretName,
22
- }));
19
+ uiLogger.error(commands.secret.subcommands.delete.errors.noSecret(secretName));
23
20
  process.exit(EXIT_CODES.ERROR);
24
21
  }
25
22
  if (!secretName) {
26
- const { secretToModify } = await secretListPrompt(secrets, i18n(`commands.secret.subcommands.delete.selectSecret`));
23
+ const { secretToModify } = await secretListPrompt(secrets, commands.secret.subcommands.delete.selectSecret);
27
24
  secretName = secretToModify;
28
25
  }
29
26
  const confirmDelete = force ||
30
- (await confirmPrompt(i18n(`commands.secret.subcommands.delete.confirmDelete`, {
31
- secretName,
32
- }), {
27
+ (await confirmPrompt(commands.secret.subcommands.delete.confirmDelete(secretName), {
33
28
  defaultAnswer: false,
34
29
  }));
35
30
  if (!confirmDelete) {
36
- logger.success(i18n(`commands.secret.subcommands.delete.deleteCanceled`));
31
+ uiLogger.success(commands.secret.subcommands.delete.deleteCanceled);
37
32
  process.exit(EXIT_CODES.SUCCESS);
38
33
  }
39
34
  await deleteSecret(derivedAccountId, secretName);
40
- logger.success(i18n(`commands.secret.subcommands.delete.success.delete`, {
41
- accountIdentifier: uiAccountDescription(derivedAccountId),
42
- secretName,
43
- }));
35
+ uiLogger.success(commands.secret.subcommands.delete.success.delete(secretName, derivedAccountId));
44
36
  }
45
37
  catch (err) {
46
38
  if (secretName) {
47
- logger.error(i18n(`commands.secret.subcommands.delete.errors.delete`, {
48
- secretName,
49
- }));
39
+ uiLogger.error(commands.secret.subcommands.delete.errors.delete(secretName));
50
40
  }
51
41
  logError(err, new ApiErrorContext({
52
42
  request: 'delete a secret',
@@ -57,7 +47,7 @@ async function handler(args) {
57
47
  function deleteSecretBuilder(yargs) {
58
48
  yargs
59
49
  .positional('name', {
60
- describe: i18n(`commands.secret.subcommands.delete.positionals.name.describe`),
50
+ describe: commands.secret.subcommands.delete.positionals.name.describe,
61
51
  type: 'string',
62
52
  })
63
53
  .options('force', {
@@ -1,26 +1,24 @@
1
- import { logger } from '@hubspot/local-dev-lib/logger';
2
1
  import { fetchSecrets } from '@hubspot/local-dev-lib/api/secrets';
3
2
  import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
4
3
  import { trackCommandUsage } from '../../lib/usageTracking.js';
5
4
  import { uiAccountDescription } from '../../lib/ui/index.js';
6
- import { i18n } from '../../lib/lang.js';
5
+ import { commands } from '../../lang/en.js';
6
+ import { uiLogger } from '../../lib/ui/logger.js';
7
7
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
8
8
  const command = 'list';
9
- const describe = i18n(`commands.secret.subcommands.list.describe`);
9
+ const describe = commands.secret.subcommands.list.describe;
10
10
  async function handler(args) {
11
11
  const { derivedAccountId } = args;
12
12
  trackCommandUsage('secrets-list', {}, derivedAccountId);
13
13
  try {
14
14
  const { data: { results }, } = await fetchSecrets(derivedAccountId);
15
- const groupLabel = i18n(`commands.secret.subcommands.list.groupLabel`, {
16
- accountIdentifier: uiAccountDescription(derivedAccountId),
17
- });
18
- logger.group(groupLabel);
19
- results.forEach(secret => logger.log(secret));
20
- logger.groupEnd();
15
+ const groupLabel = commands.secret.subcommands.list.groupLabel(uiAccountDescription(derivedAccountId));
16
+ uiLogger.group(groupLabel);
17
+ results.forEach(secret => uiLogger.log(secret));
18
+ uiLogger.groupEnd();
21
19
  }
22
20
  catch (err) {
23
- logger.error(i18n(`commands.secret.subcommands.list.errors.list`));
21
+ uiLogger.error(commands.secret.subcommands.list.errors.list);
24
22
  logError(err, new ApiErrorContext({
25
23
  request: 'add secret',
26
24
  accountId: derivedAccountId,
@@ -1,14 +1,13 @@
1
1
  import { updateSecret, fetchSecrets } from '@hubspot/local-dev-lib/api/secrets';
2
2
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
3
- import { logger } from '@hubspot/local-dev-lib/logger';
4
3
  import { ApiErrorContext, logError } from '../../lib/errorHandlers/index.js';
5
4
  import { trackCommandUsage } from '../../lib/usageTracking.js';
6
- import { uiAccountDescription } from '../../lib/ui/index.js';
7
5
  import { secretValuePrompt, secretListPrompt, } from '../../lib/prompts/secretPrompt.js';
8
- import { i18n } from '../../lib/lang.js';
6
+ import { commands } from '../../lang/en.js';
7
+ import { uiLogger } from '../../lib/ui/logger.js';
9
8
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
10
9
  const command = 'update [name]';
11
- const describe = i18n(`commands.secret.subcommands.update.describe`);
10
+ const describe = commands.secret.subcommands.update.describe;
12
11
  async function handler(args) {
13
12
  const { name, derivedAccountId } = args;
14
13
  let secretName = name;
@@ -16,27 +15,20 @@ async function handler(args) {
16
15
  try {
17
16
  const { data: { results: secrets }, } = await fetchSecrets(derivedAccountId);
18
17
  if (secretName && !secrets.includes(secretName)) {
19
- logger.error(i18n(`commands.secret.subcommands.update.errors.noSecret`, {
20
- secretName,
21
- }));
18
+ uiLogger.error(commands.secret.subcommands.update.errors.noSecret(secretName));
22
19
  process.exit(EXIT_CODES.ERROR);
23
20
  }
24
21
  if (!secretName) {
25
- const { secretToModify } = await secretListPrompt(secrets, i18n(`commands.secret.subcommands.update.selectSecret`));
22
+ const { secretToModify } = await secretListPrompt(secrets, commands.secret.subcommands.update.selectSecret);
26
23
  secretName = secretToModify;
27
24
  }
28
25
  const { secretValue } = await secretValuePrompt();
29
26
  await updateSecret(derivedAccountId, secretName, secretValue);
30
- logger.success(i18n(`commands.secret.subcommands.update.success.update`, {
31
- accountIdentifier: uiAccountDescription(derivedAccountId),
32
- secretName,
33
- }));
34
- logger.log(i18n(`commands.secret.subcommands.update.success.updateExplanation`));
27
+ uiLogger.success(commands.secret.subcommands.update.success.update(secretName, derivedAccountId));
28
+ uiLogger.log(commands.secret.subcommands.update.success.updateExplanation);
35
29
  }
36
30
  catch (err) {
37
- logger.error(i18n(`commands.secret.subcommands.update.errors.update`, {
38
- secretName: secretName || '',
39
- }));
31
+ uiLogger.error(commands.secret.subcommands.update.errors.update(secretName || ''));
40
32
  logError(err, new ApiErrorContext({
41
33
  request: 'update secret',
42
34
  accountId: derivedAccountId,
@@ -45,7 +37,7 @@ async function handler(args) {
45
37
  }
46
38
  function updateSecretBuilder(yargs) {
47
39
  yargs.positional('name', {
48
- describe: i18n(`commands.secret.subcommands.update.positionals.name.describe`),
40
+ describe: commands.secret.subcommands.update.positionals.name.describe,
49
41
  type: 'string',
50
42
  });
51
43
  return yargs;
@@ -2,10 +2,10 @@ import addSecretCommand from './secret/addSecret.js';
2
2
  import listSecretCommand from './secret/listSecret.js';
3
3
  import deleteSecretCommand from './secret/deleteSecret.js';
4
4
  import updateSecretCommand from './secret/updateSecret.js';
5
- import { i18n } from '../lib/lang.js';
5
+ import { commands } from '../lang/en.js';
6
6
  import { makeYargsBuilder } from '../lib/yargsUtils.js';
7
7
  const command = ['secret', 'secrets'];
8
- const describe = i18n(`commands.secret.describe`);
8
+ const describe = commands.secret.describe;
9
9
  function secretBuilder(yargs) {
10
10
  yargs
11
11
  .command(listSecretCommand)
@@ -1,12 +1,12 @@
1
1
  import yargs from 'yargs';
2
- import { addAccountOptions, addConfigOptions, addUseEnvironmentOptions, addTestingOptions, } from '../../../lib/commonOpts.js';
2
+ import { addConfigOptions, addUseEnvironmentOptions, addTestingOptions, } from '../../../lib/commonOpts.js';
3
3
  import testAccountDeleteCommand from '../delete.js';
4
4
  vi.mock('../../../lib/commonOpts');
5
5
  describe('commands/testAccount/delete', () => {
6
6
  const yargsMock = yargs;
7
7
  describe('command', () => {
8
8
  it('should have the correct command structure', () => {
9
- expect(testAccountDeleteCommand.command).toEqual('delete <test-account-id>');
9
+ expect(testAccountDeleteCommand.command).toEqual('delete [test-account]');
10
10
  });
11
11
  });
12
12
  describe('describe', () => {
@@ -20,8 +20,6 @@ describe('commands/testAccount/delete', () => {
20
20
  expect(yargsMock.example).toHaveBeenCalledTimes(1);
21
21
  expect(addTestingOptions).toHaveBeenCalledTimes(1);
22
22
  expect(addTestingOptions).toHaveBeenCalledWith(yargsMock);
23
- expect(addAccountOptions).toHaveBeenCalledTimes(1);
24
- expect(addAccountOptions).toHaveBeenCalledWith(yargsMock);
25
23
  expect(addConfigOptions).toHaveBeenCalledTimes(1);
26
24
  expect(addConfigOptions).toHaveBeenCalledWith(yargsMock);
27
25
  expect(addUseEnvironmentOptions).toHaveBeenCalledTimes(1);
@@ -75,9 +75,6 @@ async function handler(args) {
75
75
  resultJson.personalAccessKey = createResult.personalAccessKey;
76
76
  }
77
77
  catch (err) {
78
- SpinniesManager.fail('createTestAccount', {
79
- text: commands.testAccount.create.polling.createFailure,
80
- });
81
78
  logError(err);
82
79
  SpinniesManager.fail('createTestAccount', {
83
80
  text: commands.testAccount.create.polling.createFailure,
@@ -1,6 +1,7 @@
1
- import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, TestingArgs, YargsCommandModule } from '../../types/Yargs.js';
2
- type DeleteTestAccountArgs = CommonArgs & AccountArgs & ConfigArgs & TestingArgs & EnvironmentArgs & {
3
- testAccountId: number;
1
+ import { CommonArgs, ConfigArgs, EnvironmentArgs, TestingArgs, YargsCommandModule } from '../../types/Yargs.js';
2
+ type DeleteTestAccountArgs = CommonArgs & ConfigArgs & TestingArgs & EnvironmentArgs & {
3
+ testAccount?: string | number;
4
+ force?: boolean;
4
5
  };
5
6
  declare const deleteTestAccountCommand: YargsCommandModule<unknown, DeleteTestAccountArgs>;
6
7
  export default deleteTestAccountCommand;
@@ -1,39 +1,180 @@
1
- import { deleteDeveloperTestAccount } from '@hubspot/local-dev-lib/api/developerTestAccounts';
1
+ import { fetchDeveloperTestAccounts, deleteDeveloperTestAccount, } from '@hubspot/local-dev-lib/api/developerTestAccounts';
2
2
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
3
3
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
4
4
  import { uiLogger } from '../../lib/ui/logger.js';
5
5
  import { trackCommandUsage } from '../../lib/usageTracking.js';
6
6
  import { commands } from '../../lang/en.js';
7
- const command = 'delete <test-account-id>';
7
+ import { deleteAccount, getAccountConfig, getAccountId, getConfigPath, loadConfig, updateDefaultAccount, } from '@hubspot/local-dev-lib/config';
8
+ import { promptUser } from '../../lib/prompts/promptUtils.js';
9
+ import { debugError } from '../../lib/errorHandlers/index.js';
10
+ const command = 'delete [test-account]';
8
11
  const describe = commands.testAccount.delete.describe;
9
- async function handler(args) {
10
- const { derivedAccountId, testAccountId } = args;
11
- trackCommandUsage('test-account-delete', {}, derivedAccountId);
12
+ async function getAccountPromptOptions(derivedAccountId) {
12
13
  try {
13
- await deleteDeveloperTestAccount(derivedAccountId, testAccountId, true);
14
- uiLogger.success(commands.testAccount.delete.success.testAccountDeleted(testAccountId));
14
+ const { data } = await fetchDeveloperTestAccounts(derivedAccountId);
15
+ return data.results.map(testAccount => ({
16
+ name: `${testAccount.accountName} (${testAccount.id})`,
17
+ value: testAccount.id,
18
+ }));
15
19
  }
16
20
  catch (err) {
17
- uiLogger.error(commands.testAccount.delete.errors.failedToDelete);
21
+ uiLogger.error(commands.testAccount.delete.errors.failedToFetchTestAccounts);
22
+ throw err;
23
+ }
24
+ }
25
+ async function accountToDeleteSelectionPrompt(derivedAccountId) {
26
+ const accountData = await getAccountPromptOptions(derivedAccountId);
27
+ if (accountData.length === 0) {
28
+ uiLogger.error(commands.testAccount.delete.errors.noAccountsToDelete(derivedAccountId));
29
+ process.exit(EXIT_CODES.ERROR);
30
+ }
31
+ const { testAccountToDelete } = await promptUser([
32
+ {
33
+ type: 'list',
34
+ name: 'testAccountToDelete',
35
+ pageSize: 20,
36
+ message: commands.testAccount.delete.prompts.selectTestAccounts,
37
+ choices: accountData,
38
+ },
39
+ ]);
40
+ return testAccountToDelete;
41
+ }
42
+ async function confirmDeletion() {
43
+ const { shouldDelete } = await promptUser([
44
+ {
45
+ type: 'confirm',
46
+ name: 'shouldDelete',
47
+ message: commands.testAccount.delete.prompts.confirmDeletion,
48
+ },
49
+ ]);
50
+ return shouldDelete;
51
+ }
52
+ async function deleteTestAccountInHubSpot(derivedAccountId, accountId) {
53
+ try {
54
+ await deleteDeveloperTestAccount(derivedAccountId, accountId, true);
55
+ uiLogger.success(commands.testAccount.delete.success.testAccountDeletedFromHubSpot(accountId));
56
+ }
57
+ catch (e) {
58
+ debugError(e);
59
+ uiLogger.error(commands.testAccount.delete.errors.failedToDelete(accountId));
60
+ }
61
+ }
62
+ async function deleteTestAccountFromConfig(testAccountId, parentAccountName, account) {
63
+ try {
64
+ // If the account isn't in the local config then it wasn't auth'd on the local machine
65
+ if (account && account.name && account.accountType) {
66
+ // If the deleted test account was the default account, replace the default account with the parent account
67
+ loadConfig(getConfigPath()); // Get updated version of the config
68
+ const defaultAccountId = getAccountId(); // We need to get the current default accountId before delete the test account
69
+ await deleteAccount(account.name);
70
+ uiLogger.success(commands.testAccount.delete.success.testAccountDeletedFromConfig(testAccountId));
71
+ if (testAccountId === defaultAccountId) {
72
+ updateDefaultAccount(parentAccountName);
73
+ uiLogger.info(commands.testAccount.delete.info.replaceDefaultAccount(testAccountId, parentAccountName));
74
+ }
75
+ }
76
+ }
77
+ catch (e) {
78
+ debugError(e);
79
+ uiLogger.error(commands.testAccount.delete.errors.failedToDeleteFromConfig(testAccountId));
80
+ }
81
+ }
82
+ async function validateTestAccountConfigs(testAccountId) {
83
+ if (!testAccountId) {
84
+ uiLogger.error(commands.testAccount.delete.errors.testAccountNotFound(testAccountId));
85
+ process.exit(EXIT_CODES.ERROR);
86
+ }
87
+ const testAccountConfig = getAccountConfig(testAccountId);
88
+ if (!testAccountConfig) {
89
+ uiLogger.error(commands.testAccount.delete.errors.testAccountNotFound(testAccountId));
18
90
  process.exit(EXIT_CODES.ERROR);
19
91
  }
92
+ const parentAccountConfig = getAccountConfig(testAccountConfig.parentAccountId);
93
+ if (!parentAccountConfig) {
94
+ uiLogger.error(commands.testAccount.delete.errors.parentAccountNotFound(testAccountId));
95
+ process.exit(EXIT_CODES.ERROR);
96
+ }
97
+ const parentAccountName = parentAccountConfig.name;
98
+ return { testAccountConfig, parentAccountName };
99
+ }
100
+ async function handler(args) {
101
+ const { derivedAccountId, testAccount, force } = args;
102
+ trackCommandUsage('test-account-delete', {}, derivedAccountId);
103
+ let testAccountIdToDelete = 0;
104
+ // See if the account exists
105
+ if (testAccount) {
106
+ const accountId = getAccountId(testAccount);
107
+ await validateTestAccountConfigs(accountId);
108
+ if (accountId) {
109
+ testAccountIdToDelete = accountId;
110
+ }
111
+ }
112
+ // Prompt for selection when name or id aren't provided
113
+ if (!testAccountIdToDelete) {
114
+ try {
115
+ testAccountIdToDelete =
116
+ await accountToDeleteSelectionPrompt(derivedAccountId);
117
+ }
118
+ catch (err) {
119
+ debugError(err);
120
+ uiLogger.error(commands.testAccount.delete.errors.failedToSelectAccount);
121
+ process.exit(EXIT_CODES.ERROR);
122
+ }
123
+ }
124
+ const { testAccountConfig, parentAccountName } = await validateTestAccountConfigs(testAccountIdToDelete);
125
+ // If --force, don't prompt user; else confirm deletion
126
+ let shouldDeleteAccount;
127
+ if (force) {
128
+ shouldDeleteAccount = true;
129
+ }
130
+ else {
131
+ shouldDeleteAccount = await confirmDeletion();
132
+ }
133
+ if (shouldDeleteAccount) {
134
+ const parentAccountId = testAccountConfig.parentAccountId;
135
+ await deleteTestAccountInHubSpot(parentAccountId, testAccountIdToDelete);
136
+ await deleteTestAccountFromConfig(testAccountIdToDelete, parentAccountName, testAccountConfig);
137
+ }
138
+ else {
139
+ uiLogger.info(commands.testAccount.delete.info.deletionCanceled);
140
+ }
20
141
  process.exit(EXIT_CODES.SUCCESS);
21
142
  }
22
143
  function deleteTestAccountBuilder(yargs) {
23
- yargs.positional('test-account-id', {
24
- type: 'number',
25
- description: commands.testAccount.delete.positionals.testAccountId,
26
- required: true,
144
+ yargs.positional('test-account', {
145
+ type: 'string',
146
+ description: commands.testAccount.delete.options.id,
147
+ required: false,
148
+ });
149
+ yargs.option('force', {
150
+ describe: commands.upload.options.force,
151
+ type: 'boolean',
152
+ default: false,
27
153
  });
28
154
  yargs.example([
29
- ['$0 delete 1234567890', commands.testAccount.delete.example(1234567890)],
155
+ [
156
+ '$0 test-account delete 12345678',
157
+ commands.testAccount.delete.examples.withPositionalID(12345678),
158
+ ],
159
+ [
160
+ '$0 test-account delete my-test-account',
161
+ commands.testAccount.delete.examples.withPositionalName('my-test-account'),
162
+ ],
163
+ [
164
+ '$0 test-account delete --test-account=12345678',
165
+ commands.testAccount.delete.examples.withID(12345678),
166
+ ],
167
+ [
168
+ '$0 test-account delete --test-account=my-test-account',
169
+ commands.testAccount.delete.examples.withName('my-test-account'),
170
+ ],
171
+ ['$0 test-account delete', commands.testAccount.delete.examples.withoutId],
30
172
  ]);
31
173
  return yargs;
32
174
  }
33
175
  const builder = makeYargsBuilder(deleteTestAccountBuilder, command, describe, {
34
176
  useGlobalOptions: true,
35
177
  useEnvironmentOptions: true,
36
- useAccountOptions: true,
37
178
  useConfigOptions: true,
38
179
  useTestingOptions: true,
39
180
  });
@@ -15,8 +15,6 @@ import { handleExit, handleKeypress } from '../../lib/process.js';
15
15
  import { getProjectConfig } from '../../lib/projects/config.js';
16
16
  import { findProjectComponents } from '../../lib/projects/structure.js';
17
17
  import { ComponentTypes } from '../../types/Projects.js';
18
- import { hasFeature } from '../../lib/hasFeature.js';
19
- import { FEATURES } from '../../lib/constants.js';
20
18
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
21
19
  import { uiLogger } from '../../lib/ui/logger.js';
22
20
  const command = 'preview [--src] [--dest]';
@@ -150,8 +148,7 @@ async function handler(args) {
150
148
  catch (e) {
151
149
  uiLogger.warn('Unified dev server requires node 20 to run. Defaulting to legacy preview.');
152
150
  }
153
- const isUngatedForUnified = await hasFeature(derivedAccountId, FEATURES.UNIFIED_THEME_PREVIEW);
154
- if (isUngatedForUnified && createUnifiedDevServer) {
151
+ if (createUnifiedDevServer) {
155
152
  if (port) {
156
153
  process.env['PORT'] = port.toString();
157
154
  }