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