@hubspot/cli 7.7.19-experimental.2 → 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,249 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const fs_1 = __importDefault(require("fs"));
40
+ const HSfs = __importStar(require("@hubspot/local-dev-lib/fs"));
41
+ const logger_1 = require("@hubspot/local-dev-lib/logger");
42
+ const structure_1 = require("../structure");
43
+ const Projects_1 = require("../../../types/Projects");
44
+ vi.mock('fs');
45
+ vi.mock('@hubspot/local-dev-lib/fs');
46
+ vi.mock('@hubspot/local-dev-lib/logger');
47
+ const mockedReadFileSync = fs_1.default.readFileSync;
48
+ const mockedWalk = HSfs.walk;
49
+ const getMockPrivateAppConfig = (cards = []) => ({
50
+ name: 'test-app',
51
+ description: 'test-description',
52
+ uid: 'test-uid',
53
+ scopes: ['test-scope'],
54
+ public: true,
55
+ extensions: {
56
+ crm: {
57
+ cards,
58
+ },
59
+ },
60
+ });
61
+ describe('lib/projects/structure', () => {
62
+ describe('getComponentTypeFromConfigFile()', () => {
63
+ it('returns correct type for public app config', () => {
64
+ expect((0, structure_1.getComponentTypeFromConfigFile)('public-app.json')).toBe(Projects_1.ComponentTypes.PublicApp);
65
+ });
66
+ it('returns correct type for private app config', () => {
67
+ expect((0, structure_1.getComponentTypeFromConfigFile)('app.json')).toBe(Projects_1.ComponentTypes.PrivateApp);
68
+ });
69
+ it('returns correct type for theme config', () => {
70
+ expect((0, structure_1.getComponentTypeFromConfigFile)('theme.json')).toBe(Projects_1.ComponentTypes.HublTheme);
71
+ });
72
+ it('returns null for unknown config file', () => {
73
+ expect((0, structure_1.getComponentTypeFromConfigFile)('unknown.json')).toBeNull();
74
+ });
75
+ });
76
+ describe('loadConfigFile()', () => {
77
+ it('returns parsed JSON when file exists', () => {
78
+ const mockConfig = { name: 'test-app' };
79
+ mockedReadFileSync.mockReturnValue(JSON.stringify(mockConfig));
80
+ expect((0, structure_1.loadConfigFile)('test/path/app.json')).toEqual(mockConfig);
81
+ });
82
+ it('returns null when file read fails', () => {
83
+ mockedReadFileSync.mockImplementation(() => {
84
+ throw new Error('File not found');
85
+ });
86
+ expect((0, structure_1.loadConfigFile)('nonexistent/path/app.json')).toBeNull();
87
+ expect(logger_1.logger.debug).toHaveBeenCalled();
88
+ });
89
+ });
90
+ describe('getAppCardConfigs()', () => {
91
+ const mockAppPath = '/test/path';
92
+ it('returns empty array when no cards exist', () => {
93
+ const appConfig = getMockPrivateAppConfig();
94
+ expect((0, structure_1.getAppCardConfigs)(appConfig, mockAppPath)).toEqual([]);
95
+ });
96
+ it('returns array of card configs when valid cards exist', () => {
97
+ const mockCardConfig = { type: 'crm-card' };
98
+ mockedReadFileSync.mockReturnValue(JSON.stringify(mockCardConfig));
99
+ const appConfig = getMockPrivateAppConfig([{ file: 'card.json' }]);
100
+ expect((0, structure_1.getAppCardConfigs)(appConfig, mockAppPath)).toEqual([
101
+ mockCardConfig,
102
+ ]);
103
+ });
104
+ });
105
+ describe('getIsLegacyApp()', () => {
106
+ const mockAppPath = '/test/path';
107
+ it('returns true for a legacy app', () => {
108
+ const cardConfig = { type: 'crm-card' };
109
+ const appConfig = getMockPrivateAppConfig([{ file: 'card.json' }]);
110
+ mockedReadFileSync.mockReturnValue(JSON.stringify(cardConfig));
111
+ expect((0, structure_1.getIsLegacyApp)(appConfig, mockAppPath)).toBe(true);
112
+ });
113
+ it('returns false when the app has no cards', () => {
114
+ const appConfig = getMockPrivateAppConfig();
115
+ expect((0, structure_1.getIsLegacyApp)(appConfig, mockAppPath)).toBe(false);
116
+ });
117
+ it('returns false for non-legacy app', () => {
118
+ const cardConfig = {
119
+ data: { module: { file: 'ReactCard.jsx' } },
120
+ };
121
+ const appConfig = getMockPrivateAppConfig([{ file: 'card.json' }]);
122
+ mockedReadFileSync.mockReturnValue(JSON.stringify(cardConfig));
123
+ expect((0, structure_1.getIsLegacyApp)(appConfig, mockAppPath)).toBe(false);
124
+ });
125
+ });
126
+ describe('findProjectComponents()', () => {
127
+ it('returns an empty array of components when no components are found', async () => {
128
+ mockedWalk.mockReturnValue([]);
129
+ const components = await (0, structure_1.findProjectComponents)('');
130
+ expect(components).toEqual([]);
131
+ });
132
+ it('returns an array of components when components are found', async () => {
133
+ const cardConfig = { type: 'crm-card' };
134
+ const appConfig = getMockPrivateAppConfig();
135
+ const component = {
136
+ type: Projects_1.ComponentTypes.PrivateApp,
137
+ config: appConfig,
138
+ runnable: true,
139
+ path: '',
140
+ };
141
+ mockedWalk.mockReturnValue(['app.json']);
142
+ mockedReadFileSync
143
+ .mockReturnValueOnce(JSON.stringify(appConfig))
144
+ .mockReturnValueOnce(JSON.stringify(cardConfig));
145
+ const components = await (0, structure_1.findProjectComponents)('');
146
+ expect(components).toEqual([component]);
147
+ });
148
+ });
149
+ describe('getProjectComponentTypes()', () => {
150
+ it('returns the correct component types', () => {
151
+ const component = {
152
+ type: Projects_1.ComponentTypes.PrivateApp,
153
+ config: getMockPrivateAppConfig(),
154
+ runnable: true,
155
+ path: 'test/path',
156
+ };
157
+ const components = [component];
158
+ expect((0, structure_1.getProjectComponentTypes)(components)).toEqual({
159
+ [Projects_1.ComponentTypes.PrivateApp]: true,
160
+ });
161
+ });
162
+ it('returns the correct component types for multiple components', () => {
163
+ const component1 = {
164
+ type: Projects_1.ComponentTypes.PrivateApp,
165
+ config: getMockPrivateAppConfig(),
166
+ runnable: true,
167
+ path: 'test/path',
168
+ };
169
+ const component2 = {
170
+ type: Projects_1.ComponentTypes.PublicApp,
171
+ // Config doesn't matter for this test so we can use a private app config
172
+ config: getMockPrivateAppConfig(),
173
+ runnable: true,
174
+ path: 'test/path',
175
+ };
176
+ const components = [component1, component2];
177
+ expect((0, structure_1.getProjectComponentTypes)(components)).toEqual({
178
+ [Projects_1.ComponentTypes.PrivateApp]: true,
179
+ [Projects_1.ComponentTypes.PublicApp]: true,
180
+ });
181
+ });
182
+ it('returns an empty object when no components are provided', () => {
183
+ const components = [];
184
+ expect((0, structure_1.getProjectComponentTypes)(components)).toEqual({});
185
+ });
186
+ });
187
+ describe('getComponentUid()', () => {
188
+ it('returns uid from the component config', () => {
189
+ const component = {
190
+ type: Projects_1.ComponentTypes.PrivateApp,
191
+ config: getMockPrivateAppConfig(),
192
+ runnable: true,
193
+ path: 'test/path',
194
+ };
195
+ expect((0, structure_1.getComponentUid)(component)).toBe(component.config.uid);
196
+ });
197
+ it('returns null for null input', () => {
198
+ expect((0, structure_1.getComponentUid)(null)).toBeNull();
199
+ });
200
+ });
201
+ describe('componentIsApp()', () => {
202
+ it('returns true for public app component', () => {
203
+ const component = {
204
+ type: Projects_1.ComponentTypes.PublicApp,
205
+ // Config doesn't matter for this test so we can use a private app config
206
+ config: getMockPrivateAppConfig(),
207
+ runnable: true,
208
+ path: 'test/path',
209
+ };
210
+ expect((0, structure_1.componentIsApp)(component)).toBe(true);
211
+ });
212
+ it('returns true for private app component', () => {
213
+ const component = {
214
+ type: Projects_1.ComponentTypes.PrivateApp,
215
+ config: getMockPrivateAppConfig(),
216
+ runnable: true,
217
+ path: 'test/path',
218
+ };
219
+ expect((0, structure_1.componentIsApp)(component)).toBe(true);
220
+ });
221
+ it('returns false for null input', () => {
222
+ expect((0, structure_1.componentIsApp)(null)).toBe(false);
223
+ });
224
+ });
225
+ describe('componentIsPublicApp()', () => {
226
+ it('returns true for public app component', () => {
227
+ const component = {
228
+ type: Projects_1.ComponentTypes.PublicApp,
229
+ // Config doesn't matter for this test so we can use a private app config
230
+ config: getMockPrivateAppConfig(),
231
+ runnable: true,
232
+ path: 'test/path',
233
+ };
234
+ expect((0, structure_1.componentIsPublicApp)(component)).toBe(true);
235
+ });
236
+ it('returns false for private app component', () => {
237
+ const component = {
238
+ type: Projects_1.ComponentTypes.PrivateApp,
239
+ config: getMockPrivateAppConfig(),
240
+ runnable: true,
241
+ path: 'test/path',
242
+ };
243
+ expect((0, structure_1.componentIsPublicApp)(component)).toBe(false);
244
+ });
245
+ it('returns false for null input', () => {
246
+ expect((0, structure_1.componentIsPublicApp)(null)).toBe(false);
247
+ });
248
+ });
249
+ });
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const legacyAddComponent_1 = require("../legacyAddComponent");
4
+ const structure_1 = require("../../structure");
5
+ const legacy_1 = require("../../create/legacy");
6
+ const projectAddPrompt_1 = require("../../../prompts/projectAddPrompt");
7
+ const logger_1 = require("@hubspot/local-dev-lib/logger");
8
+ const github_1 = require("@hubspot/local-dev-lib/github");
9
+ const Projects_1 = require("../../../../types/Projects");
10
+ const en_1 = require("../../../../lang/en");
11
+ vi.mock('../../structure');
12
+ vi.mock('../../create/legacy');
13
+ vi.mock('../../../prompts/projectAddPrompt');
14
+ vi.mock('@hubspot/local-dev-lib/logger');
15
+ vi.mock('@hubspot/local-dev-lib/github');
16
+ const mockedFindProjectComponents = vi.mocked(structure_1.findProjectComponents);
17
+ const mockedGetProjectComponentListFromRepo = vi.mocked(legacy_1.getProjectComponentListFromRepo);
18
+ const mockedProjectAddPrompt = vi.mocked(projectAddPrompt_1.projectAddPrompt);
19
+ const mockedLogger = vi.mocked(logger_1.logger);
20
+ const mockedCloneGithubRepo = vi.mocked(github_1.cloneGithubRepo);
21
+ describe('lib/projects/add/legacyAddComponent', () => {
22
+ const mockProjectConfig = {
23
+ name: 'test-project',
24
+ srcDir: 'src',
25
+ platformVersion: 'v1',
26
+ };
27
+ const mockArgs = { name: 'test-component', type: 'module' };
28
+ const projectDir = '/path/to/project';
29
+ beforeEach(() => {
30
+ vi.resetAllMocks();
31
+ });
32
+ describe('legacyAddComponent()', () => {
33
+ it('successfully adds a component to a project without public apps', async () => {
34
+ const mockComponents = [
35
+ {
36
+ type: Projects_1.ComponentTypes.PrivateApp,
37
+ config: {
38
+ name: 'private-app',
39
+ description: '',
40
+ uid: '',
41
+ scopes: [],
42
+ public: false,
43
+ },
44
+ runnable: true,
45
+ path: '/path/to/private-app',
46
+ },
47
+ ];
48
+ const mockComponentList = [
49
+ { label: 'Test Component', path: 'test-component', type: 'module' },
50
+ ];
51
+ const mockPromptResponse = {
52
+ name: 'new-component',
53
+ componentTemplate: {
54
+ label: 'Test Component',
55
+ path: 'template-path',
56
+ type: 'module',
57
+ },
58
+ };
59
+ mockedFindProjectComponents.mockResolvedValue(mockComponents);
60
+ mockedGetProjectComponentListFromRepo.mockResolvedValue(mockComponentList);
61
+ mockedProjectAddPrompt.mockResolvedValue(mockPromptResponse);
62
+ mockedCloneGithubRepo.mockResolvedValue(true);
63
+ await (0, legacyAddComponent_1.legacyAddComponent)(mockArgs, projectDir, mockProjectConfig);
64
+ expect(mockedFindProjectComponents).toHaveBeenCalledWith(projectDir);
65
+ expect(mockedGetProjectComponentListFromRepo).toHaveBeenCalledWith('v1');
66
+ expect(mockedProjectAddPrompt).toHaveBeenCalledWith(mockComponentList, mockArgs);
67
+ expect(mockedCloneGithubRepo).toHaveBeenCalledWith(expect.any(String), '/path/to/project/src/new-component', expect.objectContaining({
68
+ sourceDir: 'template-path',
69
+ branch: 'main',
70
+ hideLogs: true,
71
+ }));
72
+ expect(mockedLogger.log).toHaveBeenCalledWith(en_1.commands.project.add.creatingComponent('test-project'));
73
+ expect(mockedLogger.success).toHaveBeenCalledWith(en_1.commands.project.add.success('new-component'));
74
+ });
75
+ it('throws an error when project contains a public app', async () => {
76
+ const mockComponents = [
77
+ {
78
+ type: Projects_1.ComponentTypes.PublicApp,
79
+ config: {
80
+ name: 'public-app',
81
+ uid: '',
82
+ description: '',
83
+ allowedUrls: [],
84
+ auth: {
85
+ redirectUrls: [],
86
+ requiredScopes: [],
87
+ optionalScopes: [],
88
+ conditionallyRequiredScopes: [],
89
+ },
90
+ support: {
91
+ supportEmail: '',
92
+ documentationUrl: '',
93
+ supportUrl: '',
94
+ supportPhone: '',
95
+ },
96
+ },
97
+ runnable: true,
98
+ path: '/path/to/public-app',
99
+ },
100
+ ];
101
+ mockedFindProjectComponents.mockResolvedValue(mockComponents);
102
+ await expect((0, legacyAddComponent_1.legacyAddComponent)(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow(en_1.commands.project.add.error.projectContainsPublicApp);
103
+ expect(mockedGetProjectComponentListFromRepo).not.toHaveBeenCalled();
104
+ expect(mockedProjectAddPrompt).not.toHaveBeenCalled();
105
+ expect(mockedCloneGithubRepo).not.toHaveBeenCalled();
106
+ });
107
+ it('continues when findProjectComponents throws an error', async () => {
108
+ const mockComponentList = [
109
+ { label: 'Test Component', path: 'test-component', type: 'module' },
110
+ ];
111
+ const mockPromptResponse = {
112
+ name: 'new-component',
113
+ componentTemplate: {
114
+ label: 'Test Component',
115
+ path: 'template-path',
116
+ type: 'module',
117
+ },
118
+ };
119
+ mockedFindProjectComponents.mockRejectedValue(new Error('Find components error'));
120
+ mockedGetProjectComponentListFromRepo.mockResolvedValue(mockComponentList);
121
+ mockedProjectAddPrompt.mockResolvedValue(mockPromptResponse);
122
+ mockedCloneGithubRepo.mockResolvedValue(true);
123
+ await (0, legacyAddComponent_1.legacyAddComponent)(mockArgs, projectDir, mockProjectConfig);
124
+ expect(mockedGetProjectComponentListFromRepo).toHaveBeenCalledWith('v1');
125
+ expect(mockedProjectAddPrompt).toHaveBeenCalledWith(mockComponentList, mockArgs);
126
+ expect(mockedCloneGithubRepo).toHaveBeenCalled();
127
+ });
128
+ it('throws an error when component list is empty', async () => {
129
+ const mockComponents = [
130
+ {
131
+ type: Projects_1.ComponentTypes.PrivateApp,
132
+ config: {
133
+ name: 'private-app',
134
+ description: '',
135
+ uid: '',
136
+ scopes: [],
137
+ public: false,
138
+ },
139
+ runnable: true,
140
+ path: '/path/to/private-app',
141
+ },
142
+ ];
143
+ mockedFindProjectComponents.mockResolvedValue(mockComponents);
144
+ mockedGetProjectComponentListFromRepo.mockResolvedValue([]);
145
+ await expect((0, legacyAddComponent_1.legacyAddComponent)(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow(en_1.commands.project.add.error.failedToFetchComponentList);
146
+ expect(mockedProjectAddPrompt).not.toHaveBeenCalled();
147
+ expect(mockedCloneGithubRepo).not.toHaveBeenCalled();
148
+ });
149
+ it('throws an error when component list is null', async () => {
150
+ const mockComponents = [
151
+ {
152
+ type: Projects_1.ComponentTypes.PrivateApp,
153
+ config: {
154
+ name: 'private-app',
155
+ description: '',
156
+ uid: '',
157
+ scopes: [],
158
+ public: false,
159
+ },
160
+ runnable: true,
161
+ path: '/path/to/private-app',
162
+ },
163
+ ];
164
+ mockedFindProjectComponents.mockResolvedValue(mockComponents);
165
+ // @ts-expect-error Breaking stuff on purpose
166
+ mockedGetProjectComponentListFromRepo.mockResolvedValue(null);
167
+ await expect((0, legacyAddComponent_1.legacyAddComponent)(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow(en_1.commands.project.add.error.failedToFetchComponentList);
168
+ expect(mockedProjectAddPrompt).not.toHaveBeenCalled();
169
+ expect(mockedCloneGithubRepo).not.toHaveBeenCalled();
170
+ });
171
+ it('throws an error when cloning fails', async () => {
172
+ const mockComponents = [
173
+ {
174
+ type: Projects_1.ComponentTypes.PrivateApp,
175
+ config: {
176
+ name: 'private-app',
177
+ description: '',
178
+ uid: '',
179
+ scopes: [],
180
+ public: false,
181
+ },
182
+ runnable: true,
183
+ path: '/path/to/private-app',
184
+ },
185
+ ];
186
+ const mockComponentList = [
187
+ { label: 'Test Component', path: 'test-component', type: 'module' },
188
+ ];
189
+ const mockPromptResponse = {
190
+ name: 'new-component',
191
+ componentTemplate: {
192
+ label: 'Test Component',
193
+ path: 'template-path',
194
+ type: 'module',
195
+ },
196
+ };
197
+ mockedFindProjectComponents.mockResolvedValue(mockComponents);
198
+ mockedGetProjectComponentListFromRepo.mockResolvedValue(mockComponentList);
199
+ mockedProjectAddPrompt.mockResolvedValue(mockPromptResponse);
200
+ mockedCloneGithubRepo.mockRejectedValue(new Error('Clone failed'));
201
+ await expect((0, legacyAddComponent_1.legacyAddComponent)(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow(en_1.commands.project.add.error.failedToDownloadComponent);
202
+ expect(mockedCloneGithubRepo).toHaveBeenCalled();
203
+ expect(mockedLogger.success).not.toHaveBeenCalled();
204
+ });
205
+ });
206
+ });
@@ -0,0 +1,190 @@
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 fs_1 = __importDefault(require("fs"));
7
+ const v3AddComponent_1 = require("../v3AddComponent");
8
+ const legacy_1 = require("../../create/legacy");
9
+ const v3_1 = require("../../create/v3");
10
+ const promptUtils_1 = require("../../../prompts/promptUtils");
11
+ const projectAddPrompt_1 = require("../../../prompts/projectAddPrompt");
12
+ const github_1 = require("@hubspot/local-dev-lib/github");
13
+ const logger_1 = require("@hubspot/local-dev-lib/logger");
14
+ const project_1 = require("@hubspot/project-parsing-lib/src/lib/project");
15
+ const en_1 = require("../../../../lang/en");
16
+ vi.mock('fs');
17
+ vi.mock('../../../prompts/promptUtils');
18
+ vi.mock('../../create/legacy');
19
+ vi.mock('../../create/v3');
20
+ vi.mock('../../../prompts/projectAddPrompt');
21
+ vi.mock('@hubspot/local-dev-lib/github');
22
+ vi.mock('@hubspot/local-dev-lib/logger');
23
+ vi.mock('@hubspot/project-parsing-lib/src/lib/project');
24
+ const mockedFs = vi.mocked(fs_1.default);
25
+ const mockedGetConfigForPlatformVersion = vi.mocked(legacy_1.getConfigForPlatformVersion);
26
+ const mockedConfirmPrompt = vi.mocked(promptUtils_1.confirmPrompt);
27
+ const mockedCreateV3App = vi.mocked(v3_1.createV3App);
28
+ const mockedProjectAddPromptV3 = vi.mocked(projectAddPrompt_1.projectAddPromptV3);
29
+ const mockedCloneGithubRepo = vi.mocked(github_1.cloneGithubRepo);
30
+ const mockedLogger = vi.mocked(logger_1.logger);
31
+ const mockedGetProjectMetadata = vi.mocked(project_1.getProjectMetadata);
32
+ describe('lib/projects/add/v3AddComponent', () => {
33
+ const mockProjectConfig = {
34
+ name: 'test-project',
35
+ srcDir: 'src',
36
+ platformVersion: 'v3',
37
+ };
38
+ const mockArgs = { name: 'test-component', type: 'module' };
39
+ const projectDir = '/path/to/project';
40
+ const mockComponentTemplate = {
41
+ label: 'Test Component',
42
+ path: 'test-component',
43
+ type: 'module',
44
+ supportedAuthTypes: ['oauth'],
45
+ supportedDistributions: ['private'],
46
+ };
47
+ const mockParentComponent = {
48
+ label: 'Test App',
49
+ type: 'app',
50
+ authType: 'oauth',
51
+ distribution: 'private',
52
+ path: 'app-template',
53
+ };
54
+ const mockConfig = {
55
+ components: [mockComponentTemplate],
56
+ parentComponents: [mockParentComponent],
57
+ };
58
+ const mockProjectMetadata = {
59
+ hsMetaFiles: [],
60
+ components: {
61
+ app: { count: 1, maxCount: 1, hsMetaFiles: ['/path/to/app.meta.json'] },
62
+ module: { count: 0, maxCount: 5, hsMetaFiles: [] },
63
+ },
64
+ };
65
+ beforeEach(() => {
66
+ mockedCreateV3App.mockResolvedValue({
67
+ authType: 'oauth',
68
+ distribution: 'private',
69
+ });
70
+ });
71
+ describe('v3AddComponent()', () => {
72
+ it('successfully adds a component when app already exists', async () => {
73
+ const mockAppMeta = {
74
+ config: {
75
+ distribution: 'private',
76
+ auth: { type: 'oauth' },
77
+ },
78
+ };
79
+ const mockPromptResponse = {
80
+ componentTemplate: [mockComponentTemplate],
81
+ };
82
+ mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
83
+ mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadata);
84
+ mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockAppMeta));
85
+ mockedProjectAddPromptV3.mockResolvedValue(mockPromptResponse);
86
+ mockedCloneGithubRepo.mockResolvedValue(true);
87
+ await (0, v3AddComponent_1.v3AddComponent)(mockArgs, projectDir, mockProjectConfig);
88
+ expect(mockedGetConfigForPlatformVersion).toHaveBeenCalledWith('v3');
89
+ expect(mockedGetProjectMetadata).toHaveBeenCalledWith('/path/to/project/src');
90
+ expect(mockedProjectAddPromptV3).toHaveBeenCalled();
91
+ expect(mockedCloneGithubRepo).toHaveBeenCalledWith(expect.any(String), projectDir, expect.objectContaining({
92
+ sourceDir: ['v3/test-component'],
93
+ hideLogs: true,
94
+ branch: 'main',
95
+ }));
96
+ expect(mockedLogger.success).toHaveBeenCalled();
97
+ });
98
+ it('creates an app when no app exists and user confirms', async () => {
99
+ const mockProjectMetadataNoApps = {
100
+ hsMetaFiles: [],
101
+ components: {
102
+ app: { count: 0, maxCount: 1, hsMetaFiles: [] },
103
+ module: { count: 0, maxCount: 5, hsMetaFiles: [] },
104
+ },
105
+ };
106
+ const mockPromptResponse = {
107
+ componentTemplate: [mockComponentTemplate],
108
+ };
109
+ mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
110
+ mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadataNoApps);
111
+ mockedConfirmPrompt.mockResolvedValue(true);
112
+ mockedProjectAddPromptV3.mockResolvedValue(mockPromptResponse);
113
+ mockedCloneGithubRepo.mockResolvedValue(true);
114
+ await (0, v3AddComponent_1.v3AddComponent)(mockArgs, projectDir, mockProjectConfig);
115
+ expect(mockedCreateV3App).toHaveBeenCalled();
116
+ expect(mockedCloneGithubRepo).toHaveBeenCalledWith(expect.any(String), projectDir, expect.objectContaining({
117
+ sourceDir: ['v3/test-component', 'v3/app-template'],
118
+ }));
119
+ });
120
+ it('should not call clone', async () => {
121
+ const mockProjectMetadataNoApps = {
122
+ hsMetaFiles: [],
123
+ components: {
124
+ app: {
125
+ count: 1,
126
+ maxCount: 1,
127
+ hsMetaFiles: ['/path/to/app.meta.json'],
128
+ },
129
+ module: { count: 0, maxCount: 5, hsMetaFiles: [] },
130
+ },
131
+ };
132
+ const mockPromptResponse = {
133
+ componentTemplate: [],
134
+ };
135
+ mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
136
+ mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadataNoApps);
137
+ mockedConfirmPrompt.mockResolvedValue(true);
138
+ mockedProjectAddPromptV3.mockResolvedValue(mockPromptResponse);
139
+ mockedCloneGithubRepo.mockResolvedValue(true);
140
+ await (0, v3AddComponent_1.v3AddComponent)(mockArgs, projectDir, mockProjectConfig);
141
+ expect(mockedCreateV3App).not.toHaveBeenCalled();
142
+ expect(mockedCloneGithubRepo).not.toHaveBeenCalled();
143
+ });
144
+ it('throws an error when app count exceeds maximum', async () => {
145
+ const mockProjectMetadataMaxApps = {
146
+ hsMetaFiles: [],
147
+ components: {
148
+ app: { count: 2, maxCount: 1, hsMetaFiles: [] },
149
+ module: { count: 0, maxCount: 5, hsMetaFiles: [] },
150
+ },
151
+ };
152
+ mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
153
+ mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadataMaxApps);
154
+ await expect((0, v3AddComponent_1.v3AddComponent)(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow('This project currently has the maximum number of apps: 1');
155
+ });
156
+ it('throws an error when components list is empty', async () => {
157
+ const mockEmptyConfig = {
158
+ components: [],
159
+ parentComponents: [],
160
+ };
161
+ mockedGetConfigForPlatformVersion.mockResolvedValue(mockEmptyConfig);
162
+ await expect((0, v3AddComponent_1.v3AddComponent)(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow(en_1.commands.project.add.error.failedToFetchComponentList);
163
+ });
164
+ it('throws an error when app meta file cannot be parsed', async () => {
165
+ mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
166
+ mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadata);
167
+ mockedFs.readFileSync.mockImplementation(() => {
168
+ throw new Error('File read error');
169
+ });
170
+ await expect((0, v3AddComponent_1.v3AddComponent)(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow('Unable to parse app file');
171
+ });
172
+ it('throws an error when cloning fails', async () => {
173
+ const mockAppMeta = {
174
+ config: {
175
+ distribution: 'private',
176
+ auth: { type: 'oauth' },
177
+ },
178
+ };
179
+ const mockPromptResponse = {
180
+ componentTemplate: [mockComponentTemplate],
181
+ };
182
+ mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
183
+ mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadata);
184
+ mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockAppMeta));
185
+ mockedProjectAddPromptV3.mockResolvedValue(mockPromptResponse);
186
+ mockedCloneGithubRepo.mockRejectedValue(new Error('Clone failed'));
187
+ await expect((0, v3AddComponent_1.v3AddComponent)(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow(en_1.commands.project.add.error.failedToDownloadComponent);
188
+ });
189
+ });
190
+ });
@@ -0,0 +1 @@
1
+ export {};