@hubspot/cli 7.7.19-experimental.3 → 7.7.20-experimental.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/api/__tests__/migrate.test.d.ts +1 -0
  2. package/api/__tests__/migrate.test.js +183 -0
  3. package/commands/__tests__/account.test.d.ts +1 -0
  4. package/commands/__tests__/account.test.js +74 -0
  5. package/commands/__tests__/auth.test.d.ts +1 -0
  6. package/commands/__tests__/auth.test.js +43 -0
  7. package/commands/__tests__/cms.test.d.ts +1 -0
  8. package/commands/__tests__/cms.test.js +49 -0
  9. package/commands/__tests__/config.test.d.ts +1 -0
  10. package/commands/__tests__/config.test.js +49 -0
  11. package/commands/__tests__/create.test.d.ts +1 -0
  12. package/commands/__tests__/create.test.js +38 -0
  13. package/commands/__tests__/customObject.test.d.ts +1 -0
  14. package/commands/__tests__/customObject.test.js +54 -0
  15. package/commands/__tests__/doctor.test.d.ts +1 -0
  16. package/commands/__tests__/doctor.test.js +139 -0
  17. package/commands/__tests__/feedback.test.d.ts +1 -0
  18. package/commands/__tests__/feedback.test.js +62 -0
  19. package/commands/__tests__/fetch.test.d.ts +1 -0
  20. package/commands/__tests__/fetch.test.js +56 -0
  21. package/commands/__tests__/filemanager.test.d.ts +1 -0
  22. package/commands/__tests__/filemanager.test.js +50 -0
  23. package/commands/__tests__/function.test.d.ts +1 -0
  24. package/commands/__tests__/function.test.js +51 -0
  25. package/commands/__tests__/getStarted.test.d.ts +1 -0
  26. package/commands/__tests__/getStarted.test.js +170 -0
  27. package/commands/__tests__/hubdb.test.d.ts +1 -0
  28. package/commands/__tests__/hubdb.test.js +55 -0
  29. package/commands/__tests__/init.test.d.ts +1 -0
  30. package/commands/__tests__/init.test.js +47 -0
  31. package/commands/__tests__/lint.test.d.ts +1 -0
  32. package/commands/__tests__/lint.test.js +38 -0
  33. package/commands/__tests__/list.test.d.ts +1 -0
  34. package/commands/__tests__/list.test.js +47 -0
  35. package/commands/__tests__/logs.test.d.ts +1 -0
  36. package/commands/__tests__/logs.test.js +70 -0
  37. package/commands/__tests__/mcp.test.d.ts +1 -0
  38. package/commands/__tests__/mcp.test.js +51 -0
  39. package/commands/__tests__/mv.test.d.ts +1 -0
  40. package/commands/__tests__/mv.test.js +84 -0
  41. package/commands/__tests__/open.test.d.ts +1 -0
  42. package/commands/__tests__/open.test.js +96 -0
  43. package/commands/__tests__/project.test.d.ts +1 -0
  44. package/commands/__tests__/project.test.js +100 -0
  45. package/commands/__tests__/remove.test.d.ts +1 -0
  46. package/commands/__tests__/remove.test.js +77 -0
  47. package/commands/__tests__/sandbox.test.d.ts +1 -0
  48. package/commands/__tests__/sandbox.test.js +49 -0
  49. package/commands/__tests__/secret.test.d.ts +1 -0
  50. package/commands/__tests__/secret.test.js +54 -0
  51. package/commands/__tests__/testAccount.test.d.ts +1 -0
  52. package/commands/__tests__/testAccount.test.js +60 -0
  53. package/commands/__tests__/theme.test.d.ts +1 -0
  54. package/commands/__tests__/theme.test.js +52 -0
  55. package/commands/account/__tests__/auth.test.d.ts +1 -0
  56. package/commands/account/__tests__/auth.test.js +31 -0
  57. package/commands/account/__tests__/clean.test.d.ts +1 -0
  58. package/commands/account/__tests__/clean.test.js +33 -0
  59. package/commands/account/__tests__/createOverride.test.d.ts +1 -0
  60. package/commands/account/__tests__/createOverride.test.js +37 -0
  61. package/commands/account/__tests__/info.test.d.ts +1 -0
  62. package/commands/account/__tests__/info.test.js +33 -0
  63. package/commands/account/__tests__/list.test.d.ts +1 -0
  64. package/commands/account/__tests__/list.test.js +33 -0
  65. package/commands/account/__tests__/remove.test.d.ts +1 -0
  66. package/commands/account/__tests__/remove.test.js +41 -0
  67. package/commands/account/__tests__/removeOverride.d.ts +1 -0
  68. package/commands/account/__tests__/removeOverride.js +30 -0
  69. package/commands/account/__tests__/rename.test.d.ts +1 -0
  70. package/commands/account/__tests__/rename.test.js +47 -0
  71. package/commands/account/__tests__/use.test.d.ts +1 -0
  72. package/commands/account/__tests__/use.test.js +37 -0
  73. package/commands/app/__tests__/migrate.test.d.ts +1 -0
  74. package/commands/app/__tests__/migrate.test.js +129 -0
  75. package/commands/app/secret/__tests__/add.test.d.ts +1 -0
  76. package/commands/app/secret/__tests__/add.test.js +33 -0
  77. package/commands/app/secret/__tests__/delete.test.d.ts +1 -0
  78. package/commands/app/secret/__tests__/delete.test.js +33 -0
  79. package/commands/app/secret/__tests__/list.test.d.ts +1 -0
  80. package/commands/app/secret/__tests__/list.test.js +30 -0
  81. package/commands/app/secret/__tests__/update.test.d.ts +1 -0
  82. package/commands/app/secret/__tests__/update.test.js +33 -0
  83. package/commands/app.js +1 -6
  84. package/commands/customObject/__tests__/create.test.d.ts +1 -0
  85. package/commands/customObject/__tests__/create.test.js +45 -0
  86. package/commands/customObject/__tests__/schema.test.d.ts +1 -0
  87. package/commands/customObject/__tests__/schema.test.js +58 -0
  88. package/commands/customObject/schema/__tests__/create.test.d.ts +1 -0
  89. package/commands/customObject/schema/__tests__/create.test.js +33 -0
  90. package/commands/customObject/schema/__tests__/delete.test.d.ts +1 -0
  91. package/commands/customObject/schema/__tests__/delete.test.js +47 -0
  92. package/commands/customObject/schema/__tests__/fetch-all.test.d.ts +1 -0
  93. package/commands/customObject/schema/__tests__/fetch-all.test.js +46 -0
  94. package/commands/customObject/schema/__tests__/fetch.test.d.ts +1 -0
  95. package/commands/customObject/schema/__tests__/fetch.test.js +50 -0
  96. package/commands/customObject/schema/__tests__/list.test.d.ts +1 -0
  97. package/commands/customObject/schema/__tests__/list.test.js +34 -0
  98. package/commands/customObject/schema/__tests__/update.test.d.ts +1 -0
  99. package/commands/customObject/schema/__tests__/update.test.js +45 -0
  100. package/commands/fetch.js +0 -1
  101. package/commands/filemanager/__tests__/fetch.test.d.ts +1 -0
  102. package/commands/filemanager/__tests__/fetch.test.js +37 -0
  103. package/commands/filemanager/__tests__/upload.test.d.ts +1 -0
  104. package/commands/filemanager/__tests__/upload.test.js +35 -0
  105. package/commands/hubdb/__tests__/clear.test.d.ts +1 -0
  106. package/commands/hubdb/__tests__/clear.test.js +33 -0
  107. package/commands/hubdb/__tests__/create.test.d.ts +1 -0
  108. package/commands/hubdb/__tests__/create.test.js +33 -0
  109. package/commands/hubdb/__tests__/delete.test.d.ts +1 -0
  110. package/commands/hubdb/__tests__/delete.test.js +33 -0
  111. package/commands/hubdb/__tests__/fetch.test.d.ts +1 -0
  112. package/commands/hubdb/__tests__/fetch.test.js +33 -0
  113. package/commands/hubdb/__tests__/list.test.d.ts +1 -0
  114. package/commands/hubdb/__tests__/list.test.js +101 -0
  115. package/commands/logs.js +0 -1
  116. package/commands/mcp/__tests__/setup.test.d.ts +1 -0
  117. package/commands/mcp/__tests__/setup.test.js +31 -0
  118. package/commands/mcp/__tests__/start.test.d.ts +1 -0
  119. package/commands/mcp/__tests__/start.test.js +32 -0
  120. package/commands/project/__tests__/add.test.d.ts +1 -0
  121. package/commands/project/__tests__/add.test.js +48 -0
  122. package/commands/project/__tests__/create.test.d.ts +1 -0
  123. package/commands/project/__tests__/create.test.js +45 -0
  124. package/commands/project/__tests__/deploy.test.d.ts +1 -0
  125. package/commands/project/__tests__/deploy.test.js +344 -0
  126. package/commands/project/__tests__/devUnifiedFlow.test.d.ts +1 -0
  127. package/commands/project/__tests__/devUnifiedFlow.test.js +419 -0
  128. package/commands/project/__tests__/download.test.d.ts +1 -0
  129. package/commands/project/__tests__/download.test.js +44 -0
  130. package/commands/project/__tests__/fixtures/exampleProject.json +33 -0
  131. package/commands/project/__tests__/installDeps.test.d.ts +1 -0
  132. package/commands/project/__tests__/installDeps.test.js +180 -0
  133. package/commands/project/__tests__/listBuilds.test.d.ts +1 -0
  134. package/commands/project/__tests__/listBuilds.test.js +43 -0
  135. package/commands/project/__tests__/logs.test.d.ts +1 -0
  136. package/commands/project/__tests__/logs.test.js +246 -0
  137. package/commands/project/__tests__/migrate.test.d.ts +1 -0
  138. package/commands/project/__tests__/migrate.test.js +116 -0
  139. package/commands/project/__tests__/migrateApp.test.d.ts +1 -0
  140. package/commands/project/__tests__/migrateApp.test.js +87 -0
  141. package/commands/project/__tests__/open.test.d.ts +1 -0
  142. package/commands/project/__tests__/open.test.js +44 -0
  143. package/commands/project/__tests__/profile.test.d.ts +1 -0
  144. package/commands/project/__tests__/profile.test.js +47 -0
  145. package/commands/project/__tests__/upload.test.d.ts +1 -0
  146. package/commands/project/__tests__/upload.test.js +48 -0
  147. package/commands/project/__tests__/watch.test.d.ts +1 -0
  148. package/commands/project/__tests__/watch.test.js +40 -0
  149. package/commands/project/dev/unifiedFlow.js +1 -1
  150. package/commands/sandbox/__tests__/create.test.d.ts +1 -0
  151. package/commands/sandbox/__tests__/create.test.js +36 -0
  152. package/commands/sandbox/__tests__/delete.test.d.ts +1 -0
  153. package/commands/sandbox/__tests__/delete.test.js +36 -0
  154. package/commands/secret/__tests__/addSecret.test.d.ts +1 -0
  155. package/commands/secret/__tests__/addSecret.test.js +34 -0
  156. package/commands/secret/__tests__/deleteSecret.test.d.ts +1 -0
  157. package/commands/secret/__tests__/deleteSecret.test.js +46 -0
  158. package/commands/secret/__tests__/listSecret.test.d.ts +1 -0
  159. package/commands/secret/__tests__/listSecret.test.js +34 -0
  160. package/commands/secret/__tests__/updateSecret.test.d.ts +1 -0
  161. package/commands/secret/__tests__/updateSecret.test.js +34 -0
  162. package/commands/testAccount/__tests__/create.test.d.ts +1 -0
  163. package/commands/testAccount/__tests__/create.test.js +38 -0
  164. package/commands/testAccount/__tests__/createConfig.test.d.ts +1 -0
  165. package/commands/testAccount/__tests__/createConfig.test.js +40 -0
  166. package/commands/testAccount/__tests__/delete.test.d.ts +1 -0
  167. package/commands/testAccount/__tests__/delete.test.js +36 -0
  168. package/commands/testAccount/create.js +24 -14
  169. package/commands/theme/__tests__/generate-selectors.test.d.ts +1 -0
  170. package/commands/theme/__tests__/generate-selectors.test.js +33 -0
  171. package/commands/theme/__tests__/marketplace-validate.test.d.ts +1 -0
  172. package/commands/theme/__tests__/marketplace-validate.test.js +41 -0
  173. package/commands/theme/__tests__/preview.test.d.ts +1 -0
  174. package/commands/theme/__tests__/preview.test.js +65 -0
  175. package/lang/en.d.ts +6 -65
  176. package/lang/en.js +6 -65
  177. package/lib/__tests__/accountTypes.test.d.ts +1 -0
  178. package/lib/__tests__/accountTypes.test.js +100 -0
  179. package/lib/__tests__/buildAccount.test.d.ts +1 -0
  180. package/lib/__tests__/buildAccount.test.js +231 -0
  181. package/lib/__tests__/commonOpts.test.d.ts +1 -0
  182. package/lib/__tests__/commonOpts.test.js +87 -0
  183. package/lib/__tests__/dependencyManagement.test.d.ts +1 -0
  184. package/lib/__tests__/dependencyManagement.test.js +180 -0
  185. package/lib/__tests__/developerTestAccounts.test.d.ts +1 -0
  186. package/lib/__tests__/developerTestAccounts.test.js +180 -0
  187. package/lib/__tests__/hasFeature.test.d.ts +1 -0
  188. package/lib/__tests__/hasFeature.test.js +37 -0
  189. package/lib/__tests__/npm.test.d.ts +1 -0
  190. package/lib/__tests__/npm.test.js +62 -0
  191. package/lib/__tests__/oauth.test.d.ts +1 -0
  192. package/lib/__tests__/oauth.test.js +113 -0
  193. package/lib/__tests__/parsing.test.d.ts +1 -0
  194. package/lib/__tests__/parsing.test.js +36 -0
  195. package/lib/__tests__/polling.test.d.ts +1 -0
  196. package/lib/__tests__/polling.test.js +78 -0
  197. package/lib/__tests__/process.test.d.ts +1 -0
  198. package/lib/__tests__/process.test.js +90 -0
  199. package/lib/__tests__/projectProfiles.test.d.ts +1 -0
  200. package/lib/__tests__/projectProfiles.test.js +134 -0
  201. package/lib/__tests__/sandboxSync.test.d.ts +1 -0
  202. package/lib/__tests__/sandboxSync.test.js +131 -0
  203. package/lib/__tests__/sandboxes.test.d.ts +1 -0
  204. package/lib/__tests__/sandboxes.test.js +148 -0
  205. package/lib/__tests__/serverlessLogs.test.d.ts +1 -0
  206. package/lib/__tests__/serverlessLogs.test.js +154 -0
  207. package/lib/__tests__/usageTracking.test.d.ts +1 -0
  208. package/lib/__tests__/usageTracking.test.js +171 -0
  209. package/lib/__tests__/validation.test.d.ts +1 -0
  210. package/lib/__tests__/validation.test.js +145 -0
  211. package/lib/__tests__/yargsUtils.test.d.ts +1 -0
  212. package/lib/__tests__/yargsUtils.test.js +74 -0
  213. package/lib/app/__tests__/migrate.test.d.ts +1 -0
  214. package/lib/app/__tests__/migrate.test.js +495 -0
  215. package/lib/app/__tests__/migrate_legacy.test.d.ts +1 -0
  216. package/lib/app/__tests__/migrate_legacy.test.js +136 -0
  217. package/lib/buildAccount.d.ts +1 -7
  218. package/lib/buildAccount.js +4 -54
  219. package/lib/doctor/Diagnosis.js +11 -11
  220. package/lib/doctor/Doctor.js +42 -42
  221. package/lib/doctor/__tests__/Diagnosis.test.d.ts +1 -0
  222. package/lib/doctor/__tests__/Diagnosis.test.js +87 -0
  223. package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.d.ts +1 -0
  224. package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.js +172 -0
  225. package/lib/doctor/__tests__/Doctor.test.d.ts +1 -0
  226. package/lib/doctor/__tests__/Doctor.test.js +398 -0
  227. package/lib/mcp/setup.js +18 -2
  228. package/lib/middleware/__test__/configMiddleware.test.js +12 -12
  229. package/lib/middleware/__test__/gitMiddleware.test.js +4 -4
  230. package/lib/middleware/__test__/notificationsMiddleware.test.js +2 -2
  231. package/lib/middleware/__test__/requestMiddleware.test.js +2 -2
  232. package/lib/middleware/__test__/yargsChecksMiddleware.test.js +7 -7
  233. package/lib/middleware/notificationsMiddleware.js +16 -13
  234. package/lib/projects/__tests__/AppDevModeInterface.test.d.ts +1 -0
  235. package/lib/projects/__tests__/AppDevModeInterface.test.js +517 -0
  236. package/lib/projects/__tests__/LocalDevProcess.test.d.ts +1 -0
  237. package/lib/projects/__tests__/LocalDevProcess.test.js +314 -0
  238. package/lib/projects/__tests__/LocalDevWebsocketServer.test.d.ts +1 -0
  239. package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +175 -0
  240. package/lib/projects/__tests__/ProjectLogsManager.test.d.ts +1 -0
  241. package/lib/projects/__tests__/ProjectLogsManager.test.js +191 -0
  242. package/lib/projects/__tests__/buildAndDeploy.test.d.ts +1 -0
  243. package/lib/projects/__tests__/buildAndDeploy.test.js +25 -0
  244. package/lib/projects/__tests__/components.test.d.ts +1 -0
  245. package/lib/projects/__tests__/components.test.js +186 -0
  246. package/lib/projects/__tests__/projects.test.d.ts +1 -0
  247. package/lib/projects/__tests__/projects.test.js +89 -0
  248. package/lib/projects/__tests__/structure.test.d.ts +1 -0
  249. package/lib/projects/__tests__/structure.test.js +249 -0
  250. package/lib/projects/add/__tests__/legacyAddComponent.test.d.ts +1 -0
  251. package/lib/projects/add/__tests__/legacyAddComponent.test.js +206 -0
  252. package/lib/projects/add/__tests__/v3AddComponent.test.d.ts +1 -0
  253. package/lib/projects/add/__tests__/v3AddComponent.test.js +190 -0
  254. package/lib/projects/create/__tests__/legacy.test.d.ts +1 -0
  255. package/lib/projects/create/__tests__/legacy.test.js +126 -0
  256. package/lib/projects/create/__tests__/v3.test.d.ts +1 -0
  257. package/lib/projects/create/__tests__/v3.test.js +80 -0
  258. package/lib/projects/localDev/DevServerManager.js +0 -1
  259. package/lib/projects/localDev/helpers.d.ts +1 -1
  260. package/lib/projects/localDev/helpers.js +2 -2
  261. package/lib/projects/structure.d.ts +2 -2
  262. package/lib/projects/upload.d.ts +1 -2
  263. package/lib/projects/upload.js +0 -1
  264. package/lib/prompts/__tests__/downloadProjectPrompt.test.d.ts +1 -0
  265. package/lib/prompts/__tests__/downloadProjectPrompt.test.js +30 -0
  266. package/lib/prompts/__tests__/projectsLogsPrompt.test.d.ts +1 -0
  267. package/lib/prompts/__tests__/projectsLogsPrompt.test.js +42 -0
  268. package/lib/prompts/createDeveloperTestAccountConfigPrompt.d.ts +10 -9
  269. package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +43 -81
  270. package/lib/schema.js +5 -1
  271. package/lib/ui/SpinniesManager.js +0 -1
  272. package/lib/ui/supportHyperlinks.js +2 -2
  273. package/lib/ui/supportsColor.js +2 -2
  274. package/lib/utils/hasFlag.d.ts +1 -0
  275. package/lib/utils/hasFlag.js +15 -0
  276. package/lib/yargsUtils.d.ts +2 -1
  277. package/lib/yargsUtils.js +3 -13
  278. package/mcp-server/tools/project/__tests__/AddFeatureToProject.test.d.ts +1 -0
  279. package/mcp-server/tools/project/__tests__/AddFeatureToProject.test.js +152 -0
  280. package/mcp-server/tools/project/__tests__/CreateProjectTool.test.d.ts +1 -0
  281. package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +129 -0
  282. package/mcp-server/tools/project/__tests__/DeployProject.test.d.ts +1 -0
  283. package/mcp-server/tools/project/__tests__/DeployProject.test.js +120 -0
  284. package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.d.ts +1 -0
  285. package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +127 -0
  286. package/mcp-server/tools/project/__tests__/UploadProjectTools.test.d.ts +1 -0
  287. package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +108 -0
  288. package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.d.ts +1 -0
  289. package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +111 -0
  290. package/mcp-server/utils/__tests__/command.test.d.ts +1 -0
  291. package/mcp-server/utils/__tests__/command.test.js +47 -0
  292. package/mcp-server/utils/__tests__/project.test.d.ts +1 -0
  293. package/mcp-server/utils/__tests__/project.test.js +81 -0
  294. package/package.json +8 -8
  295. package/commands/app/install.d.ts +0 -8
  296. package/commands/app/install.js +0 -127
