@hubspot/cli 7.7.19-experimental.3 → 7.7.20-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 (296) hide show
  1. package/api/__tests__/migrate.test.d.ts +1 -0
  2. package/api/__tests__/migrate.test.js +183 -0
  3. package/commands/__tests__/account.test.d.ts +1 -0
  4. package/commands/__tests__/account.test.js +74 -0
  5. package/commands/__tests__/auth.test.d.ts +1 -0
  6. package/commands/__tests__/auth.test.js +43 -0
  7. package/commands/__tests__/cms.test.d.ts +1 -0
  8. package/commands/__tests__/cms.test.js +49 -0
  9. package/commands/__tests__/config.test.d.ts +1 -0
  10. package/commands/__tests__/config.test.js +49 -0
  11. package/commands/__tests__/create.test.d.ts +1 -0
  12. package/commands/__tests__/create.test.js +38 -0
  13. package/commands/__tests__/customObject.test.d.ts +1 -0
  14. package/commands/__tests__/customObject.test.js +54 -0
  15. package/commands/__tests__/doctor.test.d.ts +1 -0
  16. package/commands/__tests__/doctor.test.js +139 -0
  17. package/commands/__tests__/feedback.test.d.ts +1 -0
  18. package/commands/__tests__/feedback.test.js +62 -0
  19. package/commands/__tests__/fetch.test.d.ts +1 -0
  20. package/commands/__tests__/fetch.test.js +56 -0
  21. package/commands/__tests__/filemanager.test.d.ts +1 -0
  22. package/commands/__tests__/filemanager.test.js +50 -0
  23. package/commands/__tests__/function.test.d.ts +1 -0
  24. package/commands/__tests__/function.test.js +51 -0
  25. package/commands/__tests__/getStarted.test.d.ts +1 -0
  26. package/commands/__tests__/getStarted.test.js +170 -0
  27. package/commands/__tests__/hubdb.test.d.ts +1 -0
  28. package/commands/__tests__/hubdb.test.js +55 -0
  29. package/commands/__tests__/init.test.d.ts +1 -0
  30. package/commands/__tests__/init.test.js +47 -0
  31. package/commands/__tests__/lint.test.d.ts +1 -0
  32. package/commands/__tests__/lint.test.js +38 -0
  33. package/commands/__tests__/list.test.d.ts +1 -0
  34. package/commands/__tests__/list.test.js +47 -0
  35. package/commands/__tests__/logs.test.d.ts +1 -0
  36. package/commands/__tests__/logs.test.js +70 -0
  37. package/commands/__tests__/mcp.test.d.ts +1 -0
  38. package/commands/__tests__/mcp.test.js +51 -0
  39. package/commands/__tests__/mv.test.d.ts +1 -0
  40. package/commands/__tests__/mv.test.js +84 -0
  41. package/commands/__tests__/open.test.d.ts +1 -0
  42. package/commands/__tests__/open.test.js +96 -0
  43. package/commands/__tests__/project.test.d.ts +1 -0
  44. package/commands/__tests__/project.test.js +100 -0
  45. package/commands/__tests__/remove.test.d.ts +1 -0
  46. package/commands/__tests__/remove.test.js +77 -0
  47. package/commands/__tests__/sandbox.test.d.ts +1 -0
  48. package/commands/__tests__/sandbox.test.js +49 -0
  49. package/commands/__tests__/secret.test.d.ts +1 -0
  50. package/commands/__tests__/secret.test.js +54 -0
  51. package/commands/__tests__/testAccount.test.d.ts +1 -0
  52. package/commands/__tests__/testAccount.test.js +60 -0
  53. package/commands/__tests__/theme.test.d.ts +1 -0
  54. package/commands/__tests__/theme.test.js +52 -0
  55. package/commands/account/__tests__/auth.test.d.ts +1 -0
  56. package/commands/account/__tests__/auth.test.js +31 -0
  57. package/commands/account/__tests__/clean.test.d.ts +1 -0
  58. package/commands/account/__tests__/clean.test.js +33 -0
  59. package/commands/account/__tests__/createOverride.test.d.ts +1 -0
  60. package/commands/account/__tests__/createOverride.test.js +37 -0
  61. package/commands/account/__tests__/info.test.d.ts +1 -0
  62. package/commands/account/__tests__/info.test.js +33 -0
  63. package/commands/account/__tests__/list.test.d.ts +1 -0
  64. package/commands/account/__tests__/list.test.js +33 -0
  65. package/commands/account/__tests__/remove.test.d.ts +1 -0
  66. package/commands/account/__tests__/remove.test.js +41 -0
  67. package/commands/account/__tests__/removeOverride.d.ts +1 -0
  68. package/commands/account/__tests__/removeOverride.js +30 -0
  69. package/commands/account/__tests__/rename.test.d.ts +1 -0
  70. package/commands/account/__tests__/rename.test.js +47 -0
  71. package/commands/account/__tests__/use.test.d.ts +1 -0
  72. package/commands/account/__tests__/use.test.js +37 -0
  73. package/commands/app/__tests__/migrate.test.d.ts +1 -0
  74. package/commands/app/__tests__/migrate.test.js +129 -0
  75. package/commands/app/secret/__tests__/add.test.d.ts +1 -0
  76. package/commands/app/secret/__tests__/add.test.js +33 -0
  77. package/commands/app/secret/__tests__/delete.test.d.ts +1 -0
  78. package/commands/app/secret/__tests__/delete.test.js +33 -0
  79. package/commands/app/secret/__tests__/list.test.d.ts +1 -0
  80. package/commands/app/secret/__tests__/list.test.js +30 -0
  81. package/commands/app/secret/__tests__/update.test.d.ts +1 -0
  82. package/commands/app/secret/__tests__/update.test.js +33 -0
  83. package/commands/app.js +1 -6
  84. package/commands/customObject/__tests__/create.test.d.ts +1 -0
  85. package/commands/customObject/__tests__/create.test.js +45 -0
  86. package/commands/customObject/__tests__/schema.test.d.ts +1 -0
  87. package/commands/customObject/__tests__/schema.test.js +58 -0
  88. package/commands/customObject/schema/__tests__/create.test.d.ts +1 -0
  89. package/commands/customObject/schema/__tests__/create.test.js +33 -0
  90. package/commands/customObject/schema/__tests__/delete.test.d.ts +1 -0
  91. package/commands/customObject/schema/__tests__/delete.test.js +47 -0
  92. package/commands/customObject/schema/__tests__/fetch-all.test.d.ts +1 -0
  93. package/commands/customObject/schema/__tests__/fetch-all.test.js +46 -0
  94. package/commands/customObject/schema/__tests__/fetch.test.d.ts +1 -0
  95. package/commands/customObject/schema/__tests__/fetch.test.js +50 -0
  96. package/commands/customObject/schema/__tests__/list.test.d.ts +1 -0
  97. package/commands/customObject/schema/__tests__/list.test.js +34 -0
  98. package/commands/customObject/schema/__tests__/update.test.d.ts +1 -0
  99. package/commands/customObject/schema/__tests__/update.test.js +45 -0
  100. package/commands/fetch.js +0 -1
  101. package/commands/filemanager/__tests__/fetch.test.d.ts +1 -0
  102. package/commands/filemanager/__tests__/fetch.test.js +37 -0
  103. package/commands/filemanager/__tests__/upload.test.d.ts +1 -0
  104. package/commands/filemanager/__tests__/upload.test.js +35 -0
  105. package/commands/hubdb/__tests__/clear.test.d.ts +1 -0
  106. package/commands/hubdb/__tests__/clear.test.js +33 -0
  107. package/commands/hubdb/__tests__/create.test.d.ts +1 -0
  108. package/commands/hubdb/__tests__/create.test.js +33 -0
  109. package/commands/hubdb/__tests__/delete.test.d.ts +1 -0
  110. package/commands/hubdb/__tests__/delete.test.js +33 -0
  111. package/commands/hubdb/__tests__/fetch.test.d.ts +1 -0
  112. package/commands/hubdb/__tests__/fetch.test.js +33 -0
  113. package/commands/hubdb/__tests__/list.test.d.ts +1 -0
  114. package/commands/hubdb/__tests__/list.test.js +101 -0
  115. package/commands/logs.js +0 -1
  116. package/commands/mcp/__tests__/setup.test.d.ts +1 -0
  117. package/commands/mcp/__tests__/setup.test.js +31 -0
  118. package/commands/mcp/__tests__/start.test.d.ts +1 -0
  119. package/commands/mcp/__tests__/start.test.js +32 -0
  120. package/commands/project/__tests__/add.test.d.ts +1 -0
  121. package/commands/project/__tests__/add.test.js +48 -0
  122. package/commands/project/__tests__/create.test.d.ts +1 -0
  123. package/commands/project/__tests__/create.test.js +45 -0
  124. package/commands/project/__tests__/deploy.test.d.ts +1 -0
  125. package/commands/project/__tests__/deploy.test.js +344 -0
  126. package/commands/project/__tests__/devUnifiedFlow.test.d.ts +1 -0
  127. package/commands/project/__tests__/devUnifiedFlow.test.js +419 -0
  128. package/commands/project/__tests__/download.test.d.ts +1 -0
  129. package/commands/project/__tests__/download.test.js +44 -0
  130. package/commands/project/__tests__/fixtures/exampleProject.json +33 -0
  131. package/commands/project/__tests__/installDeps.test.d.ts +1 -0
  132. package/commands/project/__tests__/installDeps.test.js +180 -0
  133. package/commands/project/__tests__/listBuilds.test.d.ts +1 -0
  134. package/commands/project/__tests__/listBuilds.test.js +43 -0
  135. package/commands/project/__tests__/logs.test.d.ts +1 -0
  136. package/commands/project/__tests__/logs.test.js +246 -0
  137. package/commands/project/__tests__/migrate.test.d.ts +1 -0
  138. package/commands/project/__tests__/migrate.test.js +116 -0
  139. package/commands/project/__tests__/migrateApp.test.d.ts +1 -0
  140. package/commands/project/__tests__/migrateApp.test.js +87 -0
  141. package/commands/project/__tests__/open.test.d.ts +1 -0
  142. package/commands/project/__tests__/open.test.js +44 -0
  143. package/commands/project/__tests__/profile.test.d.ts +1 -0
  144. package/commands/project/__tests__/profile.test.js +47 -0
  145. package/commands/project/__tests__/upload.test.d.ts +1 -0
  146. package/commands/project/__tests__/upload.test.js +48 -0
  147. package/commands/project/__tests__/watch.test.d.ts +1 -0
  148. package/commands/project/__tests__/watch.test.js +40 -0
  149. package/commands/project/dev/unifiedFlow.js +1 -1
  150. package/commands/sandbox/__tests__/create.test.d.ts +1 -0
  151. package/commands/sandbox/__tests__/create.test.js +36 -0
  152. package/commands/sandbox/__tests__/delete.test.d.ts +1 -0
  153. package/commands/sandbox/__tests__/delete.test.js +36 -0
  154. package/commands/secret/__tests__/addSecret.test.d.ts +1 -0
  155. package/commands/secret/__tests__/addSecret.test.js +34 -0
  156. package/commands/secret/__tests__/deleteSecret.test.d.ts +1 -0
  157. package/commands/secret/__tests__/deleteSecret.test.js +46 -0
  158. package/commands/secret/__tests__/listSecret.test.d.ts +1 -0
  159. package/commands/secret/__tests__/listSecret.test.js +34 -0
  160. package/commands/secret/__tests__/updateSecret.test.d.ts +1 -0
  161. package/commands/secret/__tests__/updateSecret.test.js +34 -0
  162. package/commands/testAccount/__tests__/create.test.d.ts +1 -0
  163. package/commands/testAccount/__tests__/create.test.js +38 -0
  164. package/commands/testAccount/__tests__/createConfig.test.d.ts +1 -0
  165. package/commands/testAccount/__tests__/createConfig.test.js +40 -0
  166. package/commands/testAccount/__tests__/delete.test.d.ts +1 -0
  167. package/commands/testAccount/__tests__/delete.test.js +36 -0
  168. package/commands/testAccount/create.js +24 -14
  169. package/commands/theme/__tests__/generate-selectors.test.d.ts +1 -0
  170. package/commands/theme/__tests__/generate-selectors.test.js +33 -0
  171. package/commands/theme/__tests__/marketplace-validate.test.d.ts +1 -0
  172. package/commands/theme/__tests__/marketplace-validate.test.js +41 -0
  173. package/commands/theme/__tests__/preview.test.d.ts +1 -0
  174. package/commands/theme/__tests__/preview.test.js +65 -0
  175. package/lang/en.d.ts +6 -65
  176. package/lang/en.js +6 -65
  177. package/lib/__tests__/accountTypes.test.d.ts +1 -0
  178. package/lib/__tests__/accountTypes.test.js +100 -0
  179. package/lib/__tests__/buildAccount.test.d.ts +1 -0
  180. package/lib/__tests__/buildAccount.test.js +231 -0
  181. package/lib/__tests__/commonOpts.test.d.ts +1 -0
  182. package/lib/__tests__/commonOpts.test.js +87 -0
  183. package/lib/__tests__/dependencyManagement.test.d.ts +1 -0
  184. package/lib/__tests__/dependencyManagement.test.js +180 -0
  185. package/lib/__tests__/developerTestAccounts.test.d.ts +1 -0
  186. package/lib/__tests__/developerTestAccounts.test.js +180 -0
  187. package/lib/__tests__/hasFeature.test.d.ts +1 -0
  188. package/lib/__tests__/hasFeature.test.js +37 -0
  189. package/lib/__tests__/npm.test.d.ts +1 -0
  190. package/lib/__tests__/npm.test.js +62 -0
  191. package/lib/__tests__/oauth.test.d.ts +1 -0
  192. package/lib/__tests__/oauth.test.js +113 -0
  193. package/lib/__tests__/parsing.test.d.ts +1 -0
  194. package/lib/__tests__/parsing.test.js +36 -0
  195. package/lib/__tests__/polling.test.d.ts +1 -0
  196. package/lib/__tests__/polling.test.js +78 -0
  197. package/lib/__tests__/process.test.d.ts +1 -0
  198. package/lib/__tests__/process.test.js +90 -0
  199. package/lib/__tests__/projectProfiles.test.d.ts +1 -0
  200. package/lib/__tests__/projectProfiles.test.js +134 -0
  201. package/lib/__tests__/sandboxSync.test.d.ts +1 -0
  202. package/lib/__tests__/sandboxSync.test.js +131 -0
  203. package/lib/__tests__/sandboxes.test.d.ts +1 -0
  204. package/lib/__tests__/sandboxes.test.js +148 -0
  205. package/lib/__tests__/serverlessLogs.test.d.ts +1 -0
  206. package/lib/__tests__/serverlessLogs.test.js +154 -0
  207. package/lib/__tests__/usageTracking.test.d.ts +1 -0
  208. package/lib/__tests__/usageTracking.test.js +171 -0
  209. package/lib/__tests__/validation.test.d.ts +1 -0
  210. package/lib/__tests__/validation.test.js +145 -0
  211. package/lib/__tests__/yargsUtils.test.d.ts +1 -0
  212. package/lib/__tests__/yargsUtils.test.js +74 -0
  213. package/lib/app/__tests__/migrate.test.d.ts +1 -0
  214. package/lib/app/__tests__/migrate.test.js +495 -0
  215. package/lib/app/__tests__/migrate_legacy.test.d.ts +1 -0
  216. package/lib/app/__tests__/migrate_legacy.test.js +136 -0
  217. package/lib/buildAccount.d.ts +1 -7
  218. package/lib/buildAccount.js +4 -54
  219. package/lib/doctor/Diagnosis.js +11 -11
  220. package/lib/doctor/Doctor.js +42 -42
  221. package/lib/doctor/__tests__/Diagnosis.test.d.ts +1 -0
  222. package/lib/doctor/__tests__/Diagnosis.test.js +87 -0
  223. package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.d.ts +1 -0
  224. package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.js +172 -0
  225. package/lib/doctor/__tests__/Doctor.test.d.ts +1 -0
  226. package/lib/doctor/__tests__/Doctor.test.js +398 -0
  227. package/lib/mcp/setup.js +18 -2
  228. package/lib/middleware/__test__/configMiddleware.test.js +12 -12
  229. package/lib/middleware/__test__/gitMiddleware.test.js +4 -4
  230. package/lib/middleware/__test__/notificationsMiddleware.test.js +2 -2
  231. package/lib/middleware/__test__/requestMiddleware.test.js +2 -2
  232. package/lib/middleware/__test__/yargsChecksMiddleware.test.js +7 -7
  233. package/lib/middleware/notificationsMiddleware.js +16 -13
  234. package/lib/projects/__tests__/AppDevModeInterface.test.d.ts +1 -0
  235. package/lib/projects/__tests__/AppDevModeInterface.test.js +517 -0
  236. package/lib/projects/__tests__/LocalDevProcess.test.d.ts +1 -0
  237. package/lib/projects/__tests__/LocalDevProcess.test.js +314 -0
  238. package/lib/projects/__tests__/LocalDevWebsocketServer.test.d.ts +1 -0
  239. package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +175 -0
  240. package/lib/projects/__tests__/ProjectLogsManager.test.d.ts +1 -0
  241. package/lib/projects/__tests__/ProjectLogsManager.test.js +191 -0
  242. package/lib/projects/__tests__/buildAndDeploy.test.d.ts +1 -0
  243. package/lib/projects/__tests__/buildAndDeploy.test.js +25 -0
  244. package/lib/projects/__tests__/components.test.d.ts +1 -0
  245. package/lib/projects/__tests__/components.test.js +186 -0
  246. package/lib/projects/__tests__/projects.test.d.ts +1 -0
  247. package/lib/projects/__tests__/projects.test.js +89 -0
  248. package/lib/projects/__tests__/structure.test.d.ts +1 -0
  249. package/lib/projects/__tests__/structure.test.js +249 -0
  250. package/lib/projects/add/__tests__/legacyAddComponent.test.d.ts +1 -0
  251. package/lib/projects/add/__tests__/legacyAddComponent.test.js +206 -0
  252. package/lib/projects/add/__tests__/v3AddComponent.test.d.ts +1 -0
  253. package/lib/projects/add/__tests__/v3AddComponent.test.js +190 -0
  254. package/lib/projects/create/__tests__/legacy.test.d.ts +1 -0
  255. package/lib/projects/create/__tests__/legacy.test.js +126 -0
  256. package/lib/projects/create/__tests__/v3.test.d.ts +1 -0
  257. package/lib/projects/create/__tests__/v3.test.js +80 -0
  258. package/lib/projects/localDev/DevServerManager.js +0 -1
  259. package/lib/projects/localDev/helpers.d.ts +1 -1
  260. package/lib/projects/localDev/helpers.js +2 -2
  261. package/lib/projects/structure.d.ts +2 -2
  262. package/lib/projects/upload.d.ts +1 -2
  263. package/lib/projects/upload.js +0 -1
  264. package/lib/prompts/__tests__/downloadProjectPrompt.test.d.ts +1 -0
  265. package/lib/prompts/__tests__/downloadProjectPrompt.test.js +30 -0
  266. package/lib/prompts/__tests__/projectsLogsPrompt.test.d.ts +1 -0
  267. package/lib/prompts/__tests__/projectsLogsPrompt.test.js +42 -0
  268. package/lib/prompts/createDeveloperTestAccountConfigPrompt.d.ts +10 -9
  269. package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +43 -81
  270. package/lib/schema.js +5 -1
  271. package/lib/ui/SpinniesManager.js +0 -1
  272. package/lib/ui/supportHyperlinks.js +2 -2
  273. package/lib/ui/supportsColor.js +2 -2
  274. package/lib/utils/hasFlag.d.ts +1 -0
  275. package/lib/utils/hasFlag.js +15 -0
  276. package/lib/yargsUtils.d.ts +2 -1
  277. package/lib/yargsUtils.js +3 -13
  278. package/mcp-server/tools/project/__tests__/AddFeatureToProject.test.d.ts +1 -0
  279. package/mcp-server/tools/project/__tests__/AddFeatureToProject.test.js +152 -0
  280. package/mcp-server/tools/project/__tests__/CreateProjectTool.test.d.ts +1 -0
  281. package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +129 -0
  282. package/mcp-server/tools/project/__tests__/DeployProject.test.d.ts +1 -0
  283. package/mcp-server/tools/project/__tests__/DeployProject.test.js +120 -0
  284. package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.d.ts +1 -0
  285. package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +127 -0
  286. package/mcp-server/tools/project/__tests__/UploadProjectTools.test.d.ts +1 -0
  287. package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +108 -0
  288. package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.d.ts +1 -0
  289. package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +111 -0
  290. package/mcp-server/utils/__tests__/command.test.d.ts +1 -0
  291. package/mcp-server/utils/__tests__/command.test.js +47 -0
  292. package/mcp-server/utils/__tests__/project.test.d.ts +1 -0
  293. package/mcp-server/utils/__tests__/project.test.js +81 -0
  294. package/package.json +8 -8
  295. package/commands/app/install.d.ts +0 -8
  296. package/commands/app/install.js +0 -127
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const util_1 = __importDefault(require("util"));
7
+ const vitest_1 = require("vitest");
8
+ vitest_1.vi.mock('@hubspot/local-dev-lib/fs');
9
+ vitest_1.vi.mock('@hubspot/local-dev-lib/config');
10
+ vitest_1.vi.mock('@hubspot/local-dev-lib/personalAccessKey');
11
+ vitest_1.vi.mock('../../projects/config');
12
+ vitest_1.vi.mock('@hubspot/local-dev-lib/api/projects');
13
+ vitest_1.vi.mock('util');
14
+ vitest_1.vi.mock('../../../package.json', () => {
15
+ return {
16
+ default: {
17
+ version: '1.0.0',
18
+ },
19
+ };
20
+ });
21
+ const DiagnosticInfoBuilder_1 = require("../DiagnosticInfoBuilder");
22
+ const config_1 = require("@hubspot/local-dev-lib/config");
23
+ const personalAccessKey_1 = require("@hubspot/local-dev-lib/personalAccessKey");
24
+ const fs_1 = require("@hubspot/local-dev-lib/fs");
25
+ const config_2 = require("../../projects/config");
26
+ const projects_1 = require("@hubspot/local-dev-lib/api/projects");
27
+ const walk = fs_1.walk;
28
+ const getAccessToken = personalAccessKey_1.getAccessToken;
29
+ const getAccountConfig = config_1.getAccountConfig;
30
+ const getConfigPath = config_1.getConfigPath;
31
+ const getDefaultAccountOverrideFilePath = config_1.getDefaultAccountOverrideFilePath;
32
+ const getAccountId = config_1.getAccountId;
33
+ const getProjectConfig = config_2.getProjectConfig;
34
+ const isConfigFlagEnabled = config_1.isConfigFlagEnabled;
35
+ const fetchProject = projects_1.fetchProject;
36
+ const mockPromisifyImpl = vitest_1.vi.fn();
37
+ const utilPromisify = vitest_1.vi.fn(() => mockPromisifyImpl);
38
+ util_1.default.promisify = utilPromisify;
39
+ describe('lib/doctor/DiagnosticInfo', () => {
40
+ const accountId = 898989;
41
+ const accountConfig = {
42
+ env: 'prod',
43
+ authType: 'personalaccesskey',
44
+ accountType: 'STANDARD',
45
+ personalAccessKey: 'super-secret-key',
46
+ };
47
+ const nodeVersion = 'v18.17.0';
48
+ const processInfo = {
49
+ platform: 'darwin',
50
+ arch: 'x64',
51
+ versions: { node: nodeVersion },
52
+ mainModule: { path: '/path/to/main/module' },
53
+ };
54
+ const projectDir = '/Users/test/project';
55
+ const projectFiles = [
56
+ `${projectDir}/.gitignore`,
57
+ `${projectDir}/README.md`,
58
+ // Config files
59
+ `${projectDir}/hsproject.json`,
60
+ `${projectDir}/src/app/app.json`,
61
+ `${projectDir}/src/app/public-app.json`,
62
+ // Serverless files
63
+ `${projectDir}/src/app/app.functions/.env`,
64
+ `${projectDir}/src/app/app.functions/function.js`,
65
+ `${projectDir}/src/app/app.functions/serverless.json`,
66
+ `${projectDir}/src/app/app.functions/package.json`,
67
+ `${projectDir}/src/app/app.functions/package-lock.json`,
68
+ // Extension files
69
+ `${projectDir}/src/app/extensions/extension.js`,
70
+ `${projectDir}/src/app/extensions/extension.json`,
71
+ `${projectDir}/src/app/extensions/package.json`,
72
+ `${projectDir}/src/app/extension/package-lock.json`,
73
+ `${projectDir}/src/app/app.functions/node_modules/axios`,
74
+ ];
75
+ const npmVersion = 'v8.17.0';
76
+ const configPath = '/path/to/config';
77
+ const defaultAccountOverrideFile = 'path/to/default/account/override/.hsaccount';
78
+ beforeEach(() => {
79
+ getAccountId.mockReturnValue(accountId);
80
+ getAccountConfig.mockReturnValue(accountConfig);
81
+ walk.mockResolvedValue(projectFiles);
82
+ isConfigFlagEnabled.mockReturnValue(false);
83
+ mockPromisifyImpl.mockResolvedValue(npmVersion);
84
+ });
85
+ it('should initialize the required state on creation', () => {
86
+ const builder = new DiagnosticInfoBuilder_1.DiagnosticInfoBuilder(processInfo);
87
+ expect(getAccountId).toHaveBeenCalledTimes(1);
88
+ expect(getAccountConfig).toHaveBeenCalledTimes(1);
89
+ expect(builder.accountId).toEqual(accountId);
90
+ expect(builder.env).toEqual(accountConfig.env);
91
+ expect(builder.authType).toEqual(accountConfig.authType);
92
+ expect(builder.accountType).toEqual(accountConfig.accountType);
93
+ expect(builder.personalAccessKey).toEqual(accountConfig.personalAccessKey);
94
+ expect(builder.processInfo).toEqual(processInfo);
95
+ });
96
+ describe('generateDiagnosticInfo', () => {
97
+ let builder;
98
+ let projectConfig;
99
+ let projectDetails;
100
+ let accessToken;
101
+ beforeEach(() => {
102
+ builder = new DiagnosticInfoBuilder_1.DiagnosticInfoBuilder(processInfo);
103
+ projectConfig = {
104
+ projectDir,
105
+ projectConfig: {
106
+ name: 'My project',
107
+ srcDir: 'project-dir',
108
+ platformVersion: 'test',
109
+ },
110
+ };
111
+ projectDetails = {
112
+ createdAt: 12345,
113
+ deletedAt: 0,
114
+ deployedBuildId: 1,
115
+ id: 8989898,
116
+ isLocked: false,
117
+ name: projectConfig.projectConfig.name,
118
+ portalId: accountId,
119
+ updatedAt: 12345,
120
+ };
121
+ accessToken = {
122
+ accessToken: 'super-secret-dont-put-this-in-a-unit-test',
123
+ accountType: 'STANDARD',
124
+ encodedOAuthRefreshToken: '',
125
+ expiresAt: '',
126
+ hubName: projectConfig.projectConfig.name,
127
+ portalId: accountId,
128
+ scopeGroups: [],
129
+ enabledFeatures: {},
130
+ };
131
+ getProjectConfig.mockResolvedValue(projectConfig);
132
+ // @ts-expect-error - Mocking AxiosResponse
133
+ fetchProject.mockResolvedValue({
134
+ data: projectDetails,
135
+ });
136
+ getAccessToken.mockResolvedValue(accessToken);
137
+ getConfigPath.mockReturnValue(configPath);
138
+ getDefaultAccountOverrideFilePath.mockReturnValue(defaultAccountOverrideFile);
139
+ });
140
+ it('should gather the required data and generate the diagnostic', async () => {
141
+ const diagnosticInfo = await builder.generateDiagnosticInfo();
142
+ expect(getProjectConfig).toHaveBeenCalledTimes(1);
143
+ expect(fetchProject).toHaveBeenCalledTimes(1);
144
+ expect(fetchProject).toHaveBeenCalledWith(accountId, projectConfig.projectConfig.name);
145
+ expect(getAccessToken).toHaveBeenCalledTimes(1);
146
+ expect(getAccessToken).toHaveBeenCalledWith(accountConfig.personalAccessKey, accountConfig.env, accountId);
147
+ // @ts-expect-error Accessing private field
148
+ expect(builder._projectConfig).toEqual(projectConfig);
149
+ expect(diagnosticInfo).toMatchSnapshot();
150
+ });
151
+ it('should handle errors when fetching project details', async () => {
152
+ fetchProject.mockRejectedValue(new Error('Failed to fetch project details'));
153
+ const diagnosticInfo = await builder.generateDiagnosticInfo();
154
+ expect(fetchProject).toHaveBeenCalledTimes(1);
155
+ expect(diagnosticInfo.project.details).toBeUndefined();
156
+ });
157
+ it('should handle errors when fetching access token', async () => {
158
+ getAccessToken.mockRejectedValue(new Error('Failed to fetch access token'));
159
+ const diagnosticInfo = await builder.generateDiagnosticInfo();
160
+ expect(getAccessToken).toHaveBeenCalledTimes(1);
161
+ expect(diagnosticInfo.account.name).toBeUndefined();
162
+ expect(diagnosticInfo.account.scopeGroups).toBeUndefined();
163
+ expect(diagnosticInfo.account.enabledFeatures).toBeUndefined();
164
+ });
165
+ it('should handle errors when fetching project filenames', async () => {
166
+ walk.mockRejectedValue(new Error('Failed to walk project directory'));
167
+ const diagnosticInfo = await builder.generateDiagnosticInfo();
168
+ expect(walk).toHaveBeenCalledTimes(1);
169
+ expect(diagnosticInfo.files).toEqual([]);
170
+ });
171
+ });
172
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,398 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const Doctor_1 = require("../Doctor");
4
+ const dependencyManagement_1 = require("../../dependencyManagement");
5
+ const portManager_1 = require("@hubspot/local-dev-lib/portManager");
6
+ const personalAccessKey_1 = require("@hubspot/local-dev-lib/personalAccessKey");
7
+ const HubSpotHttpError_1 = require("@hubspot/local-dev-lib/models/HubSpotHttpError");
8
+ const axios_1 = require("axios");
9
+ const index_1 = require("@hubspot/local-dev-lib/errors/index");
10
+ const util_1 = require("util");
11
+ vi.mock('@hubspot/local-dev-lib/logger');
12
+ vi.mock('../Diagnosis');
13
+ vi.mock('../../ui/SpinniesManager');
14
+ vi.mock('../DiagnosticInfoBuilder');
15
+ vi.mock('../../dependencyManagement');
16
+ vi.mock('../../npm');
17
+ vi.mock('@hubspot/local-dev-lib/portManager');
18
+ vi.mock('@hubspot/local-dev-lib/personalAccessKey');
19
+ vi.mock('@hubspot/local-dev-lib/errors/index');
20
+ vi.mock('util');
21
+ const hasMissingPackages = vi.mocked(dependencyManagement_1.hasMissingPackages);
22
+ const isPortManagerPortAvailable = vi.mocked(portManager_1.isPortManagerPortAvailable);
23
+ const utilPromisify = vi.mocked(util_1.promisify);
24
+ const accessTokenForPersonalAccessKey = vi.mocked(personalAccessKey_1.accessTokenForPersonalAccessKey);
25
+ const authorizedScopesForPortalAndUser = vi.mocked(personalAccessKey_1.authorizedScopesForPortalAndUser);
26
+ const scopesOnAccessToken = vi.mocked(personalAccessKey_1.scopesOnAccessToken);
27
+ const isSpecifiedError = vi.mocked(index_1.isSpecifiedError);
28
+ describe('lib/doctor/Doctor', () => {
29
+ let doctor;
30
+ // @ts-ignore
31
+ const diagnosticInfo = {
32
+ account: {},
33
+ arch: 'x64',
34
+ config: 'path/to/config',
35
+ configSettings: { httpUseLocalhost: false },
36
+ configFiles: ['src/serverless.json'],
37
+ diagnosis: '',
38
+ envFiles: [],
39
+ files: [],
40
+ jsonFiles: ['src/serverless.json', 'src/extension.json'],
41
+ packageFiles: ['src/package.json'],
42
+ packageLockFiles: ['src/package-lock.json'],
43
+ path: '',
44
+ platform: 'darwin',
45
+ project: {
46
+ config: {
47
+ projectDir: '/path/to/project',
48
+ projectConfig: {
49
+ name: 'my-project',
50
+ srcDir: '/path/to/project',
51
+ platformVersion: 'test',
52
+ },
53
+ },
54
+ },
55
+ versions: {
56
+ node: '18.1.2',
57
+ '@hubspot/cli': '6.0.0',
58
+ npm: '6.14.13',
59
+ },
60
+ };
61
+ beforeEach(() => {
62
+ doctor = new Doctor_1.Doctor({
63
+ generateDiagnosticInfo: vi.fn().mockResolvedValue({
64
+ ...diagnosticInfo,
65
+ }),
66
+ });
67
+ utilPromisify.mockReturnValue(vi.fn().mockImplementation((filename) => {
68
+ if (filename.includes('invalid')) {
69
+ return 'not-valid-json';
70
+ }
71
+ return JSON.stringify({ valid: true });
72
+ }));
73
+ });
74
+ afterEach(() => {
75
+ vi.clearAllMocks();
76
+ });
77
+ describe('CLI Checks', () => {
78
+ describe('node version', () => {
79
+ it('should add success section if node version is valid', async () => {
80
+ await doctor.diagnose();
81
+ // @ts-expect-error Testing private method
82
+ expect(doctor.diagnosis.addCliSection).toHaveBeenCalledWith({
83
+ type: 'success',
84
+ message: `node v${diagnosticInfo.versions.node} is installed`,
85
+ });
86
+ });
87
+ it('should add error section if node version is not available', async () => {
88
+ doctor = new Doctor_1.Doctor({
89
+ generateDiagnosticInfo: vi.fn().mockResolvedValue({
90
+ ...diagnosticInfo,
91
+ versions: {},
92
+ }),
93
+ });
94
+ await doctor.diagnose();
95
+ // @ts-expect-error Testing private method
96
+ expect(doctor.diagnosis.addCliSection).toHaveBeenCalledWith({
97
+ type: 'error',
98
+ message: 'Unable to determine what version of node is installed',
99
+ });
100
+ });
101
+ it('should add error section if minimum node version is not met', async () => {
102
+ doctor = new Doctor_1.Doctor({
103
+ generateDiagnosticInfo: vi.fn().mockResolvedValue({
104
+ ...diagnosticInfo,
105
+ versions: { node: '1.0.0' },
106
+ }),
107
+ });
108
+ await doctor.diagnose();
109
+ // @ts-expect-error Testing private method
110
+ expect(doctor.diagnosis.addCliSection).toHaveBeenCalledWith({
111
+ type: 'warning',
112
+ message: expect.stringMatching(/Minimum Node version is not met/),
113
+ });
114
+ });
115
+ });
116
+ describe('npm version', () => {
117
+ it('should add success section if npm is installed', async () => {
118
+ await doctor.diagnose();
119
+ // @ts-expect-error Testing private method
120
+ expect(doctor.diagnosis.addCliSection).toHaveBeenCalledWith({
121
+ type: 'success',
122
+ message: `npm v${diagnosticInfo.versions.npm} is installed`,
123
+ });
124
+ });
125
+ it('should add error section if npm is not installed', async () => {
126
+ doctor = new Doctor_1.Doctor({
127
+ generateDiagnosticInfo: vi.fn().mockResolvedValue({
128
+ ...diagnosticInfo,
129
+ versions: {},
130
+ }),
131
+ });
132
+ await doctor.diagnose();
133
+ // @ts-expect-error Testing private method
134
+ expect(doctor.diagnosis.addCliSection).toHaveBeenCalledWith({
135
+ type: 'error',
136
+ message: expect.any(String),
137
+ });
138
+ });
139
+ });
140
+ });
141
+ describe('CLI Config Checks', () => {
142
+ describe('Personal Access Key', () => {
143
+ it('should add success sections if the access token is valid', async () => {
144
+ scopesOnAccessToken.mockResolvedValueOnce(['scope1']);
145
+ authorizedScopesForPortalAndUser.mockResolvedValueOnce([
146
+ {
147
+ scopeGroup: {
148
+ name: 'scope1',
149
+ shortDescription: 'scope1',
150
+ longDescription: 'scope1',
151
+ },
152
+ portalAuthorized: true,
153
+ userAuthorized: true,
154
+ },
155
+ ]);
156
+ await doctor.diagnose();
157
+ // @ts-expect-error Testing private method
158
+ expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
159
+ type: 'success',
160
+ message: 'Default account active',
161
+ });
162
+ // @ts-expect-error Testing private method
163
+ expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
164
+ type: 'success',
165
+ message: expect.stringMatching(/Personal Access Key is valid./),
166
+ });
167
+ });
168
+ it('should add an error section if it is unable to determine if the portal is active', async () => {
169
+ accessTokenForPersonalAccessKey.mockRejectedValueOnce(new HubSpotHttpError_1.HubSpotHttpError('Invalid token', { cause: new axios_1.AxiosError() }));
170
+ await doctor.diagnose();
171
+ // @ts-expect-error Testing private method
172
+ expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
173
+ type: 'error',
174
+ message: 'Unable to determine if the portal is active',
175
+ });
176
+ });
177
+ it('should add an error section if the portal is inactive', async () => {
178
+ accessTokenForPersonalAccessKey.mockRejectedValueOnce(new HubSpotHttpError_1.HubSpotHttpError('Invalid token'));
179
+ isSpecifiedError.mockImplementation((err, fields) => {
180
+ return (fields.statusCode === 401 &&
181
+ fields.category === 'INVALID_AUTHENTICATION' &&
182
+ fields?.subCategory === 'LocalDevAuthErrorType.PORTAL_NOT_ACTIVE');
183
+ });
184
+ await doctor.diagnose();
185
+ // @ts-expect-error Testing private method
186
+ expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
187
+ type: 'error',
188
+ message: "Default account isn't active",
189
+ secondaryMessaging: expect.stringMatching(/to remove inactive accounts from your CLI config/),
190
+ });
191
+ });
192
+ it('should add an error section if the portal is not found', async () => {
193
+ accessTokenForPersonalAccessKey.mockRejectedValueOnce(new HubSpotHttpError_1.HubSpotHttpError('Not found'));
194
+ isSpecifiedError.mockImplementation((err, fields) => {
195
+ return (fields.statusCode === 404 &&
196
+ fields.category === 'INVALID_AUTHENTICATION' &&
197
+ fields?.subCategory === 'LocalDevAuthErrorType.INVALID_PORTAL_ID');
198
+ });
199
+ await doctor.diagnose();
200
+ // @ts-expect-error Testing private method
201
+ expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
202
+ type: 'error',
203
+ message: "Default account isn't active",
204
+ secondaryMessaging: expect.stringMatching(/to remove inactive accounts from your CLI config/),
205
+ });
206
+ });
207
+ it('should add multiple sections if token is invalid but the portal is active', async () => {
208
+ accessTokenForPersonalAccessKey.mockRejectedValueOnce(new HubSpotHttpError_1.HubSpotHttpError('Not found'));
209
+ isSpecifiedError.mockImplementation((err, fields) => {
210
+ return (fields.statusCode === 401 &&
211
+ fields.category === 'INVALID_AUTHENTICATION' &&
212
+ fields?.subCategory ===
213
+ 'LocalDevAuthErrorType.FAILED_TO_SIGN_REFRESH_TOKEN_DECODE');
214
+ });
215
+ await doctor.diagnose();
216
+ // @ts-expect-error Testing private method
217
+ expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
218
+ type: 'success',
219
+ message: 'Default account active',
220
+ });
221
+ // @ts-expect-error Testing private method
222
+ expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
223
+ type: 'error',
224
+ message: 'Personal access key is invalid',
225
+ secondaryMessaging: expect.stringMatching(/To get a new key, run/),
226
+ });
227
+ });
228
+ it('should add an error section if we are unable to determine if the portal is active', async () => {
229
+ accessTokenForPersonalAccessKey.mockRejectedValueOnce(new HubSpotHttpError_1.HubSpotHttpError('Not found'));
230
+ isSpecifiedError.mockReturnValue(false);
231
+ await doctor.diagnose();
232
+ // @ts-expect-error Testing private method
233
+ expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
234
+ type: 'error',
235
+ message: 'Unable to determine if the portal is active',
236
+ });
237
+ });
238
+ it('should warn when there are missing authorized scopes', async () => {
239
+ scopesOnAccessToken.mockResolvedValueOnce(['scope1', 'scope2']);
240
+ authorizedScopesForPortalAndUser.mockResolvedValueOnce([
241
+ {
242
+ scopeGroup: {
243
+ name: 'scope1',
244
+ shortDescription: 'scope1',
245
+ longDescription: 'scope1',
246
+ },
247
+ portalAuthorized: true,
248
+ userAuthorized: true,
249
+ },
250
+ {
251
+ scopeGroup: {
252
+ name: 'scope2',
253
+ shortDescription: 'scope2',
254
+ longDescription: 'scope2',
255
+ },
256
+ portalAuthorized: true,
257
+ userAuthorized: true,
258
+ },
259
+ {
260
+ scopeGroup: {
261
+ name: 'scope3',
262
+ shortDescription: 'scope3',
263
+ longDescription: 'scope3',
264
+ },
265
+ portalAuthorized: true,
266
+ userAuthorized: true,
267
+ },
268
+ ]);
269
+ await doctor.diagnose();
270
+ expect(doctor['diagnosis']?.addCLIConfigSection).toHaveBeenCalledWith({
271
+ type: 'warning',
272
+ message: 'Personal access key is valid, but there are more scopes available to your user that are not included in your key.',
273
+ secondaryMessaging: expect.any(String),
274
+ });
275
+ });
276
+ it('should not warn when the missing scope is not authorized', async () => {
277
+ scopesOnAccessToken.mockResolvedValueOnce(['scope1']);
278
+ authorizedScopesForPortalAndUser.mockResolvedValueOnce([
279
+ {
280
+ scopeGroup: {
281
+ name: 'scope1',
282
+ shortDescription: 'scope1',
283
+ longDescription: 'scope1',
284
+ },
285
+ portalAuthorized: true,
286
+ userAuthorized: true,
287
+ },
288
+ {
289
+ scopeGroup: {
290
+ name: 'scope2',
291
+ shortDescription: 'scope2',
292
+ longDescription: 'scope2',
293
+ },
294
+ portalAuthorized: true,
295
+ userAuthorized: false,
296
+ },
297
+ ]);
298
+ await doctor.diagnose();
299
+ expect(doctor['diagnosis']?.addCLIConfigSection).toHaveBeenCalledWith({
300
+ type: 'success',
301
+ message: expect.stringMatching(/Personal Access Key is valid./),
302
+ });
303
+ });
304
+ });
305
+ });
306
+ describe('Project Checks', () => {
307
+ describe('Dependencies', () => {
308
+ it('should add warning section if dependencies are missing', async () => {
309
+ hasMissingPackages.mockResolvedValue(true);
310
+ await doctor.diagnose();
311
+ // @ts-expect-error Testing private method
312
+ expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
313
+ type: 'warning',
314
+ message: expect.stringMatching(/missing dependencies in/),
315
+ secondaryMessaging: expect.stringMatching(/to install all project dependencies locally/),
316
+ });
317
+ });
318
+ it('should add success section if no dependencies are missing', async () => {
319
+ hasMissingPackages.mockResolvedValue(false);
320
+ await doctor.diagnose();
321
+ // @ts-expect-error Testing private method
322
+ expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
323
+ type: 'success',
324
+ message: 'App dependencies are installed and up to date',
325
+ });
326
+ });
327
+ it('should add error section if the package.json file is invalid JSON', async () => {
328
+ hasMissingPackages.mockImplementationOnce(() => {
329
+ throw new Error('Uh oh');
330
+ });
331
+ utilPromisify.mockReturnValueOnce(vi.fn().mockImplementation((filename) => {
332
+ if (filename.endsWith('package.json')) {
333
+ return 'not-valid-json';
334
+ }
335
+ return JSON.stringify({ valid: true });
336
+ }));
337
+ await doctor.diagnose();
338
+ // @ts-expect-error Testing private method
339
+ expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
340
+ type: 'error',
341
+ message: expect.stringMatching(/invalid JSON in/),
342
+ });
343
+ });
344
+ it('should add error section if it is unable to determine if dependencies need installed', async () => {
345
+ hasMissingPackages.mockImplementationOnce(() => {
346
+ throw new Error('Uh oh');
347
+ });
348
+ await doctor.diagnose();
349
+ // @ts-expect-error Testing private method
350
+ expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
351
+ type: 'error',
352
+ message: expect.stringMatching(/Unable to determine if dependencies are installed/),
353
+ });
354
+ });
355
+ });
356
+ describe('Port', () => {
357
+ it('should add warning section if port is in use', async () => {
358
+ isPortManagerPortAvailable.mockResolvedValue(false);
359
+ await doctor.diagnose();
360
+ // @ts-expect-error Testing private method
361
+ expect(doctor.diagnosis?.addProjectSection).toHaveBeenCalledWith({
362
+ type: 'warning',
363
+ message: 'Port 8080 is in use',
364
+ secondaryMessaging: expect.stringMatching(/Make sure it is available if before running/),
365
+ });
366
+ });
367
+ it('should add success section if port is available', async () => {
368
+ isPortManagerPortAvailable.mockResolvedValue(true);
369
+ await doctor.diagnose();
370
+ // @ts-expect-error Testing private method
371
+ expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
372
+ type: 'success',
373
+ message: 'Port 8080 available for local development',
374
+ });
375
+ });
376
+ });
377
+ describe('JSON Files', () => {
378
+ it('should add success section if project json files are valid', async () => {
379
+ utilPromisify.mockReturnValueOnce(vi.fn().mockResolvedValue(JSON.stringify({ valid: true })));
380
+ await doctor.diagnose();
381
+ // @ts-expect-error Testing private method
382
+ expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
383
+ type: 'success',
384
+ message: 'JSON files valid',
385
+ });
386
+ });
387
+ it('should add error section if project json files are invalid', async () => {
388
+ utilPromisify.mockReturnValueOnce(vi.fn().mockResolvedValue('not-valid-json'));
389
+ await doctor.diagnose();
390
+ // @ts-expect-error Testing private method
391
+ expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
392
+ type: 'error',
393
+ message: expect.stringMatching(/invalid JSON in/),
394
+ });
395
+ });
396
+ });
397
+ });
398
+ });
package/lib/mcp/setup.js CHANGED
@@ -112,9 +112,9 @@ function setupMcpConfigFile(config) {
112
112
  fs_extra_1.default.writeFileSync(config.configPath, JSON.stringify({}, null, 2));
113
113
  }
