@hubspot/cli 6.2.0 → 6.2.2-beta.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 (344) hide show
  1. package/README.md +12 -95
  2. package/bin/cli.d.ts +2 -0
  3. package/bin/cli.js +107 -128
  4. package/commands/accounts/clean.d.ts +1 -0
  5. package/commands/accounts/clean.js +82 -116
  6. package/commands/accounts/info.d.ts +1 -0
  7. package/commands/accounts/info.js +32 -43
  8. package/commands/accounts/list.d.ts +1 -0
  9. package/commands/accounts/list.js +65 -92
  10. package/commands/accounts/remove.d.ts +1 -0
  11. package/commands/accounts/remove.js +43 -73
  12. package/commands/accounts/rename.d.ts +1 -0
  13. package/commands/accounts/rename.js +26 -41
  14. package/commands/accounts/use.d.ts +1 -0
  15. package/commands/accounts/use.js +36 -57
  16. package/commands/accounts.d.ts +1 -0
  17. package/commands/accounts.js +16 -18
  18. package/commands/auth.d.ts +1 -0
  19. package/commands/auth.js +133 -200
  20. package/commands/cms/convertFields.d.ts +1 -0
  21. package/commands/cms/convertFields.js +66 -81
  22. package/commands/cms/lighthouseScore.d.ts +1 -0
  23. package/commands/cms/lighthouseScore.js +236 -298
  24. package/commands/cms/reactModules.d.ts +1 -0
  25. package/commands/cms/reactModules.js +46 -53
  26. package/commands/cms.d.ts +1 -0
  27. package/commands/cms.js +11 -13
  28. package/commands/config/set.d.ts +1 -0
  29. package/commands/config/set.js +64 -79
  30. package/commands/config.d.ts +1 -0
  31. package/commands/config.js +7 -9
  32. package/commands/create/api-sample.d.ts +1 -0
  33. package/commands/create/api-sample.js +54 -74
  34. package/commands/create/app.d.ts +1 -0
  35. package/commands/create/app.js +8 -7
  36. package/commands/create/function.d.ts +1 -0
  37. package/commands/create/function.js +15 -14
  38. package/commands/create/index.d.ts +1 -0
  39. package/commands/create/index.js +12 -9
  40. package/commands/create/module.d.ts +1 -0
  41. package/commands/create/module.js +21 -19
  42. package/commands/create/react-app.d.ts +1 -0
  43. package/commands/create/react-app.js +7 -6
  44. package/commands/create/template.d.ts +1 -0
  45. package/commands/create/template.js +23 -24
  46. package/commands/create/vue-app.d.ts +1 -0
  47. package/commands/create/vue-app.js +7 -6
  48. package/commands/create/webpack-serverless.d.ts +1 -0
  49. package/commands/create/webpack-serverless.js +7 -6
  50. package/commands/create/website-theme.d.ts +1 -0
  51. package/commands/create/website-theme.js +15 -15
  52. package/commands/create.d.ts +24 -0
  53. package/commands/create.js +65 -80
  54. package/commands/customObject/create.d.ts +1 -0
  55. package/commands/customObject/create.js +33 -47
  56. package/commands/customObject/schema/create.d.ts +1 -0
  57. package/commands/customObject/schema/create.js +42 -67
  58. package/commands/customObject/schema/delete.d.ts +1 -0
  59. package/commands/customObject/schema/delete.js +28 -39
  60. package/commands/customObject/schema/fetch-all.d.ts +1 -0
  61. package/commands/customObject/schema/fetch-all.js +30 -39
  62. package/commands/customObject/schema/fetch.d.ts +1 -0
  63. package/commands/customObject/schema/fetch.js +48 -63
  64. package/commands/customObject/schema/list.d.ts +1 -0
  65. package/commands/customObject/schema/list.js +14 -17
  66. package/commands/customObject/schema/update.d.ts +1 -0
  67. package/commands/customObject/schema/update.js +46 -72
  68. package/commands/customObject/schema.d.ts +1 -0
  69. package/commands/customObject/schema.js +12 -12
  70. package/commands/customObject.d.ts +1 -0
  71. package/commands/customObject.js +14 -22
  72. package/commands/feedback.d.ts +1 -0
  73. package/commands/feedback.js +25 -33
  74. package/commands/fetch.d.ts +1 -0
  75. package/commands/fetch.js +53 -78
  76. package/commands/filemanager/fetch.d.ts +1 -0
  77. package/commands/filemanager/fetch.js +38 -56
  78. package/commands/filemanager/upload.d.ts +1 -0
  79. package/commands/filemanager/upload.js +88 -128
  80. package/commands/filemanager.d.ts +1 -0
  81. package/commands/filemanager.js +12 -18
  82. package/commands/functions/deploy.d.ts +1 -0
  83. package/commands/functions/deploy.js +76 -99
  84. package/commands/functions/list.d.ts +1 -0
  85. package/commands/functions/list.js +41 -48
  86. package/commands/functions/server.d.ts +1 -0
  87. package/commands/functions/server.js +50 -65
  88. package/commands/functions.d.ts +1 -0
  89. package/commands/functions.js +13 -15
  90. package/commands/hubdb/clear.d.ts +1 -0
  91. package/commands/hubdb/clear.js +37 -56
  92. package/commands/hubdb/create.d.ts +1 -0
  93. package/commands/hubdb/create.js +34 -57
  94. package/commands/hubdb/delete.d.ts +1 -0
  95. package/commands/hubdb/delete.js +29 -44
  96. package/commands/hubdb/fetch.d.ts +1 -0
  97. package/commands/hubdb/fetch.js +30 -46
  98. package/commands/hubdb.d.ts +1 -0
  99. package/commands/hubdb.js +12 -14
  100. package/commands/init.d.ts +1 -0
  101. package/commands/init.js +103 -160
  102. package/commands/lint.d.ts +1 -0
  103. package/commands/lint.js +34 -45
  104. package/commands/list.d.ts +1 -0
  105. package/commands/list.js +74 -101
  106. package/commands/logs.d.ts +1 -0
  107. package/commands/logs.js +98 -121
  108. package/commands/module/marketplace-validate.d.ts +1 -0
  109. package/commands/module/marketplace-validate.js +32 -57
  110. package/commands/module.d.ts +1 -0
  111. package/commands/module.js +7 -9
  112. package/commands/mv.d.ts +1 -0
  113. package/commands/mv.js +53 -71
  114. package/commands/open.d.ts +1 -0
  115. package/commands/open.js +48 -62
  116. package/commands/project/add.d.ts +1 -0
  117. package/commands/project/add.js +47 -70
  118. package/commands/project/cloneApp.d.ts +1 -0
  119. package/commands/project/cloneApp.js +119 -180
  120. package/commands/project/create.d.ts +1 -0
  121. package/commands/project/create.js +49 -81
  122. package/commands/project/deploy.d.ts +1 -0
  123. package/commands/project/deploy.js +105 -182
  124. package/commands/project/dev.d.ts +1 -0
  125. package/commands/project/dev.js +126 -227
  126. package/commands/project/download.d.ts +1 -0
  127. package/commands/project/download.js +73 -123
  128. package/commands/project/installDeps.d.ts +1 -0
  129. package/commands/project/installDeps.js +52 -59
  130. package/commands/project/listBuilds.d.ts +1 -0
  131. package/commands/project/listBuilds.js +97 -139
  132. package/commands/project/logs.d.ts +1 -0
  133. package/commands/project/logs.js +86 -128
  134. package/commands/project/migrateApp.d.ts +1 -0
  135. package/commands/project/migrateApp.js +158 -248
  136. package/commands/project/open.d.ts +1 -0
  137. package/commands/project/open.js +44 -68
  138. package/commands/project/upload.d.ts +1 -0
  139. package/commands/project/upload.js +72 -116
  140. package/commands/project/watch.d.ts +1 -0
  141. package/commands/project/watch.js +94 -152
  142. package/commands/project.d.ts +1 -0
  143. package/commands/project.js +21 -23
  144. package/commands/remove.d.ts +1 -0
  145. package/commands/remove.js +28 -43
  146. package/commands/sandbox/create.d.ts +1 -0
  147. package/commands/sandbox/create.js +143 -187
  148. package/commands/sandbox/delete.d.ts +1 -0
  149. package/commands/sandbox/delete.js +166 -221
  150. package/commands/sandbox.d.ts +1 -0
  151. package/commands/sandbox.js +10 -12
  152. package/commands/secrets/addSecret.d.ts +1 -0
  153. package/commands/secrets/addSecret.js +34 -52
  154. package/commands/secrets/deleteSecret.d.ts +1 -0
  155. package/commands/secrets/deleteSecret.js +33 -50
  156. package/commands/secrets/listSecrets.d.ts +1 -0
  157. package/commands/secrets/listSecrets.js +28 -42
  158. package/commands/secrets/updateSecret.d.ts +1 -0
  159. package/commands/secrets/updateSecret.js +35 -53
  160. package/commands/secrets.d.ts +1 -0
  161. package/commands/secrets.js +12 -13
  162. package/commands/theme/generate-selectors.d.ts +1 -0
  163. package/commands/theme/generate-selectors.js +129 -192
  164. package/commands/theme/marketplace-validate.d.ts +1 -0
  165. package/commands/theme/marketplace-validate.js +32 -57
  166. package/commands/theme/preview.d.ts +1 -0
  167. package/commands/theme/preview.js +170 -195
  168. package/commands/theme.d.ts +1 -0
  169. package/commands/theme.js +9 -11
  170. package/commands/upload.d.ts +1 -0
  171. package/commands/upload.js +199 -287
  172. package/commands/watch.d.ts +1 -0
  173. package/commands/watch.js +128 -172
  174. package/lang/en.lyaml +2 -3
  175. package/lib/DevServerManager.d.ts +1 -0
  176. package/lib/DevServerManager.js +99 -124
  177. package/lib/LocalDevManager.d.ts +1 -0
  178. package/lib/LocalDevManager.js +322 -490
  179. package/lib/accountTypes.d.ts +7 -0
  180. package/lib/accountTypes.js +32 -34
  181. package/lib/buildAccount.d.ts +1 -0
  182. package/lib/buildAccount.js +132 -179
  183. package/lib/commonOpts.d.ts +1 -0
  184. package/lib/commonOpts.js +60 -91
  185. package/lib/configOptions.d.ts +1 -0
  186. package/lib/configOptions.js +110 -0
  187. package/lib/constants.d.ts +84 -0
  188. package/lib/constants.js +64 -91
  189. package/lib/debugInfo.d.ts +1 -0
  190. package/lib/debugInfo.js +14 -13
  191. package/lib/dependencyManagement.d.ts +1 -0
  192. package/lib/dependencyManagement.js +92 -132
  193. package/lib/developerTestAccounts.d.ts +1 -0
  194. package/lib/developerTestAccounts.js +67 -91
  195. package/lib/enums/exitCodes.d.ts +5 -0
  196. package/lib/enums/exitCodes.js +7 -8
  197. package/lib/environment.d.ts +1 -0
  198. package/lib/environment.js +13 -14
  199. package/lib/errorHandlers/index.d.ts +1 -0
  200. package/lib/errorHandlers/index.js +66 -80
  201. package/lib/errorHandlers/suppressError.d.ts +1 -0
  202. package/lib/errorHandlers/suppressError.js +66 -106
  203. package/lib/filesystem.d.ts +2 -0
  204. package/lib/filesystem.js +22 -28
  205. package/lib/generate-selectors.d.ts +1 -0
  206. package/lib/generate-selectors.js +102 -138
  207. package/lib/hasFeature.d.ts +1 -0
  208. package/lib/hasFeature.js +8 -15
  209. package/lib/hasFlag.d.ts +1 -0
  210. package/lib/hasFlag.js +13 -13
  211. package/lib/hublValidate.d.ts +2 -0
  212. package/lib/hublValidate.js +28 -28
  213. package/lib/interpolation.d.ts +1 -0
  214. package/lib/interpolation.js +50 -92
  215. package/lib/interpolationHelpers.d.ts +10 -0
  216. package/lib/interpolationHelpers.js +30 -22
  217. package/lib/lang.d.ts +1 -0
  218. package/lib/lang.js +52 -78
  219. package/lib/links.d.ts +1 -0
  220. package/lib/links.js +94 -114
  221. package/lib/localDev.d.ts +1 -0
  222. package/lib/localDev.js +285 -433
  223. package/lib/marketplace-validate.d.ts +1 -0
  224. package/lib/marketplace-validate.js +105 -126
  225. package/lib/oauth.d.ts +1 -0
  226. package/lib/oauth.js +64 -78
  227. package/lib/polling.d.ts +1 -0
  228. package/lib/polling.js +26 -26
  229. package/lib/process.d.ts +1 -0
  230. package/lib/process.js +41 -53
  231. package/lib/projectLogsManager.d.ts +1 -0
  232. package/lib/projectLogsManager.js +78 -130
  233. package/lib/projectStructure.d.ts +1 -0
  234. package/lib/projectStructure.js +89 -109
  235. package/lib/projects.d.ts +1 -0
  236. package/lib/projects.js +595 -958
  237. package/lib/projectsWatch.d.ts +1 -0
  238. package/lib/projectsWatch.js +127 -228
  239. package/lib/prompts/accountNamePrompt.d.ts +1 -0
  240. package/lib/prompts/accountNamePrompt.js +60 -65
  241. package/lib/prompts/accountsPrompt.d.ts +1 -0
  242. package/lib/prompts/accountsPrompt.js +33 -37
  243. package/lib/prompts/activeInstallConfirmationPrompt.d.ts +1 -0
  244. package/lib/prompts/activeInstallConfirmationPrompt.js +13 -13
  245. package/lib/prompts/cleanUploadPrompt.d.ts +1 -0
  246. package/lib/prompts/cleanUploadPrompt.js +13 -13
  247. package/lib/prompts/cmsFieldPrompt.d.ts +1 -0
  248. package/lib/prompts/cmsFieldPrompt.js +37 -39
  249. package/lib/prompts/createApiSamplePrompt.d.ts +1 -0
  250. package/lib/prompts/createApiSamplePrompt.js +49 -52
  251. package/lib/prompts/createFunctionPrompt.d.ts +1 -0
  252. package/lib/prompts/createFunctionPrompt.js +57 -56
  253. package/lib/prompts/createModulePrompt.d.ts +1 -0
  254. package/lib/prompts/createModulePrompt.js +47 -50
  255. package/lib/prompts/createProjectPrompt.d.ts +1 -0
  256. package/lib/prompts/createProjectPrompt.js +95 -129
  257. package/lib/prompts/createTemplatePrompt.d.ts +1 -0
  258. package/lib/prompts/createTemplatePrompt.js +18 -19
  259. package/lib/prompts/deployBuildIdPrompt.d.ts +1 -0
  260. package/lib/prompts/deployBuildIdPrompt.js +15 -15
  261. package/lib/prompts/downloadProjectPrompt.d.ts +1 -0
  262. package/lib/prompts/downloadProjectPrompt.js +39 -41
  263. package/lib/prompts/feedbackPrompt.d.ts +1 -0
  264. package/lib/prompts/feedbackPrompt.js +29 -30
  265. package/lib/prompts/folderOverwritePrompt.d.ts +1 -0
  266. package/lib/prompts/folderOverwritePrompt.js +10 -10
  267. package/lib/prompts/installPublicAppPrompt.d.ts +1 -0
  268. package/lib/prompts/installPublicAppPrompt.js +29 -42
  269. package/lib/prompts/personalAccessKeyPrompt.d.ts +1 -0
  270. package/lib/prompts/personalAccessKeyPrompt.js +104 -110
  271. package/lib/prompts/previewPrompt.d.ts +1 -0
  272. package/lib/prompts/previewPrompt.js +46 -47
  273. package/lib/prompts/projectAddPrompt.d.ts +1 -0
  274. package/lib/prompts/projectAddPrompt.js +37 -38
  275. package/lib/prompts/projectDevTargetAccountPrompt.d.ts +1 -0
  276. package/lib/prompts/projectDevTargetAccountPrompt.js +150 -193
  277. package/lib/prompts/projectNamePrompt.d.ts +1 -0
  278. package/lib/prompts/projectNamePrompt.js +25 -25
  279. package/lib/prompts/projectsLogsPrompt.d.ts +1 -0
  280. package/lib/prompts/projectsLogsPrompt.js +21 -27
  281. package/lib/prompts/promptUtils.d.ts +1 -0
  282. package/lib/prompts/promptUtils.js +17 -17
  283. package/lib/prompts/sandboxesPrompt.d.ts +1 -0
  284. package/lib/prompts/sandboxesPrompt.js +50 -59
  285. package/lib/prompts/secretPrompt.d.ts +1 -0
  286. package/lib/prompts/secretPrompt.js +15 -16
  287. package/lib/prompts/selectPublicAppPrompt.d.ts +1 -0
  288. package/lib/prompts/selectPublicAppPrompt.js +58 -82
  289. package/lib/prompts/setAsDefaultAccountPrompt.d.ts +1 -0
  290. package/lib/prompts/setAsDefaultAccountPrompt.js +19 -24
  291. package/lib/prompts/uploadPrompt.d.ts +1 -0
  292. package/lib/prompts/uploadPrompt.js +30 -30
  293. package/lib/regex.d.ts +1 -0
  294. package/lib/regex.js +4 -5
  295. package/lib/sandboxSync.d.ts +1 -0
  296. package/lib/sandboxSync.js +100 -166
  297. package/lib/sandboxes.d.ts +1 -0
  298. package/lib/sandboxes.js +201 -316
  299. package/lib/schema.d.ts +3 -0
  300. package/lib/schema.js +29 -33
  301. package/lib/serverlessLogs.d.ts +1 -0
  302. package/lib/serverlessLogs.js +131 -173
  303. package/lib/ui/SpinniesManager.d.ts +1 -0
  304. package/lib/ui/SpinniesManager.js +198 -254
  305. package/lib/ui/git.d.ts +1 -0
  306. package/lib/ui/git.js +20 -19
  307. package/lib/ui/index.d.ts +1 -0
  308. package/lib/ui/index.js +117 -167
  309. package/lib/ui/serverlessFunctionLogs.d.ts +1 -0
  310. package/lib/ui/serverlessFunctionLogs.js +53 -70
  311. package/lib/ui/spinniesUtils.d.ts +1 -0
  312. package/lib/ui/spinniesUtils.js +111 -133
  313. package/lib/ui/supportHyperlinks.d.ts +1 -0
  314. package/lib/ui/supportHyperlinks.js +49 -62
  315. package/lib/ui/supportsColor.d.ts +1 -0
  316. package/lib/ui/supportsColor.js +81 -109
  317. package/lib/ui/table.d.ts +1 -0
  318. package/lib/ui/table.js +49 -55
  319. package/lib/upload.d.ts +1 -0
  320. package/lib/upload.js +40 -43
  321. package/lib/usageTracking.d.ts +1 -0
  322. package/lib/usageTracking.js +133 -155
  323. package/lib/validation.d.ts +1 -0
  324. package/lib/validation.js +144 -203
  325. package/package.json +84 -48
  326. package/CHANGELOG.md +0 -16
  327. package/commands/__tests__/projects.test.js +0 -105
  328. package/commands/config/set/allowUsageTracking.js +0 -52
  329. package/commands/config/set/defaultMode.js +0 -59
  330. package/commands/config/set/httpTimeout.js +0 -42
  331. package/commands/project/__tests__/deploy.test.js +0 -443
  332. package/commands/project/__tests__/installDeps.test.js +0 -168
  333. package/commands/project/__tests__/logs.test.js +0 -304
  334. package/hubspot.sample.config.yml +0 -28
  335. package/jest.config.js +0 -4
  336. package/lib/__tests__/commonOpts.test.js +0 -83
  337. package/lib/__tests__/dependencyManagement.test.js +0 -243
  338. package/lib/__tests__/downloadProjectPrompt.test.js +0 -31
  339. package/lib/__tests__/projectLogsManager.test.js +0 -212
  340. package/lib/__tests__/projects.test.js +0 -140
  341. package/lib/__tests__/serverlessLogs.test.js +0 -162
  342. package/lib/__tests__/validation.test.js +0 -140
  343. package/lib/getFunctionArrays.js +0 -18
  344. package/lib/prompts/__tests__/projectsLogsPrompt.test.js +0 -46
