@hubspot/cli 4.1.8-beta.4 → 4.1.8-beta.6
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/commands/accounts/info.js +4 -2
- package/commands/project/create.js +3 -3
- package/commands/project/deploy.js +22 -26
- package/commands/project/dev.js +65 -58
- package/commands/project/download.js +57 -63
- package/commands/project/listBuilds.js +4 -1
- package/commands/project/logs.js +16 -6
- package/commands/project/upload.js +53 -26
- package/commands/project/watch.js +31 -24
- package/commands/sandbox/create.js +8 -6
- package/commands/sandbox/sync.js +32 -4
- package/commands/theme/generate-selectors.js +214 -0
- package/commands/theme.js +6 -5
- package/lang/en.lyaml +48 -36
- package/lib/DevServerManager.js +21 -2
- package/lib/LocalDevManager.js +121 -47
- package/lib/SpinniesManager.js +14 -5
- package/lib/generate-selectors.js +161 -0
- package/lib/projects.js +24 -23
- package/lib/prompts/createProjectPrompt.js +7 -5
- package/lib/prompts/downloadProjectPrompt.js +17 -2
- package/lib/prompts/projectDevTargetAccountPrompt.js +45 -71
- package/lib/prompts/projectsLogsPrompt.js +29 -13
- package/lib/sandboxes.js +7 -4
- package/package.json +4 -4
|
@@ -8,6 +8,7 @@ const {
|
|
|
8
8
|
} = require('../../lib/commonOpts');
|
|
9
9
|
const { loadAndValidateOptions } = require('../../lib/validation');
|
|
10
10
|
const { i18n } = require('../../lib/lang');
|
|
11
|
+
const { getTableContents } = require('@hubspot/cli-lib/lib/table');
|
|
11
12
|
|
|
12
13
|
const i18nKey = 'cli.commands.accounts.subcommands.info';
|
|
13
14
|
exports.describe = i18n(`${i18nKey}.describe`);
|
|
@@ -26,11 +27,12 @@ exports.handler = async options => {
|
|
|
26
27
|
|
|
27
28
|
const response = await getAccessToken(personalAccessKey, env, accountId);
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
const scopeGroups = response.scopeGroups.map(s => [s]);
|
|
30
31
|
|
|
31
32
|
logger.log(i18n(`${i18nKey}.name`, { name }));
|
|
32
33
|
logger.log(i18n(`${i18nKey}.accountId`, { accountId }));
|
|
33
|
-
logger.log(i18n(`${i18nKey}.scopeGroups
|
|
34
|
+
logger.log(i18n(`${i18nKey}.scopeGroups`));
|
|
35
|
+
logger.log(getTableContents(scopeGroups, { border: { bodyLeft: ' ' } }));
|
|
34
36
|
} else {
|
|
35
37
|
logger.log(i18n(`${i18nKey}.errors.notUsingPersonalAccessKey`));
|
|
36
38
|
}
|
|
@@ -35,7 +35,7 @@ exports.handler = async options => {
|
|
|
35
35
|
path.resolve(getCwd(), options.location || location),
|
|
36
36
|
options.name || name,
|
|
37
37
|
options.template || template,
|
|
38
|
-
options.
|
|
38
|
+
options.templateSource
|
|
39
39
|
);
|
|
40
40
|
|
|
41
41
|
logger.log('');
|
|
@@ -62,8 +62,8 @@ exports.builder = yargs => {
|
|
|
62
62
|
describe: i18n(`${i18nKey}.options.template.describe`),
|
|
63
63
|
type: 'string',
|
|
64
64
|
},
|
|
65
|
-
|
|
66
|
-
describe: i18n(`${i18nKey}.options.
|
|
65
|
+
templateSource: {
|
|
66
|
+
describe: i18n(`${i18nKey}.options.templateSource.describe`),
|
|
67
67
|
type: 'string',
|
|
68
68
|
},
|
|
69
69
|
});
|
|
@@ -52,32 +52,30 @@ exports.handler = async options => {
|
|
|
52
52
|
|
|
53
53
|
let buildIdToDeploy = buildIdOption;
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
buildIdToDeploy = buildIdPromptResponse.buildId;
|
|
71
|
-
}
|
|
55
|
+
try {
|
|
56
|
+
if (!buildIdOption) {
|
|
57
|
+
const { latestBuild, deployedBuildId } = await fetchProject(
|
|
58
|
+
accountId,
|
|
59
|
+
projectName
|
|
60
|
+
);
|
|
61
|
+
if (!latestBuild || !latestBuild.buildId) {
|
|
62
|
+
logger.error(i18n(`${i18nKey}.errors.noBuilds`));
|
|
63
|
+
process.exit(EXIT_CODES.ERROR);
|
|
64
|
+
}
|
|
65
|
+
const buildIdPromptResponse = await buildIdPrompt(
|
|
66
|
+
latestBuild.buildId,
|
|
67
|
+
deployedBuildId,
|
|
68
|
+
projectName
|
|
69
|
+
);
|
|
72
70
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
process.exit(EXIT_CODES.ERROR);
|
|
76
|
-
}
|
|
71
|
+
buildIdToDeploy = buildIdPromptResponse.buildId;
|
|
72
|
+
}
|
|
77
73
|
|
|
78
|
-
|
|
74
|
+
if (!buildIdToDeploy) {
|
|
75
|
+
logger.error(i18n(`${i18nKey}.errors.noBuildId`));
|
|
76
|
+
process.exit(EXIT_CODES.ERROR);
|
|
77
|
+
}
|
|
79
78
|
|
|
80
|
-
try {
|
|
81
79
|
const deployResp = await deployProject(
|
|
82
80
|
accountId,
|
|
83
81
|
projectName,
|
|
@@ -90,7 +88,6 @@ exports.handler = async options => {
|
|
|
90
88
|
details: deployResp.error.message,
|
|
91
89
|
})
|
|
92
90
|
);
|
|
93
|
-
exitCode = EXIT_CODES.ERROR;
|
|
94
91
|
return;
|
|
95
92
|
}
|
|
96
93
|
|
|
@@ -106,9 +103,8 @@ exports.handler = async options => {
|
|
|
106
103
|
} else {
|
|
107
104
|
logApiErrorInstance(e, new ApiErrorContext({ accountId, projectName }));
|
|
108
105
|
}
|
|
109
|
-
|
|
106
|
+
process.exit(EXIT_CODES.ERROR);
|
|
110
107
|
}
|
|
111
|
-
process.exit(exitCode);
|
|
112
108
|
};
|
|
113
109
|
|
|
114
110
|
exports.builder = yargs => {
|
package/commands/project/dev.js
CHANGED
|
@@ -29,6 +29,7 @@ const {
|
|
|
29
29
|
LocalDevManager,
|
|
30
30
|
UPLOAD_PERMISSIONS,
|
|
31
31
|
} = require('../../lib/LocalDevManager');
|
|
32
|
+
const { isSandbox } = require('../../lib/sandboxes');
|
|
32
33
|
const { getAccountConfig, getEnv } = require('@hubspot/cli-lib');
|
|
33
34
|
const { sandboxNamePrompt } = require('../../lib/prompts/sandboxesPrompt');
|
|
34
35
|
const {
|
|
@@ -37,12 +38,18 @@ const {
|
|
|
37
38
|
getAvailableSyncTypes,
|
|
38
39
|
} = require('../../lib/sandboxes');
|
|
39
40
|
const { getValidEnv } = require('@hubspot/cli-lib/lib/environment');
|
|
40
|
-
const {
|
|
41
|
+
const { ERROR_TYPES } = require('@hubspot/cli-lib/lib/constants');
|
|
42
|
+
const {
|
|
43
|
+
logErrorInstance,
|
|
44
|
+
logApiErrorInstance,
|
|
45
|
+
ApiErrorContext,
|
|
46
|
+
} = require('@hubspot/cli-lib/errorHandlers');
|
|
41
47
|
const { buildSandbox } = require('../../lib/sandbox-create');
|
|
42
48
|
const { syncSandbox } = require('../../lib/sandbox-sync');
|
|
43
49
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
|
|
44
50
|
const {
|
|
45
51
|
isMissingScopeError,
|
|
52
|
+
isSpecifiedError,
|
|
46
53
|
} = require('@hubspot/cli-lib/errorHandlers/apiErrors');
|
|
47
54
|
|
|
48
55
|
const i18nKey = 'cli.commands.project.subcommands.dev';
|
|
@@ -60,13 +67,7 @@ exports.handler = async options => {
|
|
|
60
67
|
|
|
61
68
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
62
69
|
|
|
63
|
-
logger.log(i18n(`${i18nKey}.logs.
|
|
64
|
-
uiLine();
|
|
65
|
-
logger.log(i18n(`${i18nKey}.logs.introBody1`));
|
|
66
|
-
logger.log();
|
|
67
|
-
logger.log(i18n(`${i18nKey}.logs.introBody2`));
|
|
68
|
-
uiLine();
|
|
69
|
-
logger.log();
|
|
70
|
+
logger.log(i18n(`${i18nKey}.logs.betaMessage`));
|
|
70
71
|
|
|
71
72
|
if (!projectConfig) {
|
|
72
73
|
logger.error(i18n(`${i18nKey}.errors.noProjectConfig`));
|
|
@@ -74,47 +75,32 @@ exports.handler = async options => {
|
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
const accounts = getConfigAccounts();
|
|
77
|
-
let targetAccountId = options.accountId;
|
|
78
|
+
let targetAccountId = options.account ? accountId : null;
|
|
78
79
|
let createNewSandbox = false;
|
|
79
|
-
|
|
80
|
+
const defaultAccountIsSandbox = isSandbox(accountConfig);
|
|
81
|
+
|
|
82
|
+
if (!targetAccountId && defaultAccountIsSandbox) {
|
|
83
|
+
targetAccountId = accountId;
|
|
84
|
+
}
|
|
80
85
|
|
|
81
86
|
if (!targetAccountId) {
|
|
87
|
+
//logger.log(i18n(`${i18nKey}.logs.learnMoreLink`));
|
|
88
|
+
logger.log();
|
|
89
|
+
uiLine();
|
|
90
|
+
logger.warn(i18n(`${i18nKey}.logs.nonSandboxWarning`));
|
|
91
|
+
uiLine();
|
|
92
|
+
logger.log();
|
|
93
|
+
|
|
82
94
|
const {
|
|
83
95
|
targetAccountId: promptTargetAccountId,
|
|
84
|
-
chooseNonSandbox: promptChooseNonSandbox,
|
|
85
96
|
createNewSandbox: promptCreateNewSandbox,
|
|
86
|
-
} = await selectTargetAccountPrompt(accounts, accountConfig
|
|
97
|
+
} = await selectTargetAccountPrompt(accounts, accountConfig);
|
|
87
98
|
|
|
88
99
|
targetAccountId = promptTargetAccountId;
|
|
89
|
-
chooseNonSandbox = promptChooseNonSandbox;
|
|
90
100
|
createNewSandbox = promptCreateNewSandbox;
|
|
91
101
|
}
|
|
92
102
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
// Show a warning if the user chooses a non-sandbox account (false)
|
|
96
|
-
let shouldTargetNonSandboxAccount;
|
|
97
|
-
if (chooseNonSandbox) {
|
|
98
|
-
uiLine();
|
|
99
|
-
logger.warn(i18n(`${i18nKey}.logs.prodAccountWarning`));
|
|
100
|
-
uiLine();
|
|
101
|
-
logger.log();
|
|
102
|
-
|
|
103
|
-
shouldTargetNonSandboxAccount = await confirmPrompt(
|
|
104
|
-
i18n(`${i18nKey}.prompt.targetNonSandbox`)
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
if (shouldTargetNonSandboxAccount) {
|
|
108
|
-
const {
|
|
109
|
-
targetAccountId: promptNonSandboxTargetAccountId,
|
|
110
|
-
} = await selectTargetAccountPrompt(accounts, accountConfig, true);
|
|
111
|
-
|
|
112
|
-
targetAccountId = promptNonSandboxTargetAccountId;
|
|
113
|
-
logger.log();
|
|
114
|
-
} else {
|
|
115
|
-
process.exit(EXIT_CODES.SUCCESS);
|
|
116
|
-
}
|
|
117
|
-
} else if (createNewSandbox) {
|
|
103
|
+
if (createNewSandbox) {
|
|
118
104
|
try {
|
|
119
105
|
await validateSandboxUsageLimits(accountConfig, DEVELOPER_SANDBOX, env);
|
|
120
106
|
} catch (err) {
|
|
@@ -179,7 +165,8 @@ exports.handler = async options => {
|
|
|
179
165
|
}
|
|
180
166
|
);
|
|
181
167
|
|
|
182
|
-
const isNonSandboxAccount =
|
|
168
|
+
const isNonSandboxAccount =
|
|
169
|
+
!defaultAccountIsSandbox && targetAccountId === accountId;
|
|
183
170
|
|
|
184
171
|
let uploadPermission = isNonSandboxAccount
|
|
185
172
|
? UPLOAD_PERMISSIONS.manual
|
|
@@ -198,21 +185,26 @@ exports.handler = async options => {
|
|
|
198
185
|
const spinnies = SpinniesManager.init();
|
|
199
186
|
|
|
200
187
|
if (!projectExists) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
188
|
+
// Create the project without prompting if this is a newly created sandbox
|
|
189
|
+
let shouldCreateProject = createNewSandbox;
|
|
190
|
+
|
|
191
|
+
if (!shouldCreateProject) {
|
|
192
|
+
uiLine();
|
|
193
|
+
logger.warn(
|
|
194
|
+
i18n(`${i18nKey}.logs.projectMustExistExplanation`, {
|
|
195
|
+
accountIdentifier: uiAccountDescription(targetAccountId),
|
|
196
|
+
projectName: projectConfig.name,
|
|
197
|
+
})
|
|
198
|
+
);
|
|
199
|
+
uiLine();
|
|
209
200
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
201
|
+
shouldCreateProject = await confirmPrompt(
|
|
202
|
+
i18n(`${i18nKey}.prompt.createProject`, {
|
|
203
|
+
accountIdentifier: uiAccountDescription(targetAccountId),
|
|
204
|
+
projectName: projectConfig.name,
|
|
205
|
+
})
|
|
206
|
+
);
|
|
207
|
+
}
|
|
216
208
|
|
|
217
209
|
if (shouldCreateProject) {
|
|
218
210
|
try {
|
|
@@ -228,9 +220,10 @@ exports.handler = async options => {
|
|
|
228
220
|
accountIdentifier: uiAccountDescription(targetAccountId),
|
|
229
221
|
projectName: projectConfig.name,
|
|
230
222
|
}),
|
|
223
|
+
succeedColor: 'white',
|
|
231
224
|
});
|
|
232
225
|
} catch (err) {
|
|
233
|
-
logger.log(i18n(`${i18nKey}.
|
|
226
|
+
logger.log(i18n(`${i18nKey}.status.failedToCreateProject`));
|
|
234
227
|
process.exit(EXIT_CODES.ERROR);
|
|
235
228
|
}
|
|
236
229
|
} else {
|
|
@@ -260,10 +253,24 @@ exports.handler = async options => {
|
|
|
260
253
|
);
|
|
261
254
|
}
|
|
262
255
|
|
|
263
|
-
if (result &&
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
256
|
+
if (result && result.error) {
|
|
257
|
+
if (
|
|
258
|
+
isSpecifiedError(result.error, {
|
|
259
|
+
subCategory: ERROR_TYPES.PROJECT_LOCKED,
|
|
260
|
+
})
|
|
261
|
+
) {
|
|
262
|
+
logger.log();
|
|
263
|
+
logger.error(i18n(`${i18nKey}.errors.projectLockedError`));
|
|
264
|
+
logger.log();
|
|
265
|
+
} else {
|
|
266
|
+
logApiErrorInstance(
|
|
267
|
+
result.error,
|
|
268
|
+
new ApiErrorContext({
|
|
269
|
+
accountId,
|
|
270
|
+
projectName: projectConfig.name,
|
|
271
|
+
})
|
|
272
|
+
);
|
|
273
|
+
}
|
|
267
274
|
process.exit(EXIT_CODES.ERROR);
|
|
268
275
|
} else {
|
|
269
276
|
spinnies.remove('devModeSetup');
|
|
@@ -44,83 +44,77 @@ exports.handler = async options => {
|
|
|
44
44
|
|
|
45
45
|
trackCommandUsage('project-download', null, accountId);
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
47
|
+
try {
|
|
48
|
+
const projectExists = await ensureProjectExists(accountId, projectName, {
|
|
49
|
+
allowCreate: false,
|
|
50
|
+
noLogs: true,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
if (!projectExists) {
|
|
54
|
+
logger.error(
|
|
55
|
+
i18n(`${i18nKey}.errors.projectNotFound`, {
|
|
56
|
+
projectName: chalk.bold(projectName),
|
|
57
|
+
accountId: chalk.bold(accountId),
|
|
58
|
+
})
|
|
59
|
+
);
|
|
60
|
+
let { name: promptedProjectName } = await downloadProjectPrompt(options);
|
|
61
|
+
let projectName = promptedProjectName || project;
|
|
62
|
+
}
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
const absoluteDestPath = dest ? path.resolve(getCwd(), dest) : getCwd();
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
const projectConfigCreated = await createProjectConfig(
|
|
67
|
+
absoluteDestPath,
|
|
68
|
+
projectName,
|
|
69
|
+
{ name: 'no-template' }
|
|
70
|
+
);
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
if (!projectConfigCreated) {
|
|
73
|
+
logger.log(i18n(`${i18nKey}.logs.downloadCancelled`));
|
|
74
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
75
|
+
}
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
let buildNumberToDownload = buildNumber;
|
|
77
|
+
let buildNumberToDownload = buildNumber;
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
if (!buildNumberToDownload) {
|
|
80
|
+
let projectBuildsResult;
|
|
81
81
|
|
|
82
|
-
try {
|
|
83
82
|
projectBuildsResult = await fetchProjectBuilds(accountId, projectName);
|
|
84
|
-
} catch (e) {
|
|
85
|
-
logApiErrorInstance(e, new ApiErrorContext({ accountId }));
|
|
86
|
-
process.exit(EXIT_CODES.ERROR);
|
|
87
|
-
}
|
|
88
83
|
|
|
89
|
-
|
|
84
|
+
const { results: projectBuilds } = projectBuildsResult;
|
|
90
85
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
86
|
+
if (projectBuilds && projectBuilds.length) {
|
|
87
|
+
const latestBuild = projectBuilds[0];
|
|
88
|
+
buildNumberToDownload = latestBuild.buildId;
|
|
89
|
+
}
|
|
94
90
|
}
|
|
95
|
-
}
|
|
96
91
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
92
|
+
const zippedProject = await downloadProject(
|
|
93
|
+
accountId,
|
|
94
|
+
projectName,
|
|
95
|
+
buildNumberToDownload
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
await extractZipArchive(
|
|
99
|
+
zippedProject,
|
|
100
|
+
projectName,
|
|
101
|
+
path.resolve(absoluteDestPath, 'src'),
|
|
102
|
+
{
|
|
103
|
+
includesRootDir: false,
|
|
104
|
+
}
|
|
105
|
+
);
|
|
111
106
|
|
|
112
|
-
|
|
113
|
-
|
|
107
|
+
logger.log(
|
|
108
|
+
i18n(`${i18nKey}.logs.downloadSucceeded`, {
|
|
109
|
+
buildId: buildNumberToDownload,
|
|
110
|
+
projectName,
|
|
111
|
+
})
|
|
112
|
+
);
|
|
113
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
114
|
+
} catch (e) {
|
|
115
|
+
logApiErrorInstance(e, new ApiErrorContext({ accountId, projectName }));
|
|
114
116
|
process.exit(EXIT_CODES.ERROR);
|
|
115
117
|
}
|
|
116
|
-
|
|
117
|
-
logger.log(
|
|
118
|
-
i18n(`${i18nKey}.logs.downloadSucceeded`, {
|
|
119
|
-
buildId: buildNumberToDownload,
|
|
120
|
-
projectName,
|
|
121
|
-
})
|
|
122
|
-
);
|
|
123
|
-
process.exit(EXIT_CODES.SUCCESS);
|
|
124
118
|
};
|
|
125
119
|
|
|
126
120
|
exports.builder = yargs => {
|
|
@@ -127,7 +127,10 @@ exports.handler = async options => {
|
|
|
127
127
|
if (e.statusCode === 404) {
|
|
128
128
|
logger.error(`Project ${projectConfig.name} not found. `);
|
|
129
129
|
} else {
|
|
130
|
-
logApiErrorInstance(
|
|
130
|
+
logApiErrorInstance(
|
|
131
|
+
e,
|
|
132
|
+
new ApiErrorContext({ accountId, projectName: projectConfig.name })
|
|
133
|
+
);
|
|
131
134
|
}
|
|
132
135
|
}
|
|
133
136
|
};
|
package/commands/project/logs.js
CHANGED
|
@@ -22,6 +22,10 @@ const {
|
|
|
22
22
|
getProjectAppFunctionLogs,
|
|
23
23
|
getLatestProjectAppFunctionLog,
|
|
24
24
|
} = require('@hubspot/cli-lib/api/functions');
|
|
25
|
+
const {
|
|
26
|
+
logApiErrorInstance,
|
|
27
|
+
ApiErrorContext,
|
|
28
|
+
} = require('@hubspot/cli-lib/errorHandlers');
|
|
25
29
|
const {
|
|
26
30
|
getFunctionLogs,
|
|
27
31
|
getLatestFunctionLog,
|
|
@@ -44,10 +48,16 @@ const getPrivateAppsUrl = accountId => {
|
|
|
44
48
|
return `${baseUrl}/private-apps/${accountId}`;
|
|
45
49
|
};
|
|
46
50
|
|
|
47
|
-
const handleLogsError = (e, name) => {
|
|
48
|
-
logger.debug(`Log fetch error: ${e.message}`);
|
|
51
|
+
const handleLogsError = (e, name, projectName) => {
|
|
49
52
|
if (e.statusCode === 404) {
|
|
53
|
+
logger.debug(`Log fetch error: ${e.message}`);
|
|
50
54
|
logger.log(i18n(`${i18nKey}.logs.noLogsFound`, { name }));
|
|
55
|
+
} else {
|
|
56
|
+
logApiErrorInstance(
|
|
57
|
+
e,
|
|
58
|
+
new ApiErrorContext({ accountId: getAccountId(), projectName })
|
|
59
|
+
);
|
|
60
|
+
process.exit(EXIT_CODES.ERROR);
|
|
51
61
|
}
|
|
52
62
|
};
|
|
53
63
|
|
|
@@ -77,7 +87,7 @@ const handleFunctionLog = async (accountId, options) => {
|
|
|
77
87
|
)
|
|
78
88
|
: getFunctionLogs(accountId, functionName, { after });
|
|
79
89
|
} catch (e) {
|
|
80
|
-
handleLogsError(e, functionName);
|
|
90
|
+
handleLogsError(e, functionName, projectName);
|
|
81
91
|
}
|
|
82
92
|
};
|
|
83
93
|
|
|
@@ -89,7 +99,7 @@ const handleFunctionLog = async (accountId, options) => {
|
|
|
89
99
|
projectName,
|
|
90
100
|
appPath
|
|
91
101
|
)
|
|
92
|
-
: getLatestFunctionLog(accountId, functionName);
|
|
102
|
+
: getLatestFunctionLog(accountId, functionName, projectName);
|
|
93
103
|
};
|
|
94
104
|
|
|
95
105
|
if (follow) {
|
|
@@ -104,14 +114,14 @@ const handleFunctionLog = async (accountId, options) => {
|
|
|
104
114
|
try {
|
|
105
115
|
logsResp = await fetchLatest();
|
|
106
116
|
} catch (e) {
|
|
107
|
-
handleLogsError(e, functionName);
|
|
117
|
+
handleLogsError(e, functionName, projectName);
|
|
108
118
|
return true;
|
|
109
119
|
}
|
|
110
120
|
} else {
|
|
111
121
|
try {
|
|
112
122
|
logsResp = await tailCall();
|
|
113
123
|
} catch (e) {
|
|
114
|
-
handleLogsError(e, functionName);
|
|
124
|
+
handleLogsError(e, functionName, projectName);
|
|
115
125
|
return true;
|
|
116
126
|
}
|
|
117
127
|
}
|
|
@@ -19,6 +19,14 @@ const {
|
|
|
19
19
|
} = require('../../lib/projects');
|
|
20
20
|
const { i18n } = require('../../lib/lang');
|
|
21
21
|
const { getAccountConfig } = require('@hubspot/cli-lib');
|
|
22
|
+
const { ERROR_TYPES } = require('@hubspot/cli-lib/lib/constants');
|
|
23
|
+
const {
|
|
24
|
+
isSpecifiedError,
|
|
25
|
+
} = require('@hubspot/cli-lib/errorHandlers/apiErrors');
|
|
26
|
+
const {
|
|
27
|
+
logApiErrorInstance,
|
|
28
|
+
ApiErrorContext,
|
|
29
|
+
} = require('@hubspot/cli-lib/errorHandlers');
|
|
22
30
|
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
23
31
|
|
|
24
32
|
const i18nKey = 'cli.commands.project.subcommands.upload';
|
|
@@ -42,34 +50,53 @@ exports.handler = async options => {
|
|
|
42
50
|
|
|
43
51
|
await ensureProjectExists(accountId, projectConfig.name, { forceCreate });
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (result.buildSucceeded && !result.autodeployEnabled) {
|
|
54
|
-
uiLine();
|
|
55
|
-
logger.log(
|
|
56
|
-
chalk.bold(
|
|
57
|
-
i18n(`${i18nKey}.logs.buildSucceeded`, {
|
|
58
|
-
buildId: result.buildId,
|
|
59
|
-
})
|
|
60
|
-
)
|
|
61
|
-
);
|
|
62
|
-
logger.log(i18n(`${i18nKey}.logs.readyToGoLive`));
|
|
63
|
-
logger.log(
|
|
64
|
-
i18n(`${i18nKey}.logs.runCommand`, {
|
|
65
|
-
command: chalk.hex('f5c26b')('hs project deploy'),
|
|
66
|
-
})
|
|
53
|
+
try {
|
|
54
|
+
const result = await handleProjectUpload(
|
|
55
|
+
accountId,
|
|
56
|
+
projectConfig,
|
|
57
|
+
projectDir,
|
|
58
|
+
pollProjectBuildAndDeploy,
|
|
59
|
+
message
|
|
67
60
|
);
|
|
68
|
-
uiLine();
|
|
69
|
-
}
|
|
70
61
|
|
|
71
|
-
|
|
72
|
-
|
|
62
|
+
if (result.error) {
|
|
63
|
+
if (
|
|
64
|
+
isSpecifiedError(result.error, {
|
|
65
|
+
subCategory: ERROR_TYPES.PROJECT_LOCKED,
|
|
66
|
+
})
|
|
67
|
+
) {
|
|
68
|
+
logger.log();
|
|
69
|
+
logger.error(i18n(`${i18nKey}.errors.projectLockedError`));
|
|
70
|
+
logger.log();
|
|
71
|
+
} else {
|
|
72
|
+
logApiErrorInstance(
|
|
73
|
+
result.error,
|
|
74
|
+
new ApiErrorContext({
|
|
75
|
+
accountId,
|
|
76
|
+
projectName: projectConfig.name,
|
|
77
|
+
})
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
process.exit(EXIT_CODES.ERROR);
|
|
81
|
+
}
|
|
82
|
+
if (result.buildSucceeded && !result.autodeployEnabled) {
|
|
83
|
+
uiLine();
|
|
84
|
+
logger.log(
|
|
85
|
+
chalk.bold(
|
|
86
|
+
i18n(`${i18nKey}.logs.buildSucceeded`, {
|
|
87
|
+
buildId: result.buildId,
|
|
88
|
+
})
|
|
89
|
+
)
|
|
90
|
+
);
|
|
91
|
+
uiLine();
|
|
92
|
+
logFeedbackMessage(result.buildId);
|
|
93
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
94
|
+
}
|
|
95
|
+
} catch (e) {
|
|
96
|
+
const projectName = projectConfig.name;
|
|
97
|
+
logApiErrorInstance(e, new ApiErrorContext({ accountId, projectName }));
|
|
98
|
+
process.exit(EXIT_CODES.ERROR);
|
|
99
|
+
}
|
|
73
100
|
};
|
|
74
101
|
|
|
75
102
|
exports.builder = yargs => {
|