@hubspot/cli 7.8.0-experimental.0 → 7.8.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 (357) hide show
  1. package/bin/cli.js +31 -27
  2. package/commands/__tests__/auth.test.js +5 -0
  3. package/commands/__tests__/doctor.test.js +16 -16
  4. package/commands/__tests__/getStarted.test.js +2 -2
  5. package/commands/__tests__/mcp.test.js +1 -1
  6. package/commands/__tests__/project.test.js +2 -3
  7. package/commands/account/auth.js +1 -0
  8. package/commands/account/clean.js +18 -27
  9. package/commands/account/createOverride.js +13 -31
  10. package/commands/account/info.js +20 -31
  11. package/commands/account/list.js +16 -22
  12. package/commands/account/remove.js +12 -20
  13. package/commands/account/removeOverride.js +11 -21
  14. package/commands/account/rename.js +6 -9
  15. package/commands/account/use.js +12 -26
  16. package/commands/account.js +2 -2
  17. package/commands/app/__tests__/migrate.test.js +5 -6
  18. package/commands/app/migrate.js +13 -19
  19. package/commands/app/secret/add.js +2 -1
  20. package/commands/app/secret/delete.js +2 -1
  21. package/commands/app/secret/list.js +2 -1
  22. package/commands/app/secret/update.js +2 -1
  23. package/commands/app/secret.js +2 -1
  24. package/commands/app.js +2 -2
  25. package/commands/auth.d.ts +1 -0
  26. package/commands/auth.js +17 -7
  27. package/commands/cms/convertFields.js +7 -9
  28. package/commands/cms/getReactModule.js +9 -14
  29. package/commands/cms/lighthouseScore.js +33 -36
  30. package/commands/cms.js +2 -2
  31. package/commands/completion.js +3 -3
  32. package/commands/config/set.d.ts +1 -1
  33. package/commands/config/set.js +64 -37
  34. package/commands/config.js +2 -2
  35. package/commands/create.js +2 -2
  36. package/commands/customObject/create.js +10 -12
  37. package/commands/customObject/schema/create.js +9 -11
  38. package/commands/customObject/schema/delete.js +16 -16
  39. package/commands/customObject/schema/fetch-all.js +12 -11
  40. package/commands/customObject/schema/fetch.js +15 -15
  41. package/commands/customObject/schema/list.js +4 -4
  42. package/commands/customObject/schema/update.js +13 -13
  43. package/commands/customObject/schema.js +2 -2
  44. package/commands/customObject.js +6 -7
  45. package/commands/doctor.js +8 -11
  46. package/commands/feedback.js +8 -13
  47. package/commands/fetch.js +8 -8
  48. package/commands/filemanager/fetch.js +7 -7
  49. package/commands/filemanager/upload.js +15 -34
  50. package/commands/filemanager.js +2 -2
  51. package/commands/function/deploy.js +11 -29
  52. package/commands/function/list.js +8 -8
  53. package/commands/function/server.js +9 -11
  54. package/commands/function.d.ts +1 -1
  55. package/commands/function.js +2 -2
  56. package/commands/getStarted.d.ts +1 -3
  57. package/commands/getStarted.js +68 -20
  58. package/commands/hubdb/clear.js +7 -15
  59. package/commands/hubdb/create.js +9 -15
  60. package/commands/hubdb/delete.js +8 -15
  61. package/commands/hubdb/fetch.js +6 -9
  62. package/commands/hubdb.d.ts +1 -1
  63. package/commands/hubdb.js +2 -2
  64. package/commands/init.js +2 -3
  65. package/commands/lint.js +16 -16
  66. package/commands/list.js +8 -14
  67. package/commands/logs.js +14 -20
  68. package/commands/mcp/__tests__/setup.test.js +2 -2
  69. package/commands/mcp/setup.js +11 -2
  70. package/commands/mcp.js +3 -3
  71. package/commands/mv.js +6 -17
  72. package/commands/open.js +5 -5
  73. package/commands/project/__tests__/add.test.js +15 -13
  74. package/commands/project/__tests__/create.test.js +6 -6
  75. package/commands/project/__tests__/deploy.test.js +3 -7
  76. package/commands/project/__tests__/devUnifiedFlow.test.js +2 -4
  77. package/commands/project/__tests__/installDeps.test.js +8 -8
  78. package/commands/project/__tests__/list.test.js +31 -0
  79. package/commands/project/__tests__/logs.test.js +1 -4
  80. package/commands/project/__tests__/migrate.test.js +7 -7
  81. package/commands/project/__tests__/migrateApp.test.js +3 -7
  82. package/commands/project/__tests__/profile.test.js +1 -1
  83. package/commands/project/__tests__/validate.test.js +98 -0
  84. package/commands/project/add.d.ts +2 -2
  85. package/commands/project/add.js +7 -10
  86. package/commands/project/cloneApp.js +14 -19
  87. package/commands/project/create.js +4 -11
  88. package/commands/project/deploy.js +5 -5
  89. package/commands/project/dev/deprecatedFlow.js +9 -18
  90. package/commands/project/dev/index.js +21 -18
  91. package/commands/project/dev/unifiedFlow.js +15 -8
  92. package/commands/project/download.js +15 -16
  93. package/commands/project/installDeps.d.ts +2 -2
  94. package/commands/project/installDeps.js +9 -9
  95. package/commands/project/list.d.ts +4 -0
  96. package/commands/project/list.js +62 -0
  97. package/commands/project/listBuilds.js +12 -21
  98. package/commands/project/logs.js +21 -24
  99. package/commands/project/migrate.js +33 -12
  100. package/commands/project/migrateApp.js +10 -17
  101. package/commands/project/open.js +6 -14
  102. package/commands/project/profile/add.js +3 -3
  103. package/commands/project/profile/delete.js +1 -2
  104. package/commands/project/profile.js +2 -3
  105. package/commands/project/upload.js +16 -25
  106. package/commands/project/validate.js +7 -7
  107. package/commands/project/watch.js +13 -22
  108. package/commands/project.js +4 -3
  109. package/commands/sandbox/__tests__/create.test.js +5 -5
  110. package/commands/sandbox/create.js +22 -32
  111. package/commands/sandbox/delete.js +39 -64
  112. package/commands/sandbox.js +2 -2
  113. package/commands/secret/addSecret.js +7 -17
  114. package/commands/secret/deleteSecret.js +10 -20
  115. package/commands/secret/listSecret.js +8 -10
  116. package/commands/secret/updateSecret.js +9 -17
  117. package/commands/secret.js +2 -2
  118. package/commands/testAccount/__tests__/delete.test.js +2 -4
  119. package/commands/testAccount/create.js +2 -2
  120. package/commands/testAccount/delete.d.ts +4 -3
  121. package/commands/testAccount/delete.js +155 -14
  122. package/commands/testAccount/importData.d.ts +1 -1
  123. package/commands/testAccount/importData.js +1 -1
  124. package/commands/testAccount.js +1 -1
  125. package/commands/theme/preview.js +1 -4
  126. package/lang/en.d.ts +365 -111
  127. package/lang/en.js +409 -158
  128. package/lang/en.lyaml +4 -4
  129. package/lib/__tests__/buildAccount.test.js +4 -3
  130. package/lib/__tests__/commonOpts.test.js +1 -1
  131. package/lib/__tests__/dependencyManagement.test.js +1 -1
  132. package/lib/__tests__/developerTestAccounts.test.js +3 -3
  133. package/lib/__tests__/hasFeature.test.js +145 -7
  134. package/lib/__tests__/npm.test.js +1 -1
  135. package/lib/__tests__/oauth.test.js +4 -4
  136. package/lib/__tests__/process.test.js +10 -5
  137. package/lib/__tests__/sandboxSync.test.js +8 -8
  138. package/lib/__tests__/sandboxes.test.js +8 -8
  139. package/lib/__tests__/serverlessLogs.test.js +1 -1
  140. package/lib/__tests__/usageTracking.test.js +5 -5
  141. package/lib/__tests__/validation.test.js +2 -1
  142. package/lib/__tests__/yargsUtils.test.js +83 -9
  143. package/lib/app/__tests__/migrate.test.js +19 -56
  144. package/lib/app/__tests__/migrate_legacy.test.js +1 -1
  145. package/lib/app/migrate.d.ts +2 -8
  146. package/lib/app/migrate.js +6 -81
  147. package/lib/app/migrate_legacy.js +20 -24
  148. package/lib/buildAccount.d.ts +2 -2
  149. package/lib/buildAccount.js +32 -64
  150. package/lib/commonOpts.d.ts +1 -1
  151. package/lib/commonOpts.js +25 -22
  152. package/lib/configMigrate.js +88 -9
  153. package/lib/configOptions.js +7 -0
  154. package/lib/constants.d.ts +22 -1
  155. package/lib/constants.js +26 -1
  156. package/lib/dependencyManagement.d.ts +0 -5
  157. package/lib/dependencyManagement.js +9 -36
  158. package/lib/developerTestAccounts.js +9 -23
  159. package/lib/doctor/Diagnosis.js +11 -23
  160. package/lib/doctor/DiagnosticInfoBuilder.js +12 -11
  161. package/lib/doctor/Doctor.js +42 -90
  162. package/lib/doctor/__tests__/Doctor.test.js +4 -4
  163. package/lib/errorHandlers/index.js +12 -20
  164. package/lib/errorHandlers/suppressError.js +11 -18
  165. package/lib/hasFeature.js +6 -0
  166. package/lib/lang.js +6 -5
  167. package/lib/links.d.ts +1 -0
  168. package/lib/links.js +14 -7
  169. package/lib/mcp/setup.js +1 -1
  170. package/lib/middleware/__test__/commandTargetingUtils.test.js +99 -0
  171. package/lib/middleware/__test__/configMiddleware.test.js +11 -11
  172. package/lib/middleware/__test__/yargsChecksMiddleware.test.js +6 -8
  173. package/lib/middleware/commandTargetingUtils.d.ts +8 -0
  174. package/lib/middleware/commandTargetingUtils.js +74 -0
  175. package/lib/middleware/configMiddleware.d.ts +1 -1
  176. package/lib/middleware/configMiddleware.js +21 -81
  177. package/lib/middleware/fireAlarmMiddleware.js +15 -5
  178. package/lib/middleware/gitMiddleware.js +5 -1
  179. package/lib/middleware/notificationsMiddleware.js +5 -11
  180. package/lib/middleware/yargsChecksMiddleware.js +6 -9
  181. package/lib/npm.js +2 -2
  182. package/lib/oauth.js +5 -5
  183. package/lib/process.js +5 -4
  184. package/lib/projects/__tests__/AppDevModeInterface.test.js +87 -90
  185. package/lib/projects/__tests__/LocalDevProcess.test.js +231 -19
  186. package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +89 -63
  187. package/lib/projects/__tests__/deploy.test.js +73 -8
  188. package/lib/projects/__tests__/localDevProjectHelpers.test.js +6 -2
  189. package/lib/projects/__tests__/platformVersion.test.js +8 -8
  190. package/lib/projects/__tests__/projects.test.js +12 -12
  191. package/lib/projects/__tests__/structure.test.js +3 -3
  192. package/lib/projects/__tests__/upload.test.d.ts +1 -0
  193. package/lib/projects/__tests__/upload.test.js +82 -0
  194. package/lib/projects/add/__tests__/legacyAddComponent.test.js +6 -6
  195. package/lib/projects/add/__tests__/v2AddComponent.test.d.ts +1 -0
  196. package/lib/projects/add/__tests__/{v3AddComponent.test.js → v2AddComponent.test.js} +39 -39
  197. package/lib/projects/add/{v3AddComponent.d.ts → v2AddComponent.d.ts} +1 -1
  198. package/lib/projects/add/{v3AddComponent.js → v2AddComponent.js} +5 -5
  199. package/lib/projects/create/__tests__/legacy.test.js +5 -5
  200. package/lib/projects/create/__tests__/v2.test.d.ts +1 -0
  201. package/lib/projects/create/__tests__/{v3.test.js → v2.test.js} +82 -7
  202. package/lib/projects/create/index.js +4 -4
  203. package/lib/projects/create/legacy.js +2 -2
  204. package/lib/projects/create/{v3.d.ts → v2.d.ts} +3 -3
  205. package/lib/projects/create/{v3.js → v2.js} +16 -13
  206. package/lib/projects/deploy.d.ts +1 -1
  207. package/lib/projects/deploy.js +2 -2
  208. package/lib/projects/localDev/AppDevModeInterface.d.ts +10 -1
  209. package/lib/projects/localDev/AppDevModeInterface.js +118 -89
  210. package/lib/projects/localDev/DevServerManager.d.ts +11 -29
  211. package/lib/projects/localDev/DevServerManager.js +19 -61
  212. package/lib/projects/localDev/DevServerManager_DEPRECATED.d.ts +40 -0
  213. package/lib/projects/localDev/DevServerManager_DEPRECATED.js +120 -0
  214. package/lib/projects/localDev/LocalDevLogger.d.ts +4 -0
  215. package/lib/projects/localDev/LocalDevLogger.js +27 -6
  216. package/lib/projects/localDev/{LocalDevManager.js → LocalDevManager_DEPRECATED.js} +10 -11
  217. package/lib/projects/localDev/LocalDevProcess.d.ts +7 -5
  218. package/lib/projects/localDev/LocalDevProcess.js +93 -21
  219. package/lib/projects/localDev/LocalDevState.d.ts +12 -8
  220. package/lib/projects/localDev/LocalDevState.js +27 -17
  221. package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +6 -1
  222. package/lib/projects/localDev/LocalDevWebsocketServer.js +94 -33
  223. package/lib/projects/localDev/helpers/account.d.ts +1 -1
  224. package/lib/projects/localDev/helpers/account.js +2 -2
  225. package/lib/projects/localDev/helpers/project.d.ts +3 -2
  226. package/lib/projects/localDev/helpers/project.js +49 -10
  227. package/lib/projects/localDev/localDevWebsocketServerUtils.d.ts +7 -0
  228. package/lib/projects/localDev/localDevWebsocketServerUtils.js +19 -0
  229. package/lib/projects/platformVersion.d.ts +1 -1
  230. package/lib/projects/platformVersion.js +1 -1
  231. package/lib/projects/pollProjectBuildAndDeploy.js +4 -4
  232. package/lib/projects/structure.js +6 -6
  233. package/lib/projects/upload.d.ts +1 -1
  234. package/lib/projects/upload.js +17 -8
  235. package/lib/projects/urls.d.ts +0 -1
  236. package/lib/projects/urls.js +0 -3
  237. package/lib/prompts/__tests__/downloadProjectPrompt.test.js +1 -0
  238. package/lib/prompts/__tests__/projectAddPrompt.test.js +10 -10
  239. package/lib/prompts/accountNamePrompt.js +14 -19
  240. package/lib/prompts/accountsPrompt.js +2 -2
  241. package/lib/prompts/cmsFieldPrompt.js +2 -2
  242. package/lib/prompts/createApiSamplePrompt.js +5 -5
  243. package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +10 -1
  244. package/lib/prompts/createFunctionPrompt.js +14 -14
  245. package/lib/prompts/createModulePrompt.js +9 -9
  246. package/lib/prompts/createTemplatePrompt.js +2 -2
  247. package/lib/prompts/downloadProjectPrompt.js +5 -8
  248. package/lib/prompts/installAppPrompt.d.ts +1 -6
  249. package/lib/prompts/installAppPrompt.js +1 -6
  250. package/lib/prompts/personalAccessKeyPrompt.js +3 -3
  251. package/lib/prompts/previewPrompt.js +6 -6
  252. package/lib/prompts/projectAddPrompt.d.ts +2 -2
  253. package/lib/prompts/projectAddPrompt.js +9 -2
  254. package/lib/prompts/projectDevTargetAccountPrompt.js +20 -32
  255. package/lib/prompts/projectNamePrompt.js +4 -8
  256. package/lib/prompts/projectsLogsPrompt.js +2 -4
  257. package/lib/prompts/promptUtils.js +30 -9
  258. package/lib/prompts/sandboxesPrompt.js +7 -7
  259. package/lib/prompts/secretPrompt.js +3 -3
  260. package/lib/prompts/selectAppPrompt.js +3 -3
  261. package/lib/prompts/selectHubDBTablePrompt.js +9 -13
  262. package/lib/prompts/selectProjectTemplatePrompt.js +2 -0
  263. package/lib/prompts/selectPublicAppForMigrationPrompt.js +15 -19
  264. package/lib/prompts/setAsDefaultAccountPrompt.js +4 -8
  265. package/lib/prompts/uploadPrompt.js +5 -5
  266. package/lib/sandboxSync.js +24 -41
  267. package/lib/sandboxes.js +19 -47
  268. package/lib/schema.js +3 -3
  269. package/lib/serverlessLogs.js +11 -13
  270. package/lib/theme/__tests__/migrate.test.d.ts +1 -0
  271. package/lib/theme/__tests__/migrate.test.js +233 -0
  272. package/lib/theme/migrate.d.ts +13 -0
  273. package/lib/theme/migrate.js +90 -0
  274. package/lib/ui/SpinniesManager.d.ts +2 -0
  275. package/lib/ui/SpinniesManager.js +112 -8
  276. package/lib/ui/boxen.js +1 -2
  277. package/lib/ui/git.js +13 -10
  278. package/lib/ui/index.d.ts +4 -0
  279. package/lib/ui/index.js +47 -38
  280. package/lib/ui/serverlessFunctionLogs.js +9 -7
  281. package/lib/ui/uiMessages.d.ts +72 -0
  282. package/lib/ui/uiMessages.js +75 -0
  283. package/lib/usageTracking.js +8 -8
  284. package/lib/validation.js +20 -23
  285. package/lib/yargsUtils.d.ts +1 -1
  286. package/lib/yargsUtils.js +12 -5
  287. package/mcp-server/tools/cms/HsCreateFunctionTool.js +1 -1
  288. package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +2 -2
  289. package/mcp-server/tools/cms/HsCreateModuleTool.js +1 -1
  290. package/mcp-server/tools/cms/HsCreateTemplateTool.js +1 -1
  291. package/mcp-server/tools/cms/HsFunctionLogsTool.js +2 -2
  292. package/mcp-server/tools/cms/HsListFunctionsTool.js +1 -1
  293. package/mcp-server/tools/cms/HsListTool.js +1 -1
  294. package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.js +1 -1
  295. package/mcp-server/tools/cms/__tests__/HsCreateModuleTool.test.js +1 -1
  296. package/mcp-server/tools/cms/__tests__/HsCreateTemplateTool.test.js +1 -1
  297. package/mcp-server/tools/cms/__tests__/HsFunctionLogsTool.test.js +2 -2
  298. package/mcp-server/tools/cms/__tests__/HsListFunctionsTool.test.js +1 -1
  299. package/mcp-server/tools/cms/__tests__/HsListTool.test.js +1 -1
  300. package/mcp-server/tools/index.js +4 -0
  301. package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +3 -3
  302. package/mcp-server/tools/project/AddFeatureToProjectTool.js +3 -3
  303. package/mcp-server/tools/project/CreateProjectTool.d.ts +3 -3
  304. package/mcp-server/tools/project/CreateProjectTool.js +5 -5
  305. package/mcp-server/tools/project/DeployProjectTool.js +1 -1
  306. package/mcp-server/tools/project/DocFetchTool.js +2 -2
  307. package/mcp-server/tools/project/DocsSearchTool.d.ts +4 -1
  308. package/mcp-server/tools/project/DocsSearchTool.js +7 -7
  309. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +23 -0
  310. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +68 -0
  311. package/mcp-server/tools/project/GetApplicationInfoTool.d.ts +11 -0
  312. package/mcp-server/tools/project/GetApplicationInfoTool.js +49 -0
  313. package/mcp-server/tools/project/GetConfigValuesTool.d.ts +4 -1
  314. package/mcp-server/tools/project/GetConfigValuesTool.js +13 -7
  315. package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +2 -2
  316. package/mcp-server/tools/project/GuidedWalkthroughTool.js +1 -1
  317. package/mcp-server/tools/project/UploadProjectTools.js +2 -2
  318. package/mcp-server/tools/project/ValidateProjectTool.js +1 -1
  319. package/mcp-server/tools/project/__tests__/AddFeatureToProjectTool.test.js +1 -1
  320. package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +2 -2
  321. package/mcp-server/tools/project/__tests__/DeployProjectTool.test.js +1 -1
  322. package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +2 -2
  323. package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +14 -12
  324. package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.d.ts +1 -0
  325. package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.js +169 -0
  326. package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.d.ts +1 -0
  327. package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.js +115 -0
  328. package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +9 -8
  329. package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +1 -1
  330. package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +1 -1
  331. package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +1 -1
  332. package/mcp-server/tools/project/constants.d.ts +1 -1
  333. package/mcp-server/tools/project/constants.js +9 -3
  334. package/mcp-server/utils/__tests__/cliConfig.test.d.ts +1 -0
  335. package/mcp-server/utils/__tests__/cliConfig.test.js +110 -0
  336. package/mcp-server/utils/cliConfig.d.ts +1 -0
  337. package/mcp-server/utils/cliConfig.js +12 -0
  338. package/mcp-server/utils/toolUsageTracking.js +2 -2
  339. package/package.json +8 -12
  340. package/types/LocalDev.d.ts +19 -3
  341. package/ui/components/HorizontalSelectPrompt.js +1 -1
  342. package/ui/index.js +1 -1
  343. package/commands/getStartedV2.d.ts +0 -9
  344. package/commands/getStartedV2.js +0 -39
  345. package/lib/middleware/__test__/utils.test.js +0 -51
  346. package/lib/middleware/utils.d.ts +0 -8
  347. package/lib/middleware/utils.js +0 -14
  348. package/lib/projects/localDev/DevServerManagerV2.d.ts +0 -22
  349. package/lib/projects/localDev/DevServerManagerV2.js +0 -81
  350. package/ui/components/Ascii.d.ts +0 -10
  351. package/ui/components/Ascii.js +0 -11
  352. package/ui/views/GetStarted.d.ts +0 -7
  353. package/ui/views/GetStarted.js +0 -157
  354. /package/{lib/middleware/__test__/utils.test.d.ts → commands/project/__tests__/list.test.d.ts} +0 -0
  355. /package/{lib/projects/add/__tests__/v3AddComponent.test.d.ts → commands/project/__tests__/validate.test.d.ts} +0 -0
  356. /package/lib/{projects/create/__tests__/v3.test.d.ts → middleware/__test__/commandTargetingUtils.test.d.ts} +0 -0
  357. /package/lib/projects/localDev/{LocalDevManager.d.ts → LocalDevManager_DEPRECATED.d.ts} +0 -0
