@hubspot/cli 6.4.0 → 7.0.0-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 (205) hide show
  1. package/bin/cli.js +110 -16
  2. package/bin/hs +2 -0
  3. package/bin/hscms +2 -0
  4. package/bin/silenceErrors.d.ts +2 -0
  5. package/bin/silenceErrors.js +12 -0
  6. package/commands/{accounts → account}/clean.js +10 -11
  7. package/commands/{accounts → account}/info.js +10 -16
  8. package/commands/{accounts → account}/list.js +16 -16
  9. package/commands/{accounts → account}/remove.js +12 -15
  10. package/commands/{accounts → account}/rename.js +4 -7
  11. package/commands/{accounts → account}/use.js +8 -14
  12. package/commands/account.js +26 -0
  13. package/commands/auth.js +30 -24
  14. package/commands/cms/getReactModule.js +70 -0
  15. package/commands/cms/lighthouseScore.js +19 -21
  16. package/commands/cms.js +4 -3
  17. package/commands/completion.js +22 -0
  18. package/commands/config/set.js +22 -24
  19. package/commands/config.js +2 -2
  20. package/commands/create.js +6 -3
  21. package/commands/customObject/create.js +19 -15
  22. package/commands/customObject/schema/create.js +15 -16
  23. package/commands/customObject/schema/delete.js +29 -11
  24. package/commands/customObject/schema/fetch-all.js +14 -11
  25. package/commands/customObject/schema/fetch.js +22 -14
  26. package/commands/customObject/schema/list.js +3 -6
  27. package/commands/customObject/schema/update.js +28 -18
  28. package/commands/customObject/schema.js +1 -1
  29. package/commands/customObject.js +3 -4
  30. package/commands/doctor.js +4 -2
  31. package/commands/feedback.js +2 -0
  32. package/commands/fetch.js +13 -13
  33. package/commands/filemanager/fetch.js +6 -7
  34. package/commands/filemanager/upload.js +10 -12
  35. package/commands/filemanager.js +1 -8
  36. package/commands/{functions → function}/deploy.js +13 -13
  37. package/commands/{functions → function}/list.js +7 -9
  38. package/commands/{functions → function}/server.js +5 -8
  39. package/commands/function.js +16 -0
  40. package/commands/hubdb/clear.js +14 -10
  41. package/commands/hubdb/create.js +37 -13
  42. package/commands/hubdb/delete.js +31 -10
  43. package/commands/hubdb/fetch.js +14 -9
  44. package/commands/hubdb.js +2 -3
  45. package/commands/init.js +37 -14
  46. package/commands/lint.js +6 -7
  47. package/commands/list.js +5 -7
  48. package/commands/logs.js +24 -15
  49. package/commands/module/marketplace-validate.js +6 -9
  50. package/commands/module.js +2 -1
  51. package/commands/mv.js +11 -13
  52. package/commands/open.js +11 -10
  53. package/commands/project/add.js +2 -5
  54. package/commands/project/cloneApp.js +28 -32
  55. package/commands/project/create.js +8 -10
  56. package/commands/project/deploy.js +19 -16
  57. package/commands/project/dev.js +17 -18
  58. package/commands/project/download.js +18 -15
  59. package/commands/project/listBuilds.js +36 -32
  60. package/commands/project/logs.js +6 -8
  61. package/commands/project/migrateApp.js +27 -27
  62. package/commands/project/open.js +9 -11
  63. package/commands/project/upload.js +30 -32
  64. package/commands/project/watch.js +17 -24
  65. package/commands/project.js +3 -4
  66. package/commands/remove.js +14 -13
  67. package/commands/sandbox/create.js +12 -15
  68. package/commands/sandbox/delete.js +19 -20
  69. package/commands/sandbox.js +4 -8
  70. package/commands/{secrets → secret}/addSecret.js +25 -12
  71. package/commands/secret/deleteSecret.js +71 -0
  72. package/commands/{secrets → secret}/listSecrets.js +7 -9
  73. package/commands/{secrets → secret}/updateSecret.js +21 -13
  74. package/commands/secret.js +22 -0
  75. package/commands/theme/generate-selectors.js +8 -8
  76. package/commands/theme/marketplace-validate.js +10 -13
  77. package/commands/theme/preview.js +7 -10
  78. package/commands/theme.js +3 -1
  79. package/commands/upload.js +32 -26
  80. package/commands/watch.js +19 -20
  81. package/lang/en.lyaml +200 -126
  82. package/lib/DevServerManager.js +1 -1
  83. package/lib/LocalDevManager.js +4 -4
  84. package/lib/buildAccount.js +5 -11
  85. package/lib/commonOpts.d.ts +15 -6
  86. package/lib/commonOpts.js +53 -39
  87. package/lib/configOptions.d.ts +13 -1
  88. package/lib/configOptions.js +54 -57
  89. package/lib/constants.d.ts +1 -4
  90. package/lib/dependencyManagement.d.ts +4 -1
  91. package/lib/dependencyManagement.js +2 -2
  92. package/lib/developerTestAccounts.d.ts +5 -1
  93. package/lib/developerTestAccounts.js +45 -39
  94. package/lib/doctor/DiagnosticInfoBuilder.js +8 -4
  95. package/lib/doctor/Doctor.js +11 -6
  96. package/lib/generateSelectors.d.ts +19 -0
  97. package/lib/generateSelectors.js +23 -23
  98. package/lib/localDev.js +3 -2
  99. package/lib/marketplaceValidate.d.ts +6 -1
  100. package/lib/marketplaceValidate.js +76 -77
  101. package/lib/oauth.d.ts +2 -1
  102. package/lib/oauth.js +49 -37
  103. package/lib/polling.d.ts +8 -0
  104. package/lib/polling.js +9 -12
  105. package/lib/projects/ProjectLogsManager.d.ts +20 -0
  106. package/lib/projects/ProjectLogsManager.js +105 -0
  107. package/lib/projects/buildAndDeploy.d.ts +16 -0
  108. package/lib/projects/buildAndDeploy.js +342 -0
  109. package/lib/projects/index.d.ts +24 -0
  110. package/lib/projects/index.js +256 -0
  111. package/lib/projects/structure.d.ts +78 -0
  112. package/lib/projects/structure.js +151 -0
  113. package/lib/projects/upload.d.ts +8 -0
  114. package/lib/projects/upload.js +107 -0
  115. package/lib/projects/urls.d.ts +4 -0
  116. package/lib/projects/urls.js +27 -0
  117. package/lib/{projectsWatch.js → projects/watch.js} +3 -3
  118. package/lib/prompts/accountNamePrompt.d.ts +11 -0
  119. package/lib/prompts/accountNamePrompt.js +45 -46
  120. package/lib/prompts/accountsPrompt.d.ts +1 -1
  121. package/lib/prompts/accountsPrompt.js +21 -19
  122. package/lib/prompts/cmsFieldPrompt.d.ts +1 -1
  123. package/lib/prompts/cmsFieldPrompt.js +23 -24
  124. package/lib/prompts/createApiSamplePrompt.d.ts +17 -0
  125. package/lib/prompts/createApiSamplePrompt.js +47 -44
  126. package/lib/prompts/createFunctionPrompt.d.ts +7 -0
  127. package/lib/prompts/createFunctionPrompt.js +17 -20
  128. package/lib/prompts/createModulePrompt.d.ts +8 -0
  129. package/lib/prompts/createModulePrompt.js +29 -17
  130. package/lib/prompts/createProjectPrompt.d.ts +13 -0
  131. package/lib/prompts/createProjectPrompt.js +48 -49
  132. package/lib/prompts/createTemplatePrompt.d.ts +8 -0
  133. package/lib/prompts/createTemplatePrompt.js +15 -17
  134. package/lib/prompts/downloadProjectPrompt.d.ts +8 -0
  135. package/lib/prompts/downloadProjectPrompt.js +25 -23
  136. package/lib/prompts/installPublicAppPrompt.d.ts +1 -1
  137. package/lib/prompts/installPublicAppPrompt.js +21 -19
  138. package/lib/prompts/personalAccessKeyPrompt.d.ts +28 -0
  139. package/lib/prompts/personalAccessKeyPrompt.js +46 -52
  140. package/lib/prompts/previewPrompt.d.ts +14 -0
  141. package/lib/prompts/previewPrompt.js +24 -24
  142. package/lib/prompts/projectAddPrompt.d.ts +9 -0
  143. package/lib/prompts/projectAddPrompt.js +11 -14
  144. package/lib/prompts/projectDevTargetAccountPrompt.d.ts +6 -1
  145. package/lib/prompts/projectDevTargetAccountPrompt.js +87 -69
  146. package/lib/prompts/projectsLogsPrompt.d.ts +11 -0
  147. package/lib/prompts/projectsLogsPrompt.js +8 -11
  148. package/lib/prompts/promptUtils.d.ts +7 -6
  149. package/lib/prompts/promptUtils.js +21 -8
  150. package/lib/prompts/sandboxesPrompt.d.ts +8 -0
  151. package/lib/prompts/sandboxesPrompt.js +43 -45
  152. package/lib/prompts/secretPrompt.d.ts +12 -0
  153. package/lib/prompts/secretPrompt.js +32 -19
  154. package/lib/prompts/selectHubDBTablePrompt.d.ts +12 -0
  155. package/lib/prompts/selectHubDBTablePrompt.js +69 -0
  156. package/lib/prompts/selectPublicAppPrompt.d.ts +8 -0
  157. package/lib/prompts/selectPublicAppPrompt.js +28 -27
  158. package/lib/prompts/setAsDefaultAccountPrompt.d.ts +1 -1
  159. package/lib/prompts/setAsDefaultAccountPrompt.js +12 -14
  160. package/lib/prompts/uploadPrompt.d.ts +8 -0
  161. package/lib/prompts/uploadPrompt.js +18 -18
  162. package/lib/sandboxSync.js +5 -2
  163. package/lib/sandboxes.js +12 -7
  164. package/lib/ui/index.d.ts +1 -1
  165. package/lib/ui/index.js +1 -1
  166. package/lib/usageTracking.d.ts +21 -2
  167. package/lib/usageTracking.js +53 -81
  168. package/lib/validation.d.ts +11 -1
  169. package/lib/validation.js +98 -91
  170. package/package.json +12 -6
  171. package/types/Projects.d.ts +43 -0
  172. package/types/Projects.js +2 -0
  173. package/types/Prompts.d.ts +25 -0
  174. package/types/Prompts.js +2 -0
  175. package/commands/accounts.js +0 -30
  176. package/commands/cms/reactModules.js +0 -60
  177. package/commands/functions.js +0 -24
  178. package/commands/secrets/deleteSecret.js +0 -46
  179. package/commands/secrets.js +0 -23
  180. package/lib/ProjectLogsManager.js +0 -91
  181. package/lib/projectStructure.js +0 -116
  182. package/lib/projects.d.ts +0 -4
  183. package/lib/projects.js +0 -681
  184. package/lib/projectsWatch.d.ts +0 -1
  185. package/lib/prompts/cleanUploadPrompt.d.ts +0 -1
  186. package/lib/prompts/cleanUploadPrompt.js +0 -20
  187. /package/commands/{accounts → account}/clean.d.ts +0 -0
  188. /package/commands/{accounts → account}/info.d.ts +0 -0
  189. /package/commands/{accounts → account}/list.d.ts +0 -0
  190. /package/commands/{accounts → account}/remove.d.ts +0 -0
  191. /package/commands/{accounts → account}/rename.d.ts +0 -0
  192. /package/commands/{accounts → account}/use.d.ts +0 -0
  193. /package/commands/{accounts.d.ts → account.d.ts} +0 -0
  194. /package/commands/cms/{reactModules.d.ts → getReactModule.d.ts} +0 -0
  195. /package/commands/{functions.d.ts → completion.d.ts} +0 -0
  196. /package/commands/{functions/list.d.ts → function/deploy.d.ts} +0 -0
  197. /package/commands/{functions/server.d.ts → function/list.d.ts} +0 -0
  198. /package/commands/{secrets.d.ts → function/server.d.ts} +0 -0
  199. /package/commands/{functions/deploy.d.ts → function.d.ts} +0 -0
  200. /package/commands/{secrets/deleteSecret.d.ts → secret/addSecret.d.ts} +0 -0
  201. /package/commands/{secrets/listSecrets.d.ts → secret/deleteSecret.d.ts} +0 -0
  202. /package/commands/{secrets/updateSecret.d.ts → secret/listSecrets.d.ts} +0 -0
  203. /package/{lib/ProjectLogsManager.d.ts → commands/secret/updateSecret.d.ts} +0 -0
  204. /package/commands/{secrets/addSecret.d.ts → secret.d.ts} +0 -0
  205. /package/lib/{projectStructure.d.ts → projects/watch.d.ts} +0 -0
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.writeProjectConfig = writeProjectConfig;
7
+ exports.getIsInProject = getIsInProject;
8
+ exports.getProjectConfig = getProjectConfig;
9
+ exports.createProjectConfig = createProjectConfig;
10
+ exports.validateProjectConfig = validateProjectConfig;
11
+ exports.ensureProjectExists = ensureProjectExists;
12
+ exports.logFeedbackMessage = logFeedbackMessage;
13
+ exports.createProjectComponent = createProjectComponent;
14
+ exports.getProjectComponentsByVersion = getProjectComponentsByVersion;
15
+ const fs_extra_1 = __importDefault(require("fs-extra"));
16
+ const path_1 = __importDefault(require("path"));
17
+ const findup_sync_1 = __importDefault(require("findup-sync"));
18
+ const logger_1 = require("@hubspot/local-dev-lib/logger");
19
+ const github_1 = require("@hubspot/local-dev-lib/github");
20
+ const projects_1 = require("@hubspot/local-dev-lib/api/projects");
21
+ const index_1 = require("@hubspot/local-dev-lib/errors/index");
22
+ const path_2 = require("@hubspot/local-dev-lib/path");
23
+ const github_2 = require("@hubspot/local-dev-lib/github");
24
+ const constants_1 = require("../constants");
25
+ const promptUtils_1 = require("../prompts/promptUtils");
26
+ const exitCodes_1 = require("../enums/exitCodes");
27
+ const ui_1 = require("../ui");
28
+ const lang_1 = require("../lang");
29
+ const SpinniesManager_1 = __importDefault(require("../ui/SpinniesManager"));
30
+ const index_2 = require("../errorHandlers/index");
31
+ const i18nKey = 'lib.projects';
32
+ function writeProjectConfig(configPath, config) {
33
+ try {
34
+ fs_extra_1.default.ensureFileSync(configPath);
35
+ fs_extra_1.default.writeFileSync(configPath, JSON.stringify(config, null, 2));
36
+ logger_1.logger.debug(`Wrote project config at ${configPath}`);
37
+ }
38
+ catch (e) {
39
+ logger_1.logger.debug(e);
40
+ return false;
41
+ }
42
+ return true;
43
+ }
44
+ function getIsInProject(dir) {
45
+ const configPath = getProjectConfigPath(dir);
46
+ return !!configPath;
47
+ }
48
+ function getProjectConfigPath(dir) {
49
+ const projectDir = dir ? (0, path_2.getAbsoluteFilePath)(dir) : (0, path_2.getCwd)();
50
+ const configPath = (0, findup_sync_1.default)(constants_1.PROJECT_CONFIG_FILE, {
51
+ cwd: projectDir,
52
+ nocase: true,
53
+ });
54
+ return configPath;
55
+ }
56
+ async function getProjectConfig(dir) {
57
+ const configPath = await getProjectConfigPath(dir);
58
+ if (!configPath) {
59
+ return { projectConfig: null, projectDir: null };
60
+ }
61
+ try {
62
+ const config = fs_extra_1.default.readFileSync(configPath);
63
+ const projectConfig = JSON.parse(config.toString());
64
+ return {
65
+ projectDir: path_1.default.dirname(configPath),
66
+ projectConfig,
67
+ };
68
+ }
69
+ catch (e) {
70
+ logger_1.logger.error('Could not read from project config');
71
+ return { projectConfig: null, projectDir: null };
72
+ }
73
+ }
74
+ async function createProjectConfig(projectPath, projectName, template, templateSource, githubRef) {
75
+ const { projectConfig, projectDir } = await getProjectConfig(projectPath);
76
+ if (projectConfig) {
77
+ logger_1.logger.warn(projectPath === projectDir
78
+ ? 'A project already exists in that location.'
79
+ : `Found an existing project definition in ${projectDir}.`);
80
+ const { shouldContinue } = await (0, promptUtils_1.promptUser)([
81
+ {
82
+ name: 'shouldContinue',
83
+ message: () => {
84
+ return projectPath === projectDir
85
+ ? 'Do you want to overwrite the existing project definition with a new one?'
86
+ : `Continue creating a new project in ${projectPath}?`;
87
+ },
88
+ type: 'confirm',
89
+ default: false,
90
+ },
91
+ ]);
92
+ if (!shouldContinue) {
93
+ return false;
94
+ }
95
+ }
96
+ const projectConfigPath = path_1.default.join(projectPath, constants_1.PROJECT_CONFIG_FILE);
97
+ logger_1.logger.log(`Creating project config in ${projectPath ? projectPath : 'the current folder'}`);
98
+ const hasCustomTemplateSource = Boolean(templateSource);
99
+ await (0, github_2.downloadGithubRepoContents)(templateSource || constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, template.path, projectPath, hasCustomTemplateSource ? undefined : githubRef);
100
+ const _config = JSON.parse(fs_extra_1.default.readFileSync(projectConfigPath).toString());
101
+ writeProjectConfig(projectConfigPath, {
102
+ ..._config,
103
+ name: projectName,
104
+ });
105
+ if (template.name === 'no-template') {
106
+ fs_extra_1.default.ensureDirSync(path_1.default.join(projectPath, 'src'));
107
+ }
108
+ return true;
109
+ }
110
+ function validateProjectConfig(projectConfig, projectDir) {
111
+ if (!projectConfig) {
112
+ logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.validateProjectConfig.configNotFound`, {
113
+ createCommand: (0, ui_1.uiCommandReference)('hs project create'),
114
+ }));
115
+ return process.exit(exitCodes_1.EXIT_CODES.ERROR);
116
+ }
117
+ if (!projectConfig.name || !projectConfig.srcDir) {
118
+ logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.validateProjectConfig.configMissingFields`));
119
+ return process.exit(exitCodes_1.EXIT_CODES.ERROR);
120
+ }
121
+ const resolvedPath = path_1.default.resolve(projectDir, projectConfig.srcDir);
122
+ if (!resolvedPath.startsWith(projectDir)) {
123
+ const projectConfigFile = path_1.default.relative('.', path_1.default.join(projectDir, constants_1.PROJECT_CONFIG_FILE));
124
+ logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.validateProjectConfig.srcOutsideProjectDir`, {
125
+ srcDir: projectConfig.srcDir,
126
+ projectConfig: projectConfigFile,
127
+ }));
128
+ return process.exit(exitCodes_1.EXIT_CODES.ERROR);
129
+ }
130
+ if (!fs_extra_1.default.existsSync(resolvedPath)) {
131
+ logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.validateProjectConfig.srcDirNotFound`, {
132
+ srcDir: projectConfig.srcDir,
133
+ projectDir: projectDir,
134
+ }));
135
+ return process.exit(exitCodes_1.EXIT_CODES.ERROR);
136
+ }
137
+ }
138
+ async function pollFetchProject(accountId, projectName) {
139
+ // Temporary solution for gating slowness. Retry on 403 statusCode
140
+ return new Promise((resolve, reject) => {
141
+ let pollCount = 0;
142
+ SpinniesManager_1.default.init();
143
+ SpinniesManager_1.default.add('pollFetchProject', {
144
+ text: (0, lang_1.i18n)(`${i18nKey}.pollFetchProject.checkingProject`, {
145
+ accountIdentifier: (0, ui_1.uiAccountDescription)(accountId),
146
+ }),
147
+ });
148
+ const pollInterval = setInterval(async () => {
149
+ try {
150
+ const response = await (0, projects_1.fetchProject)(accountId, projectName);
151
+ if (response && response.data) {
152
+ SpinniesManager_1.default.remove('pollFetchProject');
153
+ clearInterval(pollInterval);
154
+ resolve(response);
155
+ }
156
+ }
157
+ catch (err) {
158
+ if ((0, index_1.isSpecifiedError)(err, {
159
+ statusCode: 403,
160
+ category: 'GATED',
161
+ subCategory: 'BuildPipelineErrorType.PORTAL_GATED',
162
+ }) &&
163
+ pollCount < 15) {
164
+ pollCount += 1;
165
+ }
166
+ else {
167
+ SpinniesManager_1.default.remove('pollFetchProject');
168
+ clearInterval(pollInterval);
169
+ reject(err);
170
+ }
171
+ }
172
+ }, constants_1.POLLING_DELAY);
173
+ });
174
+ }
175
+ async function ensureProjectExists(accountId, projectName, { forceCreate = false, allowCreate = true, noLogs = false, withPolling = false, uploadCommand = false, } = {}) {
176
+ const accountIdentifier = (0, ui_1.uiAccountDescription)(accountId);
177
+ try {
178
+ const { data: project } = withPolling
179
+ ? await pollFetchProject(accountId, projectName)
180
+ : await (0, projects_1.fetchProject)(accountId, projectName);
181
+ return { projectExists: !!project, project };
182
+ }
183
+ catch (err) {
184
+ if ((0, index_1.isSpecifiedError)(err, { statusCode: 404 })) {
185
+ let shouldCreateProject = forceCreate;
186
+ if (allowCreate && !shouldCreateProject) {
187
+ const promptKey = uploadCommand ? 'createPromptUpload' : 'createPrompt';
188
+ const promptResult = await (0, promptUtils_1.promptUser)([
189
+ {
190
+ name: 'shouldCreateProject',
191
+ message: (0, lang_1.i18n)(`${i18nKey}.ensureProjectExists.${promptKey}`, {
192
+ projectName,
193
+ accountIdentifier,
194
+ }),
195
+ type: 'confirm',
196
+ },
197
+ ]);
198
+ shouldCreateProject = promptResult.shouldCreateProject;
199
+ }
200
+ if (shouldCreateProject) {
201
+ try {
202
+ const { data: project } = await (0, projects_1.createProject)(accountId, projectName);
203
+ logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.ensureProjectExists.createSuccess`, {
204
+ projectName,
205
+ accountIdentifier,
206
+ }));
207
+ return { projectExists: true, project };
208
+ }
209
+ catch (err) {
210
+ (0, index_2.logError)(err, new index_2.ApiErrorContext({ accountId }));
211
+ return { projectExists: false };
212
+ }
213
+ }
214
+ else {
215
+ if (!noLogs) {
216
+ logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.ensureProjectExists.notFound`, {
217
+ projectName,
218
+ accountIdentifier,
219
+ }));
220
+ }
221
+ return { projectExists: false };
222
+ }
223
+ }
224
+ if ((0, index_1.isSpecifiedError)(err, {
225
+ statusCode: 401,
226
+ })) {
227
+ logger_1.logger.error(err.message);
228
+ process.exit(exitCodes_1.EXIT_CODES.ERROR);
229
+ }
230
+ (0, index_2.logError)(err, new index_2.ApiErrorContext({ accountId }));
231
+ process.exit(exitCodes_1.EXIT_CODES.ERROR);
232
+ }
233
+ }
234
+ function logFeedbackMessage(buildId) {
235
+ if (buildId > 0 && buildId % constants_1.FEEDBACK_INTERVAL === 0) {
236
+ (0, ui_1.uiLine)();
237
+ logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.logFeedbackMessage.feedbackHeader`));
238
+ (0, ui_1.uiLine)();
239
+ logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.logFeedbackMessage.feedbackMessage`));
240
+ }
241
+ }
242
+ async function createProjectComponent(component, name, projectComponentsVersion) {
243
+ const i18nKey = 'commands.project.subcommands.add';
244
+ const componentName = name;
245
+ const configInfo = await getProjectConfig();
246
+ if (!configInfo.projectDir || !configInfo.projectConfig) {
247
+ logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.error.locationInProject`));
248
+ process.exit(exitCodes_1.EXIT_CODES.ERROR);
249
+ }
250
+ const componentPath = path_1.default.join(configInfo.projectDir, configInfo.projectConfig.srcDir, component.insertPath, componentName);
251
+ await (0, github_2.downloadGithubRepoContents)(constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, component.path, componentPath, projectComponentsVersion);
252
+ }
253
+ async function getProjectComponentsByVersion(projectComponentsVersion) {
254
+ const config = await (0, github_1.fetchFileFromRepository)(constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, 'config.json', projectComponentsVersion);
255
+ return config[constants_1.PROJECT_COMPONENT_TYPES.COMPONENTS] || [];
256
+ }
@@ -0,0 +1,78 @@
1
+ import { ValueOf } from '@hubspot/local-dev-lib/types/Utils';
2
+ export type Component = {
3
+ type: ComponentTypes;
4
+ config: object;
5
+ runnable: boolean;
6
+ path: string;
7
+ };
8
+ type PrivateAppComponentConfig = {
9
+ name: string;
10
+ description: string;
11
+ uid: string;
12
+ scopes: Array<string>;
13
+ public: boolean;
14
+ extensions?: {
15
+ crm: {
16
+ cards: Array<{
17
+ file: string;
18
+ }>;
19
+ };
20
+ };
21
+ };
22
+ type PublicAppComponentConfig = {
23
+ name: string;
24
+ uid: string;
25
+ description: string;
26
+ allowedUrls: Array<string>;
27
+ auth: {
28
+ redirectUrls: Array<string>;
29
+ requiredScopes: Array<string>;
30
+ optionalScopes: Array<string>;
31
+ conditionallyRequiredScopes: Array<string>;
32
+ };
33
+ support: {
34
+ supportEmail: string;
35
+ documentationUrl: string;
36
+ supportUrl: string;
37
+ supportPhone: string;
38
+ };
39
+ extensions?: {
40
+ crm: {
41
+ cards: Array<{
42
+ file: string;
43
+ }>;
44
+ };
45
+ };
46
+ webhooks?: {
47
+ file: string;
48
+ };
49
+ };
50
+ type AppCardComponentConfig = {
51
+ type: 'crm-card';
52
+ data: {
53
+ title: string;
54
+ uid: string;
55
+ location: string;
56
+ module: {
57
+ file: string;
58
+ };
59
+ objectTypes: Array<{
60
+ name: string;
61
+ }>;
62
+ };
63
+ };
64
+ export declare const COMPONENT_TYPES: {
65
+ readonly privateApp: "private-app";
66
+ readonly publicApp: "public-app";
67
+ readonly hublTheme: "hubl-theme";
68
+ };
69
+ type ComponentTypes = ValueOf<typeof COMPONENT_TYPES>;
70
+ export declare const CONFIG_FILES: {
71
+ [k in ValueOf<typeof COMPONENT_TYPES>]: string;
72
+ };
73
+ export declare function getAppCardConfigs(appConfig: PublicAppComponentConfig | PrivateAppComponentConfig, appPath: string): Array<AppCardComponentConfig>;
74
+ export declare function findProjectComponents(projectSourceDir: string): Promise<Array<Component>>;
75
+ export declare function getProjectComponentTypes(components: Array<Component>): {
76
+ [key in ComponentTypes]?: boolean;
77
+ };
78
+ export {};
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CONFIG_FILES = exports.COMPONENT_TYPES = void 0;
37
+ exports.getAppCardConfigs = getAppCardConfigs;
38
+ exports.findProjectComponents = findProjectComponents;
39
+ exports.getProjectComponentTypes = getProjectComponentTypes;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const fs_1 = require("@hubspot/local-dev-lib/fs");
43
+ const logger_1 = require("@hubspot/local-dev-lib/logger");
44
+ const index_1 = require("../errorHandlers/index");
45
+ exports.COMPONENT_TYPES = {
46
+ privateApp: 'private-app',
47
+ publicApp: 'public-app',
48
+ hublTheme: 'hubl-theme',
49
+ };
50
+ exports.CONFIG_FILES = {
51
+ [exports.COMPONENT_TYPES.privateApp]: 'app.json',
52
+ [exports.COMPONENT_TYPES.publicApp]: 'public-app.json',
53
+ [exports.COMPONENT_TYPES.hublTheme]: 'theme.json',
54
+ };
55
+ function getComponentTypeFromConfigFile(configFile) {
56
+ let key;
57
+ for (key in exports.CONFIG_FILES) {
58
+ if (exports.CONFIG_FILES[key] === configFile) {
59
+ return key;
60
+ }
61
+ }
62
+ return null;
63
+ }
64
+ function loadConfigFile(configPath) {
65
+ if (configPath) {
66
+ try {
67
+ const source = fs.readFileSync(configPath);
68
+ const parsedConfig = JSON.parse(source.toString());
69
+ return parsedConfig;
70
+ }
71
+ catch (e) {
72
+ logger_1.logger.debug(e);
73
+ }
74
+ }
75
+ return null;
76
+ }
77
+ function getAppCardConfigs(appConfig, appPath) {
78
+ const cardConfigs = [];
79
+ let cards;
80
+ if (appConfig && appConfig.extensions && appConfig.extensions.crm) {
81
+ cards = appConfig.extensions.crm.cards;
82
+ }
83
+ if (cards) {
84
+ cards.forEach(({ file }) => {
85
+ if (typeof file === 'string') {
86
+ const cardConfigPath = path.join(appPath, file);
87
+ const cardConfig = loadConfigFile(cardConfigPath);
88
+ if (cardConfig && 'type' in cardConfig) {
89
+ cardConfigs.push(cardConfig);
90
+ }
91
+ }
92
+ });
93
+ }
94
+ return cardConfigs;
95
+ }
96
+ function getIsLegacyApp(appConfig, appPath) {
97
+ let hasAnyReactExtensions = false;
98
+ if (appConfig && 'extensions' in appConfig) {
99
+ const cardConfigs = getAppCardConfigs(appConfig, appPath);
100
+ if (!cardConfigs.length) {
101
+ // Assume any app that does not have any cards is not legacy
102
+ return false;
103
+ }
104
+ cardConfigs.forEach(cardConfig => {
105
+ if (!hasAnyReactExtensions) {
106
+ const isReactExtension = cardConfig &&
107
+ !!cardConfig.data &&
108
+ !!cardConfig.data.module &&
109
+ !!cardConfig.data.module.file;
110
+ hasAnyReactExtensions = isReactExtension;
111
+ }
112
+ });
113
+ }
114
+ return !hasAnyReactExtensions;
115
+ }
116
+ async function findProjectComponents(projectSourceDir) {
117
+ const components = [];
118
+ let projectFiles = [];
119
+ try {
120
+ projectFiles = await (0, fs_1.walk)(projectSourceDir);
121
+ }
122
+ catch (e) {
123
+ (0, index_1.logError)(e);
124
+ }
125
+ projectFiles.forEach(projectFile => {
126
+ // Find app components
127
+ const { base, dir } = path.parse(projectFile);
128
+ if (Object.values(exports.CONFIG_FILES).includes(base)) {
129
+ const parsedConfig = loadConfigFile(projectFile);
130
+ if (parsedConfig) {
131
+ const isLegacy = getIsLegacyApp(parsedConfig, dir);
132
+ const isHublTheme = base === exports.CONFIG_FILES[exports.COMPONENT_TYPES.hublTheme];
133
+ const componentType = getComponentTypeFromConfigFile(base);
134
+ if (componentType) {
135
+ components.push({
136
+ type: componentType,
137
+ config: parsedConfig,
138
+ runnable: !isLegacy && !isHublTheme,
139
+ path: dir,
140
+ });
141
+ }
142
+ }
143
+ }
144
+ });
145
+ return components;
146
+ }
147
+ function getProjectComponentTypes(components) {
148
+ const projectContents = {};
149
+ components.forEach(({ type }) => (projectContents[type] = true));
150
+ return projectContents;
151
+ }
@@ -0,0 +1,8 @@
1
+ import { FileResult } from 'tmp';
2
+ import { ProjectConfig } from '../../types/Projects';
3
+ type ProjectUploadCallbackFunction<T> = (accountId: number, projectConfig: ProjectConfig, tempFile: FileResult, buildId?: number) => Promise<T | undefined>;
4
+ type ProjectUploadDefaultResult = {
5
+ uploadError?: unknown;
6
+ };
7
+ export declare function handleProjectUpload<T = ProjectUploadDefaultResult>(accountId: number, projectConfig: ProjectConfig, projectDir: string, callbackFunc: ProjectUploadCallbackFunction<T>, uploadMessage: string): Promise<unknown>;
8
+ export {};
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleProjectUpload = handleProjectUpload;
7
+ const archiver_1 = __importDefault(require("archiver"));
8
+ const tmp_1 = __importDefault(require("tmp"));
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const projects_1 = require("@hubspot/local-dev-lib/api/projects");
12
+ const ignoreRules_1 = require("@hubspot/local-dev-lib/ignoreRules");
13
+ const logger_1 = require("@hubspot/local-dev-lib/logger");
14
+ const SpinniesManager_1 = __importDefault(require("../ui/SpinniesManager"));
15
+ const ui_1 = require("../ui");
16
+ const lang_1 = require("../lang");
17
+ const exitCodes_1 = require("../enums/exitCodes");
18
+ const i18nKey = 'lib.projectUpload';
19
+ async function uploadProjectFiles(accountId, projectName, filePath, uploadMessage, platformVersion) {
20
+ SpinniesManager_1.default.init({});
21
+ const accountIdentifier = (0, ui_1.uiAccountDescription)(accountId);
22
+ SpinniesManager_1.default.add('upload', {
23
+ text: (0, lang_1.i18n)(`${i18nKey}.uploadProjectFiles.add`, {
24
+ accountIdentifier,
25
+ projectName,
26
+ }),
27
+ succeedColor: 'white',
28
+ });
29
+ let buildId;
30
+ let error;
31
+ try {
32
+ const { data: upload } = await (0, projects_1.uploadProject)(accountId, projectName, filePath, uploadMessage, platformVersion);
33
+ buildId = upload.buildId;
34
+ SpinniesManager_1.default.succeed('upload', {
35
+ text: (0, lang_1.i18n)(`${i18nKey}.uploadProjectFiles.succeed`, {
36
+ accountIdentifier,
37
+ projectName,
38
+ }),
39
+ });
40
+ if (buildId) {
41
+ logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.uploadProjectFiles.buildCreated`, {
42
+ buildId,
43
+ projectName,
44
+ }));
45
+ }
46
+ }
47
+ catch (err) {
48
+ SpinniesManager_1.default.fail('upload', {
49
+ text: (0, lang_1.i18n)(`${i18nKey}.uploadProjectFiles.fail`, {
50
+ accountIdentifier,
51
+ projectName,
52
+ }),
53
+ });
54
+ error = err;
55
+ }
56
+ return { buildId, error };
57
+ }
58
+ async function handleProjectUpload(accountId, projectConfig, projectDir, callbackFunc, uploadMessage) {
59
+ const srcDir = path_1.default.resolve(projectDir, projectConfig.srcDir);
60
+ const filenames = fs_extra_1.default.readdirSync(srcDir);
61
+ if (!filenames || filenames.length === 0) {
62
+ logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.handleProjectUpload.emptySource`, {
63
+ srcDir: projectConfig.srcDir,
64
+ }));
65
+ process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
66
+ }
67
+ const tempFile = tmp_1.default.fileSync({ postfix: '.zip' });
68
+ logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.handleProjectUpload.compressing`, {
69
+ path: tempFile.name,
70
+ }));
71
+ const output = fs_extra_1.default.createWriteStream(tempFile.name);
72
+ const archive = (0, archiver_1.default)('zip');
73
+ const result = new Promise(resolve => output.on('close', async function () {
74
+ let uploadResult;
75
+ logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.handleProjectUpload.compressed`, {
76
+ byteCount: archive.pointer(),
77
+ }));
78
+ const { buildId, error } = await uploadProjectFiles(accountId, projectConfig.name, tempFile.name, uploadMessage, projectConfig.platformVersion);
79
+ if (error) {
80
+ console.log(error);
81
+ uploadResult = { uploadError: error };
82
+ }
83
+ else if (callbackFunc) {
84
+ uploadResult = await callbackFunc(accountId, projectConfig, tempFile, buildId);
85
+ }
86
+ resolve(uploadResult || {});
87
+ }));
88
+ archive.pipe(output);
89
+ let loggedIgnoredNodeModule = false;
90
+ archive.directory(srcDir, false, file => {
91
+ const ignored = (0, ignoreRules_1.shouldIgnoreFile)(file.name, true);
92
+ if (ignored) {
93
+ const isNodeModule = file.name.includes('node_modules');
94
+ if (!isNodeModule || !loggedIgnoredNodeModule) {
95
+ logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.handleProjectUpload.fileFiltered`, {
96
+ filename: file.name,
97
+ }));
98
+ }
99
+ if (isNodeModule && !loggedIgnoredNodeModule) {
100
+ loggedIgnoredNodeModule = true;
101
+ }
102
+ }
103
+ return ignored ? false : file;
104
+ });
105
+ archive.finalize();
106
+ return result;
107
+ }
@@ -0,0 +1,4 @@
1
+ export declare function getProjectDetailUrl(projectName: string, accountId: number): string | undefined;
2
+ export declare function getProjectActivityUrl(projectName: string, accountId: number): string;
3
+ export declare function getProjectBuildDetailUrl(projectName: string, buildId: number, accountId: number): string;
4
+ export declare function getProjectDeployDetailUrl(projectName: string, deployId: number, accountId: number): string;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getProjectDetailUrl = getProjectDetailUrl;
4
+ exports.getProjectActivityUrl = getProjectActivityUrl;
5
+ exports.getProjectBuildDetailUrl = getProjectBuildDetailUrl;
6
+ exports.getProjectDeployDetailUrl = getProjectDeployDetailUrl;
7
+ const urls_1 = require("@hubspot/local-dev-lib/urls");
8
+ const config_1 = require("@hubspot/local-dev-lib/config");
9
+ const environments_1 = require("@hubspot/local-dev-lib/constants/environments");
10
+ function getProjectHomeUrl(accountId) {
11
+ const baseUrl = (0, urls_1.getHubSpotWebsiteOrigin)((0, config_1.getEnv)(accountId) === 'qa' ? environments_1.ENVIRONMENTS.QA : environments_1.ENVIRONMENTS.PROD);
12
+ return `${baseUrl}/developer-projects/${accountId}`;
13
+ }
14
+ function getProjectDetailUrl(projectName, accountId) {
15
+ if (!projectName)
16
+ return;
17
+ return `${getProjectHomeUrl(accountId)}/project/${projectName}`;
18
+ }
19
+ function getProjectActivityUrl(projectName, accountId) {
20
+ return `${getProjectDetailUrl(projectName, accountId)}/activity`;
21
+ }
22
+ function getProjectBuildDetailUrl(projectName, buildId, accountId) {
23
+ return `${getProjectActivityUrl(projectName, accountId)}/build/${buildId}`;
24
+ }
25
+ function getProjectDeployDetailUrl(projectName, deployId, accountId) {
26
+ return `${getProjectActivityUrl(projectName, accountId)}/deploy/${deployId}`;
27
+ }
@@ -5,14 +5,14 @@ const chokidar = require('chokidar');
5
5
  const path = require('path');
