@hubspot/cli 7.10.0-beta.2 → 7.10.0-experimental.0

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 (198) hide show
  1. package/bin/cli.js +5 -4
  2. package/commands/__tests__/getStarted.test.js +10 -0
  3. package/commands/__tests__/project.test.js +3 -0
  4. package/commands/account/__tests__/rename.test.js +10 -3
  5. package/commands/account/auth.js +10 -14
  6. package/commands/account/clean.js +11 -19
  7. package/commands/account/createOverride.js +15 -11
  8. package/commands/account/info.js +8 -5
  9. package/commands/account/list.js +15 -19
  10. package/commands/account/remove.js +23 -22
  11. package/commands/account/removeOverride.js +6 -6
  12. package/commands/account/rename.js +2 -2
  13. package/commands/account/use.js +19 -8
  14. package/commands/app/__tests__/migrate.test.js +8 -4
  15. package/commands/app/migrate.js +2 -2
  16. package/commands/auth.js +18 -14
  17. package/commands/config/migrate.js +5 -5
  18. package/commands/customObject/createSchema.js +2 -3
  19. package/commands/customObject/updateSchema.js +2 -3
  20. package/commands/getStarted.js +2 -3
  21. package/commands/hubdb/__tests__/list.test.js +1 -0
  22. package/commands/hubdb/list.js +2 -2
  23. package/commands/init.js +36 -32
  24. package/commands/project/__tests__/deploy.test.js +10 -5
  25. package/commands/project/__tests__/devUnifiedFlow.test.js +6 -4
  26. package/commands/project/__tests__/lint.test.js +709 -0
  27. package/commands/project/__tests__/logs.test.js +4 -0
  28. package/commands/project/__tests__/validate.test.js +2 -2
  29. package/commands/project/cloneApp.js +2 -2
  30. package/commands/project/deploy.js +2 -2
  31. package/commands/project/dev/deprecatedFlow.js +4 -5
  32. package/commands/project/dev/index.js +6 -3
  33. package/commands/project/dev/unifiedFlow.js +4 -5
  34. package/commands/project/lint.d.ts +6 -0
  35. package/commands/project/lint.js +178 -0
  36. package/commands/project/logs.js +2 -3
  37. package/commands/project/profile/add.js +6 -7
  38. package/commands/project/profile/delete.js +2 -2
  39. package/commands/project/upload.js +2 -2
  40. package/commands/project/validate.js +2 -2
  41. package/commands/project.js +2 -0
  42. package/commands/sandbox/__tests__/create.test.js +14 -5
  43. package/commands/sandbox/create.js +4 -5
  44. package/commands/sandbox/delete.js +23 -20
  45. package/commands/testAccount/create.js +2 -2
  46. package/commands/testAccount/delete.js +9 -8
  47. package/lang/en.d.ts +40 -6
  48. package/lang/en.js +49 -9
  49. package/lib/__tests__/buildAccount.test.js +22 -30
  50. package/lib/__tests__/commonOpts.test.js +9 -13
  51. package/lib/__tests__/developerTestAccounts.test.js +29 -17
  52. package/lib/__tests__/importData.test.js +20 -10
  53. package/lib/__tests__/oauth.test.js +19 -8
  54. package/lib/__tests__/sandboxSync.test.js +33 -11
  55. package/lib/__tests__/sandboxes.test.js +30 -19
  56. package/lib/__tests__/usageTracking.test.js +10 -10
  57. package/lib/__tests__/validation.test.js +32 -32
  58. package/lib/accountTypes.d.ts +9 -9
  59. package/lib/accountTypes.js +2 -4
  60. package/lib/app/__tests__/migrate.test.js +15 -0
  61. package/lib/app/__tests__/migrate_legacy.test.js +9 -0
  62. package/lib/app/migrate_legacy.d.ts +2 -2
  63. package/lib/buildAccount.d.ts +4 -4
  64. package/lib/buildAccount.js +7 -14
  65. package/lib/commonOpts.js +3 -3
  66. package/lib/configMigrate.d.ts +2 -2
  67. package/lib/configMigrate.js +42 -18
  68. package/lib/configOptions.js +3 -2
  69. package/lib/developerTestAccounts.d.ts +3 -3
  70. package/lib/developerTestAccounts.js +4 -7
  71. package/lib/doctor/DiagnosticInfoBuilder.d.ts +1 -1
  72. package/lib/doctor/DiagnosticInfoBuilder.js +9 -6
  73. package/lib/doctor/Doctor.js +4 -3
  74. package/lib/doctor/__tests__/Diagnosis.test.js +4 -3
  75. package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.js +17 -9
  76. package/lib/doctor/__tests__/Doctor.test.js +14 -0
  77. package/lib/importData.js +8 -7
  78. package/lib/links.js +5 -5
  79. package/lib/middleware/{__test__ → __tests__}/commandTargetingUtils.test.js +3 -3
  80. package/lib/middleware/{__test__ → __tests__}/configMiddleware.test.js +23 -22
  81. package/lib/middleware/{__test__ → __tests__}/gitMiddleware.test.js +9 -7
  82. package/lib/middleware/autoUpdateMiddleware.js +12 -4
  83. package/lib/middleware/commandTargetingUtils.js +3 -2
  84. package/lib/middleware/configMiddleware.d.ts +6 -1
  85. package/lib/middleware/configMiddleware.js +36 -15
  86. package/lib/middleware/gitMiddleware.js +8 -4
  87. package/lib/oauth.d.ts +2 -2
  88. package/lib/oauth.js +8 -10
  89. package/lib/projects/__tests__/AppDevModeInterface.test.js +17 -6
  90. package/lib/projects/__tests__/DevServerManager.test.js +1 -0
  91. package/lib/projects/__tests__/LocalDevProcess.test.js +1 -0
  92. package/lib/projects/__tests__/deploy.test.js +1 -0
  93. package/lib/projects/__tests__/uieLinting.test.js +640 -0
  94. package/lib/projects/create/__tests__/v2.test.js +11 -0
  95. package/lib/projects/localDev/AppDevModeInterface.js +2 -2
  96. package/lib/projects/localDev/DevServerManager_DEPRECATED.js +2 -2
  97. package/lib/projects/localDev/DevSessionManager.d.ts +17 -0
  98. package/lib/projects/localDev/DevSessionManager.js +56 -0
  99. package/lib/projects/localDev/LocalDevLogger.d.ts +3 -0
  100. package/lib/projects/localDev/LocalDevLogger.js +13 -4
  101. package/lib/projects/localDev/LocalDevManager_DEPRECATED.js +3 -3
  102. package/lib/projects/localDev/LocalDevProcess.d.ts +1 -0
  103. package/lib/projects/localDev/LocalDevProcess.js +12 -1
  104. package/lib/projects/localDev/LocalDevState.d.ts +3 -0
  105. package/lib/projects/localDev/LocalDevState.js +9 -0
  106. package/lib/projects/localDev/helpers/account.d.ts +10 -10
  107. package/lib/projects/localDev/helpers/account.js +6 -11
  108. package/lib/projects/localDev/helpers/devSessionsApi.d.ts +9 -0
  109. package/lib/projects/localDev/helpers/devSessionsApi.js +19 -0
  110. package/lib/projects/uieLinting.d.ts +33 -0
  111. package/lib/projects/uieLinting.js +222 -0
  112. package/lib/projects/urls.js +5 -6
  113. package/lib/prompts/__tests__/downloadProjectPrompt.test.js +7 -5
  114. package/lib/prompts/accountNamePrompt.js +3 -3
  115. package/lib/prompts/accountsPrompt.d.ts +1 -1
  116. package/lib/prompts/accountsPrompt.js +6 -7
  117. package/lib/prompts/confirmImportDataPrompt.js +2 -2
  118. package/lib/prompts/downloadProjectPrompt.d.ts +1 -0
  119. package/lib/prompts/downloadProjectPrompt.js +5 -2
  120. package/lib/prompts/importDataTestAccountSelectPrompt.js +4 -5
  121. package/lib/prompts/personalAccessKeyPrompt.js +2 -2
  122. package/lib/prompts/projectDevTargetAccountPrompt.d.ts +3 -3
  123. package/lib/prompts/projectDevTargetAccountPrompt.js +5 -7
  124. package/lib/prompts/sandboxesPrompt.js +7 -8
  125. package/lib/prompts/setAsDefaultAccountPrompt.js +7 -6
  126. package/lib/sandboxSync.d.ts +2 -2
  127. package/lib/sandboxSync.js +3 -9
  128. package/lib/sandboxes.d.ts +4 -4
  129. package/lib/sandboxes.js +6 -11
  130. package/lib/serverlessLogs.js +2 -2
  131. package/lib/theme/__tests__/migrate.test.js +15 -0
  132. package/lib/ui/index.js +6 -3
  133. package/lib/usageTracking.js +15 -8
  134. package/lib/validation.js +13 -11
  135. package/mcp-server/tools/cms/HsCreateFunctionTool.js +4 -2
  136. package/mcp-server/tools/cms/HsCreateModuleTool.js +4 -2
  137. package/mcp-server/tools/cms/HsCreateTemplateTool.js +4 -2
  138. package/mcp-server/tools/cms/HsFunctionLogsTool.js +4 -2
  139. package/mcp-server/tools/cms/HsListFunctionsTool.js +3 -1
  140. package/mcp-server/tools/cms/HsListTool.js +3 -1
  141. package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.js +1 -0
  142. package/mcp-server/tools/index.js +4 -0
  143. package/mcp-server/tools/project/AddFeatureToProjectTool.js +4 -2
  144. package/mcp-server/tools/project/CreateProjectTool.js +4 -2
  145. package/mcp-server/tools/project/CreateTestAccountTool.js +17 -7
  146. package/mcp-server/tools/project/DeployProjectTool.js +3 -1
  147. package/mcp-server/tools/project/DocFetchTool.js +6 -4
  148. package/mcp-server/tools/project/DocsSearchTool.d.ts +1 -1
  149. package/mcp-server/tools/project/DocsSearchTool.js +10 -8
  150. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +1 -1
  151. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +9 -7
  152. package/mcp-server/tools/project/GetApplicationInfoTool.js +8 -6
  153. package/mcp-server/tools/project/GetBuildLogsTool.d.ts +26 -0
  154. package/mcp-server/tools/project/GetBuildLogsTool.js +125 -0
  155. package/mcp-server/tools/project/GetBuildStatusTool.d.ts +26 -0
  156. package/mcp-server/tools/project/GetBuildStatusTool.js +166 -0
  157. package/mcp-server/tools/project/GetConfigValuesTool.d.ts +1 -1
  158. package/mcp-server/tools/project/GetConfigValuesTool.js +9 -7
  159. package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +1 -1
  160. package/mcp-server/tools/project/GuidedWalkthroughTool.js +5 -3
  161. package/mcp-server/tools/project/UploadProjectTools.js +3 -1
  162. package/mcp-server/tools/project/ValidateProjectTool.js +4 -2
  163. package/mcp-server/tools/project/__tests__/CreateTestAccountTool.test.js +12 -2
  164. package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +5 -1
  165. package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +23 -11
  166. package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.js +7 -5
  167. package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.js +7 -5
  168. package/mcp-server/tools/project/__tests__/GetBuildLogsTool.test.d.ts +1 -0
  169. package/mcp-server/tools/project/__tests__/GetBuildLogsTool.test.js +305 -0
  170. package/mcp-server/tools/project/__tests__/GetBuildStatusTool.test.d.ts +1 -0
  171. package/mcp-server/tools/project/__tests__/GetBuildStatusTool.test.js +240 -0
  172. package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +8 -6
  173. package/mcp-server/utils/__tests__/content.test.js +21 -20
  174. package/mcp-server/utils/__tests__/feedbackTracking.test.js +34 -28
  175. package/mcp-server/utils/config.d.ts +1 -0
  176. package/mcp-server/utils/config.js +10 -0
  177. package/mcp-server/utils/content.d.ts +1 -1
  178. package/mcp-server/utils/content.js +2 -2
  179. package/mcp-server/utils/feedbackTracking.d.ts +1 -1
  180. package/mcp-server/utils/feedbackTracking.js +3 -3
  181. package/mcp-server/utils/toolUsageTracking.js +4 -3
  182. package/package.json +8 -7
  183. package/types/LocalDev.d.ts +1 -0
  184. package/lib/middleware/__test__/notificationsMiddleware.test.js +0 -8
  185. package/lib/middleware/notificationsMiddleware.d.ts +0 -1
  186. package/lib/middleware/notificationsMiddleware.js +0 -28
  187. package/mcp-server/utils/__tests__/cliConfig.test.js +0 -110
  188. package/mcp-server/utils/cliConfig.d.ts +0 -1
  189. package/mcp-server/utils/cliConfig.js +0 -12
  190. /package/{lib/middleware/__test__/commandTargetingUtils.test.d.ts → commands/project/__tests__/lint.test.d.ts} +0 -0
  191. /package/lib/middleware/{__test__/configMiddleware.test.d.ts → __tests__/commandTargetingUtils.test.d.ts} +0 -0
  192. /package/lib/middleware/{__test__/gitMiddleware.test.d.ts → __tests__/configMiddleware.test.d.ts} +0 -0
  193. /package/lib/middleware/{__test__/notificationsMiddleware.test.d.ts → __tests__/gitMiddleware.test.d.ts} +0 -0
  194. /package/lib/middleware/{__test__ → __tests__}/requestMiddleware.test.d.ts +0 -0
  195. /package/lib/middleware/{__test__ → __tests__}/requestMiddleware.test.js +0 -0
  196. /package/lib/middleware/{__test__ → __tests__}/yargsChecksMiddleware.test.d.ts +0 -0
  197. /package/lib/middleware/{__test__ → __tests__}/yargsChecksMiddleware.test.js +0 -0
  198. /package/{mcp-server/utils/__tests__/cliConfig.test.d.ts → lib/projects/__tests__/uieLinting.test.d.ts} +0 -0
