@hubspot/cli 7.7.34-experimental.0 → 7.8.0-beta.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 (293) 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/__tests__/getStarted.test.js +2 -2
  5. package/commands/__tests__/mcp.test.js +1 -1
  6. package/commands/__tests__/project.test.js +0 -3
  7. package/commands/account/clean.js +18 -27
  8. package/commands/account/createOverride.js +13 -31
  9. package/commands/account/info.js +20 -31
  10. package/commands/account/list.js +16 -22
  11. package/commands/account/remove.js +12 -20
  12. package/commands/account/removeOverride.js +11 -21
  13. package/commands/account/rename.js +6 -9
  14. package/commands/account/use.js +12 -26
  15. package/commands/account.js +2 -2
  16. package/commands/app/__tests__/migrate.test.js +5 -6
  17. package/commands/app/migrate.js +13 -19
  18. package/commands/app/secret/add.js +2 -1
  19. package/commands/app/secret/delete.js +2 -1
  20. package/commands/app/secret/list.js +2 -1
  21. package/commands/app/secret/update.js +2 -1
  22. package/commands/app/secret.js +2 -1
  23. package/commands/app.js +3 -8
  24. package/commands/auth.d.ts +1 -0
  25. package/commands/auth.js +16 -7
  26. package/commands/cms/convertFields.js +7 -9
  27. package/commands/cms/getReactModule.js +9 -14
  28. package/commands/cms/lighthouseScore.js +33 -36
  29. package/commands/cms.js +2 -2
  30. package/commands/completion.js +3 -3
  31. package/commands/config/set.d.ts +1 -1
  32. package/commands/config/set.js +64 -37
  33. package/commands/config.js +2 -2
  34. package/commands/create.js +2 -2
  35. package/commands/customObject/create.js +10 -12
  36. package/commands/customObject/schema/create.js +9 -11
  37. package/commands/customObject/schema/delete.js +16 -16
  38. package/commands/customObject/schema/fetch-all.js +12 -11
  39. package/commands/customObject/schema/fetch.js +15 -15
  40. package/commands/customObject/schema/list.js +4 -4
  41. package/commands/customObject/schema/update.js +13 -13
  42. package/commands/customObject/schema.js +2 -2
  43. package/commands/customObject.js +6 -7
  44. package/commands/doctor.js +8 -11
  45. package/commands/feedback.js +7 -12
  46. package/commands/fetch.js +8 -8
  47. package/commands/filemanager/fetch.js +7 -7
  48. package/commands/filemanager/upload.js +15 -34
  49. package/commands/filemanager.js +2 -2
  50. package/commands/function/deploy.js +11 -29
  51. package/commands/function/list.js +8 -8
  52. package/commands/function/server.js +9 -11
  53. package/commands/function.d.ts +1 -1
  54. package/commands/function.js +2 -2
  55. package/commands/getStarted.d.ts +0 -2
  56. package/commands/getStarted.js +4 -4
  57. package/commands/hubdb/clear.js +7 -15
  58. package/commands/hubdb/create.js +9 -15
  59. package/commands/hubdb/delete.js +8 -15
  60. package/commands/hubdb/fetch.js +6 -9
  61. package/commands/hubdb.d.ts +1 -1
  62. package/commands/hubdb.js +2 -2
  63. package/commands/init.js +2 -3
  64. package/commands/lint.js +16 -16
  65. package/commands/list.js +8 -14
  66. package/commands/logs.js +14 -20
  67. package/commands/mcp/__tests__/setup.test.js +2 -2
  68. package/commands/mcp/setup.js +11 -2
  69. package/commands/mcp.js +3 -3
  70. package/commands/mv.js +6 -17
  71. package/commands/open.js +5 -5
  72. package/commands/project/__tests__/add.test.js +4 -2
  73. package/commands/project/__tests__/create.test.js +6 -6
  74. package/commands/project/__tests__/deploy.test.js +3 -7
  75. package/commands/project/__tests__/devUnifiedFlow.test.js +2 -4
  76. package/commands/project/__tests__/installDeps.test.js +8 -8
  77. package/commands/project/__tests__/logs.test.js +1 -4
  78. package/commands/project/__tests__/migrate.test.js +6 -7
  79. package/commands/project/__tests__/migrateApp.test.js +3 -7
  80. package/commands/project/__tests__/profile.test.js +1 -1
  81. package/commands/project/__tests__/validate.test.js +98 -0
  82. package/commands/project/add.js +4 -8
  83. package/commands/project/cloneApp.js +14 -19
  84. package/commands/project/create.js +3 -10
  85. package/commands/project/deploy.js +5 -5
  86. package/commands/project/dev/deprecatedFlow.js +7 -16
  87. package/commands/project/dev/index.js +16 -13
  88. package/commands/project/dev/unifiedFlow.js +8 -4
  89. package/commands/project/download.js +10 -14
  90. package/commands/project/installDeps.js +8 -9
  91. package/commands/project/listBuilds.js +12 -21
  92. package/commands/project/logs.js +21 -24
  93. package/commands/project/migrate.js +41 -13
  94. package/commands/project/migrateApp.js +10 -17
  95. package/commands/project/open.js +6 -14
  96. package/commands/project/profile/add.js +3 -3
  97. package/commands/project/profile/delete.js +1 -2
  98. package/commands/project/profile.js +2 -3
  99. package/commands/project/upload.d.ts +2 -2
  100. package/commands/project/upload.js +17 -26
  101. package/commands/project/validate.js +7 -7
  102. package/commands/project/watch.js +13 -22
  103. package/commands/project.js +2 -3
  104. package/commands/sandbox/__tests__/create.test.js +5 -5
  105. package/commands/sandbox/create.js +22 -32
  106. package/commands/sandbox/delete.js +35 -63
  107. package/commands/sandbox.js +2 -2
  108. package/commands/secret/addSecret.js +7 -17
  109. package/commands/secret/deleteSecret.js +10 -20
  110. package/commands/secret/listSecret.js +8 -10
  111. package/commands/secret/updateSecret.js +9 -17
  112. package/commands/secret.js +2 -2
  113. package/commands/testAccount/__tests__/delete.test.js +2 -4
  114. package/commands/testAccount/create.js +0 -3
  115. package/commands/testAccount/delete.d.ts +4 -3
  116. package/commands/testAccount/delete.js +155 -14
  117. package/commands/testAccount/importData.d.ts +1 -1
  118. package/commands/testAccount/importData.js +1 -1
  119. package/commands/testAccount.js +1 -1
  120. package/lang/en.d.ts +317 -120
  121. package/lang/en.js +312 -118
  122. package/lang/en.lyaml +2 -2
  123. package/lib/__tests__/buildAccount.test.js +2 -1
  124. package/lib/__tests__/commonOpts.test.js +1 -1
  125. package/lib/__tests__/dependencyManagement.test.js +1 -1
  126. package/lib/__tests__/developerTestAccounts.test.js +3 -3
  127. package/lib/__tests__/npm.test.js +1 -1
  128. package/lib/__tests__/oauth.test.js +4 -4
  129. package/lib/__tests__/process.test.js +10 -5
  130. package/lib/__tests__/sandboxSync.test.js +8 -8
  131. package/lib/__tests__/sandboxes.test.js +8 -8
  132. package/lib/__tests__/serverlessLogs.test.js +1 -1
  133. package/lib/__tests__/usageTracking.test.js +5 -5
  134. package/lib/__tests__/validation.test.js +2 -1
  135. package/lib/__tests__/yargsUtils.test.js +83 -9
  136. package/lib/app/__tests__/migrate.test.js +19 -56
  137. package/lib/app/__tests__/migrate_legacy.test.js +1 -1
  138. package/lib/app/migrate.d.ts +2 -8
  139. package/lib/app/migrate.js +5 -80
  140. package/lib/app/migrate_legacy.js +20 -24
  141. package/lib/buildAccount.js +25 -57
  142. package/lib/commonOpts.d.ts +1 -1
  143. package/lib/commonOpts.js +25 -22
  144. package/lib/configOptions.js +7 -0
  145. package/lib/constants.d.ts +13 -0
  146. package/lib/constants.js +17 -0
  147. package/lib/dependencyManagement.js +9 -27
  148. package/lib/developerTestAccounts.js +9 -23
  149. package/lib/doctor/Diagnosis.js +11 -23
  150. package/lib/doctor/DiagnosticInfoBuilder.js +12 -11
  151. package/lib/doctor/Doctor.js +42 -90
  152. package/lib/doctor/__tests__/Doctor.test.js +4 -4
  153. package/lib/errorHandlers/index.js +12 -20
  154. package/lib/errorHandlers/suppressError.js +10 -17
  155. package/lib/lang.js +6 -5
  156. package/lib/links.d.ts +1 -0
  157. package/lib/links.js +14 -7
  158. package/lib/mcp/setup.js +1 -1
  159. package/lib/middleware/__test__/commandTargetingUtils.test.js +99 -0
  160. package/lib/middleware/__test__/configMiddleware.test.js +11 -11
  161. package/lib/middleware/__test__/yargsChecksMiddleware.test.js +6 -8
  162. package/lib/middleware/commandTargetingUtils.d.ts +8 -0
  163. package/lib/middleware/commandTargetingUtils.js +78 -0
  164. package/lib/middleware/configMiddleware.d.ts +1 -1
  165. package/lib/middleware/configMiddleware.js +21 -81
  166. package/lib/middleware/fireAlarmMiddleware.js +15 -5
  167. package/lib/middleware/gitMiddleware.js +5 -1
  168. package/lib/middleware/notificationsMiddleware.js +5 -11
  169. package/lib/middleware/yargsChecksMiddleware.js +6 -9
  170. package/lib/npm.js +2 -2
  171. package/lib/oauth.js +5 -5
  172. package/lib/process.js +5 -4
  173. package/lib/projectProfiles.d.ts +1 -1
  174. package/lib/projectProfiles.js +2 -10
  175. package/lib/projects/__tests__/AppDevModeInterface.test.js +2 -0
  176. package/lib/projects/__tests__/LocalDevProcess.test.js +227 -16
  177. package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +86 -60
  178. package/lib/projects/__tests__/deploy.test.js +71 -6
  179. package/lib/projects/__tests__/localDevProjectHelpers.test.js +6 -2
  180. package/lib/projects/__tests__/platformVersion.test.js +8 -8
  181. package/lib/projects/__tests__/projects.test.js +12 -12
  182. package/lib/projects/__tests__/structure.test.js +3 -3
  183. package/lib/projects/__tests__/upload.test.d.ts +1 -0
  184. package/lib/projects/__tests__/upload.test.js +82 -0
  185. package/lib/projects/add/__tests__/legacyAddComponent.test.js +6 -6
  186. package/lib/projects/add/__tests__/v3AddComponent.test.js +4 -4
  187. package/lib/projects/create/__tests__/legacy.test.js +5 -5
  188. package/lib/projects/create/__tests__/v3.test.js +80 -5
  189. package/lib/projects/create/index.js +2 -2
  190. package/lib/projects/create/legacy.js +2 -2
  191. package/lib/projects/create/v3.js +10 -8
  192. package/lib/projects/localDev/AppDevModeInterface.d.ts +2 -0
  193. package/lib/projects/localDev/AppDevModeInterface.js +21 -12
  194. package/lib/projects/localDev/LocalDevLogger.d.ts +4 -0
  195. package/lib/projects/localDev/LocalDevLogger.js +27 -6
  196. package/lib/projects/localDev/LocalDevManager.js +4 -5
  197. package/lib/projects/localDev/LocalDevProcess.d.ts +7 -5
  198. package/lib/projects/localDev/LocalDevProcess.js +90 -19
  199. package/lib/projects/localDev/LocalDevState.d.ts +9 -8
  200. package/lib/projects/localDev/LocalDevState.js +18 -17
  201. package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +2 -1
  202. package/lib/projects/localDev/LocalDevWebsocketServer.js +62 -33
  203. package/lib/projects/localDev/helpers/project.d.ts +1 -0
  204. package/lib/projects/localDev/helpers/project.js +42 -1
  205. package/lib/projects/localDev/localDevWebsocketServerUtils.d.ts +4 -0
  206. package/lib/projects/localDev/localDevWebsocketServerUtils.js +10 -0
  207. package/lib/projects/platformVersion.d.ts +1 -1
  208. package/lib/projects/platformVersion.js +1 -1
  209. package/lib/projects/pollProjectBuildAndDeploy.js +4 -4
  210. package/lib/projects/structure.d.ts +2 -2
  211. package/lib/projects/structure.js +6 -6
  212. package/lib/projects/upload.d.ts +2 -3
  213. package/lib/projects/upload.js +17 -9
  214. package/lib/prompts/accountNamePrompt.js +14 -19
  215. package/lib/prompts/accountsPrompt.js +2 -2
  216. package/lib/prompts/cmsFieldPrompt.js +2 -2
  217. package/lib/prompts/createApiSamplePrompt.js +5 -5
  218. package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +10 -1
  219. package/lib/prompts/createFunctionPrompt.js +14 -14
  220. package/lib/prompts/createModulePrompt.js +9 -9
  221. package/lib/prompts/createTemplatePrompt.js +2 -2
  222. package/lib/prompts/downloadProjectPrompt.js +5 -8
  223. package/lib/prompts/personalAccessKeyPrompt.js +3 -3
  224. package/lib/prompts/previewPrompt.js +6 -6
  225. package/lib/prompts/projectAddPrompt.js +8 -1
  226. package/lib/prompts/projectDevTargetAccountPrompt.js +20 -32
  227. package/lib/prompts/projectNamePrompt.js +4 -8
  228. package/lib/prompts/projectsLogsPrompt.js +2 -4
  229. package/lib/prompts/promptUtils.js +30 -9
  230. package/lib/prompts/sandboxesPrompt.js +7 -7
  231. package/lib/prompts/secretPrompt.js +3 -3
  232. package/lib/prompts/selectAppPrompt.js +3 -3
  233. package/lib/prompts/selectHubDBTablePrompt.js +9 -13
  234. package/lib/prompts/selectProjectTemplatePrompt.js +2 -0
  235. package/lib/prompts/selectPublicAppForMigrationPrompt.js +15 -19
  236. package/lib/prompts/setAsDefaultAccountPrompt.js +4 -8
  237. package/lib/prompts/uploadPrompt.js +5 -5
  238. package/lib/sandboxSync.js +24 -41
  239. package/lib/sandboxes.js +19 -47
  240. package/lib/schema.js +3 -3
  241. package/lib/serverlessLogs.js +11 -13
  242. package/lib/theme/__tests__/migrate.test.d.ts +1 -0
  243. package/lib/theme/__tests__/migrate.test.js +233 -0
  244. package/lib/theme/migrate.d.ts +13 -0
  245. package/lib/theme/migrate.js +90 -0
  246. package/lib/ui/SpinniesManager.d.ts +2 -0
  247. package/lib/ui/SpinniesManager.js +7 -0
  248. package/lib/ui/boxen.js +1 -2
  249. package/lib/ui/git.js +13 -10
  250. package/lib/ui/index.js +38 -37
  251. package/lib/ui/serverlessFunctionLogs.js +9 -7
  252. package/lib/ui/uiMessages.d.ts +68 -0
  253. package/lib/ui/uiMessages.js +71 -0
  254. package/lib/usageTracking.js +8 -8
  255. package/lib/validation.js +20 -23
  256. package/lib/yargsUtils.d.ts +1 -1
  257. package/lib/yargsUtils.js +12 -5
  258. package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +2 -2
  259. package/mcp-server/tools/index.js +4 -0
  260. package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +2 -2
  261. package/mcp-server/tools/project/CreateProjectTool.d.ts +2 -2
  262. package/mcp-server/tools/project/DocsSearchTool.d.ts +4 -1
  263. package/mcp-server/tools/project/DocsSearchTool.js +5 -5
  264. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +23 -0
  265. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +68 -0
  266. package/mcp-server/tools/project/GetApplicationInfoTool.d.ts +11 -0
  267. package/mcp-server/tools/project/GetApplicationInfoTool.js +49 -0
  268. package/mcp-server/tools/project/GetConfigValuesTool.d.ts +4 -1
  269. package/mcp-server/tools/project/GetConfigValuesTool.js +12 -6
  270. package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +2 -2
  271. package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +12 -10
  272. package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.d.ts +1 -0
  273. package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.js +169 -0
  274. package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.d.ts +1 -0
  275. package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.js +115 -0
  276. package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +8 -7
  277. package/mcp-server/utils/__tests__/cliConfig.test.d.ts +1 -0
  278. package/mcp-server/utils/__tests__/cliConfig.test.js +110 -0
  279. package/mcp-server/utils/cliConfig.d.ts +1 -0
  280. package/mcp-server/utils/cliConfig.js +12 -0
  281. package/mcp-server/utils/toolUsageTracking.js +2 -2
  282. package/package.json +4 -4
  283. package/types/LocalDev.d.ts +19 -3
  284. package/types/Yargs.d.ts +1 -1
  285. package/ui/index.js +1 -1
  286. package/commands/app/__tests__/install.test.js +0 -47
  287. package/commands/app/install.d.ts +0 -8
  288. package/commands/app/install.js +0 -122
  289. package/lib/middleware/__test__/utils.test.js +0 -51
  290. package/lib/middleware/utils.d.ts +0 -8
  291. package/lib/middleware/utils.js +0 -14
  292. /package/commands/{app/__tests__/install.test.d.ts → project/__tests__/validate.test.d.ts} +0 -0
  293. /package/lib/middleware/__test__/{utils.test.d.ts → commandTargetingUtils.test.d.ts} +0 -0
