@hubspot/cli 7.0.0-experimental.1 → 7.0.1-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.
- package/bin/cli.js +110 -16
- package/bin/hs +2 -0
- package/bin/hscms +2 -0
- package/bin/silenceErrors.d.ts +2 -0
- package/bin/silenceErrors.js +12 -0
- package/commands/{accounts → account}/clean.js +10 -11
- package/commands/{accounts → account}/info.js +10 -16
- package/commands/{accounts → account}/list.js +16 -16
- package/commands/{accounts → account}/remove.js +12 -15
- package/commands/{accounts → account}/rename.js +4 -7
- package/commands/{accounts → account}/use.js +8 -14
- package/commands/account.js +26 -0
- package/commands/auth.js +30 -24
- package/commands/cms/getReactModule.js +70 -0
- package/commands/cms/lighthouseScore.js +19 -21
- package/commands/cms.js +4 -3
- package/commands/completion.js +22 -0
- package/commands/config/set.js +22 -24
- package/commands/config.js +2 -2
- package/commands/create.js +6 -3
- package/commands/customObject/create.js +19 -15
- package/commands/customObject/schema/create.js +15 -16
- package/commands/customObject/schema/delete.js +29 -11
- package/commands/customObject/schema/fetch-all.js +14 -11
- package/commands/customObject/schema/fetch.js +22 -14
- package/commands/customObject/schema/list.js +3 -6
- package/commands/customObject/schema/update.js +28 -18
- package/commands/customObject/schema.js +1 -1
- package/commands/customObject.js +3 -4
- package/commands/doctor.js +4 -2
- package/commands/feedback.js +2 -0
- package/commands/fetch.js +13 -13
- package/commands/filemanager/fetch.js +6 -7
- package/commands/filemanager/upload.js +10 -12
- package/commands/filemanager.js +1 -8
- package/commands/{functions → function}/deploy.js +13 -13
- package/commands/{functions → function}/list.js +7 -9
- package/commands/{functions → function}/server.js +5 -8
- package/commands/function.js +16 -0
- package/commands/hubdb/clear.js +14 -10
- package/commands/hubdb/create.js +37 -13
- package/commands/hubdb/delete.js +31 -10
- package/commands/hubdb/fetch.js +14 -9
- package/commands/hubdb.js +2 -3
- package/commands/init.js +37 -14
- package/commands/lint.js +6 -7
- package/commands/list.js +5 -7
- package/commands/logs.js +24 -15
- package/commands/module/marketplace-validate.js +6 -9
- package/commands/module.js +2 -1
- package/commands/mv.js +11 -13
- package/commands/open.js +11 -10
- package/commands/project/add.js +2 -5
- package/commands/project/cloneApp.js +28 -32
- package/commands/project/create.js +8 -10
- package/commands/project/deploy.js +19 -16
- package/commands/project/dev.js +17 -18
- package/commands/project/download.js +18 -15
- package/commands/project/listBuilds.js +36 -32
- package/commands/project/logs.js +6 -8
- package/commands/project/migrateApp.js +27 -27
- package/commands/project/open.js +9 -11
- package/commands/project/upload.js +35 -32
- package/commands/project/watch.js +17 -24
- package/commands/project.js +3 -4
- package/commands/remove.js +14 -13
- package/commands/sandbox/create.js +12 -15
- package/commands/sandbox/delete.js +19 -20
- package/commands/sandbox.js +4 -8
- package/commands/{secrets → secret}/addSecret.js +25 -12
- package/commands/secret/deleteSecret.js +71 -0
- package/commands/{secrets → secret}/listSecrets.js +7 -9
- package/commands/{secrets → secret}/updateSecret.js +21 -13
- package/commands/secret.js +22 -0
- package/commands/theme/generate-selectors.js +8 -8
- package/commands/theme/marketplace-validate.js +10 -13
- package/commands/theme/preview.js +7 -10
- package/commands/theme.js +3 -1
- package/commands/upload.js +32 -26
- package/commands/watch.js +19 -20
- package/lang/en.lyaml +200 -126
- package/lib/DevServerManager.js +1 -1
- package/lib/LocalDevManager.js +3 -3
- package/lib/buildAccount.js +5 -11
- package/lib/commonOpts.d.ts +15 -6
- package/lib/commonOpts.js +53 -38
- package/lib/configOptions.d.ts +13 -1
- package/lib/configOptions.js +54 -57
- package/lib/constants.d.ts +1 -4
- package/lib/developerTestAccounts.d.ts +5 -1
- package/lib/developerTestAccounts.js +45 -39
- package/lib/doctor/DiagnosticInfoBuilder.js +8 -4
- package/lib/doctor/Doctor.js +4 -3
- package/lib/generateSelectors.d.ts +19 -0
- package/lib/generateSelectors.js +23 -23
- package/lib/localDev.js +2 -1
- package/lib/marketplaceValidate.d.ts +6 -1
- package/lib/marketplaceValidate.js +76 -77
- package/lib/oauth.d.ts +2 -1
- package/lib/oauth.js +49 -37
- package/lib/polling.d.ts +8 -0
- package/lib/polling.js +9 -12
- package/lib/projects/ProjectLogsManager.d.ts +20 -0
- package/lib/projects/ProjectLogsManager.js +105 -0
- package/lib/projects/buildAndDeploy.d.ts +16 -0
- package/lib/projects/buildAndDeploy.js +342 -0
- package/lib/projects/index.d.ts +24 -0
- package/lib/projects/index.js +256 -0
- package/lib/projects/structure.d.ts +78 -0
- package/lib/projects/structure.js +151 -0
- package/lib/projects/upload.d.ts +8 -0
- package/lib/projects/upload.js +128 -0
- package/lib/projects/urls.d.ts +4 -0
- package/lib/projects/urls.js +27 -0
- package/lib/{projectsWatch.js → projects/watch.js} +3 -3
- package/lib/prompts/accountNamePrompt.d.ts +11 -0
- package/lib/prompts/accountNamePrompt.js +45 -46
- package/lib/prompts/accountsPrompt.d.ts +1 -1
- package/lib/prompts/accountsPrompt.js +21 -19
- package/lib/prompts/cmsFieldPrompt.d.ts +1 -1
- package/lib/prompts/cmsFieldPrompt.js +23 -24
- package/lib/prompts/createApiSamplePrompt.d.ts +17 -0
- package/lib/prompts/createApiSamplePrompt.js +47 -44
- package/lib/prompts/createFunctionPrompt.d.ts +7 -0
- package/lib/prompts/createFunctionPrompt.js +17 -20
- package/lib/prompts/createModulePrompt.d.ts +8 -0
- package/lib/prompts/createModulePrompt.js +29 -17
- package/lib/prompts/createProjectPrompt.d.ts +13 -0
- package/lib/prompts/createProjectPrompt.js +48 -49
- package/lib/prompts/createTemplatePrompt.d.ts +8 -0
- package/lib/prompts/createTemplatePrompt.js +15 -17
- package/lib/prompts/downloadProjectPrompt.d.ts +8 -0
- package/lib/prompts/downloadProjectPrompt.js +25 -23
- package/lib/prompts/installPublicAppPrompt.d.ts +1 -1
- package/lib/prompts/installPublicAppPrompt.js +21 -19
- package/lib/prompts/personalAccessKeyPrompt.d.ts +28 -0
- package/lib/prompts/personalAccessKeyPrompt.js +46 -52
- package/lib/prompts/previewPrompt.d.ts +14 -0
- package/lib/prompts/previewPrompt.js +24 -24
- package/lib/prompts/projectAddPrompt.d.ts +9 -0
- package/lib/prompts/projectAddPrompt.js +11 -14
- package/lib/prompts/projectDevTargetAccountPrompt.d.ts +6 -1
- package/lib/prompts/projectDevTargetAccountPrompt.js +87 -69
- package/lib/prompts/projectsLogsPrompt.d.ts +11 -0
- package/lib/prompts/projectsLogsPrompt.js +8 -11
- package/lib/prompts/promptUtils.d.ts +7 -6
- package/lib/prompts/promptUtils.js +21 -8
- package/lib/prompts/sandboxesPrompt.d.ts +8 -0
- package/lib/prompts/sandboxesPrompt.js +43 -45
- package/lib/prompts/secretPrompt.d.ts +12 -0
- package/lib/prompts/secretPrompt.js +32 -19
- package/lib/prompts/selectHubDBTablePrompt.d.ts +12 -0
- package/lib/prompts/selectHubDBTablePrompt.js +69 -0
- package/lib/prompts/selectPublicAppPrompt.d.ts +8 -0
- package/lib/prompts/selectPublicAppPrompt.js +28 -27
- package/lib/prompts/setAsDefaultAccountPrompt.d.ts +1 -1
- package/lib/prompts/setAsDefaultAccountPrompt.js +12 -14
- package/lib/prompts/uploadPrompt.d.ts +8 -0
- package/lib/prompts/uploadPrompt.js +18 -18
- package/lib/sandboxSync.js +5 -2
- package/lib/sandboxes.js +12 -7
- package/lib/ui/index.d.ts +1 -1
- package/lib/ui/index.js +1 -1
- package/lib/usageTracking.d.ts +21 -2
- package/lib/usageTracking.js +53 -81
- package/lib/validation.d.ts +11 -1
- package/lib/validation.js +98 -91
- package/package.json +14 -7
- package/types/Projects.d.ts +43 -0
- package/types/Projects.js +2 -0
- package/types/Prompts.d.ts +25 -0
- package/types/Prompts.js +2 -0
- package/commands/accounts.js +0 -30
- package/commands/cms/reactModules.js +0 -60
- package/commands/functions.js +0 -24
- package/commands/secrets/deleteSecret.js +0 -46
- package/commands/secrets.js +0 -23
- package/lib/ProjectLogsManager.js +0 -91
- package/lib/projectStructure.js +0 -116
- package/lib/projects.d.ts +0 -4
- package/lib/projects.js +0 -681
- package/lib/projectsWatch.d.ts +0 -1
- package/lib/prompts/cleanUploadPrompt.d.ts +0 -1
- package/lib/prompts/cleanUploadPrompt.js +0 -20
- /package/commands/{accounts → account}/clean.d.ts +0 -0
- /package/commands/{accounts → account}/info.d.ts +0 -0
- /package/commands/{accounts → account}/list.d.ts +0 -0
- /package/commands/{accounts → account}/remove.d.ts +0 -0
- /package/commands/{accounts → account}/rename.d.ts +0 -0
- /package/commands/{accounts → account}/use.d.ts +0 -0
- /package/commands/{accounts.d.ts → account.d.ts} +0 -0
- /package/commands/cms/{reactModules.d.ts → getReactModule.d.ts} +0 -0
- /package/commands/{functions.d.ts → completion.d.ts} +0 -0
- /package/commands/{functions/list.d.ts → function/deploy.d.ts} +0 -0
- /package/commands/{functions/server.d.ts → function/list.d.ts} +0 -0
- /package/commands/{secrets.d.ts → function/server.d.ts} +0 -0
- /package/commands/{functions/deploy.d.ts → function.d.ts} +0 -0
- /package/commands/{secrets/deleteSecret.d.ts → secret/addSecret.d.ts} +0 -0
- /package/commands/{secrets/listSecrets.d.ts → secret/deleteSecret.d.ts} +0 -0
- /package/commands/{secrets/updateSecret.d.ts → secret/listSecrets.d.ts} +0 -0
- /package/{lib/ProjectLogsManager.d.ts → commands/secret/updateSecret.d.ts} +0 -0
- /package/commands/{secrets/addSecret.d.ts → secret.d.ts} +0 -0
- /package/lib/{projectStructure.d.ts → projects/watch.d.ts} +0 -0
|
@@ -0,0 +1,342 @@
|
|
|
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.pollDeployStatus = exports.pollBuildStatus = void 0;
|
|
7
|
+
exports.displayWarnLogs = displayWarnLogs;
|
|
8
|
+
exports.pollProjectBuildAndDeploy = pollProjectBuildAndDeploy;
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
11
|
+
const projects_1 = require("@hubspot/local-dev-lib/api/projects");
|
|
12
|
+
const constants_1 = require("../constants");
|
|
13
|
+
const SpinniesManager_1 = __importDefault(require("../ui/SpinniesManager"));
|
|
14
|
+
const lang_1 = require("../lang");
|
|
15
|
+
const errorHandlers_1 = require("../errorHandlers");
|
|
16
|
+
const ui_1 = require("../ui");
|
|
17
|
+
const urls_1 = require("./urls");
|
|
18
|
+
const i18nKey = 'lib.projectBuildAndDeploy';
|
|
19
|
+
const SPINNER_STATUS = {
|
|
20
|
+
SPINNING: 'spinning',
|
|
21
|
+
};
|
|
22
|
+
function getSubtasks(task) {
|
|
23
|
+
if ('subbuildStatuses' in task) {
|
|
24
|
+
return task.subbuildStatuses;
|
|
25
|
+
}
|
|
26
|
+
return task.subdeployStatuses;
|
|
27
|
+
}
|
|
28
|
+
function getSubtaskName(task) {
|
|
29
|
+
if ('buildName' in task) {
|
|
30
|
+
return task.buildName;
|
|
31
|
+
}
|
|
32
|
+
return task.deployName;
|
|
33
|
+
}
|
|
34
|
+
function getSubtaskType(task) {
|
|
35
|
+
if ('buildType' in task) {
|
|
36
|
+
return task.buildType;
|
|
37
|
+
}
|
|
38
|
+
return task.deployType;
|
|
39
|
+
}
|
|
40
|
+
function makePollTaskStatusFunc({ statusFn, structureFn, statusText, statusStrings, linkToHubSpot, }) {
|
|
41
|
+
return async function (accountId, taskName, taskId, deployedBuildId = null, silenceLogs = false) {
|
|
42
|
+
const displayId = deployedBuildId || taskId;
|
|
43
|
+
if (linkToHubSpot && !silenceLogs) {
|
|
44
|
+
logger_1.logger.log(`\n${linkToHubSpot(accountId, taskName, taskId, deployedBuildId)}\n`);
|
|
45
|
+
}
|
|
46
|
+
SpinniesManager_1.default.init();
|
|
47
|
+
const overallTaskSpinniesKey = `overallTaskStatus-${statusText.STATUS_TEXT}`;
|
|
48
|
+
SpinniesManager_1.default.add(overallTaskSpinniesKey, {
|
|
49
|
+
text: 'Beginning',
|
|
50
|
+
succeedColor: 'white',
|
|
51
|
+
failColor: 'white',
|
|
52
|
+
failPrefix: chalk_1.default.bold('!'),
|
|
53
|
+
});
|
|
54
|
+
const [{ data: initialTaskStatus }, { data: { topLevelComponentsWithChildren: taskStructure }, },] = await Promise.all([
|
|
55
|
+
statusFn(accountId, taskName, taskId),
|
|
56
|
+
structureFn(accountId, taskName, taskId),
|
|
57
|
+
]);
|
|
58
|
+
const subtasks = getSubtasks(initialTaskStatus);
|
|
59
|
+
const tasksById = subtasks.reduce((acc, subtask) => {
|
|
60
|
+
const { id, visible } = subtask;
|
|
61
|
+
if (visible) {
|
|
62
|
+
acc[id] = subtask;
|
|
63
|
+
}
|
|
64
|
+
return acc;
|
|
65
|
+
}, {});
|
|
66
|
+
const structuredTasks = Object.keys(taskStructure).map(key => {
|
|
67
|
+
return {
|
|
68
|
+
...tasksById[key],
|
|
69
|
+
subtasks: taskStructure[key]
|
|
70
|
+
.filter(taskId => Boolean(tasksById[taskId]))
|
|
71
|
+
.map(taskId => tasksById[taskId]),
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
const numComponents = structuredTasks.length;
|
|
75
|
+
const componentCountText = silenceLogs
|
|
76
|
+
? ''
|
|
77
|
+
: (0, lang_1.i18n)(numComponents === 1
|
|
78
|
+
? `${i18nKey}.makePollTaskStatusFunc.componentCountSingular`
|
|
79
|
+
: `${i18nKey}.makePollTaskStatusFunc.componentCount`, { numComponents }) + '\n';
|
|
80
|
+
SpinniesManager_1.default.update(overallTaskSpinniesKey, {
|
|
81
|
+
text: `${statusStrings.INITIALIZE(taskName, displayId)}\n${componentCountText}`,
|
|
82
|
+
});
|
|
83
|
+
if (!silenceLogs) {
|
|
84
|
+
function addTaskSpinner(subtask, indent, newline) {
|
|
85
|
+
const taskName = getSubtaskName(subtask);
|
|
86
|
+
const taskType = getSubtaskType(subtask);
|
|
87
|
+
const formattedTaskType = constants_1.PROJECT_TASK_TYPES[taskType]
|
|
88
|
+
? `[${constants_1.PROJECT_TASK_TYPES[taskType]}]`
|
|
89
|
+
: '';
|
|
90
|
+
const text = `${indent <= 2 ? statusText.STATUS_TEXT : ''} ${chalk_1.default.bold(taskName)} ${formattedTaskType} ...${newline ? '\n' : ''}`;
|
|
91
|
+
SpinniesManager_1.default.add(subtask.id, {
|
|
92
|
+
text,
|
|
93
|
+
indent,
|
|
94
|
+
succeedColor: 'white',
|
|
95
|
+
failColor: 'white',
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
structuredTasks.forEach(task => {
|
|
99
|
+
addTaskSpinner(task, 2, !task.subtasks || task.subtasks.length === 0);
|
|
100
|
+
task.subtasks.forEach((subtask, i) => addTaskSpinner(subtask, 4, i === task.subtasks.length - 1));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
const pollInterval = setInterval(async () => {
|
|
105
|
+
let taskStatus;
|
|
106
|
+
try {
|
|
107
|
+
const { data } = await statusFn(accountId, taskName, taskId);
|
|
108
|
+
taskStatus = data;
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
logger_1.logger.debug(e);
|
|
112
|
+
(0, errorHandlers_1.logError)(e, new errorHandlers_1.ApiErrorContext({
|
|
113
|
+
accountId,
|
|
114
|
+
projectName: taskName,
|
|
115
|
+
}));
|
|
116
|
+
return reject(new Error((0, lang_1.i18n)(`${i18nKey}.makePollTaskStatusFunc.errorFetchingTaskStatus`, {
|
|
117
|
+
taskType: statusText.TYPE_KEY === constants_1.PROJECT_BUILD_TEXT.TYPE_KEY
|
|
118
|
+
? 'build'
|
|
119
|
+
: 'deploy',
|
|
120
|
+
})));
|
|
121
|
+
}
|
|
122
|
+
const subtasks = getSubtasks(taskStatus);
|
|
123
|
+
if (!taskStatus || !taskStatus.status || !subtasks) {
|
|
124
|
+
return reject(new Error((0, lang_1.i18n)(`${i18nKey}.makePollTaskStatusFunc.errorFetchingTaskStatus`, {
|
|
125
|
+
taskType: statusText.TYPE_KEY === constants_1.PROJECT_BUILD_TEXT.TYPE_KEY
|
|
126
|
+
? 'build'
|
|
127
|
+
: 'deploy',
|
|
128
|
+
})));
|
|
129
|
+
}
|
|
130
|
+
const { status } = taskStatus;
|
|
131
|
+
if (SpinniesManager_1.default.hasActiveSpinners()) {
|
|
132
|
+
subtasks.forEach(subtask => {
|
|
133
|
+
const { id, status } = subtask;
|
|
134
|
+
const spinner = SpinniesManager_1.default.pick(id);
|
|
135
|
+
if (!spinner || spinner.status !== SPINNER_STATUS.SPINNING) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const topLevelTask = structuredTasks.find(t => t.id == id);
|
|
139
|
+
if (status === statusText.STATES.SUCCESS ||
|
|
140
|
+
status === statusText.STATES.FAILURE) {
|
|
141
|
+
const taskStatusText = subtask.status === statusText.STATES.SUCCESS
|
|
142
|
+
? (0, lang_1.i18n)(`${i18nKey}.makePollTaskStatusFunc.successStatusText`)
|
|
143
|
+
: (0, lang_1.i18n)(`${i18nKey}.makePollTaskStatusFunc.failedStatusText`);
|
|
144
|
+
const hasNewline = spinner?.text?.includes('\n') || Boolean(topLevelTask);
|
|
145
|
+
const updatedText = `${spinner?.text?.replace('\n', '')} ${taskStatusText}${hasNewline ? '\n' : ''}`;
|
|
146
|
+
if (status === statusText.STATES.SUCCESS) {
|
|
147
|
+
SpinniesManager_1.default.succeed(id, { text: updatedText });
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
SpinniesManager_1.default.fail(id, { text: updatedText });
|
|
151
|
+
}
|
|
152
|
+
if (topLevelTask) {
|
|
153
|
+
topLevelTask.subtasks.forEach(currentSubtask => SpinniesManager_1.default.remove(currentSubtask.id));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
if (status === statusText.STATES.SUCCESS) {
|
|
158
|
+
SpinniesManager_1.default.succeed(overallTaskSpinniesKey, {
|
|
159
|
+
text: statusStrings.SUCCESS(taskName, displayId),
|
|
160
|
+
});
|
|
161
|
+
clearInterval(pollInterval);
|
|
162
|
+
resolve(taskStatus);
|
|
163
|
+
}
|
|
164
|
+
else if (status === statusText.STATES.FAILURE) {
|
|
165
|
+
SpinniesManager_1.default.fail(overallTaskSpinniesKey, {
|
|
166
|
+
text: statusStrings.FAIL(taskName, displayId),
|
|
167
|
+
});
|
|
168
|
+
if (!silenceLogs) {
|
|
169
|
+
const failedSubtasks = subtasks.filter(subtask => subtask.status === 'FAILURE');
|
|
170
|
+
(0, ui_1.uiLine)();
|
|
171
|
+
logger_1.logger.log(`${statusStrings.SUBTASK_FAIL(failedSubtasks.length === 1
|
|
172
|
+
? getSubtaskName(failedSubtasks[0])
|
|
173
|
+
: failedSubtasks.length + ' components', displayId)}\n`);
|
|
174
|
+
logger_1.logger.log('See below for a summary of errors.');
|
|
175
|
+
(0, ui_1.uiLine)();
|
|
176
|
+
const displayErrors = failedSubtasks.filter(subtask => subtask?.standardError?.subCategory !==
|
|
177
|
+
constants_1.PROJECT_ERROR_TYPES.SUBBUILD_FAILED &&
|
|
178
|
+
subtask?.standardError?.subCategory !==
|
|
179
|
+
constants_1.PROJECT_ERROR_TYPES.SUBDEPLOY_FAILED);
|
|
180
|
+
displayErrors.forEach(subTask => {
|
|
181
|
+
logger_1.logger.log(`\n--- ${chalk_1.default.bold(getSubtaskName(subTask))} failed with the following error ---`);
|
|
182
|
+
logger_1.logger.error(subTask.errorMessage);
|
|
183
|
+
// Log nested errors
|
|
184
|
+
if (subTask.standardError && subTask.standardError.errors) {
|
|
185
|
+
logger_1.logger.log();
|
|
186
|
+
subTask.standardError.errors.forEach(error => {
|
|
187
|
+
logger_1.logger.log(error.message);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
clearInterval(pollInterval);
|
|
193
|
+
resolve(taskStatus);
|
|
194
|
+
}
|
|
195
|
+
else if (!subtasks.length) {
|
|
196
|
+
clearInterval(pollInterval);
|
|
197
|
+
resolve(taskStatus);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}, constants_1.POLLING_DELAY);
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function pollBuildAutodeployStatus(accountId, taskName, buildId) {
|
|
205
|
+
return new Promise((resolve, reject) => {
|
|
206
|
+
let maxIntervals = (30 * 1000) / constants_1.POLLING_DELAY; // Num of intervals in ~30s
|
|
207
|
+
const pollInterval = setInterval(async () => {
|
|
208
|
+
let build;
|
|
209
|
+
try {
|
|
210
|
+
const response = await (0, projects_1.getBuildStatus)(accountId, taskName, buildId);
|
|
211
|
+
build = response.data;
|
|
212
|
+
}
|
|
213
|
+
catch (e) {
|
|
214
|
+
logger_1.logger.debug(e);
|
|
215
|
+
return reject(new Error((0, lang_1.i18n)(`${i18nKey}.pollBuildAutodeployStatusError`, { buildId })));
|
|
216
|
+
}
|
|
217
|
+
if (!build || !build.status) {
|
|
218
|
+
return reject(new Error((0, lang_1.i18n)(`${i18nKey}.pollBuildAutodeployStatusError`, { buildId })));
|
|
219
|
+
}
|
|
220
|
+
if (build.deployStatusTaskLocator || maxIntervals <= 0) {
|
|
221
|
+
clearInterval(pollInterval);
|
|
222
|
+
resolve(build);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
maxIntervals -= 1;
|
|
226
|
+
}
|
|
227
|
+
}, constants_1.POLLING_DELAY);
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
exports.pollBuildStatus = makePollTaskStatusFunc({
|
|
231
|
+
linkToHubSpot: (accountId, taskName, taskId) => (0, ui_1.uiLink)(`View build #${taskId} in HubSpot`, (0, urls_1.getProjectBuildDetailUrl)(taskName, taskId, accountId)),
|
|
232
|
+
statusFn: projects_1.getBuildStatus,
|
|
233
|
+
structureFn: projects_1.getBuildStructure,
|
|
234
|
+
statusText: constants_1.PROJECT_BUILD_TEXT,
|
|
235
|
+
statusStrings: {
|
|
236
|
+
INITIALIZE: (name, buildId) => `Building ${chalk_1.default.bold(name)} #${buildId}`,
|
|
237
|
+
SUCCESS: (name, buildId) => `Built ${chalk_1.default.bold(name)} #${buildId}`,
|
|
238
|
+
FAIL: (name, buildId) => `Failed to build ${chalk_1.default.bold(name)} #${buildId}`,
|
|
239
|
+
SUBTASK_FAIL: (buildId, name) => `Build #${buildId} failed because there was a problem\nbuilding ${chalk_1.default.bold(name)}`,
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
exports.pollDeployStatus = makePollTaskStatusFunc({
|
|
243
|
+
linkToHubSpot: (accountId, taskName, taskId, deployedBuildId) => (0, ui_1.uiLink)(`View deploy of build #${deployedBuildId} in HubSpot`, (0, urls_1.getProjectDeployDetailUrl)(taskName, taskId, accountId)),
|
|
244
|
+
statusFn: projects_1.getDeployStatus,
|
|
245
|
+
structureFn: projects_1.getDeployStructure,
|
|
246
|
+
statusText: constants_1.PROJECT_DEPLOY_TEXT,
|
|
247
|
+
statusStrings: {
|
|
248
|
+
INITIALIZE: (name, buildId) => `Deploying build #${buildId} in ${chalk_1.default.bold(name)}`,
|
|
249
|
+
SUCCESS: (name, buildId) => `Deployed build #${buildId} in ${chalk_1.default.bold(name)}`,
|
|
250
|
+
FAIL: (name, buildId) => `Failed to deploy build #${buildId} in ${chalk_1.default.bold(name)}`,
|
|
251
|
+
SUBTASK_FAIL: (deployedBuildId, name) => `Deploy for build #${deployedBuildId} failed because there was a\nproblem deploying ${chalk_1.default.bold(name)}`,
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
async function displayWarnLogs(accountId, projectName, taskId, isDeploy = false) {
|
|
255
|
+
let result;
|
|
256
|
+
if (isDeploy) {
|
|
257
|
+
try {
|
|
258
|
+
const { data } = await (0, projects_1.fetchDeployWarnLogs)(accountId, projectName, taskId);
|
|
259
|
+
result = data;
|
|
260
|
+
}
|
|
261
|
+
catch (e) {
|
|
262
|
+
(0, errorHandlers_1.logError)(e);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
try {
|
|
267
|
+
const { data } = await (0, projects_1.fetchBuildWarnLogs)(accountId, projectName, taskId);
|
|
268
|
+
result = data;
|
|
269
|
+
}
|
|
270
|
+
catch (e) {
|
|
271
|
+
(0, errorHandlers_1.logError)(e);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (result && result.logs) {
|
|
275
|
+
const logLength = result.logs.length;
|
|
276
|
+
result.logs.forEach((log, i) => {
|
|
277
|
+
logger_1.logger.warn(log.message);
|
|
278
|
+
if (i < logLength - 1) {
|
|
279
|
+
logger_1.logger.log('');
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
async function pollProjectBuildAndDeploy(accountId, projectConfig, tempFile, buildId, silenceLogs = false) {
|
|
285
|
+
let buildStatus = await (0, exports.pollBuildStatus)(accountId, projectConfig.name, buildId, null, silenceLogs);
|
|
286
|
+
if (!silenceLogs) {
|
|
287
|
+
(0, ui_1.uiLine)();
|
|
288
|
+
}
|
|
289
|
+
const result = {
|
|
290
|
+
succeeded: true,
|
|
291
|
+
buildId,
|
|
292
|
+
buildResult: buildStatus,
|
|
293
|
+
deployResult: null,
|
|
294
|
+
};
|
|
295
|
+
if (buildStatus.status === 'FAILURE') {
|
|
296
|
+
result.succeeded = false;
|
|
297
|
+
return result;
|
|
298
|
+
}
|
|
299
|
+
else if (buildStatus.isAutoDeployEnabled) {
|
|
300
|
+
if (!silenceLogs) {
|
|
301
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.pollProjectBuildAndDeploy.buildSucceededAutomaticallyDeploying`, {
|
|
302
|
+
accountIdentifier: (0, ui_1.uiAccountDescription)(accountId),
|
|
303
|
+
buildId,
|
|
304
|
+
}));
|
|
305
|
+
await displayWarnLogs(accountId, projectConfig.name, buildId);
|
|
306
|
+
}
|
|
307
|
+
// autoDeployId of 0 indicates a skipped deploy
|
|
308
|
+
const getIsDeploying = () => buildStatus.autoDeployId > 0 && buildStatus.deployStatusTaskLocator;
|
|
309
|
+
// Sometimes the deploys do not immediately initiate, give them a chance to kick off
|
|
310
|
+
if (!getIsDeploying()) {
|
|
311
|
+
buildStatus = await pollBuildAutodeployStatus(accountId, projectConfig.name, buildId);
|
|
312
|
+
}
|
|
313
|
+
if (getIsDeploying()) {
|
|
314
|
+
const deployStatus = await (0, exports.pollDeployStatus)(accountId, projectConfig.name, Number(buildStatus.deployStatusTaskLocator.id), buildId, silenceLogs);
|
|
315
|
+
result.deployResult = deployStatus;
|
|
316
|
+
if (deployStatus.status === 'FAILURE') {
|
|
317
|
+
result.succeeded = false;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else if (!silenceLogs) {
|
|
321
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.pollProjectBuildAndDeploy.unableToFindAutodeployStatus`, {
|
|
322
|
+
buildId,
|
|
323
|
+
viewDeploysLink: (0, ui_1.uiLink)((0, lang_1.i18n)(`${i18nKey}.pollProjectBuildAndDeploy.viewDeploys`), (0, urls_1.getProjectActivityUrl)(projectConfig.name, accountId)),
|
|
324
|
+
}));
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
try {
|
|
328
|
+
if (tempFile) {
|
|
329
|
+
tempFile.removeCallback();
|
|
330
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.pollProjectBuildAndDeploy.cleanedUpTempFile`, {
|
|
331
|
+
path: tempFile.name,
|
|
332
|
+
}));
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
catch (e) {
|
|
336
|
+
logger_1.logger.error(e);
|
|
337
|
+
}
|
|
338
|
+
if (result && result.deployResult) {
|
|
339
|
+
await displayWarnLogs(accountId, projectConfig.name, result.deployResult.deployId, true);
|
|
340
|
+
}
|
|
341
|
+
return result;
|
|
342
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { RepoPath } from '@hubspot/local-dev-lib/types/Github';
|
|
2
|
+
import { Project } from '@hubspot/local-dev-lib/types/Project';
|
|
3
|
+
import { ProjectTemplate, ProjectConfig, ProjectAddComponentData, ComponentTemplate } from '../../types/Projects';
|
|
4
|
+
export declare function writeProjectConfig(configPath: string, config: ProjectConfig): boolean;
|
|
5
|
+
export declare function getIsInProject(dir?: string): boolean;
|
|
6
|
+
export declare function getProjectConfig(dir?: string): Promise<{
|
|
7
|
+
projectDir: string | null;
|
|
8
|
+
projectConfig: ProjectConfig | null;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function createProjectConfig(projectPath: string, projectName: string, template: ProjectTemplate, templateSource: RepoPath, githubRef: string): Promise<boolean>;
|
|
11
|
+
export declare function validateProjectConfig(projectConfig: ProjectConfig, projectDir: string): void;
|
|
12
|
+
export declare function ensureProjectExists(accountId: number, projectName: string, { forceCreate, allowCreate, noLogs, withPolling, uploadCommand, }?: {
|
|
13
|
+
forceCreate?: boolean | undefined;
|
|
14
|
+
allowCreate?: boolean | undefined;
|
|
15
|
+
noLogs?: boolean | undefined;
|
|
16
|
+
withPolling?: boolean | undefined;
|
|
17
|
+
uploadCommand?: boolean | undefined;
|
|
18
|
+
}): Promise<{
|
|
19
|
+
projectExists: boolean;
|
|
20
|
+
project?: Project;
|
|
21
|
+
}>;
|
|
22
|
+
export declare function logFeedbackMessage(buildId: number): void;
|
|
23
|
+
export declare function createProjectComponent(component: ProjectAddComponentData, name: string, projectComponentsVersion: string): Promise<void>;
|
|
24
|
+
export declare function getProjectComponentsByVersion(projectComponentsVersion: string): Promise<ComponentTemplate[]>;
|
|
@@ -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
|
+
}
|