@@ -1,8 +1,7 @@
1
1
  import { uiLogger } from '../../lib/ui/logger.js';
2
2
  import { isSpecifiedError } from '@hubspot/local-dev-lib/errors/index';
3
3
  import { deleteSandbox } from '@hubspot/local-dev-lib/api/sandboxHubs';
4
- import { getEnv, removeSandboxAccountFromConfig, updateDefaultAccount, getAccountId, getConfigAccounts, } from '@hubspot/local-dev-lib/config';
5
- import { getAccountIdentifier } from '@hubspot/local-dev-lib/config/getAccountIdentifier';
4
+ import { getConfigAccountEnvironment, removeAccountFromConfig, setConfigAccountAsDefault, getAllConfigAccounts, getConfigAccountIfExists, getConfigDefaultAccountIfExists, } from '@hubspot/local-dev-lib/config';
6
5
  import { getHubSpotWebsiteOrigin } from '@hubspot/local-dev-lib/urls';
7
6
  import { getValidEnv } from '@hubspot/local-dev-lib/environment';
8
7
  import { trackCommandUsage } from '../../lib/usageTracking.js';
@@ -36,17 +35,20 @@ async function handler(args) {
36
35
  process.exit(EXIT_CODES.ERROR);
37
36
  }
38
37
  }
