@hubspot/cli 7.6.0-beta.3 → 7.6.0-beta.5

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 (330) hide show
  1. package/api/__tests__/migrate.test.d.ts +1 -0
  2. package/api/__tests__/migrate.test.js +183 -0
  3. package/bin/cli.js +6 -2
  4. package/commands/__tests__/account.test.d.ts +1 -0
  5. package/commands/__tests__/account.test.js +74 -0
  6. package/commands/__tests__/auth.test.d.ts +1 -0
  7. package/commands/__tests__/auth.test.js +43 -0
  8. package/commands/__tests__/cms.test.d.ts +1 -0
  9. package/commands/__tests__/cms.test.js +49 -0
  10. package/commands/__tests__/config.test.d.ts +1 -0
  11. package/commands/__tests__/config.test.js +49 -0
  12. package/commands/__tests__/create.test.d.ts +1 -0
  13. package/commands/__tests__/create.test.js +38 -0
  14. package/commands/__tests__/customObject.test.d.ts +1 -0
  15. package/commands/__tests__/customObject.test.js +54 -0
  16. package/commands/__tests__/doctor.test.d.ts +1 -0
  17. package/commands/__tests__/doctor.test.js +139 -0
  18. package/commands/__tests__/feedback.test.d.ts +1 -0
  19. package/commands/__tests__/feedback.test.js +62 -0
  20. package/commands/__tests__/fetch.test.d.ts +1 -0
  21. package/commands/__tests__/fetch.test.js +56 -0
  22. package/commands/__tests__/filemanager.test.d.ts +1 -0
  23. package/commands/__tests__/filemanager.test.js +50 -0
  24. package/commands/__tests__/function.test.d.ts +1 -0
  25. package/commands/__tests__/function.test.js +51 -0
  26. package/commands/__tests__/getStarted.test.d.ts +1 -0
  27. package/commands/__tests__/getStarted.test.js +160 -0
  28. package/commands/__tests__/hubdb.test.d.ts +1 -0
  29. package/commands/__tests__/hubdb.test.js +55 -0
  30. package/commands/__tests__/init.test.d.ts +1 -0
  31. package/commands/__tests__/init.test.js +47 -0
  32. package/commands/__tests__/lint.test.d.ts +1 -0
  33. package/commands/__tests__/lint.test.js +38 -0
  34. package/commands/__tests__/list.test.d.ts +1 -0
  35. package/commands/__tests__/list.test.js +47 -0
  36. package/commands/__tests__/logs.test.d.ts +1 -0
  37. package/commands/__tests__/logs.test.js +70 -0
  38. package/commands/__tests__/mcp.test.d.ts +1 -0
  39. package/commands/__tests__/mcp.test.js +51 -0
  40. package/commands/__tests__/mv.test.d.ts +1 -0
  41. package/commands/__tests__/mv.test.js +84 -0
  42. package/commands/__tests__/open.test.d.ts +1 -0
  43. package/commands/__tests__/open.test.js +96 -0
  44. package/commands/__tests__/project.test.d.ts +1 -0
  45. package/commands/__tests__/project.test.js +100 -0
  46. package/commands/__tests__/remove.test.d.ts +1 -0
  47. package/commands/__tests__/remove.test.js +77 -0
  48. package/commands/__tests__/sandbox.test.d.ts +1 -0
  49. package/commands/__tests__/sandbox.test.js +49 -0
  50. package/commands/__tests__/secret.test.d.ts +1 -0
  51. package/commands/__tests__/secret.test.js +54 -0
  52. package/commands/__tests__/testAccount.test.d.ts +1 -0
  53. package/commands/__tests__/testAccount.test.js +60 -0
  54. package/commands/__tests__/theme.test.d.ts +1 -0
  55. package/commands/__tests__/theme.test.js +52 -0
  56. package/commands/account/__tests__/auth.test.d.ts +1 -0
  57. package/commands/account/__tests__/auth.test.js +31 -0
  58. package/commands/account/__tests__/clean.test.d.ts +1 -0
  59. package/commands/account/__tests__/clean.test.js +33 -0
  60. package/commands/account/__tests__/createOverride.test.d.ts +1 -0
  61. package/commands/account/__tests__/createOverride.test.js +37 -0
  62. package/commands/account/__tests__/info.test.d.ts +1 -0
  63. package/commands/account/__tests__/info.test.js +33 -0
  64. package/commands/account/__tests__/list.test.d.ts +1 -0
  65. package/commands/account/__tests__/list.test.js +33 -0
  66. package/commands/account/__tests__/remove.test.d.ts +1 -0
  67. package/commands/account/__tests__/remove.test.js +41 -0
  68. package/commands/account/__tests__/removeOverride.d.ts +1 -0
  69. package/commands/account/__tests__/removeOverride.js +30 -0
  70. package/commands/account/__tests__/rename.test.d.ts +1 -0
  71. package/commands/account/__tests__/rename.test.js +47 -0
  72. package/commands/account/__tests__/use.test.d.ts +1 -0
  73. package/commands/account/__tests__/use.test.js +37 -0
  74. package/commands/app/__tests__/migrate.test.d.ts +1 -0
  75. package/commands/app/__tests__/migrate.test.js +129 -0
  76. package/commands/app/secret/__tests__/add.test.d.ts +1 -0
  77. package/commands/app/secret/__tests__/add.test.js +33 -0
  78. package/commands/app/secret/__tests__/delete.test.d.ts +1 -0
  79. package/commands/app/secret/__tests__/delete.test.js +33 -0
  80. package/commands/app/secret/__tests__/list.test.d.ts +1 -0
  81. package/commands/app/secret/__tests__/list.test.js +30 -0
  82. package/commands/app/secret/__tests__/update.test.d.ts +1 -0
  83. package/commands/app/secret/__tests__/update.test.js +33 -0
  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/getStarted.js +13 -34
  106. package/commands/hubdb/__tests__/clear.test.d.ts +1 -0
  107. package/commands/hubdb/__tests__/clear.test.js +33 -0
  108. package/commands/hubdb/__tests__/create.test.d.ts +1 -0
  109. package/commands/hubdb/__tests__/create.test.js +33 -0
  110. package/commands/hubdb/__tests__/delete.test.d.ts +1 -0
  111. package/commands/hubdb/__tests__/delete.test.js +33 -0
  112. package/commands/hubdb/__tests__/fetch.test.d.ts +1 -0
  113. package/commands/hubdb/__tests__/fetch.test.js +33 -0
  114. package/commands/hubdb/__tests__/list.test.d.ts +1 -0
  115. package/commands/hubdb/__tests__/list.test.js +101 -0
  116. package/commands/logs.js +0 -1
  117. package/commands/mcp/__tests__/setup.test.d.ts +1 -0
  118. package/commands/mcp/__tests__/setup.test.js +31 -0
  119. package/commands/mcp/__tests__/start.test.d.ts +1 -0
  120. package/commands/mcp/__tests__/start.test.js +32 -0
  121. package/commands/mcp/setup.js +1 -0
  122. package/commands/mcp/start.d.ts +4 -1
  123. package/commands/mcp/start.js +8 -3
  124. package/commands/open.js +14 -12
  125. package/commands/project/__tests__/add.test.d.ts +1 -0
  126. package/commands/project/__tests__/add.test.js +48 -0
  127. package/commands/project/__tests__/create.test.d.ts +1 -0
  128. package/commands/project/__tests__/create.test.js +45 -0
  129. package/commands/project/__tests__/deploy.test.d.ts +1 -0
  130. package/commands/project/__tests__/deploy.test.js +346 -0
  131. package/commands/project/__tests__/devUnifiedFlow.test.d.ts +1 -0
  132. package/commands/project/__tests__/devUnifiedFlow.test.js +423 -0
  133. package/commands/project/__tests__/download.test.d.ts +1 -0
  134. package/commands/project/__tests__/download.test.js +44 -0
  135. package/commands/project/__tests__/fixtures/exampleProject.json +33 -0
  136. package/commands/project/__tests__/installDeps.test.d.ts +1 -0
  137. package/commands/project/__tests__/installDeps.test.js +180 -0
  138. package/commands/project/__tests__/listBuilds.test.d.ts +1 -0
  139. package/commands/project/__tests__/listBuilds.test.js +43 -0
  140. package/commands/project/__tests__/logs.test.d.ts +1 -0
  141. package/commands/project/__tests__/logs.test.js +246 -0
  142. package/commands/project/__tests__/migrate.test.d.ts +1 -0
  143. package/commands/project/__tests__/migrate.test.js +116 -0
  144. package/commands/project/__tests__/migrateApp.test.d.ts +1 -0
  145. package/commands/project/__tests__/migrateApp.test.js +87 -0
  146. package/commands/project/__tests__/open.test.d.ts +1 -0
  147. package/commands/project/__tests__/open.test.js +44 -0
  148. package/commands/project/__tests__/profile.test.d.ts +1 -0
  149. package/commands/project/__tests__/profile.test.js +47 -0
  150. package/commands/project/__tests__/upload.test.d.ts +1 -0
  151. package/commands/project/__tests__/upload.test.js +48 -0
  152. package/commands/project/__tests__/watch.test.d.ts +1 -0
  153. package/commands/project/__tests__/watch.test.js +40 -0
  154. package/commands/project/deploy.d.ts +3 -2
  155. package/commands/project/deploy.js +61 -55
  156. package/commands/project/dev/unifiedFlow.js +7 -6
  157. package/commands/sandbox/__tests__/create.test.d.ts +1 -0
  158. package/commands/sandbox/__tests__/create.test.js +36 -0
  159. package/commands/sandbox/__tests__/delete.test.d.ts +1 -0
  160. package/commands/sandbox/__tests__/delete.test.js +36 -0
  161. package/commands/secret/__tests__/addSecret.test.d.ts +1 -0
  162. package/commands/secret/__tests__/addSecret.test.js +34 -0
  163. package/commands/secret/__tests__/deleteSecret.test.d.ts +1 -0
  164. package/commands/secret/__tests__/deleteSecret.test.js +46 -0
  165. package/commands/secret/__tests__/listSecret.test.d.ts +1 -0
  166. package/commands/secret/__tests__/listSecret.test.js +34 -0
  167. package/commands/secret/__tests__/updateSecret.test.d.ts +1 -0
  168. package/commands/secret/__tests__/updateSecret.test.js +34 -0
  169. package/commands/testAccount/__tests__/create.test.d.ts +1 -0
  170. package/commands/testAccount/__tests__/create.test.js +38 -0
  171. package/commands/testAccount/__tests__/createConfig.test.d.ts +1 -0
  172. package/commands/testAccount/__tests__/createConfig.test.js +37 -0
  173. package/commands/testAccount/__tests__/delete.test.d.ts +1 -0
  174. package/commands/testAccount/__tests__/delete.test.js +36 -0
  175. package/commands/testAccount/create.js +11 -24
  176. package/commands/testAccount/createConfig.d.ts +0 -2
  177. package/commands/testAccount/createConfig.js +7 -8
  178. package/commands/theme/__tests__/generate-selectors.test.d.ts +1 -0
  179. package/commands/theme/__tests__/generate-selectors.test.js +33 -0
  180. package/commands/theme/__tests__/marketplace-validate.test.d.ts +1 -0
  181. package/commands/theme/__tests__/marketplace-validate.test.js +41 -0
  182. package/commands/theme/__tests__/preview.test.d.ts +1 -0
  183. package/commands/theme/__tests__/preview.test.js +65 -0
  184. package/lang/en.d.ts +36 -19
  185. package/lang/en.js +36 -19
  186. package/lang/en.lyaml +0 -26
  187. package/lib/__tests__/accountTypes.test.d.ts +1 -0
  188. package/lib/__tests__/accountTypes.test.js +100 -0
  189. package/lib/__tests__/buildAccount.test.d.ts +1 -0
  190. package/lib/__tests__/buildAccount.test.js +259 -0
  191. package/lib/__tests__/commonOpts.test.d.ts +1 -0
  192. package/lib/__tests__/commonOpts.test.js +87 -0
  193. package/lib/__tests__/dependencyManagement.test.d.ts +1 -0
  194. package/lib/__tests__/dependencyManagement.test.js +180 -0
  195. package/lib/__tests__/developerTestAccounts.test.d.ts +1 -0
  196. package/lib/__tests__/developerTestAccounts.test.js +180 -0
  197. package/lib/__tests__/hasFeature.test.d.ts +1 -0
  198. package/lib/__tests__/hasFeature.test.js +37 -0
  199. package/lib/__tests__/npm.test.d.ts +1 -0
  200. package/lib/__tests__/npm.test.js +62 -0
  201. package/lib/__tests__/oauth.test.d.ts +1 -0
  202. package/lib/__tests__/oauth.test.js +113 -0
  203. package/lib/__tests__/parsing.test.d.ts +1 -0
  204. package/lib/__tests__/parsing.test.js +36 -0
  205. package/lib/__tests__/polling.test.d.ts +1 -0
  206. package/lib/__tests__/polling.test.js +78 -0
  207. package/lib/__tests__/process.test.d.ts +1 -0
  208. package/lib/__tests__/process.test.js +90 -0
  209. package/lib/__tests__/projectProfiles.test.d.ts +1 -0
  210. package/lib/__tests__/projectProfiles.test.js +134 -0
  211. package/lib/__tests__/sandboxSync.test.d.ts +1 -0
  212. package/lib/__tests__/sandboxSync.test.js +131 -0
  213. package/lib/__tests__/sandboxes.test.d.ts +1 -0
  214. package/lib/__tests__/sandboxes.test.js +148 -0
  215. package/lib/__tests__/serverlessLogs.test.d.ts +1 -0
  216. package/lib/__tests__/serverlessLogs.test.js +154 -0
  217. package/lib/__tests__/usageTracking.test.d.ts +1 -0
  218. package/lib/__tests__/usageTracking.test.js +165 -0
  219. package/lib/__tests__/validation.test.d.ts +1 -0
  220. package/lib/__tests__/validation.test.js +145 -0
  221. package/lib/__tests__/yargsUtils.test.d.ts +1 -0
  222. package/lib/__tests__/yargsUtils.test.js +74 -0
  223. package/lib/app/__tests__/migrate.test.d.ts +1 -0
  224. package/lib/app/__tests__/migrate.test.js +495 -0
  225. package/lib/app/__tests__/migrate_legacy.test.d.ts +1 -0
  226. package/lib/app/__tests__/migrate_legacy.test.js +136 -0
  227. package/lib/app/migrate.js +2 -6
  228. package/lib/buildAccount.d.ts +7 -1
  229. package/lib/buildAccount.js +54 -4
  230. package/lib/dependencyManagement.d.ts +1 -1
  231. package/lib/dependencyManagement.js +2 -2
  232. package/lib/doctor/Diagnosis.js +11 -11
  233. package/lib/doctor/Doctor.js +42 -42
  234. package/lib/doctor/__tests__/Diagnosis.test.d.ts +1 -0
  235. package/lib/doctor/__tests__/Diagnosis.test.js +87 -0
  236. package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.d.ts +1 -0
  237. package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.js +172 -0
  238. package/lib/doctor/__tests__/Doctor.test.d.ts +1 -0
  239. package/lib/doctor/__tests__/Doctor.test.js +398 -0
  240. package/lib/mcp/setup.js +26 -5
  241. package/lib/middleware/__test__/configMiddleware.test.js +12 -12
  242. package/lib/middleware/__test__/gitMiddleware.test.js +4 -4
  243. package/lib/middleware/__test__/notificationsMiddleware.test.js +2 -2
  244. package/lib/middleware/__test__/requestMiddleware.test.js +2 -2
  245. package/lib/middleware/__test__/yargsChecksMiddleware.test.js +7 -7
  246. package/lib/middleware/notificationsMiddleware.js +16 -13
  247. package/lib/projects/__tests__/AppDevModeInterface.test.d.ts +1 -0
  248. package/lib/projects/__tests__/AppDevModeInterface.test.js +517 -0
  249. package/lib/projects/__tests__/LocalDevProcess.test.d.ts +1 -0
  250. package/lib/projects/__tests__/LocalDevProcess.test.js +314 -0
  251. package/lib/projects/__tests__/LocalDevWebsocketServer.test.d.ts +1 -0
  252. package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +175 -0
  253. package/lib/projects/__tests__/ProjectLogsManager.test.d.ts +1 -0
  254. package/lib/projects/__tests__/ProjectLogsManager.test.js +191 -0
  255. package/lib/projects/__tests__/buildAndDeploy.test.d.ts +1 -0
  256. package/lib/projects/__tests__/buildAndDeploy.test.js +25 -0
  257. package/lib/projects/__tests__/components.test.d.ts +1 -0
  258. package/lib/projects/__tests__/components.test.js +186 -0
  259. package/lib/projects/__tests__/projects.test.d.ts +1 -0
  260. package/lib/projects/__tests__/projects.test.js +89 -0
  261. package/lib/projects/__tests__/structure.test.d.ts +1 -0
  262. package/lib/projects/__tests__/structure.test.js +249 -0
  263. package/lib/projects/add/__tests__/legacyAddComponent.test.d.ts +1 -0
  264. package/lib/projects/add/__tests__/legacyAddComponent.test.js +206 -0
  265. package/lib/projects/add/__tests__/v3AddComponent.test.d.ts +1 -0
  266. package/lib/projects/add/__tests__/v3AddComponent.test.js +190 -0
  267. package/lib/projects/create/__tests__/legacy.test.d.ts +1 -0
  268. package/lib/projects/create/__tests__/legacy.test.js +126 -0
  269. package/lib/projects/create/__tests__/v3.test.d.ts +1 -0
  270. package/lib/projects/create/__tests__/v3.test.js +80 -0
  271. package/lib/projects/create/v3.d.ts +3 -2
  272. package/lib/projects/create/v3.js +2 -2
  273. package/lib/projects/localDev/DevServerManager.js +0 -3
  274. package/lib/projects/localDev/DevServerManagerV2.js +0 -2
  275. package/lib/projects/localDev/helpers.d.ts +1 -1
  276. package/lib/projects/localDev/helpers.js +2 -2
  277. package/lib/projects/upload.js +1 -1
  278. package/lib/prompts/__tests__/downloadProjectPrompt.test.d.ts +1 -0
  279. package/lib/prompts/__tests__/downloadProjectPrompt.test.js +30 -0
  280. package/lib/prompts/__tests__/projectsLogsPrompt.test.d.ts +1 -0
  281. package/lib/prompts/__tests__/projectsLogsPrompt.test.js +42 -0
  282. package/lib/prompts/createDeveloperTestAccountConfigPrompt.d.ts +11 -10
  283. package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +78 -35
  284. package/lib/prompts/createModulePrompt.js +1 -2
  285. package/lib/prompts/projectAddPrompt.d.ts +2 -1
  286. package/lib/prompts/projectAddPrompt.js +2 -1
  287. package/lib/prompts/promptUtils.d.ts +2 -2
  288. package/lib/prompts/promptUtils.js +172 -36
  289. package/lib/prompts/selectProjectTemplatePrompt.d.ts +2 -1
  290. package/lib/prompts/selectProjectTemplatePrompt.js +2 -1
  291. package/lib/schema.js +5 -1
  292. package/lib/testUtils.js +1 -2
  293. package/lib/ui/SpinniesManager.js +0 -1
  294. package/lib/ui/index.js +1 -1
  295. package/lib/ui/supportHyperlinks.js +2 -2
  296. package/lib/ui/supportsColor.js +2 -2
  297. package/lib/usageTracking.d.ts +11 -0
  298. package/lib/usageTracking.js +67 -73
  299. package/lib/utils/hasFlag.d.ts +1 -0
  300. package/lib/utils/hasFlag.js +15 -0
  301. package/lib/yargsUtils.d.ts +2 -1
  302. package/lib/yargsUtils.js +3 -13
  303. package/mcp-server/tools/project/AddFeatureToProject.js +4 -1
  304. package/mcp-server/tools/project/CreateProjectTool.d.ts +2 -2
  305. package/mcp-server/tools/project/CreateProjectTool.js +4 -1
  306. package/mcp-server/tools/project/DeployProject.js +4 -1
  307. package/mcp-server/tools/project/GuidedWalkthroughTool.js +4 -1
  308. package/mcp-server/tools/project/UploadProjectTools.js +4 -1
  309. package/mcp-server/tools/project/ValidateProjectTool.js +4 -1
  310. package/mcp-server/tools/project/__tests__/AddFeatureToProject.test.d.ts +1 -0
  311. package/mcp-server/tools/project/__tests__/AddFeatureToProject.test.js +153 -0
  312. package/mcp-server/tools/project/__tests__/CreateProjectTool.test.d.ts +1 -0
  313. package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +130 -0
  314. package/mcp-server/tools/project/__tests__/DeployProject.test.d.ts +1 -0
  315. package/mcp-server/tools/project/__tests__/DeployProject.test.js +121 -0
  316. package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.d.ts +1 -0
  317. package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +128 -0
  318. package/mcp-server/tools/project/__tests__/UploadProjectTools.test.d.ts +1 -0
  319. package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +109 -0
  320. package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.d.ts +1 -0
  321. package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +112 -0
  322. package/mcp-server/utils/__tests__/command.test.d.ts +1 -0
  323. package/mcp-server/utils/__tests__/command.test.js +47 -0
  324. package/mcp-server/utils/__tests__/project.test.d.ts +1 -0
  325. package/mcp-server/utils/__tests__/project.test.js +84 -0
  326. package/mcp-server/utils/project.js +3 -0
  327. package/mcp-server/utils/toolUsageTracking.d.ts +1 -0
  328. package/mcp-server/utils/toolUsageTracking.js +25 -0
  329. package/package.json +10 -10
  330. package/types/Prompts.d.ts +4 -2