package/lib/projects.js CHANGED
@@ -1,3 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // @ts-nocheck
1
4
  const fs = require('fs-extra');
2
5
  const path = require('path');
3
6
  const archiver = require('archiver');
@@ -8,1035 +11,669 @@ const { logger } = require('@hubspot/local-dev-lib/logger');
8
11
  const { getEnv } = require('@hubspot/local-dev-lib/config');
9
12
  const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
10
13
  const { fetchFileFromRepository } = require('@hubspot/local-dev-lib/github');
11
- const {
12
- ENVIRONMENTS,
13
- } = require('@hubspot/local-dev-lib/constants/environments');
14
- const {
15
- FEEDBACK_INTERVAL,
16
- POLLING_DELAY,
17
- PROJECT_BUILD_TEXT,
18
- PROJECT_DEPLOY_TEXT,
19
- PROJECT_CONFIG_FILE,
20
- PROJECT_TASK_TYPES,
21
- PROJECT_ERROR_TYPES,
22
- HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH,
23
- PROJECT_COMPONENT_TYPES,
24
- } = require('./constants');
25
- const {
26
- createProject,
27
- getBuildStatus,
28
- getBuildStructure,
29
- getDeployStatus,
30
- getDeployStructure,
31
- fetchProject,
32
- uploadProject,
33
- fetchBuildWarnLogs,
34
- fetchDeployWarnLogs,
35
- } = require('@hubspot/local-dev-lib/api/projects');
14
+ const { ENVIRONMENTS, } = require('@hubspot/local-dev-lib/constants/environments');
15
+ const { FEEDBACK_INTERVAL, POLLING_DELAY, PROJECT_BUILD_TEXT, PROJECT_DEPLOY_TEXT, PROJECT_CONFIG_FILE, PROJECT_TASK_TYPES, PROJECT_ERROR_TYPES, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, PROJECT_COMPONENT_TYPES, } = require('./constants');
16
+ const { createProject, getBuildStatus, getBuildStructure, getDeployStatus, getDeployStructure, fetchProject, uploadProject, fetchBuildWarnLogs, fetchDeployWarnLogs, } = require('@hubspot/local-dev-lib/api/projects');
36
17
  const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/index');