@@ -0,0 +1,110 @@
1
+ import { getAccountIdFromCliConfig } from '../cliConfig.js';
2
+ import { configFileExists, findConfig, getAccountId, loadConfig, } from '@hubspot/local-dev-lib/config';
3
+ vi.mock('@hubspot/local-dev-lib/config');
4
+ const mockConfigFileExists = configFileExists;
5
+ const mockFindConfig = findConfig;
6
+ const mockGetAccountId = getAccountId;
7
+ const mockLoadConfig = loadConfig;
8
+ describe('mcp-server/utils/cliConfig', () => {
9
+ const mockWorkingDirectory = '/test/working/directory';
10
+ beforeEach(() => {
11
+ vi.clearAllMocks();
12
+ });
13
+ describe('getAccountIdFromCliConfig', () => {
14
+ it('should load global config when it exists and return account ID', () => {
15
+ const expectedAccountId = 12345;
16
+ mockConfigFileExists.mockReturnValue(true);
17
+ mockGetAccountId.mockReturnValue(expectedAccountId);
18
+ const result = getAccountIdFromCliConfig(mockWorkingDirectory);
19
+ expect(mockConfigFileExists).toHaveBeenCalledWith(true);
20
+ expect(mockLoadConfig).toHaveBeenCalledWith('');
21
+ expect(mockFindConfig).not.toHaveBeenCalled();
22
+ expect(mockGetAccountId).toHaveBeenCalledWith(undefined);
23
+ expect(result).toBe(expectedAccountId);
24
+ });
25
+ it('should load local config when global config does not exist and return account ID', () => {
26
+ const expectedAccountId = 67890;
27
+ const localConfigPath = '/path/to/local/config';
28
+ mockConfigFileExists.mockReturnValue(false);
29
+ mockFindConfig.mockReturnValue(localConfigPath);
30
+ mockGetAccountId.mockReturnValue(expectedAccountId);
31
+ const result = getAccountIdFromCliConfig(mockWorkingDirectory);
32
+ expect(mockConfigFileExists).toHaveBeenCalledWith(true);
33
+ expect(mockFindConfig).toHaveBeenCalledWith(mockWorkingDirectory);
34
+ expect(mockLoadConfig).toHaveBeenCalledWith(localConfigPath);
35
+ expect(mockGetAccountId).toHaveBeenCalledWith(undefined);
36
+ expect(result).toBe(expectedAccountId);
37
+ });
38
+ it('should pass accountNameOrId parameter to getAccountId when provided as string', () => {
39
+ const expectedAccountId = 11111;
40
+ const accountName = 'test-account';
41
+ mockConfigFileExists.mockReturnValue(true);
42
+ mockGetAccountId.mockReturnValue(expectedAccountId);
43
+ const result = getAccountIdFromCliConfig(mockWorkingDirectory, accountName);
44
+ expect(mockConfigFileExists).toHaveBeenCalledWith(true);
45
+ expect(mockLoadConfig).toHaveBeenCalledWith('');
46
+ expect(mockGetAccountId).toHaveBeenCalledWith(accountName);
47
+ expect(result).toBe(expectedAccountId);
48
+ });
49
+ it('should pass accountNameOrId parameter to getAccountId when provided as number', () => {
50
+ const expectedAccountId = 22222;
51
+ const accountId = 22222;
52
+ mockConfigFileExists.mockReturnValue(true);
53
+ mockGetAccountId.mockReturnValue(expectedAccountId);
54
+ const result = getAccountIdFromCliConfig(mockWorkingDirectory, accountId);
55
+ expect(mockConfigFileExists).toHaveBeenCalledWith(true);
56
+ expect(mockLoadConfig).toHaveBeenCalledWith('');
57
+ expect(mockGetAccountId).toHaveBeenCalledWith(accountId);
58
+ expect(result).toBe(expectedAccountId);
59
+ });
60
+ it('should return null when getAccountId returns null', () => {
61
+ mockConfigFileExists.mockReturnValue(true);
62
+ mockGetAccountId.mockReturnValue(null);
63
+ const result = getAccountIdFromCliConfig(mockWorkingDirectory);
64
+ expect(mockConfigFileExists).toHaveBeenCalledWith(true);
65
+ expect(mockLoadConfig).toHaveBeenCalledWith('');
66
+ expect(mockGetAccountId).toHaveBeenCalledWith(undefined);
67
+ expect(result).toBeNull();
68
+ });
69
+ it('should handle findConfig returning null by passing null to loadConfig', () => {
70
+ const expectedAccountId = 33333;
71
+ mockConfigFileExists.mockReturnValue(false);
72
+ mockFindConfig.mockReturnValue(null);
73
+ mockGetAccountId.mockReturnValue(expectedAccountId);
74
+ const result = getAccountIdFromCliConfig(mockWorkingDirectory);
75
+ expect(mockConfigFileExists).toHaveBeenCalledWith(true);
76
+ expect(mockFindConfig).toHaveBeenCalledWith(mockWorkingDirectory);
77
+ expect(mockLoadConfig).toHaveBeenCalledWith(null);
78
+ expect(mockGetAccountId).toHaveBeenCalledWith(undefined);
79
+ expect(result).toBe(expectedAccountId);
80
+ });
81
+ it('should work with local config when provided with account name parameter', () => {
82
+ const expectedAccountId = 44444;
83
+ const accountName = 'local-test-account';
84
+ const localConfigPath = '/path/to/local/config';
85
+ mockConfigFileExists.mockReturnValue(false);
86
+ mockFindConfig.mockReturnValue(localConfigPath);
87
+ mockGetAccountId.mockReturnValue(expectedAccountId);
88
+ const result = getAccountIdFromCliConfig(mockWorkingDirectory, accountName);
89
+ expect(mockConfigFileExists).toHaveBeenCalledWith(true);
90
+ expect(mockFindConfig).toHaveBeenCalledWith(mockWorkingDirectory);
91
+ expect(mockLoadConfig).toHaveBeenCalledWith(localConfigPath);
92
+ expect(mockGetAccountId).toHaveBeenCalledWith(accountName);
93
+ expect(result).toBe(expectedAccountId);
94
+ });
95
+ it('should work with local config when provided with account ID parameter', () => {
96
+ const expectedAccountId = 55555;
97
+ const accountId = 55555;
98
+ const localConfigPath = '/path/to/local/config';
99
+ mockConfigFileExists.mockReturnValue(false);
100
+ mockFindConfig.mockReturnValue(localConfigPath);
101
+ mockGetAccountId.mockReturnValue(expectedAccountId);
102
+ const result = getAccountIdFromCliConfig(mockWorkingDirectory, accountId);
103
+ expect(mockConfigFileExists).toHaveBeenCalledWith(true);
104
+ expect(mockFindConfig).toHaveBeenCalledWith(mockWorkingDirectory);
105
+ expect(mockLoadConfig).toHaveBeenCalledWith(localConfigPath);
106
+ expect(mockGetAccountId).toHaveBeenCalledWith(accountId);
107
+ expect(result).toBe(expectedAccountId);
108
+ });
109
+ });
110
+ });
@@ -0,0 +1 @@
1
+ export declare function getAccountIdFromCliConfig(absolutePathToWorkingDirectory: string, accountNameOrId?: string | number): number | null;
@@ -0,0 +1,12 @@
1
+ import { configFileExists, findConfig, getAccountId, loadConfig, } from '@hubspot/local-dev-lib/config';
2
+ export function getAccountIdFromCliConfig(absolutePathToWorkingDirectory, accountNameOrId) {
3
+ const globalConfigExists = configFileExists(true);
4
+ if (globalConfigExists) {
5
+ loadConfig('');
6
+ }
7
+ else {
8
+ const configPath = findConfig(absolutePathToWorkingDirectory);
9
+ loadConfig(configPath);
10
+ }
11
+ return getAccountId(accountNameOrId);
12
+ }
@@ -1,7 +1,7 @@
1
1
  import { trackUsage } from '@hubspot/local-dev-lib/trackUsage';