@@ -0,0 +1,314 @@
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 path_1 = __importDefault(require("path"));
7
+ const project_parsing_lib_1 = require("@hubspot/project-parsing-lib");
8
+ const upload_1 = require("../upload");
9
+ const config_1 = require("../config");
10
+ const LocalDevProcess_1 = __importDefault(require("../localDev/LocalDevProcess"));
11
+ const LocalDevLogger_1 = __importDefault(require("../localDev/LocalDevLogger"));
12
+ const DevServerManagerV2_1 = __importDefault(require("../localDev/DevServerManagerV2"));
13
+ const environments_1 = require("@hubspot/local-dev-lib/constants/environments");
14
+ const vitest_1 = require("vitest");
15
+ // Mock @hubspot/ui-extensions-dev-server
16
+ vitest_1.vi.mock('@hubspot/ui-extensions-dev-server', () => ({
17
+ DevModeUnifiedInterface: {
18
+ setup: vitest_1.vi.fn().mockResolvedValue(undefined),
19
+ start: vitest_1.vi.fn().mockResolvedValue(undefined),
20
+ fileChange: vitest_1.vi.fn().mockResolvedValue(undefined),
21
+ cleanup: vitest_1.vi.fn().mockResolvedValue(undefined),
22
+ },
23
+ }));
24
+ vitest_1.vi.mock('@hubspot/project-parsing-lib');
25
+ vitest_1.vi.mock('../upload');
26
+ vitest_1.vi.mock('../config');
27
+ vitest_1.vi.mock('../localDev/LocalDevLogger');
28
+ vitest_1.vi.mock('../localDev/DevServerManagerV2');
29
+ // Tests for LocalDevProcess and LocalDevState
30
+ describe('LocalDevProcess', () => {
31
+ let mockLocalDevLogger;
32
+ let mockDevServerManager;
33
+ let process;
34
+ const mockProjectConfig = {
35
+ name: 'test-project',
36
+ srcDir: 'src',
37
+ platformVersion: '1.0.0',
38
+ };
39
+ const mockSubbuildStatus = {
40
+ buildName: 'component1',
41
+ buildType: 'APP',
42
+ errorMessage: '',
43
+ finishedAt: new Date().toISOString(),
44
+ rootPath: '/test/path',
45
+ startedAt: new Date().toISOString(),
46
+ status: 'SUCCESS',
47
+ id: '123',
48
+ standardError: null,
49
+ visible: true,
50
+ };
51
+ const mockBuild = {
52
+ activitySource: { type: 'HUBSPOT' },
53
+ projectName: 'test-project',
54
+ uploadMessage: 'test-upload-message',
55
+ autoDeployId: 123,
56
+ buildId: 123,
57
+ createdAt: new Date().toISOString(),
58
+ deployableState: 'DEPLOYED',
59
+ finishedAt: new Date().toISOString(),
60
+ startedAt: new Date().toISOString(),
61
+ status: 'SUCCESS',
62
+ subbuildStatuses: [
63
+ { ...mockSubbuildStatus, buildName: 'component1' },
64
+ { ...mockSubbuildStatus, buildName: 'component2' },
65
+ ],
66
+ deployStatusTaskLocator: {
67
+ id: '123',
68
+ links: [],
69
+ },
70
+ enqueuedAt: new Date().toISOString(),
71
+ isAutoDeployEnabled: false,
72
+ portalId: 123,
73
+ };
74
+ const mockOptions = {
75
+ projectDir: '/test/project',
76
+ projectConfig: mockProjectConfig,
77
+ targetProjectAccountId: 123,
78
+ targetTestingAccountId: 456,
79
+ projectId: 789,
80
+ isGithubLinked: false,
81
+ initialProjectNodes: {},
82
+ env: environments_1.ENVIRONMENTS.PROD,
83
+ deployedBuild: mockBuild,
84
+ projectName: 'test-project',
85
+ };
86
+ beforeEach(() => {
87
+ vitest_1.vi.clearAllMocks();
88
+ mockLocalDevLogger = {
89
+ resetSpinnies: vitest_1.vi.fn(),
90
+ devServerSetupError: vitest_1.vi.fn(),
91
+ devServerStartError: vitest_1.vi.fn(),
92
+ devServerCleanupError: vitest_1.vi.fn(),
93
+ missingComponentsWarning: vitest_1.vi.fn(),
94
+ noDeployedBuild: vitest_1.vi.fn(),
95
+ startupMessage: vitest_1.vi.fn(),
96
+ monitorConsoleOutput: vitest_1.vi.fn(),
97
+ cleanupStart: vitest_1.vi.fn(),
98
+ cleanupError: vitest_1.vi.fn(),
99
+ cleanupSuccess: vitest_1.vi.fn(),
100
+ uploadInitiated: vitest_1.vi.fn(),
101
+ projectConfigMismatch: vitest_1.vi.fn(),
102
+ uploadError: vitest_1.vi.fn(),
103
+ uploadSuccess: vitest_1.vi.fn(),
104
+ clearUploadWarnings: vitest_1.vi.fn(),
105
+ fileChangeError: vitest_1.vi.fn(),
106
+ uploadWarning: vitest_1.vi.fn(),
107
+ };
108
+ mockDevServerManager = {
109
+ setup: vitest_1.vi.fn().mockResolvedValue(undefined),
110
+ start: vitest_1.vi.fn().mockResolvedValue(undefined),
111
+ cleanup: vitest_1.vi.fn().mockResolvedValue(undefined),
112
+ fileChange: vitest_1.vi.fn().mockResolvedValue(undefined),
113
+ };
114
+ // Mock constructors
115
+ LocalDevLogger_1.default.mockImplementation(() => mockLocalDevLogger);
116
+ DevServerManagerV2_1.default.mockImplementation(() => mockDevServerManager);
117
+ // Create process instance
118
+ process = new LocalDevProcess_1.default(mockOptions);
119
+ // Mock process.exit
120
+ vitest_1.vi.spyOn(global.process, 'exit').mockImplementation((code) => {
121
+ throw new Error(`Process.exit called with code ${code}`);
122
+ });
123
+ });
124
+ describe('start()', () => {
125
+ it('should exit if no deployed build exists', async () => {
126
+ const processWithoutBuild = new LocalDevProcess_1.default({
127
+ ...mockOptions,
128
+ deployedBuild: undefined,
129
+ });
130
+ await expect(processWithoutBuild.start()).rejects.toThrow('Process.exit called with code 0');
131
+ expect(mockLocalDevLogger.noDeployedBuild).toHaveBeenCalled();
132
+ });
133
+ it('should exit if dev server setup fails', async () => {
134
+ mockDevServerManager.setup.mockRejectedValue(new Error('Setup failed'));
135
+ await expect(process.start()).rejects.toThrow('Process.exit called with code 1');
136
+ expect(mockLocalDevLogger.devServerSetupError).toHaveBeenCalled();
137
+ });
138
+ it('should start successfully and compare project nodes', async () => {
139
+ await process.start();
140
+ expect(mockLocalDevLogger.startupMessage).toHaveBeenCalled();
141
+ expect(mockDevServerManager.start).toHaveBeenCalled();
142
+ expect(mockLocalDevLogger.monitorConsoleOutput).toHaveBeenCalled();
143
+ expect(mockLocalDevLogger.missingComponentsWarning).not.toHaveBeenCalled();
144
+ });
145
+ it('should warn about missing components', async () => {
146
+ const mockNode = {
147
+ uid: 'component3',
148
+ componentType: 'APP',
149
+ localDev: {
150
+ componentRoot: '/test/path',
151
+ componentConfigPath: '/test/path/config.json',
152
+ configUpdatedSinceLastUpload: false,
153
+ },
154
+ componentDeps: {},
155
+ metaFilePath: '/test/path',
156
+ config: {},
157
+ files: [],
158
+ };
159
+ const processWithNode = new LocalDevProcess_1.default({
160
+ ...mockOptions,
161
+ initialProjectNodes: {
162
+ component3: mockNode,
163
+ },
164
+ });
165
+ await processWithNode.start();
166
+ expect(mockLocalDevLogger.missingComponentsWarning).toHaveBeenCalledWith([
167
+ '[App] component3',
168
+ ]);
169
+ });
170
+ });
171
+ describe('stop()', () => {
172
+ it('should exit with error if cleanup fails', async () => {
173
+ mockDevServerManager.cleanup.mockRejectedValue(new Error('Cleanup failed'));
174
+ await expect(process.stop()).rejects.toThrow('Process.exit called with code 1');
175
+ expect(mockLocalDevLogger.cleanupError).toHaveBeenCalled();
176
+ });
177
+ it('should exit successfully after cleanup', async () => {
178
+ await expect(process.stop()).rejects.toThrow('Process.exit called with code 0');
179
+ expect(mockLocalDevLogger.cleanupSuccess).toHaveBeenCalled();
180
+ });
181
+ it('should not show progress messages when showProgress is false', async () => {
182
+ await expect(process.stop(false)).rejects.toThrow('Process.exit called with code 0');
183
+ expect(mockLocalDevLogger.cleanupStart).not.toHaveBeenCalled();
184
+ expect(mockLocalDevLogger.cleanupSuccess).not.toHaveBeenCalled();
185
+ });
186
+ });
187
+ describe('updateProjectNodes()', () => {
188
+ it('should update project nodes with translated representation', async () => {
189
+ const mockNodes = { node1: { uid: 'node1' } };
190
+ project_parsing_lib_1.translateForLocalDev.mockResolvedValue({
191
+ intermediateNodesIndexedByUid: mockNodes,
192
+ });
193
+ // @ts-expect-error testing private method
194
+ await process.updateProjectNodes();
195
+ expect(project_parsing_lib_1.translateForLocalDev).toHaveBeenCalledWith({
196
+ projectSourceDir: path_1.default.join(mockOptions.projectDir, mockOptions.projectConfig.srcDir),
197
+ platformVersion: mockOptions.projectConfig.platformVersion,
198
+ accountId: mockOptions.targetProjectAccountId,
199
+ }, { projectNodesAtLastUpload: {} });
200
+ expect(process.projectNodes).toEqual(mockNodes);
201
+ });
202
+ });
203
+ describe('uploadProject()', () => {
204
+ it('should not upload if project config is invalid', async () => {
205
+ config_1.getProjectConfig.mockResolvedValue({
206
+ projectConfig: null,
207
+ });
208
+ await process.uploadProject();
209
+ expect(mockLocalDevLogger.projectConfigMismatch).toHaveBeenCalled();
210
+ expect(upload_1.handleProjectUpload).not.toHaveBeenCalled();
211
+ });
212
+ it('should handle upload error', async () => {
213
+ config_1.getProjectConfig.mockResolvedValue({
214
+ projectConfig: mockOptions.projectConfig,
215
+ });
216
+ upload_1.handleProjectUpload.mockResolvedValue({
217
+ uploadError: new Error('Upload failed'),
218
+ });
219
+ const success = await process.uploadProject();
220
+ expect(mockLocalDevLogger.uploadError).toHaveBeenCalledWith(new Error('Upload failed'));
221
+ expect(success).toBe(false);
222
+ });
223
+ it('should handle successful upload', async () => {
224
+ await process.handleConfigFileChange();
225
+ config_1.getProjectConfig.mockResolvedValue({
226
+ projectConfig: mockOptions.projectConfig,
227
+ });
228
+ upload_1.handleProjectUpload.mockResolvedValue({
229
+ uploadError: null,
230
+ });
231
+ const success = await process.uploadProject();
232
+ expect(mockLocalDevLogger.uploadSuccess).toHaveBeenCalled();
233
+ expect(mockLocalDevLogger.clearUploadWarnings).toHaveBeenCalled();
234
+ expect(success).toBe(true);
235
+ });
236
+ it('should reset projectNodesAtLastUpload', async () => {
237
+ const mockNodes = { node1: { uid: 'node1' } };
238
+ const initialProjectNodes = { existingNode: { uid: 'existingNode' } };
239
+ // @ts-expect-error accessing private property for testing
240
+ process.state._projectNodesAtLastUpload = initialProjectNodes;
241
+ config_1.getProjectConfig.mockResolvedValue({
242
+ projectConfig: mockOptions.projectConfig,
243
+ });
244
+ upload_1.handleProjectUpload.mockResolvedValue({
245
+ uploadError: null,
246
+ });
247
+ project_parsing_lib_1.translateForLocalDev.mockResolvedValue({
248
+ intermediateNodesIndexedByUid: mockNodes,
249
+ });
250
+ const success = await process.uploadProject();
251
+ // Verify translateForLocalDev was called without projectNodesAtLastUpload option
252
+ expect(project_parsing_lib_1.translateForLocalDev).toHaveBeenCalledWith({
253
+ projectSourceDir: path_1.default.join(mockOptions.projectDir, mockOptions.projectConfig.srcDir),
254
+ platformVersion: mockOptions.projectConfig.platformVersion,
255
+ accountId: mockOptions.targetProjectAccountId,
256
+ }, { projectNodesAtLastUpload: undefined });
257
+ // Verify projectNodesAtLastUpload was reset to the new nodes
258
+ // @ts-expect-error accessing private property for testing
259
+ expect(process.state.projectNodesAtLastUpload).toEqual(mockNodes);
260
+ expect(success).toBe(true);
261
+ });
262
+ });
263
+ describe('handleFileChange()', () => {
264
+ it('should handle file change successfully', async () => {
265
+ const filePath = 'test/file.js';
266
+ const event = 'change';
267
+ await process.handleFileChange(filePath, event);
268
+ expect(mockDevServerManager.fileChange).toHaveBeenCalledWith({
269
+ filePath,
270
+ event,
271
+ });
272
+ });
273
+ it('should log error if file change fails', async () => {
274
+ const error = new Error('File change failed');
275
+ mockDevServerManager.fileChange.mockImplementation(() => {
276
+ throw error;
277
+ });
278
+ await process.handleFileChange('test/file.js', 'change');
279
+ expect(mockLocalDevLogger.fileChangeError).toHaveBeenCalledWith(error);
280
+ });
281
+ });
282
+ describe('handleConfigFileChange()', () => {
283
+ beforeEach(() => {
284
+ project_parsing_lib_1.translateForLocalDev.mockResolvedValue({
285
+ intermediateNodesIndexedByUid: {},
286
+ });
287
+ });
288
+ it('should update project nodes and show upload warning', async () => {
289
+ await process.handleConfigFileChange();
290
+ expect(project_parsing_lib_1.translateForLocalDev).toHaveBeenCalledWith({
291
+ projectSourceDir: path_1.default.join(mockOptions.projectDir, mockOptions.projectConfig.srcDir),
292
+ platformVersion: mockOptions.projectConfig.platformVersion,
293
+ accountId: mockOptions.targetProjectAccountId,
294
+ }, { projectNodesAtLastUpload: {} });
295
+ expect(mockLocalDevLogger.uploadWarning).toHaveBeenCalled();
296
+ });
297
+ });
298
+ describe('addStateListener()', () => {
299
+ it('should add state listener', () => {
300
+ const listener = vitest_1.vi.fn();
301
+ const key = 'projectNodes';
302
+ process.addStateListener(key, listener);
303
+ // @ts-expect-error
304
+ process.state.projectNodes = {};
305
+ expect(listener).toHaveBeenCalled();
306
+ });
307
+ it('should call listener immediately when callOnInit is true', () => {
308
+ const listener = vitest_1.vi.fn();
309
+ const key = 'projectNodes';
310
+ process.addStateListener(key, listener, true);
311
+ expect(listener).toHaveBeenCalledWith(process.projectNodes);
312
+ });
313
+ });
314
+ });
@@ -0,0 +1,175 @@
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 ws_1 = require("ws");
7
+ const portManager_1 = require("@hubspot/local-dev-lib/portManager");
8
+ const logger_1 = require("@hubspot/local-dev-lib/logger");
9
+ const constants_1 = require("../../constants");
10
+ const LocalDevWebsocketServer_1 = __importDefault(require("../localDev/LocalDevWebsocketServer"));
11
+ const en_1 = require("../../../lang/en");
12
+ vi.mock('ws');
13
+ vi.mock('@hubspot/local-dev-lib/portManager');
14
+ vi.mock('@hubspot/local-dev-lib/logger');
15
+ describe('LocalDevWebsocketServer', () => {
16
+ let mockLocalDevProcess;
17
+ let mockWebSocket;
18
+ let mockWebSocketServer;
19
+ let server;
20
+ beforeEach(() => {
21
+ // Reset all mocks
22
+ vi.clearAllMocks();
23
+ // Setup mock WebSocket
24
+ mockWebSocket = {
25
+ on: vi.fn(),
26
+ send: vi.fn(),
27
+ close: vi.fn(),
28
+ };
29
+ // Setup mock WebSocketServer
30
+ mockWebSocketServer = {
31
+ on: vi.fn(),
32
+ close: vi.fn(),
33
+ };
34
+ // Setup mock LocalDevProcess
35
+ mockLocalDevProcess = {
36
+ addStateListener: vi.fn(),
37
+ uploadProject: vi.fn(),
38
+ sendDevServerMessage: vi.fn(),
39
+ };
40
+ // Mock WebSocketServer constructor
41
+ ws_1.WebSocketServer.mockImplementation(() => mockWebSocketServer);
42
+ // Create server instance
43
+ server = new LocalDevWebsocketServer_1.default(mockLocalDevProcess, true);
44
+ });
45
+ describe('start()', () => {
46
+ it('should throw error if port manager is not running', async () => {
47
+ portManager_1.isPortManagerServerRunning.mockResolvedValue(false);
48
+ await expect(server.start()).rejects.toThrow();
49
+ });
50
+ it('should start websocket server successfully', async () => {
51
+ portManager_1.isPortManagerServerRunning.mockResolvedValue(true);
52
+ portManager_1.requestPorts.mockResolvedValue({
53
+ 'local-dev-ui-websocket-server': 1234,
54
+ });
55
+ await server.start();
56
+ expect(ws_1.WebSocketServer).toHaveBeenCalledWith({ port: 1234 });
57
+ expect(mockWebSocketServer.on).toHaveBeenCalledWith('connection', expect.any(Function));
58
+ expect(logger_1.logger.log).toHaveBeenCalled();
59
+ });
60
+ it('should accept connection from valid origin', async () => {
61
+ portManager_1.isPortManagerServerRunning.mockResolvedValue(true);
62
+ portManager_1.requestPorts.mockResolvedValue({
63
+ 'local-dev-ui-websocket-server': 1234,
64
+ });
65
+ await server.start();
66
+ // Get the connection callback
67
+ const connectionCallback = mockWebSocketServer.on.mock.calls[0][1];
68
+ // Simulate connection from valid origin
69
+ connectionCallback(mockWebSocket, {
70
+ headers: { origin: 'https://app.hubspot.com' },
71
+ });
72
+ expect(mockWebSocket.on).toHaveBeenCalledWith('message', expect.any(Function));
73
+ expect(mockLocalDevProcess.addStateListener).toHaveBeenCalledWith('projectNodes', expect.any(Function), true);
74
+ expect(mockWebSocket.close).not.toHaveBeenCalled();
75
+ });
76
+ it('should reject connection from invalid origin', async () => {
77
+ portManager_1.isPortManagerServerRunning.mockResolvedValue(true);
78
+ portManager_1.requestPorts.mockResolvedValue({
79
+ 'local-dev-ui-websocket-server': 1234,
80
+ });
81
+ await server.start();
82
+ // Get the connection callback
83
+ const connectionCallback = mockWebSocketServer.on.mock.calls[0][1];
84
+ // Simulate connection from invalid origin
85
+ connectionCallback(mockWebSocket, {
86
+ headers: { origin: 'https://malicious-site.com' },
87
+ });
88
+ expect(mockWebSocket.close).toHaveBeenCalledWith(1008, en_1.lib.LocalDevWebsocketServer.errors.originNotAllowed('https://malicious-site.com'));
89
+ expect(mockWebSocket.on).not.toHaveBeenCalled();
90
+ expect(mockLocalDevProcess.addStateListener).not.toHaveBeenCalled();
91
+ });
92
+ it('should reject connection with no origin header', async () => {
93
+ portManager_1.isPortManagerServerRunning.mockResolvedValue(true);
94
+ portManager_1.requestPorts.mockResolvedValue({
95
+ 'local-dev-ui-websocket-server': 1234,
96
+ });
97
+ await server.start();
98
+ // Get the connection callback
99
+ const connectionCallback = mockWebSocketServer.on.mock.calls[0][1];
100
+ // Simulate connection with no origin header
101
+ connectionCallback(mockWebSocket, {
102
+ headers: {},
103
+ });
104
+ expect(mockWebSocket.close).toHaveBeenCalledWith(1008, en_1.lib.LocalDevWebsocketServer.errors.originNotAllowed());
105
+ expect(mockWebSocket.on).not.toHaveBeenCalled();
106
+ expect(mockLocalDevProcess.addStateListener).not.toHaveBeenCalled();
107
+ });
108
+ it('should send WEBSOCKET_SERVER_CONNECTED message when valid connection is established', async () => {
109
+ portManager_1.isPortManagerServerRunning.mockResolvedValue(true);
110
+ portManager_1.requestPorts.mockResolvedValue({
111
+ 'local-dev-ui-websocket-server': 1234,
112
+ });
113
+ await server.start();
114
+ // Get the connection callback
115
+ const connectionCallback = mockWebSocketServer.on.mock.calls[0][1];
116
+ // Simulate connection from valid origin
117
+ connectionCallback(mockWebSocket, {
118
+ headers: { origin: 'https://app.hubspot.com' },
119
+ });
120
+ expect(mockLocalDevProcess.sendDevServerMessage).toHaveBeenCalledWith(constants_1.LOCAL_DEV_SERVER_MESSAGE_TYPES.WEBSOCKET_SERVER_CONNECTED);
121
+ });
122
+ });
123
+ describe('message handling', () => {
124
+ beforeEach(async () => {
125
+ portManager_1.isPortManagerServerRunning.mockResolvedValue(true);
126
+ portManager_1.requestPorts.mockResolvedValue({
127
+ 'local-dev-ui-websocket-server': 1234,
128
+ });
129
+ await server.start();
130
+ const connectionCallback = mockWebSocketServer.on.mock.calls[0][1];
131
+ connectionCallback(mockWebSocket, {
132
+ headers: { origin: 'https://app.hubspot.com' },
133
+ });
134
+ });
135
+ it('should handle UPLOAD message type', () => {
136
+ const messageCallback = mockWebSocket.on.mock.calls[0][1];
137
+ const message = {
138
+ type: constants_1.LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.UPLOAD,
139
+ };
140
+ messageCallback(JSON.stringify(message));
141
+ expect(mockLocalDevProcess.uploadProject).toHaveBeenCalled();
142
+ });
143
+ it('should log error for missing message type', () => {
144
+ const messageCallback = mockWebSocket.on.mock.calls[0][1];
145
+ const message = {};
146
+ messageCallback(JSON.stringify(message));
147
+ expect(logger_1.logger.error).toHaveBeenCalled();
148
+ });
149
+ it('should log error for unknown message type', () => {
150
+ const messageCallback = mockWebSocket.on.mock.calls[0][1];
151
+ const message = {
152
+ type: 'UNKNOWN_TYPE',
153
+ };
154
+ messageCallback(JSON.stringify(message));
155
+ expect(logger_1.logger.error).toHaveBeenCalled();
156
+ });
157
+ it('should log error for invalid JSON', () => {
158
+ const messageCallback = mockWebSocket.on.mock.calls[0][1];
159
+ const invalidJson = 'invalid json';
160
+ messageCallback(invalidJson);
161
+ expect(logger_1.logger.error).toHaveBeenCalled();
162
+ });
163
+ });
164
+ describe('shutdown()', () => {
165
+ it('should close the websocket server', async () => {
166
+ portManager_1.isPortManagerServerRunning.mockResolvedValue(true);
167
+ portManager_1.requestPorts.mockResolvedValue({
168
+ 'local-dev-ui-websocket-server': 1234,
169
+ });
170
+ await server.start();
171
+ server.shutdown();
172
+ expect(mockWebSocketServer.close).toHaveBeenCalled();
173
+ });
174
+ });
175
+ });