37
18
  const { shouldIgnoreFile } = require('@hubspot/local-dev-lib/ignoreRules');
38
19
  const { getCwd, getAbsoluteFilePath } = require('@hubspot/local-dev-lib/path');
39
20
  const { downloadGithubRepoContents } = require('@hubspot/local-dev-lib/github');
40
21
  const { promptUser } = require('./prompts/promptUtils');
41
22
  const { EXIT_CODES } = require('./enums/exitCodes');
42
- const { uiLine, uiLink, uiAccountDescription } = require('../lib/ui');
23
+ const { uiLine, uiLink, uiAccountDescription } = require('./ui');
43
24
  const { i18n } = require('./lang');
44
25
  const SpinniesManager = require('./ui/SpinniesManager');
45
26
  const { logError, ApiErrorContext } = require('./errorHandlers/index');
46
-
47
27
  const i18nKey = 'lib.projects';
48
-
49
28
  const SPINNER_STATUS = {
50
- SPINNING: 'spinning',
29
+ SPINNING: 'spinning',
51
30
  };
52
-
53
31
  const writeProjectConfig = (configPath, config) => {
54
- try {
55
- fs.ensureFileSync(configPath);
56
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
57
- logger.debug(`Wrote project config at ${configPath}`);
58
- } catch (e) {
59
- logger.debug(e);
60
- return false;
61
- }
62
- return true;
32
+ try {
33
+ fs.ensureFileSync(configPath);
34
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
35
+ logger.debug(`Wrote project config at ${configPath}`);
36
+ }
37
+ catch (e) {
38
+ logger.debug(e);
39
+ return false;
40
+ }
41
+ return true;
63
42
  };
64
-
65
43
  const getIsInProject = _dir => {
66
- const configPath = getProjectConfigPath(_dir);
67
- return !!configPath;
44
+ const configPath = getProjectConfigPath(_dir);
45
+ return !!configPath;
68
46
  };
69
-
70
47
  const getProjectConfigPath = _dir => {
71
- const projectDir = _dir ? getAbsoluteFilePath(_dir) : getCwd();
72
-
73
- const configPath = findup(PROJECT_CONFIG_FILE, {
74
- cwd: projectDir,
75
- nocase: true,
76
- });
77
-
78
- return configPath;
48
+ const projectDir = _dir ? getAbsoluteFilePath(_dir) : getCwd();
49
+ const configPath = findup(PROJECT_CONFIG_FILE, {
50
+ cwd: projectDir,
51
+ nocase: true,
52
+ });
53
+ return configPath;
79
54
  };