@@ -0,0 +1,87 @@
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
+ vi.mock('@hubspot/local-dev-lib/config');
7
+ const Diagnosis_1 = require("../Diagnosis");
8
+ const config_1 = require("@hubspot/local-dev-lib/config");
9
+ const strip_ansi_1 = __importDefault(require("strip-ansi"));
10
+ const getAccountConfig = config_1.getAccountConfig;
11
+ describe('lib/doctor/Diagnosis', () => {
12
+ const diagnosticInfo = {
13
+ account: {},
14
+ arch: process.arch,
15
+ config: 'path/to/config.json',
16
+ defaultAccountOverrideFile: 'path/to/default/account/override/.hsaccount',
17
+ configSettings: { httpUseLocalhost: false },
18
+ configFiles: [],
19
+ envFiles: [],
20
+ files: [],
21
+ jsonFiles: [],
22
+ packageFiles: [],
23
+ packageLockFiles: [],
24
+ platform: process.platform,
25
+ project: {
26
+ config: {
27
+ projectDir: 'project-dir',
28
+ projectConfig: {
29
+ name: 'Super cool project',
30
+ srcDir: 'project-dir',
31
+ platformVersion: 'test',
32
+ },
33
+ },
34
+ },
35
+ versions: { '@hubspot/cli': '123', node: '18.0.1', npm: '8.0.0' },
36
+ };
37
+ const accountId = 123456;
38
+ beforeEach(() => {
39
+ getAccountConfig.mockReturnValue({
40
+ accountType: 'STANDARD',
41
+ name: 'Standard Account',
42
+ });
43
+ });
44
+ describe('toString', () => {
45
+ it('should return an empty diagnosis when no sections have been added', () => {
46
+ const diagnosis = new Diagnosis_1.Diagnosis({ diagnosticInfo, accountId });
47
+ const output = diagnosis.toString();
48
+ expect(output).toEqual('');
49
+ });
50
+ it('should generate the diagnosis output', () => {
51
+ const diagnosis = new Diagnosis_1.Diagnosis({ diagnosticInfo, accountId });
52
+ const cliMessage = 'Important CLI Message';
53
+ const cliSecondaryMessage = 'The CLI Section is Showing';
54
+ diagnosis.addCliSection({
55
+ type: 'success',
56
+ message: cliMessage,
57
+ secondaryMessaging: cliSecondaryMessage,
58
+ });
59
+ const cliConfigMessage = 'Important CLI Config Message';
60
+ const cliConfigSecondaryMessage = 'The CLI Config Section is Showing';
61
+ diagnosis.addCLIConfigSection({
62
+ type: 'error',
63
+ message: cliConfigMessage,
64
+ secondaryMessaging: cliConfigSecondaryMessage,
65
+ });
66
+ const projectMessage = 'Important Project Message';
67
+ const projectSecondaryMessage = 'The Project Section is Showing';
68
+ diagnosis.addProjectSection({
69
+ type: 'warning',
70
+ message: projectMessage,
71
+ secondaryMessaging: projectSecondaryMessage,
72
+ });
73
+ expect((0, strip_ansi_1.default)(diagnosis.toString())).toMatchSnapshot();
74
+ });
75
+ it('should generate categories that have sections', () => {
76
+ const diagnosis = new Diagnosis_1.Diagnosis({ diagnosticInfo, accountId });
77
+ const cliMessage = 'Important CLI Message';
78
+ const cliSecondaryMessage = 'The CLI Section is Showing';
79
+ diagnosis.addCliSection({
80
+ type: 'success',
81
+ message: cliMessage,
82
+ secondaryMessaging: cliSecondaryMessage,
83
+ });
84
+ expect((0, strip_ansi_1.default)(diagnosis.toString())).toMatchSnapshot();
85
+ });
86
+ });
87
+ });
@@ -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
+ });