@@ -1,51 +1,75 @@
1
1
  import { WebSocketServer } from 'ws';
2
2
  import { isPortManagerServerRunning, requestPorts, } from '@hubspot/local-dev-lib/portManager';
3
- import { logger } from '@hubspot/local-dev-lib/logger';
3
+ import { uiLogger } from '../../ui/logger.js';
4
4
  import { addLocalStateFlag } from '@hubspot/local-dev-lib/config';
5
- import { LOCAL_DEV_UI_MESSAGE_SEND_TYPES, LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES, LOCAL_DEV_SERVER_MESSAGE_TYPES, CONFIG_LOCAL_STATE_FLAGS, } from '../../constants.js';
5
+ import { LOCAL_DEV_UI_MESSAGE_SEND_TYPES, LOCAL_DEV_SERVER_MESSAGE_TYPES, CONFIG_LOCAL_STATE_FLAGS, } from '../../constants.js';
6
6
  import { lib } from '../../../lang/en.js';
7
7
  import { removeAnsiCodes } from '../../ui/removeAnsiCodes.js';
8
+ import { isDeployWebsocketMessage, isViewedWelcomeScreenWebsocketMessage, isUploadWebsocketMessage, isAppInstallFailureWebsocketMessage, isAppInstallSuccessWebsocketMessage, isAppInstallInitiatedWebsocketMessage, } from './localDevWebsocketServerUtils.js';
9
+ import pkg from '../../../package.json' with { type: 'json' };
8
10
  const SERVER_INSTANCE_ID = 'local-dev-ui-websocket-server';