80
-
81
- const getProjectConfig = async _dir => {
82
- const configPath = await getProjectConfigPath(_dir);
83
- if (!configPath) {
84
- return { projectConfig: null, projectDir: null };
85
- }
86
-
87
- try {
88
- const config = fs.readFileSync(configPath);
89
- const projectConfig = JSON.parse(config);
90
- return {
91
- projectDir: path.dirname(configPath),
92
- projectConfig,
93
- };
94
- } catch (e) {
95
- logger.error('Could not read from project config');
96
- }
55
+ const getProjectConfig = async (_dir) => {
56
+ const configPath = await getProjectConfigPath(_dir);
57
+ if (!configPath) {
58
+ return { projectConfig: null, projectDir: null };
59
+ }
60
+ try {
61
+ const config = fs.readFileSync(configPath);
62
+ const projectConfig = JSON.parse(config);
63
+ return {
64
+ projectDir: path.dirname(configPath),
65
+ projectConfig,
66
+ };
67
+ }
68
+ catch (e) {
69
+ logger.error('Could not read from project config');
70
+ }
97
71
  };
98
-
99
- const createProjectConfig = async (
100
- projectPath,
101
- projectName,
102
- template,
103
- templateSource,
104
- githubRef
105
- ) => {
106
- const { projectConfig, projectDir } = await getProjectConfig(projectPath);
107
-
108
- if (projectConfig) {
109
- logger.warn(
110
- projectPath === projectDir
111
- ? 'A project already exists in that location.'
112
- : `Found an existing project definition in ${projectDir}.`
113
- );
114
-
115
- const { shouldContinue } = await promptUser([
116
- {
117
- name: 'shouldContinue',
118
- message: () => {
119
- return projectPath === projectDir
120
- ? 'Do you want to overwrite the existing project definition with a new one?'
121
- : `Continue creating a new project in ${projectPath}?`;
122
- },
123
- type: 'confirm',
124
- default: false,
125
- },
126
- ]);
127
-
128
- if (!shouldContinue) {
129
- return false;
72
+ const createProjectConfig = async (projectPath, projectName, template, templateSource, githubRef) => {
73
+ const { projectConfig, projectDir } = await getProjectConfig(projectPath);
74
+ if (projectConfig) {
75
+ logger.warn(projectPath === projectDir
76
+ ? 'A project already exists in that location.'
77
+ : `Found an existing project definition in ${projectDir}.`);
78
+ const { shouldContinue } = await promptUser([
79
+ {
80
+ name: 'shouldContinue',
81
+ message: () => {
82
+ return projectPath === projectDir
83
+ ? 'Do you want to overwrite the existing project definition with a new one?'
84
+ : `Continue creating a new project in ${projectPath}?`;
85
+ },
86
+ type: 'confirm',
87
+ default: false,
88
+ },
89
+ ]);
90
+ if (!shouldContinue) {
91
+ return false;
92
+ }
130
93
  }
131
- }
132
-
133
- const projectConfigPath = path.join(projectPath, PROJECT_CONFIG_FILE);
134
-
135
- logger.log(
136
- `Creating project config in ${
137
- projectPath ? projectPath : 'the current folder'
138
- }`
139
- );
140
-
141
- const hasCustomTemplateSource = Boolean(templateSource);
142
-
143
- await downloadGithubRepoContents(
144
- templateSource || HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH,
145
- template.path,
146
- projectPath,
147
- hasCustomTemplateSource ? undefined : githubRef
148
- );
149
- const _config = JSON.parse(fs.readFileSync(projectConfigPath));
150
- writeProjectConfig(projectConfigPath, {
151
- ..._config,
152
- name: projectName,
153
- });
154
-
155
- if (template.name === 'no-template') {
156
- fs.ensureDirSync(path.join(projectPath, 'src'));
157
- }
158
-
159
- return true;
94
+ const projectConfigPath = path.join(projectPath, PROJECT_CONFIG_FILE);
95
+ logger.log(`Creating project config in ${projectPath ? projectPath : 'the current folder'}`);
96
+ const hasCustomTemplateSource = Boolean(templateSource);
97
+ await downloadGithubRepoContents(templateSource || HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, template.path, projectPath, hasCustomTemplateSource ? undefined : githubRef);
98
+ const _config = JSON.parse(fs.readFileSync(projectConfigPath));
99
+ writeProjectConfig(projectConfigPath, {
100
+ ..._config,
101
+ name: projectName,
102
+ });
103
+ if (template.name === 'no-template') {
104
+ fs.ensureDirSync(path.join(projectPath, 'src'));
105
+ }
106
+ return true;
160
107
  };
161
-
162
108
  const validateProjectConfig = (projectConfig, projectDir) => {
163
- if (!projectConfig) {
164
- logger.error(
165
- `Project config not found. Try running 'hs project create' first.`
166
- );
167
- return process.exit(EXIT_CODES.ERROR);
168
- }
169
-
170
- if (!projectConfig.name || !projectConfig.srcDir) {
171
- logger.error(
172
- 'Project config is missing required fields. Try running `hs project create`.'
173
- );
174
- return process.exit(EXIT_CODES.ERROR);
175
- }
176
-
177
- const resolvedPath = path.resolve(projectDir, projectConfig.srcDir);
178
- if (!resolvedPath.startsWith(projectDir)) {
179
- const projectConfigFile = path.relative(
180
- '.',
181
- path.join(projectDir, PROJECT_CONFIG_FILE)
182
- );
183
- logger.error(
184
- i18n(`${i18nKey}.config.srcOutsideProjectDir`, {
185
- srcDir: projectConfig.srcDir,
186
- projectConfig: projectConfigFile,
187
- })
188
- );
189
- return process.exit(EXIT_CODES.ERROR);
190
- }
191
-
192
- if (!fs.existsSync(resolvedPath)) {
193
- logger.error(
194
- `Project source directory '${projectConfig.srcDir}' could not be found in ${projectDir}.`
195
- );
196
- return process.exit(EXIT_CODES.ERROR);
197
- }
109
+ if (!projectConfig) {
110
+ logger.error(`Project config not found. Try running 'hs project create' first.`);
111
+ return process.exit(EXIT_CODES.ERROR);
112
+ }
113
+ if (!projectConfig.name || !projectConfig.srcDir) {
114
+ logger.error('Project config is missing required fields. Try running `hs project create`.');
115
+ return process.exit(EXIT_CODES.ERROR);
116
+ }
117
+ const resolvedPath = path.resolve(projectDir, projectConfig.srcDir);
118
+ if (!resolvedPath.startsWith(projectDir)) {
119
+ const projectConfigFile = path.relative('.', path.join(projectDir, PROJECT_CONFIG_FILE));
120
+ logger.error(i18n(`${i18nKey}.config.srcOutsideProjectDir`, {
121
+ srcDir: projectConfig.srcDir,
122
+ projectConfig: projectConfigFile,
123
+ }));
124
+ return process.exit(EXIT_CODES.ERROR);
125
+ }
126
+ if (!fs.existsSync(resolvedPath)) {
127
+ logger.error(`Project source directory '${projectConfig.srcDir}' could not be found in ${projectDir}.`);
128
+ return process.exit(EXIT_CODES.ERROR);
129
+ }
198
130
  };
199
-
200
131
  const pollFetchProject = async (accountId, projectName) => {
201
- // Temporary solution for gating slowness. Retry on 403 statusCode
202
- return new Promise((resolve, reject) => {
203
- let pollCount = 0;
204
- SpinniesManager.init();
205
- SpinniesManager.add('pollFetchProject', {
206
- text: i18n(`${i18nKey}.pollFetchProject.checkingProject`, {
207
- accountIdentifier: uiAccountDescription(accountId),
208
- }),
132
+ // Temporary solution for gating slowness. Retry on 403 statusCode
133
+ return new Promise((resolve, reject) => {
134
+ let pollCount = 0;
135
+ SpinniesManager.init();
136
+ SpinniesManager.add('pollFetchProject', {
137
+ text: i18n(`${i18nKey}.pollFetchProject.checkingProject`, {
138
+ accountIdentifier: uiAccountDescription(accountId),
139
+ }),
140
+ });
141
+ const pollInterval = setInterval(async () => {
142
+ try {
143
+ const response = await fetchProject(accountId, projectName);
144
+ if (response && response.data) {
145
+ SpinniesManager.remove('pollFetchProject');
146
+ clearInterval(pollInterval);
147
+ resolve(response);
148
+ }
149
+ }
150
+ catch (err) {
151
+ if (isSpecifiedError(err, {
152
+ statusCode: 403,
153
+ category: 'GATED',
154
+ subCategory: 'BuildPipelineErrorType.PORTAL_GATED',
155
+ }) &&
156
+ pollCount < 15) {
157
+ pollCount += 1;
158
+ }
159
+ else {
160
+ SpinniesManager.remove('pollFetchProject');
161
+ clearInterval(pollInterval);
162
+ reject(err);
163
+ }
164
+ }
165
+ }, POLLING_DELAY);
209
166
  });
210
- const pollInterval = setInterval(async () => {
211
- try {
212
- const response = await fetchProject(accountId, projectName);
213
- if (response && response.data) {
214
- SpinniesManager.remove('pollFetchProject');
215
- clearInterval(pollInterval);
216
- resolve(response);
217
- }
218
- } catch (err) {
219
- if (
220
- isSpecifiedError(err, {
221
- statusCode: 403,
222
- category: 'GATED',
223
- subCategory: 'BuildPipelineErrorType.PORTAL_GATED',
224
- }) &&
225
- pollCount < 15
226
- ) {
227
- pollCount += 1;
228
- } else {
229
- SpinniesManager.remove('pollFetchProject');
230
- clearInterval(pollInterval);
231
- reject(err);
232
- }
233
- }
234
- }, POLLING_DELAY);
235
- });
236
167
  };
237
-
238
- const ensureProjectExists = async (
239
- accountId,
240
- projectName,
241
- {
242
- forceCreate = false,
243
- allowCreate = true,
244
- noLogs = false,
245
- withPolling = false,
246
- uploadCommand = false,
247
- } = {}
248
- ) => {
249
- const accountIdentifier = uiAccountDescription(accountId);
250
- try {
251
- const { data: project } = withPolling
252
- ? await pollFetchProject(accountId, projectName)
253
- : await fetchProject(accountId, projectName);
254
- return { projectExists: !!project, project };
255
- } catch (err) {
256
- if (isSpecifiedError(err, { statusCode: 404 })) {
257
- let shouldCreateProject = forceCreate;
258
- if (allowCreate && !shouldCreateProject) {
259
- const promptKey = uploadCommand ? 'createPromptUpload' : 'createPrompt';
260
- const promptResult = await promptUser([
261
- {
262
- name: 'shouldCreateProject',
263
- message: i18n(`${i18nKey}.ensureProjectExists.${promptKey}`, {
264
- projectName,
265
- accountIdentifier,
266
- }),
267
- type: 'confirm',
268
- },
269
- ]);
270
- shouldCreateProject = promptResult.shouldCreateProject;
271
- }
272
-
273
- if (shouldCreateProject) {
274
- try {
275
- const { data: project } = await createProject(accountId, projectName);
276
- logger.success(
277
- i18n(`${i18nKey}.ensureProjectExists.createSuccess`, {
278
- projectName,
279
- accountIdentifier,
280
- })
281
- );
282
- return { projectExists: true, project };
283
- } catch (err) {
284
- return logError(err, new ApiErrorContext({ accountId }));
168
+ const ensureProjectExists = async (accountId, projectName, { forceCreate = false, allowCreate = true, noLogs = false, withPolling = false, uploadCommand = false, } = {}) => {
169
+ const accountIdentifier = uiAccountDescription(accountId);
170
+ try {
171
+ const { data: project } = withPolling
172
+ ? await pollFetchProject(accountId, projectName)
173
+ : await fetchProject(accountId, projectName);
174
+ return { projectExists: !!project, project };
175
+ }
176
+ catch (err) {
177
+ if (isSpecifiedError(err, { statusCode: 404 })) {
178
+ let shouldCreateProject = forceCreate;
179
+ if (allowCreate && !shouldCreateProject) {
180
+ const promptKey = uploadCommand ? 'createPromptUpload' : 'createPrompt';
181
+ const promptResult = await promptUser([
182
+ {
183
+ name: 'shouldCreateProject',
184
+ message: i18n(`${i18nKey}.ensureProjectExists.${promptKey}`, {
185
+ projectName,
186
+ accountIdentifier,
187
+ }),
188
+ type: 'confirm',
189
+ },
190
+ ]);
191
+ shouldCreateProject = promptResult.shouldCreateProject;
192
+ }
193
+ if (shouldCreateProject) {
194
+ try {
195
+ const { data: project } = await createProject(accountId, projectName);
196
+ logger.success(i18n(`${i18nKey}.ensureProjectExists.createSuccess`, {
197
+ projectName,
198
+ accountIdentifier,
199
+ }));
200
+ return { projectExists: true, project };
201
+ }
202
+ catch (err) {
203
+ return logError(err, new ApiErrorContext({ accountId }));
204
+ }
205
+ }
206
+ else {
207
+ if (!noLogs) {
208
+ logger.log(i18n(`${i18nKey}.ensureProjectExists.notFound`, {
209
+ projectName,
210
+ accountIdentifier,
211
+ }));
212
+ }
213
+ return { projectExists: false };
214
+ }
285
215
  }
286
- } else {
287
- if (!noLogs) {
288
- logger.log(
289
- i18n(`${i18nKey}.ensureProjectExists.notFound`, {
290
- projectName,
291
- accountIdentifier,
292
- })
293
- );
216
+ if (isSpecifiedError(err, {
217
+ statusCode: 401,
218
+ })) {
219
+ logger.error(err.message);
220
+ process.exit(EXIT_CODES.ERROR);
294
221
  }
295
- return { projectExists: false };
296
- }
297
- }
298
- if (
299
- isSpecifiedError(err, {
300
- statusCode: 401,
301
- })
302
- ) {
303
- logger.error(err.message);
304
- process.exit(EXIT_CODES.ERROR);
222
+ logError(err, new ApiErrorContext({ accountId }));
223
+ process.exit(EXIT_CODES.ERROR);
305
224
  }
306
- logError(err, new ApiErrorContext({ accountId }));
307
- process.exit(EXIT_CODES.ERROR);
308
- }
309
225
  };
310
-
311
226
  const getProjectHomeUrl = accountId => {
312
- const baseUrl = getHubSpotWebsiteOrigin(
313
- getEnv(accountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD
314
- );
315
-
316
- return `${baseUrl}/developer-projects/${accountId}`;
227
+ const baseUrl = getHubSpotWebsiteOrigin(getEnv(accountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD);
228
+ return `${baseUrl}/developer-projects/${accountId}`;
317
229
  };
318
-
319
230
  const getProjectDetailUrl = (projectName, accountId) => {
320
- if (!projectName) return;
321
- return `${getProjectHomeUrl(accountId)}/project/${projectName}`;
231
+ if (!projectName)
232
+ return;
233
+ return `${getProjectHomeUrl(accountId)}/project/${projectName}`;
322
234
  };
323
-
324
235
  const getProjectActivityUrl = (projectName, accountId) => {
325
- if (!projectName) return;
326
- return `${getProjectDetailUrl(projectName, accountId)}/activity`;
236
+ if (!projectName)
237
+ return;
238
+ return `${getProjectDetailUrl(projectName, accountId)}/activity`;
327
239
  };
328
-
329
240
  const getProjectBuildDetailUrl = (projectName, buildId, accountId) => {
330
- if (!projectName || !buildId || !accountId) return;
331
- return `${getProjectActivityUrl(projectName, accountId)}/build/${buildId}`;
241
+ if (!projectName || !buildId || !accountId)
242
+ return;
243
+ return `${getProjectActivityUrl(projectName, accountId)}/build/${buildId}`;
332
244
  };
333
-
334
245
  const getProjectDeployDetailUrl = (projectName, deployId, accountId) => {
335
- if (!projectName || !deployId || !accountId) return;
336
- return `${getProjectActivityUrl(projectName, accountId)}/deploy/${deployId}`;
246
+ if (!projectName || !deployId || !accountId)
247
+ return;
248
+ return `${getProjectActivityUrl(projectName, accountId)}/deploy/${deployId}`;
337
249
  };
338
-
339
- const uploadProjectFiles = async (
340
- accountId,
341
- projectName,
342
- filePath,
343
- uploadMessage,
344
- platformVersion
345
- ) => {
346
- SpinniesManager.init({});
347
- const accountIdentifier = uiAccountDescription(accountId);
348
-
349
- SpinniesManager.add('upload', {
350
- text: i18n(`${i18nKey}.uploadProjectFiles.add`, {
351
- accountIdentifier,
352
- projectName,
353
- }),
354
- succeedColor: 'white',
355
- });
356
-
357
- let buildId;
358
- let error;
359
-
360
- try {
361
- const { data: upload } = await uploadProject(
362
- accountId,
363
- projectName,
364
- filePath,
365
- uploadMessage,
366
- platformVersion
367
- );
368
-
369
- buildId = upload.buildId;
370
-
371
- SpinniesManager.succeed('upload', {
372
- text: i18n(`${i18nKey}.uploadProjectFiles.succeed`, {
373
- accountIdentifier,
374
- projectName,
375
- }),
376
- });
377
-
378
- logger.debug(
379
- i18n(`${i18nKey}.uploadProjectFiles.buildCreated`, {
380
- buildId,
381
- projectName,
382
- })
383
- );
384
- } catch (err) {
385
- SpinniesManager.fail('upload', {
386
- text: i18n(`${i18nKey}.uploadProjectFiles.fail`, {
387
- accountIdentifier,
388
- projectName,
389
- }),
250
+ const uploadProjectFiles = async (accountId, projectName, filePath, uploadMessage, platformVersion) => {
251
+ SpinniesManager.init({});
252
+ const accountIdentifier = uiAccountDescription(accountId);
253
+ SpinniesManager.add('upload', {
254
+ text: i18n(`${i18nKey}.uploadProjectFiles.add`, {
255
+ accountIdentifier,
256
+ projectName,
257
+ }),
258
+ succeedColor: 'white',
390
259
  });
391
-
392
- error = err;
393
- }
394
-
395
- return { buildId, error };
396
- };
397
-
398
- const pollProjectBuildAndDeploy = async (
399
- accountId,
400
- projectConfig,
401
- tempFile,
402
- buildId,
403
- silenceLogs = false
404
- ) => {
405
- let buildStatus = await pollBuildStatus(
406
- accountId,
407
- projectConfig.name,
408
- buildId,
409
- null,
410
- silenceLogs
411
- );
412
-
413
- if (!silenceLogs) {
414
- uiLine();
415
- }
416
-
417
- const result = {
418
- succeeded: true,
419
- buildId,
420
- buildResult: buildStatus,
421
- deployResult: null,
422
- };
423
-
424
- if (buildStatus.status === 'FAILURE') {
425
- result.succeeded = false;
426
- return result;
427
- } else if (buildStatus.isAutoDeployEnabled) {
428
- if (!silenceLogs) {
429
- logger.log(
430
- i18n(
431
- `${i18nKey}.pollProjectBuildAndDeploy.buildSucceededAutomaticallyDeploying`,
432
- {
433
- accountIdentifier: uiAccountDescription(accountId),
260
+ let buildId;
261
+ let error;
262
+ try {
263
+ const { data: upload } = await uploadProject(accountId, projectName, filePath, uploadMessage, platformVersion);
264
+ buildId = upload.buildId;
265
+ SpinniesManager.succeed('upload', {
266
+ text: i18n(`${i18nKey}.uploadProjectFiles.succeed`, {
267
+ accountIdentifier,
268
+ projectName,
269
+ }),
270
+ });
271
+ logger.debug(i18n(`${i18nKey}.uploadProjectFiles.buildCreated`, {
434
272
  buildId,
435
- }
436
- )
437
- );
438
-
439
- displayWarnLogs(accountId, projectConfig.name, buildId);
273
+ projectName,
274
+ }));
440
275
  }
441
-
442
- // autoDeployId of 0 indicates a skipped deploy
443
- const getIsDeploying = () =>
444
- buildStatus.autoDeployId > 0 && buildStatus.deployStatusTaskLocator;
445
-
446
- // Sometimes the deploys do not immediately initiate, give them a chance to kick off
447
- if (!getIsDeploying()) {
448
- buildStatus = await pollBuildAutodeployStatus(
449
- accountId,
450
- projectConfig.name,
451
- buildId
452
- );
276
+ catch (err) {
277
+ SpinniesManager.fail('upload', {
278
+ text: i18n(`${i18nKey}.uploadProjectFiles.fail`, {
279
+ accountIdentifier,
280
+ projectName,
281
+ }),
282
+ });
283
+ error = err;
284
+ }
285
+ return { buildId, error };
286
+ };
287
+ const pollProjectBuildAndDeploy = async (accountId, projectConfig, tempFile, buildId, silenceLogs = false) => {
288
+ let buildStatus = await pollBuildStatus(accountId, projectConfig.name, buildId, null, silenceLogs);
289
+ if (!silenceLogs) {
290
+ uiLine();
453
291
  }
454
-
455
- if (getIsDeploying()) {
456
- const deployStatus = await pollDeployStatus(
457
- accountId,
458
- projectConfig.name,
459
- buildStatus.deployStatusTaskLocator.id,
292
+ const result = {
293
+ succeeded: true,
460
294
  buildId,
461
- silenceLogs
462
- );
463
- result.deployResult = deployStatus;
464
-
465
- if (deployStatus.status === 'FAILURE') {
295
+ buildResult: buildStatus,
296
+ deployResult: null,
297
+ };
298
+ if (buildStatus.status === 'FAILURE') {
466
299
  result.succeeded = false;
467
- }
468
- } else if (!silenceLogs) {
469
- logger.log(
470
- i18n(
471
- `${i18nKey}.pollProjectBuildAndDeploy.unableToFindAutodeployStatus`,
472
- {
473
- buildId,
474
- viewDeploysLink: uiLink(
475
- i18n(`${i18nKey}.pollProjectBuildAndDeploy.viewDeploys`),
476
- getProjectActivityUrl(projectConfig.name, accountId)
477
- ),
478
- }
479
- )
480
- );
300
+ return result;
481
301
  }
482
- }
483
-
484
- try {
485
- if (tempFile) {
486
- tempFile.removeCallback();
487
- logger.debug(
488
- i18n(`${i18nKey}.pollProjectBuildAndDeploy.cleanedUpTempFile`, {
489
- path: tempFile.name,
490
- })
491
- );
302
+ else if (buildStatus.isAutoDeployEnabled) {
303
+ if (!silenceLogs) {
304
+ logger.log(i18n(`${i18nKey}.pollProjectBuildAndDeploy.buildSucceededAutomaticallyDeploying`, {
305
+ accountIdentifier: uiAccountDescription(accountId),
306
+ buildId,
307
+ }));
308
+ await displayWarnLogs(accountId, projectConfig.name, buildId);
309
+ }
310
+ // autoDeployId of 0 indicates a skipped deploy
311
+ const getIsDeploying = () => buildStatus.autoDeployId > 0 && buildStatus.deployStatusTaskLocator;
312
+ // Sometimes the deploys do not immediately initiate, give them a chance to kick off
313
+ if (!getIsDeploying()) {
314
+ buildStatus = await pollBuildAutodeployStatus(accountId, projectConfig.name, buildId);
315
+ }
316
+ if (getIsDeploying()) {
317
+ const deployStatus = await pollDeployStatus(accountId, projectConfig.name, buildStatus.deployStatusTaskLocator.id, buildId, silenceLogs);
318
+ result.deployResult = deployStatus;
319
+ if (deployStatus.status === 'FAILURE') {
320
+ result.succeeded = false;
321
+ }
322
+ }
323
+ else if (!silenceLogs) {
324
+ logger.log(i18n(`${i18nKey}.pollProjectBuildAndDeploy.unableToFindAutodeployStatus`, {
325
+ buildId,
326
+ viewDeploysLink: uiLink(i18n(`${i18nKey}.pollProjectBuildAndDeploy.viewDeploys`), getProjectActivityUrl(projectConfig.name, accountId)),
327
+ }));
328
+ }
492
329
  }
493
- } catch (e) {
494
- logger.error(e);
495
- }
496
-
497
- if (result && result.deployResult) {
498
- displayWarnLogs(
499
- accountId,
500
- projectConfig.name,
501
- result.deployResult.deployId,
502
- true
503
- );
504
- }
505
- return result;
506
- };
507
-
508
- const handleProjectUpload = async (
509
- accountId,
510
- projectConfig,
511
- projectDir,
512
- callbackFunc,
513
- uploadMessage
514
- ) => {
515
- const srcDir = path.resolve(projectDir, projectConfig.srcDir);
516
-
517
- const filenames = fs.readdirSync(srcDir);
518
- if (!filenames || filenames.length === 0) {
519
- logger.log(
520
- i18n(`${i18nKey}.handleProjectUpload.emptySource`, {
521
- srcDir: projectConfig.srcDir,
522
- })
523
- );
524
- process.exit(EXIT_CODES.SUCCESS);
525
- }
526
-
527
- const tempFile = tmp.fileSync({ postfix: '.zip' });
528
-
529
- logger.debug(
530
- i18n(`${i18nKey}.handleProjectUpload.compressing`, {
531
- path: tempFile.name,
532
- })
533
- );
534
-
535
- const output = fs.createWriteStream(tempFile.name);
536
- const archive = archiver('zip');
537
-
538
- const result = new Promise(resolve =>
539
- output.on('close', async function() {
540
- let uploadResult = {};
541
-
542
- logger.debug(
543
- i18n(`${i18nKey}.handleProjectUpload.compressed`, {
544
- byteCount: archive.pointer(),
545
- })
546
- );
547
-
548
- const { buildId, error } = await uploadProjectFiles(
549
- accountId,
550
- projectConfig.name,
551
- tempFile.name,
552
- uploadMessage,
553
- projectConfig.platformVersion
554
- );
555
-
556
- if (error) {
557
- uploadResult.uploadError = error;
558
- } else if (callbackFunc) {
559
- uploadResult = await callbackFunc(
560
- accountId,
561
- projectConfig,
562
- tempFile,
563
- buildId
564
- );
565
- }
566
- resolve(uploadResult || {});
567
- })
568
- );
569
-
570
- archive.pipe(output);
571
-
572
- let loggedIgnoredNodeModule = false;
573
-
574
- archive.directory(srcDir, false, file => {
575
- const ignored = shouldIgnoreFile(file.name, true);
576
- if (ignored) {
577
- const isNodeModule = file.name.includes('node_modules');
578
-
579
- if (!isNodeModule || !loggedIgnoredNodeModule) {
580
- logger.debug(
581
- i18n(`${i18nKey}.handleProjectUpload.fileFiltered`, {
582
- filename: file.name,
583
- })
584
- );
585
- }
586
-
587
- if (isNodeModule && !loggedIgnoredNodeModule) {
588
- loggedIgnoredNodeModule = true;
589
- }
330
+ try {
331
+ if (tempFile) {
332
+ tempFile.removeCallback();
333
+ logger.debug(i18n(`${i18nKey}.pollProjectBuildAndDeploy.cleanedUpTempFile`, {
334
+ path: tempFile.name,
335
+ }));
336
+ }
590
337
  }
591
- return ignored ? false : file;
592
- });
593
-
594
- archive.finalize();
595
-
596
- return result;
338
+ catch (e) {
339
+ logger.error(e);
340
+ }
341
+ if (result && result.deployResult) {
342
+ await displayWarnLogs(accountId, projectConfig.name, result.deployResult.deployId, true);
343
+ }
344
+ return result;
597
345
  };
598
-
599
- const makePollTaskStatusFunc = ({
600
- statusFn,
601
- structureFn,
602
- statusText,
603
- statusStrings,
604
- linkToHubSpot,
605
- }) => {
606
- return async (
607
- accountId,
608
- taskName,
609
- taskId,
610
- deployedBuildId = null,
611
- silenceLogs = false
612
- ) => {
613
- const displayId = deployedBuildId || taskId;
614
-
615
- if (linkToHubSpot && !silenceLogs) {
616
- logger.log(
617
- `\n${linkToHubSpot(accountId, taskName, taskId, deployedBuildId)}\n`
618
- );
346
+ const handleProjectUpload = async (accountId, projectConfig, projectDir, callbackFunc, uploadMessage) => {
347
+ const srcDir = path.resolve(projectDir, projectConfig.srcDir);
348
+ const filenames = fs.readdirSync(srcDir);
349
+ if (!filenames || filenames.length === 0) {
350
+ logger.log(i18n(`${i18nKey}.handleProjectUpload.emptySource`, {
351
+ srcDir: projectConfig.srcDir,
352
+ }));
353
+ process.exit(EXIT_CODES.SUCCESS);
619
354
  }
620
-
621
- SpinniesManager.init();
622
-
623
- const overallTaskSpinniesKey = `overallTaskStatus-${statusText.STATUS_TEXT}`;
624
-
625
- SpinniesManager.add(overallTaskSpinniesKey, {
626
- text: 'Beginning',
627
- succeedColor: 'white',
628
- failColor: 'white',
629
- failPrefix: chalk.bold('!'),
630
- });
631
-
632
- const [
633
- { data: initialTaskStatus },
634
- {
635
- data: { topLevelComponentsWithChildren: taskStructure },
636
- },
637
- ] = await Promise.all([
638
- statusFn(accountId, taskName, taskId),
639
- structureFn(accountId, taskName, taskId),
640
- ]);
641
-
642
- const tasksById = initialTaskStatus[statusText.SUBTASK_KEY].reduce(
643
- (acc, task) => {
644
- const { id, visible } = task;
645
- if (visible) {
646
- acc[id] = task;
355
+ const tempFile = tmp.fileSync({ postfix: '.zip' });
356
+ logger.debug(i18n(`${i18nKey}.handleProjectUpload.compressing`, {
357
+ path: tempFile.name,
358
+ }));
359
+ const output = fs.createWriteStream(tempFile.name);
360
+ const archive = archiver('zip');
361
+ const result = new Promise(resolve => output.on('close', async function () {
362
+ let uploadResult = {};
363
+ logger.debug(i18n(`${i18nKey}.handleProjectUpload.compressed`, {
364
+ byteCount: archive.pointer(),
365
+ }));
366
+ const { buildId, error } = await uploadProjectFiles(accountId, projectConfig.name, tempFile.name, uploadMessage, projectConfig.platformVersion);
367
+ if (error) {
368
+ uploadResult.uploadError = error;
647
369
  }
648
- return acc;
649
- },
650
- {}
651
- );
652
-
653
- const structuredTasks = Object.keys(taskStructure).map(key => {
654
- return {
655
- ...tasksById[key],
656
- subtasks: taskStructure[key]
657
- .filter(taskId => Boolean(tasksById[taskId]))
658
- .map(taskId => tasksById[taskId]),
659
- };
660
- });
661
-
662
- const numComponents = structuredTasks.length;
663
- const componentCountText = silenceLogs
664
- ? ''
665
- : i18n(
666
- numComponents === 1
667
- ? `${i18nKey}.makePollTaskStatusFunc.componentCountSingular`
668
- : `${i18nKey}.makePollTaskStatusFunc.componentCount`,
669
- { numComponents }
670
- ) + '\n';
671
-
672
- SpinniesManager.update(overallTaskSpinniesKey, {
673
- text: `${statusStrings.INITIALIZE(
674
- taskName,
675
- displayId
676
- )}\n${componentCountText}`,
370
+ else if (callbackFunc) {
371
+ uploadResult = await callbackFunc(accountId, projectConfig, tempFile, buildId);
372
+ }
373
+ resolve(uploadResult || {});
374
+ }));
375
+ archive.pipe(output);
376
+ let loggedIgnoredNodeModule = false;
377
+ archive.directory(srcDir, false, file => {
378
+ const ignored = shouldIgnoreFile(file.name, true);
379
+ if (ignored) {
380
+ const isNodeModule = file.name.includes('node_modules');
381
+ if (!isNodeModule || !loggedIgnoredNodeModule) {
382
+ logger.debug(i18n(`${i18nKey}.handleProjectUpload.fileFiltered`, {
383
+ filename: file.name,
384
+ }));
385
+ }
386
+ if (isNodeModule && !loggedIgnoredNodeModule) {
387
+ loggedIgnoredNodeModule = true;
388
+ }
389
+ }
390
+ return ignored ? false : file;
677
391
  });
678
-
679
- if (!silenceLogs) {
680
- const addTaskSpinner = (task, indent, newline) => {
681
- const taskName = task[statusText.SUBTASK_NAME_KEY];
682
- const taskType = task[statusText.TYPE_KEY];
683
- const formattedTaskType = PROJECT_TASK_TYPES[taskType]
684
- ? `[${PROJECT_TASK_TYPES[taskType]}]`
685
- : '';
686
- const text = `${indent <= 2 ? statusText.STATUS_TEXT : ''} ${chalk.bold(
687
- taskName
688
- )} ${formattedTaskType} ...${newline ? '\n' : ''}`;
689
-
690
- SpinniesManager.add(task.id, {
691
- text,
692
- indent,
693
- succeedColor: 'white',
694
- failColor: 'white',
392
+ archive.finalize();
393
+ return result;
394
+ };
395
+ const makePollTaskStatusFunc = ({ statusFn, structureFn, statusText, statusStrings, linkToHubSpot, }) => {
396
+ return async (accountId, taskName, taskId, deployedBuildId = null, silenceLogs = false) => {
397
+ const displayId = deployedBuildId || taskId;
398
+ if (linkToHubSpot && !silenceLogs) {
399
+ logger.log(`\n${linkToHubSpot(accountId, taskName, taskId, deployedBuildId)}\n`);
400
+ }
401
+ SpinniesManager.init();
402
+ const overallTaskSpinniesKey = `overallTaskStatus-${statusText.STATUS_TEXT}`;
403
+ SpinniesManager.add(overallTaskSpinniesKey, {
404
+ text: 'Beginning',
405
+ succeedColor: 'white',
406
+ failColor: 'white',
407
+ failPrefix: chalk.bold('!'),
695
408
  });
696
- };
697
-
698
- structuredTasks.forEach(task => {
699
- addTaskSpinner(task, 2, !task.subtasks || task.subtasks.length === 0);
700
- task.subtasks.forEach((subtask, i) =>
701
- addTaskSpinner(subtask, 4, i === task.subtasks.length - 1)
702
- );
703
- });
704
- }
705
-
706
- return new Promise((resolve, reject) => {
707
- const pollInterval = setInterval(async () => {
708
- let taskStatus;
709
- try {
710
- const { data } = await statusFn(accountId, taskName, taskId);
711
- taskStatus = data;
712
- } catch (e) {
713
- logger.debug(e);
714
- logError(
715
- e,
716
- new ApiErrorContext({
717
- accountId,
718
- projectName: taskName,
719
- })
720
- );
721
- return reject(
722
- new Error(
723
- i18n(
724
- `${i18nKey}.makePollTaskStatusFunc.errorFetchingTaskStatus`,
725
- {
726
- taskType:
727
- statusText.TYPE_KEY === PROJECT_BUILD_TEXT.TYPE_KEY
728
- ? 'build'
729
- : 'deploy',
730
- }
731
- )
732
- )
733
- );
409
+ const [{ data: initialTaskStatus }, { data: { topLevelComponentsWithChildren: taskStructure }, },] = await Promise.all([
410
+ statusFn(accountId, taskName, taskId),
411
+ structureFn(accountId, taskName, taskId),
412
+ ]);
413
+ const tasksById = initialTaskStatus[statusText.SUBTASK_KEY].reduce((acc, task) => {
414
+ const { id, visible } = task;
415
+ if (visible) {
416
+ acc[id] = task;
417
+ }
418
+ return acc;
419
+ }, {});
420
+ const structuredTasks = Object.keys(taskStructure).map(key => {
421
+ return {
422
+ ...tasksById[key],
423
+ subtasks: taskStructure[key]
424
+ .filter(taskId => Boolean(tasksById[taskId]))
425
+ .map(taskId => tasksById[taskId]),
426
+ };
427
+ });
428
+ const numComponents = structuredTasks.length;
429
+ const componentCountText = silenceLogs
430
+ ? ''
431
+ : i18n(numComponents === 1
432
+ ? `${i18nKey}.makePollTaskStatusFunc.componentCountSingular`
433
+ : `${i18nKey}.makePollTaskStatusFunc.componentCount`, { numComponents }) + '\n';
434
+ SpinniesManager.update(overallTaskSpinniesKey, {
435
+ text: `${statusStrings.INITIALIZE(taskName, displayId)}\n${componentCountText}`,
436
+ });
437
+ if (!silenceLogs) {
438
+ const addTaskSpinner = (task, indent, newline) => {
439
+ const taskName = task[statusText.SUBTASK_NAME_KEY];
440
+ const taskType = task[statusText.TYPE_KEY];
441
+ const formattedTaskType = PROJECT_TASK_TYPES[taskType]
442
+ ? `[${PROJECT_TASK_TYPES[taskType]}]`
443
+ : '';
444
+ const text = `${indent <= 2 ? statusText.STATUS_TEXT : ''} ${chalk.bold(taskName)} ${formattedTaskType} ...${newline ? '\n' : ''}`;
445
+ SpinniesManager.add(task.id, {
446
+ text,
447
+ indent,
448
+ succeedColor: 'white',
449
+ failColor: 'white',
450
+ });
451
+ };
452
+ structuredTasks.forEach(task => {
453
+ addTaskSpinner(task, 2, !task.subtasks || task.subtasks.length === 0);
454
+ task.subtasks.forEach((subtask, i) => addTaskSpinner(subtask, 4, i === task.subtasks.length - 1));
455
+ });
734
456
  }
735
-
736
- if (
737
- !taskStatus ||
738
- !taskStatus.status ||
739
- !taskStatus[statusText.SUBTASK_KEY]
740
- ) {
741
- return reject(
742
- new Error(
743
- i18n(
744
- `${i18nKey}.makePollTaskStatusFunc.errorFetchingTaskStatus`,
745
- {
746
- taskType:
747
- statusText.TYPE_KEY === PROJECT_BUILD_TEXT.TYPE_KEY
748
- ? 'build'
749
- : 'deploy',
457
+ return new Promise((resolve, reject) => {
458
+ const pollInterval = setInterval(async () => {
459
+ let taskStatus;
460
+ try {
461
+ const { data } = await statusFn(accountId, taskName, taskId);
462
+ taskStatus = data;
750
463
  }
751
- )
752
- )
753
- );
754
- }
755
-
756
- const { status, [statusText.SUBTASK_KEY]: subTaskStatus } = taskStatus;
757
-
758
- if (SpinniesManager.hasActiveSpinners()) {
759
- subTaskStatus.forEach(subTask => {
760
- const { id, status } = subTask;
761
- const spinner = SpinniesManager.pick(id);
762
-
763
- if (!spinner || spinner.status !== SPINNER_STATUS.SPINNING) {
764
- return;
464
+ catch (e) {
465
+ logger.debug(e);
466
+ logError(e, new ApiErrorContext({
467
+ accountId,
468
+ projectName: taskName,
469
+ }));
470
+ return reject(new Error(i18n(`${i18nKey}.makePollTaskStatusFunc.errorFetchingTaskStatus`, {
471
+ taskType: statusText.TYPE_KEY === PROJECT_BUILD_TEXT.TYPE_KEY
472
+ ? 'build'
473
+ : 'deploy',
474
+ })));
475
+ }
476
+ if (!taskStatus ||
477
+ !taskStatus.status ||
478
+ !taskStatus[statusText.SUBTASK_KEY]) {
479
+ return reject(new Error(i18n(`${i18nKey}.makePollTaskStatusFunc.errorFetchingTaskStatus`, {
480
+ taskType: statusText.TYPE_KEY === PROJECT_BUILD_TEXT.TYPE_KEY
481
+ ? 'build'
482
+ : 'deploy',
483
+ })));
484
+ }
485
+ const { status, [statusText.SUBTASK_KEY]: subTaskStatus } = taskStatus;
486
+ if (SpinniesManager.hasActiveSpinners()) {
487
+ subTaskStatus.forEach(subTask => {
488
+ const { id, status } = subTask;
489
+ const spinner = SpinniesManager.pick(id);
490
+ if (!spinner || spinner.status !== SPINNER_STATUS.SPINNING) {
491
+ return;
492
+ }
493
+ const topLevelTask = structuredTasks.find(t => t.id == id);
494
+ if (status === statusText.STATES.SUCCESS ||
495
+ status === statusText.STATES.FAILURE) {
496
+ const taskStatusText = subTask.status === statusText.STATES.SUCCESS
497
+ ? i18n(`${i18nKey}.makePollTaskStatusFunc.successStatusText`)
498
+ : i18n(`${i18nKey}.makePollTaskStatusFunc.failedStatusText`);
499
+ const hasNewline = spinner.text.includes('\n') || Boolean(topLevelTask);
500
+ const updatedText = `${spinner.text.replace('\n', '')} ${taskStatusText}${hasNewline ? '\n' : ''}`;
501
+ if (status === statusText.STATES.SUCCESS) {
502
+ SpinniesManager.succeed(id, { text: updatedText });
503
+ }
504
+ else {
505
+ SpinniesManager.fail(id, { text: updatedText });
506
+ }
507
+ if (topLevelTask) {
508
+ topLevelTask.subtasks.forEach(currentSubtask => SpinniesManager.remove(currentSubtask.id));
509
+ }
510
+ }
511
+ });
512
+ if (status === statusText.STATES.SUCCESS) {
513
+ SpinniesManager.succeed(overallTaskSpinniesKey, {
514
+ text: statusStrings.SUCCESS(taskName, displayId),
515
+ });
516
+ clearInterval(pollInterval);
517
+ resolve(taskStatus);
518
+ }
519
+ else if (status === statusText.STATES.FAILURE) {
520
+ SpinniesManager.fail(overallTaskSpinniesKey, {
521
+ text: statusStrings.FAIL(taskName, displayId),
522
+ });
523
+ if (!silenceLogs) {
524
+ const failedSubtasks = subTaskStatus.filter(subtask => subtask.status === 'FAILURE');
525
+ uiLine();
526
+ logger.log(`${statusStrings.SUBTASK_FAIL(displayId, failedSubtasks.length === 1
527
+ ? failedSubtasks[0][statusText.SUBTASK_NAME_KEY]
528
+ : failedSubtasks.length + ' components')}\n`);
529
+ logger.log('See below for a summary of errors.');
530
+ uiLine();
531
+ const displayErrors = failedSubtasks.filter(subtask => subtask.standardError.subCategory !==
532
+ PROJECT_ERROR_TYPES.SUBBUILD_FAILED &&
533
+ subtask.standardError.subCategory !==
534
+ PROJECT_ERROR_TYPES.SUBDEPLOY_FAILED);
535
+ displayErrors.forEach(subTask => {
536
+ logger.log(`\n--- ${chalk.bold(subTask[statusText.SUBTASK_NAME_KEY])} failed with the following error ---`);
537
+ logger.error(subTask.errorMessage);
538
+ // Log nested errors
539
+ if (subTask.standardError && subTask.standardError.errors) {
540
+ logger.log();
541
+ subTask.standardError.errors.forEach(error => {
542
+ logger.log(error.message);
543
+ });
544
+ }
545
+ });
546
+ }
547
+ clearInterval(pollInterval);
548
+ resolve(taskStatus);
549
+ }
550
+ else if (!subTaskStatus.length) {
551
+ clearInterval(pollInterval);
552
+ resolve(taskStatus);
553
+ }
554
+ }
555
+ }, POLLING_DELAY);
556
+ });
557
+ };
558
+ };
559
+ const pollBuildAutodeployStatus = (accountId, taskName, buildId) => {
560
+ return new Promise((resolve, reject) => {
561
+ let maxIntervals = (30 * 1000) / POLLING_DELAY; // Num of intervals in ~30s
562
+ const pollInterval = setInterval(async () => {
563
+ let taskStatus;
564
+ try {
565
+ taskStatus = await getBuildStatus(accountId, taskName, buildId);
765
566
  }
766
-
767
- const topLevelTask = structuredTasks.find(t => t.id == id);
768
-
769
- if (
770
- status === statusText.STATES.SUCCESS ||
771
- status === statusText.STATES.FAILURE
772
- ) {
773
- const taskStatusText =
774
- subTask.status === statusText.STATES.SUCCESS
775
- ? i18n(`${i18nKey}.makePollTaskStatusFunc.successStatusText`)
776
- : i18n(`${i18nKey}.makePollTaskStatusFunc.failedStatusText`);
777
- const hasNewline =
778
- spinner.text.includes('\n') || Boolean(topLevelTask);
779
- const updatedText = `${spinner.text.replace(
780
- '\n',
781
- ''
782
- )} ${taskStatusText}${hasNewline ? '\n' : ''}`;
783
-
784
- status === statusText.STATES.SUCCESS
785
- ? SpinniesManager.succeed(id, { text: updatedText })
786
- : SpinniesManager.fail(id, { text: updatedText });
787
-
788
- if (topLevelTask) {
789
- topLevelTask.subtasks.forEach(currentSubtask =>
790
- SpinniesManager.remove(currentSubtask.id)
791
- );
792
- }
567
+ catch (e) {
568
+ logger.debug(e);
569
+ return reject(new Error(i18n(`${i18nKey}.pollBuildAutodeployStatusError`, { buildId })));
793
570
  }
794
- });
795
-
796
- if (status === statusText.STATES.SUCCESS) {
797
- SpinniesManager.succeed(overallTaskSpinniesKey, {
798
- text: statusStrings.SUCCESS(taskName, displayId),
799
- });
800
- clearInterval(pollInterval);
801
- resolve(taskStatus);
802
- } else if (status === statusText.STATES.FAILURE) {
803
- SpinniesManager.fail(overallTaskSpinniesKey, {
804
- text: statusStrings.FAIL(taskName, displayId),
805
- });
806
-
807
- if (!silenceLogs) {
808
- const failedSubtasks = subTaskStatus.filter(
809
- subtask => subtask.status === 'FAILURE'
810
- );
811
-
812
- uiLine();
813
- logger.log(
814
- `${statusStrings.SUBTASK_FAIL(
815
- displayId,
816
- failedSubtasks.length === 1
817
- ? failedSubtasks[0][statusText.SUBTASK_NAME_KEY]
818
- : failedSubtasks.length + ' components'
819
- )}\n`
820
- );
821
- logger.log('See below for a summary of errors.');
822
- uiLine();
823
-
824
- const displayErrors = failedSubtasks.filter(
825
- subtask =>
826
- subtask.standardError.subCategory !==
827
- PROJECT_ERROR_TYPES.SUBBUILD_FAILED &&
828
- subtask.standardError.subCategory !==
829
- PROJECT_ERROR_TYPES.SUBDEPLOY_FAILED
830
- );
831
-
832
- displayErrors.forEach(subTask => {
833
- logger.log(
834
- `\n--- ${chalk.bold(
835
- subTask[statusText.SUBTASK_NAME_KEY]
836
- )} failed with the following error ---`
837
- );
838
- logger.error(subTask.errorMessage);
839
-
840
- // Log nested errors
841
- if (subTask.standardError && subTask.standardError.errors) {
842
- logger.log();
843
- subTask.standardError.errors.forEach(error => {
844
- logger.log(error.message);
845
- });
846
- }
847
- });
571
+ if (!taskStatus || !taskStatus.status) {
572
+ return reject(new Error(i18n(`${i18nKey}.pollBuildAutodeployStatusError`, { buildId })));
848
573
  }
849
- clearInterval(pollInterval);
850
- resolve(taskStatus);
851
- } else if (!subTaskStatus.length) {
852
- clearInterval(pollInterval);
853
- resolve(taskStatus);
854
- }
855
- }
856
- }, POLLING_DELAY);
574
+ if (taskStatus.deployStatusTaskLocator || maxIntervals <= 0) {
575
+ clearInterval(pollInterval);
576
+ resolve(taskStatus);
577
+ }
578
+ else {
579
+ maxIntervals -= 1;
580
+ }
581
+ }, POLLING_DELAY);
857
582
  });
858
- };
859
- };
860
-
861
- const pollBuildAutodeployStatus = (accountId, taskName, buildId) => {
862
- return new Promise((resolve, reject) => {
863
- let maxIntervals = (30 * 1000) / POLLING_DELAY; // Num of intervals in ~30s
864
-
865
- const pollInterval = setInterval(async () => {
866
- let taskStatus;
867
- try {
868
- taskStatus = await getBuildStatus(accountId, taskName, buildId);
869
- } catch (e) {
870
- logger.debug(e);
871
- return reject(
872
- new Error(
873
- i18n(`${i18nKey}.pollBuildAutodeployStatusError`, { buildId })
874
- )
875
- );
876
- }
877
-
878
- if (!taskStatus || !taskStatus.status) {
879
- return reject(
880
- new Error(
881
- i18n(`${i18nKey}.pollBuildAutodeployStatusError`, { buildId })
882
- )
883
- );
884
- }
885
-
886
- if (taskStatus.deployStatusTaskLocator || maxIntervals <= 0) {
887
- clearInterval(pollInterval);
888
- resolve(taskStatus);
889
- } else {
890
- maxIntervals -= 1;
891
- }
892
- }, POLLING_DELAY);
893
- });
894
583
  };
895
-
896
584
  const pollBuildStatus = makePollTaskStatusFunc({
897
- linkToHubSpot: (accountId, taskName, taskId) =>
898
- uiLink(
899
- `View build #${taskId} in HubSpot`,
900
- getProjectBuildDetailUrl(taskName, taskId, accountId)
901
- ),
902
- statusFn: getBuildStatus,
903
- structureFn: getBuildStructure,
904
- statusText: PROJECT_BUILD_TEXT,
905
- statusStrings: {
906
- INITIALIZE: (name, buildId) => `Building ${chalk.bold(name)} #${buildId}`,
907
- SUCCESS: (name, buildId) => `Built ${chalk.bold(name)} #${buildId}`,
908
- FAIL: (name, buildId) => `Failed to build ${chalk.bold(name)} #${buildId}`,
909
- SUBTASK_FAIL: (buildId, name) =>
910
- `Build #${buildId} failed because there was a problem\nbuilding ${chalk.bold(
911
- name
912
- )}`,
913
- },
585
+ linkToHubSpot: (accountId, taskName, taskId) => uiLink(`View build #${taskId} in HubSpot`, getProjectBuildDetailUrl(taskName, taskId, accountId)),
586
+ statusFn: getBuildStatus,
587
+ structureFn: getBuildStructure,
588
+ statusText: PROJECT_BUILD_TEXT,
589
+ statusStrings: {
590
+ INITIALIZE: (name, buildId) => `Building ${chalk.bold(name)} #${buildId}`,
591
+ SUCCESS: (name, buildId) => `Built ${chalk.bold(name)} #${buildId}`,
592
+ FAIL: (name, buildId) => `Failed to build ${chalk.bold(name)} #${buildId}`,
593
+ SUBTASK_FAIL: (buildId, name) => `Build #${buildId} failed because there was a problem\nbuilding ${chalk.bold(name)}`,
594
+ },
914
595
  });
915
-
916
596
  const pollDeployStatus = makePollTaskStatusFunc({
917
- linkToHubSpot: (accountId, taskName, taskId, deployedBuildId) =>
918
- uiLink(
919
- `View deploy of build #${deployedBuildId} in HubSpot`,
920
- getProjectDeployDetailUrl(taskName, taskId, accountId)
921
- ),
922
- statusFn: getDeployStatus,
923
- structureFn: getDeployStructure,
924
- statusText: PROJECT_DEPLOY_TEXT,
925
- statusStrings: {
926
- INITIALIZE: (name, buildId) =>
927
- `Deploying build #${buildId} in ${chalk.bold(name)}`,
928
- SUCCESS: (name, buildId) =>
929
- `Deployed build #${buildId} in ${chalk.bold(name)}`,
930
- FAIL: (name, buildId) =>
931
- `Failed to deploy build #${buildId} in ${chalk.bold(name)}`,
932
- SUBTASK_FAIL: (deployedBuildId, name) =>
933
- `Deploy for build #${deployedBuildId} failed because there was a\nproblem deploying ${chalk.bold(
934
- name
935
- )}`,
936
- },
597
+ linkToHubSpot: (accountId, taskName, taskId, deployedBuildId) => uiLink(`View deploy of build #${deployedBuildId} in HubSpot`, getProjectDeployDetailUrl(taskName, taskId, accountId)),
598
+ statusFn: getDeployStatus,
599
+ structureFn: getDeployStructure,
600
+ statusText: PROJECT_DEPLOY_TEXT,
601
+ statusStrings: {
602
+ INITIALIZE: (name, buildId) => `Deploying build #${buildId} in ${chalk.bold(name)}`,
603
+ SUCCESS: (name, buildId) => `Deployed build #${buildId} in ${chalk.bold(name)}`,
604
+ FAIL: (name, buildId) => `Failed to deploy build #${buildId} in ${chalk.bold(name)}`,
605
+ SUBTASK_FAIL: (deployedBuildId, name) => `Deploy for build #${deployedBuildId} failed because there was a\nproblem deploying ${chalk.bold(name)}`,
606
+ },
937
607
  });
938
-
939
608
  const logFeedbackMessage = buildId => {
940
- if (buildId > 0 && buildId % FEEDBACK_INTERVAL === 0) {
941
- uiLine();
942
- logger.log(i18n(`${i18nKey}.logFeedbackMessage.feedbackHeader`));
943
- uiLine();
944
- logger.log(i18n(`${i18nKey}.logFeedbackMessage.feedbackMessage`));
945
- }
609
+ if (buildId > 0 && buildId % FEEDBACK_INTERVAL === 0) {
610
+ uiLine();
611
+ logger.log(i18n(`${i18nKey}.logFeedbackMessage.feedbackHeader`));
612
+ uiLine();
613
+ logger.log(i18n(`${i18nKey}.logFeedbackMessage.feedbackMessage`));
614
+ }
946
615
  };
947
-
948
- const createProjectComponent = async (
949
- component,
950
- name,
951
- projectComponentsVersion
952
- ) => {
953
- const i18nKey = 'commands.project.subcommands.add';
954
- let componentName = name;
955
-
956
- const configInfo = await getProjectConfig();
957
-
958
- if (!configInfo.projectDir && !configInfo.projectConfig) {
959
- logger.error(i18n(`${i18nKey}.error.locationInProject`));
960
- process.exit(EXIT_CODES.ERROR);
961
- }
962
-
963
- const componentPath = path.join(
964
- configInfo.projectDir,
965
- configInfo.projectConfig.srcDir,
966
- component.insertPath,
967
- componentName
968
- );
969
-
970
- await downloadGithubRepoContents(
971
- HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH,
972
- component.path,
973
- componentPath,
974
- projectComponentsVersion
975
- );
616
+ const createProjectComponent = async (component, name, projectComponentsVersion) => {
617
+ const i18nKey = 'commands.project.subcommands.add';
618
+ const componentName = name;
619
+ const configInfo = await getProjectConfig();
620
+ if (!configInfo.projectDir && !configInfo.projectConfig) {
621
+ logger.error(i18n(`${i18nKey}.error.locationInProject`));
622
+ process.exit(EXIT_CODES.ERROR);
623
+ }
624
+ const componentPath = path.join(configInfo.projectDir, configInfo.projectConfig.srcDir, component.insertPath, componentName);
625
+ await downloadGithubRepoContents(HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, component.path, componentPath, projectComponentsVersion);
976
626
  };
977
-
978
- const displayWarnLogs = async (
979
- accountId,
980
- projectName,
981
- taskId,
982
- isDeploy = false
983
- ) => {
984
- let result;
985
-
986
- if (isDeploy) {
987
- try {
988
- const { data } = await fetchDeployWarnLogs(
989
- accountId,
990
- projectName,
991
- taskId
992
- );
993
- result = data;
994
- } catch (e) {
995
- logError(e);
627
+ const displayWarnLogs = async (accountId, projectName, taskId, isDeploy = false) => {
628
+ let result;
629
+ if (isDeploy) {
630
+ try {
631
+ const { data } = await fetchDeployWarnLogs(accountId, projectName, taskId);
632
+ result = data;
633
+ }
634
+ catch (e) {
635
+ logError(e);
636
+ }
996
637
  }
997
- } else {
998
- try {
999
- const { data } = await fetchBuildWarnLogs(accountId, projectName, taskId);
1000
- result = data;
1001
- } catch (e) {
1002
- logError(e);
638
+ else {
639
+ try {
640
+ const { data } = await fetchBuildWarnLogs(accountId, projectName, taskId);
641
+ result = data;
642
+ }
643
+ catch (e) {
644
+ logError(e);
645
+ }
646
+ }
647
+ if (result && result.logs) {
648
+ const logLength = result.logs.length;
649
+ result.logs.forEach((log, i) => {
650
+ logger.warn(log.message);
651
+ if (i < logLength - 1) {
652
+ logger.log('');
653
+ }
654
+ });
1003
655
  }
1004
- }
1005
-
1006
- if (result && result.logs.length) {
1007
- result.logs.forEach(log => {
1008
- logger.warn(log.message);
1009
- logger.log('');
1010
- });
1011
- }
1012
656
  };
1013
-
1014
- const getProjectComponentsByVersion = async projectComponentsVersion => {
1015
- const config = await fetchFileFromRepository(
1016
- HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH,
1017
- 'config.json',
1018
- projectComponentsVersion
1019
- );
1020
-
1021
- return config[PROJECT_COMPONENT_TYPES.COMPONENTS];
657
+ const getProjectComponentsByVersion = async (projectComponentsVersion) => {
658
+ const config = await fetchFileFromRepository(HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, 'config.json', projectComponentsVersion);
659
+ return config[PROJECT_COMPONENT_TYPES.COMPONENTS];
1022
660
  };
1023
-
1024
661
  module.exports = {
1025
- writeProjectConfig,
1026
- getProjectConfig,
1027
- getIsInProject,
1028
- pollProjectBuildAndDeploy,
1029
- handleProjectUpload,
1030
- createProjectConfig,
1031
- validateProjectConfig,
1032
- getProjectHomeUrl,
1033
- getProjectDetailUrl,
1034
- getProjectBuildDetailUrl,
1035
- pollBuildStatus,
1036
- pollDeployStatus,
1037
- ensureProjectExists,
1038
- logFeedbackMessage,
1039
- createProjectComponent,
1040
- displayWarnLogs,
1041
- getProjectComponentsByVersion,
662
+ writeProjectConfig,
663
+ getProjectConfig,
664
+ getIsInProject,
665
+ pollProjectBuildAndDeploy,
666
+ handleProjectUpload,
667
+ createProjectConfig,
668
+ validateProjectConfig,
669
+ getProjectHomeUrl,
670
+ getProjectDetailUrl,
671
+ getProjectBuildDetailUrl,
672
+ pollBuildStatus,
673
+ pollDeployStatus,
674
+ ensureProjectExists,
675
+ logFeedbackMessage,
676
+ createProjectComponent,
677
+ displayWarnLogs,
678
+ getProjectComponentsByVersion,
1042
679
  };