114
114
  let mcpConfig = {};
115
+ let configContent;
115
116
  try {
116
- const configContent = fs_extra_1.default.readFileSync(config.configPath, 'utf8');
117
- mcpConfig = JSON.parse(configContent);
117
+ configContent = fs_extra_1.default.readFileSync(config.configPath, 'utf8');
118
118
  }
119
119
  catch (error) {
120
120
  SpinniesManager_1.default.fail('spinner', {
@@ -123,6 +123,22 @@ function setupMcpConfigFile(config) {
123
123
  (0, errorHandlers_1.logError)(error);
124
124
  return false;
125
125
  }
126
+ try {
127
+ // In the event the file exists, but is empty, initialize it to and empty object
128
+ if (configContent.trim() === '') {
129
+ mcpConfig = {};
130
+ }
131
+ else {
132
+ mcpConfig = JSON.parse(configContent);
133
+ }
134
+ }
135
+ catch (error) {
136
+ SpinniesManager_1.default.fail('spinner', {
137
+ text: config.failedMessage,
138
+ });
139
+ logger_1.uiLogger.error(en_1.commands.mcp.setup.errors.errorParsingJsonFIle(config.configPath, error instanceof Error ? error.message : `${error}`));
140
+ return false;
141
+ }
126
142
  // Initialize mcpServers if it doesn't exist
127
143
  if (!mcpConfig.mcpServers) {
128
144
  mcpConfig.mcpServers = {};
@@ -38,21 +38,21 @@ const cliConfig = __importStar(require("@hubspot/local-dev-lib/config"));
38
38
  const validation = __importStar(require("../../validation"));
39
39
  const exitCodes_1 = require("../../enums/exitCodes");
40
40
  const configMiddleware_1 = require("../configMiddleware");
41
- jest.mock('@hubspot/local-dev-lib/logger', () => ({
41
+ vi.mock('@hubspot/local-dev-lib/logger', () => ({
42
42
  logger: {
43
- error: jest.fn(),
44
- log: jest.fn(),
43
+ error: vi.fn(),
44
+ log: vi.fn(),
45
45
  },
46
46
  }));
47
- jest.mock('@hubspot/local-dev-lib/config');
48
- jest.mock('../../validation');
49
- const validateAccountSpy = jest.spyOn(validation, 'validateAccount');
50
- const loadConfigSpy = jest.spyOn(cliConfig, 'loadConfig');
51
- const getAccountIdSpy = jest.spyOn(cliConfig, 'getAccountId');
52
- const configFileExistsSpy = jest.spyOn(cliConfig, 'configFileExists');
53
- const getConfigPathSpy = jest.spyOn(cliConfig, 'getConfigPath');
54
- const validateConfigSpy = jest.spyOn(cliConfig, 'validateConfig');
55
- const processExitSpy = jest.spyOn(process, 'exit');
47
+ vi.mock('@hubspot/local-dev-lib/config');
48
+ vi.mock('../../validation');
49
+ const validateAccountSpy = vi.spyOn(validation, 'validateAccount');
50
+ const loadConfigSpy = vi.spyOn(cliConfig, 'loadConfig');
51
+ const getAccountIdSpy = vi.spyOn(cliConfig, 'getAccountId');
52
+ const configFileExistsSpy = vi.spyOn(cliConfig, 'configFileExists');
53
+ const getConfigPathSpy = vi.spyOn(cliConfig, 'getConfigPath');
54
+ const validateConfigSpy = vi.spyOn(cliConfig, 'validateConfig');
55
+ const processExitSpy = vi.spyOn(process, 'exit');
56
56
  describe('lib/middleware/configMiddleware', () => {
57
57
  beforeEach(() => {
58
58
  processExitSpy.mockImplementation(code => {
@@ -36,10 +36,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const config = __importStar(require("@hubspot/local-dev-lib/config"));
37
37
  const gitUI = __importStar(require("../../ui/git"));
38
38
  const gitMiddleware_1 = require("../gitMiddleware");
39
- jest.mock('@hubspot/local-dev-lib/config');
40
- jest.mock('../../ui/git');
41
- const getConfigPathSpy = jest.spyOn(config, 'getConfigPath');
42
- const checkAndWarnGitInclusionSpy = jest.spyOn(gitUI, 'checkAndWarnGitInclusion');
39
+ vi.mock('@hubspot/local-dev-lib/config');
40
+ vi.mock('../../ui/git');
41
+ const getConfigPathSpy = vi.spyOn(config, 'getConfigPath');
42
+ const checkAndWarnGitInclusionSpy = vi.spyOn(gitUI, 'checkAndWarnGitInclusion');
43
43
  describe('lib/middleware/gitMiddleware', () => {
44
44
  describe('checkAndWarnGitInclusionMiddleware()', () => {
45
45
  it('should call checkAndWarnGitInclusion when command is provided and config path exists', () => {