6
6
  const chalk = require('chalk');
7
7
  const { default: PQueue } = require('p-queue');
8
- const { logError, ApiErrorContext } = require('./errorHandlers/index');
9
- const { i18n } = require('./lang');
8
+ const { logError, ApiErrorContext } = require('../errorHandlers/index');
9
+ const { i18n } = require('../lang');
10
10
  const { logger } = require('@hubspot/local-dev-lib/logger');
11
11
  const { isAllowedExtension } = require('@hubspot/local-dev-lib/path');
12
12
  const { shouldIgnoreFile } = require('@hubspot/local-dev-lib/ignoreRules');
13
13
  const { cancelStagedBuild, provisionBuild, uploadFileToBuild, deleteFileFromBuild, queueBuild, } = require('@hubspot/local-dev-lib/api/projects');
14
14
  const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/index');
15
- const { PROJECT_ERROR_TYPES } = require('./constants');
15
+ const { PROJECT_ERROR_TYPES } = require('../constants');
16
16
  const i18nKey = 'commands.project.subcommands.watch';
17
17
  const queue = new PQueue({
18
18
  concurrency: 10,
@@ -1 +1,12 @@
1
+ import { PromptConfig } from '../../types/Prompts';
2
+ import { AccountType } from '@hubspot/local-dev-lib/types/Accounts';
3
+ type AccountNamePromptResponse = {
4
+ name: string;
5
+ };
6
+ export declare function getCliAccountNamePromptConfig(defaultName?: string): PromptConfig<AccountNamePromptResponse>;
7
+ export declare function cliAccountNamePrompt(defaultName: string): Promise<AccountNamePromptResponse>;
8
+ export declare function hubspotAccountNamePrompt({ accountType, currentPortalCount, }: {
9
+ accountType: AccountType;
10
+ currentPortalCount?: number;
11
+ }): Promise<AccountNamePromptResponse>;
1
12
  export {};