2
- import { logger } from '@hubspot/local-dev-lib/logger';
3
2
  import { EventClass, getNodeVersionData, getPlatform, } from '../../lib/usageTracking.js';
4
3
  import { getAccountId, isTrackingAllowed } from '@hubspot/local-dev-lib/config';
4
+ import { uiLogger } from '../../lib/ui/logger.js';
5
5
  export async function trackToolUsage(toolName, meta) {
6
6
  if (!isTrackingAllowed()) {
7
7
  return;
@@ -16,7 +16,7 @@ export async function trackToolUsage(toolName, meta) {
16
16
  };
17
17
  const accountId = getAccountId() || undefined;
18
18
  try {
19
- logger.info('Tracking tool usage');
19
+ uiLogger.info('Tracking tool usage');
20
20
  await trackUsage('cli-interaction', EventClass.INTERACTION, usageTrackingEvent, accountId);
21
21
  }
22
22
  catch (error) { }
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "7.7.34-experimental.0",
3
+ "version": "7.8.0-beta.0",
4
4
  "description": "The official CLI for developing on HubSpot",
5
5
  "license": "Apache-2.0",
6
6
  "repository": "https://github.com/HubSpot/hubspot-cli",
7
7
  "type": "module",
8
8
  "dependencies": {
9
- "@hubspot/local-dev-lib": "3.18.0",
10
- "@hubspot/project-parsing-lib": "0.8.3",
9
+ "@hubspot/local-dev-lib": "3.20.0",
10
+ "@hubspot/project-parsing-lib": "0.9.0",
11
11
  "@hubspot/serverless-dev-runtime": "7.0.6",
12
12
  "@hubspot/theme-preview-dev-server": "0.0.10",
13
- "@hubspot/ui-extensions-dev-server": "0.9.8",
13
+ "@hubspot/ui-extensions-dev-server": "0.10.1",
14
14
  "archiver": "7.0.1",
15
15
  "boxen": "8.0.1",
16
16
  "chalk": "5.4.1",
@@ -1,17 +1,17 @@
1
1
  import { HSProfileVariables, IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types.js';
2
2
  import { Environment } from '@hubspot/local-dev-lib/types/Config';
3
3
  import { ValueOf } from '@hubspot/local-dev-lib/types/Utils';
4
+ import { Project } from '@hubspot/local-dev-lib/types/Project';
4
5
  import { ProjectConfig } from './Projects.js';
5
6
  import LocalDevState from '../lib/projects/localDev/LocalDevState.js';
6
- import { APP_INSTALLATION_STATES, LOCAL_DEV_SERVER_MESSAGE_TYPES } from '../lib/constants.js';
7
+ import { APP_INSTALLATION_STATES, LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES, LOCAL_DEV_SERVER_MESSAGE_TYPES } from '../lib/constants.js';
7
8
  export type LocalDevStateConstructorOptions = {
8
9
  targetProjectAccountId: number;
9
10
  targetTestingAccountId: number;
10
11
  profile?: string;
11
12
  projectConfig: ProjectConfig;
12
13
  projectDir: string;
13
- projectId: number;
14
- projectName: string;
14
+ projectData: Project;
15
15
  debug?: boolean;
16
16
  initialProjectNodes: {
17
17
  [key: string]: IntermediateRepresentationNodeLocalDev;
@@ -23,6 +23,12 @@ export type LocalDevWebsocketMessage = {
23
23
  type: string;
24
24
  data?: unknown;
25
25
  };
26
+ export type LocalDevDeployWebsocketMessage = {
27
+ type: typeof LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.DEPLOY;
28
+ data: {
29
+ force: boolean;
30
+ };
31
+ };
26
32
  export type LocalDevStateListener<K extends keyof LocalDevState> = (value: LocalDevState[K]) => void;
27
33
  export type AppLocalDevData = {
28
34
  id: number;
@@ -32,3 +38,13 @@ export type AppLocalDevData = {
32
38
  scopeGroupIds: number[];
33
39
  };
34
40
  export type LocalDevServerMessage = ValueOf<typeof LOCAL_DEV_SERVER_MESSAGE_TYPES>;
41
+ export type LocalDevProjectUploadResult = {
42
+ uploadSuccess: boolean;
43
+ buildSuccess: boolean;
44
+ deploySuccess?: boolean;
45
+ deployId?: number;
46
+ };
47
+ export type LocalDevProjectDeployResult = {
48
+ success: boolean;
49
+ deployId?: number;
50
+ };
package/types/Yargs.d.ts CHANGED
@@ -15,7 +15,7 @@ export type AccountArgs = {
15
15
  account?: string;
16
16
  };
17
17
  export type EnvironmentArgs = {
18
- 'use-env'?: boolean;
18
+ 'use-env'?: string;
19
19
  };
20
20
  export type OverwriteArgs = Options & {
21
21
  o?: boolean;
package/ui/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { render } from 'ink';
2
- // Ink components will be enabled by setting the ENABLE_INK environment variable
2
+ // Ink components will be enabled by setting the HUBSPOT_ENABLE_INK environment variable
3
3
  export async function renderInline(component) {
4
4
  const { unmount } = render(component, { patchConsole: false });
5
5
  unmount();
@@ -1,47 +0,0 @@
1
- import yargs from 'yargs';
2
- import { addAccountOptions, addConfigOptions, addUseEnvironmentOptions, addGlobalOptions, addJSONOutputOptions, } from '../../../lib/commonOpts.js';
3
- import installCommand from '../install.js';
4
- vi.mock('../../../lib/commonOpts');
5
- describe('commands/app/install', () => {
6
- const yargsMock = yargs;
7
- describe('command', () => {
8
- it('should have the correct command structure', () => {
9
- expect(installCommand.command).toEqual('install <test-account-id>');
10
- });
11
- });
12
- describe('describe', () => {
13
- it('should provide a description', () => {
14
- expect(installCommand.describe).not.toBeDefined();
15
- });
16
- });
17
- describe('builder', () => {
18
- it('should support the correct options', () => {
19
- installCommand.builder(yargsMock);
20
- expect(addGlobalOptions).toHaveBeenCalledTimes(1);
21
- expect(addGlobalOptions).toHaveBeenCalledWith(yargsMock);
22
- expect(addAccountOptions).toHaveBeenCalledTimes(1);
23
- expect(addAccountOptions).toHaveBeenCalledWith(yargsMock);
24
- expect(addConfigOptions).toHaveBeenCalledTimes(1);
25
- expect(addConfigOptions).toHaveBeenCalledWith(yargsMock);
26
- expect(addUseEnvironmentOptions).toHaveBeenCalledTimes(1);
27
- expect(addUseEnvironmentOptions).toHaveBeenCalledWith(yargsMock);
28
- expect(addJSONOutputOptions).toHaveBeenCalledTimes(1);
29
- expect(addJSONOutputOptions).toHaveBeenCalledWith(yargsMock);
30
- expect(yargsMock.positional).toHaveBeenCalledTimes(1);
31
- expect(yargsMock.positional).toHaveBeenCalledWith('test-account-id', expect.objectContaining({
32
- type: 'number',
33
- required: true,
34
- describe: expect.any(String),
35
- }));
36
- expect(yargsMock.option).toHaveBeenCalledTimes(2);
37
- expect(yargsMock.option).toHaveBeenCalledWith('app-uid', expect.objectContaining({
38
- type: 'string',
39
- describe: expect.any(String),
40
- }));
41
- expect(yargsMock.option).toHaveBeenCalledWith('project-name', expect.objectContaining({
42
- type: 'string',
43
- describe: expect.any(String),
44
- }));
45
- });
46
- });
47
- });
@@ -1,8 +0,0 @@
1
- import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, YargsCommandModule, JSONOutputArgs } from '../../types/Yargs.js';
2
- type InstallAppArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs & {
3
- appUid?: string;
4
- projectName?: string;
5
- testAccountId: number;
6
- };
7
- declare const installAppCommand: YargsCommandModule<unknown, InstallAppArgs>;
8
- export default installAppCommand;
@@ -1,122 +0,0 @@
1
- import { fetchDeveloperTestAccountOauthAppInstallStatus, installOauthAppIntoDeveloperTestAccount, } from '@hubspot/local-dev-lib/api/developerTestAccounts';
2
- import { trackCommandUsage } from '../../lib/usageTracking.js';
3
- import { commands } from '../../lang/en.js';
4
- import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
5
- import { makeYargsBuilder } from '../../lib/yargsUtils.js';
6
- import { APP_AUTH_TYPES } from '../../lib/constants.js';
7
- import { uiLogger } from '../../lib/ui/logger.js';
8
- import SpinniesManager from '../../lib/ui/SpinniesManager.js';
9
- import { poll } from '../../lib/polling.js';
10
- import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
11
- import { handleTranslate } from '../../lib/projects/upload.js';
12
- import { isAppIRNode } from '../../lib/projects/structure.js';
13
- import { logError } from '../../lib/errorHandlers/index.js';
14
- const command = 'install <test-account-id>';
15
- const describe = undefined; // commands.app.subcommands.install.describe;
16
- async function handler(args) {
17
- const { derivedAccountId, appUid, projectName, testAccountId, formatOutputAsJson, } = args;
18
- trackCommandUsage('app-install', {}, derivedAccountId);
19
- const jsonOutput = {};
20
- let targetProjectName = projectName;
21
- let targetAppUid = appUid;
22
- const { projectConfig, projectDir } = await getProjectConfig();
23
- if (!targetProjectName) {
24
- validateProjectConfig(projectConfig, projectDir);
25
- targetProjectName = projectConfig?.name;
26
- }
27
- if (!targetProjectName) {
28
- uiLogger.error(commands.app.subcommands.install.errors.mustSpecifyProjectName);
29
- process.exit(EXIT_CODES.ERROR);
30
- }
31
- let isAppOauth = true;
32
- if (!targetAppUid) {
33
- const intermediateRepresentation = await handleTranslate(projectDir, projectConfig, derivedAccountId, true, undefined);
34
- if (intermediateRepresentation) {
35
- Object.values(intermediateRepresentation.intermediateNodesIndexedByUid).forEach(node => {
36
- if (isAppIRNode(node)) {
37
- targetAppUid = node.uid;
38
- isAppOauth = node.config.auth.type === APP_AUTH_TYPES.OAUTH;
39
- }
40
- });
41
- }
42
- }
43
- if (!targetAppUid) {
44
- uiLogger.error(commands.app.subcommands.install.errors.noAppUidFound);
45
- process.exit(EXIT_CODES.ERROR);
46
- }
47
- if (!isAppOauth) {
48
- uiLogger.error(commands.app.subcommands.install.errors.appMustBeOauth);
49
- process.exit(EXIT_CODES.ERROR);
50
- }
51
- try {
52
- const { data } = await installOauthAppIntoDeveloperTestAccount(derivedAccountId, testAccountId, targetProjectName, targetAppUid);
53
- if (data?.authCodes.length > 0) {
54
- jsonOutput.authCode = data.authCodes[0].authCode;
55
- }
56
- }
57
- catch (err) {
58
- logError(err);
59
- process.exit(EXIT_CODES.ERROR);
60
- }
61
- SpinniesManager.init({
62
- succeedColor: 'white',
63
- });
64
- SpinniesManager.add('installApp', {
65
- text: commands.app.subcommands.install.polling.start,
66
- });
67
- let appInstallSucceeded = false;
68
- try {
69
- await poll(() => fetchDeveloperTestAccountOauthAppInstallStatus(derivedAccountId, targetProjectName, targetAppUid), {
70
- successStates: ['SUCCESS'],
71
- errorStates: [],
72
- });
73
- appInstallSucceeded = true;
74
- }
75
- catch (err) {
76
- SpinniesManager.fail('installApp');
77
- logError(err);
78
- process.exit(EXIT_CODES.ERROR);
79
- }
80
- if (!appInstallSucceeded) {
81
- SpinniesManager.fail('installApp');
82
- process.exit(EXIT_CODES.ERROR);
83
- }
84
- SpinniesManager.succeed('installApp', {
85
- text: commands.app.subcommands.install.polling.success,
86
- });
87
- if (formatOutputAsJson) {
88
- uiLogger.json(jsonOutput);
89
- }
90
- process.exit(EXIT_CODES.SUCCESS);
91
- }
92
- function installAppBuilder(yargs) {
93
- yargs.positional('test-account-id', {
94
- describe: commands.app.subcommands.install.positionals.testAccountId,
95
- required: true,
96
- type: 'number',
97
- });
98
- yargs.option('app-uid', {
99
- describe: commands.app.subcommands.install.options.appUid,
100
- type: 'string',
101
- });
102
- yargs.option('project-name', {
103
- describe: commands.app.subcommands.install.options.projectName,
104
- type: 'string',
105
- });
106
- yargs.example('install 1234567890 --app-uid=my-app-uid --project-name=my-project', commands.app.subcommands.install.example);
107
- return yargs;
108
- }
109
- const builder = makeYargsBuilder(installAppBuilder, command, commands.app.subcommands.install.describe, {
110
- useGlobalOptions: true,
111
- useAccountOptions: true,
112
- useConfigOptions: true,
113
- useEnvironmentOptions: true,
114
- useJSONOutputOptions: true,
115
- });
116
- const installAppCommand = {
117
- command,
118
- describe,
119
- handler,
120
- builder,
121
- };
122
- export default installAppCommand;
@@ -1,51 +0,0 @@
1
- import { isTargetedCommand } from '../utils.js';
2
- const targetCommandMap = {
3
- init: { target: true },
4
- account: {
5
- target: true,
6
- subCommands: {
7
- use: { target: true },
8
- },
9
- },
10
- project: {
11
- subCommands: {
12
- deploy: { target: true },
13
- },
14
- },
15
- };
16
- describe('lib/middleware/utils', () => {
17
- describe('isTargetedCommand()', () => {
18
- it('should return true for a direct target command', () => {
19
- const result = isTargetedCommand(['init'], targetCommandMap);
20
- expect(result).toBe(true);
21
- });
22
- it('should return true for a command with a subcommand', () => {
23
- const result = isTargetedCommand(['account'], targetCommandMap);
24
- expect(result).toBe(true);
25
- });
26
- it('should return true for a nested target command', () => {
27
- const result = isTargetedCommand(['project', 'deploy'], targetCommandMap);
28
- expect(result).toBe(true);
29
- });
30
- it('should return false for a non-existent command', () => {
31
- const result = isTargetedCommand(['nonexistent'], targetCommandMap);
32
- expect(result).toBe(false);
33
- });
34
- it('should return false for a non-targeted command', () => {
35
- const result = isTargetedCommand(['auth'], targetCommandMap);
36
- expect(result).toBe(false);
37
- });
38
- it('should return false for a command with a targeted subcommand', () => {
39
- const result = isTargetedCommand(['project'], targetCommandMap);
40
- expect(result).toBe(false);
41
- });
42
- it('should return false for a non-existent subcommand', () => {
43
- const result = isTargetedCommand(['auth', 'nonexistent'], targetCommandMap);
44
- expect(result).toBe(false);
45
- });
46
- it('should return false for an empty command array', () => {
47
- const result = isTargetedCommand([], targetCommandMap);
48
- expect(result).toBe(false);
49
- });
50
- });
51
- });
@@ -1,8 +0,0 @@
1
- type TargetCommandMap = {
2
- [key: string]: {
3
- target?: boolean;
4
- subCommands?: TargetCommandMap;
5
- };
6
- };
7
- export declare function isTargetedCommand(commandParts: (string | number)[], targetCommandMap: TargetCommandMap): boolean;
8
- export {};
@@ -1,14 +0,0 @@
1
- export function isTargetedCommand(commandParts, targetCommandMap) {
2
- const currentCommand = commandParts[0];
3
- if (!targetCommandMap[currentCommand]) {
4
- return false;
5
- }
6
- if (targetCommandMap[currentCommand].target) {
7
- return true;
8
- }
9
- const subCommands = targetCommandMap[currentCommand].subCommands || {};
10
- if (commandParts.length > 1) {
11
- return isTargetedCommand(commandParts.slice(1), subCommands);
12
- }
13
- return false;
14
- }