11
+ const LOCAL_DEV_WEBSOCKET_SERVER_VERSION = 2;
9
12
  const LOG_PREFIX = '[LocalDevWebsocketServer]';
13
+ const DOMAINS = ['hubspot.com', 'hubspotqa.com'];
14
+ const SUBDOMAINS = ['local', 'app', 'app-na2', 'app-na3', 'app-ap1', 'app-eu1'];
15
+ const ALLOWED_ORIGIN_REGEX = new RegExp(`^https://(${SUBDOMAINS.join('|')})\\.(${DOMAINS.join('|')})$`);
10
16
  class LocalDevWebsocketServer {
11
17
  server;
12
18
  debug;
13
19
  localDevProcess;
14
- ALLOWED_ORIGINS = [
15
- 'https://app.hubspot.com',
16
- 'https://app.hubspotqa.com',
17
- 'https://local.hubspot.com',
18
- 'https://local.hubspotqa.com',
19
- ];
20
20
  constructor(localDevProcess, debug) {
21
21
  this.localDevProcess = localDevProcess;
22
22
  this.debug = debug;
23
23
  }
24
24
  log(message) {
25
25
  if (this.debug) {
26
- logger.log(LOG_PREFIX, message);
26
+ uiLogger.log(`${LOG_PREFIX} ${message}`);
27
27
  }
28
28
  }
29
29
  logError(message) {
30
30
  if (this.debug) {
31
- logger.error(LOG_PREFIX, message);
31
+ uiLogger.error(`${LOG_PREFIX} ${message}`);
32
32
  }
33
33
  }
34
34
  sendMessage(websocket, message) {
35
35
  websocket.send(JSON.stringify(message));
36
36
  }
37
37
  async handleUpload(websocket) {
38
- const uploadSuccess = await this.localDevProcess.uploadProject();
39
- if (uploadSuccess) {
40
- this.sendMessage(websocket, {
41
- type: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPLOAD_SUCCESS,
42
- });
43
- }
44
- else {
45
- this.sendMessage(websocket, {
46
- type: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPLOAD_FAILURE,
47
- });
48
- }
38
+ const { uploadSuccess, buildSuccess, deploySuccess, deployId } = await this.localDevProcess.uploadProject();
39
+ this.sendMessage(websocket, {
40
+ type: uploadSuccess
41
+ ? LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPLOAD_SUCCESS
42
+ : LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPLOAD_FAILURE,
43
+ data: {
44
+ latestBuild: this.localDevProcess.projectData.latestBuild,
45
+ deployedBuild: this.localDevProcess.projectData.deployedBuild,
46
+ buildSuccess,
47
+ deploySuccess,
48
+ deployId,
49
+ },
50
+ });
51
+ }
52
+ async handleDeploy(websocket, force) {
53
+ const { success, deployId } = await this.localDevProcess.deployLatestBuild(force);
54
+ this.sendMessage(websocket, {
55
+ type: success
56
+ ? LOCAL_DEV_UI_MESSAGE_SEND_TYPES.DEPLOY_SUCCESS
57
+ : LOCAL_DEV_UI_MESSAGE_SEND_TYPES.DEPLOY_FAILURE,
58
+ data: {
59
+ latestBuild: this.localDevProcess.projectData.latestBuild,
60
+ deployedBuild: this.localDevProcess.projectData.deployedBuild,
61
+ latestDeployId: deployId,
62
+ },
63
+ });
64
+ }
65
+ async handleAppInstallSuccess() {
66
+ this.localDevProcess.sendDevServerMessage(LOCAL_DEV_SERVER_MESSAGE_TYPES.STATIC_AUTH_APP_INSTALL_SUCCESS);
67
+ }
68
+ async handleAppInstallFailure() {
69
+ this.localDevProcess.sendDevServerMessage(LOCAL_DEV_SERVER_MESSAGE_TYPES.STATIC_AUTH_APP_INSTALL_FAILURE);
70
+ }
71
+ async handleAppInstallInitiated() {
72
+ this.localDevProcess.sendDevServerMessage(LOCAL_DEV_SERVER_MESSAGE_TYPES.OAUTH_APP_INSTALL_INITIATED);
49
73
  }
50
74
  setupMessageHandlers(websocket) {
51
75
  websocket.on('message', data => {
@@ -55,15 +79,26 @@ class LocalDevWebsocketServer {
55
79
  this.logError(lib.LocalDevWebsocketServer.errors.missingTypeField(data.toString()));
56
80
  return;
57
81
  }
58
- switch (message.type) {
59
- case LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.UPLOAD:
60
- this.handleUpload(websocket);
61
- break;
62
- case LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.VIEWED_WELCOME_SCREEN:
63
- addLocalStateFlag(CONFIG_LOCAL_STATE_FLAGS.LOCAL_DEV_UI_WELCOME);
64
- break;
65
- default:
66
- this.logError(lib.LocalDevWebsocketServer.errors.unknownMessageType(message.type));
82
+ if (isUploadWebsocketMessage(message)) {
83
+ this.handleUpload(websocket);
84
+ }
85
+ else if (isDeployWebsocketMessage(message)) {
86
+ this.handleDeploy(websocket, message.data.force);
87
+ }
88
+ else if (isViewedWelcomeScreenWebsocketMessage(message)) {
89
+ addLocalStateFlag(CONFIG_LOCAL_STATE_FLAGS.LOCAL_DEV_UI_WELCOME);
90
+ }
91
+ else if (isAppInstallSuccessWebsocketMessage(message)) {
92
+ this.handleAppInstallSuccess();
93
+ }
94
+ else if (isAppInstallFailureWebsocketMessage(message)) {
95
+ this.handleAppInstallFailure();
96
+ }
97
+ else if (isAppInstallInitiatedWebsocketMessage(message)) {
98
+ this.handleAppInstallInitiated();
99
+ }
100
+ else {
101
+ this.logError(lib.LocalDevWebsocketServer.errors.unknownMessageType(message.type));
67
102
  }
68
103
  }
69
104
  catch (e) {
@@ -71,12 +106,23 @@ class LocalDevWebsocketServer {
71
106
  }
72
107
  });
73
108
  }
109
+ sendCliMetadata(websocket) {
110
+ this.sendMessage(websocket, {
111
+ type: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.CLI_METADATA,
112
+ data: {
113
+ cliVersion: pkg.version,
114
+ localDevWebsocketServerVersion: LOCAL_DEV_WEBSOCKET_SERVER_VERSION,
115
+ },
116
+ });
117
+ }
74
118
  sendProjectData(websocket) {
75
119
  this.sendMessage(websocket, {
76
120
  type: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPDATE_PROJECT_DATA,
77
121
  data: {
78
- projectName: this.localDevProcess.projectName,
79
- projectId: this.localDevProcess.projectId,
122
+ projectName: this.localDevProcess.projectData.name,
123
+ projectId: this.localDevProcess.projectData.id,
124
+ latestBuild: this.localDevProcess.projectData.latestBuild,
125
+ deployedBuild: this.localDevProcess.projectData.deployedBuild,
80
126
  targetProjectAccountId: this.localDevProcess.targetProjectAccountId,
81
127
  targetTestingAccountId: this.localDevProcess.targetTestingAccountId,
82
128
  },
@@ -119,10 +165,24 @@ class LocalDevWebsocketServer {
119
165
  this.localDevProcess.removeStateListener('uploadWarnings', listener);
120
166
  });
121
167
  }
168
+ setupDevServersStartedListener(websocket) {
169
+ const listener = (devServersStarted) => {
170
+ if (devServersStarted) {
171
+ this.sendMessage(websocket, {
172
+ type: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.DEV_SERVERS_STARTED,
173
+ });
174
+ }
175
+ };
176
+ this.localDevProcess.addStateListener('devServersStarted', listener);
177
+ websocket.on('close', () => {
178
+ this.localDevProcess.removeStateListener('devServersStarted', listener);
179
+ });
180
+ }
122
181
  setupStateListeners(websocket) {
123
182
  this.setupProjectNodesListener(websocket);
124
183
  this.setupAppDataListener(websocket);
125
184
  this.setupUploadWarningsListener(websocket);
185
+ this.setupDevServersStartedListener(websocket);
126
186
  }
127
187
  async start() {
128
188
  const portManagerIsRunning = await isPortManagerServerRunning();
@@ -135,10 +195,11 @@ class LocalDevWebsocketServer {
135
195
  this.log(lib.LocalDevWebsocketServer.logs.startup(port));
136
196
  this.server.on('connection', (ws, req) => {
137
197
  const origin = req.headers.origin;
138
- if (!origin || !this.ALLOWED_ORIGINS.includes(origin)) {
198
+ if (!origin || !ALLOWED_ORIGIN_REGEX.test(origin)) {
139
199
  ws.close(1008, lib.LocalDevWebsocketServer.errors.originNotAllowed(origin));
140
200
  return;
141
201
  }
202
+ this.sendCliMetadata(ws);
142
203
  this.sendProjectData(ws);
143
204
  this.setupMessageHandlers(ws);
144
205
  this.setupStateListeners(ws);
@@ -8,7 +8,7 @@ export declare function checkIfParentAccountIsAuthed(accountConfig: CLIAccount):
8
8
  export declare function checkIfAccountFlagIsSupported(accountConfig: CLIAccount, hasPublicApps: boolean): void;
9
9
  export declare function suggestRecommendedNestedAccount(accounts: CLIAccount[], accountConfig: CLIAccount, hasPublicApps: boolean): Promise<ProjectDevTargetAccountPromptResponse>;
10
10
  export declare function createSandboxForLocalDev(accountId: number, accountConfig: CLIAccount, env: Environment): Promise<number>;
11
- export declare function createDeveloperTestAccountForLocalDev(accountId: number, accountConfig: CLIAccount, env: Environment, useV3?: boolean): Promise<number>;
11
+ export declare function createDeveloperTestAccountForLocalDev(accountId: number, accountConfig: CLIAccount, env: Environment, useV2?: boolean): Promise<number>;
12
12
  export declare function useExistingDevTestAccount(env: Environment, account: DeveloperTestAccount): Promise<void>;
13
13
  export declare function hasSandboxes(account: CLIAccount): Promise<boolean>;
14
14
  export declare function selectAccountTypePrompt(accountConfig: CLIAccount): Promise<string | null>;
@@ -138,7 +138,7 @@ export async function createSandboxForLocalDev(accountId, accountConfig, env) {
138
138
  }
139
139
  }
140
140
  // Create a developer test account and return its accountId
141
- export async function createDeveloperTestAccountForLocalDev(accountId, accountConfig, env, useV3 = false) {
141
+ export async function createDeveloperTestAccountForLocalDev(accountId, accountConfig, env, useV2 = false) {
142
142
  let currentPortalCount = 0;
143
143
  let maxTestPortals = 10;
144
144
  try {
@@ -168,7 +168,7 @@ export async function createDeveloperTestAccountForLocalDev(accountId, accountCo
168
168
  accountType: HUBSPOT_ACCOUNT_TYPES.DEVELOPER_TEST,
169
169
  });
170
170
  trackCommandMetadataUsage('developer-test-account-create', { step: 'project-dev' }, accountId);
171
- const result = await buildDeveloperTestAccount(name, accountConfig, env, maxTestPortals, useV3);
171
+ const result = await buildDeveloperTestAccount(name, accountConfig, env, maxTestPortals, useV2);
172
172
  return result;
173
173
  }
174
174
  catch (err) {
@@ -6,7 +6,8 @@ export declare function createNewProjectForLocalDev(projectConfig: ProjectConfig
6
6
  export declare function createInitialBuildForNewProject(projectConfig: ProjectConfig, projectDir: string, targetAccountId: number, sendIR?: boolean, profile?: string): Promise<Build>;
7
7
  export declare function compareLocalProjectToDeployed(projectConfig: ProjectConfig, accountId: number, deployedBuildId: number | undefined, localProjectNodes: {
8
8
  [key: string]: IntermediateRepresentationNodeLocalDev;
9
- }): Promise<void>;
9
+ }, profile?: string): Promise<void>;
10
10
  export declare function isDeployedProjectUpToDateWithLocal(projectConfig: ProjectConfig, accountId: number, deployedBuildId: number, localProjectNodes: {
11
11
  [key: string]: IntermediateRepresentationNodeLocalDev;
12
- }): Promise<boolean>;
12
+ }, profile?: string): Promise<boolean>;
13
+ export declare function checkAndInstallDependencies(): Promise<void>;
@@ -18,8 +18,9 @@ import SpinniesManager from '../../../ui/SpinniesManager.js';
18
18
  import { EXIT_CODES } from '../../../enums/exitCodes.js';
19
19
  import { handleProjectUpload } from '../../upload.js';
20
20
  import { pollProjectBuildAndDeploy } from '../../pollProjectBuildAndDeploy.js';
21
- import { logError } from '../../../errorHandlers/index.js';
21
+ import { debugError, logError } from '../../../errorHandlers/index.js';
22
22
  import { ApiErrorContext } from '../../../errorHandlers/index.js';
23
+ import { getProjectPackageJsonLocations, hasMissingPackages, installPackages, } from '../../../dependencyManagement.js';
23
24
  // Prompt the user to create a new project if one doesn't exist on their target account
24
25
  export async function createNewProjectForLocalDev(projectConfig, targetAccountId, shouldCreateWithoutConfirmation, hasPublicApps) {
25
26
  // Create the project without prompting if this is a newly created sandbox
@@ -123,7 +124,7 @@ export async function createInitialBuildForNewProject(projectConfig, projectDir,
123
124
  }
124
125
  return initialUploadResult.buildResult;
125
126
  }
126
- export async function compareLocalProjectToDeployed(projectConfig, accountId, deployedBuildId, localProjectNodes) {
127
+ export async function compareLocalProjectToDeployed(projectConfig, accountId, deployedBuildId, localProjectNodes, profile) {
127
128
  uiLogger.log('');
128
129
  if (!deployedBuildId) {
129
130
  uiLogger.error(lib.localDevHelpers.project.compareLocalProjectToDeployed.noDeployedBuild(projectConfig.name, uiAccountDescription(accountId)));
@@ -132,7 +133,7 @@ export async function compareLocalProjectToDeployed(projectConfig, accountId, de
132
133
  SpinniesManager.add('compareLocalProjectToDeployed', {
133
134
  text: lib.localDevHelpers.project.compareLocalProjectToDeployed.checking,
134
135
  });
135
- const isUpToDate = await isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes);
136
+ const isUpToDate = await isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes, profile);
136
137
  if (isUpToDate) {
137
138
  SpinniesManager.succeed('compareLocalProjectToDeployed', {
138
139
  text: lib.localDevHelpers.project.compareLocalProjectToDeployed.upToDate,
@@ -144,26 +145,28 @@ export async function compareLocalProjectToDeployed(projectConfig, accountId, de
144
145
  .notUpToDate,
145
146
  });
146
147
  uiLogger.log('');
147
- uiLogger.log(lib.localDevHelpers.project.compareLocalProjectToDeployed
148
- .notUpToDateExplanation);
148
+ uiLogger.log(lib.localDevHelpers.project.compareLocalProjectToDeployed.notUpToDateExplanation(profile));
149
149
  process.exit(EXIT_CODES.SUCCESS);
150
150
  }
151
151
  }
152
- export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes) {
152
+ export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes, profile) {
153
153
  let tempDir = null;
154
154
  try {
155
155
  tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'hubspot-project-compare-'));
156
156
  const { data: zippedProject } = await downloadProject(accountId, projectConfig.name, deployedBuildId);
157
- const extractedProjectPath = path.join(tempDir, sanitizeFileName(projectConfig.name));
158
- await extractZipArchive(zippedProject, sanitizeFileName(projectConfig.name), tempDir, { includesRootDir: false, hideLogs: true });
159
- const deployedProjectSourceDir = path.join(extractedProjectPath, projectConfig.srcDir);
157
+ await extractZipArchive(zippedProject, sanitizeFileName(projectConfig.name), tempDir, { hideLogs: true });
158
+ const deployedProjectSourceDir = path.join(tempDir, projectConfig.srcDir);
160
159
  const { intermediateNodesIndexedByUid: deployedProjectNodes } = await translate({
161
160
  projectSourceDir: deployedProjectSourceDir,
162
161
  platformVersion: projectConfig.platformVersion,
163
162
  accountId: accountId,
164
- }, {});
163
+ }, { profile });
165
164
  return isDeepEqual(localProjectNodes, deployedProjectNodes, ['localDev']);
166
165
  }
166
+ catch (err) {
167
+ debugError(err);
168
+ return false;
169
+ }
167
170
  finally {
168
171
  // Clean up temporary directory
169
172
  if (tempDir && (await fs.pathExists(tempDir))) {
@@ -171,3 +174,39 @@ export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountI
171
174
  }
172
175
  }
173
176
  }
177
+ export async function checkAndInstallDependencies() {
178
+ SpinniesManager.init();
179
+ uiLogger.log('');
180
+ SpinniesManager.add('checkingDependencies', {
181
+ text: lib.localDevHelpers.project.checkAndInstallDependencies
182
+ .checkingDependencies,
183
+ });
184
+ try {
185
+ const installLocations = await getProjectPackageJsonLocations();
186
+ const locationsToInstall = [];
187
+ for (const location of installLocations) {
188
+ if (await hasMissingPackages(location)) {
189
+ locationsToInstall.push(location);
190
+ }
191
+ }
192
+ if (locationsToInstall.length > 0) {
193
+ SpinniesManager.remove('checkingDependencies');
194
+ await installPackages({ installLocations: locationsToInstall });
195
+ }
196
+ else {
197
+ SpinniesManager.succeed('checkingDependencies', {
198
+ text: lib.localDevHelpers.project.checkAndInstallDependencies
199
+ .dependenciesUpToDate,
200
+ });
201
+ }
202
+ uiLogger.log('');
203
+ }
204
+ catch (e) {
205
+ logError(e);
206
+ SpinniesManager.fail('checkingDependencies', {
207
+ text: lib.localDevHelpers.project.checkAndInstallDependencies
208
+ .dependenciesFailure,
209
+ });
210
+ process.exit(EXIT_CODES.ERROR);
211
+ }
212
+ }
@@ -0,0 +1,7 @@
1
+ import { LocalDevDeployWebsocketMessage, LocalDevWebsocketMessage } from '../../../types/LocalDev.js';
2
+ export declare function isUploadWebsocketMessage(message: LocalDevWebsocketMessage): boolean;
3
+ export declare function isDeployWebsocketMessage(message: LocalDevWebsocketMessage): message is LocalDevDeployWebsocketMessage;
4
+ export declare function isViewedWelcomeScreenWebsocketMessage(message: LocalDevWebsocketMessage): boolean;
5
+ export declare function isAppInstallSuccessWebsocketMessage(message: LocalDevWebsocketMessage): boolean;
6
+ export declare function isAppInstallInitiatedWebsocketMessage(message: LocalDevWebsocketMessage): boolean;
7
+ export declare function isAppInstallFailureWebsocketMessage(message: LocalDevWebsocketMessage): boolean;
@@ -0,0 +1,19 @@
1
+ import { LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES } from '../../constants.js';
2
+ export function isUploadWebsocketMessage(message) {
3
+ return message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.UPLOAD;
4
+ }
5
+ export function isDeployWebsocketMessage(message) {
6
+ return message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.DEPLOY;
7
+ }
8
+ export function isViewedWelcomeScreenWebsocketMessage(message) {
9
+ return (message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.VIEWED_WELCOME_SCREEN);
10
+ }
11
+ export function isAppInstallSuccessWebsocketMessage(message) {
12
+ return (message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.APP_INSTALL_SUCCESS);
13
+ }
14
+ export function isAppInstallInitiatedWebsocketMessage(message) {
15
+ return (message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.APP_INSTALL_INITIATED);
16
+ }
17
+ export function isAppInstallFailureWebsocketMessage(message) {
18
+ return (message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.APP_INSTALL_FAILURE);
19
+ }
@@ -1 +1 @@
1
- export declare function useV3Api(platformVersion?: string | null): boolean;
1
+ export declare function isV2Project(platformVersion?: string | null): boolean;
@@ -1,4 +1,4 @@
1
- export function useV3Api(platformVersion) {
1
+ export function isV2Project(platformVersion) {
2
2
  if (!platformVersion || typeof platformVersion !== 'string') {
3
3
  return false;
4
4
  }
@@ -278,10 +278,10 @@ export async function displayWarnLogs(accountId, projectName, taskId, isDeploy =
278
278
  }
279
279
  }
280
280
  if (result && result.logs) {
281
- const logLength = result.logs.length;
282
- result.logs.forEach((log, i) => {
283
- uiLogger.warn(log.message);
284
- if (i < logLength - 1) {
281
+ const dedupedLogs = result.logs.reduce((acc, log) => acc.add(log.message), new Set());
282
+ Array.from(dedupedLogs).forEach((log, i) => {
283
+ uiLogger.warn(log);
284
+ if (i < dedupedLogs.size - 1) {
285
285
  uiLogger.log('');
286
286
  }
287
287
  });
@@ -1,14 +1,14 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { walk } from '@hubspot/local-dev-lib/fs';
4
- import { logger } from '@hubspot/local-dev-lib/logger';
4
+ import { uiLogger } from '../ui/logger.js';
5
5
  import { logError } from '../errorHandlers/index.js';
6
6
  import { ComponentTypes, } from '../../types/Projects.js';
7
- import { IR_COMPONENT_TYPES } from '../constants.js';
7
+ import { IR_COMPONENT_TYPES, LEGACY_PRIVATE_APP_FILE, LEGACY_PUBLIC_APP_FILE, THEME_FILE, } from '../constants.js';
8
8
  export const CONFIG_FILES = {
9
- [ComponentTypes.PrivateApp]: 'app.json',
10
- [ComponentTypes.PublicApp]: 'public-app.json',
11
- [ComponentTypes.HublTheme]: 'theme.json',
9
+ [ComponentTypes.PrivateApp]: LEGACY_PRIVATE_APP_FILE,
10
+ [ComponentTypes.PublicApp]: LEGACY_PUBLIC_APP_FILE,
11
+ [ComponentTypes.HublTheme]: THEME_FILE,
12
12
  };
13
13
  export function getComponentTypeFromConfigFile(configFile) {
14
14
  let key;
@@ -27,7 +27,7 @@ export function loadConfigFile(configPath) {
27
27
  return parsedConfig;
28
28
  }
29
29
  catch (e) {
30
- logger.debug(e);
30
+ uiLogger.debug(e);
31
31
  }
32
32
  }
33
33
  return null;
@@ -18,7 +18,7 @@ type HandleProjectUploadArg<T> = {
18
18
  profile?: string;
19
19
  };
20
20
  export declare function handleProjectUpload<T>({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage, forceCreate, isUploadCommand, sendIR, skipValidation, }: HandleProjectUploadArg<T>): Promise<ProjectUploadResult<T>>;
21
- export declare function validateSourceDirectory(srcDir: string, projectConfig: ProjectConfig): void;
21
+ export declare function validateSourceDirectory(srcDir: string, projectConfig: ProjectConfig, projectDir: string): Promise<void>;
22
22
  export declare function validateNoHSMetaMismatch(srcDir: string, projectConfig: ProjectConfig): Promise<void>;
23
23
  export declare function handleTranslate(projectDir: string, projectConfig: ProjectConfig, accountId: number, skipValidation: boolean, profile: string | undefined): Promise<unknown>;
24
24
  export {};
@@ -12,9 +12,11 @@ import util from 'node:util';
12
12
  import { lib } from '../../lang/en.js';
13
13
  import { ensureProjectExists } from './ensureProjectExists.js';
14
14
  import { uiLogger } from '../ui/logger.js';
15
- import { useV3Api } from './platformVersion.js';
15
+ import { isV2Project } from './platformVersion.js';
16
16
  import { EXIT_CODES } from '../enums/exitCodes.js';
17
17
  import ProjectValidationError from '../errors/ProjectValidationError.js';
18
+ import { walk } from '@hubspot/local-dev-lib/fs';
19
+ import { LEGACY_CONFIG_FILES } from '../constants.js';
18
20
  async function uploadProjectFiles(accountId, projectName, filePath, uploadMessage, platformVersion, intermediateRepresentation) {
19
21
  SpinniesManager.init({});
20
22
  const accountIdentifier = uiAccountDescription(accountId) || `${accountId}`;
@@ -45,7 +47,7 @@ async function uploadProjectFiles(accountId, projectName, filePath, uploadMessag
45
47
  export async function handleProjectUpload({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage = '', forceCreate = false, isUploadCommand = false, sendIR = false, skipValidation = false, }) {
46
48
  const srcDir = path.resolve(projectDir, projectConfig.srcDir);
47
49
  try {
48
- validateSourceDirectory(srcDir, projectConfig);
50
+ await validateSourceDirectory(srcDir, projectConfig, projectDir);
49
51
  }
50
52
  catch (e) {
51
53
  logError(e);
@@ -70,8 +72,7 @@ export async function handleProjectUpload({ accountId, projectConfig, projectDir
70
72
  intermediateRepresentation = await handleTranslate(projectDir, projectConfig, accountId, skipValidation, profile);
71
73
  }
72
74
  catch (e) {
73
- logError(e);
74
- process.exit(EXIT_CODES.ERROR);
75
+ resolve({ uploadError: e });
75
76
  }
76
77
  }
77
78
  await ensureProjectExists(accountId, projectConfig.name, {
@@ -105,15 +106,23 @@ export async function handleProjectUpload({ accountId, projectConfig, projectDir
105
106
  archive.finalize();
106
107
  return result;
107
108
  }
108
- export function validateSourceDirectory(srcDir, projectConfig) {
109
- const filenames = fs.readdirSync(srcDir);
110
- if (!filenames || filenames.length === 0) {
109
+ export async function validateSourceDirectory(srcDir, projectConfig, projectDir) {
110
+ const projectFilePaths = await walk(srcDir, ['node_modules']);
111
+ if (!projectFilePaths || projectFilePaths.length === 0) {
111
112
  throw new ProjectValidationError(lib.projectUpload.handleProjectUpload.emptySource(projectConfig.srcDir));
112
113
  }
114
+ if (isV2Project(projectConfig.platformVersion)) {
115
+ projectFilePaths.forEach(filePath => {
116
+ const filename = path.basename(filePath);
117
+ if (LEGACY_CONFIG_FILES.includes(filename)) {
118
+ uiLogger.warn(lib.projectUpload.handleProjectUpload.legacyFileDetected(path.relative(projectDir, filePath), projectConfig.platformVersion));
119
+ }
120
+ });
121
+ }
113
122
  }
114
123
  export async function validateNoHSMetaMismatch(srcDir, projectConfig) {
115
124
  const hasHsMetaFiles = await projectContainsHsMetaFiles(srcDir);
116
- if (!useV3Api(projectConfig.platformVersion) && hasHsMetaFiles) {
125
+ if (!isV2Project(projectConfig.platformVersion) && hasHsMetaFiles) {
117
126
  throw new ProjectValidationError(lib.projectUpload.wrongPlatformVersionMetaFiles);
118
127
  }
119
128
  }
@@ -7,4 +7,3 @@ export declare function getProjectBuildDetailUrl(projectName: string, buildId: n
7
7
  export declare function getProjectDeployDetailUrl(projectName: string, deployId: number, accountId: number): string;
8
8
  export declare function getLocalDevUiUrl(accountId: number, showWelcomeScreen?: boolean): string;
9
9
  export declare function getAccountHomeUrl(accountId: number): string;
10
- export declare function getAppAllowlistUrl(accountId: number, projectName: string, appUid: string): string;
@@ -41,6 +41,3 @@ export function getAccountHomeUrl(accountId) {
41
41
  const baseUrl = getHubSpotWebsiteOrigin(getEnv(accountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD);
42
42
  return `${baseUrl}/home?portalId=${accountId}`;
43
43
  }
44
- export function getAppAllowlistUrl(accountId, projectName, appUid) {
45
- return `${getProjectHomeUrl(accountId)}/project/${projectName}/component/${appUid}/distribution?panel=static-token-allowlist`;
46
- }
@@ -11,6 +11,7 @@ vi.mock('@hubspot/local-dev-lib/api/projects', () => ({
11
11
  }));
12
12
  vi.mock('@hubspot/local-dev-lib/config', () => ({
13
13
  getAccountId: vi.fn().mockImplementation(() => 123456789),
14
+ configFileExists: vi.fn().mockImplementation(() => true),
14
15
  }));
15
16
  describe('lib/prompts/downloadProjectPrompt', () => {
16
17
  it('should honor the account passed as an option', async () => {
@@ -1,5 +1,5 @@
1
1
  import { Separator } from '@inquirer/prompts';
2
- import { projectAddPromptV3 } from '../projectAddPrompt.js';
2
+ import { projectAddPromptV2 } from '../projectAddPrompt.js';
3
3
  import { promptUser } from '../promptUtils.js';
4
4
  vi.mock('../promptUtils');
5
5
  const mockedPromptUser = vi.mocked(promptUser);
@@ -19,7 +19,7 @@ describe('lib/prompts/projectAddPrompt', () => {
19
19
  supportedAuthTypes: ['oauth'],
20
20
  supportedDistributions: ['private'],
21
21
  };
22
- describe('projectAddPromptV3()', () => {
22
+ describe('projectAddPromptV2()', () => {
23
23
  beforeEach(() => {
24
24
  // Mock returns empty result, logic will use selectedComponents when selectedFeatures provided
25
25
  mockedPromptUser.mockResolvedValue({});
@@ -31,7 +31,7 @@ describe('lib/prompts/projectAddPrompt', () => {
31
31
  };
32
32
  const components = [templateChoice];
33
33
  const selectedFeatures = ['workflow-action-tool'];
34
- const result = await projectAddPromptV3(components, selectedFeatures);
34
+ const result = await projectAddPromptV2(components, selectedFeatures);
35
35
  expect(result.componentTemplate).toEqual([
36
36
  mockComponentTemplateWithCliSelector,
37
37
  ]);
@@ -49,7 +49,7 @@ describe('lib/prompts/projectAddPrompt', () => {
49
49
  };
50
50
  const components = [templateChoice];
51
51
  const selectedFeatures = ['module'];
52
- const result = await projectAddPromptV3(components, selectedFeatures);
52
+ const result = await projectAddPromptV2(components, selectedFeatures);
53
53
  expect(result.componentTemplate).toEqual([mockComponentTemplate]);
54
54
  expect(mockedPromptUser).toHaveBeenCalledWith([
55
55
  expect.objectContaining({
@@ -65,7 +65,7 @@ describe('lib/prompts/projectAddPrompt', () => {
65
65
  };
66
66
  const components = [templateChoice];
67
67
  const selectedFeatures = ['workflow-action-tool']; // matches cliSelector
68
- const result = await projectAddPromptV3(components, selectedFeatures);
68
+ const result = await projectAddPromptV2(components, selectedFeatures);
69
69
  expect(result.componentTemplate).toEqual([
70
70
  mockComponentTemplateWithCliSelector,
71
71
  ]);
@@ -78,7 +78,7 @@ describe('lib/prompts/projectAddPrompt', () => {
78
78
  const components = [templateChoice];
79
79
  const selectedFeatures = ['non-matching-feature'];
80
80
  mockedPromptUser.mockResolvedValue({ componentTemplate: [] });
81
- const result = await projectAddPromptV3(components, selectedFeatures);
81
+ const result = await projectAddPromptV2(components, selectedFeatures);
82
82
  expect(result.componentTemplate).toEqual([]);
83
83
  });
84
84
  it('should throw error when selected feature component is disabled', async () => {
@@ -89,7 +89,7 @@ describe('lib/prompts/projectAddPrompt', () => {
89
89
  };
90
90
  const components = [disabledTemplateChoice];
91
91
  const selectedFeatures = ['workflow-action-tool'];
92
- await expect(projectAddPromptV3(components, selectedFeatures)).rejects.toThrow(/Cannot.*feature.*workflow-action/);
92
+ await expect(projectAddPromptV2(components, selectedFeatures)).rejects.toThrow(/Cannot.*feature.*workflow-action/);
93
93
  });
94
94
  it('should handle multiple components with mixed cliSelector availability', async () => {
95
95
  const choice1 = {
@@ -102,7 +102,7 @@ describe('lib/prompts/projectAddPrompt', () => {
102
102
  };
103
103
  const components = [choice1, choice2];
104
104
  const selectedFeatures = ['module', 'workflow-action-tool'];
105
- const result = await projectAddPromptV3(components, selectedFeatures);
105
+ const result = await projectAddPromptV2(components, selectedFeatures);
106
106
  expect(result.componentTemplate).toEqual([
107
107
  mockComponentTemplate,
108
108
  mockComponentTemplateWithCliSelector,
@@ -116,7 +116,7 @@ describe('lib/prompts/projectAddPrompt', () => {
116
116
  };
117
117
  const components = [separator, templateChoice];
118
118
  const selectedFeatures = ['module'];
119
- const result = await projectAddPromptV3(components, selectedFeatures);
119
+ const result = await projectAddPromptV2(components, selectedFeatures);
120
120
  expect(result.componentTemplate).toEqual([mockComponentTemplate]);
121
121
  });
122
122
  it('should prompt user when no selectedFeatures provided', async () => {
@@ -129,7 +129,7 @@ describe('lib/prompts/projectAddPrompt', () => {
129
129
  mockedPromptUser.mockResolvedValue({
130
130
  componentTemplate: [mockComponentTemplate],
131
131
  });
132
- const result = await projectAddPromptV3(components, selectedFeatures);
132
+ const result = await projectAddPromptV2(components, selectedFeatures);
133
133
  expect(mockedPromptUser).toHaveBeenCalledWith([
134
134
  expect.objectContaining({
135
135
  name: 'componentTemplate',