39
- const sandboxAccountId = getAccountId(userProvidedAccount || accountPrompt.account);
40
- if (!sandboxAccountId) {
38
+ const accountIdentifier = userProvidedAccount || accountPrompt.account;
39
+ const sandboxAccount = getConfigAccountIfExists(accountIdentifier);
40
+ if (!sandboxAccount) {
41
41
  uiLogger.error(commands.sandbox.subcommands.delete.failure.noSandboxAccountId);
42
42
  process.exit(EXIT_CODES.ERROR);
43
43
  }
44
- const isDefaultAccount = sandboxAccountId === getAccountId();
45
- const baseUrl = getHubSpotWebsiteOrigin(getValidEnv(getEnv(sandboxAccountId)));
44
+ const sandboxAccountId = sandboxAccount.accountId;
45
+ const defaultAccount = getConfigDefaultAccountIfExists();
46
+ const isDefaultAccount = sandboxAccountId === defaultAccount?.accountId;
47
+ const baseUrl = getHubSpotWebsiteOrigin(getValidEnv(getConfigAccountEnvironment(sandboxAccountId)));
46
48
  let parentAccountId;
47
- const accountsList = getConfigAccounts() || [];
49
+ const accountsList = getAllConfigAccounts() || [];
48
50
  for (const portal of accountsList) {
49
- if (getAccountIdentifier(portal) === sandboxAccountId) {
51
+ if (portal.accountId === sandboxAccountId) {
50
52
  if (portal.parentAccountId) {
51
53
  parentAccountId = portal.parentAccountId;
52
54
  }
@@ -56,7 +58,8 @@ async function handler(args) {
56
58
  uiLogger.error(commands.sandbox.subcommands.delete.failure.noParentAccount);
57
59
  process.exit(EXIT_CODES.ERROR);
58
60
  }
59
- parentAccountId = getAccountId(parentAccountPrompt.account);
61
+ const parentAccount = getConfigAccountIfExists(parentAccountPrompt.account);
62
+ parentAccountId = parentAccount?.accountId;
60
63
  }
61
64
  else {
62
65
  uiLogger.error(commands.sandbox.subcommands.delete.failure.noParentAccount);
@@ -67,9 +70,9 @@ async function handler(args) {
67
70
  const url = `${baseUrl}/sandboxes/${parentAccountId}`;
68
71
  const command = uiAuthCommandReference({
69
72
  accountId: parentAccountId || undefined,
70
- qa: getEnv(sandboxAccountId) === 'qa',
73
+ qa: getConfigAccountEnvironment(sandboxAccountId) === 'qa',
71
74
  });
72
- if (parentAccountId && !getAccountId(parentAccountId)) {
75
+ if (parentAccountId && !getConfigAccountIfExists(parentAccountId)) {
73
76
  uiLogger.log('');
74
77
  uiLogger.error(commands.sandbox.subcommands.delete.failure.noParentPortalAvailable(command, url));
75
78
  uiLogger.log('');
@@ -99,14 +102,14 @@ async function handler(args) {
99
102
  ? commands.sandbox.subcommands.delete.success.deleteDefault(userProvidedAccount || accountPrompt.account, sandboxAccountId)
100
103
  : commands.sandbox.subcommands.delete.success.delete(userProvidedAccount || accountPrompt.account, sandboxAccountId));
101
104
  uiLogger.log('');
102
- const promptDefaultAccount = removeSandboxAccountFromConfig(sandboxAccountId);
103
- if (promptDefaultAccount && !force) {
105
+ removeAccountFromConfig(sandboxAccountId);
106
+ if (isDefaultAccount && !force) {
104
107
  const newDefaultAccount = await selectAccountFromConfig();
105
- updateDefaultAccount(newDefaultAccount);
108
+ setConfigAccountAsDefault(newDefaultAccount);
106
109
  }
107
110
  else if (isDefaultAccount && force) {
108
111
  // If force is specified, skip prompt and set the parent account id as the default account
109
- updateDefaultAccount(parentAccountId);
112
+ setConfigAccountAsDefault(parentAccountId);
110
113
  }
111
114
  process.exit(EXIT_CODES.SUCCESS);
112
115
  }
@@ -135,14 +138,14 @@ async function handler(args) {
135
138
  uiLogger.log('');
136
139
  uiLogger.warn(commands.sandbox.subcommands.delete.failure.objectNotFound(sandboxAccountId));
137
140
  uiLogger.log('');
138
- const promptDefaultAccount = removeSandboxAccountFromConfig(sandboxAccountId);
139
- if (promptDefaultAccount && !force) {
141
+ removeAccountFromConfig(sandboxAccountId);
142
+ if (isDefaultAccount && !force) {
140
143
  const newDefaultAccount = await selectAccountFromConfig();
141
- updateDefaultAccount(newDefaultAccount);
144
+ setConfigAccountAsDefault(newDefaultAccount);
142
145
  }
143
- else {
146
+ else if (isDefaultAccount) {
144
147
  // If force is specified, skip prompt and set the parent account id as the default account
145
- updateDefaultAccount(parentAccountId);
148
+ setConfigAccountAsDefault(parentAccountId);
146
149
  }
147
150
  process.exit(EXIT_CODES.SUCCESS);
148
151
  }
@@ -1,7 +1,7 @@
1
1
  import fs from 'fs-extra';
2
2
  import path from 'path';
3
3
  import { getValidEnv } from '@hubspot/local-dev-lib/environment';
4
- import { getEnv } from '@hubspot/local-dev-lib/config';
4
+ import { getConfigAccountEnvironment } from '@hubspot/local-dev-lib/config';
5
5
  import { getCwd } from '@hubspot/local-dev-lib/path';
6
6
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
7
7
  import { promptUser, listPrompt } from '../../lib/prompts/promptUtils.js';
@@ -89,7 +89,7 @@ async function buildTestAccountConfig(args) {
89
89
  async function handler(args) {
90
90
  const { derivedAccountId, formatOutputAsJson } = args;
91
91
  trackCommandUsage('test-account-create', {}, derivedAccountId);
92
- const env = getValidEnv(getEnv(derivedAccountId));
92
+ const env = getValidEnv(getConfigAccountEnvironment(derivedAccountId));
93
93
  const testAccountConfig = await buildTestAccountConfig(args);
94
94
  const resultJson = {};
95
95
  SpinniesManager.init({
@@ -4,7 +4,7 @@ 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
- import { deleteAccount, getAccountConfig, getAccountId, getConfigPath, loadConfig, updateDefaultAccount, } from '@hubspot/local-dev-lib/config';
7
+ import { removeAccountFromConfig, getConfigAccountById, getConfigAccountIfExists, setConfigAccountAsDefault, getConfigDefaultAccountIfExists, } from '@hubspot/local-dev-lib/config';
8
8
  import { promptUser } from '../../lib/prompts/promptUtils.js';
9
9
  import { debugError } from '../../lib/errorHandlers/index.js';
10
10
  const command = 'delete [test-account]';
@@ -64,12 +64,12 @@ async function deleteTestAccountFromConfig(testAccountId, parentAccountName, acc
64
64
  // If the account isn't in the local config then it wasn't auth'd on the local machine
65
65
  if (account && account.name && account.accountType) {
66
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);
67
+ const defaultAccount = getConfigDefaultAccountIfExists();
68
+ const defaultAccountId = defaultAccount?.accountId;
69
+ removeAccountFromConfig(account.accountId);
70
70
  uiLogger.success(commands.testAccount.delete.success.testAccountDeletedFromConfig(testAccountId));
71
71
  if (testAccountId === defaultAccountId) {
72
- updateDefaultAccount(parentAccountName);
72
+ setConfigAccountAsDefault(parentAccountName);
73
73
  uiLogger.info(commands.testAccount.delete.info.replaceDefaultAccount(testAccountId, parentAccountName));
74
74
  }
75
75
  }
@@ -84,12 +84,12 @@ async function validateTestAccountConfigs(testAccountId) {
84
84
  uiLogger.error(commands.testAccount.delete.errors.testAccountNotFound(testAccountId));
85
85
  process.exit(EXIT_CODES.ERROR);
86
86
  }
87
- const testAccountConfig = getAccountConfig(testAccountId);
87
+ const testAccountConfig = getConfigAccountById(testAccountId);
88
88
  if (!testAccountConfig) {
89
89
  uiLogger.error(commands.testAccount.delete.errors.testAccountNotFound(testAccountId));
90
90
  process.exit(EXIT_CODES.ERROR);
91
91
  }
92
- const parentAccountConfig = getAccountConfig(testAccountConfig.parentAccountId);
92
+ const parentAccountConfig = getConfigAccountById(testAccountConfig.parentAccountId);
93
93
  if (!parentAccountConfig) {
94
94
  uiLogger.error(commands.testAccount.delete.errors.parentAccountNotFound(testAccountId));
95
95
  process.exit(EXIT_CODES.ERROR);
@@ -103,7 +103,8 @@ async function handler(args) {
103
103
  let testAccountIdToDelete = 0;
104
104
  // See if the account exists
105
105
  if (testAccount) {
106
- const accountId = getAccountId(testAccount);
106
+ const account = getConfigAccountIfExists(testAccount);
107
+ const accountId = account?.accountId || null;
107
108
  await validateTestAccountConfigs(accountId);
108
109
  if (accountId) {
109
110
  testAccountIdToDelete = accountId;
package/lang/en.d.ts CHANGED
@@ -1,12 +1,13 @@
1
- import { CLIAccount } from '@hubspot/local-dev-lib/types/Accounts';
1
+ import { HubSpotConfigAccount } from '@hubspot/local-dev-lib/types/Accounts';
2
2
  export declare const commands: {
3
3
  generalErrors: {
4
4
  srcIsProject: (src: string, command: string) => string;
5
5
  handleDeprecatedEnvVariables: {
6
6
  portalEnvVarDeprecated: string;
7
7
  };
8
- loadConfigMiddleware: {
9
- configFileExists: (configPath: string) => string;
8
+ validateConfigMiddleware: {
9
+ missingConfigFile: string;
10
+ configValidationFailed: (errors: string[]) => string;
10
11
  };
11
12
  };
12
13
  getStarted: {
@@ -86,12 +87,11 @@ export declare const commands: {
86
87
  list: {
87
88
  accounts: string;
88
89
  defaultAccountTitle: string;
89
- defaultAccount: (account: string) => string;
90
+ currentResolvedDefaultAccount: (accountId: number) => string;
90
91
  describe: string;
91
92
  configPath: (configPath: string) => string;
92
93
  overrideFilePathTitle: string;
93
94
  overrideFilePath: (overrideFilePath: string) => string;
94
- overrideAccount: (account: string) => string;
95
95
  labels: {
96
96
  accountId: string;
97
97
  authType: string;
@@ -1752,6 +1752,32 @@ export declare const commands: {
1752
1752
  noPackageJsonInProject: (projectName: string) => string;
1753
1753
  packageManagerNotInstalled: (packageManager: string) => string;
1754
1754
  };
1755
+ lint: {
1756
+ help: {
1757
+ describe: string;
1758
+ lintProjectExample: string;
1759
+ lintProjectWithInstallExample: string;
1760
+ lintProjectWithoutInstallExample: string;
1761
+ installMissingDeps: string;
1762
+ };
1763
+ loading: {
1764
+ checking: string;
1765
+ creatingConfig: string;
1766
+ linting: string;
1767
+ };
1768
+ noProjectConfig: string;
1769
+ failedToReadPackageJson: (packageJsonPath: string) => string;
1770
+ installLintPackagesPrompt: (directories: string[], missingPackages: string[]) => string;
1771
+ skippingDirectoriesWarning: (directories: string[]) => string;
1772
+ deprecatedEslintConfigWarning: (details: {
1773
+ path: string;
1774
+ files: string[];
1775
+ }[]) => string;
1776
+ createEslintConfigPrompt: (directories: string[]) => string;
1777
+ eslintConfigCreated: (configPath: string) => string;
1778
+ failedToCreateEslintConfig: (configPath: string) => string;
1779
+ eslintConfigRequired: string;
1780
+ };
1755
1781
  updateDeps: {
1756
1782
  help: {
1757
1783
  describe: string;
@@ -2818,6 +2844,11 @@ export declare const lib: {
2818
2844
  startError: (message: string) => string;
2819
2845
  fileChangeError: (message: string) => string;
2820
2846
  };
2847
+ devSession: {
2848
+ registrationError: (message: string) => string;
2849
+ heartbeatError: (message: string) => string;
2850
+ deletionError: (message: string) => string;
2851
+ };
2821
2852
  };
2822
2853
  AppDevModeInterface: {
2823
2854
  autoInstallStaticAuthApp: {
@@ -3237,6 +3268,9 @@ export declare const lib: {
3237
3268
  skippedExistingAccounts: (accountIds: (string | number)[]) => string;
3238
3269
  success: string;
3239
3270
  };
3271
+ errors: {
3272
+ archive: (deprecatedConfigPath: string) => string;
3273
+ };
3240
3274
  };
3241
3275
  prompts: {
3242
3276
  promptUtils: {
@@ -3249,7 +3283,7 @@ export declare const lib: {
3249
3283
  promptMessage: string;
3250
3284
  };
3251
3285
  confirmImportDataPrompt: {
3252
- message: (dataFileNames: string[], cliAccount: CLIAccount | null) => string;
3286
+ message: (dataFileNames: string[], cliAccount: HubSpotConfigAccount | null) => string;
3253
3287
  };
3254
3288
  importDataTestAccountSelectPrompt: {
3255
3289
  errors: {
package/lang/en.js CHANGED
@@ -7,15 +7,15 @@ import { uiAccountDescription, uiBetaTag, uiCommandReference, uiLink, UI_COLORS,
7
7
  import { getProjectDetailUrl, getProjectSettingsUrl, getLocalDevUiUrl, } from '../lib/projects/urls.js';
8
8
  import { getProductUpdatesUrl } from '../lib/links.js';
9
9
  import { APP_DISTRIBUTION_TYPES, APP_AUTH_TYPES, PROJECT_CONFIG_FILE, PROJECT_WITH_APP, LEGACY_PUBLIC_APP_FILE, } from '../lib/constants.js';
10
- import { getAccountIdentifier } from '@hubspot/local-dev-lib/config/getAccountIdentifier';
11
10
  export const commands = {
12
11
  generalErrors: {
13
12
  srcIsProject: (src, command) => `"${src}" is in a project folder. Did you mean "hs project ${command}"?`,
14
13
  handleDeprecatedEnvVariables: {
15
14
  portalEnvVarDeprecated: 'The HUBSPOT_PORTAL_ID environment variable is deprecated. Please use HUBSPOT_ACCOUNT_ID instead.',
16
15
  },
17
- loadConfigMiddleware: {
18
- configFileExists: (configPath) => `A configuration file already exists at ${configPath}. To specify a new configuration file, delete the existing one and try again.`,
16
+ validateConfigMiddleware: {
17
+ missingConfigFile: `A HubSpot config file is required to run this command, but none was found. To create a new config file and authenticate a HubSpot account, run ${uiCommandReference('hs account auth')}`,
18
+ configValidationFailed: (errors) => `Your HubSpot config file is invalid. Please fix the following errors:\n - ${errors.join('\n- ')}`,
19
19
  },
20
20
  },
21
21
  getStarted: {
@@ -95,12 +95,11 @@ export const commands = {
95
95
  list: {
96
96
  accounts: `${chalk.bold('Accounts')}:`,
97
97
  defaultAccountTitle: `${chalk.bold('Default Account')}`,
98
- defaultAccount: (account) => `Account: ${account}`,
98
+ currentResolvedDefaultAccount: (accountId) => `Account: ${uiAccountDescription(accountId)}`,
99
99
  describe: 'List names of accounts defined in config.',
100
100
  configPath: (configPath) => `Source: ${configPath}`,
101
101
  overrideFilePathTitle: `${chalk.bold('Default Account Override')}`,
102
102
  overrideFilePath: (overrideFilePath) => `Source: ${overrideFilePath}`,
103
- overrideAccount: (account) => `Account: ${account}`,
104
103
  labels: {
105
104
  accountId: 'Account ID',
106
105
  authType: 'Auth Type',
@@ -1552,7 +1551,7 @@ export const commands = {
1552
1551
  noBuilds: 'Deploy error: no builds for this project were found.',
1553
1552
  noBuildId: 'You must specify a build to deploy',
1554
1553
  projectNotFound: (accountId, projectName) => `The project ${chalk.bold(projectName)} does not exist in account ${uiAccountDescription(accountId)}. Run ${uiCommandReference('hs project upload')} to upload your project files to HubSpot.`,
1555
- buildIdDoesNotExist: (accountId, buildId, projectName) => `Build ${buildId} does not exist for project ${chalk.bold(projectName)}. ${uiLink('View project builds in HubSpot', getProjectDetailUrl(projectName, accountId))}`,
1554
+ buildIdDoesNotExist: (accountId, buildId, projectName) => `Build ${buildId} does not exist for project ${chalk.bold(projectName)}. Run ${uiCommandReference('hs project list-builds')} to view existing builds for this project.`,
1556
1555
  buildAlreadyDeployed: (accountId, buildId, projectName) => `Build ${buildId} is already deployed. ${uiLink('View project builds in HubSpot', getProjectDetailUrl(projectName, accountId))}`,
1557
1556
  deployContainsRemovals: (componentName) => `- This deploy would remove the ${chalk.bold(componentName)} component. To proceed, run the deploy command with the ${uiCommandReference('--force')} flag`,
1558
1557
  deployBlockedHeader: "This build couldn't be deployed because it will be too disruptive for existing users. Fix the following issues and try again:",
@@ -1768,6 +1767,39 @@ export const commands = {
1768
1767
  noPackageJsonInProject: (projectName) => `No dependencies to install. The project ${projectName} folder might be missing component or subcomponent files. ${uiLink('Learn how to create a project from scratch', 'https://developers.hubspot.com/docs/apps/developer-platform/build-apps/create-an-app#customize-a-new-project-using-the-cli')}`,
1769
1768
  packageManagerNotInstalled: (packageManager) => `This command depends on ${packageManager}, install ${uiLink(packageManager, 'https://docs.npmjs.com/downloading-and-installing-node-js-and-npm')}`,
1770
1769
  },
1770
+ lint: {
1771
+ help: {
1772
+ describe: 'Lint the UI Extensions components in your project.',
1773
+ lintProjectExample: 'Lint the UI Extensions components in your project.',
1774
+ lintProjectWithInstallExample: 'Lint the UI Extensions components in the project and automatically install missing dependencies.',
1775
+ lintProjectWithoutInstallExample: 'Lint the UI Extensions components in the project without installing missing dependencies.',
1776
+ installMissingDeps: 'Automatically install missing linting dependencies for the UI Extensions components in the project without prompting.',
1777
+ },
1778
+ loading: {
1779
+ checking: 'Checking lint packages and configuration…',
1780
+ creatingConfig: 'Creating ESLint configuration files…',
1781
+ linting: 'Linting…',
1782
+ },
1783
+ noProjectConfig: 'No project detected. Run this command from a project directory.',
1784
+ failedToReadPackageJson: (packageJsonPath) => `Failed to read package.json at ${packageJsonPath}`,
1785
+ installLintPackagesPrompt: (directories, missingPackages) => {
1786
+ const uniquePackages = Array.from(new Set(missingPackages)).sort();
1787
+ return `The dependencies required for linting are missing or outdated.\n\nDependencies:\n${uniquePackages.map(p => ` - ${p}`).join('\n')}\n\n${directories.length === 1 ? 'Directory' : 'Directories'}:\n${directories.map(d => ` - ${d}`).join('\n')}\n\nWould you like to install the required dependencies?`;
1788
+ },
1789
+ skippingDirectoriesWarning: (directories) => `Skipping linting for the following ${directories.length === 1 ? 'directory' : 'directories'}:\n${directories.map(d => ` - ${d}`).join('\n')}`,
1790
+ deprecatedEslintConfigWarning: (details) => {
1791
+ const dirCount = details.length;
1792
+ const header = `Deprecated ESLint configuration file${dirCount === 1 ? '' : 's'} detected in the following ${dirCount === 1 ? 'directory' : 'directories'}:`;
1793
+ const dirList = details
1794
+ .map(d => ` - ${d.path}: ${d.files.join(', ')}`)
1795
+ .join('\n');
1796
+ return `${header}\n${dirList}\n`;
1797
+ },
1798
+ createEslintConfigPrompt: (directories) => `ESLint configuration file not found in the following ${directories.length === 1 ? 'directory' : 'directories'}:\n${directories.map(d => ` - ${d}`).join('\n')}\n\nWould you like to set up the required ESLint configuration?`,
1799
+ eslintConfigCreated: (configPath) => `ESLint configuration created at ${configPath}`,
1800
+ failedToCreateEslintConfig: (configPath) => `Failed to create ESLint configuration at ${configPath}`,
1801
+ eslintConfigRequired: 'ESLint configuration is required to run the lint command. Run the command again to create the configuration.',
1802
+ },
1771
1803
  updateDeps: {
1772
1804
  help: {
1773
1805
  describe: 'Update the npm dependencies for your project, or update specific dependencies in a subcomponent of a project.',
@@ -2834,6 +2866,11 @@ export const lib = {
2834
2866
  startError: (message) => `Failed to start local dev server: ${message}`,
2835
2867
  fileChangeError: (message) => `Failed to notify local dev server of file change: ${message}`,
2836
2868
  },
2869
+ devSession: {
2870
+ registrationError: (message) => `Failed to register dev session: ${message}`,
2871
+ heartbeatError: (message) => `Failed to send dev session heartbeat: ${message}`,
2872
+ deletionError: (message) => `Failed to delete dev session: ${message}`,
2873
+ },
2837
2874
  },
2838
2875
  AppDevModeInterface: {
2839
2876
  autoInstallStaticAuthApp: {
@@ -3253,6 +3290,9 @@ export const lib = {
3253
3290
  skippedExistingAccounts: (accountIds) => `The following accounts were not merged because they already exist in the global config:${accountIds.map(id => `\n- ${uiAccountDescription(Number(id))}`).join('')}`,
3254
3291
  success: 'Your deprecated config file has been successfully merged with the global config file.',
3255
3292
  },
3293
+ errors: {
3294
+ archive: (deprecatedConfigPath) => `The config migration was successful, but an error occurred when archiving config file at ${deprecatedConfigPath}. You may need to manually delete or rename this config file.`,
3295
+ },
3256
3296
  },
3257
3297
  prompts: {
3258
3298
  promptUtils: {
@@ -3265,7 +3305,7 @@ export const lib = {
3265
3305
  promptMessage: '[--file-path] Select the JSON file that will be used to import your data.',
3266
3306
  },
3267
3307
  confirmImportDataPrompt: {
3268
- message: (dataFileNames, cliAccount) => `You are importing [${dataFileNames.join(', ')}] into ${uiAccountDescription(getAccountIdentifier(cliAccount))}. Continue?`,
3308
+ message: (dataFileNames, cliAccount) => `You are importing [${dataFileNames.join(', ')}] into ${uiAccountDescription(cliAccount?.accountId)}. Continue?`,
3269
3309
  },
3270
3310
  importDataTestAccountSelectPrompt: {
3271
3311
  errors: {
@@ -3617,7 +3657,7 @@ export const lib = {
3617
3657
  },
3618
3658
  failure: {
3619
3659
  syncTypeFetch: 'Unable to fetch available sandbox sync types. Please try again.',
3620
- invalidUser: (accountName, parentAccountName) => `Couldn't sync ${chalk.bold(accountName)} because your account has been removed from ${chalk.bold(parentAccountName)} or your permission set doesn't allow you to sync the sandbox. To update your permissions, contact a super admin in ${chalk.bold(parentAccountName)}.`,
3660
+ invalidUser: (accountName, parentAccountName) => `Couldn't sync sandbox ${chalk.bold(accountName)} because your account has been removed from parent account${chalk.bold(parentAccountName)} or your permission set doesn't allow you to sync the sandbox. To update your permissions, contact a super admin in ${chalk.bold(parentAccountName)}.`,
3621
3661
  syncInProgress: (url) => `Couldn't run the sync because there's another sync in progress. Wait for the current sync to finish and then try again. To check the sync status, visit the sync activity log: ${url}.`,
3622
3662
  notSuperAdmin: (accountId) => `Couldn't run the sync because you are not a super admin in ${uiAccountDescription(accountId)}. Ask the account owner for super admin access to the sandbox.`,
3623
3663
  objectNotFound: (accountId) => `Couldn't sync the sandbox because ${uiAccountDescription(accountId)} may have been deleted through the UI. Run ${uiCommandReference('hs sandbox delete')} to remove this account from the config.`,
@@ -3745,7 +3785,7 @@ export const lib = {
3745
3785
  },
3746
3786
  validation: {
3747
3787
  accountNotFoundInConfig: (userProvidedAccount) => `The account "${userProvidedAccount}" could not be found in the config`,
3748
- accountRequired: 'An account needs to be supplied either via "--account" or through setting a "defaultPortal"',
3788
+ accountRequired: 'An account needs to be supplied either via "--account" or through setting a "defaultAccount"',
3749
3789
  userProvidedAccount: 'Cannot specify an account when environment variables are supplied. Please unset the environment variables or do not use the "--account" flag.',
3750
3790
  accountNotConfigured: (accountId) => `The account ${uiAccountDescription(accountId)} has not been configured`,
3751
3791
  invalidAuthType: (authType, accountId, configPath, validValues) => `Invalid "authType" value "${authType}" for account "${uiAccountDescription(accountId)}" in config file: ${configPath}. Valid values are ${validValues}.`,
@@ -1,11 +1,12 @@
1
1
  import { getAccessToken, updateConfigWithAccessToken, } from '@hubspot/local-dev-lib/personalAccessKey';
2
- import { accountNameExistsInConfig, updateAccountConfig, writeConfig, getAccountId, } from '@hubspot/local-dev-lib/config';
2
+ import { getConfigAccountIfExists, updateConfigAccount, } from '@hubspot/local-dev-lib/config';
3
3
  import { createDeveloperTestAccount, fetchDeveloperTestAccountGateSyncStatus, generateDeveloperTestAccountPersonalAccessKey, } from '@hubspot/local-dev-lib/api/developerTestAccounts';
4
4
  import { createSandbox, createV2Sandbox, getSandboxPersonalAccessKey, } from '@hubspot/local-dev-lib/api/sandboxHubs';
5
5
  import { HUBSPOT_ACCOUNT_TYPES } from '@hubspot/local-dev-lib/constants/config';
6
6
  import { personalAccessKeyPrompt } from '../prompts/personalAccessKeyPrompt.js';
7
7
  import { cliAccountNamePrompt } from '../prompts/accountNamePrompt.js';
8
8
  import * as buildAccount from '../buildAccount.js';
9
+ import { poll } from '../polling.js';
9
10
  vi.mock('@hubspot/local-dev-lib/personalAccessKey');
10
11
  vi.mock('@hubspot/local-dev-lib/config');
11
12
  vi.mock('@hubspot/local-dev-lib/api/developerTestAccounts');
@@ -14,6 +15,7 @@ vi.mock('../ui/logger.js');
14
15
  vi.mock('../errorHandlers/index.js');
15
16
  vi.mock('../prompts/personalAccessKeyPrompt');
16
17
  vi.mock('../prompts/accountNamePrompt');
18
+ vi.mock('../polling.js');
17
19
  vi.mock('../ui/SpinniesManager', () => ({
18
20
  default: {
19
21
  init: vi.fn(),
@@ -25,17 +27,16 @@ vi.mock('../ui/SpinniesManager', () => ({
25
27
  const mockedPersonalAccessKeyPrompt = personalAccessKeyPrompt;
26
28
  const mockedGetAccessToken = getAccessToken;
27
29
  const mockedUpdateConfigWithAccessToken = updateConfigWithAccessToken;
28
- const mockedAccountNameExistsInConfig = accountNameExistsInConfig;
29
- const mockedUpdateAccountConfig = updateAccountConfig;
30
- const mockedWriteConfig = writeConfig;
30
+ const mockedGetConfigAccountIfExists = getConfigAccountIfExists;
31
+ const mockedUpdateConfigAccount = updateConfigAccount;
31
32
  const mockedCliAccountNamePrompt = cliAccountNamePrompt;
32
- const mockedGetAccountId = getAccountId;
33
33
  const mockedCreateDeveloperTestAccount = createDeveloperTestAccount;
34
34
  const mockedFetchDeveloperTestAccountGateSyncStatus = fetchDeveloperTestAccountGateSyncStatus;
35
35
  const mockedGenerateDeveloperTestAccountPersonalAccessKey = generateDeveloperTestAccountPersonalAccessKey;
36
36
  const mockedCreateSandbox = createSandbox;
37
37
  const mockedCreateV2Sandbox = createV2Sandbox;
38
38
  const mockedGetPersonalAccessKey = getSandboxPersonalAccessKey;
39
+ const mockedPoll = poll;
39
40
  describe('lib/buildAccount', () => {
40
41
  describe('saveAccountToConfig()', () => {
41
42
  const mockAccountConfig = {
@@ -61,9 +62,8 @@ describe('lib/buildAccount', () => {
61
62
  });
62
63
  mockedGetAccessToken.mockResolvedValue(accessToken);
63
64
  mockedUpdateConfigWithAccessToken.mockResolvedValue(mockAccountConfig);
64
- mockedAccountNameExistsInConfig.mockResolvedValue(false);
65
- mockedUpdateAccountConfig.mockReturnValue(undefined);
66
- mockedWriteConfig.mockReturnValue(undefined);
65
+ mockedGetConfigAccountIfExists.mockResolvedValue(undefined);
66
+ mockedUpdateConfigAccount.mockReturnValue(undefined);
67
67
  });
68
68
  afterEach(() => {
69
69
  vi.clearAllMocks();
@@ -72,8 +72,7 @@ describe('lib/buildAccount', () => {
72
72
  const result = await buildAccount.saveAccountToConfig(mockAccountConfig.accountId, mockAccountConfig.name, mockAccountConfig.env, 'test-key');
73
73
  expect(mockedPersonalAccessKeyPrompt).not.toHaveBeenCalled();
74
74
  expect(mockedUpdateConfigWithAccessToken).toHaveBeenCalledWith(accessToken, 'test-key', mockAccountConfig.env);
75
- expect(mockedUpdateAccountConfig).toHaveBeenCalledWith(expect.objectContaining(mockAccountConfig));
76
- expect(mockedWriteConfig).toHaveBeenCalled();
75
+ expect(mockedUpdateConfigAccount).toHaveBeenCalledWith(expect.objectContaining(mockAccountConfig));
77
76
  expect(result).toBe(mockAccountConfig.name);
78
77
  });
79
78
  it('should prompt for personal access key if not provided', async () => {
@@ -83,8 +82,7 @@ describe('lib/buildAccount', () => {
83
82
  account: mockAccountConfig.accountId,
84
83
  });
85
84
  expect(mockedUpdateConfigWithAccessToken).toHaveBeenCalledWith(accessToken, 'test-key', mockAccountConfig.env);
86
- expect(mockedUpdateAccountConfig).toHaveBeenCalledWith(expect.objectContaining(mockAccountConfig));
87
- expect(mockedWriteConfig).toHaveBeenCalled();
85
+ expect(mockedUpdateConfigAccount).toHaveBeenCalledWith(expect.objectContaining(mockAccountConfig));
88
86
  expect(result).toBe(mockAccountConfig.name);
89
87
  });
90
88
  it('should handle duplicate account names', async () => {
@@ -93,7 +91,7 @@ describe('lib/buildAccount', () => {
93
91
  name: undefined,
94
92
  };
95
93
  mockedUpdateConfigWithAccessToken.mockResolvedValue(mockAccountConfigWithNoName);
96
- mockedAccountNameExistsInConfig.mockResolvedValue(true);
94
+ mockedGetConfigAccountIfExists.mockResolvedValue({ accountId: 123 });
97
95
  mockedCliAccountNamePrompt.mockResolvedValue({
98
96
  name: 'test-account-with-new-name',
99
97
  });
@@ -109,6 +107,7 @@ describe('lib/buildAccount', () => {
109
107
  description: 'Test Account created by the HubSpot CLI',
110
108
  };
111
109
  beforeEach(() => {
110
+ vi.useFakeTimers();
112
111
  mockedCreateDeveloperTestAccount.mockResolvedValue({
113
112
  data: { id: 123456 },
114
113
  });
@@ -118,15 +117,23 @@ describe('lib/buildAccount', () => {
118
117
  mockedGenerateDeveloperTestAccountPersonalAccessKey.mockResolvedValue({
119
118
  data: { personalAccessKey: 'test-key' },
120
119
  });
120
+ // Mock poll to resolve immediately with the success status
121
+ mockedPoll.mockResolvedValue({ status: 'SUCCESS' });
122
+ });
123
+ afterEach(() => {
124
+ vi.useRealTimers();
121
125
  });
122
126
  it('should create a developer test account successfully', async () => {
123
- const result = await buildAccount.createDeveloperTestAccountV2(parentAccountId, mockDeveoperTestAccountConfig);
127
+ const resultPromise = buildAccount.createDeveloperTestAccountV2(parentAccountId, mockDeveoperTestAccountConfig);
128
+ // Fast-forward the 5 second setTimeout
129
+ await vi.advanceTimersByTimeAsync(5000);
130
+ const result = await resultPromise;
124
131
  expect(result).toEqual({
125
132
  accountName: mockDeveoperTestAccountConfig.accountName,
126
133
  accountId: 123456,
127
134
  personalAccessKey: 'test-key',
128
135
  });
129
- }, 10000);
136
+ });
130
137
  });
131
138
  describe('buildDeveloperTestAccount()', () => {
132
139
  const mockParentAccountConfig = {
@@ -146,7 +153,6 @@ describe('lib/buildAccount', () => {
146
153
  };
147
154
  beforeEach(() => {
148
155
  vi.spyOn(buildAccount, 'saveAccountToConfig').mockResolvedValue(mockParentAccountConfig.name);
149
- mockedGetAccountId.mockReturnValue(mockParentAccountConfig.accountId);
150
156
  mockedCreateDeveloperTestAccount.mockResolvedValue({
151
157
  data: mockDeveloperTestAccount,
152
158
  });
@@ -158,10 +164,6 @@ describe('lib/buildAccount', () => {
158
164
  const result = await buildAccount.buildDeveloperTestAccount(mockDeveloperTestAccount.accountName, mockParentAccountConfig, mockParentAccountConfig.env, 10);
159
165
  expect(result).toEqual(mockDeveloperTestAccount.id);
160
166
  });
161
- it('should throw error if account ID is not found', async () => {
162
- mockedGetAccountId.mockReturnValue(null);
163
- await expect(buildAccount.buildDeveloperTestAccount(mockDeveloperTestAccount.accountName, mockParentAccountConfig, mockParentAccountConfig.env, 10)).rejects.toThrow();
164
- });
165
167
  it('should handle API errors when creating developer test account', async () => {
166
168
  mockedCreateDeveloperTestAccount.mockRejectedValue(new Error('test-error'));
167
169
  await expect(buildAccount.buildDeveloperTestAccount(mockDeveloperTestAccount.accountName, mockParentAccountConfig, mockParentAccountConfig.env, 10)).rejects.toThrow();
@@ -192,7 +194,6 @@ describe('lib/buildAccount', () => {
192
194
  };
193
195
  beforeEach(() => {
194
196
  vi.spyOn(buildAccount, 'saveAccountToConfig').mockResolvedValue(mockParentAccountConfig.name);
195
- mockedGetAccountId.mockReturnValue(mockParentAccountConfig.accountId);
196
197
  mockedCreateSandbox.mockResolvedValue({
197
198
  data: { sandbox: mockSandbox, personalAccessKey: 'test-key' },
198
199
  });
@@ -216,10 +217,6 @@ describe('lib/buildAccount', () => {
216
217
  sandbox: mockSandbox,
217
218
  });
218
219
  });
219
- it('should throw error if account ID is not found', async () => {
220
- mockedGetAccountId.mockReturnValue(null);
221
- await expect(buildAccount.buildSandbox(mockSandbox.name, mockParentAccountConfig, HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX, mockParentAccountConfig.env)).rejects.toThrow();
222
- });
223
220
  it('should handle API errors when creating sandbox', async () => {
224
221
  mockedCreateSandbox.mockRejectedValue(new Error('test-error'));
225
222
  await expect(buildAccount.buildSandbox(mockSandbox.name, mockParentAccountConfig, HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX, mockParentAccountConfig.env, false)).rejects.toThrow();
@@ -250,7 +247,6 @@ describe('lib/buildAccount', () => {
250
247
  };
251
248
  beforeEach(() => {
252
249
  vi.spyOn(buildAccount, 'saveAccountToConfig').mockResolvedValue(mockParentAccountConfig.name);
253
- mockedGetAccountId.mockReturnValue(mockParentAccountConfig.accountId);
254
250
  mockedCreateV2Sandbox.mockResolvedValue({
255
251
  data: mockSandbox,
256
252
  });
@@ -271,10 +267,6 @@ describe('lib/buildAccount', () => {
271
267
  expect(result).toEqual({ sandbox: mockSandbox });
272
268
  expect(mockedGetPersonalAccessKey).toHaveBeenCalledWith(mockParentAccountConfig.accountId, mockSandbox.sandboxHubId);
273
269
  });
274
- it('should throw error if account ID is not found', async () => {
275
- mockedGetAccountId.mockReturnValue(null);
276
- await expect(buildAccount.buildV2Sandbox(mockSandbox.name, mockParentAccountConfig, HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX, false, mockParentAccountConfig.env, false)).rejects.toThrow();
277
- });
278
270
  it('should handle API errors when creating sandbox', async () => {
279
271
  mockedCreateV2Sandbox.mockRejectedValue(new Error('test-error'));
280
272
  await expect(buildAccount.buildV2Sandbox(mockSandbox.name, mockParentAccountConfig, HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX, false, mockParentAccountConfig.env, false)).rejects.toThrow();
@@ -1,9 +1,8 @@
1
1
  import { CMS_PUBLISH_MODE, DEFAULT_CMS_PUBLISH_MODE, } from '@hubspot/local-dev-lib/constants/files';
2
- import { getAndLoadConfigIfNeeded, getAccountConfig, loadConfigFromEnvironment, } from '@hubspot/local-dev-lib/config';
2
+ import { getConfig, getConfigAccountById } from '@hubspot/local-dev-lib/config';
3
3
  import { getCmsPublishMode } from '../commonOpts.js';
4
- const mockedGetAccountConfig = getAccountConfig;
5
- const mockedGetAndLoadConfigIfNeeded = getAndLoadConfigIfNeeded;
6
- const mockedLoadConfigFromEnvironment = loadConfigFromEnvironment;
4
+ const mockedGetConfigAccountById = getConfigAccountById;
5
+ const mockedGetConfig = getConfig;
7
6
  function buildArguments(args) {
8
7
  return {
9
8
  _: [],
@@ -42,8 +41,8 @@ describe('lib/commonOpts', () => {
42
41
  describe('cms publish mode option precedence', () => {
43
42
  describe('1. --cmsPublishMode', () => {
44
43
  it('should return the cms publish mode specified by the command option if present.', () => {
45
- mockedGetAndLoadConfigIfNeeded.mockReturnValue(configWithDefaultCmsPublishMode);
46
- mockedGetAccountConfig.mockReturnValue(devAccountConfig);
44
+ mockedGetConfig.mockReturnValue(configWithDefaultCmsPublishMode);
45
+ mockedGetConfigAccountById.mockReturnValue(devAccountConfig);
47
46
  expect(getCmsPublishMode(buildArguments({
48
47
  cmsPublishMode: CMS_PUBLISH_MODE.draft,
49
48
  }))).toBe(CMS_PUBLISH_MODE.draft);
@@ -54,9 +53,8 @@ describe('lib/commonOpts', () => {
54
53
  });
55
54
  describe('2. hubspot.config.yml -> config.accounts[x].defaultCmsPublishMode', () => {
56
55
  it('should return the defaultCmsPublishMode specified by the account specific config if present.', () => {
57
- mockedGetAndLoadConfigIfNeeded.mockReturnValue(configWithDefaultCmsPublishMode);
58
- mockedGetAccountConfig.mockReturnValue(devAccountConfig);
59
- mockedLoadConfigFromEnvironment.mockReturnValue(undefined);
56
+ mockedGetConfig.mockReturnValue(configWithDefaultCmsPublishMode);
57
+ mockedGetConfigAccountById.mockReturnValue(devAccountConfig);
60
58
  expect(getCmsPublishMode(buildArguments({
61
59
  account: accounts.DEV,
62
60
  }))).toBe(CMS_PUBLISH_MODE.draft);
@@ -64,9 +62,8 @@ describe('lib/commonOpts', () => {
64
62
  });
65
63
  describe('3. hubspot.config.yml -> config.defaultCmsPublishMode', () => {
66
64
  it('should return the defaultCmsPublishMode specified by the config if present.', () => {
67
- mockedGetAndLoadConfigIfNeeded.mockReturnValue(configWithDefaultCmsPublishMode);
68
- mockedGetAccountConfig.mockReturnValue(prodAccountConfig);
69
- mockedLoadConfigFromEnvironment.mockReturnValue(undefined);
65
+ mockedGetConfig.mockReturnValue(configWithDefaultCmsPublishMode);
66
+ mockedGetConfigAccountById.mockReturnValue(prodAccountConfig);
70
67
  expect(getCmsPublishMode(buildArguments({
71
68
  account: accounts.PROD,
72
69
  }))).toBe(CMS_PUBLISH_MODE.draft);
@@ -74,7 +71,6 @@ describe('lib/commonOpts', () => {
74
71
  });
75
72
  describe('4. DEFAULT_CMS_PUBLISH_MODE', () => {
76
73
  it('should return the defaultCmsPubishMode specified by the config if present.', () => {
77
- mockedLoadConfigFromEnvironment.mockReturnValue(undefined);
78
74
  expect(getCmsPublishMode(buildArguments({
79
75
  account: 'xxxxx',
80
76
  }))).toBe(DEFAULT_CMS_PUBLISH_MODE);